diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 2037d55dfa..26ea86867b 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -268,7 +268,6 @@ set(SOURCES HTML/WorkerLocation.cpp HTML/WorkerNavigator.cpp HighResolutionTime/Performance.cpp - ImageDecoding.cpp Infra/ByteSequences.cpp IntersectionObserver/IntersectionObserver.cpp Layout/BlockContainer.cpp @@ -355,6 +354,7 @@ set(SOURCES Painting/TextPaintable.cpp Platform/EventLoopPlugin.cpp Platform/FontPlugin.cpp + Platform/ImageCodecPlugin.cpp Platform/Timer.cpp RequestIdleCallback/IdleDeadline.cpp ResizeObserver/ResizeObserver.cpp diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 9fd5d9024c..5b4d4158df 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -12,9 +12,9 @@ #include #include #include -#include #include #include +#include namespace Web::HTML { @@ -156,7 +156,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active() return false; RefPtr favicon_bitmap; - auto decoded_image = Web::ImageDecoding::Decoder::the().decode_image(resource()->encoded_data()); + auto decoded_image = Platform::ImageCodecPlugin::the().decode_image(resource()->encoded_data()); if (!decoded_image.has_value() || decoded_image->frames.is_empty()) { dbgln("Could not decode favicon {}", resource()->url()); return false; diff --git a/Userland/Libraries/LibWeb/ImageDecoding.cpp b/Userland/Libraries/LibWeb/ImageDecoding.cpp deleted file mode 100644 index fc2aefee4e..0000000000 --- a/Userland/Libraries/LibWeb/ImageDecoding.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021, Andreas Kling - * Copyright (c) 2022, Dex♪ - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include - -namespace Web::ImageDecoding { - -static RefPtr s_decoder; - -Decoder::Decoder() = default; - -Decoder::~Decoder() = default; - -void Decoder::initialize(RefPtr&& decoder) -{ - s_decoder = move(decoder); -} - -Decoder& Decoder::the() -{ - if (!s_decoder) [[unlikely]] { - dbgln("Web::ImageDecoding::Decoder was not initialized!"); - VERIFY_NOT_REACHED(); - } - return *s_decoder; -} - -} diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp index dd16be17db..f757ddd81e 100644 --- a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp @@ -19,10 +19,10 @@ #include #include #include -#include #include #include #include +#include #include namespace Web { @@ -82,7 +82,7 @@ static bool build_text_document(DOM::Document& document, ByteBuffer const& data) static bool build_image_document(DOM::Document& document, ByteBuffer const& data) { - auto image = ImageDecoding::Decoder::the().decode_image(data); + auto image = Platform::ImageCodecPlugin::the().decode_image(data); if (!image.has_value() || image->frames.is_empty()) return false; auto const& frame = image->frames[0]; @@ -215,7 +215,7 @@ bool FrameLoader::load(LoadRequest& request, Type type) if (data.is_empty()) return; RefPtr favicon_bitmap; - auto decoded_image = ImageDecoding::Decoder::the().decode_image(data); + auto decoded_image = Platform::ImageCodecPlugin::the().decode_image(data); if (!decoded_image.has_value() || decoded_image->frames.is_empty()) { dbgln("Could not decode favicon {}", favicon_url); } else { diff --git a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp index ac2704f4c4..25a60753d5 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include namespace Web { @@ -47,7 +47,7 @@ void ImageResource::decode_if_needed() const if (!m_decoded_frames.is_empty()) return; - auto image = ImageDecoding::Decoder::the().decode_image(encoded_data()); + auto image = Platform::ImageCodecPlugin::the().decode_image(encoded_data()); if (image.has_value()) { m_loop_count = image.value().loop_count; diff --git a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp new file mode 100644 index 0000000000..5405734961 --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021-2022, Andreas Kling + * Copyright (c) 2022, Dex♪ + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::Platform { + +static ImageCodecPlugin* s_the; + +ImageCodecPlugin::~ImageCodecPlugin() = default; + +ImageCodecPlugin& ImageCodecPlugin::the() +{ + VERIFY(s_the); + return *s_the; +} + +void ImageCodecPlugin::install(ImageCodecPlugin& plugin) +{ + VERIFY(!s_the); + s_the = &plugin; +} + +} diff --git a/Userland/Libraries/LibWeb/ImageDecoding.h b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h similarity index 59% rename from Userland/Libraries/LibWeb/ImageDecoding.h rename to Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h index 2c462aae2c..c26f61114d 100644 --- a/Userland/Libraries/LibWeb/ImageDecoding.h +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, Andreas Kling + * Copyright (c) 2020-2022, Andreas Kling * Copyright (c) 2022, Dex♪ * * SPDX-License-Identifier: BSD-2-Clause @@ -9,9 +9,9 @@ #include #include -#include +#include -namespace Web::ImageDecoding { +namespace Web::Platform { struct Frame { RefPtr bitmap; @@ -24,17 +24,14 @@ struct DecodedImage { Vector frames; }; -class Decoder : public RefCounted { +class ImageCodecPlugin { public: - virtual ~Decoder(); + static ImageCodecPlugin& the(); + static void install(ImageCodecPlugin&); - static void initialize(RefPtr&&); - static Decoder& the(); + virtual ~ImageCodecPlugin(); virtual Optional decode_image(ReadonlyBytes) = 0; - -protected: - explicit Decoder(); }; } diff --git a/Userland/Libraries/LibWebView/CMakeLists.txt b/Userland/Libraries/LibWebView/CMakeLists.txt index 64aa178e56..6b2aa60744 100644 --- a/Userland/Libraries/LibWebView/CMakeLists.txt +++ b/Userland/Libraries/LibWebView/CMakeLists.txt @@ -1,6 +1,5 @@ set(SOURCES DOMTreeModel.cpp - ImageDecoderClientAdapter.cpp OutOfProcessWebView.cpp RequestServerAdapter.cpp StylePropertiesModel.cpp @@ -16,6 +15,6 @@ set(GENERATED_SOURCES ) serenity_lib(LibWebView webview) -target_link_libraries(LibWebView LibFileSystemAccessClient LibGfx LibGUI LibImageDecoderClient LibIPC LibProtocol LibWeb) +target_link_libraries(LibWebView LibFileSystemAccessClient LibGfx LibGUI LibIPC LibProtocol LibWeb) add_subdirectory(DumpLayoutTree) diff --git a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h b/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h deleted file mode 100644 index e46b0e6974..0000000000 --- a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022, Dex♪ - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace ImageDecoderClient { -class Client; -} - -namespace WebView { - -class ImageDecoderClientAdapter : public Web::ImageDecoding::Decoder { -public: - static NonnullRefPtr create(); - - virtual ~ImageDecoderClientAdapter() override = default; - - virtual Optional decode_image(ReadonlyBytes) override; - -private: - explicit ImageDecoderClientAdapter() = default; - - RefPtr m_client; -}; - -} diff --git a/Userland/Services/WebContent/CMakeLists.txt b/Userland/Services/WebContent/CMakeLists.txt index 0a46963ba8..ca7b7395a8 100644 --- a/Userland/Services/WebContent/CMakeLists.txt +++ b/Userland/Services/WebContent/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES ConsoleGlobalObject.cpp EventLoopPluginSerenity.cpp FontPluginSerenity.cpp + ImageCodecPluginSerenity.cpp PageHost.cpp TimerSerenity.cpp WebContentClientEndpoint.h @@ -21,5 +22,5 @@ set(SOURCES ) serenity_bin(WebContent) -target_link_libraries(WebContent LibCore LibIPC LibGfx LibWebView LibWeb LibMain) +target_link_libraries(WebContent LibCore LibIPC LibGfx LibImageDecoderClient LibWebView LibWeb LibMain) link_with_locale_data(WebContent) diff --git a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp similarity index 66% rename from Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp rename to Userland/Services/WebContent/ImageCodecPluginSerenity.cpp index 47fa6e1878..426cf5fb27 100644 --- a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp @@ -1,20 +1,19 @@ /* * Copyright (c) 2022, Dex♪ + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ +#include "ImageCodecPluginSerenity.h" #include -#include -namespace WebView { +namespace WebContent { -NonnullRefPtr ImageDecoderClientAdapter::create() -{ - return adopt_ref(*new ImageDecoderClientAdapter()); -} +ImageCodecPluginSerenity::ImageCodecPluginSerenity() = default; +ImageCodecPluginSerenity::~ImageCodecPluginSerenity() = default; -Optional ImageDecoderClientAdapter::decode_image(ReadonlyBytes bytes) +Optional ImageCodecPluginSerenity::decode_image(ReadonlyBytes bytes) { if (!m_client) { m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors(); @@ -28,7 +27,7 @@ Optional ImageDecoderClientAdapter::decode_ima return {}; auto result = result_or_empty.release_value(); - Web::ImageDecoding::DecodedImage decoded_image; + 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) { diff --git a/Userland/Services/WebContent/ImageCodecPluginSerenity.h b/Userland/Services/WebContent/ImageCodecPluginSerenity.h new file mode 100644 index 0000000000..42d967b0f1 --- /dev/null +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Dex♪ + * Copyright (c) 2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace ImageDecoderClient { +class Client; +} + +namespace WebContent { + +class ImageCodecPluginSerenity final : public Web::Platform::ImageCodecPlugin { +public: + ImageCodecPluginSerenity(); + virtual ~ImageCodecPluginSerenity() override; + + virtual Optional decode_image(ReadonlyBytes) override; + +private: + RefPtr m_client; +}; + +} diff --git a/Userland/Services/WebContent/main.cpp b/Userland/Services/WebContent/main.cpp index fccdf5380a..ce7c2c5266 100644 --- a/Userland/Services/WebContent/main.cpp +++ b/Userland/Services/WebContent/main.cpp @@ -6,16 +6,15 @@ #include "EventLoopPluginSerenity.h" #include "FontPluginSerenity.h" +#include "ImageCodecPluginSerenity.h" #include #include #include #include #include -#include #include #include #include -#include #include #include #include @@ -32,9 +31,9 @@ ErrorOr serenity_main(Main::Arguments) TRY(Core::System::unveil(nullptr, nullptr)); Web::Platform::EventLoopPlugin::install(*new WebContent::EventLoopPluginSerenity); + Web::Platform::ImageCodecPlugin::install(*new WebContent::ImageCodecPluginSerenity); Web::Platform::FontPlugin::install(*new WebContent::FontPluginSerenity); - Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create()); Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create())); Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index db0f2c5b7f..350d69be13 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -36,11 +36,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -235,26 +235,22 @@ private: Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto }; }; -class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder { +class ImageCodecPluginHeadless : public Web::Platform::ImageCodecPlugin { public: - static NonnullRefPtr create() - { - return adopt_ref(*new HeadlessImageDecoderClient()); - } + ImageCodecPluginHeadless() = default; + virtual ~ImageCodecPluginHeadless() override = default; - virtual ~HeadlessImageDecoderClient() override = default; - - virtual Optional decode_image(ReadonlyBytes data) override + virtual Optional decode_image(ReadonlyBytes data) override { auto decoder = Gfx::ImageDecoder::try_create(data); if (!decoder) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; + return Web::Platform::DecodedImage { false, 0, Vector {} }; if (!decoder->frame_count()) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; + return Web::Platform::DecodedImage { false, 0, Vector {} }; - Vector frames; + Vector frames; for (size_t i = 0; i < decoder->frame_count(); ++i) { auto frame_or_error = decoder->frame(i); if (frame_or_error.is_error()) { @@ -265,15 +261,12 @@ public: } } - return Web::ImageDecoding::DecodedImage { + return Web::Platform::DecodedImage { decoder->is_animated(), static_cast(decoder->loop_count()), frames, }; } - -private: - explicit HeadlessImageDecoderClient() = default; }; static HashTable> s_all_requests; @@ -675,7 +668,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::Yes); args_parser.parse(arguments); - Web::ImageDecoding::Decoder::initialize(HeadlessImageDecoderClient::create()); + Web::Platform::ImageCodecPlugin::install(*new ImageCodecPluginHeadless); Web::ResourceLoader::initialize(HeadlessRequestServer::create()); Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create());