mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-10 19:46:03 +00:00
LibGfx/WebPWriter: Let compress_VP8L_image*() return if image was opaque
We compute that as part of compression there anyways, so let's compute it only once. No behavior change.
This commit is contained in:
parent
ab0219bb08
commit
2d80a5c6ca
Notes:
sideshowbarker
2024-07-16 23:51:07 +09:00
Author: https://github.com/nico
Commit: 2d80a5c6ca
Pull-request: https://github.com/SerenityOS/serenity/pull/24468
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/LucasChollet ✅
3 changed files with 14 additions and 19 deletions
|
@ -67,15 +67,6 @@ static ErrorOr<void> write_VP8L_header(Stream& stream, unsigned width, unsigned
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool are_all_pixels_opaque(Bitmap const& bitmap)
|
|
||||||
{
|
|
||||||
for (ARGB32 pixel : bitmap) {
|
|
||||||
if ((pixel >> 24) != 0xff)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Consider using LibRIFF for RIFF writing details. (It currently has no writing support.)
|
// FIXME: Consider using LibRIFF for RIFF writing details. (It currently has no writing support.)
|
||||||
static ErrorOr<void> align_to_two(Stream& stream, size_t number_of_bytes_written)
|
static ErrorOr<void> align_to_two(Stream& stream, size_t number_of_bytes_written)
|
||||||
{
|
{
|
||||||
|
@ -190,11 +181,11 @@ static ErrorOr<void> align_to_two(AllocatingMemoryStream& stream)
|
||||||
|
|
||||||
ErrorOr<void> WebPWriter::encode(Stream& stream, Bitmap const& bitmap, Options const& options)
|
ErrorOr<void> WebPWriter::encode(Stream& stream, Bitmap const& bitmap, Options const& options)
|
||||||
{
|
{
|
||||||
bool alpha_is_used_hint = !are_all_pixels_opaque(bitmap);
|
|
||||||
dbgln_if(WEBP_DEBUG, "Writing WebP of size {} with alpha hint: {}", bitmap.size(), alpha_is_used_hint);
|
|
||||||
|
|
||||||
// The chunk headers need to know their size, so we either need a SeekableStream or need to buffer the data. We're doing the latter.
|
// The chunk headers need to know their size, so we either need a SeekableStream or need to buffer the data. We're doing the latter.
|
||||||
auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap));
|
bool is_fully_opaque;
|
||||||
|
auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap, is_fully_opaque));
|
||||||
|
bool alpha_is_used_hint = !is_fully_opaque;
|
||||||
|
dbgln_if(WEBP_DEBUG, "Writing WebP of size {} with alpha hint: {}", bitmap.size(), alpha_is_used_hint);
|
||||||
|
|
||||||
ByteBuffer vp8x_chunk_bytes;
|
ByteBuffer vp8x_chunk_bytes;
|
||||||
ByteBuffer iccp_chunk_bytes;
|
ByteBuffer iccp_chunk_bytes;
|
||||||
|
@ -315,7 +306,8 @@ ErrorOr<void> WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In
|
||||||
// Since we have a SeekableStream, we could write both the VP8L chunk header and the ANMF chunk header with a placeholder size,
|
// Since we have a SeekableStream, we could write both the VP8L chunk header and the ANMF chunk header with a placeholder size,
|
||||||
// compress the frame data directly to the stream, and then go back and update the two sizes.
|
// compress the frame data directly to the stream, and then go back and update the two sizes.
|
||||||
// That's pretty messy though, and the compressed image data is smaller than the uncompressed bitmap passed in. So we'll buffer it.
|
// That's pretty messy though, and the compressed image data is smaller than the uncompressed bitmap passed in. So we'll buffer it.
|
||||||
auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap));
|
bool is_fully_opaque;
|
||||||
|
auto vp8l_data_bytes = TRY(compress_VP8L_image_data(bitmap, is_fully_opaque));
|
||||||
|
|
||||||
ANMFChunkHeader chunk;
|
ANMFChunkHeader chunk;
|
||||||
chunk.frame_x = static_cast<u32>(at.x());
|
chunk.frame_x = static_cast<u32>(at.x());
|
||||||
|
@ -331,7 +323,7 @@ ErrorOr<void> WebPAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, In
|
||||||
|
|
||||||
TRY(update_size_in_header());
|
TRY(update_size_in_header());
|
||||||
|
|
||||||
if (!(m_vp8x_flags & 0x10) && !are_all_pixels_opaque(bitmap))
|
if (!(m_vp8x_flags & 0x10) && !is_fully_opaque)
|
||||||
TRY(set_alpha_bit_in_header());
|
TRY(set_alpha_bit_in_header());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -213,7 +213,7 @@ static ErrorOr<CanonicalCode> write_normal_code_lengths(LittleEndianOutputBitStr
|
||||||
return CanonicalCode::from_bytes(bit_lengths.span().trim(code_count));
|
return CanonicalCode::from_bytes(bit_lengths.span().trim(code_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ErrorOr<void> write_VP8L_image_data(Stream& stream, Bitmap const& bitmap)
|
static ErrorOr<void> write_VP8L_image_data(Stream& stream, Bitmap const& bitmap, bool& is_fully_opaque)
|
||||||
{
|
{
|
||||||
LittleEndianOutputBitStream bit_stream { MaybeOwned<Stream>(stream) };
|
LittleEndianOutputBitStream bit_stream { MaybeOwned<Stream>(stream) };
|
||||||
|
|
||||||
|
@ -291,6 +291,9 @@ static ErrorOr<void> write_VP8L_image_data(Stream& stream, Bitmap const& bitmap)
|
||||||
prefix_code_group[i] = TRY(write_simple_code_lengths(bit_stream, { symbols, non_zero_symbol_count }));
|
prefix_code_group[i] = TRY(write_simple_code_lengths(bit_stream, { symbols, non_zero_symbol_count }));
|
||||||
else
|
else
|
||||||
prefix_code_group[i] = TRY(write_normal_code_lengths(bit_stream, code_lengths[i], alphabet_sizes[i]));
|
prefix_code_group[i] = TRY(write_normal_code_lengths(bit_stream, code_lengths[i], alphabet_sizes[i]));
|
||||||
|
|
||||||
|
if (i == 3)
|
||||||
|
is_fully_opaque = non_zero_symbol_count == 1 && symbols[0] == 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For code #5, use a simple empty code, since we don't use this yet.
|
// For code #5, use a simple empty code, since we don't use this yet.
|
||||||
|
@ -306,10 +309,10 @@ static ErrorOr<void> write_VP8L_image_data(Stream& stream, Bitmap const& bitmap)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<ByteBuffer> compress_VP8L_image_data(Bitmap const& bitmap)
|
ErrorOr<ByteBuffer> compress_VP8L_image_data(Bitmap const& bitmap, bool& is_fully_opaque)
|
||||||
{
|
{
|
||||||
AllocatingMemoryStream vp8l_data_stream;
|
AllocatingMemoryStream vp8l_data_stream;
|
||||||
TRY(write_VP8L_image_data(vp8l_data_stream, bitmap));
|
TRY(write_VP8L_image_data(vp8l_data_stream, bitmap, is_fully_opaque));
|
||||||
return vp8l_data_stream.read_until_eof();
|
return vp8l_data_stream.read_until_eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
ErrorOr<ByteBuffer> compress_VP8L_image_data(Bitmap const&);
|
ErrorOr<ByteBuffer> compress_VP8L_image_data(Bitmap const&, bool& is_fully_opaque);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue