231{
232 ioDevice->open(QIODevice::ReadOnly);
234 std::string xmpPacket_;
235 QByteArray arr = ioDevice->readAll();
236 xmpPacket_.assign(arr.data(), arr.length());
238
239 Exiv2::XmpData xmpData_;
240 if (Exiv2::XmpParser::decode(xmpData_, xmpPacket_) != 0) {
242 return false;
243 }
244 QMap<const KisMetaData::Schema *, QMap<QString, QMap<QString, KisMetaData::Value>>> structures;
245 QMap<const KisMetaData::Schema *, QMap<QString, QVector<QMap<QString, KisMetaData::Value>>>> arraysOfStructures;
246 for (Exiv2::XmpData::iterator it = xmpData_.begin(); it != xmpData_.end(); ++it) {
247 dbgMetaData <<
"Start iteration" << it->key().c_str();
248
249 Exiv2::XmpKey key(it->key());
250 dbgMetaData << key.groupName().c_str() <<
" " << key.tagName().c_str() <<
" " << key.ns().c_str();
251 if ((key.groupName() == "exif" || key.groupName() == "tiff")
252 && key.tagName() == "NativeDigest") {
253
254
256 } else {
259 if (!schema) {
261 if (!schema) {
263 Q_ASSERT(schema);
264 }
265 }
266#if EXIV2_TEST_VERSION(0,28,0)
267 const Exiv2::Value::UniquePtr
value = it->getValue();
268#else
269 const Exiv2::Value::AutoPtr
value = it->getValue();
270#endif
271 QString structName;
272 int arrayIndex = -1;
273 QString tagName;
275
276 if (!
parseTagName(key.tagName().c_str(), structName, arrayIndex, tagName, &typeInfo, schema))
277 continue;
278
279 bool isStructureEntry = !structName.isEmpty() && arrayIndex == -1;
280 bool isStructureInArrayEntry = !structName.isEmpty() && arrayIndex != -1;
281 Q_ASSERT(isStructureEntry != isStructureInArrayEntry || !isStructureEntry);
282
284 bool ignoreValue = false;
285
286 if (
value->typeId() == Exiv2::xmpBag ||
value->typeId() == Exiv2::xmpSeq
287 ||
value->typeId() == Exiv2::xmpAlt) {
289 if (typeInfo) {
291 }
293 if (embeddedTypeInfo) {
294 parser = embeddedTypeInfo->
parser();
295 }
296 const Exiv2::XmpArrayValue *xav =
dynamic_cast<const Exiv2::XmpArrayValue *
>(
value.get());
297 Q_ASSERT(xav);
299#if EXIV2_TEST_VERSION(0,28,0)
300 for (size_t i = 0; i < xav->count(); ++i) {
301#else
302 for (int i = 0; i < xav->count(); ++i) {
303#endif
304 QString
value = QString::fromStdString(xav->toString(i));
305 if (parser) {
307 } else {
308 dbgImage <<
"No parser " << tagName;
310 }
311 }
313 switch (xav->xmpArrayType()) {
314 case Exiv2::XmpValue::xaNone:
315 warnKrita <<
"KisXMPIO: Unsupported array";
316 break;
317 case Exiv2::XmpValue::xaAlt:
319 break;
320 case Exiv2::XmpValue::xaBag:
322 break;
323 case Exiv2::XmpValue::xaSeq:
325 break;
326 }
328 }
else if (
value->typeId() == Exiv2::langAlt) {
329 const Exiv2::LangAltValue *xav =
dynamic_cast<const Exiv2::LangAltValue *
>(
value.get());
331
333 for (std::map<std::string, std::string>::const_iterator it = xav->value_.begin();
334 it != xav->value_.end();
335 ++it) {
338 alt.push_back(valt);
339 }
341 } else {
342 QString valTxt =
value->toString().c_str();
343 if (typeInfo && typeInfo->
parser()) {
345 } else {
348 }
349 if (valTxt == "type=\"Struct\"") {
351 ignoreValue = true;
352 }
353 }
354 }
355
356
357 if (isStructureEntry) {
358 structures[schema][structName][tagName] =
v;
359 } else if (isStructureInArrayEntry) {
360 if (arraysOfStructures[schema][structName].
size() <= arrayIndex) {
361 arraysOfStructures[schema][structName].resize(arrayIndex + 1);
362 }
363
364 if (!arraysOfStructures[schema][structName][arrayIndex].contains(tagName)) {
365 arraysOfStructures[schema][structName][arrayIndex][tagName] =
v;
366 } else {
367 warnKrita <<
"WARNING: trying to overwrite tag" << tagName <<
"in" << structName << arrayIndex;
368 }
369 } else {
370 if (!ignoreValue) {
372 } else {
373 dbgMetaData <<
"Ignoring value for " << tagName <<
" " <<
v;
374 }
375 }
376 }
377 }
378
379 for (QMap<
const KisMetaData::Schema *, QMap<QString, QMap<QString, KisMetaData::Value>>>::iterator it =
380 structures.begin();
381 it != structures.end();
382 ++it) {
384 for (QMap<QString, QMap<QString, KisMetaData::Value>>::iterator it2 = it.value().begin();
385 it2 != it.value().end();
386 ++it2) {
388 }
389 }
391 arraysOfStructures.begin();
392 it != arraysOfStructures.end();
393 ++it) {
395 for (QMap<QString,
QVector<QMap<QString, KisMetaData::Value>>>::iterator it2 = it.value().begin();
396 it2 != it.value().end();
397 ++it2) {
399 QString entryName = it2.key();
404 break;
407 break;
410 break;
411 default:
413 break;
414 }
417 if (
value.isArray()) {
419 }
420 }
424 for (int i = 0; i < it2.value().size(); ++i) {
425 valueList.append(it2.value()[i]);
426 }
428 }
429 }
430 }
431
432 return true;
433}
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)