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>
Psd::parse drops the layers, records Psd::warnings and keeps the header and
merged image; the importer then imports the flattened image as one layer and
reports 'Layers could not be read'. Header damage and a missing merged image
stay hard errors.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
One decode_plane for raw/RLE/ZIP (decode_channel and composite), placed::eight and
quad_from for the SoLd/PlLd transforms, the writer's big-endian and UTF-16 helpers
from descriptor.rs, one delimiter const in engine_data.rs, and the dead binding in
write.rs. No behaviour change; adds ZIP and RLE composite tests.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Psd::tree flattens groups nested deeper than MAX_GROUP_DEPTH into their depth-64 parent, keeping every layer, so the importer recursion and the tree's Drop/Clone/PartialEq are bounded. The import result reports how many groups were flattened.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Layer bounds come straight from the file as four i32s. Rect::width/height subtracted them in
i32 (overflow: a panic in debug builds, garbage sizes in release), and layer_pixels allocated
width x height pixels before reading any data, so a 100-byte file claiming a 2^31-square layer
hit "capacity overflow" (or an out-of-memory abort). Widths are now computed in i64 and
clamped, every decoded image is capped at 2^28 pixels (Error::Unsupported beyond that), zlib
data is inflated with a limit of the expected size, RLE count tables and UTF-16 strings
reserve no more than the remaining bytes, and the per-pixel copy only visits the part of the
layer that lands in the output. Denies the panic lints in the crate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>