From a587ecf2f6920ae8f0adc3895a31209457c8137a Mon Sep 17 00:00:00 2001 From: qbnu <93988953+qbnu@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:43:58 -0400 Subject: [PATCH] fix CR3 detection --- src/JPEGView/Helpers.cpp | 2 +- src/JPEGView/ImageLoadThread.cpp | 41 ++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/JPEGView/Helpers.cpp b/src/JPEGView/Helpers.cpp index 0aa8cc42..7d59a420 100644 --- a/src/JPEGView/Helpers.cpp +++ b/src/JPEGView/Helpers.cpp @@ -767,7 +767,7 @@ EImageFormat GetImageFormat(LPCTSTR sFileName) { return IF_JXL; } else if (_tcsicmp(sEnding, _T("AVIF")) == 0) { return IF_AVIF; - } else if (_tcsicmp(sEnding, _T("HEIF")) == 0 || _tcsicmp(sEnding, _T("HEIC")) == 0) { + } else if (_tcsicmp(sEnding, _T("HEIF")) == 0 || _tcsicmp(sEnding, _T("HEIC")) == 0 || _tcsicmp(sEnding, _T("HIF")) == 0) { return IF_HEIF; } else if (_tcsicmp(sEnding, _T("TGA")) == 0) { return IF_TGA; diff --git a/src/JPEGView/ImageLoadThread.cpp b/src/JPEGView/ImageLoadThread.cpp index 144cefae..6a7aec58 100644 --- a/src/JPEGView/ImageLoadThread.cpp +++ b/src/JPEGView/ImageLoadThread.cpp @@ -62,28 +62,19 @@ static EImageFormat GetImageFormat(LPCTSTR sFileName) { } else if ((header[0] == 0xff && header[1] == 0x0a) || memcmp(header, "\x00\x00\x00\x0cJXL\x20\x0d\x0a\x87\x0a", 12) == 0) { return IF_JXL; - - // Unfortunately, TIFF detection by header bytes is not reliable - // A few RAW image formats use TIFF as the container - // ex: CR2 - http://lclevy.free.fr/cr2/#key_info - // ex: DNG - https://www.adobe.com/creativecloud/file-types/image/raw/dng-file.html#dng - // - // JPEGView will fail to open these files if the following code is used - // - //} else if ((header[0] == 0x49 && header[1] == 0x49 && header[2] == 0x2a && header[3] == 0x00) || - // (header[0] == 0x4d && header[1] == 0x4d && header[2] == 0x00 && header[3] == 0x2a)) { - // return IF_TIFF; - - } else if (header[0] == 0x00 && header[1] == 0x00 && header[2] == 0x00 && memcmp(header+4, "ftyp", 4) == 0) { + } else if (!memcmp(header+4, "ftyp", 4)) { // https://github.com/strukturag/libheif/issues/83 // https://github.com/strukturag/libheif/blob/ce1e4586b6222588c5afcd60c7ba9caa86bcc58c/libheif/heif.h#L602-L805 + // AV1: avif, avis + if (!memcmp(header+8, "avi", 3)) + return IF_AVIF; // H265: heic, heix, hevc, hevx, heim, heis, hevm, hevs - if (header[8] == 'h' && header[9] == 'e') + if (!memcmp(header+8, "hei", 3) || !memcmp(header+8, "hev", 3)) return IF_HEIF; - // AV1: avif, avis - // Unspecified encoding: mif1, mif2, msf1, miaf, 1pic - return IF_AVIF; // try libavif, fallback to libheif + // Canon CR3 + if (!memcmp(header+8, "crx ", 4)) + return IF_CameraRAW; } else if (header[0] == 'q' && header[1] == 'o' && header[2] == 'i' && header[3] == 'f') { return IF_QOI; } else if (header[0] == '8' && header[1] == 'B' && header[2] == 'P' && header[3] == 'S') { @@ -91,7 +82,21 @@ static EImageFormat GetImageFormat(LPCTSTR sFileName) { } // default fallback if no matches based on magic bytes - return Helpers::GetImageFormat(sFileName); + EImageFormat eImageFormat = Helpers::GetImageFormat(sFileName); + + if (eImageFormat != IF_Unknown) { + return eImageFormat; + } else if (!memcmp(header+4, "ftyp", 4)) { + // Unspecified encoding (possibly AVIF or HEIF): mif1, mif2, msf1, miaf, 1pic + return IF_AVIF; + } else if (!memcmp(header, "II*\0", 4) || !memcmp(header, "MM\0*", 4)) { + // Must be checked after file extension to avoid classifying RAW as TIFF + // A few RAW image formats use TIFF as the container + // ex: CR2 - http://lclevy.free.fr/cr2/#key_info + // ex: DNG - https://www.adobe.com/creativecloud/file-types/image/raw/dng-file.html#dng + return IF_TIFF; + } + return IF_Unknown; } static EImageFormat GetBitmapFormat(Gdiplus::Bitmap * pBitmap) {