Package: release.debian.org
Severity: normal
X-Debbugs-Cc: kf6-kimageform...@packages.debian.org, Debian Qt/KDE Maintainers 
<debian-qt-...@lists.debian.org>
Control: affects -1 + src:kf6-kimageformats
User: release.debian....@packages.debian.org
Usertags: unblock

Dear Release Team,

please unblock package kf6-kimageformats.

[ Reason ]
It contains the following changes:
* Backport upstream commits:
  - Improve EXIF V3 compatibility.
  - Multiple fixes for jxr files management.

[ Tests ]
Upstream testsuite passes.

[ Risks ]
Only backport of upstream commits that apply cleanly. Further fixes can
easily be backported or the changes reverted.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing


Thanks!


unblock kf6-kimageformats/6.13.0-2
diff -Nru kf6-kimageformats-6.13.0/debian/changelog 
kf6-kimageformats-6.13.0/debian/changelog
--- kf6-kimageformats-6.13.0/debian/changelog   2025-04-12 19:35:54.000000000 
+0200
+++ kf6-kimageformats-6.13.0/debian/changelog   2025-05-17 01:06:18.000000000 
+0200
@@ -1,3 +1,12 @@
+kf6-kimageformats (6.13.0-2) unstable; urgency=medium
+
+  [ Aurélien COUDERC ]
+  * Backport upstream commits:
+    - Improve EXIF V3 compatibility.
+    - Multiple fixes for jxr files management.
+
+ -- Aurélien COUDERC <couc...@debian.org>  Sat, 17 May 2025 01:06:18 +0200
+
 kf6-kimageformats (6.13.0-1) unstable; urgency=medium
 
   [ Patrick Franz ]
diff -Nru kf6-kimageformats-6.13.0/debian/patches/series 
kf6-kimageformats-6.13.0/debian/patches/series
--- kf6-kimageformats-6.13.0/debian/patches/series      1970-01-01 
01:00:00.000000000 +0100
+++ kf6-kimageformats-6.13.0/debian/patches/series      2025-05-16 
23:45:46.000000000 +0200
@@ -0,0 +1,4 @@
+upstream_ae62ea3d_Improved-EXIF-V3-compatibility.patch
+upstream_2adca7c0_jxr-Use-qsizetype-for-image-size-variables.patch
+upstream_850068c1_JXR-fix-compilation-error-on-32-bit-systems.patch
+upstream_e3aefd2a_JXR-Restore-device-position-after-reading-options.patch
diff -Nru 
kf6-kimageformats-6.13.0/debian/patches/upstream_2adca7c0_jxr-Use-qsizetype-for-image-size-variables.patch
 
kf6-kimageformats-6.13.0/debian/patches/upstream_2adca7c0_jxr-Use-qsizetype-for-image-size-variables.patch
--- 
kf6-kimageformats-6.13.0/debian/patches/upstream_2adca7c0_jxr-Use-qsizetype-for-image-size-variables.patch
  1970-01-01 01:00:00.000000000 +0100
+++ 
kf6-kimageformats-6.13.0/debian/patches/upstream_2adca7c0_jxr-Use-qsizetype-for-image-size-variables.patch
  2025-05-16 23:44:34.000000000 +0200
@@ -0,0 +1,38 @@
+From 2adca7c0ca506480bde0b87afbc6c7a03919a829 Mon Sep 17 00:00:00 2001
+From: Alessandro Astone <ales.ast...@gmail.com>
+Date: Mon, 21 Apr 2025 10:06:58 +0200
+Subject: [PATCH] jxr: Use qsizetype for image size variables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes type mismatch on 32-bit architectures.
+
+/builddir/build/BUILD/kf6-kimageformats-6.13.0-build/kimageformats-6.13.0/src/imageformats/jxr.cpp:
 In member function ‘virtual bool JXRHandler::read(QImage*)’:
+/builddir/build/BUILD/kf6-kimageformats-6.13.0-build/kimageformats-6.13.0/src/imageformats/jxr.cpp:994:88:
 error: no matching function for call to ‘min(qint64&, qsizetype)’
+  994 |                 std::memcpy(img.scanLine(y), ba.data() + 
convStrideSize * y, (std::min)(convStrideSize, img.bytesPerLine()));
+      |                                                                        
      ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---
+ src/imageformats/jxr.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/imageformats/jxr.cpp b/src/imageformats/jxr.cpp
+index fbc2bcf3..7e535f17 100644
+--- a/src/imageformats/jxr.cpp
++++ b/src/imageformats/jxr.cpp
+@@ -977,9 +977,9 @@ bool JXRHandler::read(QImage *outImage)
+                 return false;
+             }
+         } else { // additional buffer needed
+-            qint64 convStrideSize = (img.width() * 
d->pDecoder->WMP.wmiI.cBitsPerUnit + 7) / 8;
+-            qint64 buffSize = convStrideSize * img.height();
+-            qint64 limit = QImageReader::allocationLimit();
++            qsizetype convStrideSize = (img.width() * 
d->pDecoder->WMP.wmiI.cBitsPerUnit + 7) / 8;
++            qsizetype buffSize = convStrideSize * img.height();
++            qsizetype limit = QImageReader::allocationLimit();
+             if (limit && (buffSize + img.sizeInBytes()) > limit * 1024 * 
1024) {
+                 qCWarning(LOG_JXRPLUGIN) << "JXRHandler::read() unable to 
covert due to allocation limit set:" << limit << "MiB";
+                 return false;
+-- 
+GitLab
+
diff -Nru 
kf6-kimageformats-6.13.0/debian/patches/upstream_850068c1_JXR-fix-compilation-error-on-32-bit-systems.patch
 
kf6-kimageformats-6.13.0/debian/patches/upstream_850068c1_JXR-fix-compilation-error-on-32-bit-systems.patch
--- 
kf6-kimageformats-6.13.0/debian/patches/upstream_850068c1_JXR-fix-compilation-error-on-32-bit-systems.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
kf6-kimageformats-6.13.0/debian/patches/upstream_850068c1_JXR-fix-compilation-error-on-32-bit-systems.patch
 2025-05-16 23:45:23.000000000 +0200
@@ -0,0 +1,38 @@
+From 850068c1dc81c2ae0867cf395ae488f6d6c33781 Mon Sep 17 00:00:00 2001
+From: Mirco Miranda <mirco.mira...@systemceramics.com>
+Date: Tue, 22 Apr 2025 08:01:02 +0200
+Subject: [PATCH] JXR: fix compilation error on 32-bit systems
+
+---
+ src/imageformats/jxr.cpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/imageformats/jxr.cpp b/src/imageformats/jxr.cpp
+index 7e535f17..7124f53c 100644
+--- a/src/imageformats/jxr.cpp
++++ b/src/imageformats/jxr.cpp
+@@ -977,9 +977,9 @@ bool JXRHandler::read(QImage *outImage)
+                 return false;
+             }
+         } else { // additional buffer needed
+-            qsizetype convStrideSize = (img.width() * 
d->pDecoder->WMP.wmiI.cBitsPerUnit + 7) / 8;
+-            qsizetype buffSize = convStrideSize * img.height();
+-            qsizetype limit = QImageReader::allocationLimit();
++            qint64 convStrideSize = (img.width() * 
d->pDecoder->WMP.wmiI.cBitsPerUnit + 7) / 8;
++            qint64 buffSize = convStrideSize * img.height();
++            qint64 limit = QImageReader::allocationLimit();
+             if (limit && (buffSize + img.sizeInBytes()) > limit * 1024 * 
1024) {
+                 qCWarning(LOG_JXRPLUGIN) << "JXRHandler::read() unable to 
covert due to allocation limit set:" << limit << "MiB";
+                 return false;
+@@ -991,7 +991,7 @@ bool JXRHandler::read(QImage *outImage)
+                 return false;
+             }
+             for (qint32 y = 0, h = img.height(); y < h; ++y) {
+-                std::memcpy(img.scanLine(y), ba.data() + convStrideSize * y, 
(std::min)(convStrideSize, img.bytesPerLine()));
++                std::memcpy(img.scanLine(y), ba.data() + convStrideSize * y, 
(std::min)(convStrideSize, qint64(img.bytesPerLine())));
+             }
+         }
+         PKFormatConverter_Release(&pConverter);
+-- 
+GitLab
+
diff -Nru 
kf6-kimageformats-6.13.0/debian/patches/upstream_ae62ea3d_Improved-EXIF-V3-compatibility.patch
 
kf6-kimageformats-6.13.0/debian/patches/upstream_ae62ea3d_Improved-EXIF-V3-compatibility.patch
--- 
kf6-kimageformats-6.13.0/debian/patches/upstream_ae62ea3d_Improved-EXIF-V3-compatibility.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
kf6-kimageformats-6.13.0/debian/patches/upstream_ae62ea3d_Improved-EXIF-V3-compatibility.patch
      2025-05-16 23:42:51.000000000 +0200
@@ -0,0 +1,368 @@
+From ae62ea3dfc7ac1d73c2ed95a58c8e413540aca57 Mon Sep 17 00:00:00 2001
+From: Mirco Miranda <mirco...@gmail.com>
+Date: Fri, 18 Apr 2025 13:53:12 +0000
+Subject: [PATCH] Improved EXIF V3 compatibility
+
+EXIF specs V3 added the UTF-8 data type. The MicroExif class now allows 
serializations to choose whether to support the V2 or V3 format. To maximize 
compatibility with old readers, even when V3 is set, the ASCII data type is 
used if possible.
+
+The JXR plugin, based on TIFF V6 container, does not allow to use the V3 
format (it does not recognize the UTF-8 data type) and therefore V2 has been 
forced. For all other plugins using MicroExif, it is now possible to save, 
e.g., descriptions in Japanese.
+
+Please note that this patch is also a bugfix: when saving, version 3 was set 
but the strings were always saved as ASCII.
+---
+ autotests/write/basic/avif.json |  2 +-
+ autotests/write/basic/heif.json |  2 +-
+ autotests/write/basic/jxl.json  |  2 +-
+ src/imageformats/jxr.cpp        |  4 +-
+ src/imageformats/microexif.cpp  | 84 ++++++++++++++++++++++-----------
+ src/imageformats/microexif_p.h  | 25 +++++++---
+ 6 files changed, 80 insertions(+), 39 deletions(-)
+
+diff --git a/autotests/write/basic/avif.json b/autotests/write/basic/avif.json
+index 1e99fb58..d91d0d8f 100644
+--- a/autotests/write/basic/avif.json
++++ b/autotests/write/basic/avif.json
+@@ -31,7 +31,7 @@
+         },
+         {
+             "key" : "Description",
+-            "value" : "TV broadcast test image."
++            "value" : "テレビ放送テスト映像。(TV broadcast test image.)"
+         },
+         {
+             "key" : "Latitude",
+diff --git a/autotests/write/basic/heif.json b/autotests/write/basic/heif.json
+index 479d742d..a89919fe 100644
+--- a/autotests/write/basic/heif.json
++++ b/autotests/write/basic/heif.json
+@@ -31,7 +31,7 @@
+         },
+         {
+             "key" : "Description",
+-            "value" : "TV broadcast test image."
++            "value" : "テレビ放送テスト映像。(TV broadcast test image.)"
+         },
+         {
+             "key" : "Latitude",
+diff --git a/autotests/write/basic/jxl.json b/autotests/write/basic/jxl.json
+index c5ba2db3..24e96008 100644
+--- a/autotests/write/basic/jxl.json
++++ b/autotests/write/basic/jxl.json
+@@ -31,7 +31,7 @@
+         },
+         {
+             "key" : "Description",
+-            "value" : "TV broadcast test image."
++            "value" : "テレビ放送テスト映像。(TV broadcast test image.)"
+         },
+         {
+             "key" : "Latitude",
+diff --git a/src/imageformats/jxr.cpp b/src/imageformats/jxr.cpp
+index 8b2e3522..fbc2bcf3 100644
+--- a/src/imageformats/jxr.cpp
++++ b/src/imageformats/jxr.cpp
+@@ -720,11 +720,11 @@ public:
+ 
+         auto exif = MicroExif::fromImage(image);
+         if (!exif.isEmpty()) {
+-            auto exifIfd = exif.exifIfdByteArray(QDataStream::LittleEndian);
++            auto exifIfd = exif.exifIfdByteArray(QDataStream::LittleEndian, 
MicroExif::V2);
+             if (auto err = PKImageEncode_SetEXIFMetadata_WMP(pEncoder, 
reinterpret_cast<const quint8 *>(exifIfd.constData()), exifIfd.size())) {
+                 qCWarning(LOG_JXRPLUGIN) << "JXRHandler::write() error while 
setting EXIF data:" << err;
+             }
+-            auto gpsIfd = exif.gpsIfdByteArray(QDataStream::LittleEndian);
++            auto gpsIfd = exif.gpsIfdByteArray(QDataStream::LittleEndian, 
MicroExif::V2);
+             if (auto err = PKImageEncode_SetGPSInfoMetadata_WMP(pEncoder, 
reinterpret_cast<const quint8 *>(gpsIfd.constData()), gpsIfd.size())) {
+                 qCWarning(LOG_JXRPLUGIN) << "JXRHandler::write() error while 
setting GPS data:" << err;
+             }
+diff --git a/src/imageformats/microexif.cpp b/src/imageformats/microexif.cpp
+index 4a113bff..785e6176 100644
+--- a/src/imageformats/microexif.cpp
++++ b/src/imageformats/microexif.cpp
+@@ -111,17 +111,17 @@ static const KnownTags staticTagTypes = {
+     TagInfo(TIFF_IMAGEWIDTH, ExifTagType::Long),
+     TagInfo(TIFF_IMAGEHEIGHT, ExifTagType::Long),
+     TagInfo(TIFF_BITSPERSAMPLE, ExifTagType::Short),
+-    TagInfo(TIFF_IMAGEDESCRIPTION, ExifTagType::Ascii),
+-    TagInfo(TIFF_MAKE, ExifTagType::Ascii),
+-    TagInfo(TIFF_MODEL, ExifTagType::Ascii),
++    TagInfo(TIFF_IMAGEDESCRIPTION, ExifTagType::Utf8),
++    TagInfo(TIFF_MAKE, ExifTagType::Utf8),
++    TagInfo(TIFF_MODEL, ExifTagType::Utf8),
+     TagInfo(TIFF_ORIENT, ExifTagType::Short),
+     TagInfo(TIFF_XRES, ExifTagType::Rational),
+     TagInfo(TIFF_YRES, ExifTagType::Rational),
+     TagInfo(TIFF_URES, ExifTagType::Short),
+-    TagInfo(TIFF_SOFTWARE, ExifTagType::Ascii),
+-    TagInfo(TIFF_ARTIST, ExifTagType::Ascii),
++    TagInfo(TIFF_SOFTWARE, ExifTagType::Utf8),
++    TagInfo(TIFF_ARTIST, ExifTagType::Utf8),
+     TagInfo(TIFF_DATETIME, ExifTagType::Ascii),
+-    TagInfo(TIFF_COPYRIGHT, ExifTagType::Ascii),
++    TagInfo(TIFF_COPYRIGHT, ExifTagType::Utf8),
+     TagInfo(EXIF_EXIFIFD, ExifTagType::Long),
+     TagInfo(EXIF_GPSIFD, ExifTagType::Long),
+     TagInfo(EXIF_DATETIMEORIGINAL, ExifTagType::Ascii),
+@@ -134,10 +134,10 @@ static const KnownTags staticTagTypes = {
+     TagInfo(EXIF_PIXELYDIM, ExifTagType::Long),
+     TagInfo(EXIF_IMAGEUNIQUEID, ExifTagType::Ascii),
+     TagInfo(EXIF_BODYSERIALNUMBER, ExifTagType::Ascii),
+-    TagInfo(EXIF_LENSMAKE, ExifTagType::Ascii),
+-    TagInfo(EXIF_LENSMODEL, ExifTagType::Ascii),
++    TagInfo(EXIF_LENSMAKE, ExifTagType::Utf8),
++    TagInfo(EXIF_LENSMODEL, ExifTagType::Utf8),
+     TagInfo(EXIF_LENSSERIALNUMBER, ExifTagType::Ascii),
+-    TagInfo(EXIF_IMAGETITLE, ExifTagType::Ascii),
++    TagInfo(EXIF_IMAGETITLE, ExifTagType::Utf8),
+     TagInfo(EXIF_EXIFVERSION, ExifTagType::Undefined)
+ };
+ // clang-format on
+@@ -367,6 +367,30 @@ static void writeData(QDataStream &ds, const QVariant 
&value, const ExifTagType&
+     }
+ }
+ 
++static ExifTagType updateDataType(const ExifTagType &dataType, const QVariant 
&value, const MicroExif::Version &ver)
++{
++    if (dataType != ExifTagType::Utf8)
++        return dataType;
++
++    if (ver == MicroExif::V2)
++        return ExifTagType::Ascii;
++
++    // Note that in EXIF specs, UTF-8 is backward compatible with ASCII: all 
UTF-8 tags can also be ASCII.
++    // To maximize compatibility, I check if the string can be encoded in 
ASCII.
++    auto txt = value.toString();
++
++    // I try to implement a rudimentary check without going through Qt's 
string conversion classes:
++    // a UTF-8 string if it uses only characters in the first 127 of the 
ASCII table is encoded as
++    // a Latin 1. Each character above 128, whether it is an extended ASCII 
character or a character
++    // of another nature, uses 2 or more bytes. Since the EXIF 
​​specifications state that the ASCII
++    // type must use only the first 127 characters, I only need to do the 
size comparison to understand
++    // which type to use.
++    if (txt.toLatin1().size() == txt.toUtf8().size())
++        return ExifTagType::Ascii;
++
++    return dataType;
++}
++
+ /*!
+  * \brief writeIfd
+  * \param ds The stream.
+@@ -375,7 +399,12 @@ static void writeData(QDataStream &ds, const QVariant 
&value, const ExifTagType&
+  * \param knownTags List of known and supported tags.
+  * \return True on success, otherwise false.
+  */
+-static bool writeIfd(QDataStream &ds, const MicroExif::Tags &tags, TagPos 
&positions, quint32 pos = 0, const KnownTags &knownTags = staticTagTypes)
++static bool writeIfd(QDataStream &ds,
++                     const MicroExif::Version &ver,
++                     const MicroExif::Tags &tags,
++                     TagPos &positions,
++                     quint32 pos = 0,
++                     const KnownTags &knownTags = staticTagTypes)
+ {
+     if (tags.isEmpty())
+         return true;
+@@ -390,7 +419,7 @@ static bool writeIfd(QDataStream &ds, const 
MicroExif::Tags &tags, TagPos &posit
+             continue;
+         }
+         auto value = tags.value(key);
+-        auto dataType = knownTags.value(key);
++        auto dataType = updateDataType(knownTags.value(key), value, ver);
+         auto count = countBytes(dataType, value);
+ 
+         ds << quint16(key);
+@@ -412,9 +441,8 @@ static bool writeIfd(QDataStream &ds, const 
MicroExif::Tags &tags, TagPos &posit
+         if (!knownTags.contains(key)) {
+             continue;
+         }
+-
+         auto value = tags.value(key);
+-        auto dataType = knownTags.value(key);
++        auto dataType = updateDataType(knownTags.value(key), value, ver);
+         auto count = countBytes(dataType, value);
+         auto valueSize = count * EXIF_TAG_SIZEOF(dataType);
+         if (valueSize <= 4)
+@@ -1032,7 +1060,7 @@ void MicroExif::setImageDirection(double degree, bool 
isMagnetic)
+     m_gpsTags.insert(GPS_IMGDIRECTION, degree);
+ }
+ 
+-QByteArray MicroExif::toByteArray(const QDataStream::ByteOrder &byteOrder) 
const
++QByteArray MicroExif::toByteArray(const QDataStream::ByteOrder &byteOrder, 
const Version &version) const
+ {
+     QByteArray ba;
+     {
+@@ -1043,16 +1071,16 @@ QByteArray MicroExif::toByteArray(const 
QDataStream::ByteOrder &byteOrder) const
+     return ba;
+ }
+ 
+-QByteArray MicroExif::exifIfdByteArray(const QDataStream::ByteOrder 
&byteOrder) const
++QByteArray MicroExif::exifIfdByteArray(const QDataStream::ByteOrder 
&byteOrder, const Version &version) const
+ {
+     QByteArray ba;
+     {
+         QDataStream ds(&ba, QIODevice::WriteOnly);
+         ds.setByteOrder(byteOrder);
+         auto exifTags = m_exifTags;
+-        exifTags.insert(EXIF_EXIFVERSION, QByteArray("0300"));
++        exifTags.insert(EXIF_EXIFVERSION, version == Version::V3 ? 
QByteArray("0300") : QByteArray("0232"));
+         TagPos positions;
+-        if (!writeIfd(ds, exifTags, positions))
++        if (!writeIfd(ds, version, exifTags, positions))
+             return {};
+     }
+     return ba;
+@@ -1065,7 +1093,7 @@ bool MicroExif::setExifIfdByteArray(const QByteArray 
&ba, const QDataStream::Byt
+     return readIfd(ds, m_exifTags, 0, staticTagTypes);
+ }
+ 
+-QByteArray MicroExif::gpsIfdByteArray(const QDataStream::ByteOrder 
&byteOrder) const
++QByteArray MicroExif::gpsIfdByteArray(const QDataStream::ByteOrder 
&byteOrder, const Version &version) const
+ {
+     QByteArray ba;
+     {
+@@ -1074,7 +1102,7 @@ QByteArray MicroExif::gpsIfdByteArray(const 
QDataStream::ByteOrder &byteOrder) c
+         auto gpsTags = m_gpsTags;
+         gpsTags.insert(GPS_GPSVERSION, QByteArray("2400"));
+         TagPos positions;
+-        if (!writeIfd(ds, gpsTags, positions, 0, staticGpsTagTypes))
++        if (!writeIfd(ds, version, gpsTags, positions, 0, staticGpsTagTypes))
+             return {};
+         return ba;
+     }
+@@ -1087,7 +1115,7 @@ bool MicroExif::setGpsIfdByteArray(const QByteArray &ba, 
const QDataStream::Byte
+     return readIfd(ds, m_gpsTags, 0, staticGpsTagTypes);
+ }
+ 
+-bool MicroExif::write(QIODevice *device, const QDataStream::ByteOrder 
&byteOrder) const
++bool MicroExif::write(QIODevice *device, const QDataStream::ByteOrder 
&byteOrder, const Version &version) const
+ {
+     if (device == nullptr || device->isSequential() || isEmpty())
+         return false;
+@@ -1096,7 +1124,7 @@ bool MicroExif::write(QIODevice *device, const 
QDataStream::ByteOrder &byteOrder
+         ds.setByteOrder(byteOrder);
+         if (!writeHeader(ds))
+             return false;
+-        if (!writeIfds(ds))
++        if (!writeIfds(ds, version))
+             return false;
+     }
+     device->close();
+@@ -1327,30 +1355,30 @@ bool MicroExif::writeHeader(QDataStream &ds) const
+     return ds.status() ==  QDataStream::Ok;
+ }
+ 
+-bool MicroExif::writeIfds(QDataStream &ds) const
++bool MicroExif::writeIfds(QDataStream &ds, const Version &version) const
+ {
+     auto tiffTags = m_tiffTags;
+     auto exifTags = m_exifTags;
+     auto gpsTags = m_gpsTags;
+-    updateTags(tiffTags, exifTags, gpsTags);
++    updateTags(tiffTags, exifTags, gpsTags, version);
+ 
+     TagPos positions;
+-    if (!writeIfd(ds, tiffTags, positions))
++    if (!writeIfd(ds, version, tiffTags, positions))
+         return false;
+-    if (!writeIfd(ds, exifTags, positions, positions.value(EXIF_EXIFIFD)))
++    if (!writeIfd(ds, version, exifTags, positions, 
positions.value(EXIF_EXIFIFD)))
+         return false;
+-    if (!writeIfd(ds, gpsTags, positions, positions.value(EXIF_GPSIFD), 
staticGpsTagTypes))
++    if (!writeIfd(ds, version, gpsTags, positions, 
positions.value(EXIF_GPSIFD), staticGpsTagTypes))
+         return false;
+     return true;
+ }
+ 
+-void MicroExif::updateTags(Tags &tiffTags, Tags &exifTags, Tags &gpsTags) 
const
++void MicroExif::updateTags(Tags &tiffTags, Tags &exifTags, Tags &gpsTags, 
const Version &version) const
+ {
+     if (exifTags.isEmpty()) {
+         tiffTags.remove(EXIF_EXIFIFD);
+     } else {
+         tiffTags.insert(EXIF_EXIFIFD, quint32());
+-        exifTags.insert(EXIF_EXIFVERSION, QByteArray("0300"));
++        exifTags.insert(EXIF_EXIFVERSION, version == Version::V3 ? 
QByteArray("0300") : QByteArray("0232"));
+     }
+     if (gpsTags.isEmpty()) {
+         tiffTags.remove(EXIF_GPSIFD);
+diff --git a/src/imageformats/microexif_p.h b/src/imageformats/microexif_p.h
+index 6014d48d..6e89b020 100644
+--- a/src/imageformats/microexif_p.h
++++ b/src/imageformats/microexif_p.h
+@@ -37,6 +37,15 @@ class MicroExif
+ public:
+     using Tags = QMap<quint16, QVariant>;
+ 
++    /*!
++     * \brief The Version enum
++     * Exif specs version used when writing.
++     */
++    enum Version {
++        V2, // V2.xx
++        V3 // V3.xx, use of UTF-8 data type (default)
++    };
++
+     /*!
+      * \brief MicroExif
+      * Constructs an empty class.
+@@ -265,18 +274,20 @@ public:
+      * - EXIF IFD
+      * - GPS IFD
+      * \param byteOrder Sets the serialization byte order for EXIF data.
++     * \param version The EXIF specs version to use.
+      * \return A byte array containing the serialized data.
+      * \sa write
+      */
+-    QByteArray toByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER) const;
++    QByteArray toByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER, const Version &version = Version::V3) const;
+ 
+     /*!
+      * \brief exifIfdByteArray
+      * Convert the EXIF IFD only to RAW data. Useful when you want to add 
EXIF data to an existing TIFF container.
+      * \param byteOrder Sets the serialization byte order for the data.
++     * \param version The EXIF specs version to use.
+      * \return A byte array containing the serialized data.
+      */
+-    QByteArray exifIfdByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER) const;
++    QByteArray exifIfdByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER, const Version &version = Version::V3) const;
+     /*!
+      * \brief setExifIfdByteArray
+      * \param ba The RAW data of EXIF IFD.
+@@ -289,9 +300,10 @@ public:
+      * \brief gpsIfdByteArray
+      * Convert the GPS IFD only to RAW data. Useful when you want to add GPS 
data to an existing TIFF container.
+      * \param byteOrder Sets the serialization byte order for the data.
++     * \param version The EXIF specs version to use.
+      * \return A byte array containing the serialized data.
+      */
+-    QByteArray gpsIfdByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER) const;
++    QByteArray gpsIfdByteArray(const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER, const Version &version = Version::V3) const;
+     /*!
+      * \brief setGpsIfdByteArray
+      * \param ba The RAW data of GPS IFD.
+@@ -309,10 +321,11 @@ public:
+      * - GPS IFD
+      * \param device A random access device.
+      * \param byteOrder Sets the serialization byte order for EXIF data.
++     * \param version The EXIF specs version to use.
+      * \return True on success, otherwise false.
+      * \sa toByteArray
+      */
+-    bool write(QIODevice *device, const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER) const;
++    bool write(QIODevice *device, const QDataStream::ByteOrder &byteOrder = 
EXIF_DEFAULT_BYTEORDER, const Version &version = Version::V3) const;
+ 
+     /*!
+      * \brief updateImageMetadata
+@@ -373,8 +386,8 @@ private:
+     void setGpsString(quint16 tagId, const QString& s);
+     QString gpsString(quint16 tagId) const;
+     bool writeHeader(QDataStream &ds) const;
+-    bool writeIfds(QDataStream &ds) const;
+-    void updateTags(Tags &tiffTags, Tags &exifTags, Tags &gpsTags) const;
++    bool writeIfds(QDataStream &ds, const Version &version) const;
++    void updateTags(Tags &tiffTags, Tags &exifTags, Tags &gpsTags, const 
Version &version) const;
+ 
+     static void setString(Tags &tags, quint16 tagId, const QString &s);
+     static QString string(const Tags &tags, quint16 tagId);
+-- 
+GitLab
+
diff -Nru 
kf6-kimageformats-6.13.0/debian/patches/upstream_e3aefd2a_JXR-Restore-device-position-after-reading-options.patch
 
kf6-kimageformats-6.13.0/debian/patches/upstream_e3aefd2a_JXR-Restore-device-position-after-reading-options.patch
--- 
kf6-kimageformats-6.13.0/debian/patches/upstream_e3aefd2a_JXR-Restore-device-position-after-reading-options.patch
   1970-01-01 01:00:00.000000000 +0100
+++ 
kf6-kimageformats-6.13.0/debian/patches/upstream_e3aefd2a_JXR-Restore-device-position-after-reading-options.patch
   2025-05-16 23:45:46.000000000 +0200
@@ -0,0 +1,68 @@
+From e3aefd2aa1f9be6598b24d118d7b90e9931b5172 Mon Sep 17 00:00:00 2001
+From: Mirco Miranda <mirco...@gmail.com>
+Date: Wed, 14 May 2025 02:50:03 +0200
+Subject: [PATCH] JXR: Restore device position after reading options
+
+---
+ src/imageformats/jxr.cpp | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/src/imageformats/jxr.cpp b/src/imageformats/jxr.cpp
+index 7124f53c..725196e6 100644
+--- a/src/imageformats/jxr.cpp
++++ b/src/imageformats/jxr.cpp
+@@ -243,6 +243,24 @@ public:
+         return true;
+     }
+ 
++    /*!
++     * \brief initForReadingAndRollBack
++     * Initialize the device for reading and rollback the device to start 
position.
++     * \param device The source device.
++     * \return True on success, otherwise false.
++     */
++    bool initForReadingAndRollBack(QIODevice *device)
++    {
++        if (device) {
++            device->startTransaction();
++        }
++        auto ok = initForReading(device);
++        if (device) {
++            device->rollbackTransaction();
++        }
++        return ok;
++    }
++
+     /*!
+      * \brief jxrFormat
+      * \return The JXR format.
+@@ -1153,7 +1171,7 @@ QVariant JXRHandler::option(ImageOption option) const
+     QVariant v;
+ 
+     if (option == QImageIOHandler::Size) {
+-        if (d->initForReading(device())) {
++        if (d->initForReadingAndRollBack(device())) {
+             auto size = d->imageSize();
+             if (size.isValid()) {
+                 v = QVariant::fromValue(size);
+@@ -1162,7 +1180,7 @@ QVariant JXRHandler::option(ImageOption option) const
+     }
+ 
+     if (option == QImageIOHandler::ImageFormat) {
+-        if (d->initForReading(device())) {
++        if (d->initForReadingAndRollBack(device())) {
+             v = QVariant::fromValue(d->imageFormat());
+         }
+     }
+@@ -1173,7 +1191,7 @@ QVariant JXRHandler::option(ImageOption option) const
+ 
+     if (option == QImageIOHandler::ImageTransformation) {
+         // ignore result: I might want to read the value set in writing
+-        d->initForReading(device());
++        d->initForReadingAndRollBack(device());
+         v = int(d->transformation());
+     }
+ 
+-- 
+GitLab
+

Reply via email to