diff --git a/src/utils/Image.ts b/src/utils/Image.ts index eed70bdf32..ab7c67d477 100644 --- a/src/utils/Image.ts +++ b/src/utils/Image.ts @@ -31,13 +31,13 @@ export async function blobIsAnimated(mimeType: string | undefined, blob: Blob): case "image/webp": { // Only extended file format WEBP images support animation, so grab the expected data range and verify header. // Based on https://developers.google.com/speed/webp/docs/riff_container#extended_file_format - const arr = await blob.slice(0, 17).arrayBuffer(); + const arr = await blob.slice(0, 21).arrayBuffer(); if ( arrayBufferReadStr(arr, 0, 4) === "RIFF" && arrayBufferReadStr(arr, 8, 4) === "WEBP" && arrayBufferReadStr(arr, 12, 4) === "VP8X" ) { - const [flags] = arrayBufferRead(arr, 16, 1); + const [flags] = arrayBufferRead(arr, 20, 1); // Flags: R R I L E X _A_ R (reversed) const animationFlagMask = 1 << 1; return (flags & animationFlagMask) != 0; diff --git a/test/unit-tests/Image-test.ts b/test/unit-tests/Image-test.ts index 149ee0ff26..966236bc8a 100644 --- a/test/unit-tests/Image-test.ts +++ b/test/unit-tests/Image-test.ts @@ -51,6 +51,13 @@ describe("Image", () => { expect(await blobIsAnimated("image/webp", img)).toBeFalsy(); }); + it("Static WEBP in extended file format", async () => { + const img = new Blob([ + fs.readFileSync(path.resolve(__dirname, "images", "static-logo-extended-file-format.webp")), + ]); + expect(await blobIsAnimated("image/webp", img)).toBeFalsy(); + }); + it("Animated PNG", async () => { const img = new Blob([fs.readFileSync(path.resolve(__dirname, "images", "animated-logo.apng"))]); expect(await blobIsAnimated("image/png", img)).toBeTruthy(); diff --git a/test/unit-tests/images/static-logo-extended-file-format.webp b/test/unit-tests/images/static-logo-extended-file-format.webp new file mode 100644 index 0000000000..bb4364374b Binary files /dev/null and b/test/unit-tests/images/static-logo-extended-file-format.webp differ