1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +00:00

LibWeb: Abstract the image decoding via Web::ImageDecoding::Decoder

After this change, LibWeb now expects Web::ImageDecoding::Decoder to be
pre-initialized with a concrete implementation before using the webpage.
The previous implementation, based on the ImageDecoder service, has been
provided directly through an adapter in LibWebClient, and is now used as
the default value by WebContent.
This commit is contained in:
DexesTTP 2022-04-30 11:21:21 +02:00 committed by Andreas Kling
parent 962040b49c
commit 2198091bbc
11 changed files with 132 additions and 20 deletions

View file

@ -377,7 +377,7 @@ set(GENERATED_SOURCES
)
serenity_lib(LibWeb web)
target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibProtocol LibImageDecoderClient LibWasm LibXML)
target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibProtocol LibWasm LibXML)
link_with_unicode_data(LibWeb)
generate_js_wrappers(LibWeb)

View file

@ -155,7 +155,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
return false;
RefPtr<Gfx::Bitmap> favicon_bitmap;
auto decoded_image = Web::image_decoder_client().decode_image(resource()->encoded_data());
auto decoded_image = Web::ImageDecoding::Decoder::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;

View file

@ -1,23 +1,32 @@
/*
* 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 {
namespace Web::ImageDecoding {
ImageDecoderClient::Client& image_decoder_client()
static RefPtr<Decoder> s_decoder;
Decoder::Decoder() = default;
Decoder::~Decoder() = default;
void Decoder::initialize(RefPtr<Decoder>&& decoder)
{
static RefPtr<ImageDecoderClient::Client> image_decoder_client;
if (!image_decoder_client) {
image_decoder_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
image_decoder_client->on_death = [&] {
image_decoder_client = nullptr;
};
s_decoder = move(decoder);
}
Decoder& Decoder::the()
{
if (!s_decoder) [[unlikely]] {
dbgln("Web::ImageDecoding::Decoder was not initialized!");
VERIFY_NOT_REACHED();
}
return *image_decoder_client;
return *s_decoder;
}
}

View file

@ -1,15 +1,40 @@
/*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibImageDecoderClient/Client.h>
#include <AK/RefPtr.h>
#include <AK/Vector.h>
#include <LibGfx/Bitmap.h>
namespace Web {
namespace Web::ImageDecoding {
ImageDecoderClient::Client& image_decoder_client();
struct Frame {
RefPtr<Gfx::Bitmap> bitmap;
size_t duration { 0 };
};
struct DecodedImage {
bool is_animated { false };
u32 loop_count { 0 };
Vector<Frame> frames;
};
class Decoder : public RefCounted<Decoder> {
public:
virtual ~Decoder();
static void initialize(RefPtr<Decoder>&&);
static Decoder& the();
virtual Optional<DecodedImage> decode_image(ReadonlyBytes) = 0;
protected:
explicit Decoder();
};
}

View file

@ -75,8 +75,7 @@ static bool build_text_document(DOM::Document& document, ByteBuffer const& data)
static bool build_image_document(DOM::Document& document, ByteBuffer const& data)
{
NonnullRefPtr decoder = image_decoder_client();
auto image = decoder->decode_image(data);
auto image = ImageDecoding::Decoder::the().decode_image(data);
if (!image.has_value() || image->frames.is_empty())
return false;
auto const& frame = image->frames[0];
@ -209,7 +208,7 @@ bool FrameLoader::load(LoadRequest& request, Type type)
if (data.is_empty())
return;
RefPtr<Gfx::Bitmap> favicon_bitmap;
auto decoded_image = image_decoder_client().decode_image(data);
auto decoded_image = ImageDecoding::Decoder::the().decode_image(data);
if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
dbgln("Could not decode favicon {}", favicon_url);
} else {

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Function.h>
#include <LibGfx/Bitmap.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/ImageResource.h>
@ -46,8 +47,7 @@ void ImageResource::decode_if_needed() const
if (!m_decoded_frames.is_empty())
return;
NonnullRefPtr decoder = image_decoder_client();
auto image = decoder->decode_image(encoded_data());
auto image = ImageDecoding::Decoder::the().decode_image(encoded_data());
if (image.has_value()) {
m_loop_count = image.value().loop_count;

View file

@ -1,5 +1,6 @@
set(SOURCES
DOMTreeModel.cpp
ImageDecoderClientAdapter.cpp
OutOfProcessWebView.cpp
StylePropertiesModel.cpp
WebContentClient.cpp
@ -13,6 +14,6 @@ set(GENERATED_SOURCES
)
serenity_lib(LibWebView webview)
target_link_libraries(LibWebView LibGfx LibGUI LibIPC LibWeb)
target_link_libraries(LibWebView LibGfx LibGUI LibImageDecoderClient LibIPC LibWeb)
add_subdirectory(DumpLayoutTree)

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibImageDecoderClient/Client.h>
#include <LibWebView/ImageDecoderClientAdapter.h>
namespace WebView {
NonnullRefPtr<ImageDecoderClientAdapter> ImageDecoderClientAdapter::create()
{
return adopt_ref(*new ImageDecoderClientAdapter());
}
Optional<Web::ImageDecoding::DecodedImage> ImageDecoderClientAdapter::decode_image(ReadonlyBytes bytes)
{
if (!m_client) {
m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
m_client->on_death = [&] {
m_client = nullptr;
};
}
auto result_or_empty = m_client->decode_image(bytes);
if (!result_or_empty.has_value())
return {};
auto result = result_or_empty.release_value();
Web::ImageDecoding::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);
}
return decoded_image;
}
}

View file

@ -0,0 +1,32 @@
/*
* 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

@ -1,6 +1,7 @@
#include <AK/URL.h>
#include <LibCore/AnonymousBuffer.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibWeb/Cookie/ParsedCookie.h>
endpoint WebContentClient
{

View file

@ -9,6 +9,8 @@
#include <LibCore/System.h>
#include <LibIPC/SingleServer.h>
#include <LibMain/Main.h>
#include <LibWeb/ImageDecoding.h>
#include <LibWebView/ImageDecoderClientAdapter.h>
#include <WebContent/ConnectionFromClient.h>
ErrorOr<int> serenity_main(Main::Arguments)
@ -22,6 +24,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
TRY(Core::System::unveil("/tmp/portal/websocket", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create());
auto client = TRY(IPC::take_over_accepted_client_from_system_server<WebContent::ConnectionFromClient>());
return event_loop.exec();
}