diff --git a/Ladybird/WebView.cpp b/Ladybird/WebView.cpp index 88f2f6f0f1..e3d808c1b5 100644 --- a/Ladybird/WebView.cpp +++ b/Ladybird/WebView.cpp @@ -833,6 +833,59 @@ void WebView::resizeEvent(QResizeEvent* event) m_page_client->set_viewport_rect(rect); } +static Optional decode_image_with_qt(ReadonlyBytes data) +{ + auto image = QImage::fromData(data.data(), static_cast(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 frames; + + frames.append(Web::ImageDecoding::Frame { + bitmap, + }); + return Web::ImageDecoding::DecodedImage { + false, + 0, + move(frames), + }; +} + +static Optional decode_image_with_libgfx(ReadonlyBytes data) +{ + auto decoder = Gfx::ImageDecoder::try_create(data); + + if (!decoder || !decoder->frame_count()) { + return {}; + } + + bool had_errors = false; + Vector 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(frame.duration) }); + } + } + + if (had_errors) + return {}; + + return Web::ImageDecoding::DecodedImage { + decoder->is_animated(), + static_cast(decoder->loop_count()), + move(frames), + }; +} + class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder { public: static NonnullRefPtr create() @@ -844,30 +897,10 @@ public: virtual Optional decode_image(ReadonlyBytes data) override { - auto decoder = Gfx::ImageDecoder::try_create(data); - - if (!decoder) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; - - if (!decoder->frame_count()) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; - - Vector 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 }); - } else { - auto frame = frame_or_error.release_value(); - frames.append({ move(frame.image), static_cast(frame.duration) }); - } - } - - return Web::ImageDecoding::DecodedImage { - decoder->is_animated(), - static_cast(decoder->loop_count()), - frames, - }; + auto image = decode_image_with_libgfx(data); + if (image.has_value()) + return image; + return decode_image_with_qt(data); } private: