From 42654b298ebf2d2931a1b6d099f9f2b901dc37b1 Mon Sep 17 00:00:00 2001 From: Sam Judd Date: Fri, 14 Jan 2022 15:19:52 -0800 Subject: [PATCH] Add support for animated webp detection to Glide's ImageHeaderParser. PiperOrigin-RevId: 421923663 --- checkstyle.xml | 5 - .../glide/load/ImageHeaderParser.java | 13 + .../bitmap/DefaultImageHeaderParser.java | 10 +- .../load/resource/bitmap/Downsampler.java | 2 +- .../bitmap/DefaultImageHeaderParserTest.java | 275 ++++++++++++++++-- .../src/test/resources/animated_webp.webp | Bin 0 -> 24754 bytes 6 files changed, 281 insertions(+), 24 deletions(-) create mode 100644 library/test/src/test/resources/animated_webp.webp diff --git a/checkstyle.xml b/checkstyle.xml index 9a3d19a946..d8a1c0ee5b 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -71,11 +71,6 @@ - - - - - diff --git a/library/src/main/java/com/bumptech/glide/load/ImageHeaderParser.java b/library/src/main/java/com/bumptech/glide/load/ImageHeaderParser.java index 0f52857b2d..da7beabd5c 100644 --- a/library/src/main/java/com/bumptech/glide/load/ImageHeaderParser.java +++ b/library/src/main/java/com/bumptech/glide/load/ImageHeaderParser.java @@ -30,6 +30,8 @@ enum ImageType { WEBP_A(true), /** WebP type without alpha. */ WEBP(false), + /** All animated webps. */ + ANIMATED_WEBP(true), /** Avif type (may contain alpha). */ AVIF(true), /** Unrecognized type. */ @@ -44,6 +46,17 @@ enum ImageType { public boolean hasAlpha() { return hasAlpha; } + + public boolean isWebp() { + switch (this) { + case WEBP: + case WEBP_A: + case ANIMATED_WEBP: + return true; + default: + return false; + } + } } @NonNull diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java index 01116ad190..386865d607 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParser.java @@ -1,5 +1,6 @@ package com.bumptech.glide.load.resource.bitmap; +import static com.bumptech.glide.load.ImageHeaderParser.ImageType.ANIMATED_WEBP; import static com.bumptech.glide.load.ImageHeaderParser.ImageType.AVIF; import static com.bumptech.glide.load.ImageHeaderParser.ImageType.GIF; import static com.bumptech.glide.load.ImageHeaderParser.ImageType.JPEG; @@ -53,6 +54,7 @@ public final class DefaultImageHeaderParser implements ImageHeaderParser { private static final int VP8_HEADER_TYPE_EXTENDED = 0x00000058; // 'L' private static final int VP8_HEADER_TYPE_LOSSLESS = 0x0000004C; + private static final int WEBP_EXTENDED_ANIMATION_FLAG = 1 << 1; private static final int WEBP_EXTENDED_ALPHA_FLAG = 1 << 4; private static final int WEBP_LOSSLESS_ALPHA_FLAG = 1 << 3; // Avif-related @@ -146,7 +148,13 @@ private ImageType getType(Reader reader) throws IOException { // Skip some more length bytes and check for transparency/alpha flag. reader.skip(4); short flags = reader.getUInt8(); - return (flags & WEBP_EXTENDED_ALPHA_FLAG) != 0 ? ImageType.WEBP_A : ImageType.WEBP; + if ((flags & WEBP_EXTENDED_ANIMATION_FLAG) != 0) { + return ANIMATED_WEBP; + } else if ((flags & WEBP_EXTENDED_ALPHA_FLAG) != 0) { + return ImageType.WEBP_A; + } else { + return ImageType.WEBP; + } } if ((fourthFourBytes & VP8_HEADER_TYPE_MASK) == VP8_HEADER_TYPE_LOSSLESS) { // See chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java index 2a1a85e6d7..df1a7e0d1d 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java @@ -575,7 +575,7 @@ private static void calculateScaling( } else if (imageType == ImageType.PNG || imageType == ImageType.PNG_A) { powerOfTwoWidth = (int) Math.floor(orientedSourceWidth / (float) powerOfTwoSampleSize); powerOfTwoHeight = (int) Math.floor(orientedSourceHeight / (float) powerOfTwoSampleSize); - } else if (imageType == ImageType.WEBP || imageType == ImageType.WEBP_A) { + } else if (imageType.isWebp()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { powerOfTwoWidth = Math.round(orientedSourceWidth / (float) powerOfTwoSampleSize); powerOfTwoHeight = Math.round(orientedSourceHeight / (float) powerOfTwoSampleSize); diff --git a/library/test/src/test/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParserTest.java b/library/test/src/test/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParserTest.java index 00b31b6393..8bd3e48d14 100644 --- a/library/test/src/test/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParserTest.java +++ b/library/test/src/test/java/com/bumptech/glide/load/resource/bitmap/DefaultImageHeaderParserTest.java @@ -176,7 +176,7 @@ public void run( } @Test - public void testCanParseWebpWithAlpha() throws IOException { + public void testCanParseLosslessWebpWithAlpha() throws IOException { byte[] data = new byte[] { 0x52, @@ -194,12 +194,12 @@ public void testCanParseWebpWithAlpha() throws IOException { 0x56, 0x50, 0x38, - 0x4c, + 0x4c, // Lossless 0x30, 0x50, 0x00, 0x00, - 0x2f, + 0x2f, // Flags (byte) 0xef, (byte) 0x80, 0x15, @@ -231,15 +231,15 @@ public void run( } @Test - public void testCanParseWebpWithoutAlpha() throws IOException { + public void testCanParseLosslessWebpWithoutAlpha() throws IOException { byte[] data = new byte[] { 0x52, 0x49, 0x46, 0x46, - 0x72, - 0x1c, + 0x3c, + 0x50, 0x00, 0x00, 0x57, @@ -249,23 +249,133 @@ public void testCanParseWebpWithoutAlpha() throws IOException { 0x56, 0x50, 0x38, - 0x20, - 0x66, - 0x1c, + 0x4c, // Lossless + 0x30, + 0x50, 0x00, 0x00, + 0x00, // Flags + (byte) 0xef, + (byte) 0x80, + 0x15, + 0x10, + (byte) 0x8d, 0x30, + 0x68, + 0x1b, + (byte) 0xc9, + (byte) 0x91, + (byte) 0xb2 + }; + runTest( + data, + new ParserTestCase() { + @Override + public void run(DefaultImageHeaderParser parser, InputStream is, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.WEBP, parser.getType(is)); + } + + @Override + public void run( + DefaultImageHeaderParser parser, ByteBuffer byteBuffer, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.WEBP, parser.getType(byteBuffer)); + } + }); + } + + @Test + public void testCanParseExtendedWebpWithAlpha() throws IOException { + byte[] data = + new byte[] { + 0x52, + 0x49, + 0x46, + 0x46, 0x3c, - 0x01, - (byte) 0x9d, - 0x01, - 0x2a, + 0x50, + 0x00, + 0x00, + 0x57, + 0x45, + 0x42, + 0x50, + 0x56, + 0x50, + 0x38, + 0x58, // Extended + 0x30, + 0x50, + 0x00, + 0x00, + 0x10, // flags + (byte) 0xef, + (byte) 0x80, + 0x15, + 0x10, + (byte) 0x8d, + 0x30, + 0x68, + 0x1b, + (byte) 0xc9, + (byte) 0x91, + (byte) 0xb2 + }; + runTest( + data, + new ParserTestCase() { + @Override + public void run(DefaultImageHeaderParser parser, InputStream is, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.WEBP_A, parser.getType(is)); + } + + @Override + public void run( + DefaultImageHeaderParser parser, ByteBuffer byteBuffer, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.WEBP_A, parser.getType(byteBuffer)); + } + }); + } + + @Test + public void testCanParseExtendedWebpWithoutAlpha() throws IOException { + byte[] data = + new byte[] { 0x52, - 0x02, - (byte) 0x94, - 0x03, + 0x49, + 0x46, + 0x46, + 0x3c, + 0x50, + 0x00, 0x00, - (byte) 0xc7 + 0x57, + 0x45, + 0x42, + 0x50, + 0x56, + 0x50, + 0x38, + 0x58, // Extended + 0x30, + 0x50, + 0x00, + 0x00, + 0x00, // flags + (byte) 0xef, + (byte) 0x80, + 0x15, + 0x10, + (byte) 0x8d, + 0x30, + 0x68, + 0x1b, + (byte) 0xc9, + (byte) 0x91, + (byte) 0xb2 }; runTest( data, @@ -285,6 +395,137 @@ public void run( }); } + @Test + public void testCanParseExtendedWebpWithoutAlphaAndWithAnimation() throws IOException { + byte[] data = + new byte[] { + 0x52, + 0x49, + 0x46, + 0x46, + 0x3c, + 0x50, + 0x00, + 0x00, + 0x57, + 0x45, + 0x42, + 0x50, + 0x56, + 0x50, + 0x38, + 0x58, // Extended + 0x30, + 0x50, + 0x00, + 0x00, + 0x02, // Flags + (byte) 0xef, + (byte) 0x80, + 0x15, + 0x10, + (byte) 0x8d, + 0x30, + 0x68, + 0x1b, + (byte) 0xc9, + (byte) 0x91, + (byte) 0xb2 + }; + runTest( + data, + new ParserTestCase() { + @Override + public void run(DefaultImageHeaderParser parser, InputStream is, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.ANIMATED_WEBP, parser.getType(is)); + } + + @Override + public void run( + DefaultImageHeaderParser parser, ByteBuffer byteBuffer, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.ANIMATED_WEBP, parser.getType(byteBuffer)); + } + }); + } + + @Test + public void testCanParseExtendedWebpWithAlphaAndAnimation() throws IOException { + byte[] data = + new byte[] { + 0x52, + 0x49, + 0x46, + 0x46, + 0x3c, + 0x50, + 0x00, + 0x00, + 0x57, + 0x45, + 0x42, + 0x50, + 0x56, + 0x50, + 0x38, + 0x58, // Extended + 0x30, + 0x50, + 0x00, + 0x00, + (byte) 0x12, // Flags + (byte) 0xef, + (byte) 0x80, + 0x15, + 0x10, + (byte) 0x8d, + 0x30, + 0x68, + 0x1b, + (byte) 0xc9, + (byte) 0x91, + (byte) 0xb2 + }; + runTest( + data, + new ParserTestCase() { + @Override + public void run(DefaultImageHeaderParser parser, InputStream is, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.ANIMATED_WEBP, parser.getType(is)); + } + + @Override + public void run( + DefaultImageHeaderParser parser, ByteBuffer byteBuffer, ArrayPool byteArrayPool) + throws IOException { + assertEquals(ImageType.ANIMATED_WEBP, parser.getType(byteBuffer)); + } + }); + } + + @Test + public void testCanParseRealAnimatedWebpFile() throws IOException { + byte[] data = Util.readBytes(TestResourceUtil.openResource(getClass(), "animated_webp.webp")); + runTest( + data, + new ParserTestCase() { + @Override + public void run(DefaultImageHeaderParser parser, InputStream is, ArrayPool byteArrayPool) + throws IOException { + assertThat(parser.getType(is)).isEqualTo(ImageType.ANIMATED_WEBP); + } + + @Override + public void run( + DefaultImageHeaderParser parser, ByteBuffer byteBuffer, ArrayPool byteArrayPool) + throws IOException { + assertThat(parser.getType(byteBuffer)).isEqualTo(ImageType.ANIMATED_WEBP); + } + }); + } + @Test public void testCanParseAvifMajorBrand() throws IOException { byte[] data = diff --git a/library/test/src/test/resources/animated_webp.webp b/library/test/src/test/resources/animated_webp.webp new file mode 100644 index 0000000000000000000000000000000000000000..2d28dbfd380b85bb66a94b964ab94f51d6256ef2 GIT binary patch literal 24754 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 literal 0 HcmV?d00001