ImageCodecPluginLadybird.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #define AK_DONT_REPLACE_STD
  8. #include "ImageCodecPluginLadybird.h"
  9. #include <LibGfx/Bitmap.h>
  10. #include <LibGfx/ImageFormats/ImageDecoder.h>
  11. #include <QImage>
  12. namespace Ladybird {
  13. ImageCodecPluginLadybird::~ImageCodecPluginLadybird() = default;
  14. static Optional<Web::Platform::DecodedImage> decode_image_with_qt(ReadonlyBytes data)
  15. {
  16. auto image = QImage::fromData(data.data(), static_cast<int>(data.size()));
  17. if (image.isNull())
  18. return {};
  19. image = image.convertToFormat(QImage::Format::Format_ARGB32);
  20. auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::IntSize(image.width(), image.height())));
  21. for (int y = 0; y < image.height(); ++y) {
  22. memcpy(bitmap->scanline_u8(y), image.scanLine(y), image.width() * 4);
  23. }
  24. Vector<Web::Platform::Frame> frames;
  25. frames.append(Web::Platform::Frame {
  26. bitmap,
  27. });
  28. return Web::Platform::DecodedImage {
  29. false,
  30. 0,
  31. move(frames),
  32. };
  33. }
  34. static Optional<Web::Platform::DecodedImage> decode_image_with_libgfx(ReadonlyBytes data)
  35. {
  36. auto decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(data);
  37. if (!decoder || !decoder->frame_count()) {
  38. return {};
  39. }
  40. bool had_errors = false;
  41. Vector<Web::Platform::Frame> frames;
  42. for (size_t i = 0; i < decoder->frame_count(); ++i) {
  43. auto frame_or_error = decoder->frame(i);
  44. if (frame_or_error.is_error()) {
  45. frames.append({ {}, 0 });
  46. had_errors = true;
  47. } else {
  48. auto frame = frame_or_error.release_value();
  49. frames.append({ move(frame.image), static_cast<size_t>(frame.duration) });
  50. }
  51. }
  52. if (had_errors)
  53. return {};
  54. return Web::Platform::DecodedImage {
  55. decoder->is_animated(),
  56. static_cast<u32>(decoder->loop_count()),
  57. move(frames),
  58. };
  59. }
  60. Optional<Web::Platform::DecodedImage> ImageCodecPluginLadybird::decode_image(ReadonlyBytes data)
  61. {
  62. auto image = decode_image_with_libgfx(data);
  63. if (image.has_value())
  64. return image;
  65. return decode_image_with_qt(data);
  66. }
  67. }