mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibGfx: Factor out PNG frame decoding logic
The logic for decoding APNGs and single-frame PNGs had some duplicated code. No functional changes.
This commit is contained in:
parent
d30c217866
commit
c6644c92e7
Notes:
github-actions[bot]
2025-03-22 16:50:40 +00:00
Author: https://github.com/gmta
Commit: c6644c92e7
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3705
1 changed files with 14 additions and 16 deletions
|
@ -248,15 +248,25 @@ ErrorOr<void> PNGLoadingContext::apply_exif_orientation()
|
||||||
|
|
||||||
ErrorOr<size_t> PNGLoadingContext::read_frames(png_structp png_ptr, png_infop info_ptr)
|
ErrorOr<size_t> PNGLoadingContext::read_frames(png_structp png_ptr, png_infop info_ptr)
|
||||||
{
|
{
|
||||||
|
Vector<u8*> row_pointers;
|
||||||
|
auto decode_frame = [&](IntSize frame_size) -> ErrorOr<NonnullRefPtr<Bitmap>> {
|
||||||
|
auto frame_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, frame_size));
|
||||||
|
|
||||||
|
row_pointers.resize_and_keep_capacity(frame_size.height());
|
||||||
|
for (auto i = 0; i < frame_size.height(); ++i)
|
||||||
|
row_pointers[i] = frame_bitmap->scanline_u8(i);
|
||||||
|
|
||||||
|
png_read_image(png_ptr, row_pointers.data());
|
||||||
|
return frame_bitmap;
|
||||||
|
};
|
||||||
|
|
||||||
if (png_get_acTL(png_ptr, info_ptr, &frame_count, &loop_count)) {
|
if (png_get_acTL(png_ptr, info_ptr, &frame_count, &loop_count)) {
|
||||||
// acTL chunk present: This is an APNG.
|
// acTL chunk present: This is an APNG.
|
||||||
|
|
||||||
png_set_acTL(png_ptr, info_ptr, frame_count, loop_count);
|
png_set_acTL(png_ptr, info_ptr, frame_count, loop_count);
|
||||||
|
|
||||||
// Conceptually, at the beginning of each play the output buffer must be completely initialized to a fully transparent black rectangle, with width and height dimensions from the `IHDR` chunk.
|
// Conceptually, at the beginning of each play the output buffer must be completely initialized to a fully transparent black rectangle, with width and height dimensions from the `IHDR` chunk.
|
||||||
auto output_buffer = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, size));
|
auto output_buffer = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, size));
|
||||||
auto painter = Painter::create(output_buffer);
|
auto painter = Painter::create(output_buffer);
|
||||||
Vector<u8*> row_pointers;
|
|
||||||
|
|
||||||
for (size_t frame_index = 0; frame_index < frame_count; ++frame_index) {
|
for (size_t frame_index = 0; frame_index < frame_count; ++frame_index) {
|
||||||
png_read_frame_head(png_ptr, info_ptr);
|
png_read_frame_head(png_ptr, info_ptr);
|
||||||
|
@ -287,12 +297,7 @@ ErrorOr<size_t> PNGLoadingContext::read_frames(png_structp png_ptr, png_infop in
|
||||||
}
|
}
|
||||||
auto frame_rect = FloatRect { x, y, width, height };
|
auto frame_rect = FloatRect { x, y, width, height };
|
||||||
|
|
||||||
auto decoded_frame_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, IntSize { static_cast<int>(width), static_cast<int>(height) }));
|
auto decoded_frame_bitmap = TRY(decode_frame({ width, height }));
|
||||||
row_pointers.resize(height);
|
|
||||||
for (u32 i = 0; i < height; ++i) {
|
|
||||||
row_pointers[i] = decoded_frame_bitmap->scanline_u8(i);
|
|
||||||
}
|
|
||||||
png_read_image(png_ptr, row_pointers.data());
|
|
||||||
|
|
||||||
RefPtr<Bitmap> prev_output_buffer;
|
RefPtr<Bitmap> prev_output_buffer;
|
||||||
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS) // Only actually clone if it's necessary
|
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS) // Only actually clone if it's necessary
|
||||||
|
@ -331,17 +336,10 @@ ErrorOr<size_t> PNGLoadingContext::read_frames(png_structp png_ptr, png_infop in
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is a single-frame PNG.
|
// This is a single-frame PNG.
|
||||||
|
|
||||||
frame_count = 1;
|
frame_count = 1;
|
||||||
loop_count = 0;
|
loop_count = 0;
|
||||||
|
|
||||||
auto decoded_frame_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, size));
|
auto decoded_frame_bitmap = TRY(decode_frame(size));
|
||||||
Vector<u8*> row_pointers;
|
|
||||||
row_pointers.resize(size.height());
|
|
||||||
for (int i = 0; i < size.height(); ++i)
|
|
||||||
row_pointers[i] = decoded_frame_bitmap->scanline_u8(i);
|
|
||||||
|
|
||||||
png_read_image(png_ptr, row_pointers.data());
|
|
||||||
frame_descriptors.append({ move(decoded_frame_bitmap), 0 });
|
frame_descriptors.append({ move(decoded_frame_bitmap), 0 });
|
||||||
}
|
}
|
||||||
return this->frame_count;
|
return this->frame_count;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue