1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:58:11 +00:00

ImageDecoder+LibImageDecoder+LibWeb: Support animations in ImageDecoder

The ImageDecoder service now returns a list of image frames, each with
a duration value.

The code for in-process image decoding is removed from LibWeb, an all
image decode requests are sent out-of-process to ImageDecoder. :^)

This won't scale super well to very long and/or large animations, but
we can work on improving that separately. The main goal here is simply
to stop doing any image decoding inside LibWeb.

Fixes #5165.
This commit is contained in:
Andreas Kling 2021-01-29 22:30:48 +01:00
parent 449d56ef74
commit 7449c1b27f
10 changed files with 143 additions and 73 deletions

View file

@ -68,16 +68,33 @@ OwnPtr<Messages::ImageDecoderServer::DecodeImageResponse> ClientConnection::hand
}
auto decoder = Gfx::ImageDecoder::create(encoded_buffer.data<u8>(), encoded_buffer.size());
auto bitmap = decoder->bitmap();
if (!bitmap) {
if (!decoder->frame_count()) {
#if IMAGE_DECODER_DEBUG
dbgln("Could not decode image from encoded data");
#endif
return make<Messages::ImageDecoderServer::DecodeImageResponse>(Gfx::ShareableBitmap());
return make<Messages::ImageDecoderServer::DecodeImageResponse>(false, 0, Vector<Gfx::ShareableBitmap> {}, Vector<u32> {});
}
return make<Messages::ImageDecoderServer::DecodeImageResponse>(bitmap->to_shareable_bitmap());
Vector<Gfx::ShareableBitmap> bitmaps;
Vector<u32> durations;
for (size_t i = 0; i < decoder->frame_count(); ++i) {
// FIXME: All image decoder plugins should be rewritten to return frame() instead of bitmap().
// Non-animated images can simply return 1 frame.
Gfx::ImageFrameDescriptor frame;
if (decoder->is_animated()) {
frame = decoder->frame(i);
} else {
frame.image = decoder->bitmap();
}
if (frame.image)
bitmaps.append(frame.image->to_shareable_bitmap());
else
bitmaps.append(Gfx::ShareableBitmap {});
durations.append(frame.duration);
}
return make<Messages::ImageDecoderServer::DecodeImageResponse>(decoder->is_animated(), decoder->loop_count(), bitmaps, durations);
}
}