KisMetaData::Value deviceSettingDescriptionExifToKMD(const Exiv2::Value::AutoPtr value) { QMap<QString, KisMetaData::Value> deviceSettingStructure; QByteArray array; const Exiv2::DataValue* dvalue = dynamic_cast<const Exiv2::DataValue*>(&*value); if(dvalue) { array.resize(dvalue->count()); dvalue->copy((Exiv2::byte*)array.data()); } else { Q_ASSERT(value->typeId() == Exiv2::unsignedShort); array.resize(2 * value->count()); value->copy((Exiv2::byte*)array.data(), Exiv2::littleEndian); } int columns = (reinterpret_cast<quint16*>(array.data()))[0]; int rows = (reinterpret_cast<quint16*>(array.data()))[1]; deviceSettingStructure["Columns"] = KisMetaData::Value(columns); deviceSettingStructure["Rows"] = KisMetaData::Value(rows); QList<KisMetaData::Value> settings; QByteArray null(2, 0); for (int index = 4; index < array.size(); ) { int lastIndex = array.indexOf(null, index); QString setting = QString::fromUtf16((ushort*)(void*)( array.data() + index), lastIndex - index + 2); index = lastIndex + 2; dbgFile << "Setting << " << setting; settings.append(KisMetaData::Value(setting)); } deviceSettingStructure["Settings"] = KisMetaData::Value(settings, KisMetaData::Value::OrderedArray); return KisMetaData::Value(deviceSettingStructure); }
// Convert an exiv value to a KisMetaData value KisMetaData::Value exivValueToKMDValue(const Exiv2::Value::AutoPtr value, bool forceSeq, KisMetaData::Value::ValueType arrayType) { switch (value->typeId()) { case Exiv2::signedByte: case Exiv2::invalidTypeId: case Exiv2::lastTypeId: case Exiv2::directory: dbgFile << "Invalid value :" << value->typeId() << " value =" << value->toString().c_str(); return KisMetaData::Value(); case Exiv2::undefined: { dbgFile << "Undefined value :" << value->typeId() << " value =" << value->toString().c_str(); QByteArray array(value->count() , 0); value->copy((Exiv2::byte*)array.data(), Exiv2::invalidByteOrder); return KisMetaData::Value(QString(array.toBase64())); } case Exiv2::unsignedByte: case Exiv2::unsignedShort: case Exiv2::unsignedLong: case Exiv2::signedShort: case Exiv2::signedLong: { if (value->count() == 1 && !forceSeq) { return KisMetaData::Value((int)value->toLong()); } else { QList<KisMetaData::Value> array; for (int i = 0; i < value->count(); i++) array.push_back(KisMetaData::Value((int)value->toLong(i))); return KisMetaData::Value(array, arrayType); } } case Exiv2::asciiString: case Exiv2::string: case Exiv2::comment: // look at kexiv2 for the problem about decoding correctly that tag return KisMetaData::Value(value->toString().c_str()); case Exiv2::unsignedRational: if(value->size() < 2) { dbgFile << "Invalid size :" << value->size() << " value =" << value->toString().c_str(); return KisMetaData::Value(); } return KisMetaData::Value(KisMetaData::Rational(value->toRational().first , value->toRational().second)); case Exiv2::signedRational: if(value->size() < 2) { dbgFile << "Invalid size :" << value->size() << " value =" << value->toString().c_str(); return KisMetaData::Value(); } return KisMetaData::Value(KisMetaData::Rational(value->toRational().first , value->toRational().second)); case Exiv2::date: case Exiv2::time: return KisMetaData::Value(QDateTime::fromString(value->toString().c_str(), Qt::ISODate)); case Exiv2::xmpText: case Exiv2::xmpAlt: case Exiv2::xmpBag: case Exiv2::xmpSeq: case Exiv2::langAlt: default: { dbgFile << "Unknown type id :" << value->typeId() << " value =" << value->toString().c_str(); //Q_ASSERT(false); // This point must never be reached ! return KisMetaData::Value(); } } dbgFile << "Unknown type id :" << value->typeId() << " value =" << value->toString().c_str(); //Q_ASSERT(false); // This point must never be reached ! return KisMetaData::Value(); }