221{
222 ioDevice->open(QIODevice::ReadOnly);
224 std::string xmpPacket_;
225 QByteArray arr = ioDevice->readAll();
226 xmpPacket_.assign(arr.data(), arr.length());
228
229 Exiv2::XmpData xmpData_;
230 if (Exiv2::XmpParser::decode(xmpData_, xmpPacket_) != 0) {
232 return false;
233 }
234 QMap<const KisMetaData::Schema *, QMap<QString, QMap<QString, KisMetaData::Value>>> structures;
235 QMap<const KisMetaData::Schema *, QMap<QString, QVector<QMap<QString, KisMetaData::Value>>>> arraysOfStructures;
236 for (Exiv2::XmpData::iterator it = xmpData_.begin(); it != xmpData_.end(); ++it) {
237 dbgMetaData <<
"Start iteration" << it->key().c_str();
238
239 Exiv2::XmpKey key(it->key());
240 dbgMetaData << key.groupName().c_str() <<
" " << key.tagName().c_str() <<
" " << key.ns().c_str();
241 if ((key.groupName() == "exif" || key.groupName() == "tiff")
242 && key.tagName() == "NativeDigest") {
243
244
246 } else {
249 if (!schema) {
251 if (!schema) {
253 Q_ASSERT(schema);
254 }
255 }
256#if EXIV2_TEST_VERSION(0,28,0)
257 const Exiv2::Value::UniquePtr
value = it->getValue();
258#else
259 const Exiv2::Value::AutoPtr
value = it->getValue();
260#endif
261 QString structName;
262 int arrayIndex = -1;
263 QString tagName;
265
266 if (!
parseTagName(key.tagName().c_str(), structName, arrayIndex, tagName, &typeInfo, schema))
267 continue;
268
269 bool isStructureEntry = !structName.isEmpty() && arrayIndex == -1;
270 bool isStructureInArrayEntry = !structName.isEmpty() && arrayIndex != -1;
271 Q_ASSERT(isStructureEntry != isStructureInArrayEntry || !isStructureEntry);
272
274 bool ignoreValue = false;
275
276 if (
value->typeId() == Exiv2::xmpBag ||
value->typeId() == Exiv2::xmpSeq
277 ||
value->typeId() == Exiv2::xmpAlt) {
279 if (typeInfo) {
281 }
283 if (embeddedTypeInfo) {
284 parser = embeddedTypeInfo->
parser();
285 }
286 const Exiv2::XmpArrayValue *xav =
dynamic_cast<const Exiv2::XmpArrayValue *
>(
value.get());
287 Q_ASSERT(xav);
289#if EXIV2_TEST_VERSION(0,28,0)
290 for (size_t i = 0; i < xav->count(); ++i) {
291#else
292 for (int i = 0; i < xav->count(); ++i) {
293#endif
294 QString
value = QString::fromStdString(xav->toString(i));
295 if (parser) {
297 } else {
298 dbgImage <<
"No parser " << tagName;
300 }
301 }
303 switch (xav->xmpArrayType()) {
304 case Exiv2::XmpValue::xaNone:
305 warnKrita <<
"KisXMPIO: Unsupported array";
306 break;
307 case Exiv2::XmpValue::xaAlt:
309 break;
310 case Exiv2::XmpValue::xaBag:
312 break;
313 case Exiv2::XmpValue::xaSeq:
315 break;
316 }
318 }
else if (
value->typeId() == Exiv2::langAlt) {
319 const Exiv2::LangAltValue *xav =
dynamic_cast<const Exiv2::LangAltValue *
>(
value.get());
321
323 for (std::map<std::string, std::string>::const_iterator it = xav->value_.begin();
324 it != xav->value_.end();
325 ++it) {
328 alt.push_back(valt);
329 }
331 } else {
332 QString valTxt =
value->toString().c_str();
333 if (typeInfo && typeInfo->
parser()) {
335 } else {
338 }
339 if (valTxt == "type=\"Struct\"") {
341 ignoreValue = true;
342 }
343 }
344 }
345
346
347 if (isStructureEntry) {
348 structures[schema][structName][tagName] =
v;
349 } else if (isStructureInArrayEntry) {
350 if (arraysOfStructures[schema][structName].
size() <= arrayIndex) {
351 arraysOfStructures[schema][structName].resize(arrayIndex + 1);
352 }
353
354 if (!arraysOfStructures[schema][structName][arrayIndex].contains(tagName)) {
355 arraysOfStructures[schema][structName][arrayIndex][tagName] =
v;
356 } else {
357 warnKrita <<
"WARNING: trying to overwrite tag" << tagName <<
"in" << structName << arrayIndex;
358 }
359 } else {
360 if (!ignoreValue) {
362 } else {
363 dbgMetaData <<
"Ignoring value for " << tagName <<
" " <<
v;
364 }
365 }
366 }
367 }
368
369 for (QMap<
const KisMetaData::Schema *, QMap<QString, QMap<QString, KisMetaData::Value>>>::iterator it =
370 structures.begin();
371 it != structures.end();
372 ++it) {
374 for (QMap<QString, QMap<QString, KisMetaData::Value>>::iterator it2 = it.value().begin();
375 it2 != it.value().end();
376 ++it2) {
378 }
379 }
381 arraysOfStructures.begin();
382 it != arraysOfStructures.end();
383 ++it) {
385 for (QMap<QString,
QVector<QMap<QString, KisMetaData::Value>>>::iterator it2 = it.value().begin();
386 it2 != it.value().end();
387 ++it2) {
389 QString entryName = it2.key();
394 break;
397 break;
400 break;
401 default:
403 break;
404 }
407 if (
value.isArray()) {
409 }
410 }
414 for (int i = 0; i < it2.value().size(); ++i) {
415 valueList.append(it2.value()[i]);
416 }
418 }
419 }
420 }
421
422 return true;
423}
float value(const T *src, size_t ch)
const KisMetaData::Value & value() const
BackendType type() const override
bool parseTagName(const QString &tagString, QString &structName, int &arrayIndex, QString &tagName, const KisMetaData::TypeInfo **typeInfo, const KisMetaData::Schema *schema)
int size(const Forest< T > &forest)