fix: "smearing" of gifs with transparent pixels #207
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes: #84
Problem
I tried this with a number of different gifs, seems like it only happened with these stark black/white ones. In the specific case from the linked issue, white pixels from the witch silhouette were being incorrectly marked as transparent when they should remain opaque. The transparency is causing the previous frame's content to show through, creating the smearing effect.
Fix
So, we have a palette lookup table comprised of bit-crushed RGB values. For extreme colors like pure white (255,255,255), the crushed center calculation:
uint32_t R_center = (R & 0xf8) | 4;
meant taht forR=255
, we'd get252
, aka a slightly different color than what we actually had.When comparing colors for transparency optimization, the
least_dist
we got from palette matching might have been larger than it should have been (because we used approximated colors), making it more likely for the transparency choice to "win" the comparison.By using the actual RGB values instead, we get more accurate color matching against the palette, which means
least_dist
is more likely to be small for exact color matches. This makes it less likely for the transparency optimization to incorrectly override a good palette color match, especially for extreme colors like pure white or black.