1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:04:59 +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

@ -46,20 +46,30 @@ void Client::handle(const Messages::ImageDecoderClient::Dummy&)
{
}
RefPtr<Gfx::Bitmap> Client::decode_image(const ByteBuffer& encoded_data)
Optional<DecodedImage> Client::decode_image(const ByteBuffer& encoded_data)
{
if (encoded_data.is_empty())
return nullptr;
return {};
auto encoded_buffer = Core::AnonymousBuffer::create_with_size(encoded_data.size());
if (!encoded_buffer.is_valid()) {
dbgln("Could not allocate encoded buffer");
return nullptr;
return {};
}
memcpy(encoded_buffer.data<void>(), encoded_data.data(), encoded_data.size());
auto response = send_sync<Messages::ImageDecoderServer::DecodeImage>(move(encoded_buffer));
return response->bitmap().bitmap();
DecodedImage image;
image.is_animated = response->is_animated();
image.loop_count = response->loop_count();
image.frames.resize(response->bitmaps().size());
for (size_t i = 0; i < image.frames.size(); ++i) {
auto& frame = image.frames[i];
frame.bitmap = response->bitmaps()[i].bitmap();
frame.duration = response->durations()[i];
}
return move(image);
}
}

View file

@ -33,6 +33,17 @@
namespace ImageDecoderClient {
struct Frame {
RefPtr<Gfx::Bitmap> bitmap;
u32 duration { 0 };
};
struct DecodedImage {
bool is_animated { false };
u32 loop_count { 0 };
Vector<Frame> frames;
};
class Client
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
, public ImageDecoderClientEndpoint {
@ -41,7 +52,7 @@ class Client
public:
virtual void handshake() override;
RefPtr<Gfx::Bitmap> decode_image(const ByteBuffer&);
Optional<DecodedImage> decode_image(const ByteBuffer&);
private:
Client();