mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-21 18:15:58 +00:00
Ladybird: Implement the Web::Platform::ImageCodecPlugin interface
...and move it to separate files while we're at it.
This commit is contained in:
parent
4334929323
commit
ef757f33da
|
@ -51,6 +51,7 @@ set(SOURCES
|
||||||
CookieJar.cpp
|
CookieJar.cpp
|
||||||
EventLoopPluginQt.cpp
|
EventLoopPluginQt.cpp
|
||||||
FontPluginQt.cpp
|
FontPluginQt.cpp
|
||||||
|
ImageCodecPluginLadybird.cpp
|
||||||
RequestManagerQt.cpp
|
RequestManagerQt.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
WebView.cpp
|
WebView.cpp
|
||||||
|
|
80
Ladybird/ImageCodecPluginLadybird.cpp
Normal file
80
Ladybird/ImageCodecPluginLadybird.cpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com>
|
||||||
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AK_DONT_REPLACE_STD
|
||||||
|
|
||||||
|
#include "ImageCodecPluginLadybird.h"
|
||||||
|
#include <LibGfx/Bitmap.h>
|
||||||
|
#include <LibGfx/ImageDecoder.h>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
namespace Ladybird {
|
||||||
|
|
||||||
|
ImageCodecPluginLadybird::~ImageCodecPluginLadybird() = default;
|
||||||
|
|
||||||
|
static Optional<Web::Platform::DecodedImage> decode_image_with_qt(ReadonlyBytes data)
|
||||||
|
{
|
||||||
|
auto image = QImage::fromData(data.data(), static_cast<int>(data.size()));
|
||||||
|
if (image.isNull())
|
||||||
|
return {};
|
||||||
|
image = image.convertToFormat(QImage::Format::Format_ARGB32);
|
||||||
|
auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height())));
|
||||||
|
for (int y = 0; y < image.height(); ++y) {
|
||||||
|
memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4);
|
||||||
|
}
|
||||||
|
Vector<Web::Platform::Frame> frames;
|
||||||
|
|
||||||
|
frames.append(Web::Platform::Frame {
|
||||||
|
bitmap,
|
||||||
|
});
|
||||||
|
return Web::Platform::DecodedImage {
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
move(frames),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Optional<Web::Platform::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data)
|
||||||
|
{
|
||||||
|
auto decoder = Gfx::ImageDecoder::try_create(data);
|
||||||
|
|
||||||
|
if (!decoder || !decoder->frame_count()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool had_errors = false;
|
||||||
|
Vector<Web::Platform::Frame> frames;
|
||||||
|
for (size_t i = 0; i < decoder->frame_count(); ++i) {
|
||||||
|
auto frame_or_error = decoder->frame(i);
|
||||||
|
if (frame_or_error.is_error()) {
|
||||||
|
frames.append({ {}, 0 });
|
||||||
|
had_errors = true;
|
||||||
|
} else {
|
||||||
|
auto frame = frame_or_error.release_value();
|
||||||
|
frames.append({ move(frame.image), static_cast<size_t>(frame.duration) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (had_errors)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return Web::Platform::DecodedImage {
|
||||||
|
decoder->is_animated(),
|
||||||
|
static_cast<u32>(decoder->loop_count()),
|
||||||
|
move(frames),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Web::Platform::DecodedImage> ImageCodecPluginLadybird::decode_image(ReadonlyBytes data)
|
||||||
|
{
|
||||||
|
auto image = decode_image_with_libgfx(data);
|
||||||
|
if (image.has_value())
|
||||||
|
return image;
|
||||||
|
return decode_image_with_qt(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
Ladybird/ImageCodecPluginLadybird.h
Normal file
22
Ladybird/ImageCodecPluginLadybird.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* 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 <LibWeb/Platform/ImageCodecPlugin.h>
|
||||||
|
|
||||||
|
namespace Ladybird {
|
||||||
|
|
||||||
|
class ImageCodecPluginLadybird final : public Web::Platform::ImageCodecPlugin {
|
||||||
|
public:
|
||||||
|
ImageCodecPluginLadybird() = default;
|
||||||
|
virtual ~ImageCodecPluginLadybird() override;
|
||||||
|
|
||||||
|
virtual Optional<Web::Platform::DecodedImage> decode_image(ReadonlyBytes data) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include "CookieJar.h"
|
#include "CookieJar.h"
|
||||||
#include "EventLoopPluginQt.h"
|
#include "EventLoopPluginQt.h"
|
||||||
#include "FontPluginQt.h"
|
#include "FontPluginQt.h"
|
||||||
|
#include "ImageCodecPluginLadybird.h"
|
||||||
#include "RequestManagerQt.h"
|
#include "RequestManagerQt.h"
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
#include <LibCore/Timer.h>
|
#include <LibCore/Timer.h>
|
||||||
#include <LibGfx/Bitmap.h>
|
#include <LibGfx/Bitmap.h>
|
||||||
#include <LibGfx/Font/FontDatabase.h>
|
#include <LibGfx/Font/FontDatabase.h>
|
||||||
#include <LibGfx/ImageDecoder.h>
|
|
||||||
#include <LibGfx/PNGWriter.h>
|
#include <LibGfx/PNGWriter.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
#include <LibJS/Runtime/ConsoleObject.h>
|
#include <LibJS/Runtime/ConsoleObject.h>
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
||||||
#include <LibWeb/HTML/Storage.h>
|
#include <LibWeb/HTML/Storage.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/Window.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>
|
||||||
|
@ -654,80 +653,6 @@ void WebView::resizeEvent(QResizeEvent* event)
|
||||||
m_page_client->set_viewport_rect(rect);
|
m_page_client->set_viewport_rect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<Web::ImageDecoding::DecodedImage> decode_image_with_qt(ReadonlyBytes data)
|
|
||||||
{
|
|
||||||
auto image = QImage::fromData(data.data(), static_cast<int>(data.size()));
|
|
||||||
if (image.isNull())
|
|
||||||
return {};
|
|
||||||
image = image.convertToFormat(QImage::Format::Format_ARGB32);
|
|
||||||
auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height())));
|
|
||||||
for (int y = 0; y < image.height(); ++y) {
|
|
||||||
memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4);
|
|
||||||
}
|
|
||||||
Vector<Web::ImageDecoding::Frame> frames;
|
|
||||||
|
|
||||||
frames.append(Web::ImageDecoding::Frame {
|
|
||||||
bitmap,
|
|
||||||
});
|
|
||||||
return Web::ImageDecoding::DecodedImage {
|
|
||||||
false,
|
|
||||||
0,
|
|
||||||
move(frames),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static Optional<Web::ImageDecoding::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data)
|
|
||||||
{
|
|
||||||
auto decoder = Gfx::ImageDecoder::try_create(data);
|
|
||||||
|
|
||||||
if (!decoder || !decoder->frame_count()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool had_errors = false;
|
|
||||||
Vector<Web::ImageDecoding::Frame> frames;
|
|
||||||
for (size_t i = 0; i < decoder->frame_count(); ++i) {
|
|
||||||
auto frame_or_error = decoder->frame(i);
|
|
||||||
if (frame_or_error.is_error()) {
|
|
||||||
frames.append({ {}, 0 });
|
|
||||||
had_errors = true;
|
|
||||||
} else {
|
|
||||||
auto frame = frame_or_error.release_value();
|
|
||||||
frames.append({ move(frame.image), static_cast<size_t>(frame.duration) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (had_errors)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return Web::ImageDecoding::DecodedImage {
|
|
||||||
decoder->is_animated(),
|
|
||||||
static_cast<u32>(decoder->loop_count()),
|
|
||||||
move(frames),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder {
|
|
||||||
public:
|
|
||||||
static NonnullRefPtr<HeadlessImageDecoderClient> create()
|
|
||||||
{
|
|
||||||
return adopt_ref(*new HeadlessImageDecoderClient());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~HeadlessImageDecoderClient() override = default;
|
|
||||||
|
|
||||||
virtual Optional<Web::ImageDecoding::DecodedImage> decode_image(ReadonlyBytes data) override
|
|
||||||
{
|
|
||||||
auto image = decode_image_with_libgfx(data);
|
|
||||||
if (image.has_value())
|
|
||||||
return image;
|
|
||||||
return decode_image_with_qt(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit HeadlessImageDecoderClient() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HeadlessWebSocketClientManager : public Web::WebSockets::WebSocketClientManager {
|
class HeadlessWebSocketClientManager : public Web::WebSockets::WebSocketClientManager {
|
||||||
public:
|
public:
|
||||||
class HeadlessWebSocket
|
class HeadlessWebSocket
|
||||||
|
@ -851,8 +776,8 @@ static void platform_init()
|
||||||
void initialize_web_engine()
|
void initialize_web_engine()
|
||||||
{
|
{
|
||||||
Web::Platform::EventLoopPlugin::install(*new Ladybird::EventLoopPluginQt);
|
Web::Platform::EventLoopPlugin::install(*new Ladybird::EventLoopPluginQt);
|
||||||
|
Web::Platform::ImageCodecPlugin::install(*new Ladybird::ImageCodecPluginLadybird);
|
||||||
|
|
||||||
Web::ImageDecoding::Decoder::initialize(HeadlessImageDecoderClient::create());
|
|
||||||
Web::ResourceLoader::initialize(RequestManagerQt::create());
|
Web::ResourceLoader::initialize(RequestManagerQt::create());
|
||||||
Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create());
|
Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue