LibGfx: Set correct alpha type for webp decoding

The libwebp decoder gives us unpremultiplied color data, so mark our
bitmaps as such.
This commit is contained in:
Jelle Raaijmakers 2024-10-02 13:44:50 +02:00 committed by Sam Atkins
parent 07300a5bb4
commit 768d814ffd
Notes: github-actions[bot] 2024-10-02 20:04:31 +00:00
3 changed files with 15 additions and 2 deletions

View file

@ -927,6 +927,19 @@ TEST_CASE(test_webp_extended_lossless_animated)
}
}
TEST_CASE(test_webp_unpremultiplied_alpha)
{
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("webp/semi-transparent-pixel.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = TRY_OR_FAIL(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 1, 1 }));
// Webp decodes with unpremultiplied color data, so {R,G,B} can be >A (unlike with premultiplied colors).
EXPECT_EQ(frame.image->alpha_type(), Gfx::AlphaType::Unpremultiplied);
EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color(255, 255, 255, 128));
}
TEST_CASE(test_tvg)
{
auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("tvg/yak.tvg"sv)));

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 B

View file

@ -139,7 +139,7 @@ static ErrorOr<void> decode_webp_image(WebPLoadingContext& context)
return Error::from_string_literal("Failed to decode animated frame");
auto bitmap_format = context.has_alpha ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888;
auto bitmap = TRY(Bitmap::create(bitmap_format, context.size));
auto bitmap = TRY(Bitmap::create(bitmap_format, Gfx::AlphaType::Unpremultiplied, context.size));
memcpy(bitmap->scanline_u8(0), frame_data, context.size.width() * context.size.height() * 4);
@ -150,7 +150,7 @@ static ErrorOr<void> decode_webp_image(WebPLoadingContext& context)
}
} else {
auto bitmap_format = context.has_alpha ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888;
auto bitmap = TRY(Bitmap::create(bitmap_format, context.size));
auto bitmap = TRY(Bitmap::create(bitmap_format, Gfx::AlphaType::Unpremultiplied, context.size));
auto image_data = WebPDecodeBGRAInto(context.data.data(), context.data.size(), bitmap->scanline_u8(0), bitmap->data_size(), bitmap->pitch());
if (image_data == nullptr)