QStringList KExiv2::getIptcSubCategories() const { try { if (!d->iptcMetadata().empty()) { QStringList subCategories; Exiv2::IptcData iptcData(d->iptcMetadata()); for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it) { QString key = QString::fromLocal8Bit(it->key().c_str()); if (key == QString("Iptc.Application2.SuppCategory")) { QString val(it->toString().c_str()); subCategories.append(val); } } return subCategories; } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError("Cannot get Iptc Sub Categories from image using Exiv2 ", e); } return QStringList(); }
QStringList KExiv2::getIptcTagsStringList(const char* iptcTagName, bool escapeCR) const { try { if (!d->iptcMetadata().empty()) { QStringList values; Exiv2::IptcData iptcData(d->iptcMetadata()); for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it) { QString key = QString::fromLocal8Bit(it->key().c_str()); if (key == QString(iptcTagName)) { QString tagValue(it->toString().c_str()); if (escapeCR) tagValue.replace('\n', ' '); values.append(tagValue); } } return values; } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError(QString("Cannot find Iptc key '%1' into image using Exiv2 ") .arg(iptcTagName), e); } return QStringList(); }
QString KExiv2::getIptcTagString(const char* iptcTagName, bool escapeCR) const { try { Exiv2::IptcKey iptcKey(iptcTagName); Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcData::iterator it = iptcData.findKey(iptcKey); if (it != iptcData.end()) { std::ostringstream os; os << *it; QString tagValue(os.str().c_str()); if (escapeCR) tagValue.replace('\n', ' '); return tagValue; } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError(QString("Cannot find Iptc key '%1' into image using Exiv2 ") .arg(iptcTagName), e); } return QString(); }
bool KExiv2::setIptcTagsStringList(const char* iptcTagName, int maxSize, const QStringList& oldValues, const QStringList& newValues, bool setProgramName) const { if (!setProgramId(setProgramName)) return false; try { QStringList oldvals = oldValues; QStringList newvals = newValues; kDebug() << d->filePath.toAscii().constData() << " : " << iptcTagName << " => " << newvals.join(",").toAscii().constData(); // Remove all old values. Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcData::iterator it = iptcData.begin(); while(it != iptcData.end()) { QString key = QString::fromLocal8Bit(it->key().c_str()); QString val(it->toString().c_str()); // Also remove new values to avoid duplicates. They will be added again below. if ( key == QString(iptcTagName) && (oldvals.contains(val) || newvals.contains(val)) ) it = iptcData.erase(it); else ++it; }; // Add new values. Exiv2::IptcKey iptcTag(iptcTagName); for (QStringList::iterator it = newvals.begin(); it != newvals.end(); ++it) { QString key = *it; key.truncate(maxSize); Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string); val->read(key.toLatin1().constData()); iptcData.add(iptcTag, val.get()); } d->iptcMetadata() = iptcData; return true; } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError(QString("Cannot set Iptc key '%1' into image using Exiv2 ") .arg(iptcTagName), e); } return false; }
bool KExiv2::setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords, bool setProgramName) const { if (!setProgramId(setProgramName)) return false; try { QStringList oldkeys = oldKeywords; QStringList newkeys = newKeywords; kDebug() << d->filePath.toAscii().constData() << " ==> Iptc Keywords: " << newkeys.join(",").toAscii().constData(); // Remove all old keywords. Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcData::iterator it = iptcData.begin(); while(it != iptcData.end()) { QString key = QString::fromLocal8Bit(it->key().c_str()); QString val(it->toString().c_str()); // Also remove new keywords to avoid duplicates. They will be added again below. if ( key == QString("Iptc.Application2.Keywords") && (oldKeywords.contains(val) || newKeywords.contains(val)) ) it = iptcData.erase(it); else ++it; }; // Add new keywords. Note that Keywords Iptc tag is limited to 64 char but can be redondant. Exiv2::IptcKey iptcTag("Iptc.Application2.Keywords"); for (QStringList::iterator it = newkeys.begin(); it != newkeys.end(); ++it) { QString key = *it; key.truncate(64); Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string); val->read(key.toLatin1().constData()); iptcData.add(iptcTag, val.get()); } d->iptcMetadata() = iptcData; return true; } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError("Cannot set Iptc Keywords into image using Exiv2 ", e); } return false; }
bool KExiv2::setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories, bool setProgramName) const { if (!setProgramId(setProgramName)) return false; try { QStringList oldkeys = oldSubCategories; QStringList newkeys = newSubCategories; // Remove all old Sub Categories. Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcData::iterator it = iptcData.begin(); while(it != iptcData.end()) { QString key = QString::fromLocal8Bit(it->key().c_str()); QString val(it->toString().c_str()); if (key == QString("Iptc.Application2.SuppCategory") && oldSubCategories.contains(val)) it = iptcData.erase(it); else ++it; }; // Add new Sub Categories. Note that SubCategories Iptc tag is limited to 32 // characters but can be redondant. Exiv2::IptcKey iptcTag("Iptc.Application2.SuppCategory"); for (QStringList::iterator it = newkeys.begin(); it != newkeys.end(); ++it) { QString key = *it; key.truncate(32); Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string); val->read(key.toLatin1().constData()); iptcData.add(iptcTag, val.get()); } d->iptcMetadata() = iptcData; return true; } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError("Cannot set Iptc Sub Categories into image using Exiv2 ", e); } return false; }
void PgfImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::PgfImage::readMetadata: Reading PGF file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isPgfType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "PGF"); } clearMetadata(); readPgfMagicNumber(*io_); uint32_t headerSize = readPgfHeaderSize(*io_); readPgfHeaderStructure(*io_, &pixelWidth_, &pixelHeight_); // And now, the most interresting, the user data byte array where metadata are stored as small image. long size = 8 + headerSize - io_->tell(); #ifdef DEBUG std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; #endif if (size < 0) throw Error(20); if (size == 0) return; DataBuf imgData(size); std::memset(imgData.pData_, 0x0, imgData.size_); long bufRead = io_->read(imgData.pData_, imgData.size_); if (io_->error()) throw Error(14); if (bufRead != imgData.size_) throw Error(20); Image::AutoPtr image = Exiv2::ImageFactory::open(imgData.pData_, imgData.size_); image->readMetadata(); exifData() = image->exifData(); iptcData() = image->iptcData(); xmpData() = image->xmpData(); } // PgfImage::readMetadata
QByteArray KExiv2::getIptcTagData(const char* iptcTagName) const { try { Exiv2::IptcKey iptcKey(iptcTagName); Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcData::iterator it = iptcData.findKey(iptcKey); if (it != iptcData.end()) { char *s = new char[(*it).size()]; (*it).copy((Exiv2::byte*)s, Exiv2::bigEndian); QByteArray data(s, (*it).size()); delete [] s; return data; } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError(QString("Cannot find Iptc key '%1' into image using Exiv2 ") .arg(iptcTagName), e); } return QByteArray(); }
void Jp2Image::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isJp2Type(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "JPEG-2000"); } long position = 0; Jp2BoxHeader box = {0,0}; Jp2BoxHeader subBox = {0,0}; Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0}; Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; while (io_->read((byte*)&box, sizeof(box)) == sizeof(box)) { position = io_->tell(); box.boxLength = getLong((byte*)&box.boxLength, bigEndian); #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Position: " << position << "\n"; std::cout << "Exiv2::Jp2Image::readMetadata: Find box type: " << std::string((const char*)&box.boxType) << " lenght: " << box.boxLength << "\n"; #endif box.boxType = getLong((byte*)&box.boxType, bigEndian); if (box.boxLength == 0) { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Null Box size has been found. " "This is the last box of file.\n"; #endif return; } if (box.boxLength == 1) { // FIXME. Special case. the real box size is given in another place. } switch(box.boxType) { case kJp2BoxTypeJp2Header: { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: JP2Header box found\n"; #endif if (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox)) { subBox.boxLength = getLong((byte*)&subBox.boxLength, bigEndian); subBox.boxType = getLong((byte*)&subBox.boxType, bigEndian); if((subBox.boxType == kJp2BoxTypeImageHeader) && (io_->read((byte*)&ihdr, sizeof(ihdr)) == sizeof(ihdr))) { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Ihdr data found\n"; #endif ihdr.imageHeight = getLong((byte*)&ihdr.imageHeight, bigEndian); ihdr.imageWidth = getLong((byte*)&ihdr.imageWidth, bigEndian); ihdr.componentCount = getShort((byte*)&ihdr.componentCount, bigEndian); ihdr.compressionTypeProfile = getShort((byte*)&ihdr.compressionTypeProfile, bigEndian); pixelWidth_ = ihdr.imageWidth; pixelHeight_ = ihdr.imageHeight; } } break; } case kJp2BoxTypeUuid: { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: UUID box found\n"; #endif if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid)) { DataBuf rawData; long bufRead; if(memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid)) == 0) { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found\n"; #endif // we've hit an embedded Exif block rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); if (io_->error()) throw Error(14); if (bufRead != rawData.size_) throw Error(20); if (rawData.size_ > 0) { // Find the position of Exif header in bytes array. const byte exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; long pos = -1; for (long i=0 ; i < rawData.size_-(long)sizeof(exifHeader) ; i++) { if (memcmp(exifHeader, &rawData.pData_[i], sizeof(exifHeader)) == 0) { pos = i; break; } } // If found it, store only these data at from this place. if (pos !=-1) { #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos << "\n"; #endif pos = pos + sizeof(exifHeader); ByteOrder bo = TiffParser::decode(exifData(), iptcData(), xmpData(), rawData.pData_ + pos, rawData.size_ - pos); setByteOrder(bo); } } else { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode Exif metadata.\n"; #endif exifData_.clear(); } } else if(memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid)) == 0) { // we've hit an embedded IPTC block #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found\n"; #endif rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); if (io_->error()) throw Error(14); if (bufRead != rawData.size_) throw Error(20); if (IptcParser::decode(iptcData_, rawData.pData_, rawData.size_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode IPTC metadata.\n"; #endif iptcData_.clear(); } } else if(memcmp(uuid.uuid, kJp2UuidXmp, sizeof(uuid)) == 0) { // we've hit an embedded XMP block #ifdef DEBUG std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found\n"; #endif rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); if (io_->error()) throw Error(14); if (bufRead != rawData.size_) throw Error(20); xmpPacket_.assign(reinterpret_cast<char *>(rawData.pData_), rawData.size_); std::string::size_type idx = xmpPacket_.find_first_of('<'); if (idx != std::string::npos && idx > 0) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Removing " << static_cast<uint32_t>(idx) << " characters from the beginning of the XMP packet\n"; #endif xmpPacket_ = xmpPacket_.substr(idx); } if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode XMP metadata.\n"; #endif } } } break; } default: { break; } } // Move to the next box. io_->seek(static_cast<long>(position - sizeof(box) + box.boxLength), BasicIo::beg); if (io_->error() || io_->eof()) throw Error(14); } } // Jp2Image::readMetadata
QDateTime KExiv2::getDigitizationDateTime(bool fallbackToCreationTime) const { try { // In first, trying to get Date & time from Exif tags. if (!d->exifMetadata().empty()) { // Try Exif date time digitized. Exiv2::ExifData exifData(d->exifMetadata()); Exiv2::ExifKey key("Exif.Photo.DateTimeDigitized"); Exiv2::ExifData::iterator it = exifData.findKey(key); if (it != exifData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime (Exif digitalized): " << dateTime.toString().toAscii().constData(); return dateTime; } } } // In second, trying to get Date & time from Iptc tags. if (!d->iptcMetadata().empty()) { // Try digitization Iptc date time entries. Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcKey keyDigitizationDate("Iptc.Application2.DigitizationDate"); Exiv2::IptcData::iterator it = iptcData.findKey(keyDigitizationDate); if (it != iptcData.end()) { QString IptcDateDigitization(it->toString().c_str()); Exiv2::IptcKey keyDigitizationTime("Iptc.Application2.DigitizationTime"); Exiv2::IptcData::iterator it2 = iptcData.findKey(keyDigitizationTime); if (it2 != iptcData.end()) { QString IptcTimeDigitization(it2->toString().c_str()); QDate date = QDate::fromString(IptcDateDigitization, Qt::ISODate); QTime time = QTime::fromString(IptcTimeDigitization, Qt::ISODate); QDateTime dateTime = QDateTime(date, time); if (dateTime.isValid()) { kDebug() << "Date (IPTC digitalized): " << dateTime.toString().toAscii().constData(); return dateTime; } } } } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError("Cannot parse Exif digitization date & time tag using Exiv2 ", e); } catch(...) { kError() << "Default exception from Exiv2"; } if (fallbackToCreationTime) return getImageDateTime(); else return QDateTime(); }
QDateTime KExiv2::getImageDateTime() const { try { // In first, trying to get Date & time from Exif tags. if (!d->exifMetadata().empty()) { Exiv2::ExifData exifData(d->exifMetadata()); { Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); Exiv2::ExifData::iterator it = exifData.findKey(key); if (it != exifData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Exif.Photo.DateTimeOriginal => " << dateTime; return dateTime; } } } { Exiv2::ExifKey key("Exif.Photo.DateTimeDigitized"); Exiv2::ExifData::iterator it = exifData.findKey(key); if (it != exifData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Exif.Photo.DateTimeDigitized => " << dateTime; return dateTime; } } } { Exiv2::ExifKey key("Exif.Image.DateTime"); Exiv2::ExifData::iterator it = exifData.findKey(key); if (it != exifData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Exif.Image.DateTime => " << dateTime; return dateTime; } } } } // In second, trying to get Date & time from Xmp tags. #ifdef _XMP_SUPPORT_ if (!d->xmpMetadata().empty()) { Exiv2::XmpData xmpData(d->xmpMetadata()); { Exiv2::XmpKey key("Xmp.exif.DateTimeOriginal"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.exif.DateTimeOriginal => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.exif.DateTimeDigitized"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.exif.DateTimeDigitized => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.photoshop.DateCreated"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.photoshop.DateCreated => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.xmp.CreateDate"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.xmp.CreateDate => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.tiff.DateTime"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.tiff.DateTime => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.xmp.ModifyDate"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.xmp.ModifyDate => " << dateTime; return dateTime; } } } { Exiv2::XmpKey key("Xmp.xmp.MetadataDate"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate); if (dateTime.isValid()) { kDebug() << "DateTime => Xmp.xmp.MetadataDate => " << dateTime; return dateTime; } } } } #endif // _XMP_SUPPORT_ // In third, trying to get Date & time from Iptc tags. if (!d->iptcMetadata().empty()) { Exiv2::IptcData iptcData(d->iptcMetadata()); // Try creation Iptc date & time entries. Exiv2::IptcKey keyDateCreated("Iptc.Application2.DateCreated"); Exiv2::IptcData::iterator it = iptcData.findKey(keyDateCreated); if (it != iptcData.end()) { QString IptcDateCreated(it->toString().c_str()); Exiv2::IptcKey keyTimeCreated("Iptc.Application2.TimeCreated"); Exiv2::IptcData::iterator it2 = iptcData.findKey(keyTimeCreated); if (it2 != iptcData.end()) { QString IptcTimeCreated(it2->toString().c_str()); QDate date = QDate::fromString(IptcDateCreated, Qt::ISODate); QTime time = QTime::fromString(IptcTimeCreated, Qt::ISODate); QDateTime dateTime = QDateTime(date, time); if (dateTime.isValid()) { kDebug() << "DateTime => Iptc.Application2.DateCreated => " << dateTime; return dateTime; } } } // Try digitization Iptc date & time entries. Exiv2::IptcKey keyDigitizationDate("Iptc.Application2.DigitizationDate"); Exiv2::IptcData::iterator it3 = iptcData.findKey(keyDigitizationDate); if (it3 != iptcData.end()) { QString IptcDateDigitization(it3->toString().c_str()); Exiv2::IptcKey keyDigitizationTime("Iptc.Application2.DigitizationTime"); Exiv2::IptcData::iterator it4 = iptcData.findKey(keyDigitizationTime); if (it4 != iptcData.end()) { QString IptcTimeDigitization(it4->toString().c_str()); QDate date = QDate::fromString(IptcDateDigitization, Qt::ISODate); QTime time = QTime::fromString(IptcTimeDigitization, Qt::ISODate); QDateTime dateTime = QDateTime(date, time); if (dateTime.isValid()) { kDebug() << "DateTime => Iptc.Application2.DigitizationDate => " << dateTime; return dateTime; } } } } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError("Cannot parse Exif date & time tag using Exiv2 ", e); } catch(...) { kError() << "Default exception from Exiv2"; } return QDateTime(); }
QDateTime MetaEngine::getDigitizationDateTime(bool fallbackToCreationTime) const { try { // In first, trying to get Date & time from Exif tags. if (!d->exifMetadata().empty()) { // Try Exif date time digitized. Exiv2::ExifData exifData(d->exifMetadata()); Exiv2::ExifKey key("Exif.Photo.DateTimeDigitized"); Exiv2::ExifData::iterator it = exifData.findKey(key); if (it != exifData.end()) { QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate); if (dateTime.isValid()) { qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (Exif digitalized): " << dateTime.toString().toLatin1().constData(); return dateTime; } } } // In second, we trying XMP #ifdef _XMP_SUPPORT_ if (!d->xmpMetadata().empty()) { Exiv2::XmpData xmpData(d->xmpMetadata()); { Exiv2::XmpKey key("Xmp.exif.DateTimeDigitized"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate); if (dateTime.isValid()) { qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (XMP-Exif digitalized): " << dateTime.toString().toLatin1().constData(); return dateTime; } } } { Exiv2::XmpKey key("Xmp.video.DateTimeDigitized"); Exiv2::XmpData::iterator it = xmpData.findKey(key); if (it != xmpData.end()) { QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate); if (dateTime.isValid()) { qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (XMP-Video digitalized): " << dateTime.toString().toLatin1().constData(); return dateTime; } } } } #endif // _XMP_SUPPORT_ // In third, trying to get Date & time from Iptc tags. if (!d->iptcMetadata().empty()) { // Try digitization Iptc date time entries. Exiv2::IptcData iptcData(d->iptcMetadata()); Exiv2::IptcKey keyDigitizationDate("Iptc.Application2.DigitizationDate"); Exiv2::IptcData::iterator it = iptcData.findKey(keyDigitizationDate); if (it != iptcData.end()) { QString IptcDateDigitization(QString::fromLatin1(it->toString().c_str())); Exiv2::IptcKey keyDigitizationTime("Iptc.Application2.DigitizationTime"); Exiv2::IptcData::iterator it2 = iptcData.findKey(keyDigitizationTime); if (it2 != iptcData.end()) { QString IptcTimeDigitization(QString::fromLatin1(it2->toString().c_str())); QDate date = QDate::fromString(IptcDateDigitization, Qt::ISODate); QTime time = QTime::fromString(IptcTimeDigitization, Qt::ISODate); QDateTime dateTime = QDateTime(date, time); if (dateTime.isValid()) { qCDebug(DIGIKAM_METAENGINE_LOG) << "Date (IPTC digitalized): " << dateTime.toString().toLatin1().constData(); return dateTime; } } } } } catch( Exiv2::Error& e ) { d->printExiv2ExceptionError(QString::fromLatin1("Cannot parse Exif digitization date & time tag using Exiv2 "), e); } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; } if (fallbackToCreationTime) return getImageDateTime(); else return QDateTime(); }