@@ -30,7 +30,6 @@ using namespace QuickView;
3030#include < immintrin.h> // SIMD
3131#include " SIMDUtils.h"
3232#include < thread>
33- #include " PreviewExtractor.h"
3433#include < shobjidl.h> // [Add] for IShellItemImageFactory
3534#include " MappedFile.h" // [Opt]
3635#if defined(__has_include)
@@ -173,102 +172,95 @@ namespace QuickView {
173172static std::wstring DetectFormatFromContent (const uint8_t * magic, size_t size) {
174173 if (size < 4 ) return L" Unknown" ;
175174
176- // Check JPEG: FF D8 FF
177- if (size >= 3 && magic[0 ] == 0xFF && magic[1 ] == 0xD8 && magic[2 ] == 0xFF ) return L" JPEG" ;
178-
179- // Check PNG: 89 50 4E 47
180- if (size >= 4 && magic[0 ] == 0x89 && magic[1 ] == 0x50 && magic[2 ] == 0x4E && magic[3 ] == 0x47 ) return L" PNG" ;
181-
182- // Check WebP: RIFF ... WEBP
183- if (size >= 12 && magic[0 ] == ' R' && magic[1 ] == ' I' && magic[2 ] == ' F' && magic[3 ] == ' F' &&
184- magic[8 ] == ' W' && magic[9 ] == ' E' && magic[10 ] == ' B' && magic[11 ] == ' P' ) return L" WebP" ;
185-
186- // Check AVIF: ftypavif OR ftypavis (AVIF Sequence)
187- if (size >= 12 && magic[4 ] == ' f' && magic[5 ] == ' t' && magic[6 ] == ' y' && magic[7 ] == ' p' ) {
188- bool isAvif = (magic[8 ] == ' a' && magic[9 ] == ' v' && magic[10 ] == ' i' && magic[11 ] == ' f' );
189- bool isAvis = (magic[8 ] == ' a' && magic[9 ] == ' v' && magic[10 ] == ' i' && magic[11 ] == ' s' );
190- if (isAvif || isAvis) return L" AVIF" ;
191- }
175+ struct MagicSignature {
176+ const wchar_t * name;
177+ size_t offset;
178+ const uint8_t * signature;
179+ size_t sig_len;
180+ };
192181
193- // Check HEIC/HEIF/CR3: ftyp + brand
194- if (size >= 12 && magic[4 ] == ' f' && magic[5 ] == ' t' && magic[6 ] == ' y' && magic[7 ] == ' p' ) {
195- // Canon CR3 (Raw)
196- if (magic[8 ] == ' c' && magic[9 ] == ' r' && magic[10 ] == ' x' ) return L" RAW" ; // crx
182+ static const uint8_t sig_jpeg[] = {0xFF , 0xD8 , 0xFF };
183+ static const uint8_t sig_png[] = {0x89 , 0x50 , 0x4E , 0x47 };
184+ static const uint8_t sig_webp[] = {' W' , ' E' , ' B' , ' P' };
185+ static const uint8_t sig_jxl1[] = {0xFF , 0x0A };
186+ static const uint8_t sig_jxl2[] = {' J' , ' X' , ' L' , ' ' };
187+ static const uint8_t sig_dds[] = {' D' , ' D' , ' S' , ' ' };
188+ static const uint8_t sig_bmp[] = {' B' , ' M' };
189+ static const uint8_t sig_psd[] = {' 8' , ' B' , ' P' , ' S' };
190+ static const uint8_t sig_hdr[] = {' #' , ' ?' };
191+ static const uint8_t sig_exr[] = {0x76 , 0x2F , 0x31 , 0x01 };
192+ static const uint8_t sig_pic[] = {0x53 , 0x80 , 0xF6 , 0x34 };
193+ static const uint8_t sig_qoi[] = {' q' , ' o' , ' i' , ' f' };
194+ static const uint8_t sig_pcx[] = {0x0A };
195+ static const uint8_t sig_ico[] = {0x00 , 0x00 , 0x01 , 0x00 };
196+ static const uint8_t sig_tif1[] = {0x49 , 0x49 , 0x2A , 0x00 };
197+ static const uint8_t sig_tif2[] = {0x4D , 0x4D , 0x00 , 0x2A };
198+
199+ static const MagicSignature signatures[] = {
200+ { L" JPEG" , 0 , sig_jpeg, sizeof (sig_jpeg) },
201+ { L" PNG" , 0 , sig_png, sizeof (sig_png) },
202+ { L" WebP" , 8 , sig_webp, sizeof (sig_webp) },
203+ { L" JXL" , 0 , sig_jxl1, sizeof (sig_jxl1) },
204+ { L" JXL" , 4 , sig_jxl2, sizeof (sig_jxl2) },
205+ { L" DDS" , 0 , sig_dds, sizeof (sig_dds) },
206+ { L" BMP" , 0 , sig_bmp, sizeof (sig_bmp) },
207+ { L" PSD" , 0 , sig_psd, sizeof (sig_psd) },
208+ { L" HDR" , 0 , sig_hdr, sizeof (sig_hdr) },
209+ { L" EXR" , 0 , sig_exr, sizeof (sig_exr) },
210+ { L" PIC" , 0 , sig_pic, sizeof (sig_pic) },
211+ { L" QOI" , 0 , sig_qoi, sizeof (sig_qoi) },
212+ { L" PCX" , 0 , sig_pcx, sizeof (sig_pcx) },
213+ { L" ICO" , 0 , sig_ico, sizeof (sig_ico) },
214+ { L" TIFF" , 0 , sig_tif1, sizeof (sig_tif1) },
215+ { L" TIFF" , 0 , sig_tif2, sizeof (sig_tif2) }
216+ };
197217
198- // Check brand at offset 8
199- if ((magic[8 ] == ' h' && magic[9 ] == ' e' && magic[10 ] == ' i' && (magic[11 ] == ' c' || magic[11 ] == ' x' || magic[11 ] == ' s' || magic[11 ] == ' m' )) || // heic, heix, heis, heim
200- (magic[8 ] == ' h' && magic[9 ] == ' e' && magic[10 ] == ' v' && (magic[11 ] == ' c' || magic[11 ] == ' m' || magic[11 ] == ' s' )) || // hevc, hevm, hevs
201- (magic[8 ] == ' m' && magic[9 ] == ' i' && magic[10 ] == ' f' && magic[11 ] == ' 1' ) || // mif1
202- (magic[8 ] == ' m' && magic[9 ] == ' s' && magic[10 ] == ' f' && magic[11 ] == ' 1' )) // msf1
203- {
204- return L" HEIC" ; // Unified as HEIC/HEIF
218+ for (const auto & sig : signatures) {
219+ if (size >= sig.offset + sig.sig_len ) {
220+ bool match = true ;
221+ size_t i = 0 ;
222+ for (size_t k = 0 ; k < sig.sig_len ; ++k) {
223+ uint8_t byte = sig.signature [k];
224+ if (magic[sig.offset + i] != byte) {
225+ match = false ;
226+ break ;
227+ }
228+ i++;
229+ }
230+ // Additional context rules for WebP / JXL box
231+ if (match) {
232+ if (wcscmp (sig.name , L" WebP" ) == 0 && !(magic[0 ] == ' R' && magic[1 ] == ' I' && magic[2 ] == ' F' && magic[3 ] == ' F' )) match = false ;
233+ if (sig.offset == 4 && wcscmp (sig.name , L" JXL" ) == 0 && !(magic[0 ] == 0x00 && magic[1 ] == 0x00 && magic[2 ] == 0x00 && magic[3 ] == 0x0C )) match = false ;
234+ }
235+ if (match) return sig.name ;
205236 }
206237 }
207-
208- // Check JXL: FF 0A or 00 00 00 0C JXL
209- if (size >= 2 && magic[0 ] == 0xFF && magic[1 ] == 0x0A ) return L" JXL" ;
210- if (size >= 8 && magic[0 ] == 0x00 && magic[1 ] == 0x00 && magic[2 ] == 0x00 && magic[3 ] == 0x0C &&
211- magic[4 ] == ' J' && magic[5 ] == ' X' && magic[6 ] == ' L' && magic[7 ] == ' ' ) return L" JXL" ;
212-
213- // Check DDS: DDS\x20 (Magic Number: 0x20534444)
214- if (size >= 4 && magic[0 ] == ' D' && magic[1 ] == ' D' && magic[2 ] == ' S' && magic[3 ] == ' ' ) return L" DDS" ;
215-
216- // Check GIF: GIF87a or GIF89a
217- if (size >= 6 && magic[0 ] == ' G' && magic[1 ] == ' I' && magic[2 ] == ' F' && magic[3 ] == ' 8' &&
218- (magic[4 ] == ' 7' || magic[4 ] == ' 9' ) && magic[5 ] == ' a' ) return L" GIF" ;
219-
220- // Check BMP: BM
221- if (size >= 2 && magic[0 ] == ' B' && magic[1 ] == ' M' ) return L" BMP" ;
222238
223- // Check PSD: 8BPS
224- if (size >= 4 && magic[0 ] == ' 8' && magic[1 ] == ' B' && magic[2 ] == ' P' && magic[3 ] == ' S' ) return L" PSD" ;
225-
226- // Check HDR: #?RADIANCE or #?RGBE
227- if (size >= 2 && magic[0 ] == ' #' && magic[1 ] == ' ?' ) return L" HDR" ;
239+ // Complex / Heuristic checks
240+ if (size >= 12 && magic[4 ] == ' f' && magic[5 ] == ' t' && magic[6 ] == ' y' && magic[7 ] == ' p' ) {
241+ if (magic[8 ] == ' a' && magic[9 ] == ' v' && magic[10 ] == ' i' && (magic[11 ] == ' f' || magic[11 ] == ' s' )) return L" AVIF" ;
242+ if (magic[8 ] == ' c' && magic[9 ] == ' r' && magic[10 ] == ' x' ) return L" RAW" ;
243+ if ((magic[8 ] == ' h' && magic[9 ] == ' e' && magic[10 ] == ' i' && (magic[11 ] == ' c' || magic[11 ] == ' x' || magic[11 ] == ' s' || magic[11 ] == ' m' )) ||
244+ (magic[8 ] == ' h' && magic[9 ] == ' e' && magic[10 ] == ' v' && (magic[11 ] == ' c' || magic[11 ] == ' m' || magic[11 ] == ' s' )) ||
245+ (magic[8 ] == ' m' && magic[9 ] == ' i' && magic[10 ] == ' f' && magic[11 ] == ' 1' ) ||
246+ (magic[8 ] == ' m' && magic[9 ] == ' s' && magic[10 ] == ' f' && magic[11 ] == ' 1' )) return L" HEIC" ;
247+ }
228248
229- // Check EXR: v/1\x01 (0x76 0x2f 0x31 0x01)
230- if (size >= 4 && magic[0 ] == 0x76 && magic[1 ] == 0x2F && magic[2 ] == 0x31 && magic[3 ] == 0x01 ) return L" EXR" ;
231-
232- // Check PIC: 0x53 0x80 ...
233- if (size >= 4 && magic[0 ] == 0x53 && magic[1 ] == 0x80 && magic[2 ] == 0xF6 && magic[3 ] == 0x34 ) return L" PIC" ;
234-
235- // Check PNM: P1-P7
249+ if (size >= 6 && magic[0 ] == ' G' && magic[1 ] == ' I' && magic[2 ] == ' F' && magic[3 ] == ' 8' && (magic[4 ] == ' 7' || magic[4 ] == ' 9' ) && magic[5 ] == ' a' ) return L" GIF" ;
236250 if (size >= 2 && magic[0 ] == ' P' && magic[1 ] >= ' 1' && magic[1 ] <= ' 7' ) return L" PNM" ;
237-
238- // Check QOI: qoif
239- if (size >= 4 && magic[0 ] == ' q' && magic[1 ] == ' o' && magic[2 ] == ' i' && magic[3 ] == ' f' ) return L" QOI" ;
240-
241- // Check PCX: 0x0A ...
242- if (size >= 1 && magic[0 ] == 0x0A ) return L" PCX" ;
243-
244- // Check ICO: 00 00 01 00
245- if (size >= 4 && magic[0 ] == 0x00 && magic[1 ] == 0x00 && magic[2 ] == 0x01 && magic[3 ] == 0x00 ) return L" ICO" ;
246251
247- // Check TIFF: II (49 49 2A 00) or MM (4D 4D 00 2A)
248- if (size >= 4 && magic[0 ] == 0x49 && magic[1 ] == 0x49 && magic[2 ] == 0x2A && magic[3 ] == 0x00 ) return L" TIFF" ;
249- if (size >= 4 && magic[0 ] == 0x4D && magic[1 ] == 0x4D && magic[2 ] == 0x00 && magic[3 ] == 0x2A ) return L" TIFF" ;
250-
251- // [v6.9.7] PRIORITIZE TGA Check over WBMP (since TGA often starts with 00 00)
252- // Check TGA (Heuristic): ColorMapType(0/1) + ImageType(1/2/3/9/10/11) + PixelDepth(8/15/16/24/32) at offset 16
253252 if (size >= 18 ) {
254253 bool validColorMap = (magic[1 ] == 0 || magic[1 ] == 1 );
255254 bool validType = (magic[2 ] == 1 || magic[2 ] == 2 || magic[2 ] == 3 || magic[2 ] == 9 || magic[2 ] == 10 || magic[2 ] == 11 );
256255 bool validBpp = (magic[16 ] == 8 || magic[16 ] == 15 || magic[16 ] == 16 || magic[16 ] == 24 || magic[16 ] == 32 );
257256 if (validColorMap && validType && validBpp) return L" TGA" ;
258257 }
259258
260- // [v6.9.6] Check WBMP: Type 0, Fixed Header 0
261- // [Fix] Must exclude ISOBMFF (ftyp) to avoid hijacking CR3/MP4 which start with size 00 00 ...
262259 if (size >= 2 && magic[0 ] == 0x00 && magic[1 ] == 0x00 ) {
263- // If it looks like ftyp, it's NOT WBMP
264- if (size >= 8 && magic[4 ] == ' f' && magic[5 ] == ' t' && magic[6 ] == ' y' && magic[7 ] == ' p' ) {
265- // Check known brands like crx? Already handled above.
266- // If we are here, it's an UNKNOWN ftyp. Return Unknown, not WBMP.
267- return L" Unknown" ;
268- }
260+ if (size >= 8 && magic[4 ] == ' f' && magic[5 ] == ' t' && magic[6 ] == ' y' && magic[7 ] == ' p' ) return L" Unknown" ;
269261 return L" WBMP" ;
270262 }
271-
263+
272264 return L" Unknown" ;
273265}
274266
@@ -581,16 +573,10 @@ HRESULT CImageLoader::LoadFromFile(LPCWSTR filePath, IWICBitmapSource** bitmap)
581573 return hr;
582574}
583575
584- #include < turbojpeg.h>
585576
586577// High-Performance Library Includes
587578
588579#include < webp/decode.h> // libwebp
589- #include < webp/demux.h>
590- #include < avif/avif.h> // libavif
591- #include < jxl/decode.h> // libjxl
592- #include < jxl/resizable_parallel_runner.h>
593- #include < jxl/thread_parallel_runner.h>
594580#include < libraw/libraw.h> // libraw
595581#include < wincodec.h>
596582
@@ -600,13 +586,11 @@ HRESULT CImageLoader::LoadFromFile(LPCWSTR filePath, IWICBitmapSource** bitmap)
600586#include < sstream>
601587#include < iomanip>
602588#include " exif.h"
603- #include < immintrin.h> // [AVX2]
604589 // [v6.0] EasyExif
605590#include " ImageEngine.h"
606591
607592// Wuffs (Google's memory-safe decoder)
608593// Implementation is in WuffsImpl.cpp with selective module loading
609- #include " WuffsLoader.h"
610594
611595// [v5.3] Global storage - kept for internal decoder use, exposed via DecodeResult.metadata
612596std::wstring g_lastFormatDetails;
@@ -7419,7 +7403,6 @@ void CImageLoader::ComputeHistogramFromFrame(const QuickView::RawImageFrame& fra
74197403// Phase 6: Surgical Format Optimizations
74207404// ============================================================================
74217405
7422- #include < webp/decode.h>
74237406
74247407
74257408
@@ -8727,7 +8710,6 @@ CImageLoader::ImageHeaderInfo CImageLoader::PeekHeader(LPCWSTR filePath) {
87278710// It decodes images directly to RawImageFrame, bypassing WIC where possible.
87288711// ============================================================================
87298712
8730- #include " MemoryArena.h"
87318713
87328714HRESULT CImageLoader::LoadToFrame (LPCWSTR filePath, QuickView::RawImageFrame* outFrame,
87338715 QuantumArena* arena,
0 commit comments