mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-07-18 03:54:18 -04:00
JXL: Resolution and metadata support via EXIF
- Added a class to read and write minimal exif metadata. - JXL plugin uses EXIF metadata to load/save the resolution of the image (like GIMP). - JXL plugin uses EXIF metadata to set/store text metadata and date/time. - Enable info display in Dolphin (JXL File -> Properties -> Details on a JXL file, see image below). - Enabled read test to check also image metadata and resolution. {width=401 height=357}
This commit is contained in:
@ -12,6 +12,49 @@
|
||||
#include <QJsonObject>
|
||||
#include <QVersionNumber>
|
||||
|
||||
static QJsonObject searchObject(const QFileInfo& file)
|
||||
{
|
||||
auto fi = QFileInfo(QStringLiteral("%1.json").arg(file.filePath()));
|
||||
if (!fi.exists()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QFile f(fi.filePath());
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QJsonParseError err;
|
||||
auto doc = QJsonDocument::fromJson(f.readAll(), &err);
|
||||
if (err.error != QJsonParseError::NoError || !doc.isArray()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto currentQt = QVersionNumber::fromString(qVersion());
|
||||
auto arr = doc.array();
|
||||
for (auto val : arr) {
|
||||
if (!val.isObject())
|
||||
continue;
|
||||
auto obj = val.toObject();
|
||||
auto minQt = QVersionNumber::fromString(obj.value("minQtVersion").toString());
|
||||
auto maxQt = QVersionNumber::fromString(obj.value("maxQtVersion").toString());
|
||||
auto name = obj.value("fileName").toString();
|
||||
auto unsupportedFormat = obj.value("unsupportedFormat").toBool();
|
||||
|
||||
// filter
|
||||
if (name.isEmpty() && !unsupportedFormat)
|
||||
continue;
|
||||
if (!minQt.isNull() && currentQt < minQt)
|
||||
continue;
|
||||
if (!maxQt.isNull() && currentQt > maxQt)
|
||||
continue;
|
||||
return obj;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
TemplateImage::TemplateImage(const QFileInfo &fi) :
|
||||
m_fi(fi)
|
||||
{
|
||||
@ -45,6 +88,43 @@ QFileInfo TemplateImage::compareImage(TestFlags &flags, QString& comment) const
|
||||
return legacyImage();
|
||||
}
|
||||
|
||||
bool TemplateImage::checkOptionaInfo(const QImage& image, QString& error) const
|
||||
{
|
||||
auto obj = searchObject(m_fi);
|
||||
if (obj.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test resolution
|
||||
auto res = obj.value("resolution").toObject();
|
||||
if (!res.isEmpty()) {
|
||||
auto resx = res.value("dotsPerMeterX").toInt();
|
||||
auto resy = res.value("dotsPerMeterY").toInt();
|
||||
if (resx != image.dotsPerMeterX()) {
|
||||
error = QStringLiteral("X resolution mismatch (current: %1, expected: %2)!").arg(image.dotsPerMeterX()).arg(resx);
|
||||
return false;
|
||||
}
|
||||
if (resy != image.dotsPerMeterY()) {
|
||||
error = QStringLiteral("Y resolution mismatch (current: %1, expected: %2)!").arg(image.dotsPerMeterY()).arg(resy);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test metadata
|
||||
auto meta = obj.value("metadata").toArray();
|
||||
for (auto jv : meta) {
|
||||
auto obj = jv.toObject();
|
||||
auto key = obj.value("Key").toString();
|
||||
auto val = obj.value("Value").toString();
|
||||
auto cur = image.text(key);
|
||||
if (cur != val) {
|
||||
error = QStringLiteral("Metadata '%1' mismatch (current: '%2', expected:'%3')!").arg(key, cur, val);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList TemplateImage::suffixes()
|
||||
{
|
||||
@ -66,51 +146,25 @@ QFileInfo TemplateImage::legacyImage() const
|
||||
QFileInfo TemplateImage::jsonImage(TestFlags &flags, QString& comment) const
|
||||
{
|
||||
flags = TestFlag::None;
|
||||
auto fi = QFileInfo(QStringLiteral("%1.json").arg(m_fi.filePath()));
|
||||
if (!fi.exists()) {
|
||||
|
||||
auto obj = searchObject(m_fi);
|
||||
if (obj.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QFile f(fi.filePath());
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
auto name = obj.value("fileName").toString();
|
||||
auto unsupportedFormat = obj.value("unsupportedFormat").toBool();
|
||||
comment = obj.value("comment").toString();
|
||||
|
||||
if(obj.value("disableAutoTransform").toBool()) {
|
||||
flags |= TestFlag::DisableAutotransform;
|
||||
}
|
||||
|
||||
if (unsupportedFormat) {
|
||||
flags |= TestFlag::SkipTest;
|
||||
return {};
|
||||
}
|
||||
|
||||
QJsonParseError err;
|
||||
auto doc = QJsonDocument::fromJson(f.readAll(), &err);
|
||||
if (err.error != QJsonParseError::NoError || !doc.isArray()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto currentQt = QVersionNumber::fromString(qVersion());
|
||||
auto arr = doc.array();
|
||||
for (auto val : arr) {
|
||||
if (!val.isObject())
|
||||
continue;
|
||||
auto obj = val.toObject();
|
||||
auto minQt = QVersionNumber::fromString(obj.value("minQtVersion").toString());
|
||||
auto maxQt = QVersionNumber::fromString(obj.value("maxQtVersion").toString());
|
||||
auto name = obj.value("fileName").toString();
|
||||
auto unsupportedFormat = obj.value("unsupportedFormat").toBool();
|
||||
comment = obj.value("comment").toString();
|
||||
|
||||
if(obj.value("disableAutoTransform").toBool())
|
||||
flags |= TestFlag::DisableAutotransform;
|
||||
|
||||
// filter
|
||||
if (name.isEmpty() && !unsupportedFormat)
|
||||
continue;
|
||||
if (!minQt.isNull() && currentQt < minQt)
|
||||
continue;
|
||||
if (!maxQt.isNull() && currentQt > maxQt)
|
||||
continue;
|
||||
if (unsupportedFormat) {
|
||||
flags |= TestFlag::SkipTest;
|
||||
break;
|
||||
}
|
||||
return QFileInfo(QStringLiteral("%1/%2").arg(fi.path(), name));
|
||||
}
|
||||
|
||||
return {};
|
||||
return QFileInfo(QStringLiteral("%1/%2").arg(m_fi.path(), name));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user