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 * Internal private container. 9 * 10 * Copyright (C) 2006-2021 by Gilles Caulier <caulier dot gilles at gmail dot com> 11 * Copyright (C) 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 12 * 13 * This program is free software; you can redistribute it 14 * and/or modify it under the terms of the GNU General 15 * Public License as published by the Free Software Foundation; 16 * either version 2, or (at your option) 17 * any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * ============================================================ */ 25 26 #ifndef DIGIKAM_META_ENGINE_PRIVATE_H 27 #define DIGIKAM_META_ENGINE_PRIVATE_H 28 29 #include "metaengine.h" 30 31 // C++ includes 32 33 #include <cstdlib> 34 #include <cstdio> 35 #include <cmath> 36 #include <cfloat> 37 #include <iostream> 38 #include <iomanip> 39 #include <string> 40 41 // Qt includes 42 43 #include <QFile> 44 #include <QSize> 45 #include <QLatin1String> 46 #include <QFileInfo> 47 #include <QSharedData> 48 #include <QMutexLocker> 49 #include <QMimeDatabase> 50 51 // Exiv2 includes ------------------------------------------------------- 52 53 // NOTE: All Exiv2 headers must be stay there to not expose external source code to Exiv2 API 54 // and reduce Exiv2 dependency to client code. 55 56 #if defined(Q_CC_CLANG) 57 # pragma clang diagnostic push 58 # pragma clang diagnostic ignored "-Wdeprecated-declarations" 59 #endif 60 61 // The pragmas are required to be able to catch exceptions thrown by libexiv2: 62 // See gcc.gnu.org/wiki/Visibility, the section about c++ exceptions. 63 // They are needed for all libexiv2 versions that do not care about visibility. 64 65 #ifdef Q_CC_GNU 66 # pragma GCC visibility push(default) 67 #endif 68 69 #include <exiv2/exv_conf.h> 70 #include <exiv2/error.hpp> 71 #include <exiv2/image.hpp> 72 #include <exiv2/jpgimage.hpp> 73 #include <exiv2/datasets.hpp> 74 #include <exiv2/tags.hpp> 75 #include <exiv2/preview.hpp> 76 #include <exiv2/properties.hpp> 77 #include <exiv2/types.hpp> 78 #include <exiv2/exif.hpp> 79 #include <exiv2/xmpsidecar.hpp> 80 #include <exiv2/version.hpp> 81 82 // Check if Exiv2 support XMP 83 84 #ifdef EXV_HAVE_XMP_TOOLKIT 85 # define _XMP_SUPPORT_ 1 86 #endif 87 88 #ifndef EXIV2_TEST_VERSION 89 # define EXIV2_TEST_VERSION(major,minor,patch) \ 90 ( EXIV2_VERSION >= EXIV2_MAKE_VERSION(major,minor,patch) ) 91 #endif 92 93 #if EXIV2_TEST_VERSION(0,27,99) 94 # define AutoPtr UniquePtr 95 #endif 96 97 #if EXIV2_TEST_VERSION(0,27,4) 98 # include <exiv2/bmffimage.hpp> 99 #endif 100 101 // With exiv2 > 0.20.0, all makernote header files have been removed to increase binary compatibility. 102 // See Exiv2 bugzilla entry dev.exiv2.org/issues/719 103 // and wiki topic dev.exiv2.org/boards/3/topics/583 104 105 #ifdef Q_CC_GNU 106 # pragma GCC visibility pop 107 #endif 108 109 // End of Exiv2 headers ------------------------------------------------------ 110 111 // Local includes 112 113 #include "metaengine_mergehelper.h" 114 115 namespace Digikam 116 { 117 118 extern QMutex s_metaEngineMutex; ///< Mutex to fix no re-entrancy from Exiv2. 119 extern bool s_metaEngineSupportBmff; ///< Flag for Exiv2 Base Media File Format support. 120 121 // -------------------------------------------------------------------------- 122 123 class Q_DECL_HIDDEN MetaEngine::Private 124 { 125 public: 126 127 explicit Private(); 128 ~Private(); 129 130 void copyPrivateData(const Private* const other); 131 132 bool saveToXMPSidecar(const QFileInfo& finfo) const; 133 bool saveToFile(const QFileInfo& finfo) const; 134 bool saveOperations(const QFileInfo& finfo, Exiv2::Image::AutoPtr image) const; 135 136 /** 137 * Wrapper method to convert a Comments content to a QString. 138 */ 139 QString convertCommentValue(const Exiv2::Exifdatum& exifDatum) const; 140 141 /** 142 * Charset autodetection to convert a string to a QString. 143 */ 144 QString detectEncodingAndDecode(const std::string& value) const; 145 146 /** 147 * UTF8 autodetection from a string. 148 */ 149 bool isUtf8(const char* const buffer) const; 150 151 int getXMPTagsListFromPrefix(const QString& pf, MetaEngine::TagsMap& tagsMap) const; 152 153 const Exiv2::ExifData& exifMetadata() const; 154 const Exiv2::IptcData& iptcMetadata() const; 155 const std::string& itemComments() const; 156 157 Exiv2::ExifData& exifMetadata(); 158 Exiv2::IptcData& iptcMetadata(); 159 std::string& itemComments(); 160 161 public: 162 163 #ifdef _XMP_SUPPORT_ 164 165 const Exiv2::XmpData& xmpMetadata() const; 166 Exiv2::XmpData& xmpMetadata(); 167 168 void loadSidecarData(Exiv2::Image::AutoPtr xmpsidecar); 169 170 #endif 171 172 public: 173 174 /** 175 * Helper method to decode IPTC tag string contents following characters encoding preset. 176 */ 177 QString extractIptcTagString(const Exiv2::IptcData& iptcData, const Exiv2::Iptcdatum& iptcTag) const; 178 179 public: 180 181 /** 182 * Generic method to print the Exiv2 C++ Exception error message from 'e'. 183 * 'msg' string is printed using qDebug rules. 184 */ 185 static void printExiv2ExceptionError(const QString& msg, Exiv2::AnyError& e); 186 187 /** 188 * Generic method to print debug message from Exiv2. 189 * 'msg' string is printed using qDebug rules. 'lvl' is the debug level of Exiv2 message. 190 */ 191 static void printExiv2MessageHandler(int lvl, const char* msg); 192 193 public: 194 195 bool writeRawFiles; 196 bool writeDngFiles; 197 bool updateFileTimeStamp; 198 199 bool useXMPSidecar4Reading; 200 bool useCompatibleFileName; 201 202 /// A mode from #MetadataWritingMode enum. 203 int metadataWritingMode; 204 205 /// XMP, and parts of EXIF/IPTC, were loaded from an XMP sidecar file 206 bool loadedFromSidecar; 207 208 QString filePath; 209 QSize pixelSize; 210 QString mimeType; 211 212 QExplicitlySharedDataPointer<MetaEngineData::Private> data; 213 }; 214 215 } // namespace Digikam 216 217 #if defined(Q_CC_CLANG) 218 # pragma clang diagnostic pop 219 #endif 220 221 #endif // DIGIKAM_META_ENGINE_PRIVATE_H 222