bool MetaEngine::Private::saveToXMPSidecar(const QFileInfo& finfo) const { QString filePath = MetaEngine::sidecarFilePathForFile(finfo.filePath()); if (filePath.isEmpty()) { return false; } try { Exiv2::Image::AutoPtr image; image = Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, (const char*)(QFile::encodeName(filePath).constData())); return saveOperations(finfo, image); } catch( Exiv2::Error& e ) { printExiv2ExceptionError(QString::fromLatin1("Cannot save metadata to XMP sidecar using Exiv2 "), e); return false; } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; return false; } }
QString MetaEngine::Private::convertCommentValue(const Exiv2::Exifdatum& exifDatum) const { try { std::string comment; std::string charset; comment = exifDatum.toString(); // libexiv2 will prepend "charset=\"SomeCharset\" " if charset is specified // Before conversion to QString, we must know the charset, so we stay with std::string for a while if (comment.length() > 8 && comment.substr(0, 8) == "charset=") { // the prepended charset specification is followed by a blank std::string::size_type pos = comment.find_first_of(' '); if (pos != std::string::npos) { // extract string between the = and the blank charset = comment.substr(8, pos-8); // get the rest of the string after the charset specification comment = comment.substr(pos+1); } } if (charset == "\"Unicode\"") { return QString::fromUtf8(comment.data()); } else if (charset == "\"Jis\"") { QTextCodec* const codec = QTextCodec::codecForName("JIS7"); return codec->toUnicode(comment.c_str()); } else if (charset == "\"Ascii\"") { return QString::fromLatin1(comment.c_str()); } else { return detectEncodingAndDecode(comment); } } catch( Exiv2::Error& e ) { printExiv2ExceptionError(QString::fromLatin1("Cannot convert Comment using Exiv2 "), e); } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; } return QString(); }
int MetaEngine::Private::getXMPTagsListFromPrefix(const QString& pf, MetaEngine::TagsMap& tagsMap) const { int i = 0; #ifdef _XMP_SUPPORT_ try { QList<const Exiv2::XmpPropertyInfo*> tags; tags << Exiv2::XmpProperties::propertyList(pf.toLatin1().data()); for (QList<const Exiv2::XmpPropertyInfo*>::iterator it = tags.begin(); it != tags.end(); ++it) { while ( (*it) && !QString::fromLatin1((*it)->name_).isNull() ) { QString key = QLatin1String( Exiv2::XmpKey( pf.toLatin1().data(), (*it)->name_ ).key().c_str() ); QStringList values; values << QString::fromLatin1((*it)->name_) << QString::fromLatin1((*it)->title_) << QString::fromLatin1((*it)->desc_); tagsMap.insert(key, values); ++(*it); i++; } } } catch( Exiv2::Error& e ) { printExiv2ExceptionError(QString::fromLatin1("Cannot get Xmp tags list using Exiv2 "), e); } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; } #else Q_UNUSED(pf); Q_UNUSED(tagsMap); #endif // _XMP_SUPPORT_ return i; }
bool KExiv2::Private::saveToXMPSidecar(const QFileInfo& finfo) const { QString filePath = KExiv2::sidecarFilePathForFile(finfo.filePath()); if (filePath.isEmpty()) { return false; } try { Exiv2::Image::AutoPtr image; image = Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, (const char*)(QFile::encodeName(filePath))); return saveOperations(finfo, image); } catch( Exiv2::Error& e ) { printExiv2ExceptionError("Cannot save metadata to XMP sidecar using Exiv2 ", e); return false; } }
bool KExiv2::Private::saveToFile(const QFileInfo& finfo) const { if (!finfo.isWritable()) { kDebug() << "File '" << finfo.fileName().toAscii().constData() << "' is read only. Metadata not written."; return false; } QStringList rawTiffBasedSupported, rawTiffBasedNotSupported; // Raw files supported by Exiv2 0.21 rawTiffBasedSupported << "dng" << "nef" << "pef" << "orf" << "srw"; if (Exiv2::testVersion(0,23,0)) { rawTiffBasedSupported << "cr2"; } // Raw files not supported by Exiv2 0.21 rawTiffBasedNotSupported << "3fr" << "arw" << "cr2" << "dcr" << "erf" << "k25" << "kdc" << "mos" << "raw" << "sr2" << "srf" << "rw2"; if (!Exiv2::testVersion(0,23,0)) { rawTiffBasedNotSupported << "cr2"; } QString ext = finfo.suffix().toLower(); if (!writeRawFiles && (rawTiffBasedSupported.contains(ext) || rawTiffBasedNotSupported.contains(ext)) ) { kDebug() << finfo.fileName() << "is a TIFF based RAW file, writing to such a file is disabled by current settings."; return false; } /* if (rawTiffBasedNotSupported.contains(ext)) { kDebug() << finfo.fileName() << "is TIFF based RAW file not yet supported. Metadata not saved."; return false; } if (rawTiffBasedSupported.contains(ext) && !writeRawFiles) { kDebug() << finfo.fileName() << "is TIFF based RAW file supported but writing mode is disabled. " << "Metadata not saved."; return false; } kDebug() << "File Extension: " << ext << " is supported for writing mode"; bool ret = false; */ try { Exiv2::Image::AutoPtr image; image = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(finfo.filePath()))); return saveOperations(finfo, image); } catch( Exiv2::Error& e ) { printExiv2ExceptionError("Cannot save metadata to image using Exiv2 ", e); return false; } }
bool KExiv2::Private::saveOperations(const QFileInfo& finfo, Exiv2::Image::AutoPtr image) const { try { Exiv2::AccessMode mode; bool wroteComment = false, wroteEXIF = false, wroteIPTC = false, wroteXMP = false; // We need to load target file metadata to merge with new one. It's mandatory with TIFF format: // like all tiff file structure is based on Exif. image->readMetadata(); // Image Comments --------------------------------- mode = image->checkMode(Exiv2::mdComment); if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite)) { image->setComment(imageComments()); wroteComment = true; } // Exif metadata ---------------------------------- mode = image->checkMode(Exiv2::mdExif); if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite)) { if (image->mimeType() == "image/tiff") { Exiv2::ExifData orgExif = image->exifData(); Exiv2::ExifData newExif; QStringList untouchedTags; // With tiff image we cannot overwrite whole Exif data as well, because // image data are stored in Exif container. We need to take a care about // to not lost image data. untouchedTags << "Exif.Image.ImageWidth"; untouchedTags << "Exif.Image.ImageLength"; untouchedTags << "Exif.Image.BitsPerSample"; untouchedTags << "Exif.Image.Compression"; untouchedTags << "Exif.Image.PhotometricInterpretation"; untouchedTags << "Exif.Image.FillOrder"; untouchedTags << "Exif.Image.SamplesPerPixel"; untouchedTags << "Exif.Image.StripOffsets"; untouchedTags << "Exif.Image.RowsPerStrip"; untouchedTags << "Exif.Image.StripByteCounts"; untouchedTags << "Exif.Image.XResolution"; untouchedTags << "Exif.Image.YResolution"; untouchedTags << "Exif.Image.PlanarConfiguration"; untouchedTags << "Exif.Image.ResolutionUnit"; for (Exiv2::ExifData::iterator it = orgExif.begin(); it != orgExif.end(); ++it) { if (untouchedTags.contains(it->key().c_str())) { newExif[it->key().c_str()] = orgExif[it->key().c_str()]; } } Exiv2::ExifData readedExif = exifMetadata(); for (Exiv2::ExifData::iterator it = readedExif.begin(); it != readedExif.end(); ++it) { if (!untouchedTags.contains(it->key().c_str())) { newExif[it->key().c_str()] = readedExif[it->key().c_str()]; } } image->setExifData(newExif); } else { image->setExifData(exifMetadata()); } wroteEXIF = true; } // Iptc metadata ---------------------------------- mode = image->checkMode(Exiv2::mdIptc); if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite)) { image->setIptcData(iptcMetadata()); wroteIPTC = true; } // Xmp metadata ----------------------------------- mode = image->checkMode(Exiv2::mdXmp); if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite)) { #ifdef _XMP_SUPPORT_ image->setXmpData(xmpMetadata()); wroteXMP = true; #endif } if (!wroteComment && !wroteEXIF && !wroteIPTC && !wroteXMP) { kDebug() << "Writing metadata is not supported for file" << finfo.fileName(); return false; } else if (!wroteEXIF || !wroteIPTC || !wroteXMP) { kDebug() << "Support for writing metadata is limited for file" << finfo.fileName() << "EXIF" << wroteEXIF << "IPTC" << wroteIPTC << "XMP" << wroteXMP; } if (!updateFileTimeStamp) { // Don't touch access and modification timestamp of file. struct stat st; ::stat(QFile::encodeName(filePath), &st); struct utimbuf ut; ut.modtime = st.st_mtime; ut.actime = st.st_atime; image->writeMetadata(); ::utime(QFile::encodeName(filePath), &ut); } else { image->writeMetadata(); } return true; } catch( Exiv2::Error& e ) { printExiv2ExceptionError("Cannot save metadata using Exiv2 ", e); } return false; }
bool MetaEngine::Private::saveToFile(const QFileInfo& finfo) const { if (!finfo.isWritable()) { qCDebug(DIGIKAM_METAENGINE_LOG) << "File" << finfo.fileName() << "is read only. Metadata not written."; return false; } QStringList rawTiffBasedSupported, rawTiffBasedNotSupported; // Raw files supported by Exiv2 0.21 rawTiffBasedSupported << QString::fromLatin1("dng") << QString::fromLatin1("nef") << QString::fromLatin1("pef") << QString::fromLatin1("orf") << QString::fromLatin1("srw"); if (Exiv2::testVersion(0,23,0)) { rawTiffBasedSupported << QString::fromLatin1("cr2"); } // Raw files not supported by Exiv2 0.21 rawTiffBasedNotSupported << QString::fromLatin1("3fr") << QString::fromLatin1("arw") << QString::fromLatin1("dcr") << QString::fromLatin1("erf") << QString::fromLatin1("k25") << QString::fromLatin1("kdc") << QString::fromLatin1("mos") << QString::fromLatin1("raw") << QString::fromLatin1("sr2") << QString::fromLatin1("srf") << QString::fromLatin1("rw2"); if (!Exiv2::testVersion(0,23,0)) { rawTiffBasedNotSupported << QString::fromLatin1("cr2"); } QString ext = finfo.suffix().toLower(); if (!writeRawFiles && (rawTiffBasedSupported.contains(ext) || rawTiffBasedNotSupported.contains(ext)) ) { qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName() << "is a TIFF based RAW file, writing to such a file is disabled by current settings."; return false; } /* if (rawTiffBasedNotSupported.contains(ext)) { qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName() << "is TIFF based RAW file not yet supported. Metadata not saved."; return false; } if (rawTiffBasedSupported.contains(ext) && !writeRawFiles) { qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName() << "is TIFF based RAW file supported but writing mode is disabled. " << "Metadata not saved."; return false; } qCDebug(DIGIKAM_METAENGINE_LOG) << "File Extension: " << ext << " is supported for writing mode"; bool ret = false; */ try { Exiv2::Image::AutoPtr image; image = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(finfo.filePath()).constData())); return saveOperations(finfo, image); } catch( Exiv2::Error& e ) { printExiv2ExceptionError(QString::fromLatin1("Cannot save metadata to image using Exiv2 "), e); return false; } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; return false; } }