1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:18:12 +00:00

LibWeb+LibWebView+WebContent: Add Web::Platform::ImageCodecPlugin

This replaces the previous Web::ImageDecoding::Decoder interface.
While we're doing this, also move the SerenityOS implementation of this
interface from LibWebView to WebContent. That means we no longer have to
link with LibImageDecoderClient in applications that use a web view.
This commit is contained in:
Andreas Kling 2022-09-16 15:01:47 +02:00
parent 412b2313f3
commit cd7262ee56
14 changed files with 95 additions and 113 deletions

View file

@ -268,7 +268,6 @@ set(SOURCES
HTML/WorkerLocation.cpp HTML/WorkerLocation.cpp
HTML/WorkerNavigator.cpp HTML/WorkerNavigator.cpp
HighResolutionTime/Performance.cpp HighResolutionTime/Performance.cpp
ImageDecoding.cpp
Infra/ByteSequences.cpp Infra/ByteSequences.cpp
IntersectionObserver/IntersectionObserver.cpp IntersectionObserver/IntersectionObserver.cpp
Layout/BlockContainer.cpp Layout/BlockContainer.cpp
@ -355,6 +354,7 @@ set(SOURCES
Painting/TextPaintable.cpp Painting/TextPaintable.cpp
Platform/EventLoopPlugin.cpp Platform/EventLoopPlugin.cpp
Platform/FontPlugin.cpp Platform/FontPlugin.cpp
Platform/ImageCodecPlugin.cpp
Platform/Timer.cpp Platform/Timer.cpp
RequestIdleCallback/IdleDeadline.cpp RequestIdleCallback/IdleDeadline.cpp
ResizeObserver/ResizeObserver.cpp ResizeObserver/ResizeObserver.cpp

View file

@ -12,9 +12,9 @@
#include <LibWeb/CSS/Parser/Parser.h> #include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLLinkElement.h> #include <LibWeb/HTML/HTMLLinkElement.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Page/Page.h> #include <LibWeb/Page/Page.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
namespace Web::HTML { namespace Web::HTML {
@ -156,7 +156,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
return false; return false;
RefPtr<Gfx::Bitmap> favicon_bitmap; RefPtr<Gfx::Bitmap> 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()) { if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
dbgln("Could not decode favicon {}", resource()->url()); dbgln("Could not decode favicon {}", resource()->url());
return false; return false;

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/ImageDecoding.h>
namespace Web::ImageDecoding {
static RefPtr<Decoder> s_decoder;
Decoder::Decoder() = default;
Decoder::~Decoder() = default;
void Decoder::initialize(RefPtr<Decoder>&& 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;
}
}

View file

@ -19,10 +19,10 @@
#include <LibWeb/HTML/HTMLIFrameElement.h> #include <LibWeb/HTML/HTMLIFrameElement.h>
#include <LibWeb/HTML/NavigationParams.h> #include <LibWeb/HTML/NavigationParams.h>
#include <LibWeb/HTML/Parser/HTMLParser.h> #include <LibWeb/HTML/Parser/HTMLParser.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/FrameLoader.h> #include <LibWeb/Loader/FrameLoader.h>
#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Page/Page.h> #include <LibWeb/Page/Page.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
#include <LibWeb/XML/XMLDocumentBuilder.h> #include <LibWeb/XML/XMLDocumentBuilder.h>
namespace Web { 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) 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()) if (!image.has_value() || image->frames.is_empty())
return false; return false;
auto const& frame = image->frames[0]; auto const& frame = image->frames[0];
@ -215,7 +215,7 @@ bool FrameLoader::load(LoadRequest& request, Type type)
if (data.is_empty()) if (data.is_empty())
return; return;
RefPtr<Gfx::Bitmap> favicon_bitmap; RefPtr<Gfx::Bitmap> 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()) { if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
dbgln("Could not decode favicon {}", favicon_url); dbgln("Could not decode favicon {}", favicon_url);
} else { } else {

View file

@ -6,8 +6,8 @@
#include <AK/Function.h> #include <AK/Function.h>
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/ImageResource.h> #include <LibWeb/Loader/ImageResource.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
namespace Web { namespace Web {
@ -47,7 +47,7 @@ void ImageResource::decode_if_needed() const
if (!m_decoded_frames.is_empty()) if (!m_decoded_frames.is_empty())
return; return;
auto image = ImageDecoding::Decoder::the().decode_image(encoded_data()); auto image = Platform::ImageCodecPlugin::the().decode_image(encoded_data());
if (image.has_value()) { if (image.has_value()) {
m_loop_count = image.value().loop_count; m_loop_count = image.value().loop_count;

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Platform/ImageCodecPlugin.h>
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;
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com> * Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -9,9 +9,9 @@
#include <AK/RefPtr.h> #include <AK/RefPtr.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibGfx/Bitmap.h> #include <LibGfx/Forward.h>
namespace Web::ImageDecoding { namespace Web::Platform {
struct Frame { struct Frame {
RefPtr<Gfx::Bitmap> bitmap; RefPtr<Gfx::Bitmap> bitmap;
@ -24,17 +24,14 @@ struct DecodedImage {
Vector<Frame> frames; Vector<Frame> frames;
}; };
class Decoder : public RefCounted<Decoder> { class ImageCodecPlugin {
public: public:
virtual ~Decoder(); static ImageCodecPlugin& the();
static void install(ImageCodecPlugin&);
static void initialize(RefPtr<Decoder>&&); virtual ~ImageCodecPlugin();
static Decoder& the();
virtual Optional<DecodedImage> decode_image(ReadonlyBytes) = 0; virtual Optional<DecodedImage> decode_image(ReadonlyBytes) = 0;
protected:
explicit Decoder();
}; };
} }

View file

@ -1,6 +1,5 @@
set(SOURCES set(SOURCES
DOMTreeModel.cpp DOMTreeModel.cpp
ImageDecoderClientAdapter.cpp
OutOfProcessWebView.cpp OutOfProcessWebView.cpp
RequestServerAdapter.cpp RequestServerAdapter.cpp
StylePropertiesModel.cpp StylePropertiesModel.cpp
@ -16,6 +15,6 @@ set(GENERATED_SOURCES
) )
serenity_lib(LibWebView webview) 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) add_subdirectory(DumpLayoutTree)

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/NonnullRefPtr.h>
#include <LibWeb/ImageDecoding.h>
namespace ImageDecoderClient {
class Client;
}
namespace WebView {
class ImageDecoderClientAdapter : public Web::ImageDecoding::Decoder {
public:
static NonnullRefPtr<ImageDecoderClientAdapter> create();
virtual ~ImageDecoderClientAdapter() override = default;
virtual Optional<Web::ImageDecoding::DecodedImage> decode_image(ReadonlyBytes) override;
private:
explicit ImageDecoderClientAdapter() = default;
RefPtr<ImageDecoderClient::Client> m_client;
};
}

View file

@ -12,6 +12,7 @@ set(SOURCES
ConsoleGlobalObject.cpp ConsoleGlobalObject.cpp
EventLoopPluginSerenity.cpp EventLoopPluginSerenity.cpp
FontPluginSerenity.cpp FontPluginSerenity.cpp
ImageCodecPluginSerenity.cpp
PageHost.cpp PageHost.cpp
TimerSerenity.cpp TimerSerenity.cpp
WebContentClientEndpoint.h WebContentClientEndpoint.h
@ -21,5 +22,5 @@ set(SOURCES
) )
serenity_bin(WebContent) 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) link_with_locale_data(WebContent)

View file

@ -1,20 +1,19 @@
/* /*
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com> * Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include "ImageCodecPluginSerenity.h"
#include <LibImageDecoderClient/Client.h> #include <LibImageDecoderClient/Client.h>
#include <LibWebView/ImageDecoderClientAdapter.h>
namespace WebView { namespace WebContent {
NonnullRefPtr<ImageDecoderClientAdapter> ImageDecoderClientAdapter::create() ImageCodecPluginSerenity::ImageCodecPluginSerenity() = default;
{ ImageCodecPluginSerenity::~ImageCodecPluginSerenity() = default;
return adopt_ref(*new ImageDecoderClientAdapter());
}
Optional<Web::ImageDecoding::DecodedImage> ImageDecoderClientAdapter::decode_image(ReadonlyBytes bytes) Optional<Web::Platform::DecodedImage> ImageCodecPluginSerenity::decode_image(ReadonlyBytes bytes)
{ {
if (!m_client) { if (!m_client) {
m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors(); m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
@ -28,7 +27,7 @@ Optional<Web::ImageDecoding::DecodedImage> ImageDecoderClientAdapter::decode_ima
return {}; return {};
auto result = result_or_empty.release_value(); 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.is_animated = result.is_animated;
decoded_image.loop_count = result.loop_count; decoded_image.loop_count = result.loop_count;
for (auto const& frame : result.frames) { for (auto const& frame : result.frames) {

View file

@ -0,0 +1,30 @@
/*
* 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 <AK/RefPtr.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
namespace ImageDecoderClient {
class Client;
}
namespace WebContent {
class ImageCodecPluginSerenity final : public Web::Platform::ImageCodecPlugin {
public:
ImageCodecPluginSerenity();
virtual ~ImageCodecPluginSerenity() override;
virtual Optional<Web::Platform::DecodedImage> decode_image(ReadonlyBytes) override;
private:
RefPtr<ImageDecoderClient::Client> m_client;
};
}

View file

@ -6,16 +6,15 @@
#include "EventLoopPluginSerenity.h" #include "EventLoopPluginSerenity.h"
#include "FontPluginSerenity.h" #include "FontPluginSerenity.h"
#include "ImageCodecPluginSerenity.h"
#include <LibCore/EventLoop.h> #include <LibCore/EventLoop.h>
#include <LibCore/LocalServer.h> #include <LibCore/LocalServer.h>
#include <LibCore/System.h> #include <LibCore/System.h>
#include <LibIPC/SingleServer.h> #include <LibIPC/SingleServer.h>
#include <LibMain/Main.h> #include <LibMain/Main.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Platform/EventLoopPlugin.h> #include <LibWeb/Platform/EventLoopPlugin.h>
#include <LibWeb/WebSockets/WebSocket.h> #include <LibWeb/WebSockets/WebSocket.h>
#include <LibWebView/ImageDecoderClientAdapter.h>
#include <LibWebView/RequestServerAdapter.h> #include <LibWebView/RequestServerAdapter.h>
#include <LibWebView/WebSocketClientAdapter.h> #include <LibWebView/WebSocketClientAdapter.h>
#include <WebContent/ConnectionFromClient.h> #include <WebContent/ConnectionFromClient.h>
@ -32,9 +31,9 @@ ErrorOr<int> serenity_main(Main::Arguments)
TRY(Core::System::unveil(nullptr, nullptr)); TRY(Core::System::unveil(nullptr, nullptr));
Web::Platform::EventLoopPlugin::install(*new WebContent::EventLoopPluginSerenity); Web::Platform::EventLoopPlugin::install(*new WebContent::EventLoopPluginSerenity);
Web::Platform::ImageCodecPlugin::install(*new WebContent::ImageCodecPluginSerenity);
Web::Platform::FontPlugin::install(*new WebContent::FontPluginSerenity); Web::Platform::FontPlugin::install(*new WebContent::FontPluginSerenity);
Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create());
Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create())); Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create()));
Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create()));

View file

@ -36,11 +36,11 @@
#include <LibWeb/Cookie/ParsedCookie.h> #include <LibWeb/Cookie/ParsedCookie.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/BrowsingContext.h> #include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Layout/InitialContainingBlock.h> #include <LibWeb/Layout/InitialContainingBlock.h>
#include <LibWeb/Loader/ResourceLoader.h> #include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/Page/Page.h> #include <LibWeb/Page/Page.h>
#include <LibWeb/Painting/PaintableBox.h> #include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Platform/ImageCodecPlugin.h>
#include <LibWeb/WebSockets/WebSocket.h> #include <LibWeb/WebSockets/WebSocket.h>
#include <LibWebSocket/ConnectionInfo.h> #include <LibWebSocket/ConnectionInfo.h>
#include <LibWebSocket/Message.h> #include <LibWebSocket/Message.h>
@ -235,26 +235,22 @@ private:
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto }; Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
}; };
class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder { class ImageCodecPluginHeadless : public Web::Platform::ImageCodecPlugin {
public: public:
static NonnullRefPtr<HeadlessImageDecoderClient> create() ImageCodecPluginHeadless() = default;
{ virtual ~ImageCodecPluginHeadless() override = default;
return adopt_ref(*new HeadlessImageDecoderClient());
}
virtual ~HeadlessImageDecoderClient() override = default; virtual Optional<Web::Platform::DecodedImage> decode_image(ReadonlyBytes data) override
virtual Optional<Web::ImageDecoding::DecodedImage> decode_image(ReadonlyBytes data) override
{ {
auto decoder = Gfx::ImageDecoder::try_create(data); auto decoder = Gfx::ImageDecoder::try_create(data);
if (!decoder) if (!decoder)
return Web::ImageDecoding::DecodedImage { false, 0, Vector<Web::ImageDecoding::Frame> {} }; return Web::Platform::DecodedImage { false, 0, Vector<Web::Platform::Frame> {} };
if (!decoder->frame_count()) if (!decoder->frame_count())
return Web::ImageDecoding::DecodedImage { false, 0, Vector<Web::ImageDecoding::Frame> {} }; return Web::Platform::DecodedImage { false, 0, Vector<Web::Platform::Frame> {} };
Vector<Web::ImageDecoding::Frame> frames; Vector<Web::Platform::Frame> frames;
for (size_t i = 0; i < decoder->frame_count(); ++i) { for (size_t i = 0; i < decoder->frame_count(); ++i) {
auto frame_or_error = decoder->frame(i); auto frame_or_error = decoder->frame(i);
if (frame_or_error.is_error()) { if (frame_or_error.is_error()) {
@ -265,15 +261,12 @@ public:
} }
} }
return Web::ImageDecoding::DecodedImage { return Web::Platform::DecodedImage {
decoder->is_animated(), decoder->is_animated(),
static_cast<u32>(decoder->loop_count()), static_cast<u32>(decoder->loop_count()),
frames, frames,
}; };
} }
private:
explicit HeadlessImageDecoderClient() = default;
}; };
static HashTable<RefPtr<Web::ResourceLoaderConnectorRequest>> s_all_requests; static HashTable<RefPtr<Web::ResourceLoaderConnectorRequest>> s_all_requests;
@ -675,7 +668,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::Yes); args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::Yes);
args_parser.parse(arguments); args_parser.parse(arguments);
Web::ImageDecoding::Decoder::initialize(HeadlessImageDecoderClient::create()); Web::Platform::ImageCodecPlugin::install(*new ImageCodecPluginHeadless);
Web::ResourceLoader::initialize(HeadlessRequestServer::create()); Web::ResourceLoader::initialize(HeadlessRequestServer::create());
Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create()); Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create());