shssoichiro / oxipng

Multithreaded PNG optimizer written in Rust
MIT License
2.86k stars 124 forks source link

Try both gray and indexed low depths #594

Closed andrews05 closed 6 months ago

andrews05 commented 7 months ago

Changes the depth reduction logic to also try low-depth indexed even if we already achieved low-depth grayscale, but only if we can do it even lower than the grayscale.

Fixes #515

ace-dent commented 7 months ago

There are rare situations where higher bit-depth indexed can beat lower bit-depth grayscale. In part because: 1. freedom to optimise the first colour entry (explained in original issue); 2. 8-bit symbols may form a more compressible data stream. The assumptions in the PR are quite reasonable for most cases. However, it'd be nice if there was a max level that tested all these combinations (color type & bit depths).

andrews05 commented 7 months ago

8-bit indexed can indeed be better than grayscale and this is well covered already.

The PR is specifically for low depths (1,2,4), where indexed will necessarily reach equal or lower depth than grayscale. There was a missed reduction where the indexed might have reached a lower depth than the grayscale but we weren't checking. I haven't actually found such an image in practice though (I had to create one synthetically to test), which is why I've been so slow to add this.

It is theoretically possible that indexed could be better even if it isn't lower (e.g. 2-bit indexed vs 2-bit grayscale), but it seems unlikely. Maybe I should test that further...

andrews05 commented 6 months ago

I've updated this to attempt both reductions, but to skip the evaluation if the data comes out the same.