From d8cc88a7720755e0054038ebc0e152b2e0dcfa00 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Fri, 13 Nov 2026 00:39:31 -0500 Subject: [PATCH] Add image document formats to shared registry --- crates/file-formats/src/lib.rs | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/file-formats/src/lib.rs b/crates/file-formats/src/lib.rs index 29bf92a3f..9d3a3c438 100644 --- a/crates/file-formats/src/lib.rs +++ b/crates/file-formats/src/lib.rs @@ -21,6 +21,14 @@ pub enum Format { Tiff, WebP, Heif, + Psd, + Affinity, + Ora, + Kra, + Xcf, + Pdn, + Raw, + Pcraft, Gcode, Studio, StencilCraft, @@ -37,6 +45,18 @@ pub fn detect(name: &str, bytes: &[u8]) -> Option { (craft_eps::Kind::PostScript, _) => Format::PostScript, }); } + if bytes.starts_with(b"8BPS") { + return Some(Format::Psd); + } + if bytes.starts_with(b"PDN3") { + return Some(Format::Pdn); + } + if bytes.starts_with(b"gimp xcf ") || gzipped_xcf(name, bytes) { + return Some(Format::Xcf); + } + if bytes.starts_with(b"\0\xffKA") { + return Some(Format::Affinity); + } if let Some(raster) = raster_signature(bytes) { return Some(raster); } @@ -75,6 +95,16 @@ pub fn from_extension(ext: &str) -> Option { "tif" | "tiff" => Some(Format::Tiff), "webp" => Some(Format::WebP), "heic" | "heif" => Some(Format::Heif), + "psd" | "psb" => Some(Format::Psd), + "afdesign" | "afphoto" | "afpub" => Some(Format::Affinity), + "ora" => Some(Format::Ora), + "kra" => Some(Format::Kra), + "xcf" => Some(Format::Xcf), + "pdn" => Some(Format::Pdn), + "dng" | "3fr" | "ari" | "arw" | "bay" | "cap" | "cr2" | "cr3" | "dcs" | "dcr" | "drf" | "eip" | "erf" | "fff" | "gpr" | "iiq" | "k25" + | "kdc" | "mdc" | "mef" | "mos" | "mrw" | "nef" | "nrw" | "obm" | "orf" | "pef" | "ptx" | "pxn" | "r3d" | "raf" | "raw" | "rwl" | "rw2" + | "rwz" | "sr2" | "srf" | "sti" | "x3f" => Some(Format::Raw), + "pcraft" => Some(Format::Pcraft), "studio" | "studio3" => Some(Format::Studio), "stencilcraft" => Some(Format::StencilCraft), "gcode" | "nc" => Some(Format::Gcode), @@ -86,6 +116,11 @@ fn extension(name: &str) -> Option<&str> { Some(name.rsplit(['/', '\\']).next()?.rsplit_once('.')?.1) } +fn gzipped_xcf(name: &str, bytes: &[u8]) -> bool { + let lower = name.rsplit(['/', '\\']).next().unwrap_or(name).to_ascii_lowercase(); + bytes.starts_with(&[0x1f, 0x8b]) && (lower.ends_with(".xcf.gz") || lower.ends_with(".xcfgz")) +} + fn dxf_ascii_prefix(bytes: &[u8]) -> bool { let text = String::from_utf8_lossy(bytes); let mut lines = text.lines().map(str::trim);