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 0000000000..08d3cbc400 Binary files /dev/null and b/tests/testdata/image/1x1-3f-animated.gif differ 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])); + } });