Serenity Operating System
at master 80 lines 2.3 kB view raw
1/* 2 * Copyright (c) 2022, Dex♪ <dexes.ttp@gmail.com> 3 * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#define AK_DONT_REPLACE_STD 9 10#include "ImageCodecPluginLadybird.h" 11#include <LibGfx/Bitmap.h> 12#include <LibGfx/ImageDecoder.h> 13#include <QImage> 14 15namespace Ladybird { 16 17ImageCodecPluginLadybird::~ImageCodecPluginLadybird() = default; 18 19static Optional<Web::Platform::DecodedImage> decode_image_with_qt(ReadonlyBytes data) 20{ 21 auto image = QImage::fromData(data.data(), static_cast<int>(data.size())); 22 if (image.isNull()) 23 return {}; 24 image = image.convertToFormat(QImage::Format::Format_ARGB32); 25 auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height()))); 26 for (int y = 0; y < image.height(); ++y) { 27 memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4); 28 } 29 Vector<Web::Platform::Frame> frames; 30 31 frames.append(Web::Platform::Frame { 32 bitmap, 33 }); 34 return Web::Platform::DecodedImage { 35 false, 36 0, 37 move(frames), 38 }; 39} 40 41static Optional<Web::Platform::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data) 42{ 43 auto decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(data); 44 45 if (!decoder || !decoder->frame_count()) { 46 return {}; 47 } 48 49 bool had_errors = false; 50 Vector<Web::Platform::Frame> frames; 51 for (size_t i = 0; i < decoder->frame_count(); ++i) { 52 auto frame_or_error = decoder->frame(i); 53 if (frame_or_error.is_error()) { 54 frames.append({ {}, 0 }); 55 had_errors = true; 56 } else { 57 auto frame = frame_or_error.release_value(); 58 frames.append({ move(frame.image), static_cast<size_t>(frame.duration) }); 59 } 60 } 61 62 if (had_errors) 63 return {}; 64 65 return Web::Platform::DecodedImage { 66 decoder->is_animated(), 67 static_cast<u32>(decoder->loop_count()), 68 move(frames), 69 }; 70} 71 72Optional<Web::Platform::DecodedImage> ImageCodecPluginLadybird::decode_image(ReadonlyBytes data) 73{ 74 auto image = decode_image_with_libgfx(data); 75 if (image.has_value()) 76 return image; 77 return decode_image_with_qt(data); 78} 79 80}