Skip to content

Commit 2198091

Browse files
Dexesttpawesomekling
authored andcommitted
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.
1 parent 962040b commit 2198091

File tree

11 files changed

+132
-20
lines changed

11 files changed

+132
-20
lines changed

Userland/Libraries/LibWeb/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ set(GENERATED_SOURCES
377377
)
378378

379379
serenity_lib(LibWeb web)
380-
target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibProtocol LibImageDecoderClient LibWasm LibXML)
380+
target_link_libraries(LibWeb LibCore LibJS LibMarkdown LibGemini LibGUI LibGfx LibTextCodec LibProtocol LibWasm LibXML)
381381
link_with_unicode_data(LibWeb)
382382

383383
generate_js_wrappers(LibWeb)

Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
155155
return false;
156156

157157
RefPtr<Gfx::Bitmap> favicon_bitmap;
158-
auto decoded_image = Web::image_decoder_client().decode_image(resource()->encoded_data());
158+
auto decoded_image = Web::ImageDecoding::Decoder::the().decode_image(resource()->encoded_data());
159159
if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
160160
dbgln("Could not decode favicon {}", resource()->url());
161161
return false;
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
/*
22
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
3+
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
34
*
45
* SPDX-License-Identifier: BSD-2-Clause
56
*/
67

78
#include <LibWeb/ImageDecoding.h>
89

9-
namespace Web {
10+
namespace Web::ImageDecoding {
1011

11-
ImageDecoderClient::Client& image_decoder_client()
12+
static RefPtr<Decoder> s_decoder;
13+
14+
Decoder::Decoder() = default;
15+
16+
Decoder::~Decoder() = default;
17+
18+
void Decoder::initialize(RefPtr<Decoder>&& decoder)
19+
{
20+
s_decoder = move(decoder);
21+
}
22+
23+
Decoder& Decoder::the()
1224
{
13-
static RefPtr<ImageDecoderClient::Client> image_decoder_client;
14-
if (!image_decoder_client) {
15-
image_decoder_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
16-
image_decoder_client->on_death = [&] {
17-
image_decoder_client = nullptr;
18-
};
25+
if (!s_decoder) [[unlikely]] {
26+
dbgln("Web::ImageDecoding::Decoder was not initialized!");
27+
VERIFY_NOT_REACHED();
1928
}
20-
return *image_decoder_client;
29+
return *s_decoder;
2130
}
2231

2332
}
Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
11
/*
22
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
3+
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
34
*
45
* SPDX-License-Identifier: BSD-2-Clause
56
*/
67

78
#pragma once
89

9-
#include <LibImageDecoderClient/Client.h>
10+
#include <AK/RefPtr.h>
11+
#include <AK/Vector.h>
12+
#include <LibGfx/Bitmap.h>
1013

11-
namespace Web {
14+
namespace Web::ImageDecoding {
1215

13-
ImageDecoderClient::Client& image_decoder_client();
16+
struct Frame {
17+
RefPtr<Gfx::Bitmap> bitmap;
18+
size_t duration { 0 };
19+
};
20+
21+
struct DecodedImage {
22+
bool is_animated { false };
23+
u32 loop_count { 0 };
24+
Vector<Frame> frames;
25+
};
26+
27+
class Decoder : public RefCounted<Decoder> {
28+
public:
29+
virtual ~Decoder();
30+
31+
static void initialize(RefPtr<Decoder>&&);
32+
static Decoder& the();
33+
34+
virtual Optional<DecodedImage> decode_image(ReadonlyBytes) = 0;
35+
36+
protected:
37+
explicit Decoder();
38+
};
1439

1540
}

Userland/Libraries/LibWeb/Loader/FrameLoader.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ static bool build_text_document(DOM::Document& document, ByteBuffer const& data)
7575

7676
static bool build_image_document(DOM::Document& document, ByteBuffer const& data)
7777
{
78-
NonnullRefPtr decoder = image_decoder_client();
79-
auto image = decoder->decode_image(data);
78+
auto image = ImageDecoding::Decoder::the().decode_image(data);
8079
if (!image.has_value() || image->frames.is_empty())
8180
return false;
8281
auto const& frame = image->frames[0];
@@ -209,7 +208,7 @@ bool FrameLoader::load(LoadRequest& request, Type type)
209208
if (data.is_empty())
210209
return;
211210
RefPtr<Gfx::Bitmap> favicon_bitmap;
212-
auto decoded_image = image_decoder_client().decode_image(data);
211+
auto decoded_image = ImageDecoding::Decoder::the().decode_image(data);
213212
if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
214213
dbgln("Could not decode favicon {}", favicon_url);
215214
} else {

Userland/Libraries/LibWeb/Loader/ImageResource.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* SPDX-License-Identifier: BSD-2-Clause
55
*/
66

7+
#include <AK/Function.h>
78
#include <LibGfx/Bitmap.h>
89
#include <LibWeb/ImageDecoding.h>
910
#include <LibWeb/Loader/ImageResource.h>
@@ -46,8 +47,7 @@ void ImageResource::decode_if_needed() const
4647
if (!m_decoded_frames.is_empty())
4748
return;
4849

49-
NonnullRefPtr decoder = image_decoder_client();
50-
auto image = decoder->decode_image(encoded_data());
50+
auto image = ImageDecoding::Decoder::the().decode_image(encoded_data());
5151

5252
if (image.has_value()) {
5353
m_loop_count = image.value().loop_count;

Userland/Libraries/LibWebView/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
set(SOURCES
22
DOMTreeModel.cpp
3+
ImageDecoderClientAdapter.cpp
34
OutOfProcessWebView.cpp
45
StylePropertiesModel.cpp
56
WebContentClient.cpp
@@ -13,6 +14,6 @@ set(GENERATED_SOURCES
1314
)
1415

1516
serenity_lib(LibWebView webview)
16-
target_link_libraries(LibWebView LibGfx LibGUI LibIPC LibWeb)
17+
target_link_libraries(LibWebView LibGfx LibGUI LibImageDecoderClient LibIPC LibWeb)
1718

1819
add_subdirectory(DumpLayoutTree)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <LibImageDecoderClient/Client.h>
8+
#include <LibWebView/ImageDecoderClientAdapter.h>
9+
10+
namespace WebView {
11+
12+
NonnullRefPtr<ImageDecoderClientAdapter> ImageDecoderClientAdapter::create()
13+
{
14+
return adopt_ref(*new ImageDecoderClientAdapter());
15+
}
16+
17+
Optional<Web::ImageDecoding::DecodedImage> ImageDecoderClientAdapter::decode_image(ReadonlyBytes bytes)
18+
{
19+
if (!m_client) {
20+
m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
21+
m_client->on_death = [&] {
22+
m_client = nullptr;
23+
};
24+
}
25+
26+
auto result_or_empty = m_client->decode_image(bytes);
27+
if (!result_or_empty.has_value())
28+
return {};
29+
auto result = result_or_empty.release_value();
30+
31+
Web::ImageDecoding::DecodedImage decoded_image;
32+
decoded_image.is_animated = result.is_animated;
33+
decoded_image.loop_count = result.loop_count;
34+
for (auto const& frame : result.frames) {
35+
decoded_image.frames.empend(move(frame.bitmap), frame.duration);
36+
}
37+
38+
return decoded_image;
39+
}
40+
41+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <AK/NonnullRefPtr.h>
10+
#include <LibWeb/ImageDecoding.h>
11+
12+
namespace ImageDecoderClient {
13+
class Client;
14+
}
15+
16+
namespace WebView {
17+
18+
class ImageDecoderClientAdapter : public Web::ImageDecoding::Decoder {
19+
public:
20+
static NonnullRefPtr<ImageDecoderClientAdapter> create();
21+
22+
virtual ~ImageDecoderClientAdapter() override = default;
23+
24+
virtual Optional<Web::ImageDecoding::DecodedImage> decode_image(ReadonlyBytes) override;
25+
26+
private:
27+
explicit ImageDecoderClientAdapter() = default;
28+
29+
RefPtr<ImageDecoderClient::Client> m_client;
30+
};
31+
32+
}

Userland/Services/WebContent/WebContentClient.ipc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <AK/URL.h>
22
#include <LibCore/AnonymousBuffer.h>
33
#include <LibGfx/ShareableBitmap.h>
4+
#include <LibWeb/Cookie/ParsedCookie.h>
45

56
endpoint WebContentClient
67
{

0 commit comments

Comments
 (0)