diff options
author | Andreas Kling <kling@serenityos.org> | 2022-09-16 15:15:14 +0200 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-25 07:58:58 -0700 |
commit | ef757f33da46d6d488163915f877ba5c1930281c (patch) | |
tree | 52d8e5cad9a1c23b07af481ac6756057680b5984 | |
parent | 4334929323d24e5b093b5ad6470dc1cbd7de6e7f (diff) | |
download | serenity-ef757f33da46d6d488163915f877ba5c1930281c.zip |
Ladybird: Implement the Web::Platform::ImageCodecPlugin interface
...and move it to separate files while we're at it.
-rw-r--r-- | Ladybird/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Ladybird/ImageCodecPluginLadybird.cpp | 80 | ||||
-rw-r--r-- | Ladybird/ImageCodecPluginLadybird.h | 22 | ||||
-rw-r--r-- | Ladybird/WebView.cpp | 79 |
4 files changed, 105 insertions, 77 deletions
diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt index 5f54f42c56..cdbacedde9 100644 --- a/Ladybird/CMakeLists.txt +++ b/Ladybird/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCES CookieJar.cpp EventLoopPluginQt.cpp FontPluginQt.cpp + ImageCodecPluginLadybird.cpp RequestManagerQt.cpp main.cpp WebView.cpp diff --git a/Ladybird/ImageCodecPluginLadybird.cpp b/Ladybird/ImageCodecPluginLadybird.cpp new file mode 100644 index 0000000000..c00c10ac43 --- /dev/null +++ b/Ladybird/ImageCodecPluginLadybird.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#define AK_DONT_REPLACE_STD + +#include "ImageCodecPluginLadybird.h" +#include <LibGfx/Bitmap.h> +#include <LibGfx/ImageDecoder.h> +#include <QImage> + +namespace Ladybird { + +ImageCodecPluginLadybird::~ImageCodecPluginLadybird() = default; + +static Optional<Web::Platform::DecodedImage> decode_image_with_qt(ReadonlyBytes data) +{ + auto image = QImage::fromData(data.data(), static_cast<int>(data.size())); + if (image.isNull()) + return {}; + image = image.convertToFormat(QImage::Format::Format_ARGB32); + auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height()))); + for (int y = 0; y < image.height(); ++y) { + memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4); + } + Vector<Web::Platform::Frame> frames; + + frames.append(Web::Platform::Frame { + bitmap, + }); + return Web::Platform::DecodedImage { + false, + 0, + move(frames), + }; +} + +static Optional<Web::Platform::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data) +{ + auto decoder = Gfx::ImageDecoder::try_create(data); + + if (!decoder || !decoder->frame_count()) { + return {}; + } + + bool had_errors = false; + Vector<Web::Platform::Frame> frames; + for (size_t i = 0; i < decoder->frame_count(); ++i) { + auto frame_or_error = decoder->frame(i); + if (frame_or_error.is_error()) { + frames.append({ {}, 0 }); + had_errors = true; + } else { + auto frame = frame_or_error.release_value(); + frames.append({ move(frame.image), static_cast<size_t>(frame.duration) }); + } + } + + if (had_errors) + return {}; + + return Web::Platform::DecodedImage { + decoder->is_animated(), + static_cast<u32>(decoder->loop_count()), + move(frames), + }; +} + +Optional<Web::Platform::DecodedImage> ImageCodecPluginLadybird::decode_image(ReadonlyBytes data) +{ + auto image = decode_image_with_libgfx(data); + if (image.has_value()) + return image; + return decode_image_with_qt(data); +} + +} diff --git a/Ladybird/ImageCodecPluginLadybird.h b/Ladybird/ImageCodecPluginLadybird.h new file mode 100644 index 0000000000..ae2e49ee39 --- /dev/null +++ b/Ladybird/ImageCodecPluginLadybird.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> + * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWeb/Platform/ImageCodecPlugin.h> + +namespace Ladybird { + +class ImageCodecPluginLadybird final : public Web::Platform::ImageCodecPlugin { +public: + ImageCodecPluginLadybird() = default; + virtual ~ImageCodecPluginLadybird() override; + + virtual Optional<Web::Platform::DecodedImage> decode_image(ReadonlyBytes data) override; +}; + +} diff --git a/Ladybird/WebView.cpp b/Ladybird/WebView.cpp index 93f5fc9a48..42902ba5c8 100644 --- a/Ladybird/WebView.cpp +++ b/Ladybird/WebView.cpp @@ -12,6 +12,7 @@ #include "CookieJar.h" #include "EventLoopPluginQt.h" #include "FontPluginQt.h" +#include "ImageCodecPluginLadybird.h" #include "RequestManagerQt.h" #include <AK/Assertions.h> #include <AK/ByteBuffer.h> @@ -30,7 +31,6 @@ #include <LibCore/Timer.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Font/FontDatabase.h> -#include <LibGfx/ImageDecoder.h> #include <LibGfx/PNGWriter.h> #include <LibGfx/Rect.h> #include <LibJS/Runtime/ConsoleObject.h> @@ -43,7 +43,6 @@ #include <LibWeb/HTML/Scripting/ClassicScript.h> #include <LibWeb/HTML/Storage.h> #include <LibWeb/HTML/Window.h> -#include <LibWeb/ImageDecoding.h> #include <LibWeb/Layout/InitialContainingBlock.h> #include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Page/Page.h> @@ -654,80 +653,6 @@ void WebView::resizeEvent(QResizeEvent* event) m_page_client->set_viewport_rect(rect); } -static Optional<Web::ImageDecoding::DecodedImage> decode_image_with_qt(ReadonlyBytes data) -{ - auto image = QImage::fromData(data.data(), static_cast<int>(data.size())); - if (image.isNull()) - return {}; - image = image.convertToFormat(QImage::Format::Format_ARGB32); - auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height()))); - for (int y = 0; y < image.height(); ++y) { - memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4); - } - Vector<Web::ImageDecoding::Frame> frames; - - frames.append(Web::ImageDecoding::Frame { - bitmap, - }); - return Web::ImageDecoding::DecodedImage { - false, - 0, - move(frames), - }; -} - -static Optional<Web::ImageDecoding::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data) -{ - auto decoder = Gfx::ImageDecoder::try_create(data); - - if (!decoder || !decoder->frame_count()) { - return {}; - } - - bool had_errors = false; - Vector<Web::ImageDecoding::Frame> frames; - for (size_t i = 0; i < decoder->frame_count(); ++i) { - auto frame_or_error = decoder->frame(i); - if (frame_or_error.is_error()) { - frames.append({ {}, 0 }); - had_errors = true; - } else { - auto frame = frame_or_error.release_value(); - frames.append({ move(frame.image), static_cast<size_t>(frame.duration) }); - } - } - - if (had_errors) - return {}; - - return Web::ImageDecoding::DecodedImage { - decoder->is_animated(), - static_cast<u32>(decoder->loop_count()), - move(frames), - }; -} - -class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder { -public: - static NonnullRefPtr<HeadlessImageDecoderClient> create() - { - return adopt_ref(*new HeadlessImageDecoderClient()); - } - - virtual ~HeadlessImageDecoderClient() override = default; - - virtual Optional<Web::ImageDecoding::DecodedImage> decode_image(ReadonlyBytes data) override - { - auto image = decode_image_with_libgfx(data); - if (image.has_value()) - return image; - return decode_image_with_qt(data); - } - -private: - explicit HeadlessImageDecoderClient() = default; -}; - class HeadlessWebSocketClientManager : public Web::WebSockets::WebSocketClientManager { public: class HeadlessWebSocket @@ -851,8 +776,8 @@ static void platform_init() void initialize_web_engine() { Web::Platform::EventLoopPlugin::install(*new Ladybird::EventLoopPluginQt); + Web::Platform::ImageCodecPlugin::install(*new Ladybird::ImageCodecPluginLadybird); - Web::ImageDecoding::Decoder::initialize(HeadlessImageDecoderClient::create()); Web::ResourceLoader::initialize(RequestManagerQt::create()); Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create()); |