PNGLoader.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Vector.h>
  8. #include <LibGfx/ImageFormats/PNGLoader.h>
  9. #include <LibGfx/ImageFormats/TIFFLoader.h>
  10. #include <LibGfx/ImageFormats/TIFFMetadata.h>
  11. #include <LibGfx/Painter.h>
  12. #include <png.h>
  13. namespace Gfx {
  14. struct AnimationFrame {
  15. RefPtr<Bitmap> bitmap;
  16. int x_offset { 0 };
  17. int y_offset { 0 };
  18. int width { 0 };
  19. int height { 0 };
  20. int delay_den { 0 };
  21. int delay_num { 0 };
  22. u8 blend_op { 0 };
  23. u8 dispose_op { 0 };
  24. AnimationFrame(RefPtr<Bitmap> bitmap, int x_offset, int y_offset, int width, int height, int delay_den, int delay_num, u8 blend_op, u8 dispose_op)
  25. : bitmap(move(bitmap))
  26. , x_offset(x_offset)
  27. , y_offset(y_offset)
  28. , width(width)
  29. , height(height)
  30. , delay_den(delay_den)
  31. , delay_num(delay_num)
  32. , blend_op(blend_op)
  33. , dispose_op(dispose_op)
  34. {
  35. }
  36. [[nodiscard]] int duration_ms() const
  37. {
  38. if (delay_num == 0)
  39. return 1;
  40. u32 const denominator = delay_den != 0 ? static_cast<u32>(delay_den) : 100u;
  41. auto unsigned_duration_ms = (delay_num * 1000) / denominator;
  42. if (unsigned_duration_ms > INT_MAX)
  43. return INT_MAX;
  44. return static_cast<int>(unsigned_duration_ms);
  45. }
  46. [[nodiscard]] IntRect rect() const { return { x_offset, y_offset, width, height }; }
  47. };
  48. struct PNGLoadingContext {
  49. ReadonlyBytes data;
  50. IntSize size;
  51. u32 frame_count { 0 };
  52. u32 loop_count { 0 };
  53. Vector<ImageFrameDescriptor> frame_descriptors;
  54. Optional<ByteBuffer> icc_profile;
  55. OwnPtr<ExifMetadata> exif_metadata;
  56. Vector<AnimationFrame> animation_frames;
  57. Vector<u8*> row_pointers;
  58. Vector<u8> image_data;
  59. RefPtr<Gfx::Bitmap> decoded_frame_bitmap;
  60. ErrorOr<size_t> read_frames(png_structp, png_infop);
  61. };
  62. ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> PNGImageDecoderPlugin::create(ReadonlyBytes bytes)
  63. {
  64. auto decoder = adopt_own(*new PNGImageDecoderPlugin(bytes));
  65. if (!TRY(decoder->initialize()))
  66. return Error::from_string_literal("PNG load error");
  67. return decoder;
  68. }
  69. PNGImageDecoderPlugin::PNGImageDecoderPlugin(ReadonlyBytes data)
  70. : m_context(adopt_own(*new PNGLoadingContext))
  71. {
  72. m_context->data = data;
  73. }
  74. size_t PNGImageDecoderPlugin::first_animated_frame_index()
  75. {
  76. return 0;
  77. }
  78. IntSize PNGImageDecoderPlugin::size()
  79. {
  80. return m_context->size;
  81. }
  82. bool PNGImageDecoderPlugin::is_animated()
  83. {
  84. return m_context->frame_count > 1;
  85. }
  86. size_t PNGImageDecoderPlugin::loop_count()
  87. {
  88. return m_context->loop_count;
  89. }
  90. size_t PNGImageDecoderPlugin::frame_count()
  91. {
  92. return m_context->frame_count;
  93. }
  94. ErrorOr<ImageFrameDescriptor> PNGImageDecoderPlugin::frame(size_t index, Optional<IntSize>)
  95. {
  96. if (index >= m_context->frame_descriptors.size())
  97. return Error::from_errno(EINVAL);
  98. return m_context->frame_descriptors[index];
  99. }
  100. ErrorOr<Optional<ReadonlyBytes>> PNGImageDecoderPlugin::icc_data()
  101. {
  102. if (m_context->icc_profile.has_value())
  103. return Optional<ReadonlyBytes>(*m_context->icc_profile);
  104. return OptionalNone {};
  105. }
  106. ErrorOr<bool> PNGImageDecoderPlugin::initialize()
  107. {
  108. png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  109. if (!png_ptr)
  110. return false;
  111. png_infop info_ptr = png_create_info_struct(png_ptr);
  112. if (!info_ptr) {
  113. png_destroy_read_struct(&png_ptr, nullptr, nullptr);
  114. return false;
  115. }
  116. if (setjmp(png_jmpbuf(png_ptr))) {
  117. png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
  118. return false;
  119. }
  120. png_set_read_fn(png_ptr, &m_context->data, [](png_structp png_ptr, png_bytep data, png_size_t length) {
  121. auto* read_data = reinterpret_cast<ReadonlyBytes*>(png_get_io_ptr(png_ptr));
  122. if (read_data->size() < length) {
  123. png_error(png_ptr, "Read error");
  124. return;
  125. }
  126. memcpy(data, read_data->data(), length);
  127. *read_data = read_data->slice(length);
  128. });
  129. png_read_info(png_ptr, info_ptr);
  130. u32 width = 0;
  131. u32 height = 0;
  132. int bit_depth = 0;
  133. int color_type = 0;
  134. png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
  135. m_context->size = { static_cast<int>(width), static_cast<int>(height) };
  136. if (color_type == PNG_COLOR_TYPE_PALETTE)
  137. png_set_palette_to_rgb(png_ptr);
  138. if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
  139. png_set_expand_gray_1_2_4_to_8(png_ptr);
  140. if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  141. png_set_tRNS_to_alpha(png_ptr);
  142. if (bit_depth == 16)
  143. png_set_strip_16(png_ptr);
  144. if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  145. png_set_gray_to_rgb(png_ptr);
  146. png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
  147. png_set_bgr(png_ptr);
  148. char* profile_name = nullptr;
  149. int compression_type = 0;
  150. u8* profile_data = nullptr;
  151. u32 profile_len = 0;
  152. if (png_get_iCCP(png_ptr, info_ptr, &profile_name, &compression_type, &profile_data, &profile_len)) {
  153. m_context->icc_profile = TRY(ByteBuffer::copy(profile_data, profile_len));
  154. }
  155. png_read_update_info(png_ptr, info_ptr);
  156. m_context->frame_count = TRY(m_context->read_frames(png_ptr, info_ptr));
  157. u8* exif_data = nullptr;
  158. u32 exif_length = 0;
  159. int const num_exif_chunks = png_get_eXIf_1(png_ptr, info_ptr, &exif_length, &exif_data);
  160. if (num_exif_chunks > 0) {
  161. m_context->exif_metadata = TRY(TIFFImageDecoderPlugin::read_exif_metadata({ exif_data, exif_length }));
  162. }
  163. png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
  164. return true;
  165. }
  166. static ErrorOr<NonnullRefPtr<Bitmap>> render_animation_frame(AnimationFrame const& prev_animation_frame, AnimationFrame const& animation_frame, Bitmap const& decoded_frame_bitmap)
  167. {
  168. auto rendered_bitmap = TRY(prev_animation_frame.bitmap->clone());
  169. Painter painter(rendered_bitmap);
  170. auto frame_rect = animation_frame.rect();
  171. switch (prev_animation_frame.dispose_op) {
  172. case PNG_DISPOSE_OP_BACKGROUND:
  173. painter.clear_rect(rendered_bitmap->rect(), Color::NamedColor::Transparent);
  174. break;
  175. case PNG_DISPOSE_OP_PREVIOUS:
  176. painter.blit(frame_rect.location(), decoded_frame_bitmap, frame_rect, 1.0f, false);
  177. break;
  178. default:
  179. break;
  180. }
  181. switch (animation_frame.blend_op) {
  182. case PNG_BLEND_OP_SOURCE:
  183. painter.blit(frame_rect.location(), decoded_frame_bitmap, decoded_frame_bitmap.rect(), 1.0f, false);
  184. break;
  185. case PNG_BLEND_OP_OVER:
  186. painter.blit(frame_rect.location(), decoded_frame_bitmap, decoded_frame_bitmap.rect(), 1.0f, true);
  187. break;
  188. default:
  189. break;
  190. }
  191. return rendered_bitmap;
  192. }
  193. ErrorOr<size_t> PNGLoadingContext::read_frames(png_structp png_ptr, png_infop info_ptr)
  194. {
  195. if (png_get_acTL(png_ptr, info_ptr, &frame_count, &loop_count)) {
  196. // acTL chunk present: This is an APNG.
  197. png_set_acTL(png_ptr, info_ptr, frame_count, loop_count);
  198. for (size_t frame_index = 0; frame_index < frame_count; ++frame_index) {
  199. png_read_frame_head(png_ptr, info_ptr);
  200. u32 width = 0;
  201. u32 height = 0;
  202. u32 x = 0;
  203. u32 y = 0;
  204. u16 delay_num = 0;
  205. u16 delay_den = 0;
  206. u8 dispose_op = 0;
  207. u8 blend_op = 0;
  208. if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_fcTL)) {
  209. return Error::from_string_literal("Missing fcTL chunk in APNG frame");
  210. }
  211. png_get_next_frame_fcTL(png_ptr, info_ptr, &width, &height, &x, &y, &delay_num, &delay_den, &dispose_op, &blend_op);
  212. decoded_frame_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, IntSize { static_cast<int>(width), static_cast<int>(height) }));
  213. row_pointers.resize(height);
  214. for (u32 i = 0; i < height; ++i) {
  215. row_pointers[i] = decoded_frame_bitmap->scanline_u8(i);
  216. }
  217. png_read_image(png_ptr, row_pointers.data());
  218. auto animation_frame = AnimationFrame(nullptr, x, y, width, height, delay_den, delay_num, blend_op, dispose_op);
  219. if (frame_index == 0) {
  220. animation_frame.bitmap = decoded_frame_bitmap;
  221. frame_descriptors.append({ decoded_frame_bitmap, animation_frame.duration_ms() });
  222. } else {
  223. animation_frame.bitmap = TRY(render_animation_frame(animation_frames.last(), animation_frame, *decoded_frame_bitmap));
  224. frame_descriptors.append({ animation_frame.bitmap, animation_frame.duration_ms() });
  225. }
  226. animation_frames.append(move(animation_frame));
  227. }
  228. } else {
  229. // This is a single-frame PNG.
  230. frame_count = 1;
  231. loop_count = 0;
  232. decoded_frame_bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, AlphaType::Unpremultiplied, size));
  233. row_pointers.resize(size.height());
  234. for (int i = 0; i < size.height(); ++i)
  235. row_pointers[i] = decoded_frame_bitmap->scanline_u8(i);
  236. png_read_image(png_ptr, row_pointers.data());
  237. frame_descriptors.append({ move(decoded_frame_bitmap), 0 });
  238. }
  239. return this->frame_count;
  240. }
  241. PNGImageDecoderPlugin::~PNGImageDecoderPlugin() = default;
  242. bool PNGImageDecoderPlugin::sniff(ReadonlyBytes data)
  243. {
  244. Array<u8, 8> png_signature { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
  245. if (data.size() < png_signature.size())
  246. return false;
  247. return data.slice(0, png_signature.size()) == ReadonlyBytes(png_signature.data(), png_signature.size());
  248. }
  249. Optional<Metadata const&> PNGImageDecoderPlugin::metadata()
  250. {
  251. if (m_context->exif_metadata)
  252. return *m_context->exif_metadata;
  253. return OptionalNone {};
  254. }
  255. }