Files
photocraft/crates/codecs/tests
dde01384d2 perf(io): stream large PNGs row by row into the layer's tiles (#10259) (#10305)
* perf(io): build JPEG/PNG tiles straight from the decoded rows, in parallel (#10259)

Surface::try_write_rows_with fills tiles row by row on all cores; image_surface
converts from the borrowed decoded rows into it (no per-band copy, no staging
Image). Opaque sources skip the prune scan. import_flat_with checks cancel after
the decode and the tile build and reports progress.

* fix(io): store an F16 target as F32 so its opaque alpha is 1.0

An image without alpha converted to an F16 target got the alpha 0.0: the
opaque-alpha path copied two bytes of 1.0f32. The surface keeps 16-bit float
as 32-bit float anyway, so image_surface now converts an F16 target to F32.

* Format fused tile import integration

* perf(io): decode PNG rows straight into the layer's tiles (#10259)

* test(codecs): PngSuite rows test skips files without a PNG signature (#10259)

* perf(io): stream PNG rows only for images of 32 MiB or more (#10259)

* Update crates/codecs/src/codecs/png.rs

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>

* fix(io): name the image, not the failed reservation, in PNG/JPEG allocation errors (#10259)

A failed surface reservation is one tile or row band, so reporting its bytes as
"a N MB image" was misleading (usually "0 MB"). Report the image's pixel size.

* refactor(codecs): the caller picks the PNG row-group height (#10259)

decode_png_rows takes the rows per group instead of a fixed 256, and io
passes TILE_SIZE, so the groups can't drift from the tile rows they fill.
A group of 0 counts as 1.

* Complete PNG streaming integration with upstream TIFF imports

* Preserve F16 conversion and route default imports through interrupt wrapper

* fix(io): check free memory before PNG tiles, and cancel TIFF imports after the decode (#10259)

import_png_streamed refuses an image whose tiles and one row group the machine
can't hold before the first tile exists, as tiff_to_document does; the
whole-image path (the base PNG path among it) checks the layer's tiles before
allocating them, for images above the streaming size, so a small image still
opens where the reserve alone would have refused it.

import_flat_with now honours the interrupt after a successful TIFF import, as
the whole-image path does; a decode error is still reported as itself.

* fix(io): pass lazy memory probe to PNG importer

* fix(io): handle scratch read errors during flat import

* test(io): respect early TIFF import cancellation

* fix(io): thread ImportOptions decode limits into PNG row streaming

After merging main, the whole-image open path respects
ImportOptions::flat_max_pixel_bytes via decode_limits, but the
streamed PNG path still used DecodeOptions::default(). Pass opts
through so both paths share the same decoder limits.

* fix(io): silence clippy needless_update on DecodeOptions; rustfmt

DecodeOptions only has limits + keep_orientation, so specifying both
and ..Default::default() trips -D clippy::needless_update. Also apply
rustfmt to the decode_png_rows call that gate's fmt check rejected.

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: FredApps <fred@apps.local>
2026-11-05 15:10:21 +01:00
..