Commit Graph
7 Commits
Author SHA1 Message Date
Brandon Thomas a55af3b235 Merge pull request #1134 from vangel76/psd-simplify-dedupe
# Conflicts:
#	crates/psd/src/tests.rs
2026-10-13 04:28:39 -04:00
vangel76andClaude Sonnet 5.5 cf22417c1a PSD: share the duplicated decode, placed-transform and writer helpers (#1133)
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>
2026-10-12 22:58:31 +02:00
vangel76andClaude Sonnet 5.5 130bcb2385 PSD: drop non-finite values from descriptors, EngineData and 32-bit samples; no panic in Warp::apply or Rect::new (#1130)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 22:57:27 +02:00
Brandon ThomasandClaude Opus 5.5 d1413d5209 Never crash: bound PSD descriptor nesting
The descriptor depth limit restarted at 0 inside every nested descriptor (Objc / GlbO /
ObAr), so a crafted file of 100 000 nested descriptors (2.4 MB) recursed until the stack
overflowed and aborted the app. The depth now carries through nested descriptors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:05:55 -04:00
Brandon ThomasandClaude Opus 5.5 dc573f77e6 Never crash: PSD reader bounds overflow and input-sized allocations
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>
2026-10-04 12:27:18 -04:00
Brandon ThomasandClaude Opus 5.5 7b0a449c5f M13.6: PSD smart objects apply perspective quads and placed-layer warps
nonAffineTransform and the warp descriptor (named styles with bend / distortion, custom
envelope quilt meshes via ObAr meshPoints) are baked as placed over the placed bounds
(SourceLayer::placed), at up to 4x resolution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:21:00 -04:00
Brandon ThomasandClaude Opus 5.5 94e1c86d89 IO-2/SHP-5/PRV-2: PSD import, SVG import + vector/text conversions, persistent disk cache
- effectcraft-psd (L1): PSD/PSB reader from Adobe's published file format spec (layers, groups,
  masks, blend modes, text engine data, lfx2 effects, fill/adjustment layers, vector masks;
  1/8/16/32-bit, RGB/CMYK/Gray/Lab/Indexed, raw/RLE/ZIP) and a minimal writer for fixtures.
- File > Import: importAs footage|composition|compositionLayerSizes, layer (Choose Layer);
  groups -> precomps (pass-through collapses), text -> editable text, styles -> Layer Styles,
  adjustments -> adjustment layers with effects; UI asks the Import Kind for Photoshop files.
- effectcraft-svg (L2): SVG parser (shapes, paths, transforms, use, CSS, gradients) and
  rasteriser; .svg imports as footage, continuously rasterised when the switch is on.
- layer.create: shapesFromVector, shapesFromText, masksFromText, editableText (stub removed).
- Disk cache (render::disk_cache): LZ4 content-keyed frames and layer buffers, LRU size limit
  from prefs, atomic writes, restart persistence; edit.purge clears it, cache.diskStats query;
  viewer frames read/write it and the timeline shows disk-only frames in blue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:10:48 -04:00