digiKam
Loading...
Searching...
No Matches
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 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
16 * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
17 *
18 * SPDX-License-Identifier: GPL-2.0-or-later
19 *
20 * ============================================================ */
21
22#pragma once
23
24// QT includes
25
26#include <QByteArray>
27#include <QString>
28#include <QDateTime>
29#include <QMap>
30#include <QSharedDataPointer>
31#include <QStringList>
32#include <QVariant>
33#include <QRegularExpression>
34#include <QUrl>
35#include <QImage>
36
37// Local includes
38
39#include "metaengine_data.h"
40#include "digikam_export.h"
41
42namespace Digikam
43{
44
45// TODO: merge with DMetadata class.
46
47class DIGIKAM_EXPORT MetaEngine
48{
49
50public:
51
57 {
59 WRITE_TO_FILE_ONLY = 0,
60
62 WRITE_TO_SIDECAR_ONLY = 1,
63
65 WRITE_TO_SIDECAR_AND_FILE = 2,
66
68 WRITE_TO_SIDECAR_ONLY_FOR_READ_ONLY_FILES = 3
69 };
70
75 {
76 WORKSPACE_UNSPECIFIED = 0,
77 WORKSPACE_SRGB = 1,
78 WORKSPACE_ADOBERGB = 2,
79 WORKSPACE_UNCALIBRATED = 65535
80 };
81
86 {
87 ORIENTATION_UNSPECIFIED = 0,
88 ORIENTATION_NORMAL = 1,
89 ORIENTATION_HFLIP = 2,
90 ORIENTATION_ROT_180 = 3,
91 ORIENTATION_VFLIP = 4,
92 ORIENTATION_ROT_90_HFLIP = 5,
93 ORIENTATION_ROT_90 = 6,
94 ORIENTATION_ROT_90_VFLIP = 7,
95 ORIENTATION_ROT_270 = 8
96 };
97
102 {
103 NormalTag = 0,
104 ArrayBagTag = 1,
105 StructureTag = 2,
106 ArrayLangTag = 3,
107 ArraySeqTag = 4
108 };
109
124
128 typedef QMap<QString, QString> MetaDataMap;
129
135 typedef QMap<QString, QString> AltLangMap;
136
143 typedef QMap<QString, QStringList> TagsMap;
144
145public:
146
150 MetaEngine();
151
155 explicit MetaEngine(const MetaEngineData& data);
156
160 explicit MetaEngine(const QString& filePath);
161
165 virtual ~MetaEngine();
166
167public:
168
169 //-----------------------------------------------------------------
171
172
180 static bool initializeExiv2();
181
185 static bool supportXmp();
186
190 static bool supportJpegXL();
191
197 static bool supportBmff();
198
202 static bool supportMetadataWriting(const QString& typeMime);
203
207 static QString Exiv2Version();
208
210
211 //-----------------------------------------------------------------
213
214
215 MetaEngineData data() const;
216 void setData(const MetaEngineData& data);
217
222 bool loadFromData(const QByteArray& imgData);
223
229 bool loadFromDataAndMerge(const QByteArray& imgData, const QStringList& exclude = QStringList());
230
234 bool isEmpty() const;
235
246 QSize getPixelSize() const;
247
252 QString getMimeType() const;
253
257 void setReadWithExifTool(const bool on);
258
262 bool readWithExifTool() const;
263
267 void setWriteWithExifTool(const bool on);
268
272 bool writeWithExifTool() const;
273
278 void setWriteRawFiles(const bool on);
279
283 bool writeRawFiles() const;
284
288 void setWriteDngFiles(const bool on);
289
293 bool writeDngFiles() const;
294
298 void setUseXMPSidecar4Reading(const bool on);
299
303 bool useXMPSidecar4Reading() const;
304
308 void setUseCompatibleFileName(const bool on);
309
313 bool useCompatibleFileName() const;
314
320 void setMetadataWritingMode(const int mode);
321
327 int metadataWritingMode() const;
328
333 void setUpdateFileTimeStamp(bool on);
334
338 bool updateFileTimeStamp() const;
339
341
342 //-------------------------------------------------------------------
344
345
349 void setFilePath(const QString& path);
350
354 QString getFilePath() const;
355
360 static QString sidecarFilePathForFile(const QString& path);
361
365 static QString sidecarPath(const QString& path);
366
370 static QUrl sidecarUrl(const QUrl& url);
371
375 static QUrl sidecarUrl(const QString& path);
376
380 static bool hasSidecar(const QString& path);
381
386 static QString backendName(Backend t);
387
394 bool load(const QString& filePath, Backend* backend = nullptr);
395
400 bool loadFromSidecarAndMerge(const QString& filePath);
401
406 bool save(const QString& filePath, bool setVersion = false) const;
407
412 bool applyChanges(bool setVersion = false) const;
413
418 bool exportChanges(const QString& exvTmpFile) const;
419
421
422 //-------------------------------------------------------------------
424
425
430 bool setItemProgramId(const QString& program, const QString& version) const;
431
436 QSize getItemDimensions() const;
437
442 bool setItemDimensions(const QSize& size) const;
443
448 MetaEngine::ImageOrientation getItemOrientation() const;
449
454 bool setItemOrientation(ImageOrientation orientation) const;
455
460 MetaEngine::ImageColorWorkSpace getItemColorWorkSpace() const;
461
466 bool setItemColorWorkSpace(ImageColorWorkSpace workspace) const;
467
472 QDateTime getItemDateTime() const;
473
478 bool setImageDateTime(const QDateTime& dateTime, bool setDateTimeDigitized = false) const;
479
485 QDateTime getDigitizationDateTime(bool fallbackToCreationTime = false) const;
486
491 bool getItemPreview(QImage& preview) const;
492
500 bool setItemPreview(const QImage& preview) const;
501
505 QByteArray getItemIccProfile() const;
506
510 bool setItemIccProfile(const QByteArray& iccData) const;
511
513
514 //-----------------------------------------------------------------
516
517
521 static bool canWriteComment(const QString& filePath);
522
526 bool hasComments() const;
527
531 bool clearComments() const;
532
538 QByteArray getComments() const;
539
545 QString getCommentsDecoded() const;
546
551 bool setComments(const QByteArray& data) const;
552
558 static QString detectLanguageAlt(const QString& value, QString& lang);
559
561
562 //-----------------------------------------------------------------
564
565
569 TagsMap getStdExifTagsList() const;
570
574 TagsMap getMakernoteTagsList() const;
575
579 static bool canWriteExif(const QString& filePath);
580
584 bool hasExif() const;
585
589 bool clearExif() const;
590
599 QByteArray getExifEncoded(bool addExifHeader = false) const;
600
605 bool setExif(const QByteArray& data) const;
606
612 QImage getExifThumbnail(bool fixOrientation) const;
613
618 bool rotateExifQImage(QImage& image, ImageOrientation orientation) const;
619
624 bool setExifThumbnail(const QImage& thumb) const;
625
629 bool removeExifThumbnail() const;
630
634 bool setTiffThumbnail(const QImage& thumb) const;
635
640 QString getExifComment(bool readDescription = true) const;
641
646 QString getExifTagComment(const char* exifTagName) const;
647
652 bool setExifComment(const QString& comment, bool writeDescription = true) const;
653
658 QString getExifTagString(const char* exifTagName, bool escapeCR = true) const;
659
663 bool setExifTagString(const char* exifTagName, const QString& value) const;
664
668 bool getExifTagLong(const char* exifTagName, long &val) const;
669
673 bool getExifTagLong(const char* exifTagName, long &val, int component) const;
674
678 bool setExifTagLong(const char* exifTagName, long val) const;
679
683 bool setExifTagUShort(const char* exifTagName, unsigned int val) const;
684
690 bool getExifTagRational(const char* exifTagName, long int& num, long int& den, int component = 0) const;
691
697 bool setExifTagRational(const char* exifTagName, long int num, long int den) const;
698
704 bool setExifTagURational(const char* exifTagName, unsigned long int num, unsigned long int den) const;
705
710 QByteArray getExifTagData(const char* exifTagName) const;
711
715 bool setExifTagData(const char* exifTagName, const QByteArray& data) const;
716
726 QVariant getExifTagVariant(const char* exifTagName, bool rationalAsListOfInts = true,
727 bool escapeCR = true, int component = 0) const;
728
736 bool setExifTagVariant(const char* exifTagName, const QVariant& data,
737 bool rationalWantSmallDenominator = true) const;
738
743 bool removeExifTag(const char* exifTagName) const;
744
748 QString getExifTagTitle(const char* exifTagName);
749
753 QString getExifTagDescription(const char* exifTagName);
754
761 QString createExifUserStringFromValue(const char* exifTagName, const QVariant& val, bool escapeCR = true);
762
787 MetaEngine::MetaDataMap getExifTagsDataList(const QStringList& exifKeysFilter = QStringList(),
788 bool invertSelection = false,
789 bool extractBinary = true) const;
790
792
793 //-------------------------------------------------------------
795
796
800 MetaEngine::TagsMap getIptcTagsList() const;
801
805 static bool canWriteIptc(const QString& filePath);
806
810 bool hasIptc() const;
811
815 bool clearIptc() const;
816
822 QByteArray getIptc(bool addIrbHeader = false) const;
823
828 bool setIptc(const QByteArray& data) const;
829
834 QString getIptcTagString(const char* iptcTagName, bool escapeCR = true) const;
835
839 bool setIptcTagString(const char* iptcTagName, const QString& value) const;
840
849 QStringList getIptcTagsStringList(const char* iptcTagName, bool escapeCR = true) const;
850
855 bool setIptcTagsStringList(const char* iptcTagName, int maxSize,
856 const QStringList& oldValues, const QStringList& newValues) const;
857
862 QByteArray getIptcTagData(const char* iptcTagName) const;
863
867 bool setIptcTagData(const char* iptcTagName, const QByteArray& data) const;
868
873 bool removeIptcTag(const char* iptcTagName) const;
874
878 QString getIptcTagTitle(const char* iptcTagName);
879
883 QString getIptcTagDescription(const char* iptcTagName);
884
904 MetaEngine::MetaDataMap getIptcTagsDataList(const QStringList& iptcKeysFilter = QStringList(),
905 bool invertSelection = false) const;
906
910 QStringList getIptcKeywords() const;
911
918 bool setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords) const;
919
923 QStringList getIptcSubjects() const;
924
931 bool setIptcSubjects(const QStringList& oldSubjects, const QStringList& newSubjects) const;
932
937 QStringList getIptcSubCategories() const;
938
945 bool setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories) const;
946
948
949 //------------------------------------------------------------
951
952
956 MetaEngine::TagsMap getXmpTagsList() const;
957
961 static bool canWriteXmp(const QString& filePath);
962
966 bool hasXmp() const;
967
971 bool clearXmp() const;
972
977 QByteArray getXmp() const;
978
983 bool setXmp(const QByteArray& data) const;
984
989 QString getXmpTagString(const char* xmpTagName, bool escapeCR = true) const;
990
994 bool setXmpTagString(const char* xmpTagName, const QString& value) const;
995
1001 bool setXmpTagString(const char* xmpTagName, const QString& value,
1002 XmpTagType type) const;
1003
1007 QString getXmpTagTitle(const char* xmpTagName);
1008
1012 QString getXmpTagDescription(const char* xmpTagName);
1013
1033 MetaEngine::MetaDataMap getXmpTagsDataList(const QStringList& xmpKeysFilter = QStringList(),
1034 bool invertSelection = false) const;
1035
1042 MetaEngine::AltLangMap getXmpTagStringListLangAlt(const char* xmpTagName,
1043 bool escapeCR = true) const;
1044
1050 bool setXmpTagStringListLangAlt(const char* xmpTagName, const MetaEngine::AltLangMap& values) const;
1051
1058 QString getXmpTagStringLangAlt(const char* xmpTagName, const QString& langAlt, bool escapeCR) const;
1059
1066 bool setXmpTagStringLangAlt(const char* xmpTagName, const QString& value,
1067 const QString& langAlt) const;
1068
1073 QStringList getXmpTagStringSeq(const char* xmpTagName, bool escapeCR = true) const;
1074
1079 bool setXmpTagStringSeq(const char* xmpTagName, const QStringList& seq) const;
1080
1085 QStringList getXmpTagStringBag(const char* xmpTagName, bool escapeCR) const;
1086
1091 bool setXmpTagStringBag(const char* xmpTagName, const QStringList& bag) const;
1092
1099 bool addToXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToAdd) const;
1100
1106 bool removeFromXmpTagStringBag(const char* xmpTagName, const QStringList& entriesToRemove) const;
1107
1119 QVariant getXmpTagVariant(const char* xmpTagName, bool rationalAsListOfInts = true, bool stringEscapeCR = true) const;
1120
1124 QStringList getXmpKeywords() const;
1125
1132 bool setXmpKeywords(const QStringList& newKeywords) const;
1133
1138 bool removeXmpKeywords(const QStringList& keywordsToRemove);
1139
1143 QStringList getXmpSubjects() const;
1144
1151 bool setXmpSubjects(const QStringList& newSubjects) const;
1152
1157 bool removeXmpSubjects(const QStringList& subjectsToRemove);
1158
1163 QStringList getXmpSubCategories() const;
1164
1171 bool setXmpSubCategories(const QStringList& newSubCategories) const;
1172
1177 bool removeXmpSubCategories(const QStringList& categoriesToRemove);
1178
1183 bool removeXmpTag(const char* xmpTagName, bool family = false) const;
1184
1192 static bool registerXmpNameSpace(const QString& uri, const QString& prefix);
1193
1197 static bool unregisterXmpNameSpace(const QString& uri);
1198
1200
1201 //------------------------------------------------------------
1203
1204
1208 bool initializeGPSInfo();
1209
1213 bool getGPSInfo(double& altitude, double& latitude, double& longitude) const;
1214
1219 QString getGPSLatitudeString() const;
1220 QString getGPSLongitudeString() const;
1221
1227 bool getGPSLatitudeNumber(double* const latitude) const;
1228 bool getGPSLongitudeNumber(double* const longitude) const;
1229
1233 bool getGPSAltitude(double* const altitude) const;
1234
1239 bool setGPSInfo(const double altitude, const double latitude, const double longitude);
1240
1245 bool setGPSInfo(const double* const altitude, const double latitude, const double longitude);
1246
1251 bool setGPSInfo(const double altitude, const QString& latitude, const QString& longitude);
1252
1257 bool removeGPSInfo();
1258
1265 static void convertToRational(const double number,
1266 long int* const numerator,
1267 long int* const denominator,
1268 const int rounding);
1269
1278 static void convertToRationalSmallDenominator(const double number,
1279 long int* const numerator,
1280 long int* const denominator);
1281
1285 static double convertDegreeAngleToDouble(double degrees, double minutes, double seconds);
1286
1287
1292 static QString convertToGPSCoordinateString(const long int numeratorDegrees,
1293 const long int denominatorDegrees,
1294 const long int numeratorMinutes,
1295 const long int denominatorMinutes,
1296 const long int numeratorSeconds,
1297 const long int denominatorSeconds,
1298 const char directionReference);
1299
1304 static QString convertToGPSCoordinateString(const bool isLatitude,
1305 double coordinate);
1306
1312 static bool convertFromGPSCoordinateString(const QString& coordinate,
1313 long int* const numeratorDegrees,
1314 long int* const denominatorDegrees,
1315 long int* const numeratorMinutes,
1316 long int* const denominatorMinutes,
1317 long int* const numeratorSeconds,
1318 long int* const denominatorSeconds,
1319 char* const directionReference);
1320
1326 static bool convertFromGPSCoordinateString(const QString& gpsString,
1327 double* const coordinate);
1328
1333 static bool convertToUserPresentableNumbers(const QString& coordinate,
1334 int* const degrees,
1335 int* const minutes,
1336 double* const seconds,
1337 char* const directionReference);
1338
1345 static void convertToUserPresentableNumbers(const bool isLatitude,
1346 double coordinate,
1347 int* const degrees,
1348 int* const minutes,
1349 double* const seconds,
1350 char* const directionReference);
1351
1353
1354protected:
1355
1360 bool setProgramId() const;
1361
1362private:
1363
1364 // Disable copy constructor and operator to prevent potential slicing with this class, reported by Clazy static analyzer.
1365 // https://github.com/KDE/clazy/blob/master/docs/checks/README-copyable-polymorphic.md
1366 // This methods was implemented to be able to pass this class or a derived version to signals and slots. This is very
1367 // Dangerous as virtual methods are present in this polymorphic class and is copyable.
1368 // Instead to use this class in signals and slots, use MetaEngineData container.
1369
1370 // TODO: remove legacy implementations for these methods later if no side effect.
1371
1372 MetaEngine(const MetaEngine& metadata);
1373 MetaEngine& operator=(const MetaEngine& metadata);
1374
1375private:
1376
1380 class Private;
1381 Private* const d = nullptr;
1382
1384};
1385
1386} // namespace Digikam
Definition metaengine_data.h:31
Definition metaengine_previews.h:34
Definition metaengine_p.h:124
Definition metaengine.h:48
ImageOrientation
Definition metaengine.h:86
QMap< QString, QString > MetaDataMap
Definition metaengine.h:128
XmpTagType
Definition metaengine.h:102
MetadataWritingMode
Definition metaengine.h:57
Backend
Definition metaengine.h:114
@ FFMpegBackend
DMetadata only.
Definition metaengine.h:119
@ ExifToolBackend
DMetadata only.
Definition metaengine.h:120
@ VideoMergeBackend
DMetadata only.
Definition metaengine.h:121
@ LibHeifBackend
DMetadata only.
Definition metaengine.h:117
@ LibRawBackend
DMetadata only.
Definition metaengine.h:116
@ ImageMagickBackend
DMetadata only.
Definition metaengine.h:118
QMap< QString, QStringList > TagsMap
Definition metaengine.h:143
ImageColorWorkSpace
Definition metaengine.h:75
QMap< QString, QString > AltLangMap
Definition metaengine.h:135
QStringView prefix
Definition itemviewutilities.cpp:586
qulonglong value
Definition itemviewutilities.cpp:585
Definition datefolderview.cpp:34