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(); }
Iptcdatum& IptcData::operator[](const std::string& key) { IptcKey iptcKey(key); iterator pos = findKey(iptcKey); if (pos == end()) { add(Iptcdatum(iptcKey)); pos = findKey(iptcKey); } return *pos; }
// Always creates a new metadata entry. // Passing invalidTypeId causes the type to be guessed. // Guessing types is accurate for IPTC, but not for EXIF. // Returns 0 on success EXIVSIMPLE_API int AddMeta(HIMAGE img, const char *key, const char *val, DllTypeId type) { assert(img && key && val); if (img==0 || key==0 || val==0) return -1; ImageWrapper *imgWrap = (ImageWrapper*)img; int rc = 2; Exiv2::IptcData &iptcData = imgWrap->image->iptcData(); Exiv2::ExifData &exifData = imgWrap->image->exifData(); std::string data(val); { size_t dataLen = data.length(); // if data starts and ends with quotes, remove them if (dataLen > 1 && *(data.begin()) == '\"' && *(data.rbegin()) == '\"') { data = data.substr(1, dataLen-2); } } try { Exiv2::IptcKey iptcKey(key); rc = 1; if (type == invalidTypeId) type = (DllTypeId)Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); Exiv2::Value::AutoPtr value = Exiv2::Value::create((Exiv2::TypeId)type); value->read(data); rc = iptcData.add(iptcKey, value.get()); } catch(const Exiv2::AnyError&) { } if (rc) { // Failed with iptc, so try exif try { Exiv2::ExifKey exifKey(key); rc = 1; // No way to get value type for exif... string is the most common if (type == invalidTypeId) type = asciiString; Exiv2::Value::AutoPtr value = Exiv2::Value::create((Exiv2::TypeId)type); value->read(data); exifData.add(exifKey, value.get()); rc = 0; } catch(const Exiv2::AnyError&) { } } return rc; }
// This is weird because iptc and exif have not been "unified". Once // they are unified, this DLL should not have to know // about either... just generic images, keys, values, etc. // // buffsize should be the total size of *buff (including space for null) // Note that if there is more than one entry (for some IPTC datasets) this // returns the first one found. Currently no way to get the others. // Returns 0 on success EXIVSIMPLE_API int ReadMeta(HIMAGE img, const char *key, char *buff, int buffsize) { assert(img && key && buff); if (img==0 || key==0 || buff==0 || buffsize==0) return -1; ImageWrapper *imgWrap = (ImageWrapper*)img; int rc = 2; Exiv2::IptcData &iptcData = imgWrap->image->iptcData(); Exiv2::ExifData &exifData = imgWrap->image->exifData(); try { // First try iptc Exiv2::IptcKey iptcKey(key); rc = 1; Exiv2::IptcData::const_iterator iter = iptcData.findKey(iptcKey); if (iter != iptcData.end()) { strncpy(buff, iter->value().toString().c_str(), buffsize); buff[buffsize-1] = 0; rc = 0; } } catch(const Exiv2::AnyError&) { } if (rc) { // No iptc value, so try exif try { Exiv2::ExifKey exifKey(key); rc = 1; Exiv2::ExifData::const_iterator iter = exifData.findKey(exifKey); if (iter != exifData.end()) { strncpy(buff, iter->value().toString().c_str(), buffsize); buff[buffsize-1] = 0; rc = 0; } } catch(const Exiv2::AnyError&) { } } return rc; }
// If multiple entires exist, this only remove the first one // found. Call multiple times to remove many. // Returns 0 on success EXIVSIMPLE_API int RemoveMeta(HIMAGE img, const char *key) { assert(img && key); if (img==0 || key==0) return -1; ImageWrapper *imgWrap = (ImageWrapper*)img; int rc = 2; Exiv2::IptcData &iptcData = imgWrap->image->iptcData(); Exiv2::ExifData &exifData = imgWrap->image->exifData(); try { Exiv2::IptcKey iptcKey(key); rc = 1; Exiv2::IptcData::iterator iter = iptcData.findKey(iptcKey); if (iter != iptcData.end()) { iptcData.erase(iter); rc = 0; } } catch(const Exiv2::AnyError&) { } if (rc) { // No iptc value, so try exif try { Exiv2::ExifKey exifKey(key); rc = 1; Exiv2::ExifData::iterator iter = exifData.findKey(exifKey); if (iter != exifData.end()) { exifData.erase(iter); rc = 0; } } catch(const Exiv2::AnyError&) { } } return rc; }
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(); }
// Overwrites existing value if found, otherwise creates a new one. // Passing invalidTypeId causes the type to be guessed. // Guessing types is accurate for IPTC, but not for EXIF. // Returns 0 on success EXIVSIMPLE_API int ModifyMeta(HIMAGE img, const char *key, const char *val, DllTypeId type) { assert(img && key && val); if (img==0 || key==0 || val==0) return -1; ImageWrapper *imgWrap = (ImageWrapper*)img; int rc = 2; Exiv2::IptcData &iptcData = imgWrap->image->iptcData(); Exiv2::ExifData &exifData = imgWrap->image->exifData(); std::string data(val); // if data starts and ends with quotes, remove them if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') { data = data.substr(1, data.size()-2); } try { Exiv2::IptcKey iptcKey(key); rc = 1; if (type == invalidTypeId) type = (DllTypeId)Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); Exiv2::Value::AutoPtr value = Exiv2::Value::create((Exiv2::TypeId)type); value->read(data); Exiv2::IptcData::iterator iter = iptcData.findKey(iptcKey); if (iter != iptcData.end()) { iter->setValue(value.get()); rc = 0; } else { rc = iptcData.add(iptcKey, value.get()); } } catch(const Exiv2::AnyError&) { } if (rc) { // Failed with iptc, so try exif try { Exiv2::ExifKey exifKey(key); rc = 1; // No way to get value type for exif... string is the most common if (type == invalidTypeId) type = asciiString; Exiv2::Value::AutoPtr value = Exiv2::Value::create((Exiv2::TypeId)type); value->read(data); Exiv2::ExifData::iterator iter = exifData.findKey(exifKey); if (iter != exifData.end()) { iter->setValue(value.get()); rc = 0; } else { exifData.add(exifKey, value.get()); rc = 0; } } catch(const Exiv2::AnyError&) { } } return rc; }