EXIF: always use little-endian for UTF-16

In practice UTF-16 (especially from windows) uses little-endian without
a BOM. By default Qt uses host endianess which causes TIFF_XPTITLE and
TIFF_XPKEYWORDS to not be read correctly.

Fixes c21b50d699
This commit is contained in:
Sertonix Norson
2026-10-05 12:28:36 +02:00
parent af34c774d3
commit cb74a20421
+6 -5
View File
@@ -13,6 +13,7 @@
#include <QDataStream> #include <QDataStream>
#include <QHash> #include <QHash>
#include <QStringDecoder> #include <QStringDecoder>
#include <QStringEncoder>
#include <QTimeZone> #include <QTimeZone>
// TIFF 6 specs // TIFF 6 specs
@@ -1748,9 +1749,10 @@ void MicroExif::setUtf16String(Tags &tags, quint16 tagId, const QString &s)
tags.remove(tagId); tags.remove(tagId);
return; return;
} }
auto s16 = s.toStdU16String();
QStringEncoder fromUtf16(QStringEncoder::Utf16LE, QStringEncoder::Flag::Stateless);
QByteArray ba = fromUtf16(s);
QList<quint8> uba; QList<quint8> uba;
auto ba = QByteArrayView(reinterpret_cast<char*>(s16.data()), s.size() * 2);
for(auto&& c : ba) for(auto&& c : ba)
uba.append(quint8(c)); uba.append(quint8(c));
uba.append(quint8('\0')); uba.append(quint8('\0'));
@@ -1763,7 +1765,6 @@ QString MicroExif::utf16String(const Tags &tags, quint16 tagId)
auto ba = tags.value(tagId).value<QList<quint8>>(); auto ba = tags.value(tagId).value<QList<quint8>>();
if (ba.isEmpty()) if (ba.isEmpty())
return {}; return {};
auto p16 = reinterpret_cast<char16_t*>(ba.data()); QStringDecoder toUtf16(QStringDecoder::Utf16LE, QStringDecoder::Flag::Stateless);
auto sz = std::max(ba.size() / 2 - 1, qsizetype()); return toUtf16(QByteArrayView(ba.data(), std::max(ba.size() - 2, qsizetype())));
return QString::fromUtf16(p16, sz);
} }