From 25cc8bc262f26e7e7e78c90ecf3903663368cdb6 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Mon, 3 Mar 2025 09:17:56 +0100 Subject: [PATCH] MicroExif: search for the TIFF signature --- src/imageformats/heif.cpp | 2 +- src/imageformats/microexif.cpp | 20 ++++++++++++++++---- src/imageformats/microexif_p.h | 11 ++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/imageformats/heif.cpp b/src/imageformats/heif.cpp index 46bd4c5..fd96b0d 100644 --- a/src/imageformats/heif.cpp +++ b/src/imageformats/heif.cpp @@ -953,7 +953,7 @@ bool HEIFHandler::ensureDecoder() if (isXmp) { m_current_image.setText(QStringLiteral(META_KEY_XMP_ADOBE), QString::fromUtf8(ba)); } else if (isExif) { - auto exif = MicroExif::fromByteArray(ba.mid(4)); + auto exif = MicroExif::fromByteArray(ba, true); if (!exif.isEmpty()) { exif.updateImageResolution(m_current_image); exif.updateImageMetadata(m_current_image); diff --git a/src/imageformats/microexif.cpp b/src/imageformats/microexif.cpp index 5cebcb8..4a113bf 100644 --- a/src/imageformats/microexif.cpp +++ b/src/imageformats/microexif.cpp @@ -1166,18 +1166,30 @@ void MicroExif::updateImageResolution(QImage &targetImage) targetImage.setDotsPerMeterY(qRound(verticalResolution() / 25.4 * 1000)); } -MicroExif MicroExif::fromByteArray(const QByteArray &ba) +MicroExif MicroExif::fromByteArray(const QByteArray &ba, bool searchHeader) { + auto ba0(ba); + if (searchHeader) { + auto idxLE = ba0.indexOf(QByteArray("II")); + auto idxBE = ba0.indexOf(QByteArray("MM")); + auto idx = -1; + if (idxLE > -1 && idxBE > -1) + idx = std::min(idxLE, idxBE); + else + idx = idxLE > -1 ? idxLE : idxBE; + if(idx > 0) + ba0 = ba0.mid(idx); + } QBuffer buf; - buf.setData(ba); + buf.setData(ba0); return fromDevice(&buf); } -MicroExif MicroExif::fromRawData(const char *data, size_t size) +MicroExif MicroExif::fromRawData(const char *data, size_t size, bool searchHeader) { if (data == nullptr || size == 0) return {}; - return fromByteArray(QByteArray::fromRawData(data, size)); + return fromByteArray(QByteArray::fromRawData(data, size), searchHeader); } MicroExif MicroExif::fromDevice(QIODevice *device) diff --git a/src/imageformats/microexif_p.h b/src/imageformats/microexif_p.h index e469259..6014d48 100644 --- a/src/imageformats/microexif_p.h +++ b/src/imageformats/microexif_p.h @@ -332,18 +332,23 @@ public: /*! * \brief fromByteArray * Creates the class from RAW EXIF data. + * \param ba Raw data containing EXIF ​​data. + * \param searchHeader If true, the EXIF ​​header is searched within the data. If false, the data must begin with the EXIF ​​header. * \return The created class (empty on error). * \sa isEmpty */ - static MicroExif fromByteArray(const QByteArray &ba); + static MicroExif fromByteArray(const QByteArray &ba, bool searchHeader = false); /*! * \brief fromRawData * Creates the class from RAW EXIF data. + * \param data Raw data containing EXIF ​​data. + * \param size The size of \a data. + * \param searchHeader If true, the EXIF ​​header is searched within the data. If false, the data must begin with the EXIF ​​header. * \return The created class (empty on error). - * \sa isEmpty + * \sa isEmpty, fromByteArray */ - static MicroExif fromRawData(const char *data, size_t size); + static MicroExif fromRawData(const char *data, size_t size, bool searchHeader = false); /*! * \brief fromDevice