-
Notifications
You must be signed in to change notification settings - Fork 88
Description
Summary
Piexif incorrectly sets the VP8X canvas dimensions for certain animated WebP files, leading to a "Frame exceeds canvas" error when frames exceed the dimensions of the last frame.
Steps to Reproduce:
- Process an animated WebP file using Piexif where the frames vary in size.
- Ensure that the last frame is smaller than some of the previous frames.
- Run a tool like
webpinfoon the output file to observe the error.
This can be reproduced with the pil_animated2.webp file in my fork: 5a12974
Input Test File
→ webpinfo -diag tests/images/pil_animated2.webp
File: tests/images/pil_animated2.webp
RIFF HEADER:
File size: 37342
Chunk VP8X at offset 12, length 18
ICCP: 0
Alpha: 1
EXIF: 0
XMP: 0
Animation: 1
Canvas size 400 x 400
Chunk ANIM at offset 30, length 14
Background color:(ARGB) ff 00 00 00
Loop count : 0
Chunk ANMF at offset 44, length 5190
Offset_X: 0
Offset_Y: 0
Width: 400
Height: 400
Duration: 70
Dispose: 0
Blend: 1
Chunk VP8L at offset 68, length 5166
Width: 400
Height: 400
Alpha: 0
Animation: 0
Format: Lossless (2)
...
Chunk ANMF at offset 34824, length 2518
Offset_X: 0
Offset_Y: 6
Width: 320
Height: 382
Duration: 70
Dispose: 0
Blend: 0
Chunk VP8L at offset 34848, length 2494
Width: 320
Height: 382
Alpha: 1
Animation: 0
Format: Lossless (2)
No error detected.
Output Test File
→ webpinfo -diag tests/images/out/i_pil_animated2.webp
File: tests/images/out/i_pil_animated2.webp
RIFF HEADER:
File size: 37400
Chunk VP8X at offset 12, length 18
ICCP: 0
Alpha: 0
EXIF: 1
XMP: 0
Animation: 1
Canvas size 320 x 382
Chunk EXIF at offset 30, length 58
Chunk ANIM at offset 88, length 14
Background color:(ARGB) ff 00 00 00
Loop count : 0
Chunk ANMF at offset 102, length 5190
Offset_X: 0
Offset_Y: 0
Width: 400
Height: 400
Duration: 70
Dispose: 0
Blend: 1
Error: Frame exceeds canvas in ANMF chunk.
Errors detected.
Expected Behavior:
The VP8X chunk should reflect the maximum dimensions across all frames to correctly represent the entire canvas, preventing any "Frame exceeds canvas" errors.
Actual Behavior:
The VP8X chunk dimensions are set based on the last frame processed. If this frame is smaller than earlier frames, the overall canvas size is incorrect, leading to errors.
This issue affects users processing animated WebP files with frames of varying sizes. Ensuring the correct canvas size in the VP8X chunk is critical for maintaining compatibility and avoiding errors in tools that validate WebP file structure.
Technical Details
The issue arises because the set_vp8x function in the piexif library sets the width and height based on the last frame it processes. This approach fails to account for previous frames that may be larger, resulting in an incorrect canvas size.
WebP Image (OK)
For non-animated WebP files, the VP8X chunk correctly represents the image dimensions:
+--------------------------+
| WebP Container |
| |
| +--------------------+ |
| | VP8X Chunk | | <-- Flags and size info
| +--------------------+ |
| |
| +--------------------+ |
| | VP8L Chunk | | <-- Image data (Lossless)
| +--------------------+ |
| |
+--------------------------+
Animated WebP (Broken)
For animated WebP files, the VP8X chunk incorrectly sets the canvas dimensions based on the last frame processed, even if earlier frames are larger:
+--------------------------+
| WebP Container |
| |
| +--------------------+ |
| | VP8X Chunk | | <-- Flags and canvas size info (incorrectly set)
| +--------------------+ |
| |
| +--------------------+ |
| | ANIM Chunk | | <-- Animation control info
| +--------------------+ |
| |
| +--------------------+ |
| | ANMF Chunk | | <-- Frame 1 (larger than last frame)
| | +--------------+ | |
| | | VP8L Chunk | | | <-- Image data
| +--------------------+ |
| |
| +--------------------+ |
| | ANMF Chunk | | <-- Frame 2 (smaller, last frame processed)
| | +--------------+ | |
| | | VP8L Chunk | | | <-- Image data
| +--------------------+ |
| |
+--------------------------+
Proposal:
Modify the set_vp8x function to track the maximum width and height across all frames. The VP8X chunk should be updated to reflect these maximum dimensions, ensuring that the canvas size accommodates all frames.
I have a commit in my fork that appears to resolve this: 7c6522a