digiKam
metaengine.h
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date : 2006-09-15
7  * Description : Exiv2 library interface
8  * Exiv2: https://www.exiv2.org
9  * Exif : https://www.exif.org/Exif2-2.PDF
10  * Iptc : https://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
11  * Xmp : https://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf
12  * https://www.iptc.org/std/Iptc4xmpCore/1.0/specification/Iptc4xmpCore_1.0-spec-XMPSchema_8.pdf
13  * Paper: www.metadataworkinggroup.com/pdf/mwg_guidance.pdf
14  *
15  * Copyright (C) 2006-2022 by Gilles Caulier <caulier dot gilles at gmail dot com>
16  * Copyright (C) 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
17  *
18  * This program is free software; you can redistribute it
19  * and/or modify it under the terms of the GNU General
20  * Public License as published by the Free Software Foundation;
21  * either version 2, or (at your option)
22  * any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * ============================================================ */
30 
31 #ifndef DIGIKAM_META_ENGINE_H
32 #define DIGIKAM_META_ENGINE_H
33 
34 // QT includes
35 
36 #include <QByteArray>
37 #include <QString>
38 #include <QDateTime>
39 #include <QMap>
40 #include <QSharedDataPointer>
41 #include <QStringList>
42 #include <QVariant>
43 #include <QRegularExpression>
44 #include <QUrl>
45 #include <QImage>
46 
47 // Local includes
48 
49 #include "metaengine_data.h"
50 #include "digikam_export.h"
51 
52 namespace Digikam
53 {
54 
55 // TODO: merge with DMetadata class.
56 
57 class DIGIKAM_EXPORT MetaEngine
58 {
59 
60 public:
61 
67  {
69  WRITE_TO_FILE_ONLY = 0,
70 
72  WRITE_TO_SIDECAR_ONLY = 1,
73 
75  WRITE_TO_SIDECAR_AND_FILE = 2,
76 
78  WRITE_TO_SIDECAR_ONLY_FOR_READ_ONLY_FILES = 3
79  };
80 
85  {
86  WORKSPACE_UNSPECIFIED = 0,
87  WORKSPACE_SRGB = 1,
88  WORKSPACE_ADOBERGB = 2,
89  WORKSPACE_UNCALIBRATED = 65535
90  };
91 
96  {
97  ORIENTATION_UNSPECIFIED = 0,
98  ORIENTATION_NORMAL = 1,
99  ORIENTATION_HFLIP = 2,
100  ORIENTATION_ROT_180 = 3,
101  ORIENTATION_VFLIP = 4,
102  ORIENTATION_ROT_90_HFLIP = 5,
103  ORIENTATION_ROT_90 = 6,
104  ORIENTATION_ROT_90_VFLIP = 7,
105  ORIENTATION_ROT_270 = 8
106  };
107 
112  {
113  NormalTag = 0,
114  ArrayBagTag = 1,
115  StructureTag = 2,
116  ArrayLangTag = 3,
117  ArraySeqTag = 4
118  };
119 
123  enum Backend
124  {
125  Exiv2Backend = 0,
130  NoBackend
131  };
132 
136  typedef QMap<QString, QString> MetaDataMap;
137 
143  typedef QMap<QString, QString> AltLangMap;
144 
151  typedef QMap<QString, QStringList> TagsMap;
152 
153 public:
154 
158  MetaEngine();
159 
163  explicit MetaEngine(const MetaEngineData& data);
164 
168  explicit MetaEngine(const QString& filePath);
169 
173  virtual ~MetaEngine();
174 
175 public:
176 
177  //-----------------------------------------------------------------
179 
180 
188  static bool initializeExiv2();
189 
193  static bool supportXmp();
194 
200  static bool supportBmff();
201 
205  static bool supportMetadataWriting(const QString& typeMime);
206 
210  static QString Exiv2Version();
211 
213 
214  //-----------------------------------------------------------------
216 
217 
218  MetaEngineData data() const;
219  void setData(const MetaEngineData& data);
220 
225  bool loadFromData(const QByteArray& imgData);
226 
230  bool isEmpty() const;
231 
242  QSize getPixelSize() const;
243 
248  QString getMimeType() const;
249 
254  void setWriteRawFiles(const bool on);
255 
260  bool writeRawFiles() const;
261 
265  void setWriteDngFiles(const bool on);
266 
270  bool writeDngFiles() const;
271 
275  void setUseXMPSidecar4Reading(const bool on);
276 
280  bool useXMPSidecar4Reading() const;
281 
285  void setUseCompatibleFileName(const bool on);
286 
290  bool useCompatibleFileName() const;
291 
297  void setMetadataWritingMode(const int mode);
298 
304  int metadataWritingMode() const;
305 
310  void setUpdateFileTimeStamp(bool on);
311 
315  bool updateFileTimeStamp() const;
316 
318 
319  //-------------------------------------------------------------------
321 
322 
326  void setFilePath(const QString& path);
327 
331  QString getFilePath() const;
332 
337  static QString sidecarFilePathForFile(const QString& path, bool useLR = false);
338 
342  static QString sidecarPath(const QString& path);
343 
347  static QUrl sidecarUrl(const QUrl& url);
348 
352  static QUrl sidecarUrl(const QString& path);
353 
357  static bool hasSidecar(const QString& path);
358 
363  static QString backendName(Backend t);
364 
371  bool load(const QString& filePath, Backend* backend = nullptr);
372 
377  bool loadFromSidecarAndMerge(const QString& filePath);
378 
383  bool save(const QString& filePath, bool setVersion = false) const;
384 
389  bool applyChanges(bool setVersion = false) const;
390 
397  bool exportChanges(const QString& exvTmpFile, QStringList& removedTags) const;
398 
400 
401  //-------------------------------------------------------------------
403 
404 
409  bool setItemProgramId(const QString& program, const QString& version) const;
410 
415  QSize getItemDimensions() const;
416 
421  bool setItemDimensions(const QSize& size) const;
422 
427  MetaEngine::ImageOrientation getItemOrientation() const;
428 
433  bool setItemOrientation(ImageOrientation orientation) const;
434 
439  MetaEngine::ImageColorWorkSpace getItemColorWorkSpace() const;
440 
445  bool setItemColorWorkSpace(ImageColorWorkSpace workspace) const;
446 
451  QDateTime getItemDateTime() const;
452 
457  bool setImageDateTime(const QDateTime& dateTime, bool setDateTimeDigitized = false) const;
458 
464  QDateTime getDigitizationDateTime(bool fallbackToCreationTime = false) const;
465 
470  bool getItemPreview(QImage& preview) const;
471 
479  bool setItemPreview(const QImage& preview) const;
480 
482 
483  //-----------------------------------------------------------------
485 
486 
490  static bool canWriteComment(const QString& filePath);
491 
495  bool hasComments() const;
496 
500  bool clearComments() const;
501 
507  QByteArray getComments() const;
508 
514  QString getCommentsDecoded() const;
515 
520  bool setComments(const QByteArray& data) const;
521 
527  static QString detectLanguageAlt(const QString& value, QString& lang);
528 
530 
531  //-----------------------------------------------------------------
533 
534 
538  TagsMap getStdExifTagsList() const;
539 
543  TagsMap getMakernoteTagsList() const;
544 
548  static bool canWriteExif(const QString& filePath);
549 
553  bool hasExif() const;
554 
558  bool clearExif() const;
559 
568  QByteArray getExifEncoded(bool addExifHeader = false) const;
569 
574  bool setExif(const QByteArray& data) const;
575 
581  QImage getExifThumbnail(bool fixOrientation) const;
582 
587  bool rotateExifQImage(QImage& image, ImageOrientation orientation) const;
588 
593  bool setExifThumbnail(const QImage& thumb) const;
594 
598  bool removeExifThumbnail() const;
599 
603  bool setTiffThumbnail(const QImage& thumb) const;
604 
609  QString getExifComment(bool readDescription = true) const;
610 
615  bool setExifComment(const QString& comment, bool writeDescription = true) const;
616 
621  QString getExifTagString(const char* exifTagName, bool escapeCR = true) const;
622 
626  bool setExifTagString(const char* exifTagName, const QString& value) const;
627 
631  bool getExifTagLong(const char* exifTagName, long &val) const;
632 
636  bool getExifTagLong(const char* exifTagName, long &val, int component) const;
637 
641  bool setExifTagLong(const char* exifTagName, long val) const;
642 
648  bool getExifTagRational(const char* exifTagName, long int& num, long int& den, int component = 0) const;
649 
655  bool setExifTagRational(const char* exifTagName, long int num, long int den) const;
656 
661  QByteArray getExifTagData(const char* exifTagName) const;
662 
666  bool setExifTagData(const char* exifTagName, const QByteArray& data) const;
667 
677  QVariant getExifTagVariant(const char* exifTagName, bool rationalAsListOfInts = true,
678  bool escapeCR = true, int component = 0) const;
679 
687  bool setExifTagVariant(const char* exifTagName, const QVariant& data,
688  bool rationalWantSmallDenominator = true) const;
689 
694  bool removeExifTag(const char* exifTagName) const;
695 
699  QString getExifTagTitle(const char* exifTagName);
700 
704  QString getExifTagDescription(const char* exifTagName);
705 
712  QString createExifUserStringFromValue(const char* exifTagName, const QVariant& val, bool escapeCR = true);
713 
738  MetaEngine::MetaDataMap getExifTagsDataList(const QStringList& exifKeysFilter = QStringList(),
739  bool invertSelection = false,
740  bool extractBinary = true) const;
741 
743 
744  //-------------------------------------------------------------
746 
747 
751  MetaEngine::TagsMap getIptcTagsList() const;
752 
756  static bool canWriteIptc(const QString& filePath);
757 
761  bool hasIptc() const;
762 
766  bool clearIptc() const;
767 
773  QByteArray getIptc(bool addIrbHeader = false) const;
774 
779  bool setIptc(const QByteArray& data) const;
780 
785  QString getIptcTagString(const char* iptcTagName, bool escapeCR = true) const;
786 
790  bool setIptcTagString(const char* iptcTagName, const QString& value) const;
791 
800  QStringList getIptcTagsStringList(const char* iptcTagName, bool escapeCR = true) const;
801 
806  bool setIptcTagsStringList(const char* iptcTagName, int maxSize,
807  const QStringList& oldValues, const QStringList& newValues) const;
808 
813  QByteArray getIptcTagData(const char* iptcTagName) const;
814 
818  bool setIptcTagData(const char* iptcTagName, const QByteArray& data) const;
819 
824  bool removeIptcTag(const char* iptcTagName) const;
825 
829  QString getIptcTagTitle(const char* iptcTagName);
830 
834  QString getIptcTagDescription(const char* iptcTagName);
835 
855  MetaEngine::MetaDataMap getIptcTagsDataList(const QStringList& iptcKeysFilter = QStringList(),
856  bool invertSelection = false) const;
857 
861  QStringList getIptcKeywords() const;
862 
869  bool setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords) const;
870 
874  QStringList getIptcSubjects() const;
875 
882  bool setIptcSubjects(const QStringList& oldSubjects, const QStringList& newSubjects) const;
883 
888  QStringList getIptcSubCategories() const;
889 
896  bool setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories) const;
897 
899 
900  //------------------------------------------------------------
902 
903 
907  MetaEngine::TagsMap getXmpTagsList() const;
908 
912  static bool canWriteXmp(const QString& filePath);
913 
917  bool hasXmp() const;
918 
922  bool clearXmp() const;
923 
928  QByteArray getXmp() const;
929 
934  bool setXmp(const QByteArray& data) const;
935 
940  QString getXmpTagString(const char* xmpTagName, bool escapeCR = true) const;
941 
945  bool setXmpTagString(const char* xmpTagName, const QString& value) const;
946 
952  bool setXmpTagString(const char* xmpTagName, const QString& value,
953  XmpTagType type) const;
954 
958  QString getXmpTagTitle(const char* xmpTagName);
959 
963  QString getXmpTagDescription(const char* xmpTagName);
964 
984  MetaEngine::MetaDataMap getXmpTagsDataList(const QStringList& xmpKeysFilter = QStringList(),
985  bool invertSelection = false) const;
986 
993  MetaEngine::AltLangMap getXmpTagStringListLangAlt(const char* xmpTagName,
994  bool escapeCR = true) const;
995 
1001  bool setXmpTagStringListLangAlt(const char* xmpTagName, const MetaEngine::AltLangMap& values) const;
1002 
1009  QString getXmpTagStringLangAlt(const char* xmpTagName, const QString& langAlt, bool escapeCR) const;
1010 
1017  bool setXmpTagStringLangAlt(const char* xmpTagName, const QString& value,
1018  const QString& langAlt) const;
1019 
1024  QStringList getXmpTagStringSeq(const char* xmpTagName, bool escapeCR = true) const;
1025 
1030  bool setXmpTagStringSeq(const char* xmpTagName, const QStringList& seq) const;
1031 
1036  QStringList getXmpTagStringBag(const char* xmpTagName, bool escapeCR) const;
1037 
1042  bool setXmpTagStringBag(const char* xmpTagName, const QStringList& bag) const;
1043 
1050  bool addToXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToAdd) const;
1051 
1057  bool removeFromXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToRemove) const;
1058 
1070  QVariant getXmpTagVariant(const char* xmpTagName, bool rationalAsListOfInts = true, bool stringEscapeCR = true) const;
1071 
1075  QStringList getXmpKeywords() const;
1076 
1083  bool setXmpKeywords(const QStringList& newKeywords) const;
1084 
1089  bool removeXmpKeywords(const QStringList& keywordsToRemove);
1090 
1094  QStringList getXmpSubjects() const;
1095 
1102  bool setXmpSubjects(const QStringList& newSubjects) const;
1103 
1108  bool removeXmpSubjects(const QStringList& subjectsToRemove);
1109 
1114  QStringList getXmpSubCategories() const;
1115 
1122  bool setXmpSubCategories(const QStringList& newSubCategories) const;
1123 
1128  bool removeXmpSubCategories(const QStringList& categoriesToRemove);
1129 
1134  bool removeXmpTag(const char* xmpTagName, bool family = false) const;
1135 
1143  static bool registerXmpNameSpace(const QString& uri, const QString& prefix);
1144 
1148  static bool unregisterXmpNameSpace(const QString& uri);
1149 
1151 
1152  //------------------------------------------------------------
1154 
1155 
1159  bool initializeGPSInfo();
1160 
1164  bool getGPSInfo(double& altitude, double& latitude, double& longitude) const;
1165 
1170  QString getGPSLatitudeString() const;
1171  QString getGPSLongitudeString() const;
1172 
1178  bool getGPSLatitudeNumber(double* const latitude) const;
1179  bool getGPSLongitudeNumber(double* const longitude) const;
1180 
1184  bool getGPSAltitude(double* const altitude) const;
1185 
1190  bool setGPSInfo(const double altitude, const double latitude, const double longitude);
1191 
1196  bool setGPSInfo(const double* const altitude, const double latitude, const double longitude);
1197 
1202  bool setGPSInfo(const double altitude, const QString& latitude, const QString& longitude);
1203 
1208  bool removeGPSInfo();
1209 
1216  static void convertToRational(const double number,
1217  long int* const numerator,
1218  long int* const denominator,
1219  const int rounding);
1220 
1229  static void convertToRationalSmallDenominator(const double number,
1230  long int* const numerator,
1231  long int* const denominator);
1232 
1236  static double convertDegreeAngleToDouble(double degrees, double minutes, double seconds);
1237 
1238 
1243  static QString convertToGPSCoordinateString(const long int numeratorDegrees,
1244  const long int denominatorDegrees,
1245  const long int numeratorMinutes,
1246  const long int denominatorMinutes,
1247  const long int numeratorSeconds,
1248  const long int denominatorSeconds,
1249  const char directionReference);
1250 
1255  static QString convertToGPSCoordinateString(const bool isLatitude,
1256  double coordinate);
1257 
1263  static bool convertFromGPSCoordinateString(const QString& coordinate,
1264  long int* const numeratorDegrees,
1265  long int* const denominatorDegrees,
1266  long int* const numeratorMinutes,
1267  long int* const denominatorMinutes,
1268  long int* const numeratorSeconds,
1269  long int* const denominatorSeconds,
1270  char* const directionReference);
1271 
1277  static bool convertFromGPSCoordinateString(const QString& gpsString,
1278  double* const coordinate);
1279 
1284  static bool convertToUserPresentableNumbers(const QString& coordinate,
1285  int* const degrees,
1286  int* const minutes,
1287  double* const seconds,
1288  char* const directionReference);
1289 
1296  static void convertToUserPresentableNumbers(const bool isLatitude,
1297  double coordinate,
1298  int* const degrees,
1299  int* const minutes,
1300  double* const seconds,
1301  char* const directionReference);
1302 
1304 
1305 protected:
1306 
1311  bool setProgramId() const;
1312 
1313 private:
1314 
1315  // Disable copy constructor and operator to prevent potential slicing with this class, reported by Clazy static analyzer.
1316  // https://github.com/KDE/clazy/blob/master/docs/checks/README-copyable-polymorphic.md
1317  // This methods was implemented to be able to pass this class or a derived version to signals and slots. This is very
1318  // Dangerous as virtual methods are present in this polymorphic class and is copyable.
1319  // Instead to use this class in signals and slots, use MetaEngineData container.
1320  // TODO: remove legacy implementations for these methods later if no side effect.
1321  MetaEngine(const MetaEngine& metadata);
1322  MetaEngine& operator=(const MetaEngine& metadata);
1323 
1324 private:
1325 
1329  class Private;
1330  Private* const d;
1331 
1332  friend class MetaEnginePreviews;
1333 };
1334 
1335 } // namespace Digikam
1336 
1337 #endif // DIGIKAM_META_ENGINE_H
Definition: metaengine_data.h:41
Definition: metaengine_previews.h:44
Definition: metaengine_p.h:127
Definition: metaengine.h:58
ImageOrientation
Definition: metaengine.h:96
QMap< QString, QString > MetaDataMap
Definition: metaengine.h:136
XmpTagType
Definition: metaengine.h:112
MetadataWritingMode
Definition: metaengine.h:67
Backend
Definition: metaengine.h:124
@ FFMpegBackend
DMetadata only.
Definition: metaengine.h:129
@ LibHeifBackend
DMetadata only.
Definition: metaengine.h:127
@ LibRawBackend
DMetadata only.
Definition: metaengine.h:126
@ ImageMagickBackend
DMetadata only.
Definition: metaengine.h:128
QMap< QString, QStringList > TagsMap
Definition: metaengine.h:151
ImageColorWorkSpace
Definition: metaengine.h:85
QMap< QString, QString > AltLangMap
Definition: metaengine.h:143
QStringView prefix
Definition: itemviewutilities.cpp:593
qulonglong value
Definition: itemviewutilities.cpp:592
Definition: datefolderview.cpp:43