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:
parent
962040b49c
commit
2198091bbc
11 changed files with 132 additions and 20 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
41
Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp
Normal file
41
Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
32
Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h
Normal file
32
Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h
Normal 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;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include <AK/URL.h>
|
||||
#include <LibCore/AnonymousBuffer.h>
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
|
||||
endpoint WebContentClient
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue