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(); }
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 getIptcKeywords(Exiv2::IptcData &iptcData, bool isIptcUtf8, QStringList &keywords) { bool anyAdded = false; try { QString keywordsTagName = QString::fromLatin1(IPTC_KEYWORDS); for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it) { QString key = QString::fromLocal8Bit(it->key().c_str()); if (key == keywordsTagName) { QString tag; if (isIptcUtf8) { tag = QString::fromUtf8(it->toString().c_str()); } else { tag = QString::fromLocal8Bit(it->toString().c_str()); } keywords.append(tag); anyAdded = true; } } if (keywords.length() == 1 && keywords[0].contains(',')) { LOG_DEBUG << "processing legacy saved keywords"; QString composite = keywords[0]; keywords.clear(); keywords += decomposeKeyword(composite); } } catch (Exiv2::Error &e) { LOG_WARNING << "Exiv2 error:" << e.what(); anyAdded = false; } catch (...) { LOG_WARNING << "Exception"; anyAdded = false; #ifdef QT_DEBUG throw; #endif } return anyAdded; }
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; }
gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag) { g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL); g_return_val_if_fail(tag != NULL, NULL); g_return_val_if_fail(self->priv->image.get() != NULL, NULL); Exiv2::IptcData& iptc_data = self->priv->image->iptcData(); try { Exiv2::IptcData::iterator it = iptc_data.findKey(Exiv2::IptcKey(tag)); while (it != iptc_data.end() && it->count() == 0) it++; if (it != iptc_data.end()) return g_strdup (it->toString ().c_str ()); } catch (Exiv2::Error& e) { LOG_ERROR(e); } return NULL; }
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(); }