mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-19 02:10:26 +00:00
Implement the client side of streaming animation decode sessions. The ImageDecoderClient handles new IPC messages for frame delivery and failure reporting, and the ImageCodecPlugin bridges this through the platform abstraction layer used by LibWeb.
94 lines
3.1 KiB
C++
94 lines
3.1 KiB
C++
/*
|
|
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
|
|
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibGfx/Bitmap.h>
|
|
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
|
#include <LibImageDecoderClient/Client.h>
|
|
#include <LibWebView/Plugins/ImageCodecPlugin.h>
|
|
#include <LibWebView/Utilities.h>
|
|
|
|
namespace WebView {
|
|
|
|
ImageCodecPlugin::ImageCodecPlugin(NonnullRefPtr<ImageDecoderClient::Client> client)
|
|
: m_client(move(client))
|
|
{
|
|
setup_client_callbacks();
|
|
}
|
|
|
|
void ImageCodecPlugin::set_client(NonnullRefPtr<ImageDecoderClient::Client> client)
|
|
{
|
|
m_client = move(client);
|
|
setup_client_callbacks();
|
|
}
|
|
|
|
void ImageCodecPlugin::setup_client_callbacks()
|
|
{
|
|
m_client->on_death = [this] {
|
|
m_client = nullptr;
|
|
};
|
|
m_client->on_animation_frames_decoded = [this](i64 session_id, Vector<NonnullRefPtr<Gfx::Bitmap>> bitmaps) {
|
|
if (on_animation_frames_decoded)
|
|
on_animation_frames_decoded(session_id, move(bitmaps));
|
|
};
|
|
m_client->on_animation_decode_failed = [this](i64 session_id, String) {
|
|
if (on_animation_decode_failed)
|
|
on_animation_decode_failed(session_id);
|
|
};
|
|
}
|
|
|
|
ImageCodecPlugin::~ImageCodecPlugin() = default;
|
|
|
|
NonnullRefPtr<Core::Promise<Web::Platform::DecodedImage>> ImageCodecPlugin::decode_image(ReadonlyBytes bytes, Function<ErrorOr<void>(Web::Platform::DecodedImage&)> on_resolved, Function<void(Error&)> on_rejected)
|
|
{
|
|
auto promise = Core::Promise<Web::Platform::DecodedImage>::construct();
|
|
if (on_resolved)
|
|
promise->on_resolution = move(on_resolved);
|
|
if (on_rejected)
|
|
promise->on_rejection = move(on_rejected);
|
|
|
|
if (!m_client) {
|
|
promise->reject(Error::from_string_literal("ImageDecoderClient is disconnected"));
|
|
return promise;
|
|
}
|
|
|
|
auto image_decoder_promise = m_client->decode_image(
|
|
bytes,
|
|
[promise](ImageDecoderClient::DecodedImage& result) -> ErrorOr<void> {
|
|
// FIXME: Remove this codec plugin and just use the ImageDecoderClient directly to avoid these copies
|
|
Web::Platform::DecodedImage decoded_image;
|
|
decoded_image.is_animated = result.is_animated;
|
|
decoded_image.loop_count = result.loop_count;
|
|
decoded_image.frame_count = result.frame_count;
|
|
decoded_image.session_id = result.session_id;
|
|
decoded_image.all_durations = move(result.all_durations);
|
|
for (auto& frame : result.frames) {
|
|
decoded_image.frames.empend(move(frame.bitmap), frame.duration);
|
|
}
|
|
decoded_image.color_space = move(result.color_space);
|
|
promise->resolve(move(decoded_image));
|
|
return {};
|
|
},
|
|
[promise](auto& error) {
|
|
promise->reject(Error::copy(error));
|
|
});
|
|
|
|
return promise;
|
|
}
|
|
|
|
void ImageCodecPlugin::request_animation_frames(i64 session_id, u32 start_frame_index, u32 count)
|
|
{
|
|
if (m_client)
|
|
m_client->request_animation_frames(session_id, start_frame_index, count);
|
|
}
|
|
|
|
void ImageCodecPlugin::stop_animation_decode(i64 session_id)
|
|
{
|
|
if (m_client)
|
|
m_client->stop_animation_decode(session_id);
|
|
}
|
|
|
|
}
|