Commit 3a672f38 authored by Gilles Caulier's avatar Gilles Caulier 🗼
Browse files

Write metadata with ExifTool backend if Exiv2 fails to process, for exemple...

Write metadata with ExifTool backend if Exiv2 fails to process, for exemple with RAW files or Video files.
Tested successfuly with a MP4 video to insert a comment.
For RAW and other king of files as MPO or JPEG with more than 64kB of Exif segement, Exiv2 must be bannned to uses in cases of writting operations as files can be corrupted.
This require more regression tests to validate ExifTool uses in place of Exiv2.

CCBUGS: 406540
CCBUGS: 416516
CCBUGS: 237504
CCBUGS: 384092
CCBUGS: 264210
CCBUGS: 326408
CCBUGS: 421464
CCBUGS: 134486
CCBUGS: 309341
CCBUGS: 219856
CCBUGS: 377622
CCBUGS: 325458
CCBUGS: 170693
CCBUGS: 448729
CCBUGS: 338075
CCBUGS: 436876
CCBUGS: 366348
parent 5e67c955
Pipeline #160659 failed with stage
in 23 minutes and 33 seconds
......@@ -416,6 +416,7 @@ private:
* ExifTool helper methods.
*/
bool loadUsingExifTool(const QString& filePath);
bool saveUsingExifTool(const QString& filePath) const;
};
} // namespace Digikam
......
......@@ -91,4 +91,47 @@ bool DMetadata::loadUsingExifTool(const QString& filePath)
return true;
}
bool DMetadata::saveUsingExifTool(const QString& filePath) const
{
ExifToolParser* const parser = new ExifToolParser(nullptr);
if (parser->exifToolAvailable())
{
QString exvPath = QFileInfo(getFilePath()).baseName() + QLatin1String("_changes.exv");
QStringList removedTags;
exportChanges(exvPath, removedTags);
QString targetPath;
// NOTE: if filePath is empty, we will apply changex on original file, else save changes on different file.
if (!filePath.isEmpty())
{
targetPath = filePath;
}
else
{
targetPath = getFilePath();
}
if (!parser->applyChanges(targetPath, exvPath))
{
qCWarning(DIGIKAM_METAENGINE_LOG) << "Cannot apply changes with ExifTool on" << targetPath;
delete parser;
return false;
}
}
else
{
qCWarning(DIGIKAM_METAENGINE_LOG) << "ExifTool is not available to save metadata...";
delete parser;
return false;
}
delete parser;
return true;
}
} // namespace Digikam
......@@ -109,7 +109,7 @@ bool DMetadata::load(const QString& filePath, Backend* backend)
}
else
{
// No image files (aka video or audio), process with ffmpeg backend.
// No image files (aka video or audio), process with ExifTool or ffmpeg backends.
if (!(hasLoaded = loadUsingExifTool(filePath)))
{
......@@ -146,14 +146,60 @@ bool DMetadata::save(const QString& filePath, bool setVersion) const
{
FileWriteLocker lock(filePath);
return MetaEngine::save(filePath, setVersion);
Backend usedBackend = NoBackend;
bool hasSaved = false;
if (!(hasSaved = MetaEngine::save(filePath, setVersion)))
{
if (!(hasSaved = saveUsingExifTool(filePath)))
{
usedBackend = NoBackend;
}
else
{
usedBackend = ExifToolBackend;
}
}
else
{
usedBackend = Exiv2Backend;
}
qCDebug(DIGIKAM_METAENGINE_LOG) << "Saving metadata with"
<< backendName(usedBackend)
<< "backend to" << filePath;
return hasSaved;
}
bool DMetadata::applyChanges(bool setVersion) const
{
FileWriteLocker lock(getFilePath());
return MetaEngine::applyChanges(setVersion);
Backend usedBackend = NoBackend;
bool hasSaved = false;
if (!(hasSaved = MetaEngine::applyChanges(setVersion)))
{
if (!(hasSaved = saveUsingExifTool(QString())))
{
usedBackend = NoBackend;
}
else
{
usedBackend = ExifToolBackend;
}
}
else
{
usedBackend = Exiv2Backend;
}
qCDebug(DIGIKAM_METAENGINE_LOG) << "Apply metadata changes with"
<< backendName(usedBackend)
<< "backend to" << getFilePath();
return hasSaved;
}
} // namespace Digikam
......@@ -137,7 +137,7 @@ public:
bool loadChunk(const QString& path);
/**
* Apply tag changes to a target file with ExifTool with a list of tag properties.
* Apply tag changes to a target file using ExifTool with a list of tag properties.
* Tags can already exists in target file or new ones can be created.
* To remove a tag, pass an empty string as value.
* @param path is the target files to change.
......@@ -146,7 +146,7 @@ public:
bool applyChanges(const QString& path, const ExifToolData& newTags);
/**
* Apply tag changes to a target file with ExifTool with a EXV container.
* Apply tag changes to a target file using ExifTool with a EXV container.
* Tags can already exists in target file or new ones can be created.
* @param path is the target files to change.
* @param exvTempFile is the list of changes embedded in EXV container.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment