mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-12 21:23:02 +00:00
- import_file_for_open_with decodes single-part flat scanline EXR block by block into tiles; headers the band decoder refuses fall back to the whole-file decoder, so files main opened still open. Band-time failures and cancellation publish no document. - The RAM tile budget and scratch-disk checks live in exr_native (the PSD stream module they came from is dropped); over-budget opens fail with IoError::OutOfMemory. - The band decoder picks colour channels with exr_color_channels, like the byte decoder. - Tests move into the per-crate it binaries and use import_file; an engine open-job test covers the OpenSource::Path route. The ui-egui sync open test is dropped: main's synchronous open reads bytes, and the io test covers the oversized header. - docs/streaming-io.md, roadmap, scratch-disks and REL-212-1 describe EXR only.
28 lines
1.8 KiB
Markdown
28 lines
1.8 KiB
Markdown
# EXR streaming
|
|
|
|
Native path opens (`photocraft_io::import_file_for_open_with`, used by the background open job
|
|
and by automation file opens) decode single-part flat scanline EXR files one compression block
|
|
at a time straight into guarded raster tiles. The document keeps the source dimensions and
|
|
samples; HALF samples are stored as F32, with a warning. Tiles count against the RAM tile
|
|
budget, and scratch residency can move cold tiles to disk; without a scratch disk an image whose
|
|
tiles cannot fit the budget fails with a clear out-of-memory error before any pixels are
|
|
decoded. Layered PSD/PSB files use the existing streaming PSD reader on the same route.
|
|
|
|
The block decoder (`photocraft_codecs::exr_stream`) treats the file as untrusted. Header metadata
|
|
is bounded (8 MiB, 4096 attributes); dimensions, channel count, chunk count, offsets, block
|
|
lengths and sample counts are checked against the file length and the header before anything is
|
|
allocated, and one decoded block is capped at 64 MiB. Duplicate, misaligned or truncated blocks
|
|
fail the open. It picks the same colour channels as the whole-file decoder.
|
|
|
|
Multi-part, deep, tiled, subsampled and custom-chromaticity files, and headers the block decoder
|
|
refuses, fall back to the whole-file decoder, under its own limits and working-memory admission.
|
|
Web and byte opens always use the whole-file decoder.
|
|
|
|
Cancellation is checked between reads and between scanlines, and progress reports completed
|
|
lines. A cancelled or failed open publishes no partial document. The open also fails if the
|
|
file's size or modification time changed while it was being read.
|
|
|
|
Tests compare the streamed document with the whole-file decoder across Gray/GrayA/RGB/RGBA, HALF
|
|
and FLOAT, and None/RLE/ZIP/ZIPS/PIZ compression, and cover cancellation, truncation, forged
|
|
offsets and lengths, hostile metadata and oversized headers.
|