bool KExiv2::canWriteIptc(const QString& filePath) { try { Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((const char*) (QFile::encodeName(filePath))); Exiv2::AccessMode mode = image->checkMode(Exiv2::mdIptc); return (mode == Exiv2::amWrite || mode == Exiv2::amReadWrite); } catch( Exiv2::Error& e ) { std::string s(e.what()); kDebug() << "Cannot check Iptc access mode using Exiv2 (Error #" << e.code() << ": " << s.c_str() << ")"; } return false; }
bool MetaEngine::canWriteComment(const QString& filePath) { try { Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((const char*) (QFile::encodeName(filePath).constData())); Exiv2::AccessMode mode = image->checkMode(Exiv2::mdComment); return (mode == Exiv2::amWrite || mode == Exiv2::amReadWrite); } catch( Exiv2::Error& e ) { std::string s(e.what()); qCCritical(DIGIKAM_METAENGINE_LOG) << "Cannot check Comment access mode using Exiv2 (Error #" << e.code() << ": " << s.c_str() << ")"; } catch(...) { qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2"; } 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; }