fix(images): pick the decoder from the bytes, not the extension

`image::open` chooses the decoder by extension, so a PNG saved as .jpg
(Android screenshots, chat exports) failed thumbnails, previews,
perceptual hashes, insights and face crops with "Illegal start bytes:
8950". New `file_types::open_image` sniffs the header and falls back to
the extension when it's unknown; every decode site uses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Opus 5.5 authored and cameron committed 2026-10-17 04:24:02 +00:00
1 parent bc27aea81a
commit b95adb4f77
5 files changed
+29 -6

No files matched your search

+1 -1
View File
@@ -30,7 +30,7 @@ pub struct PerceptualIdentity {
/// callers should treat that as "no perceptual signal available" and
/// proceed with exact-match dedup only.
pub fn compute(path: &Path) -> Option<PerceptualIdentity> {
let img = image::open(path).ok()?;
let img = crate::file_types::open_image(path).ok()?;
// 8x8 = 64 bits, the standard size for pHash/dHash. Larger sizes
// give more discriminative power but no longer fit in i64 and the