Skip to content

gamut-png: order the palette, and clean caller-supplied ones #482

Description

@justin13888

gamut-png's palette handling does the minimum: build_indexed (src/reduce.rs:250-277) trims
trailing opaque tRNS entries, and that is all.

Missing

Ordering. palette.push(key) (src/reduce.rs:104) assigns indices in raster-scan
first-appearance order. There is no sort in the file at all. Index order directly changes the byte
stream DEFLATE sees, and adjacency changes how well the row filters predict — oxipng uses
modified-Zeng ordering (plus Battiato) and reports it as its best size-per-line-of-code
reduction pass. Sorting transparent entries first would also make the existing trailing-opaque
trim actually pay.

The caller-supplied path. encode_indexed8 (src/encoder.rs:284) only range-checks indices
and writes palette.plte() verbatim. No dedupe, no unused-entry removal, no depth re-derivation.
A caller handing in a 256-entry palette that uses three colours gets 768 wasted PLTE bytes and
depth 8 where depth 2 would do. (The auto-reduce path is fine here by construction — its palette
is built from the pixels, so it can contain neither duplicates nor unused entries.)

Trailing-opaque trim on the caller path. PngPalette::trns() (src/palette.rs:113-119)
returns the whole alpha vector; only the auto-reduce path trims.

Note

Palette overhead is incompressible, so this interacts with the cost model: #224 added
write_reduced_or_native, which races the palette encoding against the unreduced one and keeps
the smaller. A smaller PLTE shifts that crossover, so this work makes the palette win on more
images, not just win by more.

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

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions