diff --git a/Ladybird/ImageCodecPlugin.cpp b/Ladybird/ImageCodecPlugin.cpp index b10155f1be6..1678a4a7dd0 100644 --- a/Ladybird/ImageCodecPlugin.cpp +++ b/Ladybird/ImageCodecPlugin.cpp @@ -20,7 +20,7 @@ namespace Ladybird { ImageCodecPlugin::~ImageCodecPlugin() = default; -Optional ImageCodecPlugin::decode_image(ReadonlyBytes bytes) +NonnullRefPtr> ImageCodecPlugin::decode_image(ReadonlyBytes bytes, Function(Web::Platform::DecodedImage&)> on_resolved, Function on_rejected) { if (!m_client) { #ifdef AK_OS_ANDROID @@ -34,19 +34,30 @@ Optional ImageCodecPlugin::decode_image(ReadonlyByt }; } - auto result_or_empty = m_client->decode_image(bytes); - if (!result_or_empty.has_value()) - return {}; - auto result = result_or_empty.release_value(); + auto promise = Core::Promise::construct(); + if (on_resolved) + promise->on_resolution = move(on_resolved); + if (on_rejected) + promise->on_rejection = move(on_rejected); - Web::Platform::DecodedImage decoded_image; - decoded_image.is_animated = result.is_animated; - decoded_image.loop_count = result.loop_count; - for (auto const& frame : result.frames) { - decoded_image.frames.empend(move(frame.bitmap), frame.duration); - } + auto image_decoder_promise = m_client->decode_image( + bytes, + [promise](ImageDecoderClient::DecodedImage& result) -> ErrorOr { + // 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; + for (auto const& frame : result.frames) { + decoded_image.frames.empend(move(frame.bitmap), frame.duration); + } + promise->resolve(move(decoded_image)); + return {}; + }, + [promise](auto& error) { + promise->reject(Error::copy(error)); + }); - return decoded_image; + return promise; } } diff --git a/Ladybird/ImageCodecPlugin.h b/Ladybird/ImageCodecPlugin.h index e6774e9041c..e9cd93fadf5 100644 --- a/Ladybird/ImageCodecPlugin.h +++ b/Ladybird/ImageCodecPlugin.h @@ -17,7 +17,7 @@ public: ImageCodecPlugin() = default; virtual ~ImageCodecPlugin() override; - virtual Optional decode_image(ReadonlyBytes data) override; + virtual NonnullRefPtr> decode_image(ReadonlyBytes, Function(Web::Platform::DecodedImage&)> on_resolved, Function on_rejected) override; private: RefPtr m_client; diff --git a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp index 54057349610..58ae72dcc20 100644 --- a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp @@ -25,4 +25,13 @@ void ImageCodecPlugin::install(ImageCodecPlugin& plugin) s_the = &plugin; } +Optional ImageCodecPlugin::decode_image(ReadonlyBytes encoded_data) +{ + auto promise = decode_image(encoded_data, {}, {}); + auto result = promise->await(); + if (result.is_error()) + return {}; + return result.release_value(); +} + } diff --git a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h index c26f61114d0..85c94841a6d 100644 --- a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace Web::Platform { @@ -31,7 +32,8 @@ public: virtual ~ImageCodecPlugin(); - virtual Optional decode_image(ReadonlyBytes) = 0; + virtual NonnullRefPtr> decode_image(ReadonlyBytes, Function(DecodedImage&)> on_resolved, Function on_rejected) = 0; + Optional decode_image(ReadonlyBytes); }; } diff --git a/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp index cc50fdf202f..0214d5b104f 100644 --- a/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp @@ -13,7 +13,7 @@ namespace WebContent { ImageCodecPluginSerenity::ImageCodecPluginSerenity() = default; ImageCodecPluginSerenity::~ImageCodecPluginSerenity() = default; -Optional ImageCodecPluginSerenity::decode_image(ReadonlyBytes bytes) +NonnullRefPtr> ImageCodecPluginSerenity::decode_image(ReadonlyBytes bytes, Function(Web::Platform::DecodedImage&)> on_resolved, Function on_rejected) { if (!m_client) { m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors(); @@ -22,19 +22,30 @@ Optional ImageCodecPluginSerenity::decode_image(Rea }; } - auto result_or_empty = m_client->decode_image(bytes); - if (!result_or_empty.has_value()) - return {}; - auto result = result_or_empty.release_value(); + auto promise = Core::Promise::construct(); + if (on_resolved) + promise->on_resolution = move(on_resolved); + if (on_rejected) + promise->on_rejection = move(on_rejected); - Web::Platform::DecodedImage decoded_image; - decoded_image.is_animated = result.is_animated; - decoded_image.loop_count = result.loop_count; - for (auto const& frame : result.frames) { - decoded_image.frames.empend(frame.bitmap, frame.duration); - } + auto image_decoder_promise = m_client->decode_image( + bytes, + [promise](ImageDecoderClient::DecodedImage& result) -> ErrorOr { + // 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; + for (auto const& frame : result.frames) { + decoded_image.frames.empend(move(frame.bitmap), frame.duration); + } + promise->resolve(move(decoded_image)); + return {}; + }, + [promise](auto& error) { + promise->reject(Error::copy(error)); + }); - return decoded_image; + return promise; } } diff --git a/Userland/Services/WebContent/ImageCodecPluginSerenity.h b/Userland/Services/WebContent/ImageCodecPluginSerenity.h index 42d967b0f1b..c065234cefb 100644 --- a/Userland/Services/WebContent/ImageCodecPluginSerenity.h +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.h @@ -21,7 +21,7 @@ public: ImageCodecPluginSerenity(); virtual ~ImageCodecPluginSerenity() override; - virtual Optional decode_image(ReadonlyBytes) override; + virtual NonnullRefPtr> decode_image(ReadonlyBytes, Function(Web::Platform::DecodedImage&)> on_resolved, Function on_rejected) override; private: RefPtr m_client;