Out of 16 million possible opaque solid color blocks, previous code was not encoding all of them perfectly.
In slow,veryslow,slowest perceptual modes: 1038 colors (out of 16M) not encoded identically.
In basic perceptual mode: 3056 colors (out of 16M) not encoded perfectly (most obvious being pure red: 255,0,0,255 decodes as 253,0,0,255).
Similar issues are with alpha solid color blocks.
First I tried adding a dedicated "detect if pure solid color block, encode all the solid color modes no matter the settings" path. E.g. default perceptual basic mode never uses modes 2,4 or 5, and neither of mode 1 or 6 can encode pure opaque red for example. Anyway, adding that path gave better results, similar to how "slow" modes do.
But then I added optimal endpoint tables for modes 3 and 5, similar to how other endpoint tables are done. And that's when I found that all the opaque solid color blocks can be encoded with just mode 5 perfectly. So the final code change is fairly simple, just:
detect if it's a solid color block (done in the same place as detection of alpha).
if it is a solid color block, encode using mode 5, using optimal tables. No rotation is used.
initialization code computes tables for mode 5 now too, which does increase initialization time a bit though (before: 39ms, now: 48ms on my machine).
I tested all 16M possible opaque colors, and a bunch of ones with alpha too, and they all can be encoded perfectly now.
Out of 16 million possible opaque solid color blocks, previous code was not encoding all of them perfectly.
In slow,veryslow,slowest perceptual modes: 1038 colors (out of 16M) not encoded identically. In basic perceptual mode: 3056 colors (out of 16M) not encoded perfectly (most obvious being pure red: 255,0,0,255 decodes as 253,0,0,255).
Similar issues are with alpha solid color blocks.
First I tried adding a dedicated "detect if pure solid color block, encode all the solid color modes no matter the settings" path. E.g. default perceptual basic mode never uses modes 2,4 or 5, and neither of mode 1 or 6 can encode pure opaque red for example. Anyway, adding that path gave better results, similar to how "slow" modes do.
But then I added optimal endpoint tables for modes 3 and 5, similar to how other endpoint tables are done. And that's when I found that all the opaque solid color blocks can be encoded with just mode 5 perfectly. So the final code change is fairly simple, just:
I tested all 16M possible opaque colors, and a bunch of ones with alpha too, and they all can be encoded perfectly now.