File indexing completed on 2025-01-05 03:56:29
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 * Internal private container. 0009 * 0010 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #ifndef DIGIKAM_META_ENGINE_PRIVATE_H 0018 #define DIGIKAM_META_ENGINE_PRIVATE_H 0019 0020 #include "metaengine.h" 0021 0022 // C++ includes 0023 0024 #include <cstdlib> 0025 #include <cstdio> 0026 #include <cmath> 0027 #include <cfloat> 0028 #include <iostream> 0029 #include <iomanip> 0030 #include <string> 0031 #include <memory> 0032 0033 // Qt includes 0034 0035 #include <QDir> 0036 #include <QFile> 0037 #include <QSize> 0038 #include <QLatin1String> 0039 #include <QFileInfo> 0040 #include <QSharedData> 0041 #include <QMutexLocker> 0042 #include <QRecursiveMutex> 0043 #include <QMimeDatabase> 0044 0045 // Exiv2 includes ------------------------------------------------------- 0046 0047 // NOTE: All Exiv2 headers must be stay there to not expose external source code to Exiv2 API 0048 // and reduce Exiv2 dependency to client code. 0049 0050 #if defined(Q_CC_CLANG) 0051 # pragma clang diagnostic push 0052 # pragma clang diagnostic ignored "-Wdeprecated-declarations" 0053 #endif 0054 0055 // The pragmas are required to be able to catch exceptions thrown by libexiv2: 0056 // See gcc.gnu.org/wiki/Visibility, the section about c++ exceptions. 0057 // They are needed for all libexiv2 versions that do not care about visibility. 0058 0059 #ifdef Q_CC_GNU 0060 # pragma GCC visibility push(default) 0061 #endif 0062 0063 #include <exiv2/exv_conf.h> 0064 #include <exiv2/error.hpp> 0065 #include <exiv2/convert.hpp> 0066 #include <exiv2/image.hpp> 0067 #include <exiv2/jpgimage.hpp> 0068 #include <exiv2/datasets.hpp> 0069 #include <exiv2/tags.hpp> 0070 #include <exiv2/preview.hpp> 0071 #include <exiv2/properties.hpp> 0072 #include <exiv2/types.hpp> 0073 #include <exiv2/exif.hpp> 0074 #include <exiv2/xmpsidecar.hpp> 0075 #include <exiv2/version.hpp> 0076 0077 // Check if Exiv2 support XMP 0078 0079 #ifdef EXV_HAVE_XMP_TOOLKIT 0080 # define _XMP_SUPPORT_ 1 0081 #endif 0082 0083 #ifndef EXIV2_TEST_VERSION 0084 # define EXIV2_TEST_VERSION(major,minor,patch) \ 0085 ( EXIV2_VERSION >= EXIV2_MAKE_VERSION(major,minor,patch) ) 0086 #endif 0087 0088 #if EXIV2_TEST_VERSION(0,27,99) 0089 # define AutoPtr UniquePtr 0090 # define AnyError Error 0091 # define kerErrorMessage ErrorCode::kerErrorMessage 0092 # include <exiv2/photoshop.hpp> 0093 #endif 0094 0095 #if EXIV2_TEST_VERSION(0,27,4) 0096 # include <exiv2/bmffimage.hpp> 0097 #endif 0098 0099 // With exiv2 > 0.20.0, all makernote header files have been removed to increase binary compatibility. 0100 // See Exiv2 bugzilla entry dev.exiv2.org/issues/719 0101 // and wiki topic dev.exiv2.org/boards/3/topics/583 0102 0103 #ifdef Q_CC_GNU 0104 # pragma GCC visibility pop 0105 #endif 0106 0107 // End of Exiv2 headers ------------------------------------------------------ 0108 0109 // Local includes 0110 0111 #include "metaengine_mergehelper.h" 0112 #include "metaenginesettings.h" 0113 0114 namespace Digikam 0115 { 0116 0117 extern QRecursiveMutex s_metaEngineMutex; ///< Mutex to fix no re-entrancy from Exiv2. 0118 extern bool s_metaEngineSupportBmff; ///< Flag for Exiv2 Base Media File Format support. 0119 extern bool s_metaEngineWarnOrError; ///< Flag for Exiv2 has printed a warning or error. 0120 0121 // -------------------------------------------------------------------------- 0122 0123 class Q_DECL_HIDDEN MetaEngine::Private 0124 { 0125 public: 0126 0127 explicit Private(MetaEngine* const q); 0128 ~Private(); 0129 0130 void copyPrivateData(const Private* const other); 0131 0132 bool saveToXMPSidecar(const QFileInfo& finfo) const; 0133 bool saveToFile(const QFileInfo& finfo) const; 0134 bool saveUsingExiv2(const QFileInfo& finfo, 0135 const QDateTime& modTime, 0136 Exiv2::Image::AutoPtr image) const; 0137 bool saveUsingExifTool(const QFileInfo& finfo, 0138 const QDateTime& modTime) const; 0139 0140 bool exportChanges(const QString& exvTmpFile) const; 0141 0142 /** 0143 * Wrapper method to convert a Comments content to a QString. 0144 */ 0145 QString convertCommentValue(const Exiv2::Exifdatum& exifDatum) const; 0146 0147 /** 0148 * Charset autodetection to convert a string to a QString. 0149 */ 0150 QString detectEncodingAndDecode(const std::string& value) const; 0151 0152 /** 0153 * UTF8 autodetection from a string. 0154 */ 0155 bool isUtf8(const char* const buffer) const; 0156 0157 /** 0158 * Decodes Latitude or Longitude from EXIF tag name. 0159 */ 0160 bool decodeGPSCoordinate(const char* exifTagName, double* const coordinate) const; 0161 0162 int getXMPTagsListFromPrefix(const QString& pf, MetaEngine::TagsMap& tagsMap) const; 0163 0164 const Exiv2::ExifData& exifMetadata() const; 0165 const Exiv2::IptcData& iptcMetadata() const; 0166 const std::string& itemComments() const; 0167 0168 Exiv2::ExifData& exifMetadata(); 0169 Exiv2::IptcData& iptcMetadata(); 0170 std::string& itemComments(); 0171 0172 public: 0173 0174 #ifdef _XMP_SUPPORT_ 0175 0176 const Exiv2::XmpData& xmpMetadata() const; 0177 Exiv2::XmpData& xmpMetadata(); 0178 0179 void loadSidecarData(Exiv2::Image::AutoPtr xmpsidecar); 0180 0181 #endif 0182 0183 public: 0184 0185 /** 0186 * Helper method to decode IPTC tag string contents following characters encoding preset. 0187 */ 0188 QString extractIptcTagString(const Exiv2::IptcData& iptcData, const Exiv2::Iptcdatum& iptcTag) const; 0189 0190 public: 0191 0192 /** 0193 * Generic method to print the Exiv2 C++ Exception error message from 'e'. 0194 * 'msg' string is printed using qDebug rules. 0195 */ 0196 static void printExiv2ExceptionError(const QString& msg, Exiv2::AnyError& e); 0197 0198 /** 0199 * Generic method to print debug message from Exiv2. 0200 * 'msg' string is printed using qDebug rules. 'lvl' is the debug level of Exiv2 message. 0201 */ 0202 static void printExiv2MessageHandler(int lvl, const char* msg); 0203 0204 public: 0205 0206 bool writeWithExifTool; 0207 bool writeRawFiles; 0208 bool writeDngFiles; 0209 bool updateFileTimeStamp; 0210 0211 bool useXMPSidecar4Reading; 0212 bool useCompatibleFileName; 0213 0214 /// A mode from #MetadataWritingMode enum. 0215 int metadataWritingMode; 0216 0217 /// XMP, and parts of EXIF/IPTC, were loaded from an XMP sidecar file 0218 bool loadedFromSidecar; 0219 0220 QString filePath; 0221 QSize pixelSize; 0222 QString mimeType; 0223 0224 MetaEngine* parent; 0225 0226 QExplicitlySharedDataPointer<MetaEngineData::Private> data; 0227 }; 0228 0229 } // namespace Digikam 0230 0231 #if defined(Q_CC_CLANG) 0232 # pragma clang diagnostic pop 0233 #endif 0234 0235 #endif // DIGIKAM_META_ENGINE_PRIVATE_H