File indexing completed on 2025-01-19 03:56:03
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2020-11-28 0007 * Description : ExifTool process stream parser. 0008 * 0009 * SPDX-FileCopyrightText: 2020-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #ifndef DIGIKAM_EXIFTOOL_PARSER_H 0016 #define DIGIKAM_EXIFTOOL_PARSER_H 0017 0018 // Qt Core 0019 0020 #include <QHash> 0021 #include <QObject> 0022 #include <QString> 0023 #include <QVariant> 0024 #include <QProcess> 0025 #include <QFileInfo> 0026 #include <QByteArray> 0027 0028 // Local includes 0029 0030 #include "digikam_export.h" 0031 #include "exiftoolprocess.h" 0032 #include "metaengine.h" 0033 0034 namespace Digikam 0035 { 0036 0037 class DIGIKAM_EXPORT ExifToolParser : public QObject 0038 { 0039 Q_OBJECT 0040 0041 public: 0042 0043 /** 0044 * A map used to store ExifTool data shared with ExifToolProcess class: 0045 * 0046 * With load() method, the container is used to get a map of 0047 * ExifTool tag name as key and tags properties as values: 0048 * key = ExifTool Tag name (QString - ExifTool Group 0.1.2.4.6) 0049 * See -G Exiftool option (https://exiftool.org/exiftool_pod.html#Input-output-text-formatting). 0050 * values = ExifTool Tag value (QString). 0051 * ExifTool Tag type (QString). 0052 * ExifTool Tag description (QString). 0053 * ExifTool Tag numerical value (QString) - available if any . 0054 * 0055 * With loadChunk() method, the container is used to get 0056 * a EXV chunk as value: 0057 * key = "EXV" (QString). 0058 * value = the Exiv2 metadata container (QByteArray). 0059 * 0060 * With applyChanges() method, the container is used as argument to 0061 * store tupple of ExifTool tag name as key and tag value: 0062 * key = ExifTool tag name (QString). 0063 * value = ExifTool Tag value (QString). 0064 * 0065 * With readableFormats() method, the container is used to get 0066 * a list of upper-case file format extensions supported by ExifTool for reading. 0067 * key = "READ_FORMAT" (QString). 0068 * value = list of pairs (ext,desc) (QStringList) 0069 * 0070 * With writableFormats() method, the container is used to get 0071 * a list of upper-case file format extensions supported by ExifTool for writing. 0072 * key = "WRITE_FORMAT" (QString). 0073 * value = list of pairs (ext,desc) (QStringList). 0074 * 0075 * With translationsList() method, the container is used to get 0076 * a list of ExifTool languages available for translations. 0077 * key = "TRANSLATIONS_LIST" (QString). 0078 * value = list of languages as strings 0079 * (aka fr, en, de, es, etc.) (QStringList). 0080 * 0081 * With tagsDatabase() method, the container is used as argument to 0082 * store tupple of ExifTool tag name as key and tag description: 0083 * key = ExifTool tag name (QString). 0084 * values = ExifTool Tag description (QString). 0085 * ExifTool Tag type (QString). 0086 * ExifTool Tag writable (QString). 0087 */ 0088 typedef QHash<QString, QVariantList> ExifToolData; 0089 0090 public: 0091 0092 //--------------------------------------------------------------------------------------------- 0093 /// Constructor, Destructor, and Configuration Accessors. See exiftoolparser.cpp for details. 0094 //@{ 0095 0096 explicit ExifToolParser(QObject* const parent, bool async = false); 0097 ~ExifToolParser(); 0098 0099 void setExifToolProgram(const QString& path); 0100 0101 QString currentPath() const; 0102 ExifToolData currentData() const; 0103 QString currentErrorString() const; 0104 0105 /** 0106 * Check the ExifTool program availability. 0107 */ 0108 bool exifToolAvailable() const; 0109 0110 //@} 0111 0112 public: 0113 0114 //--------------------------------------------------------------------------------------------- 0115 /// ExifTool Command Methods. See exiftoolparser_command.cpp for details. 0116 //@{ 0117 0118 /** 0119 * Load all metadata with ExifTool from a file. 0120 * Use currentData() to get the ExifTool map. 0121 */ 0122 bool load(const QString& path); 0123 0124 /** 0125 * Load Exif, Iptc, and Xmp chunk as Exiv2 EXV byte-array from a file. 0126 * Use currentData() to get the container. 0127 */ 0128 bool loadChunk(const QString& path, bool copyToAll = false); 0129 0130 /** 0131 * Apply tag changes to a target file using ExifTool with a list of tag properties. 0132 * Tags can already exists in target file or new ones can be created. 0133 * To remove a tag, pass an empty string as value. 0134 * @param path is the target files to change. 0135 * @param newTags is the list of tag properties. 0136 */ 0137 bool applyChanges(const QString& path, const ExifToolData& newTags); 0138 0139 /** 0140 * Apply tag changes to a target file using ExifTool with a EXV container. 0141 * Tags can already exists in target file or new ones can be created. 0142 * @param path is the target files to change. 0143 * @param exvTempFile is the list of changes embedded in EXV container. 0144 * @param hasExif if the EXV container has Exif metadata restore MarkerNotes. 0145 */ 0146 bool applyChanges(const QString& path, 0147 const QString& exvTempFile, 0148 bool hasExif = true, bool hasXmp = true, bool hasCSet = false); 0149 0150 /** 0151 * Apply a file with metadata to the target file. 0152 * @param path is the target file to change. 0153 * @param meta is the metadata file. 0154 */ 0155 bool applyMetadataFile(const QString& path, const QString& meta); 0156 0157 /** 0158 * Return a list of readable file format extensions. 0159 * Use currentData() to get the container as QStringList. 0160 */ 0161 bool readableFormats(); 0162 0163 /** 0164 * Return a list of writable file format extensions. 0165 * Use currentData() to get the container as QStringList. 0166 */ 0167 bool writableFormats(); 0168 0169 /** 0170 * Return a list of available translations. 0171 * Use currentData() to get the container as QStringList. 0172 */ 0173 bool translationsList(); 0174 0175 /** 0176 * Return a list of all tags from ExifTool database. 0177 * Use currentData() to get the container. 0178 * Warning: This method get whole ExifTool database in XML format and take age. 0179 */ 0180 bool tagsDatabase(); 0181 0182 /** 0183 * Return the current version of ExifTool. 0184 * Use currentData() to get the container as QString. 0185 */ 0186 bool version(); 0187 0188 /** 0189 * Copy group of tags from one source file to a destination file, following copy operations defined by 'copyOps'. 0190 * @param copyOps is a OR combination of ExifToolProcess::CopyTagsSource values. 0191 * @param transOps is a OR combination of ExifToolProcess::TranslateTagsOps values. 0192 * @param writeModes is a OR combaniation of ExifToolProcess::WritingTagsMode values. 0193 * @param dst must be a writable file format supported by ExifTool. 0194 */ 0195 bool copyTags(const QString& src, 0196 const QString& dst, 0197 unsigned char copyOps, 0198 unsigned char writeModes = ExifToolProcess::ALL_MODES); 0199 0200 /** 0201 * Translate group of tags in file. 0202 * @param transOps is a OR combination of ExifToolProcess::TranslateTagsOps values. 0203 */ 0204 bool translateTags(const QString& path, unsigned char transOps); 0205 0206 //@} 0207 0208 public: 0209 0210 //--------------------------------------------------------------------------------------------- 0211 /// ExifTool Output Management Methods. See exiftoolparser_output.cpp for details 0212 //@{ 0213 0214 void cmdCompleted(const ExifToolProcess::Result& result); 0215 0216 void errorOccurred(const ExifToolProcess::Result& result, 0217 QProcess::ProcessError error, 0218 const QString& description); 0219 0220 void finished(); 0221 0222 public Q_SLOTS: 0223 0224 void slotExifToolResult(int cmdId); 0225 0226 //@} 0227 0228 Q_SIGNALS: 0229 0230 void signalExifToolDataAvailable(); 0231 void signalExifToolAsyncData(const ExifToolParser::ExifToolData& map); 0232 0233 public: 0234 0235 /** 0236 * Unit-test method to check ExifTool stream parsing. 0237 */ 0238 void setOutputStream(int cmdAction, 0239 const QByteArray& cmdOutputChannel, 0240 const QByteArray& cmdErrorChannel); 0241 0242 /** 0243 * Helper conversion method to translate unordered tags database hash-table to ordered map. 0244 */ 0245 static MetaEngine::TagsMap tagsDbToOrderedMap(const ExifToolData& tagsDb); 0246 0247 private: 0248 0249 void printExifToolOutput(const QByteArray& stdOut); 0250 0251 //@} 0252 0253 private: 0254 0255 class Private; 0256 Private* const d; 0257 }; 0258 0259 } // namespace Digikam 0260 0261 #endif // DIGIKAM_EXIFTOOL_PARSER_H