File indexing completed on 2025-04-20 13:38:27
0001 /*************************************************************************** 0002 exiv2plugin.cpp - description 0003 ------------------- 0004 begin : Thu Oct 9th 2008 0005 copyright : (C) 2008 by Dominik Seichter 0006 email : domseichter@web.de 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #include "exiv2plugin.h" 0019 0020 #include "../config-krename.h" 0021 0022 #include <KLocalizedString> 0023 0024 #include <exiv2/error.hpp> 0025 #include <exiv2/exif.hpp> 0026 #include <exiv2/image.hpp> 0027 #include <exiv2/iptc.hpp> 0028 #ifdef HAVE_LIBEXIV2_0_27 0029 #include <exiv2/xmp_exiv2.hpp> 0030 #else 0031 #include <exiv2/xmp.hpp> 0032 #endif 0033 #include <exiv2/tags.hpp> 0034 0035 #include "batchrenamer.h" 0036 #include "tokenhelpdialog.h" 0037 0038 using namespace Exiv2; 0039 0040 static const char *exifTags[] = { 0041 "Exif.Image.ImageWidth", 0042 "Exif.Image.ImageLength", 0043 "Exif.Image.BitsPerSample", 0044 "Exif.Image.Compression", 0045 "Exif.Image.PhotometricInterpretation", 0046 "Exif.Image.Orientation", 0047 "Exif.Image.SamplesPerPixel", 0048 "Exif.Image.PlanarConfiguration", 0049 "Exif.Image.YCbCrSubSampling", 0050 "Exif.Image.YCbCrPositioning", 0051 "Exif.Image.XResolution", 0052 "Exif.Image.YResolution", 0053 "Exif.Image.ResolutionUnit", 0054 "Exif.Image.TransferFunction", 0055 "Exif.Image.WhitePoint", 0056 "Exif.Image.PrimaryChromaticities", 0057 "Exif.Image.YCbCrCoefficients", 0058 "Exif.Image.ReferenceBlackWhite", 0059 "Exif.Image.DateTime", 0060 "Exif.Image.ImageDescription", 0061 "Exif.Image.Make", 0062 "Exif.Image.Model", 0063 "Exif.Image.Software", 0064 "Exif.Image.Artist", 0065 "Exif.Image.Copyright", 0066 "Exif.Photo.ExifVersion", 0067 "Exif.Photo.FlashpixVersion", 0068 "Exif.Photo.ColorSpace", 0069 "Exif.Photo.ComponentsConfiguration", 0070 "Exif.Photo.CompressedBitsPerPixel", 0071 "Exif.Photo.PixelXDimension", 0072 "Exif.Photo.PixelYDimension", 0073 "Exif.Photo.UserComment", 0074 "Exif.Photo.RelatedSoundFile", 0075 "Exif.Photo.DateTimeOriginal", 0076 "Exif.Photo.DateTimeDigitized", 0077 "Exif.Photo.ExposureTime", 0078 "Exif.Photo.FNumber", 0079 "Exif.Photo.ExposureProgram", 0080 "Exif.Photo.SpectralSensitivity", 0081 "Exif.Photo.ISOSpeedRatings", 0082 "Exif.Photo.OECF", 0083 "Exif.Photo.ShutterSpeedValue", 0084 "Exif.Photo.ApertureValue", 0085 "Exif.Photo.BrightnessValue", 0086 "Exif.Photo.ExposureBiasValue", 0087 "Exif.Photo.MaxApertureValue", 0088 "Exif.Photo.SubjectDistance", 0089 "Exif.Photo.MeteringMode", 0090 "Exif.Photo.LightSource", 0091 "Exif.Photo.Flash", 0092 "Exif.Photo.FocalLength", 0093 "Exif.Photo.SubjectArea", 0094 "Exif.Photo.FlashEnergy", 0095 "Exif.Photo.SpatialFrequencyResponse", 0096 "Exif.Photo.FocalPlaneXResolution", 0097 "Exif.Photo.FocalPlaneYResolution", 0098 "Exif.Photo.FocalPlaneResolutionUnit", 0099 "Exif.Photo.SubjectLocation", 0100 "Exif.Photo.ExposureIndex", 0101 "Exif.Photo.SensingMethod", 0102 "Exif.Photo.FileSource", 0103 "Exif.Photo.SceneType", 0104 "Exif.Photo.CFAPattern", 0105 "Exif.Photo.CustomRendered", 0106 "Exif.Photo.ExposureMode", 0107 "Exif.Photo.WhiteBalance", 0108 "Exif.Photo.DigitalZoomRatio", 0109 "Exif.Photo.FocalLengthIn35mmFilm", 0110 "Exif.Photo.SceneCaptureType", 0111 "Exif.Photo.GainControl", 0112 "Exif.Photo.Contrast", 0113 "Exif.Photo.Saturation", 0114 "Exif.Photo.Sharpness", 0115 "Exif.Photo.DeviceSettingDescription", 0116 "Exif.Photo.SubjectDistanceRange", 0117 "Exif.Photo.ImageUniqueID", 0118 "Exif.GPSInfo.GPSVersionID", 0119 "Exif.GPSInfo.GPSLatitude", 0120 "Exif.GPSInfo.GPSLongitude", 0121 "Exif.GPSInfo.GPSAltitudeRef", 0122 "Exif.GPSInfo.GPSAltitude", 0123 "Exif.GPSInfo.GPSTimeStamp", 0124 "Exif.GPSInfo.GPSSatellites", 0125 "Exif.GPSInfo.GPSStatus", 0126 "Exif.GPSInfo.GPSMeasureMode", 0127 "Exif.GPSInfo.GPSDOP", 0128 "Exif.GPSInfo.GPSSpeedRef", 0129 "Exif.GPSInfo.GPSSpeed", 0130 "Exif.GPSInfo.GPSTrackRef", 0131 "Exif.GPSInfo.GPSTrack", 0132 "Exif.GPSInfo.GPSImgDirectionRef", 0133 "Exif.GPSInfo.GPSImgDirection", 0134 "Exif.GPSInfo.GPSMapDatum", 0135 "Exif.GPSInfo.GPSDestLatitude", 0136 "Exif.GPSInfo.GPSDestLongitude", 0137 "Exif.GPSInfo.GPSDestBearingRef", 0138 "Exif.GPSInfo.GPSDestBearing", 0139 "Exif.GPSInfo.GPSDestDistanceRef", 0140 "Exif.GPSInfo.GPSDestDistance", 0141 "Exif.GPSInfo.GPSProcessingMethod", 0142 "Exif.GPSInfo.GPSAreaInformation", 0143 "Exif.GPSInfo.GPSDifferential", 0144 NULL 0145 }; 0146 0147 static const char *xmpTags[] = { 0148 "Xmp.tiff.ImageWidth", 0149 "Xmp.tiff.ImageLength", 0150 "Xmp.tiff.BitsPerSample", 0151 "Xmp.tiff.Compression", 0152 "Xmp.tiff.PhotometricInterpretation", 0153 "Xmp.tiff.Orientation", 0154 "Xmp.tiff.SamplesPerPixe", 0155 "Xmp.tiff.PlanarConfiguration", 0156 "Xmp.tiff.YCbCrSubSampling", 0157 "Xmp.tiff.YCbCrPositioning", 0158 "Xmp.tiff.XResolution", 0159 "Xmp.tiff.YResolution", 0160 "Xmp.tiff.ResolutionUnit", 0161 "Xmp.tiff.TransferFunction", 0162 "Xmp.tiff.WhitePoint", 0163 "Xmp.tiff.PrimaryChromaticities", 0164 "Xmp.tiff.YCbCrCoefficients", 0165 "Xmp.tiff.ReferenceBlackWhite", 0166 "Xmp.tiff.DateTime", 0167 "Xmp.dc.description", 0168 "Xmp.tiff.Make", 0169 "Xmp.tiff.Model", 0170 "Xmp.tiff.Software", 0171 "Xmp.dc.creator", 0172 "Xmp.dc.rights", 0173 "Xmp.exif.ExifVersion", 0174 "Xmp.exif.FlashpixVersion", 0175 "Xmp.exif.ColorSpace", 0176 "Xmp.exif.ComponentsConfiguration", 0177 "Xmp.exif.CompressedBitsPerPixel", 0178 "Xmp.exif.PixelXDimension", 0179 "Xmp.exif.PixelYDimension", 0180 "Xmp.exif.UserComment", 0181 "Xmp.exif.RelatedSoundFile", 0182 "Xmp.exif.DateTimeOriginal", 0183 "Xmp.exif.DateTimeDigitized", 0184 "Xmp.exif.ExposureTime", 0185 "Xmp.exif.FNumber", 0186 "Xmp.exif.ExposureProgram", 0187 "Xmp.exif.SpectralSensitivity", 0188 "Xmp.exif.ISOSpeedRatings", 0189 "Xmp.exif.OECF", 0190 "Xmp.exif.ShutterSpeedValue", 0191 "Xmp.exif.ApertureValue", 0192 "Xmp.exif.BrightnessValue", 0193 "Xmp.exif.ExposureBiasValue", 0194 "Xmp.exif.MaxApertureValue", 0195 "Xmp.exif.SubjectDistance", 0196 "Xmp.exif.MeteringMode", 0197 "Xmp.exif.LightSource", 0198 "Xmp.exif.Flash", 0199 "Xmp.exif.FocalLength", 0200 "Xmp.exif.SubjectArea", 0201 "Xmp.exif.FlashEnergy", 0202 "Xmp.exif.SpatialFrequencyResponse", 0203 "Xmp.exif.FocalPlaneXResolution", 0204 "Xmp.exif.FocalPlaneYResolution", 0205 "Xmp.exif.FocalPlaneResolutionUnit", 0206 "Xmp.exif.SubjectLocation", 0207 "Xmp.exif.ExposureIndex", 0208 "Xmp.exif.SensingMethod", 0209 "Xmp.exif.FileSource", 0210 "Xmp.exif.SceneType", 0211 "Xmp.exif.CFAPattern", 0212 "Xmp.exif.CustomRendered", 0213 "Xmp.exif.ExposureMode", 0214 "Xmp.exif.WhiteBalance", 0215 "Xmp.exif.DigitalZoomRatio", 0216 "Xmp.exif.FocalLengthIn35mmFilm", 0217 "Xmp.exif.SceneCaptureType", 0218 "Xmp.exif.GainControl", 0219 "Xmp.exif.Contrast", 0220 "Xmp.exif.Saturation", 0221 "Xmp.exif.Sharpness", 0222 "Xmp.exif.DeviceSettingDescription", 0223 "Xmp.exif.SubjectDistanceRange", 0224 "Xmp.exif.ImageUniqueID", 0225 "Xmp.exif.GPSVersionID", 0226 "Xmp.exif.GPSLatitude", 0227 "Xmp.exif.GPSLongitude", 0228 "Xmp.exif.GPSAltitudeRef", 0229 "Xmp.exif.GPSAltitude", 0230 "Xmp.exif.GPSTimeStamp", 0231 "Xmp.exif.GPSSatellites", 0232 "Xmp.exif.GPSStatus", 0233 "Xmp.exif.GPSMeasureMode", 0234 "Xmp.exif.GPSDOP", 0235 "Xmp.exif.GPSSpeedRef", 0236 "Xmp.exif.GPSSpeed", 0237 "Xmp.exif.GPSTrackRef", 0238 "Xmp.exif.GPSTrack", 0239 "Xmp.exif.GPSImgDirectionRef", 0240 "Xmp.exif.GPSImgDirection", 0241 "Xmp.exif.GPSMapDatum", 0242 "Xmp.exif.GPSDestLatitude", 0243 "Xmp.exif.GPSDestLongitude", 0244 "Xmp.exif.GPSDestBearingRef", 0245 "Xmp.exif.GPSDestBearing", 0246 "Xmp.exif.GPSDestDistanceRef", 0247 "Xmp.exif.GPSDestDistance", 0248 "Xmp.exif.GPSProcessingMethod", 0249 "Xmp.exif.GPSAreaInformation", 0250 "Xmp.exif.GPSDifferential", 0251 "Xmp.dc.title", 0252 "Xmp.photoshop.Urgency", 0253 "Xmp.photoshop.Category", 0254 "Xmp.photoshop.SupplementalCategory", 0255 "Xmp.dc.subject", 0256 "Xmp.iptc.Location", 0257 "Xmp.photoshop.Instruction", 0258 "Xmp.photoshop.DateCreated", 0259 "Xmp.dc.creator", 0260 "Xmp.photoshop.AuthorsPosition", 0261 "Xmp.photoshop.City", 0262 "Xmp.photoshop.State", 0263 "Xmp.iptc.CountryCode", 0264 "Xmp.photoshop.Country", 0265 "Xmp.photoshop.TransmissionReference", 0266 "Xmp.photoshop.Headline", 0267 "Xmp.photoshop.Credit", 0268 "Xmp.photoshop.Source", 0269 "Xmp.dc.rights", 0270 "Xmp.dc.description", 0271 "Xmp.photoshop.CaptionWriter", 0272 NULL 0273 }; 0274 0275 static const char *iptcTags[] = { 0276 "Iptc.Application2.ObjectName", 0277 "Iptc.Application2.Urgency", 0278 "Iptc.Application2.Category", 0279 "Iptc.Application2.SuppCategory", 0280 "Iptc.Application2.Keywords", 0281 "Iptc.Application2.LocationName", 0282 "Iptc.Application2.SpecialInstructions", 0283 "Iptc.Application2.DateCreated", 0284 "Iptc.Application2.Byline", 0285 "Iptc.Application2.BylineTitle", 0286 "Iptc.Application2.City", 0287 "Iptc.Application2.ProvinceState", 0288 "Iptc.Application2.CountryCode", 0289 "Iptc.Application2.CountryName", 0290 "Iptc.Application2.TransmissionReference", 0291 "Iptc.Application2.Headline", 0292 "Iptc.Application2.Credit", 0293 "Iptc.Application2.Source", 0294 "Iptc.Application2.Copyright", 0295 "Iptc.Application2.Caption", 0296 "Iptc.Application2.Writer", 0297 NULL 0298 }; 0299 0300 Exiv2Plugin::Exiv2Plugin(PluginLoader *loader) 0301 : FilePlugin(loader) 0302 { 0303 const QString prefix("exif"); 0304 const char **token; 0305 0306 this->addSupportedToken("exifComment"); 0307 //this->addSupportedToken("exifWidth"); 0308 //this->addSupportedToken("exifHeight"); 0309 m_help.append("[exifComment]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the comment of an image")); 0310 //m_help.append( "[exifWidth]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the width in pixel of an image") ); 0311 //m_help.append( "[exifHeight]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the height in pixel of an image") ); 0312 0313 // Add exif taks 0314 token = exifTags; 0315 while (*token) { 0316 ExifKey key(*token); 0317 QString help; 0318 try { 0319 help = QString::fromUtf8(key.tagLabel().c_str()); 0320 } catch (std::exception e) { 0321 help = ""; 0322 // exiv2 throws sometimes exceptions 0323 // because it tries to create std::string from NULL pointers 0324 } 0325 0326 QString cur(*token); 0327 this->addSupportedToken(prefix + cur); 0328 m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); 0329 0330 m_mapRealKeys[QString(prefix + cur).toLower()] = cur; 0331 ++token; 0332 } 0333 0334 // Add exif taks 0335 token = xmpTags; 0336 while (*token) { 0337 XmpKey key(*token); 0338 QString help; 0339 try { 0340 help = QString::fromUtf8(key.tagLabel().c_str()); 0341 } catch (std::exception e) { 0342 help = ""; 0343 // exiv2 throws sometimes exceptions 0344 // because it tries to create std::string from NULL pointers 0345 } 0346 0347 QString cur(*token); 0348 this->addSupportedToken(prefix + cur); 0349 m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); 0350 0351 m_mapRealKeys[QString(prefix + cur).toLower()] = cur; 0352 ++token; 0353 } 0354 0355 // Add exif taks 0356 token = iptcTags; 0357 while (*token) { 0358 IptcKey key(*token); 0359 QString help; 0360 try { 0361 help = QString::fromUtf8(key.tagLabel().c_str()); 0362 } catch (std::exception e) { 0363 help = ""; 0364 // exiv2 throws sometimes exceptions 0365 // because it tries to create std::string from NULL pointers 0366 } 0367 0368 QString cur(*token); 0369 this->addSupportedToken(prefix + cur); 0370 m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); 0371 0372 m_mapRealKeys[QString(prefix + cur).toLower()] = cur; 0373 ++token; 0374 } 0375 0376 m_name = i18n("Exiv2 (JPEG/TIFF Exif) Plugin"); 0377 m_comment = i18n("<qt>This plugin supports reading tags from " 0378 "JPEG and TIFF files.</qt>"); 0379 0380 m_icon = "image-x-generic"; 0381 } 0382 0383 QString Exiv2Plugin::processFile(BatchRenamer *b, int index, const QString &filenameOrToken, EPluginType) 0384 { 0385 QString token(filenameOrToken.toLower()); 0386 QString filename = (*b->files())[index].srcUrl().path(); 0387 0388 if (!this->supports(token)) { 0389 return QString(""); 0390 } 0391 0392 //const QByteArray asc = filename.toAscii(); 0393 // Use toUtf8 so that unicode filenames will work 0394 const QByteArray asc = filename.toUtf8(); 0395 std::string strFilename(asc.constData(), asc.length()); 0396 0397 try { 0398 Image::AutoPtr image = Exiv2::ImageFactory::open(strFilename); 0399 if (image.get() != nullptr && image->good()) { 0400 image->readMetadata(); 0401 0402 if (token == "exifcomment") { 0403 return QString::fromUtf8(image->comment().c_str()); 0404 } 0405 /* 0406 else if( token =="exifwidth" ) 0407 return QString::number( image->pixelWidth() ); 0408 else if( token =="exifheight" ) 0409 return QString::number( image->pixelHeight() ); 0410 */ 0411 if (token.startsWith(QLatin1String("exifexif."))) { 0412 ExifKey key(m_mapRealKeys[token].toLatin1().data()); 0413 ExifData::const_iterator it = image->exifData().findKey(key); 0414 if (it != image->exifData().end()) { 0415 std::string val = (*it).toString(); 0416 return QString::fromUtf8(val.c_str()); 0417 } 0418 } else if (token.startsWith(QLatin1String("exifxmp."))) { 0419 XmpKey key(m_mapRealKeys[token].toLatin1().data()); 0420 XmpData::const_iterator it = image->xmpData().findKey(key); 0421 if (it != image->xmpData().end()) { 0422 std::string val = (*it).toString(); 0423 return QString::fromUtf8(val.c_str()); 0424 } 0425 } else if (token.startsWith(QLatin1String("exifiptc."))) { 0426 IptcKey key(m_mapRealKeys[token].toLatin1().data()); 0427 IptcData::const_iterator it = image->iptcData().findKey(key); 0428 if (it != image->iptcData().end()) { 0429 std::string val = (*it).toString(); 0430 return QString::fromUtf8(val.c_str()); 0431 } 0432 } 0433 } 0434 } catch (std::exception &err) { 0435 return QString::fromUtf8(err.what()); 0436 } 0437 0438 return QString(""); 0439 }