From 396c09c24d3ff066c5e819c3b270ff6ede6ea301 Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:00:05 +0900 Subject: [PATCH] support animated GIF --- ext/canvas/lib.rs | 14 +------------- tests/testdata/image/1x1-3f-animated.gif | Bin 0 -> 126 bytes tests/unit/image_bitmap_test.ts | 13 +++++++++++++ 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 tests/testdata/image/1x1-3f-animated.gif diff --git a/ext/canvas/lib.rs b/ext/canvas/lib.rs index 66a6c06e94..0c42c7efbf 100644 --- a/ext/canvas/lib.rs +++ b/ext/canvas/lib.rs @@ -14,7 +14,6 @@ use image::codecs::png::PngDecoder; use image::codecs::webp::WebPDecoder; use image::imageops::overlay; use image::imageops::FilterType; -use image::AnimationDecoder; use image::ColorType; use image::DynamicImage; use image::GenericImageView; @@ -391,6 +390,7 @@ macro_rules! impl_image_decoder_from_reader { // If PngDecoder decodes an animated image, it returns the default image if one is set, or the first frame if not. impl_image_decoder_from_reader!(PngDecoder, ImageDecoderFromReaderType); impl_image_decoder_from_reader!(JpegDecoder, ImageDecoderFromReaderType); +// The GifDecoder decodes the first frame. impl_image_decoder_from_reader!(GifDecoder, ImageDecoderFromReaderType); impl_image_decoder_from_reader!(BmpDecoder, ImageDecoderFromReaderType); impl_image_decoder_from_reader!(IcoDecoder, ImageDecoderFromReaderType); @@ -423,18 +423,6 @@ fn decode_bitmap_data( decoder.to_intermediate_image()? } "image/gif" => { - let decoder: GifDecoder = - ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new( - buf, - )))?; - if decoder.into_frames().count() > 1 { - return Err( - DOMExceptionInvalidStateError::new( - "Animation image is not supported.", - ) - .into(), - ); - } let decoder: GifDecoder = ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new( buf, diff --git a/tests/testdata/image/1x1-3f-animated.gif b/tests/testdata/image/1x1-3f-animated.gif new file mode 100644 index 0000000000000000000000000000000000000000..08d3cbc4008a209cce25d1e76f6f49faecb7c883 GIT binary patch literal 126 zcmZ?wbhEHbWMp7uXkdT>#sA!Xt|7tBjsdPldIrplKw-t7EG$MqS_h;AtoT2O#lXbm S!iYtZ0W6D45-barv<3ipl@L|{ literal 0 HcmV?d00001 diff --git a/tests/unit/image_bitmap_test.ts b/tests/unit/image_bitmap_test.ts index 118ad775ad..fb3ecf9595 100644 --- a/tests/unit/image_bitmap_test.ts +++ b/tests/unit/image_bitmap_test.ts @@ -346,4 +346,17 @@ Deno.test(async function imageBitmapFromBlobAnimatedImage() { // deno-fmt-ignore assertEquals(Deno[Deno.internal].getBitmapData(imageBitmap), new Uint8Array([255, 0, 0, 127])); } + { + // the chunk of animated gif is below (3 frames, 1x1, 8-bit, RGBA) + // [ 255, 0, 0, 255, + // 0, 255, 0, 255, + // 0, 0, 255, 255 ] + const imageData = new Blob([ + await Deno.readFile(`${prefix}/1x1-3f-animated.gif`), + ], { type: "image/gif" }); + const imageBitmap = await createImageBitmap(imageData); + // @ts-ignore: Deno[Deno.internal].core allowed + // deno-fmt-ignore + assertEquals(Deno[Deno.internal].getBitmapData(imageBitmap), new Uint8Array([255, 0, 0, 255])); + } });