Skip to content

gamut-png: parallel filter trials, and a composed effort dial #484

Description

@justin13888

Two speed items from the #224 audit that need a workspace-level decision rather than a local
change.

1. Parallelism across filter trials

PngEncoder::compress_scanlines (src/encoder.rs:427-437) runs BruteForce's six candidates
sequentially — six full filter passes and six full DEFLATE streams, one after another. They are
embarrassingly parallel, and there is no threading anywhere in gamut-png or gamut-deflate.

oxipng parallelises exactly here (filters.par_iter().with_max_len(1)), not across deflate
attempts, and ships src/rayon.rs — a serial shim implementing join/spawn/par_iter with
identical signatures for when the feature is off. That is the cleanest pattern to copy.

The decision this needs: gamut-deflate advertises zero runtime dependencies, and rayon on
wasm32 builds but only degrades to serial for the implicit global pool (build_global() errors).
So it would have to be feature-gated off by default. Worth noting the closest precedent,
image-rs's png 0.18.1, has no rayon at all.

Determinism must survive: the reduction stays min_by_key over an ordered collection, and the
size contract's encoded_size_is_deterministic already guards it.

2. No composed effort dial

with_compression(Level), with_effort(u8) and with_filter(FilterStrategy) are three
independent knobs, plus with_auto_reduce and now with_transparent_cleanup. Nothing maps one
integer onto a sensible ladder, so a caller wanting "smallest" has to know that it means
Level::Best + BruteForce + auto-reduce. gamut-cli exposes only --png-effort and hardcodes
the rest. gamut-deflate's with_optimal_parse_limit is not re-exported on PngEncoder at all,
so PNG callers are stuck at 1 MiB spans.

Refs #224

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions