Skip to content

Commit

Permalink
Bugfix: CR3 detection
Browse files Browse the repository at this point in the history
CR3 uses HEIF container, and is now properly detected as RAW and not HEIF

Merge PR #310 by https://github.com/qbnu
  • Loading branch information
sylikc committed Jun 19, 2024
2 parents a189456 + a587ecf commit dc058fa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/JPEGView/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 23 additions & 18 deletions src/JPEGView/ImageLoadThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,36 +62,41 @@ 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') {
return IF_PSD;
}

// 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) {
Expand Down

0 comments on commit dc058fa

Please sign in to comment.