PSD: take the integration branch's adapted non-finite test and psd_import formatting (#1149)

The six PSD PRs merged one by one leave #1131's test calling samples()/to_rgb(), which #1139
replaced; vangel76's integration draft #1149 has the adapted version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-13 04:47:27 -04:00
1 parent 02c412b835
commit eb2b734059
2 files changed
+61 -63

No files matched your search

+3 -6
View File
@@ -111,16 +111,13 @@ struct Ctx<'a> {
pub fn import(proj: &mut Project, psd: &Psd, path: &str, name: &str, retain: bool, rate: FrameRate, duration: Tick) -> PsdImport {
let folder = proj.add_item(&format!("{name} Layers"), Label::Yellow, None, ItemKind::Folder);
let mut cx = Ctx { psd, path, retain, folder, rate, duration, items: vec![], warnings: vec![] };
cx.warnings.extend(psd.warnings.iter().cloned());
let (tree, flattened) = psd.tree_report();
if flattened > 0 {
cx.warnings.push(format!("{flattened} group(s) nested deeper than {} levels were flattened into their parent", effectcraft_psd::MAX_GROUP_DEPTH));
}
cx.warnings.extend(psd.warnings.iter().cloned());
let comp = if psd.layers.is_empty() && !psd.warnings.is_empty() {
flattened_comp(proj, &mut cx, name)
} else {
build_comp(proj, &mut cx, name, &tree, None)
};
let comp =
if psd.layers.is_empty() && !psd.warnings.is_empty() { flattened_comp(proj, &mut cx, name) } else { build_comp(proj, &mut cx, name, &tree, None) };
PsdImport { comp, folder, items: cx.items, warnings: cx.warnings }
}
+58 -57
View File
@@ -340,9 +340,10 @@ fn non_finite_32_bit_samples_become_finite() {
d.layers = vec![WLayer::solid("L", Rect::new(0, 0, 4, 4), [0.5, 0.5, 0.5, 1.0])];
let p = Psd::parse(write(&d)).unwrap();
let raw: Vec<u8> = [f32::NAN, f32::INFINITY, f32::NEG_INFINITY, 0.25].iter().flat_map(|v| v.to_be_bytes()).collect();
let s = p.samples(&raw, 4, 1);
let mut s = vec![f32::NAN; 4];
p.for_each_sample(&raw, 4, 1, |i, v| s[i] = v);
assert_eq!(s, vec![0.0, 1.0, 0.0, 0.25]);
assert!(p.to_rgb(&[Some(s.clone()), Some(s.clone()), Some(s)], 1).iter().all(|v| v.is_finite()));
assert!(p.rgb_from([s[1], s[1], s[1], 0.0]).iter().all(|v| v.is_finite()));
}
#[test]
@@ -352,6 +353,61 @@ fn rect_new_near_i32_max_saturates() {
assert!(r.is_empty());
}
fn find(bytes: &[u8], needle: &[u8]) -> usize {
bytes.windows(needle.len()).position(|w| w == needle).expect("needle present")
}
/// The second layer record's signature overwritten.
fn bad_signature() -> Vec<u8> {
let mut bytes = write(&doc_with_layers(8, ColorMode::Rgb, true));
let at = find(&bytes, b"8BIMmul ");
bytes[at] = b'X';
bytes
}
/// The first channel of the first layer claims more data than the file holds.
fn bad_channel_length() -> Vec<u8> {
let mut bytes = write(&doc_with_layers(8, ColorMode::Rgb, true));
let at = find(&bytes, b"8BIMnorm");
let first_len = at - 4 * 6 + 2;
bytes[first_len..first_len + 4].copy_from_slice(&0x7fff_fff0u32.to_be_bytes());
bytes
}
#[test]
fn damaged_layer_section_keeps_the_merged_image() {
let good = Psd::parse(write(&doc_with_layers(8, ColorMode::Rgb, true))).unwrap();
assert!(good.warnings.is_empty() && good.layers.len() == 3);
let want = good.composite().unwrap();
for bytes in [bad_signature(), bad_channel_length()] {
let p = Psd::parse(bytes).unwrap();
assert!(p.layers.is_empty());
assert_eq!(p.warnings.len(), 1, "{:?}", p.warnings);
assert!(p.warnings[0].contains("Layers could not be read"));
assert_eq!((p.width, p.height), (40, 30));
let got = p.composite().unwrap();
assert_eq!(got.data, want.data);
}
}
#[test]
fn header_damage_and_missing_merged_image_still_fail() {
let good = write(&doc_with_layers(8, ColorMode::Rgb, true));
// Zero width.
let mut b = good.clone();
b[18..22].copy_from_slice(&0u32.to_be_bytes());
assert!(Psd::parse(b).is_err());
// Unknown colour mode.
let mut b = good.clone();
b[24..26].copy_from_slice(&99u16.to_be_bytes());
assert!(Psd::parse(b).is_err());
// Damaged layers and no merged image at all: nothing to fall back to.
let end = Psd::parse(good).unwrap().merged_offset;
let mut b = bad_signature();
b.truncate(end);
assert!(Psd::parse(b).is_err());
}
/// A ZIP plane body for the decoder: the plane delta-coded per row when `predict`.
fn zip_body(raw: &[u8], w: usize, depth: u16, predict: bool) -> Vec<u8> {
if !predict {
@@ -434,58 +490,3 @@ fn rle_composite_matches_the_raw_one() {
assert_eq!(rle.layer_pixels(2, true).unwrap().data, raw.layer_pixels(2, true).unwrap().data, "{depth} bit");
}
}
fn find(bytes: &[u8], needle: &[u8]) -> usize {
bytes.windows(needle.len()).position(|w| w == needle).expect("needle present")
}
/// The second layer record's signature overwritten.
fn bad_signature() -> Vec<u8> {
let mut bytes = write(&doc_with_layers(8, ColorMode::Rgb, true));
let at = find(&bytes, b"8BIMmul ");
bytes[at] = b'X';
bytes
}
/// The first channel of the first layer claims more data than the file holds.
fn bad_channel_length() -> Vec<u8> {
let mut bytes = write(&doc_with_layers(8, ColorMode::Rgb, true));
let at = find(&bytes, b"8BIMnorm");
let first_len = at - 4 * 6 + 2;
bytes[first_len..first_len + 4].copy_from_slice(&0x7fff_fff0u32.to_be_bytes());
bytes
}
#[test]
fn damaged_layer_section_keeps_the_merged_image() {
let good = Psd::parse(write(&doc_with_layers(8, ColorMode::Rgb, true))).unwrap();
assert!(good.warnings.is_empty() && good.layers.len() == 3);
let want = good.composite().unwrap();
for bytes in [bad_signature(), bad_channel_length()] {
let p = Psd::parse(bytes).unwrap();
assert!(p.layers.is_empty());
assert_eq!(p.warnings.len(), 1, "{:?}", p.warnings);
assert!(p.warnings[0].contains("Layers could not be read"));
assert_eq!((p.width, p.height), (40, 30));
let got = p.composite().unwrap();
assert_eq!(got.data, want.data);
}
}
#[test]
fn header_damage_and_missing_merged_image_still_fail() {
let good = write(&doc_with_layers(8, ColorMode::Rgb, true));
// Zero width.
let mut b = good.clone();
b[18..22].copy_from_slice(&0u32.to_be_bytes());
assert!(Psd::parse(b).is_err());
// Unknown colour mode.
let mut b = good.clone();
b[24..26].copy_from_slice(&99u16.to_be_bytes());
assert!(Psd::parse(b).is_err());
// Damaged layers and no merged image at all: nothing to fall back to.
let end = Psd::parse(good).unwrap().merged_offset;
let mut b = bad_signature();
b.truncate(end);
assert!(Psd::parse(b).is_err());
}