File indexing completed on 2025-01-19 03:56:00
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2006-09-15 0007 * Description : Exiv2 library interface 0008 * Exiv2: https://www.exiv2.org 0009 * Exif : https://www.exif.org/Exif2-2.PDF 0010 * Iptc : https://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf 0011 * Xmp : https://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf 0012 * https://www.iptc.org/std/Iptc4xmpCore/1.0/specification/Iptc4xmpCore_1.0-spec-XMPSchema_8.pdf 0013 * Paper: www.metadataworkinggroup.com/pdf/mwg_guidance.pdf 0014 * 0015 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0016 * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0017 * 0018 * SPDX-License-Identifier: GPL-2.0-or-later 0019 * 0020 * ============================================================ */ 0021 0022 #ifndef DIGIKAM_META_ENGINE_H 0023 #define DIGIKAM_META_ENGINE_H 0024 0025 // QT includes 0026 0027 #include <QByteArray> 0028 #include <QString> 0029 #include <QDateTime> 0030 #include <QMap> 0031 #include <QSharedDataPointer> 0032 #include <QStringList> 0033 #include <QVariant> 0034 #include <QRegularExpression> 0035 #include <QUrl> 0036 #include <QImage> 0037 0038 // Local includes 0039 0040 #include "metaengine_data.h" 0041 #include "digikam_export.h" 0042 0043 namespace Digikam 0044 { 0045 0046 // TODO: merge with DMetadata class. 0047 0048 class DIGIKAM_EXPORT MetaEngine 0049 { 0050 0051 public: 0052 0053 /** 0054 * The item metadata writing mode, between item file metadata and XMP sidecar file, depending on the context. 0055 * @sa MetadataWritingMode(), metadataWritingMode() 0056 */ 0057 enum MetadataWritingMode 0058 { 0059 /// Write metadata to item file only. 0060 WRITE_TO_FILE_ONLY = 0, 0061 0062 /// Write metadata to sidecar file only. 0063 WRITE_TO_SIDECAR_ONLY = 1, 0064 0065 /// Write metadata to item and sidecar files. 0066 WRITE_TO_SIDECAR_AND_FILE = 2, 0067 0068 /// Write metadata to sidecar file only for read only items such as RAW files for example. 0069 WRITE_TO_SIDECAR_ONLY_FOR_READ_ONLY_FILES = 3 0070 }; 0071 0072 /** 0073 * The item color workspace values given by Exif metadata. 0074 */ 0075 enum ImageColorWorkSpace 0076 { 0077 WORKSPACE_UNSPECIFIED = 0, 0078 WORKSPACE_SRGB = 1, 0079 WORKSPACE_ADOBERGB = 2, 0080 WORKSPACE_UNCALIBRATED = 65535 0081 }; 0082 0083 /** 0084 * The item orientation values given by Exif metadata. 0085 */ 0086 enum ImageOrientation 0087 { 0088 ORIENTATION_UNSPECIFIED = 0, 0089 ORIENTATION_NORMAL = 1, 0090 ORIENTATION_HFLIP = 2, 0091 ORIENTATION_ROT_180 = 3, 0092 ORIENTATION_VFLIP = 4, 0093 ORIENTATION_ROT_90_HFLIP = 5, 0094 ORIENTATION_ROT_90 = 6, 0095 ORIENTATION_ROT_90_VFLIP = 7, 0096 ORIENTATION_ROT_270 = 8 0097 }; 0098 0099 /** 0100 * Xmp tag types, used by setXmpTag, only first three types are used 0101 */ 0102 enum XmpTagType 0103 { 0104 NormalTag = 0, 0105 ArrayBagTag = 1, 0106 StructureTag = 2, 0107 ArrayLangTag = 3, 0108 ArraySeqTag = 4 0109 }; 0110 0111 /** 0112 * Metadata Backend used to populate information. 0113 */ 0114 enum Backend 0115 { 0116 Exiv2Backend = 0, ///< Default backend used by MetaEngine. 0117 LibRawBackend, ///< DMetadata only. 0118 LibHeifBackend, ///< DMetadata only. 0119 ImageMagickBackend, ///< DMetadata only. 0120 FFMpegBackend, ///< DMetadata only. 0121 ExifToolBackend, ///< DMetadata only. 0122 VideoMergeBackend, ///< DMetadata only. 0123 NoBackend ///< No backend used (aka file cannot be read). 0124 }; 0125 0126 /** 0127 * A map used to store Tags Key and Tags Value. 0128 */ 0129 typedef QMap<QString, QString> MetaDataMap; 0130 0131 /** 0132 * A map used to store a list of Alternative Language values. 0133 * The map key is the language code following RFC3066 notation 0134 * (like "fr-FR" for French), and the map value the text. 0135 */ 0136 typedef QMap<QString, QString> AltLangMap; 0137 0138 /** 0139 * A map used to store Tags Key and a list of Tags properties : 0140 * - name, 0141 * - title, 0142 * - description. 0143 */ 0144 typedef QMap<QString, QStringList> TagsMap; 0145 0146 public: 0147 0148 /** 0149 * Standard constructor. 0150 */ 0151 MetaEngine(); 0152 0153 /** 0154 * Constructor to load from parsed data. 0155 */ 0156 explicit MetaEngine(const MetaEngineData& data); 0157 0158 /** 0159 * Constructor to Load Metadata from item file. 0160 */ 0161 explicit MetaEngine(const QString& filePath); 0162 0163 /** 0164 * Standard destructor 0165 */ 0166 virtual ~MetaEngine(); 0167 0168 public: 0169 0170 //----------------------------------------------------------------- 0171 /// @name Static methods 0172 //@{ 0173 0174 /** 0175 * Return true if Exiv2 library initialization is done properly. 0176 * This method must be called before using libMetaEngine with multithreading. 0177 * It initialize several non re-entrancy code from Adobe XMP SDK, and register 0178 * a function to cleanup automatically all XMP SDK memory allocation. 0179 * See Bug #166424 for details. 0180 */ 0181 static bool initializeExiv2(); 0182 0183 /** 0184 * Return true if Exiv2 library is compiled with Xmp metadata support. 0185 */ 0186 static bool supportXmp(); 0187 0188 /** 0189 * Return true if Exiv2 library is compiled with JpegXL metadata support. 0190 */ 0191 static bool supportJpegXL(); 0192 0193 /** 0194 * Return true if library support Base Media File Format (aka CR3, HEIF, HEIC, and AVIF). 0195 * Note: use this function only after to call initializeExiv2(), else false will always returned. 0196 * The function return true only if Exiv2 >= 0.27.4 compiled with BMFF support. 0197 */ 0198 static bool supportBmff(); 0199 0200 /** 0201 * Return true if library can write metadata to typeMime file format. 0202 */ 0203 static bool supportMetadataWriting(const QString& typeMime); 0204 0205 /** 0206 * Return a string version of Exiv2 release in format "major.minor.patch" 0207 */ 0208 static QString Exiv2Version(); 0209 0210 //@} 0211 0212 //----------------------------------------------------------------- 0213 /// @name General methods 0214 //@{ 0215 0216 MetaEngineData data() const; 0217 void setData(const MetaEngineData& data); 0218 0219 /** 0220 * Load all metadata (Exif, Iptc, Xmp, and JFIF Comments) from a byte array. 0221 * Return true if metadata have been loaded successfully from item data. 0222 */ 0223 bool loadFromData(const QByteArray& imgData); 0224 0225 /** 0226 * Load and merge metadata (Exif, Iptc and Xmp) from a byte array. 0227 * Use 'exclude' to remove Exif tags from the 'imgData' that will not be merged. 0228 * Return true if metadata have been loaded and merged successfully from item data. 0229 */ 0230 bool loadFromDataAndMerge(const QByteArray& imgData, const QStringList& exclude = QStringList()); 0231 0232 /** 0233 * Return 'true' if metadata container in memory as no Comments, Exif, Iptc, and Xmp. 0234 */ 0235 bool isEmpty() const; 0236 0237 /** 0238 * Returns the pixel size of the current item. This information is read from the file, 0239 * not from the metadata. The returned QSize is valid if the MetaEngine object was _constructed_ 0240 * by reading a file or item data; the information is not available when the object 0241 * was created from MetaEngineData. 0242 * Note that in the Exif or XMP metadata, there may be fields describing the item size. 0243 * These fields are not accessed by this method. 0244 * When replacing the metadata with setData(), the metadata may change; this information 0245 * always keeps referring to the file it was initially read from. 0246 */ 0247 QSize getPixelSize() const; 0248 0249 /** 0250 * Returns the mime type of this item. The information is read from the file; 0251 * see the docs for getPixelSize() to know when it is available. 0252 */ 0253 QString getMimeType() const; 0254 0255 /** 0256 * Enable or disable writing metadata operations with ExifTool. 0257 */ 0258 void setWriteWithExifTool(const bool on); 0259 0260 /** 0261 * Return true if writing metadata operations with ExifTool is enabled. 0262 */ 0263 bool writeWithExifTool() const; 0264 0265 /** 0266 * Enable or disable writing metadata operations to RAW files. 0267 * By default RAW files are untouched. 0268 */ 0269 void setWriteRawFiles(const bool on); 0270 0271 /** 0272 * Return true if writing metadata operations on RAW files is enabled. 0273 */ 0274 bool writeRawFiles() const; 0275 0276 /** 0277 * Enable or disable writing metadata operations to DNG files. 0278 */ 0279 void setWriteDngFiles(const bool on); 0280 0281 /** 0282 * Return true if writing metadata operations on DNG files is enabled. 0283 */ 0284 bool writeDngFiles() const; 0285 0286 /** 0287 * Enable or disable using XMP sidecar for reading metadata. 0288 */ 0289 void setUseXMPSidecar4Reading(const bool on); 0290 0291 /** 0292 * Return true if using XMP sidecar for reading metadata is enabled. 0293 */ 0294 bool useXMPSidecar4Reading() const; 0295 0296 /** 0297 * Enable or disable using compatible file name for sidecar files. 0298 */ 0299 void setUseCompatibleFileName(const bool on); 0300 0301 /** 0302 * Return true if using compatible file name for sidecar files. 0303 */ 0304 bool useCompatibleFileName() const; 0305 0306 /** 0307 * Set metadata writing mode. 0308 * @param mode Metadata writing mode as defined by the #MetadataWritingMode enum. 0309 * @sa MetadataWritingMode, metadataWritingMode() 0310 */ 0311 void setMetadataWritingMode(const int mode); 0312 0313 /** 0314 * Return the metadata writing mode. 0315 * @returns Metadata writing mode as defined by the #MetadataWritingMode enum. 0316 * @sa MetadataWritingMode, setMetadataWritingMode() 0317 */ 0318 int metadataWritingMode() const; 0319 0320 /** 0321 * Enable or disable file timestamp updating when metadata are saved. 0322 * By default files timestamp are untouched. 0323 */ 0324 void setUpdateFileTimeStamp(bool on); 0325 0326 /** 0327 * Return true if file timestamp is updated when metadata are saved. 0328 */ 0329 bool updateFileTimeStamp() const; 0330 0331 //@} 0332 0333 //------------------------------------------------------------------- 0334 /// @name File I/O methods 0335 //@{ 0336 0337 /** 0338 * Set the file path of current item. 0339 */ 0340 void setFilePath(const QString& path); 0341 0342 /** 0343 * Return the file path of current item. 0344 */ 0345 QString getFilePath() const; 0346 0347 /** 0348 * Return the XMP Sidecar file path for a item file path. 0349 * If item file path do not include a file name or is empty, this function return a null string. 0350 */ 0351 static QString sidecarFilePathForFile(const QString& path); 0352 0353 /** 0354 * Like sidecarFilePathForFile(), but works for local file path. 0355 */ 0356 static QString sidecarPath(const QString& path); 0357 0358 /** 0359 * Like sidecarFilePathForFile(), but works for remote URLs. 0360 */ 0361 static QUrl sidecarUrl(const QUrl& url); 0362 0363 /** 0364 * Gives a file url for a local path. 0365 */ 0366 static QUrl sidecarUrl(const QString& path); 0367 0368 /** 0369 * Performs a QFileInfo based check if the given local file has a sidecar. 0370 */ 0371 static bool hasSidecar(const QString& path); 0372 0373 /** 0374 * Return a string of backend name used to parse metadata from file. 0375 * See Backend enum for details. 0376 */ 0377 static QString backendName(Backend t); 0378 0379 /** 0380 * Load all metadata (Exif, Iptc, Xmp, and JFIF Comments) from a picture (JPEG, RAW, TIFF, PNG, 0381 * DNG, etc...). Return true if metadata have been loaded successfully from file. 0382 * If backend is non null, return the backend used to populate metadata (Exiv2). 0383 * See Backend enum for details. 0384 */ 0385 bool load(const QString& filePath, Backend* backend = nullptr); 0386 0387 /** 0388 * Load metadata from a sidecar file and merge. 0389 * Return true if metadata have been loaded successfully from file. 0390 */ 0391 bool loadFromSidecarAndMerge(const QString& filePath); 0392 0393 /** 0394 * Save all metadata to a file. This one can be different than original picture to perform 0395 * transfer operation Return true if metadata have been saved into file. 0396 */ 0397 bool save(const QString& filePath, bool setVersion = false) const; 0398 0399 /** 0400 * The same than save() method, but it apply on current item. Return true if metadata 0401 * have been saved into file. 0402 */ 0403 bool applyChanges(bool setVersion = false) const; 0404 0405 /** 0406 * Export metadata to a temporary EXV file container. 0407 * 'exvTmpFile' is the path to the temporary EXV container to create. 0408 */ 0409 bool exportChanges(const QString& exvTmpFile) const; 0410 0411 //@} 0412 0413 //------------------------------------------------------------------- 0414 /// @name Metadata item information manipulation methods 0415 //@{ 0416 0417 /** 0418 * Set Program name and program version in Exif and Iptc Metadata. Return true if information 0419 * have been changed in metadata. 0420 */ 0421 bool setItemProgramId(const QString& program, const QString& version) const; 0422 0423 /** 0424 * Return the size of item in pixels using Exif tags. Return a null dimension if size cannot 0425 * be found. 0426 */ 0427 QSize getItemDimensions() const; 0428 0429 /** 0430 * Set the size of item in pixels in Exif tags. Return true if size have been changed 0431 * in metadata. 0432 */ 0433 bool setItemDimensions(const QSize& size) const; 0434 0435 /** 0436 * Return the item orientation set in Exif metadata. The makernotes of item are also parsed to 0437 * get this information. See ImageOrientation values for details. 0438 */ 0439 MetaEngine::ImageOrientation getItemOrientation() const; 0440 0441 /** 0442 * Set the Exif orientation tag of item. See ImageOrientation values for details 0443 * Return true if orientation have been changed in metadata. 0444 */ 0445 bool setItemOrientation(ImageOrientation orientation) const; 0446 0447 /** 0448 * Return the item color-space set in Exif metadata. The makernotes of item are also parsed to 0449 * get this information. See ImageColorWorkSpace values for details. 0450 */ 0451 MetaEngine::ImageColorWorkSpace getItemColorWorkSpace() const; 0452 0453 /** 0454 * Set the Exif color-space tag of item. See ImageColorWorkSpace values for details 0455 * Return true if work-space have been changed in metadata. 0456 */ 0457 bool setItemColorWorkSpace(ImageColorWorkSpace workspace) const; 0458 0459 /** 0460 * Return the time stamp of item. Exif information are check in first, IPTC in second 0461 * if item don't have Exif information. If no time stamp is found, a null date is returned. 0462 */ 0463 QDateTime getItemDateTime() const; 0464 0465 /** 0466 * Set the Exif and Iptc time stamp. If 'setDateTimeDigitized' parameter is true, the 'Digitalized' 0467 * time stamp is set, else only 'Created' time stamp is set. 0468 */ 0469 bool setImageDateTime(const QDateTime& dateTime, bool setDateTimeDigitized = false) const; 0470 0471 /** 0472 * Return the digitization time stamp of the item. First Exif information is checked, then IPTC. 0473 * If no digitization time stamp is found, getItemDateTime() is called if fallbackToCreationTime 0474 * is true, or a null QDateTime is returned if fallbackToCreationTime is false. 0475 */ 0476 QDateTime getDigitizationDateTime(bool fallbackToCreationTime = false) const; 0477 0478 /** 0479 * Return a QImage copy of Iptc preview image. Return a null item if preview cannot 0480 * be found. 0481 */ 0482 bool getItemPreview(QImage& preview) const; 0483 0484 /** 0485 * Set the Iptc preview image. The thumbnail item must have the right size before (64Kb max 0486 * with JPEG file, else 256Kb). Look Iptc specification for details. Return true if preview 0487 * have been changed in metadata. 0488 * Re-implement this method if you want to use another item file format than JPEG to 0489 * save preview. 0490 */ 0491 bool setItemPreview(const QImage& preview) const; 0492 0493 //@} 0494 0495 //----------------------------------------------------------------- 0496 /// @name Comments manipulation methods 0497 //@{ 0498 0499 /** 0500 * Return 'true' if Comments can be written in file. 0501 */ 0502 static bool canWriteComment(const QString& filePath); 0503 0504 /** 0505 * Return 'true' if metadata container in memory as Comments. 0506 */ 0507 bool hasComments() const; 0508 0509 /** 0510 * Clear the Comments metadata container in memory. 0511 */ 0512 bool clearComments() const; 0513 0514 /** 0515 * Return a Qt byte array copy of Comments container get from current item. 0516 * Comments are JFIF section of JPEG images. Look Exiv2 API for more information. 0517 * Return a null Qt byte array if there is no Comments metadata in memory. 0518 */ 0519 QByteArray getComments() const; 0520 0521 /** 0522 * Return a Qt string object of Comments from current item decoded using 0523 * the 'detectEncodingAndDecode()' method. Return a null string if there is no 0524 * Comments metadata available. 0525 */ 0526 QString getCommentsDecoded() const; 0527 0528 /** 0529 * Set the Comments data using a Qt byte array. Return true if Comments metadata 0530 * have been changed in memory. 0531 */ 0532 bool setComments(const QByteArray& data) const; 0533 0534 /** 0535 * Language Alternative autodetection. Return a QString without language alternative 0536 * header. Header is saved into 'lang'. If no language alternative is founf, value is returned 0537 * as well and 'lang' is set to a null string. 0538 */ 0539 static QString detectLanguageAlt(const QString& value, QString& lang); 0540 0541 //@} 0542 0543 //----------------------------------------------------------------- 0544 /// @name Exif manipulation methods 0545 //@{ 0546 0547 /** 0548 * Return a map of all standard Exif tags supported by Exiv2. 0549 */ 0550 TagsMap getStdExifTagsList() const; 0551 0552 /** 0553 * Return a map of all non-standard Exif tags (makernotes) supported by Exiv2. 0554 */ 0555 TagsMap getMakernoteTagsList() const; 0556 0557 /** 0558 * Return 'true' if Exif can be written in file. 0559 */ 0560 static bool canWriteExif(const QString& filePath); 0561 0562 /** 0563 * Return 'true' if metadata container in memory as Exif. 0564 */ 0565 bool hasExif() const; 0566 0567 /** 0568 * Clear the Exif metadata container in memory. 0569 */ 0570 bool clearExif() const; 0571 0572 /** 0573 * Returns the exif data encoded to a QByteArray in a form suitable 0574 * for storage in a JPEG image. 0575 * Note that this encoding is a lossy operation. 0576 * 0577 * Set true 'addExifHeader' parameter to add an Exif header to Exif metadata. 0578 * Returns a null Qt byte array if there is no Exif metadata in memory. 0579 */ 0580 QByteArray getExifEncoded(bool addExifHeader = false) const; 0581 0582 /** 0583 * Set the Exif data using a Qt byte array. Return true if Exif metadata 0584 * have been changed in memory. 0585 */ 0586 bool setExif(const QByteArray& data) const; 0587 0588 /** 0589 * Return a QImage copy of Exif thumbnail image. Return a null image if thumbnail cannot 0590 * be found. The 'fixOrientation' parameter will rotate automatically the thumbnail if Exif 0591 * orientation tags information are attached with thumbnail. 0592 */ 0593 QImage getExifThumbnail(bool fixOrientation) const; 0594 0595 /** 0596 * Fix orientation of a QImage image accordingly with Exif orientation tag. 0597 * Return true if image is rotated, else false. 0598 */ 0599 bool rotateExifQImage(QImage& image, ImageOrientation orientation) const; 0600 0601 /** 0602 * Set the Exif Thumbnail image. The thumbnail image must have the right dimensions before. 0603 * Look Exif specification for details. Return true if thumbnail have been changed in metadata. 0604 */ 0605 bool setExifThumbnail(const QImage& thumb) const; 0606 0607 /** 0608 * Remove the Exif Thumbnail from the item 0609 */ 0610 bool removeExifThumbnail() const; 0611 0612 /** 0613 * Adds a JPEG thumbnail to a TIFF images. Use this instead of setExifThumbnail for TIFF images. 0614 */ 0615 bool setTiffThumbnail(const QImage& thumb) const; 0616 0617 /** 0618 * Return a QString copy of Exif user comments. Return a null string if user comments cannot 0619 * be found. 0620 */ 0621 QString getExifComment(bool readDescription = true) const; 0622 0623 /** 0624 * Return a Exif tag comment like a string. Return a null string if user comments cannot 0625 * be found. 0626 */ 0627 QString getExifTagComment(const char* exifTagName) const; 0628 0629 /** 0630 * Set the Exif user comments from item. Look Exif specification for more details about this tag. 0631 * Return true if Exif user comments have been changed in metadata. 0632 */ 0633 bool setExifComment(const QString& comment, bool writeDescription = true) const; 0634 0635 /** 0636 * Get an Exif tags content like a string. If 'escapeCR' parameter is true, the CR characters 0637 * will be removed. If Exif tag cannot be found a null string is returned. 0638 */ 0639 QString getExifTagString(const char* exifTagName, bool escapeCR = true) const; 0640 0641 /** 0642 * Set an Exif tag content using a string. Return true if tag is set successfully. 0643 */ 0644 bool setExifTagString(const char* exifTagName, const QString& value) const; 0645 0646 /** 0647 * Get an Exif tag content like a long value. Return true if Exif tag be found. 0648 */ 0649 bool getExifTagLong(const char* exifTagName, long &val) const; 0650 0651 /** 0652 * Get an Exif tag content like a long value. Return true if Exif tag be found. 0653 */ 0654 bool getExifTagLong(const char* exifTagName, long &val, int component) const; 0655 0656 /** 0657 * Set an Exif tag content using a long value. Return true if tag is set successfully. 0658 */ 0659 bool setExifTagLong(const char* exifTagName, long val) const; 0660 0661 /** 0662 * Get the 'component' index of an Exif tags content like a rational value. 0663 * 'num' and 'den' are the numerator and the denominator of the rational value. 0664 * Return true if Exif tag be found. 0665 */ 0666 bool getExifTagRational(const char* exifTagName, long int& num, long int& den, int component = 0) const; 0667 0668 /** 0669 * Set an Exif tag content using a rational value. 0670 * 'num' and 'den' are the numerator and the denominator of the rational value. 0671 * Return true if tag is set successfully. 0672 */ 0673 bool setExifTagRational(const char* exifTagName, long int num, long int den) const; 0674 0675 /** 0676 * Get an Exif tag content like a bytes array. Return an empty bytes array if Exif 0677 * tag cannot be found. 0678 */ 0679 QByteArray getExifTagData(const char* exifTagName) const; 0680 0681 /** 0682 * Set an Exif tag content using a bytes array. Return true if tag is set successfully. 0683 */ 0684 bool setExifTagData(const char* exifTagName, const QByteArray& data) const; 0685 0686 /** 0687 * Get an Exif tags content as a QVariant. Returns a null QVariant if the Exif 0688 * tag cannot be found. 0689 * For string and integer values the matching QVariant types will be used, 0690 * for date and time values QVariant::DateTime. 0691 * Rationals will be returned as QVariant::List with two integer QVariants (numerator, denominator) 0692 * if rationalAsListOfInts is true, as double if rationalAsListOfInts is false. 0693 * An exif tag of numerical type may contain more than one value; set component to the desired index. 0694 */ 0695 QVariant getExifTagVariant(const char* exifTagName, bool rationalAsListOfInts = true, 0696 bool escapeCR = true, int component = 0) const; 0697 0698 /** 0699 * Set an Exif tag content using a QVariant. Returns true if tag is set successfully. 0700 * All types described for the getExifTagVariant() method are supported. 0701 * Calling with a QVariant of type ByteArray is equivalent to calling setExifTagData. 0702 * For the meaning of rationalWantSmallDenominator, see the documentation of the convertToRational methods. 0703 * Setting a value with multiple components is currently not supported. 0704 */ 0705 bool setExifTagVariant(const char* exifTagName, const QVariant& data, 0706 bool rationalWantSmallDenominator = true) const; 0707 0708 /** 0709 * Remove the Exif tag 'exifTagName' from Exif metadata. Return true if tag is 0710 * removed successfully or if no tag was present. 0711 */ 0712 bool removeExifTag(const char* exifTagName) const; 0713 0714 /** 0715 * Return the Exif Tag title or a null string. 0716 */ 0717 QString getExifTagTitle(const char* exifTagName); 0718 0719 /** 0720 * Return the Exif Tag description or a null string. 0721 */ 0722 QString getExifTagDescription(const char* exifTagName); 0723 0724 /** 0725 * Takes a QVariant value as it could have been retrieved by getExifTagVariant with the given exifTagName, 0726 * and returns its value properly converted to a string (including translations from Exiv2). 0727 * This is equivalent to calling getExifTagString directly. 0728 * If escapeCR is true CR characters will be removed from the result. 0729 */ 0730 QString createExifUserStringFromValue(const char* exifTagName, const QVariant& val, bool escapeCR = true); 0731 0732 /** 0733 * Return a map of Exif tags name/value found in metadata sorted by 0734 * Exif keys given by 'exifKeysFilter'. 0735 * 0736 * 'exifKeysFilter' is a QStringList of Exif keys. 0737 * For example, if you use the string list given below: 0738 * 0739 * "Iop" 0740 * "Thumbnail" 0741 * "Image" 0742 * "Photo" 0743 * 0744 * List can be empty to not filter output. 0745 * 0746 * ... this method will return a map of all Exif tags which : 0747 * 0748 * - include "Iop", or "Thumbnail", or "Image", or "Photo" in the Exif tag keys 0749 * if 'inverSelection' is false. 0750 * - not include "Iop", or "Thumbnail", or "Image", or "Photo" in the Exif tag keys 0751 * if 'inverSelection' is true. 0752 * if 'extractBinary" is true, tags with undefined types of data are extracted (default), 0753 * else contents is replaced by "Binary data ... bytes". Take a care as large binary data as 0754 * original RAW data from DNG container can be huge and listing Exif tags from GUI can take a while. 0755 */ 0756 MetaEngine::MetaDataMap getExifTagsDataList(const QStringList& exifKeysFilter = QStringList(), 0757 bool invertSelection = false, 0758 bool extractBinary = true) const; 0759 0760 //@} 0761 0762 //------------------------------------------------------------- 0763 /// @name IPTC manipulation methods 0764 //@{ 0765 0766 /** 0767 * Return a map of all standard Iptc tags supported by Exiv2. 0768 */ 0769 MetaEngine::TagsMap getIptcTagsList() const; 0770 0771 /** 0772 * Return 'true' if Iptc can be written in file. 0773 */ 0774 static bool canWriteIptc(const QString& filePath); 0775 0776 /** 0777 * Return 'true' if metadata container in memory as Iptc. 0778 */ 0779 bool hasIptc() const; 0780 0781 /** 0782 * Clear the Iptc metadata container in memory. 0783 */ 0784 bool clearIptc() const; 0785 0786 /** 0787 * Return a Qt byte array copy of Iptc container get from current item. 0788 * Set true 'addIrbHeader' parameter to add an Irb header to Iptc metadata. 0789 * Return a null Qt byte array if there is no Iptc metadata in memory. 0790 */ 0791 QByteArray getIptc(bool addIrbHeader = false) const; 0792 0793 /** 0794 * Set the Iptc data using a Qt byte array. Return true if Iptc metadata 0795 * have been changed in memory. 0796 */ 0797 bool setIptc(const QByteArray& data) const; 0798 0799 /** 0800 * Get an Iptc tag content like a string. If 'escapeCR' parameter is true, the CR characters 0801 * will be removed. If Iptc tag cannot be found a null string is returned. 0802 */ 0803 QString getIptcTagString(const char* iptcTagName, bool escapeCR = true) const; 0804 0805 /** 0806 * Set an Iptc tag content using a string. Return true if tag is set successfully. 0807 */ 0808 bool setIptcTagString(const char* iptcTagName, const QString& value) const; 0809 0810 /** 0811 * Returns a strings list with of multiple Iptc tags from the item. Return an empty list if no tag is found. 0812 * Get the values of all IPTC tags with the given tag name in a string list. 0813 * (In Iptc, there can be multiple tags with the same name) 0814 * If the 'escapeCR' parameter is true, the CR characters 0815 * will be removed. 0816 * If no tag can be found an empty list is returned. 0817 */ 0818 QStringList getIptcTagsStringList(const char* iptcTagName, bool escapeCR = true) const; 0819 0820 /** 0821 * Set multiple Iptc tags contents using a strings list. 'maxSize' is the max characters size 0822 * of one entry. Return true if all tags have been set successfully. 0823 */ 0824 bool setIptcTagsStringList(const char* iptcTagName, int maxSize, 0825 const QStringList& oldValues, const QStringList& newValues) const; 0826 0827 /** 0828 * Get an Iptc tag content as a bytes array. Return an empty bytes array if Iptc 0829 * tag cannot be found. 0830 */ 0831 QByteArray getIptcTagData(const char* iptcTagName) const; 0832 0833 /** 0834 * Set an Iptc tag content using a bytes array. Return true if tag is set successfully. 0835 */ 0836 bool setIptcTagData(const char* iptcTagName, const QByteArray& data) const; 0837 0838 /** 0839 * Remove the all instance of Iptc tags 'iptcTagName' from Iptc metadata. Return true if all 0840 * tags have been removed successfully (or none were present). 0841 */ 0842 bool removeIptcTag(const char* iptcTagName) const; 0843 0844 /** 0845 * Return the Iptc Tag title or a null string. 0846 */ 0847 QString getIptcTagTitle(const char* iptcTagName); 0848 0849 /** 0850 * Return the Iptc Tag description or a null string. 0851 */ 0852 QString getIptcTagDescription(const char* iptcTagName); 0853 0854 /** 0855 * Return a map of Iptc tags name/value found in metadata sorted by 0856 * Iptc keys given by 'iptcKeysFilter'. 0857 * 0858 * 'iptcKeysFilter' is a QStringList of Iptc keys. 0859 * For example, if you use the string list given below: 0860 * 0861 * "Envelope" 0862 * "Application2" 0863 * 0864 * List can be empty to not filter output. 0865 * 0866 * ... this method will return a map of all Iptc tags which : 0867 * 0868 * - include "Envelope", or "Application2" in the Iptc tag keys 0869 * if 'inverSelection' is false. 0870 * - not include "Envelope", or "Application2" in the Iptc tag keys 0871 * if 'inverSelection' is true. 0872 */ 0873 MetaEngine::MetaDataMap getIptcTagsDataList(const QStringList& iptcKeysFilter = QStringList(), 0874 bool invertSelection = false) const; 0875 0876 /** 0877 * Return a strings list of Iptc keywords from item. Return an empty list if no keyword are set. 0878 */ 0879 QStringList getIptcKeywords() const; 0880 0881 /** 0882 * Set Iptc keywords using a list of strings defined by 'newKeywords' parameter. Use 'getImageKeywords()' 0883 * method to set 'oldKeywords' parameter with existing keywords from item. The method will compare 0884 * all new keywords with all old keywords to prevent duplicate entries in item. Return true if keywords 0885 * have been changed in metadata. 0886 */ 0887 bool setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords) const; 0888 0889 /** 0890 * Return a strings list of Iptc subjects from item. Return an empty list if no subject are set. 0891 */ 0892 QStringList getIptcSubjects() const; 0893 0894 /** 0895 * Set Iptc subjects using a list of strings defined by 'newSubjects' parameter. Use 'getImageSubjects()' 0896 * method to set 'oldSubjects' parameter with existing subjects from item. The method will compare 0897 * all new subjects with all old subjects to prevent duplicate entries in item. Return true if subjects 0898 * have been changed in metadata. 0899 */ 0900 bool setIptcSubjects(const QStringList& oldSubjects, const QStringList& newSubjects) const; 0901 0902 /** 0903 * Return a strings list of Iptc sub-categories from item. Return an empty list if no sub-category 0904 * are set. 0905 */ 0906 QStringList getIptcSubCategories() const; 0907 0908 /** 0909 * Set Iptc sub-categories using a list of strings defined by 'newSubCategories' parameter. Use 0910 * 'getImageSubCategories()' method to set 'oldSubCategories' parameter with existing sub-categories 0911 * from item. The method will compare all new sub-categories with all old sub-categories to prevent 0912 * duplicate entries in item. Return true if sub-categories have been changed in metadata. 0913 */ 0914 bool setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories) const; 0915 0916 //@} 0917 0918 //------------------------------------------------------------ 0919 /// @name XMP manipulation methods 0920 //@{ 0921 0922 /** 0923 * Return a map of all standard Xmp tags supported by Exiv2. 0924 */ 0925 MetaEngine::TagsMap getXmpTagsList() const; 0926 0927 /** 0928 * Return 'true' if Xmp can be written in file. 0929 */ 0930 static bool canWriteXmp(const QString& filePath); 0931 0932 /** 0933 * Return 'true' if metadata container in memory as Xmp. 0934 */ 0935 bool hasXmp() const; 0936 0937 /** 0938 * Clear the Xmp metadata container in memory. 0939 */ 0940 bool clearXmp() const; 0941 0942 /** 0943 * Return a Qt byte array copy of XMp container get from current item. 0944 * Return a null Qt byte array if there is no Xmp metadata in memory. 0945 */ 0946 QByteArray getXmp() const; 0947 0948 /** 0949 * Set the Xmp data using a Qt byte array. Return true if Xmp metadata 0950 * have been changed in memory. 0951 */ 0952 bool setXmp(const QByteArray& data) const; 0953 0954 /** 0955 * Get a Xmp tag content like a string. If 'escapeCR' parameter is true, the CR characters 0956 * will be removed. If Xmp tag cannot be found a null string is returned. 0957 */ 0958 QString getXmpTagString(const char* xmpTagName, bool escapeCR = true) const; 0959 0960 /** 0961 * Set a Xmp tag content using a string. Return true if tag is set successfully. 0962 */ 0963 bool setXmpTagString(const char* xmpTagName, const QString& value) const; 0964 0965 /** 0966 * Set a Xmp tag with a specific type. Return true if tag is set successfully. 0967 * This method only accept NormalTag, ArrayBagTag and StructureTag. 0968 * Other XmpTagTypes do nothing 0969 */ 0970 bool setXmpTagString(const char* xmpTagName, const QString& value, 0971 XmpTagType type) const; 0972 0973 /** 0974 * Return the Xmp Tag title or a null string. 0975 */ 0976 QString getXmpTagTitle(const char* xmpTagName); 0977 0978 /** 0979 * Return the Xmp Tag description or a null string. 0980 */ 0981 QString getXmpTagDescription(const char* xmpTagName); 0982 0983 /** 0984 * Return a map of Xmp tags name/value found in metadata sorted by 0985 * Xmp keys given by 'xmpKeysFilter'. 0986 * 0987 * 'xmpKeysFilter' is a QStringList of Xmp keys. 0988 * For example, if you use the string list given below: 0989 * 0990 * "dc" // Dubling Core schema. 0991 * "xmp" // Standard Xmp schema. 0992 * 0993 * List can be empty to not filter output. 0994 * 0995 * ... this method will return a map of all Xmp tags which : 0996 * 0997 * - include "dc", or "xmp" in the Xmp tag keys 0998 * if 'inverSelection' is false. 0999 * - not include "dc", or "xmp" in the Xmp tag keys 1000 * if 'inverSelection' is true. 1001 */ 1002 MetaEngine::MetaDataMap getXmpTagsDataList(const QStringList& xmpKeysFilter = QStringList(), 1003 bool invertSelection = false) const; 1004 1005 /** 1006 * Get all redondant Alternative Language Xmp tags content like a map. 1007 * See AltLangMap class description for details. 1008 * If 'escapeCR' parameter is true, the CR characters will be removed from strings. 1009 * If Xmp tag cannot be found a null string list is returned. 1010 */ 1011 MetaEngine::AltLangMap getXmpTagStringListLangAlt(const char* xmpTagName, 1012 bool escapeCR = true) const; 1013 1014 /** 1015 * Set an Alternative Language Xmp tag content using a map. See AltLangMap class 1016 * description for details. If tag already exist, it will be removed before. 1017 * Return true if tag is set successfully. 1018 */ 1019 bool setXmpTagStringListLangAlt(const char* xmpTagName, const MetaEngine::AltLangMap& values) const; 1020 1021 /** 1022 * Get a Xmp tag content like a string set with an alternative language 1023 * header 'langAlt' (like "fr-FR" for French - RFC3066 notation) 1024 * If 'escapeCR' parameter is true, the CR characters will be removed. 1025 * If Xmp tag cannot be found a null string is returned. 1026 */ 1027 QString getXmpTagStringLangAlt(const char* xmpTagName, const QString& langAlt, bool escapeCR) const; 1028 1029 /** 1030 * Set a Xmp tag content using a string with an alternative language header. 'langAlt' contain the 1031 * language alternative information (like "fr-FR" for French - RFC3066 notation) or is null to 1032 * set alternative language to default settings ("x-default"). 1033 * Return true if tag is set successfully. 1034 */ 1035 bool setXmpTagStringLangAlt(const char* xmpTagName, const QString& value, 1036 const QString& langAlt) const; 1037 1038 /** 1039 * Get a Xmp tag content like a sequence of strings. If 'escapeCR' parameter is true, the CR characters 1040 * will be removed from strings. If Xmp tag cannot be found a null string list is returned. 1041 */ 1042 QStringList getXmpTagStringSeq(const char* xmpTagName, bool escapeCR = true) const; 1043 1044 /** 1045 * Set a Xmp tag content using the sequence of strings 'seq'. 1046 * Return true if tag is set successfully. 1047 */ 1048 bool setXmpTagStringSeq(const char* xmpTagName, const QStringList& seq) const; 1049 1050 /** 1051 * Get a Xmp tag content like a bag of strings. If 'escapeCR' parameter is true, the CR characters 1052 * will be removed from strings. If Xmp tag cannot be found a null string list is returned. 1053 */ 1054 QStringList getXmpTagStringBag(const char* xmpTagName, bool escapeCR) const; 1055 1056 /** 1057 * Set a Xmp tag content using the bag of strings 'bag'. 1058 * Return true if tag is set successfully. 1059 */ 1060 bool setXmpTagStringBag(const char* xmpTagName, const QStringList& bag) const; 1061 1062 /** 1063 * Set an Xmp tag content using a list of strings defined by the 'entriesToAdd' parameter. 1064 * The existing entries are preserved. The method will compare 1065 * all new with all already existing entries to prevent duplicates in the item. 1066 * Return true if the entries have been added to metadata. 1067 */ 1068 bool addToXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToAdd) const; 1069 1070 /** 1071 * Remove those Xmp tag entries that are listed in entriesToRemove from the entries in metadata. 1072 * Return true if tag entries are no longer contained in metadata. 1073 * All other entries are preserved. 1074 */ 1075 bool removeFromXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToRemove) const; 1076 1077 /** 1078 * Get an Xmp tag content as a QVariant. Returns a null QVariant if the Xmp 1079 * tag cannot be found. 1080 * For string and integer values the matching QVariant types will be used, 1081 * for date and time values QVariant::DateTime. 1082 * Rationals will be returned as QVariant::List with two integer QVariants (numerator, denominator) 1083 * if rationalAsListOfInts is true, as double if rationalAsListOfInts is false. 1084 * Arrays (ordered, unordered, alternative) are returned as type StringList. 1085 * LangAlt values will have type Map (QMap<QString, QVariant>) with the language 1086 * code as key and the contents as value, of type String. 1087 */ 1088 QVariant getXmpTagVariant(const char* xmpTagName, bool rationalAsListOfInts = true, bool stringEscapeCR = true) const; 1089 1090 /** 1091 * Return a strings list of Xmp keywords from item. Return an empty list if no keyword are set. 1092 */ 1093 QStringList getXmpKeywords() const; 1094 1095 /** 1096 * Set Xmp keywords using a list of strings defined by 'newKeywords' parameter. 1097 * The existing keywords from item are preserved. The method will compare 1098 * all new keywords with all already existing keywords to prevent duplicate entries in item. 1099 * Return true if keywords have been changed in metadata. 1100 */ 1101 bool setXmpKeywords(const QStringList& newKeywords) const; 1102 1103 /** 1104 * Remove those Xmp keywords that are listed in keywordsToRemove from the keywords in metadata. 1105 * Return true if keywords are no longer contained in metadata. 1106 */ 1107 bool removeXmpKeywords(const QStringList& keywordsToRemove); 1108 1109 /** 1110 * Return a strings list of Xmp subjects from item. Return an empty list if no subject are set. 1111 */ 1112 QStringList getXmpSubjects() const; 1113 1114 /** 1115 * Set Xmp subjects using a list of strings defined by 'newSubjects' parameter. 1116 * The existing subjects from item are preserved. The method will compare 1117 * all new subject with all already existing subject to prevent duplicate entries in item. 1118 * Return true if subjects have been changed in metadata. 1119 */ 1120 bool setXmpSubjects(const QStringList& newSubjects) const; 1121 1122 /** 1123 * Remove those Xmp subjects that are listed in subjectsToRemove from the subjects in metadata. 1124 * Return true if subjects are no longer contained in metadata. 1125 */ 1126 bool removeXmpSubjects(const QStringList& subjectsToRemove); 1127 1128 /** 1129 * Return a strings list of Xmp sub-categories from item. Return an empty list if no sub-category 1130 * are set. 1131 */ 1132 QStringList getXmpSubCategories() const; 1133 1134 /** 1135 * Set Xmp sub-categories using a list of strings defined by 'newSubCategories' parameter. 1136 * The existing sub-categories from item are preserved. The method will compare 1137 * all new sub-categories with all already existing sub-categories to prevent duplicate entries in item. 1138 * Return true if sub-categories have been changed in metadata. 1139 */ 1140 bool setXmpSubCategories(const QStringList& newSubCategories) const; 1141 1142 /** 1143 * Remove those Xmp sub-categories that are listed in categoriesToRemove from the sub-categories in metadata. 1144 * Return true if subjects are no longer contained in metadata. 1145 */ 1146 bool removeXmpSubCategories(const QStringList& categoriesToRemove); 1147 1148 /** 1149 * Remove the Xmp tag 'xmpTagName' from Xmp metadata. Return true if tag is 1150 * removed successfully or if no tag was present. 1151 */ 1152 bool removeXmpTag(const char* xmpTagName, bool family = false) const; 1153 1154 /** 1155 * Register a namespace which Exiv2 doesn't know yet. This is only needed 1156 * when new Xmp properties are added manually. 'uri' is the namespace url and 'prefix' the 1157 * string used to construct new Xmp key (ex. "Xmp.digiKam.tagList"). 1158 * NOTE: If the Xmp metadata is read from an item, namespaces are decoded and registered 1159 * by Exiv2 at the same time. 1160 */ 1161 static bool registerXmpNameSpace(const QString& uri, const QString& prefix); 1162 1163 /** 1164 * Unregister a previously registered custom namespace 1165 */ 1166 static bool unregisterXmpNameSpace(const QString& uri); 1167 1168 //@} 1169 1170 //------------------------------------------------------------ 1171 /// @name GPS manipulation methods 1172 //@{ 1173 1174 /** 1175 * Make sure all static required GPS EXIF and XMP tags exist 1176 */ 1177 bool initializeGPSInfo(); 1178 1179 /** 1180 * Get all GPS location information set in item. Return true if all information can be found. 1181 */ 1182 bool getGPSInfo(double& altitude, double& latitude, double& longitude) const; 1183 1184 /** 1185 * Get GPS location information set in the item, in the GPSCoordinate format 1186 * as described in the XMP specification. Returns a null string in the information cannot be found. 1187 */ 1188 QString getGPSLatitudeString() const; 1189 QString getGPSLongitudeString() const; 1190 1191 /** 1192 * Get GPS location information set in the item, as a double floating point number as in degrees 1193 * where the sign determines the direction ref (North + / South - ; East + / West -). 1194 * Returns true if the information is available. 1195 */ 1196 bool getGPSLatitudeNumber(double* const latitude) const; 1197 bool getGPSLongitudeNumber(double* const longitude) const; 1198 1199 /** 1200 * Get GPS altitude information, in meters, relative to sea level (positive sign above sea level) 1201 */ 1202 bool getGPSAltitude(double* const altitude) const; 1203 1204 /** 1205 * Set all GPS location information into item. Return true if all information have been 1206 * changed in metadata. 1207 */ 1208 bool setGPSInfo(const double altitude, const double latitude, const double longitude); 1209 1210 /** 1211 * Set all GPS location information into item. Return true if all information have been 1212 * changed in metadata. If you do not want altitude to be set, pass a null pointer. 1213 */ 1214 bool setGPSInfo(const double* const altitude, const double latitude, const double longitude); 1215 1216 /** 1217 * Set all GPS location information into item. Return true if all information have been 1218 * changed in metadata. 1219 */ 1220 bool setGPSInfo(const double altitude, const QString& latitude, const QString& longitude); 1221 1222 /** 1223 * Remove all Exif tags relevant of GPS location information. Return true if all tags have been 1224 * removed successfully in metadata. 1225 */ 1226 bool removeGPSInfo(); 1227 1228 /** 1229 * This method converts 'number' to a rational value, returned in the 'numerator' and 1230 * 'denominator' parameters. Set the precision using 'rounding' parameter. 1231 * Use this method if you want to retrieve a most exact rational for a number 1232 * without further properties, without any requirements to the denominator. 1233 */ 1234 static void convertToRational(const double number, 1235 long int* const numerator, 1236 long int* const denominator, 1237 const int rounding); 1238 1239 /** 1240 * This method convert a 'number' to a rational value, returned in 'numerator' and 1241 * 'denominator' parameters. 1242 * This method will be able to retrieve a rational number from a double - if you 1243 * constructed your double with 1.0 / 4786.0, this method will retrieve 1 / 4786. 1244 * If your number is not expected to be rational, use the method above which is just as 1245 * exact with rounding = 4 and more exact with rounding > 4. 1246 */ 1247 static void convertToRationalSmallDenominator(const double number, 1248 long int* const numerator, 1249 long int* const denominator); 1250 1251 /** 1252 * Converts degrees values as a double representation. This code take a care about hemisphere position. 1253 */ 1254 static double convertDegreeAngleToDouble(double degrees, double minutes, double seconds); 1255 1256 1257 /** 1258 * Converts a GPS position stored as rationals in Exif to the form described 1259 * as GPSCoordinate in the XMP specification, either in the from "256,45,34N" or "256,45.566667N" 1260 */ 1261 static QString convertToGPSCoordinateString(const long int numeratorDegrees, 1262 const long int denominatorDegrees, 1263 const long int numeratorMinutes, 1264 const long int denominatorMinutes, 1265 const long int numeratorSeconds, 1266 const long int denominatorSeconds, 1267 const char directionReference); 1268 1269 /** 1270 * Converts a GPS position stored as double floating point number in degrees to the form described 1271 * as GPSCoordinate in the XMP specification. 1272 */ 1273 static QString convertToGPSCoordinateString(const bool isLatitude, 1274 double coordinate); 1275 1276 /** 1277 * Converts a GPSCoordinate string as defined by XMP to three rationals and the direction reference. 1278 * Returns true if the conversion was successful. 1279 * If minutes is given in the fractional form, a denominator of 1000000 for the minutes will be used. 1280 */ 1281 static bool convertFromGPSCoordinateString(const QString& coordinate, 1282 long int* const numeratorDegrees, 1283 long int* const denominatorDegrees, 1284 long int* const numeratorMinutes, 1285 long int* const denominatorMinutes, 1286 long int* const numeratorSeconds, 1287 long int* const denominatorSeconds, 1288 char* const directionReference); 1289 1290 /** 1291 * Convert a GPSCoordinate string as defined by XMP to a double floating point number in degrees 1292 * where the sign determines the direction ref (North + / South - ; East + / West -). 1293 * Returns true if the conversion was successful. 1294 */ 1295 static bool convertFromGPSCoordinateString(const QString& gpsString, 1296 double* const coordinate); 1297 1298 /** 1299 * Converts a GPSCoordinate string to user presentable numbers, integer degrees and minutes and 1300 * double floating point seconds, and a direction reference ('N' or 'S', 'E' or 'W') 1301 */ 1302 static bool convertToUserPresentableNumbers(const QString& coordinate, 1303 int* const degrees, 1304 int* const minutes, 1305 double* const seconds, 1306 char* const directionReference); 1307 1308 /** 1309 * Converts a double floating point number to user presentable numbers, integer degrees and minutes and 1310 * double floating point seconds, and a direction reference ('N' or 'S', 'E' or 'W'). 1311 * The method needs to know for the direction reference 1312 * if the latitude or the longitude is meant by the double parameter. 1313 */ 1314 static void convertToUserPresentableNumbers(const bool isLatitude, 1315 double coordinate, 1316 int* const degrees, 1317 int* const minutes, 1318 double* const seconds, 1319 char* const directionReference); 1320 1321 //@} 1322 1323 protected: 1324 1325 /** 1326 * Set the Program Name and Program Version 1327 * information in Exif and Iptc metadata 1328 */ 1329 bool setProgramId() const; 1330 1331 private: 1332 1333 // Disable copy constructor and operator to prevent potential slicing with this class, reported by Clazy static analyzer. 1334 // https://github.com/KDE/clazy/blob/master/docs/checks/README-copyable-polymorphic.md 1335 // This methods was implemented to be able to pass this class or a derived version to signals and slots. This is very 1336 // Dangerous as virtual methods are present in this polymorphic class and is copyable. 1337 // Instead to use this class in signals and slots, use MetaEngineData container. 1338 // TODO: remove legacy implementations for these methods later if no side effect. 1339 MetaEngine(const MetaEngine& metadata); 1340 MetaEngine& operator=(const MetaEngine& metadata); 1341 1342 private: 1343 1344 /** 1345 * Internal container to store private members. Used to improve binary compatibility 1346 */ 1347 class Private; 1348 Private* const d; 1349 1350 friend class MetaEnginePreviews; 1351 }; 1352 1353 } // namespace Digikam 1354 1355 #endif // DIGIKAM_META_ENGINE_H