ImageCodecPluginLadybird.cpp 2.2 KB

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