File indexing completed on 2024-05-05 04:33:10

0001 /*
0002     SPDX-FileCopyrightText: 2006-2015 Gilles Caulier <caulier dot gilles at gmail dot com>
0003     SPDX-FileCopyrightText: 2006-2013 Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef KEXIV2_H
0009 #define KEXIV2_H
0010 
0011 // Std
0012 
0013 #include <memory>
0014 
0015 // QT includes
0016 
0017 #include <QByteArray>
0018 #include <QString>
0019 #include <QDateTime>
0020 #include <QMap>
0021 #include <QSharedDataPointer>
0022 #include <QStringList>
0023 #include <QVariant>
0024 #include <QUrl>
0025 #include <QImage>
0026 
0027 // Local includes
0028 
0029 #include "libkexiv2_export.h"
0030 #include "kexiv2data.h"
0031 
0032 /**
0033  * @brief  KExiv2Iface - Exiv2 library interface
0034  *
0035  * @li Exiv2: https://www.exiv2.org
0036  * @li Exif : https://www.exif.org/Exif2-2.PDF
0037  * @li Iptc : https://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
0038  * @li Xmp  : https://www.adobe.com/devnet/xmp.html
0039  *            https://www.iptc.org/std/Iptc4xmpCore/1.0/specification/Iptc4xmpCore_1.0-spec-XMPSchema_8.pdf
0040  * @li Paper: http://www.metadataworkinggroup.com/pdf/mwg_guidance.pdf
0041  */
0042 namespace KExiv2Iface
0043 {
0044 
0045 /**
0046  * @class KExiv2 kexiv2.h <KExiv2/KExiv2>
0047  *
0048  * KExiv2
0049  */
0050 class LIBKEXIV2_EXPORT KExiv2
0051 {
0052 
0053 public:
0054 
0055     /** The image metadata writing mode, between image file metadata and XMP sidecar file, depending on the context.
0056      * @sa MetadataWritingMode(), metadataWritingMode()
0057      */
0058     enum MetadataWritingMode
0059     {
0060         /// Write metadata to image file only.
0061         WRITETOIMAGEONLY                 = 0,
0062 
0063         /// Write metadata to sidecar file only.
0064         WRITETOSIDECARONLY               = 1,
0065 
0066         /// Write metadata to image and sidecar files.
0067         WRITETOSIDECARANDIMAGE           = 2,
0068 
0069         /// Write metadata to sidecar file only for read only images such as RAW files for example.
0070         WRITETOSIDECARONLY4READONLYFILES = 3
0071     };
0072 
0073     /** The image 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     /** The image orientation values given by Exif metadata.
0084      */
0085     enum ImageOrientation
0086     {
0087         ORIENTATION_UNSPECIFIED  = 0,
0088         ORIENTATION_NORMAL       = 1,
0089         ORIENTATION_HFLIP        = 2,
0090         ORIENTATION_ROT_180      = 3,
0091         ORIENTATION_VFLIP        = 4,
0092         ORIENTATION_ROT_90_HFLIP = 5,
0093         ORIENTATION_ROT_90       = 6,
0094         ORIENTATION_ROT_90_VFLIP = 7,
0095         ORIENTATION_ROT_270      = 8
0096     };
0097 
0098     /**
0099      * Xmp tag types, used by setXmpTag, only first three types are used
0100      */
0101     enum XmpTagType
0102     {
0103         NormalTag               = 0,
0104         ArrayBagTag             = 1,
0105         StructureTag            = 2,
0106         ArrayLangTag            = 3,
0107         ArraySeqTag             = 4
0108     };
0109 
0110     /** A map used to store Tags Key and Tags Value.
0111      */
0112     typedef QMap<QString, QString> MetaDataMap;
0113 
0114     /** A map used to store a list of Alternative Language values.
0115         The map key is the language code following RFC3066 notation
0116         (like "fr-FR" for French), and the map value the text.
0117      */
0118     typedef QMap<QString, QString> AltLangMap;
0119 
0120     /** A map used to store Tags Key and a list of Tags properties :
0121         - name,
0122         - title,
0123         - description.
0124      */
0125     typedef QMap<QString, QStringList> TagsMap;
0126 
0127 public:
0128 
0129     /** Standard constructor.
0130      */
0131     KExiv2();
0132 
0133     /** Copy constructor.
0134      */
0135     KExiv2(const KExiv2& metadata);
0136 
0137     /** Constructor to load from parsed data.
0138      */
0139     KExiv2(const KExiv2Data& data);
0140 
0141     /** Contructor to Load Metadata from image file.
0142      */
0143     KExiv2(const QString& filePath);
0144 
0145     /** Standard destructor
0146      */
0147     virtual ~KExiv2();
0148 
0149     /** Create a copy of container
0150      */
0151     KExiv2& operator=(const KExiv2& metadata);
0152 
0153 public:
0154 
0155     //-----------------------------------------------------------------
0156     /// @name Static methods
0157     //@{
0158 
0159     /** Return true if Exiv2 library initialization is done properly.
0160         This method must be called before using libkexiv2 with multithreading.
0161         It initialize several non re-entrancy code from Adobe XMP SDK
0162         See B.K.O #166424 for details. Call cleanupExiv2() to clean things up later.
0163      */
0164     static bool initializeExiv2();
0165 
0166     /** Return true if Exiv2 library memory allocations are cleaned properly.
0167         This method must be called after using libkexiv2 with multithreading.
0168         It cleans up memory used by Adobe XMP SDK
0169         See B.K.O #166424 for details.
0170      */
0171     static bool cleanupExiv2();
0172 
0173     /** Return true if library can handle Xmp metadata
0174      */
0175     static bool supportXmp();
0176 
0177     /** Return true if library can write metadata to typeMime file format.
0178      */
0179     static bool supportMetadataWritting(const QString& typeMime);
0180 
0181     /** Return a string version of Exiv2 release in format "major.minor.patch"
0182      */
0183     static QString Exiv2Version();
0184 
0185     /** Return a string version of libkexiv2 release
0186      */
0187     static QString version();
0188 
0189     /** Return the XMP Sidecar file path for a image file path.
0190      *  If image file path do not include a file name or is empty, this function return a null string.
0191      */
0192     static QString sidecarFilePathForFile(const QString& path);
0193 
0194     /** Like sidecarFilePathForFile(), but works for local file path.
0195      */
0196     static QString sidecarPath(const QString& path);
0197 
0198     /** Like sidecarFilePathForFile(), but works for remote URLs.
0199      */
0200     static QUrl sidecarUrl(const QUrl& url);
0201 
0202     /** Gives a file url for a local path.
0203      */
0204     static QUrl sidecarUrl(const QString& path);
0205 
0206     /** Performs a QFileInfo based check if the given local file has a sidecar.
0207      */
0208     static bool hasSidecar(const QString& path);
0209 
0210     //@}
0211 
0212     //-----------------------------------------------------------------
0213     /// @name General methods
0214     //@{
0215 
0216     KExiv2Data data() const;
0217     void setData(const KExiv2Data& data);
0218 
0219     /** Load all metadata (Exif, Iptc, Xmp, and JFIF Comments) from a byte array.
0220         Return true if metadata have been loaded successfully from image data.
0221      */
0222     bool loadFromData(const QByteArray& imgData) const;
0223 
0224     /** Load all metadata (Exif, Iptc, Xmp, and JFIF Comments) from a picture (JPEG, RAW, TIFF, PNG,
0225         DNG, etc...). Return true if metadata have been loaded successfully from file.
0226      */
0227     virtual bool load(const QString& filePath) const;
0228 
0229     /** Save all metadata to a file. This one can be different than original picture to perform
0230         transfert operation Return true if metadata have been saved into file.
0231      */
0232     bool save(const QString& filePath) const;
0233 
0234     /** The same than save() method, but it apply on current image. Return true if metadata
0235         have been saved into file.
0236      */
0237     bool applyChanges() const;
0238 
0239     /** Return 'true' if metadata container in memory as no Comments, Exif, Iptc, and Xmp.
0240      */
0241     bool isEmpty() const;
0242 
0243     /** Set the file path of current image.
0244      */
0245     void setFilePath(const QString& path);
0246 
0247     /** Return the file path of current image.
0248      */
0249     QString getFilePath() const;
0250 
0251     /** Returns the pixel size of the current image. This information is read from the file,
0252      *  not from the metadata. The returned QSize is valid if the KExiv2 object was _constructed_
0253      *  by reading a file or image data; the information is not available when the object
0254      *  was created from KExiv2Data.
0255      *  Note that in the Exif or XMP metadata, there may be fields describing the image size.
0256      *  These fields are not accessed by this method.
0257      *  When replacing the metadata with setData(), the metadata may change; this information
0258      *  always keeps referring to the file it was initially read from.
0259      */
0260     QSize getPixelSize() const;
0261 
0262     /** Returns the mime type of this image. The information is read from the file;
0263      *  see the docs for getPixelSize() to know when it is available.
0264      */
0265     QString getMimeType() const;
0266 
0267     /** Enable or disable writing metadata operations to RAW tiff based files.
0268         It requires Exiv2 0.18. By default RAW files are untouched.
0269      */
0270     void setWriteRawFiles(const bool on);
0271 
0272     /** Return true if writing metadata operations on RAW tiff based files is enabled.
0273         It's require Exiv2 0.18.
0274      */
0275     bool writeRawFiles() const;
0276 
0277     /** Enable or disable using XMP sidecar for reading metadata
0278      */
0279     void setUseXMPSidecar4Reading(const bool on);
0280 
0281     /** Return true if using XMP sidecar for reading metadata is enabled.
0282      */
0283     bool useXMPSidecar4Reading() const;
0284 
0285     /** Set metadata writing mode.
0286      * @param mode Metadata writing mode as defined by the #MetadataWritingMode enum.
0287      * @sa MetadataWritingMode, metadataWritingMode()
0288      */
0289     void setMetadataWritingMode(const int mode);
0290 
0291     /** Return the metadata writing mode.
0292      * @returns Metadata writing mode as defined by the #MetadataWritingMode enum.
0293      * @sa MetadataWritingMode, setMetadataWritingMode()
0294      */
0295     int metadataWritingMode() const;
0296 
0297     /** Enable or disable file timestamp updating when metadata are saved.
0298         By default files timestamp are untouched.
0299      */
0300     void setUpdateFileTimeStamp(bool on);
0301 
0302     /** Return true if file timestamp is updated when metadata are saved.
0303      */
0304     bool updateFileTimeStamp() const;
0305 
0306     //@}
0307 
0308     //-------------------------------------------------------------------
0309     /// @name Metadata image information manipulation methods
0310     //@{
0311 
0312     /** Set Program name and program version in Exif and Iptc Metadata. Return true if information
0313         have been changed in metadata.
0314      */
0315     bool setImageProgramId(const QString& program, const QString& version) const;
0316 
0317     /** Return the size of image in pixels using Exif tags. Return a null dimmension if size cannot
0318         be found.
0319      */
0320     QSize getImageDimensions() const;
0321 
0322     /** Set the size of image in pixels in Exif tags. Return true if size have been changed
0323         in metadata.
0324      */
0325     bool setImageDimensions(const QSize& size, bool setProgramName=true) const;
0326 
0327     /** Return the image orientation set in Exif metadata. The makernotes of image are also parsed to
0328         get this information. See ImageOrientation values for details.
0329      */
0330     KExiv2::ImageOrientation getImageOrientation() const;
0331 
0332     /** Set the Exif orientation tag of image. See ImageOrientation values for details
0333         Return true if orientation have been changed in metadata.
0334      */
0335     bool setImageOrientation(ImageOrientation orientation, bool setProgramName=true) const;
0336 
0337     /** Return the image color-space set in Exif metadata. The makernotes of image are also parsed to
0338         get this information. See ImageColorWorkSpace values for details.
0339      */
0340     KExiv2::ImageColorWorkSpace getImageColorWorkSpace() const;
0341 
0342     /** Set the Exif color-space tag of image. See ImageColorWorkSpace values for details
0343         Return true if work-space have been changed in metadata.
0344      */
0345     bool setImageColorWorkSpace(ImageColorWorkSpace workspace, bool setProgramName=true) const;
0346 
0347     /** Return the time stamp of image. Exif information are check in first, IPTC in second
0348         if image don't have Exif information. If no time stamp is found, a null date is returned.
0349      */
0350     QDateTime getImageDateTime() const;
0351 
0352     /** Set the Exif and Iptc time stamp. If 'setDateTimeDigitized' parameter is true, the 'Digitalized'
0353         time stamp is set, else only 'Created' time stamp is set.
0354      */
0355     bool setImageDateTime(const QDateTime& dateTime, bool setDateTimeDigitized=false,
0356                           bool setProgramName=true) const;
0357 
0358     /** Return the digitization time stamp of the image. First Exif information is checked, then IPTC.
0359         If no digitization time stamp is found, getImageDateTime() is called if fallbackToCreationTime
0360         is true, or a null QDateTime is returned if fallbackToCreationTime is false.
0361      */
0362     QDateTime getDigitizationDateTime(bool fallbackToCreationTime=false) const;
0363 
0364     /** Return a QImage copy of Iptc preview image. Return a null image if preview cannot
0365         be found.
0366      */
0367     bool getImagePreview(QImage& preview) const;
0368 
0369     /** Set the Iptc preview image. The thumbnail image must have the right size before (64Kb max
0370         with JPEG file, else 256Kb). Look Iptc specification for details. Return true if preview
0371         have been changed in metadata.
0372         Re-implemente this method if you want to use another image file format than JPEG to
0373         save preview.
0374     */
0375     virtual bool setImagePreview(const QImage& preview, bool setProgramName=true) const;
0376 
0377     //@}
0378 
0379     //-----------------------------------------------------------------
0380     /// @name Comments manipulation methods
0381     //@{
0382 
0383     /** Return 'true' if Comments can be written in file.
0384      */
0385     static bool canWriteComment(const QString& filePath);
0386 
0387     /** Return 'true' if metadata container in memory as Comments.
0388      */
0389     bool hasComments() const;
0390 
0391     /** Clear the Comments metadata container in memory.
0392      */
0393     bool clearComments() const;
0394 
0395     /** Return a Qt byte array copy of Comments container get from current image.
0396         Comments are JFIF section of JPEG images. Look Exiv2 API for more information.
0397         Return a null Qt byte array if there is no Comments metadata in memory.
0398      */
0399     QByteArray getComments() const;
0400 
0401     /** Return a Qt string object of Comments from current image decoded using
0402         the 'detectEncodingAndDecode()' method. Return a null string if there is no
0403         Comments metadata available.
0404      */
0405     QString getCommentsDecoded() const;
0406 
0407     /** Set the Comments data using a Qt byte array. Return true if Comments metadata
0408         have been changed in memory.
0409      */
0410     bool setComments(const QByteArray& data) const;
0411 
0412     /** Language Alternative autodetection. Return a QString without language alternative
0413         header. Header is saved into 'lang'. If no language alternative is founf, value is returned
0414         as well and 'lang' is set to a null string.
0415      */
0416     static QString detectLanguageAlt(const QString& value, QString& lang);
0417 
0418     //@}
0419 
0420     //-----------------------------------------------------------------
0421     /// @name Exif manipulation methods
0422     //@{
0423 
0424     /** Return a map of all standard Exif tags supported by Exiv2.
0425      */
0426     TagsMap getStdExifTagsList() const;
0427 
0428     /** Return a map of all non-standard Exif tags (makernotes) supported by Exiv2.
0429      */
0430     TagsMap getMakernoteTagsList() const;
0431 
0432     /** Return 'true' if Exif can be written in file.
0433      */
0434     static bool canWriteExif(const QString& filePath);
0435 
0436     /** Return 'true' if metadata container in memory as Exif.
0437      */
0438     bool hasExif() const;
0439 
0440     /** Clear the Exif metadata container in memory.
0441      */
0442     bool clearExif() const;
0443 
0444     /** Returns the exif data encoded to a QByteArray in a form suitable
0445         for storage in a JPEG image.
0446         Note that this encoding is a lossy operation.
0447 
0448         Set true 'addExifHeader' parameter to add an Exif header to Exif metadata.
0449         Returns a null Qt byte array if there is no Exif metadata in memory.
0450      */
0451     QByteArray getExifEncoded(bool addExifHeader=false) const;
0452 
0453     /** Set the Exif data using a Qt byte array. Return true if Exif metadata
0454         have been changed in memory.
0455      */
0456     bool setExif(const QByteArray& data) const;
0457 
0458     /** Return a QImage copy of Exif thumbnail image. Return a null image if thumbnail cannot
0459         be found. The 'fixOrientation' parameter will rotate automatically the thumbnail if Exif
0460         orientation tags information are attached with thumbnail.
0461      */
0462     QImage getExifThumbnail(bool fixOrientation) const;
0463 
0464     /** Fix orientation of a QImage image accordingly with Exif orientation tag.
0465         Return true if image is rotated, else false.
0466      */
0467     bool rotateExifQImage(QImage& image, ImageOrientation orientation) const;
0468 
0469     /** Set the Exif Thumbnail image. The thumbnail image must have the right dimensions before.
0470         Look Exif specification for details. Return true if thumbnail have been changed in metadata.
0471      */
0472     bool setExifThumbnail(const QImage& thumb, bool setProgramName=true) const;
0473 
0474     /** Remove the Exif Thumbnail from the image */
0475     bool removeExifThumbnail() const;
0476 
0477     /** Adds a JPEG thumbnail to a TIFF images. Use this instead of setExifThumbnail for TIFF images. */
0478     bool setTiffThumbnail(const QImage& thumb, bool setProgramName=true) const;
0479 
0480     /** Return a QString copy of Exif user comments. Return a null string if user comments cannot
0481         be found.
0482      */
0483     QString getExifComment() const;
0484 
0485     /** Set the Exif user comments from image. Look Exif specification for more details about this tag.
0486         Return true if Exif user comments have been changed in metadata.
0487      */
0488     bool setExifComment(const QString& comment, bool setProgramName=true) const;
0489 
0490     /** Get an Exif tags content like a string. If 'escapeCR' parameter is true, the CR characters
0491         will be removed. If Exif tag cannot be found a null string is returned.
0492      */
0493     QString getExifTagString(const char* exifTagName, bool escapeCR=true) const;
0494 
0495     /** Set an Exif tag content using a string. Return true if tag is set successfully.
0496      */
0497     bool setExifTagString(const char* exifTagName, const QString& value, bool setProgramName=true) const;
0498 
0499     /** Get an Exif tag content like a long value. Return true if Exif tag be found.
0500      */
0501     bool getExifTagLong(const char* exifTagName, long &val) const;
0502 
0503     /** Get an Exif tag content like a long value. Return true if Exif tag be found.
0504      */
0505     bool getExifTagLong(const char* exifTagName, long &val, int component) const;
0506 
0507     /** Set an Exif tag content using a long value. Return true if tag is set successfully.
0508      */
0509     bool setExifTagLong(const char* exifTagName, long val, bool setProgramName=true) const;
0510 
0511     /** Get the 'component' index of an Exif tags content like a rational value.
0512         'num' and 'den' are the numerator and the denominator of the rational value.
0513         Return true if Exif tag be found.
0514      */
0515     bool getExifTagRational(const char* exifTagName, long int& num, long int& den, int component=0) const;
0516 
0517     /** Set an Exif tag content using a rational value.
0518         'num' and 'den' are the numerator and the denominator of the rational value.
0519         Return true if tag is set successfully.
0520      */
0521     bool setExifTagRational(const char* exifTagName, long int num, long int den, bool setProgramName=true) const;
0522 
0523     /** Get an Exif tag content like a bytes array. Return an empty bytes array if Exif
0524         tag cannot be found.
0525      */
0526     QByteArray getExifTagData(const char* exifTagName) const;
0527 
0528     /** Set an Exif tag content using a bytes array. Return true if tag is set successfully.
0529      */
0530     bool setExifTagData(const char* exifTagName, const QByteArray& data, bool setProgramName=true) const;
0531 
0532     /** Get an Exif tags content as a QVariant. Returns a null QVariant if the Exif
0533         tag cannot be found.
0534         For string and integer values the matching QVariant types will be used,
0535         for date and time values QVariant::DateTime.
0536         Rationals will be returned as QVariant::List with two integer QVariants (numerator, denominator)
0537         if rationalAsListOfInts is true, as double if rationalAsListOfInts is false.
0538         An exif tag of numerical type may contain more than one value; set component to the desired index.
0539      */
0540     QVariant getExifTagVariant(const char* exifTagName, bool rationalAsListOfInts=true, bool escapeCR=true, int component=0) const;
0541 
0542     /** Set an Exif tag content using a QVariant. Returns true if tag is set successfully.
0543         All types described for the getExifTagVariant() method are supported.
0544         Calling with a QVariant of type ByteArray is equivalent to calling setExifTagData.
0545         For the meaning of rationalWantSmallDenominator, see the documentation of the convertToRational methods.
0546         Setting a value with multiple components is currently not supported.
0547      */
0548     bool setExifTagVariant(const char* exifTagName, const QVariant& data,
0549                            bool rationalWantSmallDenominator=true, bool setProgramName=true) const;
0550 
0551     /** Remove the Exif tag 'exifTagName' from Exif metadata. Return true if tag is
0552         removed successfully or if no tag was present.
0553      */
0554     bool removeExifTag(const char* exifTagName, bool setProgramName=true) const;
0555 
0556     /** Return the Exif Tag title or a null string.
0557      */
0558     QString getExifTagTitle(const char* exifTagName);
0559 
0560     /** Return the Exif Tag description or a null string.
0561      */
0562     QString getExifTagDescription(const char* exifTagName);
0563 
0564     /** Takes a QVariant value as it could have been retrieved by getExifTagVariant with the given exifTagName,
0565         and returns its value properly converted to a string (including translations from Exiv2).
0566         This is equivalent to calling getExifTagString directly.
0567         If escapeCR is true CR characters will be removed from the result.
0568      */
0569     QString createExifUserStringFromValue(const char* exifTagName, const QVariant& val, bool escapeCR=true);
0570 
0571     /** Return a map of Exif tags name/value found in metadata sorted by
0572         Exif keys given by 'exifKeysFilter'.
0573 
0574         'exifKeysFilter' is a QStringList of Exif keys.
0575         For example, if you use the string list given below:
0576 
0577         "Iop"
0578         "Thumbnail"
0579         "Image"
0580         "Photo"
0581 
0582         List can be empty to not filter output.
0583 
0584         ... this method will return a map of all Exif tags witch :
0585 
0586         - include "Iop", or "Thumbnail", or "Image", or "Photo" in the Exif tag keys
0587           if 'inverSelection' is false.
0588         - not include "Iop", or "Thumbnail", or "Image", or "Photo" in the Exif tag keys
0589           if 'inverSelection' is true.
0590      */
0591     KExiv2::MetaDataMap getExifTagsDataList(const QStringList& exifKeysFilter=QStringList(), bool invertSelection=false) const;
0592 
0593     //@}
0594 
0595     //-------------------------------------------------------------
0596     /// @name IPTC manipulation methods
0597     //@{
0598 
0599     /** Return a map of all standard Iptc tags supported by Exiv2.
0600      */
0601     KExiv2::TagsMap getIptcTagsList() const;
0602 
0603     /** Return 'true' if Iptc can be written in file.
0604      */
0605     static bool canWriteIptc(const QString& filePath);
0606 
0607     /** Return 'true' if metadata container in memory as Iptc.
0608      */
0609     bool hasIptc() const;
0610 
0611     /** Clear the Iptc metadata container in memory.
0612      */
0613     bool clearIptc() const;
0614 
0615     /** Return a Qt byte array copy of Iptc container get from current image.
0616         Set true 'addIrbHeader' parameter to add an Irb header to Iptc metadata.
0617         Return a null Qt byte array if there is no Iptc metadata in memory.
0618      */
0619     QByteArray  getIptc(bool addIrbHeader=false) const;
0620 
0621     /** Set the Iptc data using a Qt byte array. Return true if Iptc metadata
0622         have been changed in memory.
0623      */
0624     bool setIptc(const QByteArray& data) const;
0625 
0626     /** Get an Iptc tag content like a string. If 'escapeCR' parameter is true, the CR characters
0627         will be removed. If Iptc tag cannot be found a null string is returned.
0628      */
0629     QString getIptcTagString(const char* iptcTagName, bool escapeCR=true) const;
0630 
0631     /** Set an Iptc tag content using a string. Return true if tag is set successfully.
0632      */
0633     bool setIptcTagString(const char* iptcTagName, const QString& value, bool setProgramName=true) const;
0634 
0635     /** Returns a strings list with of multiple Iptc tags from the image. Return an empty list if no tag is found. */
0636     /** Get the values of all IPTC tags with the given tag name in a string list.
0637         (In Iptc, there can be multiple tags with the same name)
0638         If the 'escapeCR' parameter is true, the CR characters
0639         will be removed.
0640         If no tag can be found an empty list is returned.
0641      */
0642     QStringList getIptcTagsStringList(const char* iptcTagName, bool escapeCR=true) const;
0643 
0644     /** Set multiple Iptc tags contents using a strings list. 'maxSize' is the max characters size
0645         of one entry. Return true if all tags have been set successfully.
0646      */
0647     bool setIptcTagsStringList(const char* iptcTagName, int maxSize,
0648                                const QStringList& oldValues, const QStringList& newValues,
0649                                bool setProgramName=true) const;
0650 
0651     /** Get an Iptc tag content as a bytes array. Return an empty bytes array if Iptc
0652         tag cannot be found.
0653      */
0654     QByteArray getIptcTagData(const char* iptcTagName) const;
0655 
0656     /** Set an Iptc tag content using a bytes array. Return true if tag is set successfully.
0657      */
0658     bool setIptcTagData(const char* iptcTagName, const QByteArray& data, bool setProgramName=true) const;
0659 
0660     /** Remove the all instance of Iptc tags 'iptcTagName' from Iptc metadata. Return true if all
0661         tags have been removed successfully (or none were present).
0662      */
0663     bool removeIptcTag(const char* iptcTagName, bool setProgramName=true) const;
0664 
0665     /** Return the Iptc Tag title or a null string.
0666      */
0667     QString getIptcTagTitle(const char* iptcTagName);
0668 
0669     /** Return the Iptc Tag description or a null string.
0670      */
0671     QString getIptcTagDescription(const char* iptcTagName);
0672 
0673     /** Return a map of Iptc tags name/value found in metadata sorted by
0674         Iptc keys given by 'iptcKeysFilter'.
0675 
0676         'iptcKeysFilter' is a QStringList of Iptc keys.
0677         For example, if you use the string list given below:
0678 
0679         "Envelope"
0680         "Application2"
0681 
0682         List can be empty to not filter output.
0683 
0684         ... this method will return a map of all Iptc tags witch :
0685 
0686         - include "Envelope", or "Application2" in the Iptc tag keys
0687           if 'inverSelection' is false.
0688         - not include "Envelope", or "Application2" in the Iptc tag keys
0689           if 'inverSelection' is true.
0690      */
0691     KExiv2::MetaDataMap getIptcTagsDataList(const QStringList& iptcKeysFilter=QStringList(), bool invertSelection=false) const;
0692 
0693     /** Return a strings list of Iptc keywords from image. Return an empty list if no keyword are set.
0694      */
0695     QStringList getIptcKeywords() const;
0696 
0697     /** Set Iptc keywords using a list of strings defined by 'newKeywords' parameter. Use 'getImageKeywords()'
0698         method to set 'oldKeywords' parameter with existing keywords from image. The method will compare
0699         all new keywords with all old keywords to prevent duplicate entries in image. Return true if keywords
0700         have been changed in metadata.
0701      */
0702     bool setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords,
0703                          bool setProgramName=true) const;
0704 
0705     /** Return a strings list of Iptc subjects from image. Return an empty list if no subject are set.
0706      */
0707     QStringList getIptcSubjects() const;
0708 
0709     /** Set Iptc subjects using a list of strings defined by 'newSubjects' parameter. Use 'getImageSubjects()'
0710         method to set 'oldSubjects' parameter with existing subjects from image. The method will compare
0711         all new subjects with all old subjects to prevent duplicate entries in image. Return true if subjects
0712         have been changed in metadata.
0713      */
0714     bool setIptcSubjects(const QStringList& oldSubjects, const QStringList& newSubjects,
0715                          bool setProgramName=true) const;
0716 
0717     /** Return a strings list of Iptc sub-categories from image. Return an empty list if no sub-category
0718         are set.
0719      */
0720     QStringList getIptcSubCategories() const;
0721 
0722     /** Set Iptc sub-categories using a list of strings defined by 'newSubCategories' parameter. Use
0723         'getImageSubCategories()' method to set 'oldSubCategories' parameter with existing sub-categories
0724         from image. The method will compare all new sub-categories with all old sub-categories to prevent
0725         duplicate entries in image. Return true if sub-categories have been changed in metadata.
0726      */
0727     bool setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories,
0728                               bool setProgramName=true) const;
0729 
0730     //@}
0731 
0732     //------------------------------------------------------------
0733     /// @name XMP manipulation methods
0734     //@{
0735 
0736     /** Return a map of all standard Xmp tags supported by Exiv2.
0737      */
0738     KExiv2::TagsMap getXmpTagsList() const;
0739 
0740     /** Return 'true' if Xmp can be written in file.
0741      */
0742     static bool canWriteXmp(const QString& filePath);
0743 
0744     /** Return 'true' if metadata container in memory as Xmp.
0745      */
0746     bool hasXmp() const;
0747 
0748     /** Clear the Xmp metadata container in memory.
0749      */
0750     bool clearXmp() const;
0751 
0752     /** Return a Qt byte array copy of XMp container get from current image.
0753         Return a null Qt byte array if there is no Xmp metadata in memory.
0754      */
0755     QByteArray getXmp() const;
0756 
0757     /** Set the Xmp data using a Qt byte array. Return true if Xmp metadata
0758         have been changed in memory.
0759      */
0760     bool setXmp(const QByteArray& data) const;
0761 
0762     /** Get a Xmp tag content like a string. If 'escapeCR' parameter is true, the CR characters
0763         will be removed. If Xmp tag cannot be found a null string is returned.
0764      */
0765     QString getXmpTagString(const char* xmpTagName, bool escapeCR=true) const;
0766 
0767     /** Set a Xmp tag content using a string. Return true if tag is set successfully.
0768      */
0769     bool setXmpTagString(const char* xmpTagName, const QString& value,
0770                          bool setProgramName=true) const;
0771 
0772     /** Set a Xmp tag with a specific type. Return true if tag is set successfully.
0773      *  This method only accept NormalTag, ArrayBagTag and StructureTag.
0774      *  Other XmpTagTypes do nothing
0775      */
0776     bool setXmpTagString(const char* xmpTagName, const QString& value,
0777                          XmpTagType type,bool setProgramName=true) const;
0778 
0779     /** Return the Xmp Tag title or a null string.
0780      */
0781     QString getXmpTagTitle(const char* xmpTagName);
0782 
0783     /** Return the Xmp Tag description or a null string.
0784      */
0785     QString getXmpTagDescription(const char* xmpTagName);
0786 
0787     /** Return a map of Xmp tags name/value found in metadata sorted by
0788         Xmp keys given by 'xmpKeysFilter'.
0789 
0790         'xmpKeysFilter' is a QStringList of Xmp keys.
0791         For example, if you use the string list given below:
0792 
0793         "dc"           // Dubling Core schema.
0794         "xmp"          // Standard Xmp schema.
0795 
0796         List can be empty to not filter output.
0797 
0798         ... this method will return a map of all Xmp tags witch :
0799 
0800         - include "dc", or "xmp" in the Xmp tag keys
0801           if 'inverSelection' is false.
0802         - not include "dc", or "xmp" in the Xmp tag keys
0803           if 'inverSelection' is true.
0804      */
0805     KExiv2::MetaDataMap getXmpTagsDataList(const QStringList& xmpKeysFilter=QStringList(), bool invertSelection=false) const;
0806 
0807     /** Get all redondant Alternative Language Xmp tags content like a map.
0808         See AltLangMap class description for details.
0809         If 'escapeCR' parameter is true, the CR characters will be removed from strings.
0810         If Xmp tag cannot be found a null string list is returned.
0811      */
0812     KExiv2::AltLangMap getXmpTagStringListLangAlt(const char* xmpTagName, bool escapeCR=true) const;
0813 
0814     /** Set an Alternative Language Xmp tag content using a map. See AltLangMap class
0815         description for details. If tag already exist, it wil be removed before.
0816         Return true if tag is set successfully.
0817      */
0818     bool setXmpTagStringListLangAlt(const char* xmpTagName, const KExiv2::AltLangMap& values,
0819                                     bool setProgramName) const;
0820 
0821     /** Get a Xmp tag content like a string set with an alternative language
0822         header 'langAlt' (like "fr-FR" for French - RFC3066 notation)
0823         If 'escapeCR' parameter is true, the CR characters will be removed.
0824         If Xmp tag cannot be found a null string is returned.
0825      */
0826     QString getXmpTagStringLangAlt(const char* xmpTagName, const QString& langAlt, bool escapeCR) const;
0827 
0828     /** Set a Xmp tag content using a string with an alternative language header. 'langAlt' contain the
0829         language alternative information (like "fr-FR" for French - RFC3066 notation) or is null to
0830         set alternative language to default settings ("x-default").
0831         Return true if tag is set successfully.
0832      */
0833     bool setXmpTagStringLangAlt(const char* xmpTagName, const QString& value,
0834                                 const QString& langAlt, bool setProgramName=true) const;
0835 
0836     /** Get a Xmp tag content like a sequence of strings. If 'escapeCR' parameter is true, the CR characters
0837         will be removed from strings. If Xmp tag cannot be found a null string list is returned.
0838      */
0839     QStringList getXmpTagStringSeq(const char* xmpTagName, bool escapeCR=true) const;
0840 
0841     /** Set a Xmp tag content using the sequence of strings 'seq'.
0842         Return true if tag is set successfully.
0843      */
0844     bool setXmpTagStringSeq(const char* xmpTagName, const QStringList& seq,
0845                             bool setProgramName=true) const;
0846 
0847     /** Get a Xmp tag content like a bag of strings. If 'escapeCR' parameter is true, the CR characters
0848         will be removed from strings. If Xmp tag cannot be found a null string list is returned.
0849      */
0850     QStringList getXmpTagStringBag(const char* xmpTagName, bool escapeCR) const;
0851 
0852     /** Set a Xmp tag content using the bag of strings 'bag'.
0853         Return true if tag is set successfully.
0854      */
0855     bool setXmpTagStringBag(const char* xmpTagName, const QStringList& bag,
0856                             bool setProgramName=true) const;
0857 
0858     /** Set an Xmp tag content using a list of strings defined by the 'entriesToAdd' parameter.
0859         The existing entries are preserved. The method will compare
0860         all new with all already existing entries to prevent duplicates in the image.
0861         Return true if the entries have been added to metadata.
0862      */
0863     bool addToXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToAdd,
0864                               bool setProgramName) const;
0865 
0866     /** Remove those Xmp tag entries that are listed in entriesToRemove from the entries in metadata.
0867         Return true if tag entries are no longer contained in metadata.
0868         All other entries are preserved.
0869      */
0870     bool removeFromXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToRemove,
0871                                    bool setProgramName) const;
0872 
0873     /** Get an Xmp tag content as a QVariant. Returns a null QVariant if the Xmp
0874         tag cannot be found.
0875         For string and integer values the matching QVariant types will be used,
0876         for date and time values QVariant::DateTime.
0877         Rationals will be returned as QVariant::List with two integer QVariants (numerator, denominator)
0878         if rationalAsListOfInts is true, as double if rationalAsListOfInts is false.
0879         Arrays (ordered, unordered, alternative) are returned as type StringList.
0880         LangAlt values will have type Map (QMap<QString, QVariant>) with the language
0881         code as key and the contents as value, of type String.
0882      */
0883     QVariant getXmpTagVariant(const char* xmpTagName, bool rationalAsListOfInts=true, bool stringEscapeCR=true) const;
0884 
0885     /** Return a strings list of Xmp keywords from image. Return an empty list if no keyword are set.
0886      */
0887     QStringList getXmpKeywords() const;
0888 
0889     /** Set Xmp keywords using a list of strings defined by 'newKeywords' parameter.
0890         The existing keywords from image are preserved. The method will compare
0891         all new keywords with all already existing keywords to prevent duplicate entries in image.
0892         Return true if keywords have been changed in metadata.
0893      */
0894     bool setXmpKeywords(const QStringList& newKeywords, bool setProgramName=true) const;
0895 
0896     /** Remove those Xmp keywords that are listed in keywordsToRemove from the keywords in metadata.
0897         Return true if keywords are no longer contained in metadata.
0898      */
0899     bool removeXmpKeywords(const QStringList& keywordsToRemove, bool setProgramName=true);
0900 
0901     /** Return a strings list of Xmp subjects from image. Return an empty list if no subject are set.
0902      */
0903     QStringList getXmpSubjects() const;
0904 
0905     /** Set Xmp subjects using a list of strings defined by 'newSubjects' parameter.
0906         The existing subjects from image are preserved. The method will compare
0907         all new subject with all already existing subject to prevent duplicate entries in image.
0908         Return true if subjects have been changed in metadata.
0909      */
0910     bool setXmpSubjects(const QStringList& newSubjects, bool setProgramName=true) const;
0911 
0912     /** Remove those Xmp subjects that are listed in subjectsToRemove from the subjects in metadata.
0913         Return true if subjects are no longer contained in metadata.
0914      */
0915     bool removeXmpSubjects(const QStringList& subjectsToRemove, bool setProgramName=true);
0916 
0917     /** Return a strings list of Xmp sub-categories from image. Return an empty list if no sub-category
0918         are set.
0919      */
0920     QStringList getXmpSubCategories() const;
0921 
0922     /** Set Xmp sub-categories using a list of strings defined by 'newSubCategories' parameter.
0923         The existing sub-categories from image are preserved. The method will compare
0924         all new sub-categories with all already existing sub-categories to prevent duplicate entries in image.
0925         Return true if sub-categories have been changed in metadata.
0926      */
0927     bool setXmpSubCategories(const QStringList& newSubCategories, bool setProgramName=true) const;
0928 
0929     /** Remove those Xmp sub-categories that are listed in categoriesToRemove from the sub-categories in metadata.
0930         Return true if subjects are no longer contained in metadata.
0931      */
0932     bool removeXmpSubCategories(const QStringList& categoriesToRemove, bool setProgramName=true);
0933 
0934     /** Remove the Xmp tag 'xmpTagName' from Xmp metadata. Return true if tag is
0935         removed successfully or if no tag was present.
0936      */
0937     bool removeXmpTag(const char* xmpTagName, bool setProgramName=true) const;
0938 
0939 
0940     /** Register a namespace which Exiv2 doesn't know yet. This is only needed
0941         when new Xmp properties are added manually. 'uri' is the namespace url and prefix the
0942         string used to construct new Xmp key.
0943         NOTE: If the Xmp metadata is read from an image, namespaces are decoded and registered
0944         by Exiv2 at the same time.
0945      */
0946     static bool registerXmpNameSpace(const QString& uri, const QString& prefix);
0947 
0948     /** Unregister a previously registered custom namespace */
0949     static bool unregisterXmpNameSpace(const QString& uri);
0950 
0951     //@}
0952 
0953     //------------------------------------------------------------
0954     /// @name GPS manipulation methods
0955     //@{
0956 
0957     /** Make sure all static required GPS EXIF and XMP tags exist
0958      */
0959     bool initializeGPSInfo(const bool setProgramName);
0960 
0961     /** Get all GPS location information set in image. Return true if all information can be found.
0962      */
0963     bool getGPSInfo(double& altitude, double& latitude, double& longitude) const;
0964 
0965     /** Get GPS location information set in the image, in the GPSCoordinate format
0966         as described in the XMP specification. Returns a null string in the information cannot be found.
0967      */
0968     QString getGPSLatitudeString() const;
0969     QString getGPSLongitudeString() const;
0970 
0971     /** Get GPS location information set in the image, as a double floating point number as in degrees
0972         where the sign determines the direction ref (North + / South - ; East + / West -).
0973         Returns true if the information is available.
0974     */
0975     bool getGPSLatitudeNumber(double* const latitude) const;
0976     bool getGPSLongitudeNumber(double* const longitude) const;
0977 
0978     /** Get GPS altitude information, in meters, relative to sea level (positive sign above sea level)
0979      */
0980     bool getGPSAltitude(double* const altitude) const;
0981 
0982     /** Set all GPS location information into image. Return true if all information have been
0983         changed in metadata.
0984      */
0985     bool setGPSInfo(const double altitude, const double latitude, const double longitude, const bool setProgramName=true);
0986 
0987     /** Set all GPS location information into image. Return true if all information have been
0988         changed in metadata. If you do not want altitude to be set, pass a null pointer.
0989      */
0990     bool setGPSInfo(const double* const altitude, const double latitude, const double longitude, const bool setProgramName=true);
0991 
0992     /** Set all GPS location information into image. Return true if all information have been
0993         changed in metadata.
0994      */
0995     bool setGPSInfo(const double altitude, const QString &latitude, const QString &longitude, const bool setProgramName=true);
0996 
0997     /** Remove all Exif tags relevant of GPS location information. Return true if all tags have been
0998         removed successfully in metadata.
0999      */
1000     bool removeGPSInfo(const bool setProgramName=true);
1001 
1002     /** This method converts 'number' to a rational value, returned in the 'numerator' and
1003         'denominator' parameters. Set the precision using 'rounding' parameter.
1004         Use this method if you want to retrieve a most exact rational for a number
1005         without further properties, without any requirements to the denominator.
1006      */
1007     static void convertToRational(const double number, long int* const numerator,
1008                                   long int* const denominator, const int rounding);
1009 
1010     /** This method convert a 'number' to a rational value, returned in 'numerator' and
1011         'denominator' parameters.
1012         This method will be able to retrieve a rational number from a double - if you
1013         constructed your double with 1.0 / 4786.0, this method will retrieve 1 / 4786.
1014         If your number is not expected to be rational, use the method above which is just as
1015         exact with rounding = 4 and more exact with rounding > 4.
1016      */
1017     static void convertToRationalSmallDenominator(const double number, long int* const numerator,
1018                                                   long int* const denominator);
1019 
1020     /** Converts a GPS position stored as rationals in Exif to the form described
1021         as GPSCoordinate in the XMP specification, either in the from "256,45,34N" or "256,45.566667N"
1022      */
1023     static QString convertToGPSCoordinateString(const long int numeratorDegrees, const long int denominatorDegrees,
1024                                                 const long int numeratorMinutes, const long int denominatorMinutes,
1025                                                 const long int numeratorSeconds, long int denominatorSeconds,
1026                                                 const char directionReference);
1027 
1028     /** Converts a GPS position stored as double floating point number in degrees to the form described
1029         as GPSCoordinate in the XMP specification.
1030      */
1031     static QString convertToGPSCoordinateString(const bool isLatitude, double coordinate);
1032 
1033     /** Converts a GPSCoordinate string as defined by XMP to three rationals and the direction reference.
1034         Returns true if the conversion was successful.
1035         If minutes is given in the fractional form, a denominator of 1000000 for the minutes will be used.
1036      */
1037     static bool convertFromGPSCoordinateString(const QString& coordinate,
1038                                                long int* const numeratorDegrees, long int* const denominatorDegrees,
1039                                                long int* const numeratorMinutes, long int* const denominatorMinutes,
1040                                                long int* const numeratorSeconds, long int* const denominatorSeconds,
1041                                                char* const directionReference);
1042 
1043     /** Convert a GPSCoordinate string as defined by XMP to a double floating point number in degrees
1044         where the sign determines the direction ref (North + / South - ; East + / West -).
1045         Returns true if the conversion was successful.
1046      */
1047     static bool convertFromGPSCoordinateString(const QString& gpsString, double* const coordinate);
1048 
1049     /** Converts a GPSCoordinate string to user presentable numbers, integer degrees and minutes and
1050         double floating point seconds, and a direction reference ('N' or 'S', 'E' or 'W')
1051      */
1052     static bool convertToUserPresentableNumbers(const QString& coordinate,
1053                                                 int* const degrees, int* const minutes,
1054                                                 double* const seconds, char* const directionReference);
1055 
1056     /** Converts a double floating point number to user presentable numbers, integer degrees and minutes and
1057         double floating point seconds, and a direction reference ('N' or 'S', 'E' or 'W').
1058         The method needs to know for the direction reference
1059         if the latitude or the longitude is meant by the double parameter.
1060      */
1061     static void convertToUserPresentableNumbers(const bool isLatitude, double coordinate,
1062                                                 int* const degrees, int* const minutes,
1063                                                 double* const seconds, char* const directionReference);
1064 
1065     //@}
1066 
1067 protected:
1068 
1069     /** Re-implement this method to set automatically the Program Name and Program Version
1070         information in Exif and Iptc metadata if 'on' argument is true. This method is called by all methods which
1071         change tags in metadata. By default this method does nothing and returns true.
1072      */
1073     virtual bool setProgramId(bool on=true) const;
1074 
1075 private:
1076 
1077     /** Internal container to store private members. Used to improve binary compatibility
1078      */
1079     std::unique_ptr<class KExiv2Private> const d;
1080 
1081     friend class KExiv2Previews;
1082 };
1083 
1084 }  // NameSpace KExiv2Iface
1085 
1086 #endif /* KEXIV2_H */