mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-08-17 01:10:28 +03:00
LibGfx/WebPWriter: Do not write color index if only one channel varies
The benefit of the color indexing transform is to have only one varying channel after it (the green channel, which after the transform serves as index into the color table). If there is only one varying channel before the transform, it's not beneficial. (...except if there are <= 16 colors, then the pixel bundling presumably still works.)
This commit is contained in:
parent
634c4567fe
commit
347e2831b2
Notes:
sideshowbarker
2024-07-16 20:31:50 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/347e2831b2 Pull-request: https://github.com/SerenityOS/serenity/pull/24503 Reviewed-by: https://github.com/AtkinsSJ Reviewed-by: https://github.com/timschumi ✅
@ -339,21 +339,38 @@ static ErrorOr<NonnullRefPtr<Bitmap>> maybe_write_color_indexing_transform(Littl
|
||||
// https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#44_color_indexing_transform
|
||||
unsigned color_table_size = 0;
|
||||
HashTable<ARGB32> seen_colors;
|
||||
ARGB32 channels = 0;
|
||||
ARGB32 first_pixel = bitmap->get_pixel(0, 0).value();
|
||||
for (ARGB32 pixel : *bitmap) {
|
||||
auto result = seen_colors.set(pixel);
|
||||
if (result == HashSetResult::InsertedNewEntry) {
|
||||
++color_table_size;
|
||||
channels |= pixel ^ first_pixel;
|
||||
if (color_table_size > 256)
|
||||
break;
|
||||
}
|
||||
}
|
||||
dbgln_if(WEBP_DEBUG, "WebP: Image has {}{} colors", color_table_size > 256 ? ">= " : "", color_table_size);
|
||||
dbgln_if(WEBP_DEBUG, "WebP: Image has {}{} colors; all pixels or'd is {:#08x}", color_table_size > 256 ? ">= " : "", color_table_size, channels);
|
||||
|
||||
// If the image has a single color, the huffman table can encode it in 0 bits and color indexing does not help.
|
||||
// FIXME: If all colors use just a single channel, color indexing does not help either.
|
||||
if (color_table_size <= 1 || color_table_size > 256)
|
||||
return bitmap;
|
||||
|
||||
// If all colors use just a single channel, color indexing does not help either,
|
||||
// except if there are <= 16 colors and we can do pixel bundling.
|
||||
// FIXME: Once we support color cache, maybe that helps for single-channel pixels with fewer than 16 colors
|
||||
// and we don't need to write a color index then?
|
||||
if (color_table_size > 16) {
|
||||
int number_of_non_constant_channels = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (channels & (0xff << (i * 8)))
|
||||
number_of_non_constant_channels++;
|
||||
}
|
||||
if (number_of_non_constant_channels <= 1)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
dbgln_if(WEBP_DEBUG, "WebP: Writing color index transform");
|
||||
TRY(bit_stream.write_bits(1u, 1u)); // Transform present.
|
||||
TRY(bit_stream.write_bits(static_cast<unsigned>(COLOR_INDEXING_TRANSFORM), 2u));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user