A WebP file is a RIFF container. All numbers are little-endian. The specifications are
RFC 9649 and Google’s WebP Container Specification. The media type is
image/webp.
Types
| Name | Meaning |
|---|---|
| u16, u24, u32 | Unsigned little-endian integers of 16, 24 and 32 bits. |
| FourCC | Four ASCII characters, case-sensitive. WebP does not follow the RIFF habit of upper case for standard chunks. |
| 1-based | A field that stores the value minus 1. |
The specifications number the bits within a byte from the most significant, so bit 0 is the top bit. The flag tables below give a mask as well, to avoid confusion.
File header
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | FourCC | RIFF | 52 49 46 46 |
| 4 | 4 | u32 | file size | The size of the file from offset 8: the chunks plus 4 bytes for WEBP. At most 232 − 10, which keeps a file under 4 GiB − 2 bytes. |
| 8 | 4 | FourCC | WEBP | 57 45 42 50 |
Files should not have data past the declared size. Readers may parse such files and ignore the extra bytes.
Chunk layout
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | FourCC | chunk ID | The chunk type. |
| 4 | 4 | u32 | chunk size | The size of the payload only: no header, no padding. |
| 8 | size | bytes | payload | |
| 8 + size | 0 or 1 | u8 | padding | A single 00 when the size is odd. |
Chunk types
| FourCC | Bytes | Contents |
|---|---|---|
VP8X | 56 50 38 58 | Extended header: feature flags and canvas size. |
VP8 | 56 50 38 20 | Lossy bitstream. The fourth character is a space. |
VP8L | 56 50 38 4C | Lossless bitstream. |
ALPH | 41 4C 50 48 | Alpha data for a lossy image. |
ANIM | 41 4E 49 4D | Global animation parameters. |
ANMF | 41 4E 4D 46 | One animation frame. |
ICCP | 49 43 43 50 | ICC colour profile. |
EXIF | 45 58 49 46 | Exif metadata. |
XMP | 58 4D 50 20 | XMP metadata. The fourth character is a space. |
The three layouts
| Layout | Chunks after the file header | Canvas size comes from |
|---|---|---|
| Simple lossy | VP8 | The VP8 frame header. |
| Simple lossless | VP8L | The VP8L header. |
| Extended | VP8X first, then as below | VP8X. |
Decoded VP8 data is Y′CbCr and should be converted to RGB with Recommendation 601. Other conversions are allowed but may look different between decoders.
Chunk order in the extended layout
Chunks that matter for reconstruction must appear in this order, and readers should fail on chunks out of order:
VP8XICCPANIMANMF, for an animationALPHthenVP8, orVP8L, for a still image
EXIF, XMP and unknown chunks may appear anywhere. Typical
layouts:
| Image | Chunks |
|---|---|
| Lossy with alpha | VP8X, ALPH, VP8 |
| Lossless with an unknown chunk | VP8X, VP8L, unknown |
| Lossless with profile and XMP | VP8X, ICCP, VP8L, XMP |
| Animated with Exif | VP8X, ANIM, ANMF × N, EXIF |
VP8X
A 10-byte payload.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 1 | bits | flags | See below. |
| 1 | 3 | u24 | reserved | Must be 0; readers ignore it. |
| 4 | 3 | u24 | canvas width minus one | 1-based. |
| 7 | 3 | u24 | canvas height minus one | 1-based. |
Width × height must be at most 232 − 1. Unknown future fields must be ignored.
| Spec bit | Mask | Name | Meaning when set |
|---|---|---|---|
| 0–1 | C0 | reserved | Must be 0; readers ignore them. |
| 2 | 20 | I | An ICC profile is present. |
| 3 | 10 | L | Some frame has alpha. |
| 4 | 08 | E | Exif metadata is present. |
| 5 | 04 | X | XMP metadata is present. |
| 6 | 02 | A | Animation: use ANIM and ANMF. |
| 7 | 01 | R | Reserved, must be 0; readers ignore it. |
A VP8X chunk with the alpha flag and a 100 by 50 canvas:
56 50 38 58 0A 00 00 00 10 00 00 00 63 00 00 31 00 00
ICCP
The payload is an ICC profile. It must come before the image data, and there is at most one; readers should use the first and may ignore any others. Without one, assume sRGB.
EXIF and XMP
The payloads are Exif metadata and XMP metadata. There is at most one of each, and readers may ignore extras.
Unknown chunks
Any FourCC not defined here. They are allowed at the end of the file or at the end of
an ANMF payload. Readers should ignore them, and writers should keep them
in their original order unless they mean to change them.