• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!--
2
3Although you may be viewing an alternate representation, this document
4is sourced in Markdown, a light-duty markup scheme, and is optimized for
5the [kramdown](https://kramdown.gettalong.org/) transformer.
6
7See the accompanying specs_generation.md. External link targets are referenced
8at the end of this file.
9
10-->
11
12
13WebP Container Specification
14============================
15
16* TOC placeholder
17{:toc}
18
19
20Introduction
21------------
22
23WebP is an image format that uses either (i) the VP8 key frame encoding
24to compress image data in a lossy way, or (ii) the WebP lossless encoding
25(and possibly other encodings in the future). These encoding schemes should
26make it more efficient than currently used formats. It is optimized for fast
27image transfer over the network (e.g., for websites). The WebP format has
28feature parity (color profile, metadata, animation, etc.) with other formats as
29well. This document describes the structure of a WebP file.
30
31The WebP container (i.e., RIFF container for WebP) allows feature support over
32and above the basic use case of WebP (i.e., a file containing a single image
33encoded as a VP8 key frame). The WebP container provides additional support
34for:
35
36  * **Lossless compression.** An image can be losslessly compressed, using the
37    WebP Lossless Format.
38
39  * **Metadata.** An image may have metadata stored in Exif or XMP formats.
40
41  * **Transparency.** An image may have transparency, i.e., an alpha channel.
42
43  * **Color Profile.** An image may have an embedded ICC profile as described
44    by the [International Color Consortium][iccspec].
45
46  * **Animation.** An image may have multiple frames with pauses between them,
47    making it an animation.
48
49The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
50"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
51document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][]
52when, and only when, they appear in all capitals, as shown here.
53
54Bit numbering in chunk diagrams starts at `0` for the most significant bit
55('MSB 0') as described in [RFC 1166][].
56
57Terminology & Basics
58--------------------
59
60A WebP file contains either a still image (i.e., an encoded matrix of pixels)
61or an [animation](#animation). Optionally, it can also contain transparency
62information, color profile and metadata. In case we need to refer only to the
63matrix of pixels, we will call it the _canvas_ of the image.
64
65Below are additional terms used throughout this document:
66
67_Reader/Writer_
68
69: Code that reads WebP files is referred to as a _reader_, while code that
70  writes them is referred to as a _writer_.
71
72_uint16_
73
74: A 16-bit, little-endian, unsigned integer.
75
76_uint24_
77
78: A 24-bit, little-endian, unsigned integer.
79
80_uint32_
81
82: A 32-bit, little-endian, unsigned integer.
83
84_FourCC_
85
86: A _FourCC_ (four-character code) is a _uint32_ created by concatenating four
87  ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and
88 'AAAA' (0x41414141) are treated as different _FourCCs_.
89
90_1-based_
91
92: An unsigned integer field storing values offset by `-1`. e.g., Such a field
93  would store value _25_ as _24_.
94
95_ChunkHeader('ABCD')_
96
97: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
98  chunks, where 'ABCD' is the FourCC for the chunk. This element's size is 8
99  bytes.
100
101
102RIFF File Format
103----------------
104
105The WebP file format is based on the RIFF (Resource Interchange File Format)
106document format.
107
108The basic element of a RIFF file is a _chunk_. It consists of:
109
110     0                   1                   2                   3
111     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
112    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113    |                         Chunk FourCC                          |
114    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115    |                          Chunk Size                           |
116    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117    :                         Chunk Payload                         :
118    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119
120Chunk FourCC: 32 bits
121
122: ASCII four-character code used for chunk identification.
123
124Chunk Size: 32 bits (_uint32_)
125
126: The size of the chunk in bytes, not including this field, the chunk
127  identifier or padding.
128
129Chunk Payload: _Chunk Size_ bytes
130
131: The data payload. If _Chunk Size_ is odd, a single padding byte -- that MUST
132  be `0` to conform with RIFF -- is added.
133
134**Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard
135chunks that apply to any RIFF file format, while FourCCs specific to a file
136format are all lowercase. WebP does not follow this convention.
137
138
139WebP File Header
140----------------
141
142     0                   1                   2                   3
143     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
144    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145    |      'R'      |      'I'      |      'F'      |      'F'      |
146    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147    |                           File Size                           |
148    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
149    |      'W'      |      'E'      |      'B'      |      'P'      |
150    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151
152'RIFF': 32 bits
153
154: The ASCII characters 'R' 'I' 'F' 'F'.
155
156File Size: 32 bits (_uint32_)
157
158: The size of the file in bytes starting at offset 8. The maximum value of
159  this field is 2^32 minus 10 bytes and thus the size of the whole file is at
160  most 4GiB minus 2 bytes.
161
162'WEBP': 32 bits
163
164: The ASCII characters 'W' 'E' 'B' 'P'.
165
166A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size
167in the header is the total size of the chunks that follow plus `4` bytes for
168the 'WEBP' FourCC. The file SHOULD NOT contain any data after the data
169specified by _File Size_. Readers MAY parse such files, ignoring the trailing
170data. As the size of any chunk is even, the size given by the RIFF header is
171also even. The contents of individual chunks will be described in the following
172sections.
173
174
175Simple File Format (Lossy)
176--------------------------
177
178This layout SHOULD be used if the image requires _lossy_ encoding and does not
179require transparency or other advanced features provided by the extended format.
180Files with this layout are smaller and supported by older software.
181
182Simple WebP (lossy) file format:
183
184     0                   1                   2                   3
185     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
186    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187    |                                                               |
188    |                    WebP file header (12 bytes)                |
189    |                                                               |
190    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
191    :                          VP8 chunk                            :
192    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
193
194VP8 chunk:
195
196     0                   1                   2                   3
197     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
198    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199    |                      ChunkHeader('VP8 ')                      |
200    |                                                               |
201    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202    :                           VP8 data                            :
203    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204
205VP8 data: _Chunk Size_ bytes
206
207: VP8 bitstream data.
208
209Note the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20).
210
211The VP8 bitstream format specification can be found at [VP8 Data Format and
212Decoding Guide][vp8spec]. Note that the VP8 frame header contains the VP8 frame
213width and height. That is assumed to be the width and height of the canvas.
214
215The VP8 specification describes how to decode the image into Y'CbCr format. To
216convert to RGB, Rec. 601 SHOULD be used. Applications MAY use another
217conversion method, but visual results may differ among decoders.
218
219
220Simple File Format (Lossless)
221-----------------------------
222
223**Note:** Older readers may not support files using the lossless format.
224
225This layout SHOULD be used if the image requires _lossless_ encoding (with an
226optional transparency channel) and does not require advanced features provided
227by the extended format.
228
229Simple WebP (lossless) file format:
230
231     0                   1                   2                   3
232     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
233    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
234    |                                                               |
235    |                    WebP file header (12 bytes)                |
236    |                                                               |
237    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238    :                          VP8L chunk                           :
239    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
240
241VP8L chunk:
242
243     0                   1                   2                   3
244     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
245    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
246    |                      ChunkHeader('VP8L')                      |
247    |                                                               |
248    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
249    :                           VP8L data                           :
250    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
251
252VP8L data: _Chunk Size_ bytes
253
254: VP8L bitstream data.
255
256The current specification of the VP8L bitstream can be found at
257[WebP Lossless Bitstream Format][webpllspec]. Note that the VP8L header
258contains the VP8L image width and height. That is assumed to be the width
259and height of the canvas.
260
261
262Extended File Format
263--------------------
264
265**Note:** Older readers may not support files using the extended format.
266
267An extended format file consists of:
268
269  * A 'VP8X' chunk with information about features used in the file.
270
271  * An optional 'ICCP' chunk with color profile.
272
273  * An optional 'ANIM' chunk with animation control data.
274
275  * Image data.
276
277  * An optional 'EXIF' chunk with Exif metadata.
278
279  * An optional 'XMP ' chunk with XMP metadata.
280
281  * An optional list of [unknown chunks](#unknown-chunks).
282
283For a _still image_, the _image data_ consists of a single frame, which is made
284up of:
285
286  * An optional [alpha subchunk](#alpha).
287
288  * A [bitstream subchunk](#bitstream-vp8vp8l).
289
290For an _animated image_, the _image data_ consists of multiple frames. More
291details about frames can be found in the [Animation](#animation) section.
292
293All chunks SHOULD be placed in the same order as listed above. If a chunk
294appears in the wrong place, the file is invalid, but readers MAY parse the
295file, ignoring the chunks that are out of order.
296
297**Rationale:** Setting the order of chunks should allow quicker file
298parsing. For example, if an 'ALPH' chunk does not appear in its required
299position, a decoder can choose to stop searching for it. The rule of
300ignoring late chunks should make programs that need to do a full search
301give the same results as the ones stopping early.
302
303Extended WebP file header:
304{:#extended_header}
305
306     0                   1                   2                   3
307     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
308    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
309    |                                                               |
310    |                   WebP file header (12 bytes)                 |
311    |                                                               |
312    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
313    |                      ChunkHeader('VP8X')                      |
314    |                                                               |
315    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
316    |Rsv|I|L|E|X|A|R|                   Reserved                    |
317    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
318    |          Canvas Width Minus One               |             ...
319    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
320    ...  Canvas Height Minus One    |
321    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322
323Reserved (Rsv): 2 bits
324
325: MUST be `0`. Readers MUST ignore this field.
326
327ICC profile (I): 1 bit
328
329: Set if the file contains an ICC profile.
330
331Alpha (L): 1 bit
332
333: Set if any of the frames of the image contain transparency information
334  ("alpha").
335
336Exif metadata (E): 1 bit
337
338: Set if the file contains Exif metadata.
339
340XMP metadata (X): 1 bit
341
342: Set if the file contains XMP metadata.
343
344Animation (A): 1 bit
345
346: Set if this is an animated image. Data in 'ANIM' and 'ANMF' chunks should be
347  used to control the animation.
348
349Reserved (R): 1 bit
350
351: MUST be `0`. Readers MUST ignore this field.
352
353Reserved: 24 bits
354
355: MUST be `0`. Readers MUST ignore this field.
356
357Canvas Width Minus One: 24 bits
358
359: _1-based_ width of the canvas in pixels.
360  The actual canvas width is `1 + Canvas Width Minus One`.
361
362Canvas Height Minus One: 24 bits
363
364: _1-based_ height of the canvas in pixels.
365  The actual canvas height is `1 + Canvas Height Minus One`.
366
367The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
368
369Future specifications may add more fields. Unknown fields MUST be ignored.
370
371### Chunks
372
373#### Animation
374
375An animation is controlled by ANIM and ANMF chunks.
376
377ANIM Chunk:
378{:#anim_chunk}
379
380For an animated image, this chunk contains the _global parameters_ of the
381animation.
382
383     0                   1                   2                   3
384     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
385    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
386    |                      ChunkHeader('ANIM')                      |
387    |                                                               |
388    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
389    |                       Background Color                        |
390    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
391    |          Loop Count           |
392    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
393
394Background Color: 32 bits (_uint32_)
395
396: The default background color of the canvas in \[Blue, Green, Red, Alpha\]
397  byte order. This color MAY be used to fill the unused space on the canvas
398  around the frames, as well as the transparent pixels of the first frame.
399  Background color is also used when disposal method is `1`.
400
401**Note**:
402
403  * Background color MAY contain a non-opaque alpha value, even if the _Alpha_
404    flag in [VP8X chunk](#extended_header) is unset.
405
406  * Viewer applications SHOULD treat the background color value as a hint, and
407    are not required to use it.
408
409  * The canvas is cleared at the start of each loop. The background color MAY be
410    used to achieve this.
411
412Loop Count: 16 bits (_uint16_)
413
414: The number of times to loop the animation. `0` means infinitely.
415
416This chunk MUST appear if the _Animation_ flag in the VP8X chunk is set.
417If the _Animation_ flag is not set and this chunk is present, it MUST be
418ignored.
419
420ANMF chunk:
421
422For animated images, this chunk contains information about a _single_ frame.
423If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
424
425     0                   1                   2                   3
426     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
427    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
428    |                      ChunkHeader('ANMF')                      |
429    |                                                               |
430    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
431    |                        Frame X                |             ...
432    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
433    ...          Frame Y            |   Frame Width Minus One     ...
434    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
435    ...             |           Frame Height Minus One              |
436    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
437    |                 Frame Duration                |  Reserved |B|D|
438    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
439    :                         Frame Data                            :
440    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
441
442Frame X: 24 bits (_uint24_)
443
444: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
445
446Frame Y: 24 bits (_uint24_)
447
448: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
449
450Frame Width Minus One: 24 bits (_uint24_)
451
452: The _1-based_ width of the frame.
453  The frame width is `1 + Frame Width Minus One`.
454
455Frame Height Minus One: 24 bits (_uint24_)
456
457: The _1-based_ height of the frame.
458  The frame height is `1 + Frame Height Minus One`.
459
460Frame Duration: 24 bits (_uint24_)
461
462: The time to wait before displaying the next frame, in 1 millisecond units.
463  Note the interpretation of frame duration of 0 (and often <= 10) is
464  implementation defined. Many tools and browsers assign a minimum duration
465  similar to GIF.
466
467Reserved: 6 bits
468
469: MUST be `0`. Readers MUST ignore this field.
470
471Blending method (B): 1 bit
472
473: Indicates how transparent pixels of _the current frame_ are to be blended
474  with corresponding pixels of the previous canvas:
475
476    * `0`: Use alpha blending. After disposing of the previous frame, render the
477      current frame on the canvas using [alpha-blending](#alpha-blending). If
478      the current frame does not have an alpha channel, assume alpha value of
479      255, effectively replacing the rectangle.
480
481    * `1`: Do not blend. After disposing of the previous frame, render the
482      current frame on the canvas by overwriting the rectangle covered by the
483      current frame.
484
485Disposal method (D): 1 bit
486
487: Indicates how _the current frame_ is to be treated after it has been
488  displayed (before rendering the next frame) on the canvas:
489
490    * `0`: Do not dispose. Leave the canvas as is.
491
492    * `1`: Dispose to background color. Fill the _rectangle_ on the canvas
493      covered by the _current frame_ with background color specified in the
494      [ANIM chunk](#anim_chunk).
495
496**Notes**:
497
498  * The frame disposal only applies to the _frame rectangle_, that is, the
499    rectangle defined by _Frame X_, _Frame Y_, _frame width_ and _frame height_.
500    It may or may not cover the whole canvas.
501
502{:#alpha-blending}
503  * **Alpha-blending**:
504
505    Given that each of the R, G, B and A channels is 8-bit, and the RGB
506    channels are _not premultiplied_ by alpha, the formula for blending
507    'dst' onto 'src' is:
508
509~~~~~
510    blend.A = src.A + dst.A * (1 - src.A / 255)
511    if blend.A = 0 then
512      blend.RGB = 0
513    else
514      blend.RGB =
515          (src.RGB * src.A +
516           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
517~~~~~
518
519  * Alpha-blending SHOULD be done in linear color space, by taking into account
520    the [color profile](#color-profile) of the image. If the color profile is
521    not present, sRGB is to be assumed. (Note that sRGB also needs to be
522    linearized due to a gamma of ~2.2).
523
524Frame Data: _Chunk Size_ - `16` bytes
525
526: Consists of:
527
528  * An optional [alpha subchunk](#alpha) for the frame.
529
530  * A [bitstream subchunk](#bitstream-vp8vp8l) for the frame.
531
532  * An optional list of [unknown chunks](#unknown-chunks).
533
534**Note**: The 'ANMF' payload, _Frame Data_ above, consists of individual
535_padded_ chunks as described by the [RIFF file format](#riff-file-format).
536
537#### Alpha
538
539     0                   1                   2                   3
540     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
541    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
542    |                      ChunkHeader('ALPH')                      |
543    |                                                               |
544    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
545    |Rsv| P | F | C |     Alpha Bitstream...                        |
546    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
547
548Reserved (Rsv): 2 bits
549
550: MUST be `0`. Readers MUST ignore this field.
551
552Pre-processing (P): 2 bits
553
554: These _informative_ bits are used to signal the pre-processing that has
555  been performed during compression. The decoder can use this information to
556  e.g. dither the values or smooth the gradients prior to display.
557
558    * `0`: No pre-processing.
559    * `1`: Level reduction.
560
561Filtering method (F): 2 bits
562
563: The filtering method used:
564
565    * `0`: None.
566    * `1`: Horizontal filter.
567    * `2`: Vertical filter.
568    * `3`: Gradient filter.
569
570For each pixel, filtering is performed using the following calculations.
571Assume the alpha values surrounding the current `X` position are labeled as:
572
573     C | B |
574    ---+---+
575     A | X |
576
577We seek to compute the alpha value at position `X`. First, a prediction is
578made depending on the filtering method:
579
580  * Method `0`: predictor = 0
581  * Method `1`: predictor = A
582  * Method `2`: predictor = B
583  * Method `3`: predictor = clip(A + B - C)
584
585where `clip(v)` is equal to:
586
587  * 0    if v < 0
588  * 255  if v > 255
589  * v    otherwise
590
591The final value is derived by adding the decompressed value `X` to the
592predictor and using modulo-256 arithmetic to wrap the \[256..511\] range
593into the \[0..255\] one:
594
595`alpha = (predictor + X) % 256`
596
597There are special cases for the left-most and top-most pixel positions:
598
599  * The top-left value at location (0, 0) uses 0 as predictor value. Otherwise,
600  * For horizontal or gradient filtering methods, the left-most pixels at
601    location (0, y) are predicted using the location (0, y-1) just above.
602  * For vertical or gradient filtering methods, the top-most pixels at
603    location (x, 0) are predicted using the location (x-1, 0) on the left.
604
605
606Decoders are not required to use this information in any specified way.
607
608Compression method (C): 2 bits
609
610: The compression method used:
611
612    * `0`: No compression.
613    * `1`: Compressed using the WebP lossless format.
614
615Alpha bitstream: _Chunk Size_ - `1` bytes
616
617: Encoded alpha bitstream.
618
619This optional chunk contains encoded alpha data for this frame. A frame
620containing a 'VP8L' chunk SHOULD NOT contain this chunk.
621
622**Rationale**: The transparency information is already part of the 'VP8L'
623chunk.
624
625The alpha channel data is stored as uncompressed raw data (when
626compression method is '0') or compressed using the lossless format
627(when the compression method is '1').
628
629  * Raw data: consists of a byte sequence of length width * height,
630    containing all the 8-bit transparency values in scan order.
631
632  * Lossless format compression: the byte sequence is a compressed
633    image-stream (as described in the [WebP Lossless Bitstream Format]
634    [webpllspec]) of implicit dimension width x height. That is, this
635    image-stream does NOT contain any headers describing the image dimension.
636
637    **Rationale**: the dimension is already known from other sources,
638    so storing it again would be redundant and error-prone.
639
640    Once the image-stream is decoded into ARGB color values, following
641    the process described in the lossless format specification, the
642    transparency information must be extracted from the *green* channel
643    of the ARGB quadruplet.
644
645    **Rationale**: the green channel is allowed extra transformation
646    steps in the specification -- unlike the other channels -- that can
647    improve compression.
648
649#### Bitstream (VP8/VP8L)
650
651This chunk contains compressed bitstream data for a single frame.
652
653A bitstream chunk may be either (i) a VP8 chunk, using "VP8 " (note the
654significant fourth-character space) as its tag _or_ (ii) a VP8L chunk, using
655"VP8L" as its tag.
656
657The formats of VP8 and VP8L chunks are as described in sections
658[Simple File Format (Lossy)](#simple-file-format-lossy)
659and [Simple File Format (Lossless)](#simple-file-format-lossless) respectively.
660
661#### Color Profile
662
663     0                   1                   2                   3
664     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
665    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
666    |                      ChunkHeader('ICCP')                      |
667    |                                                               |
668    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
669    :                       Color Profile                           :
670    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
671
672Color Profile: _Chunk Size_ bytes
673
674: ICC profile.
675
676This chunk MUST appear before the image data.
677
678There SHOULD be at most one such chunk. If there are more such chunks, readers
679MAY ignore all except the first one.
680See the [ICC Specification][iccspec] for details.
681
682If this chunk is not present, sRGB SHOULD be assumed.
683
684#### Metadata
685
686Metadata can be stored in 'EXIF' or 'XMP ' chunks.
687
688There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there
689are more such chunks, readers MAY ignore all except the first one.
690
691The chunks are defined as follows:
692
693EXIF chunk:
694
695     0                   1                   2                   3
696     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
697    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
698    |                      ChunkHeader('EXIF')                      |
699    |                                                               |
700    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
701    :                        Exif Metadata                          :
702    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
703
704Exif Metadata: _Chunk Size_ bytes
705
706: Image metadata in Exif format.
707
708XMP chunk:
709
710     0                   1                   2                   3
711     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
712    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
713    |                      ChunkHeader('XMP ')                      |
714    |                                                               |
715    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
716    :                        XMP Metadata                           :
717    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
718
719XMP Metadata: _Chunk Size_ bytes
720
721: Image metadata in XMP format.
722
723Note the fourth character in the 'XMP ' FourCC is an ASCII space (0x20).
724
725Additional guidance about handling metadata can be found in the
726Metadata Working Group's [Guidelines for Handling Metadata][metadata].
727
728#### Unknown Chunks
729
730A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk
731tag_ is different from any of the chunks described in this document, is
732considered an _unknown chunk_.
733
734**Rationale**: Allowing unknown chunks gives a provision for future extension
735of the format, and also allows storage of any application-specific data.
736
737A file MAY contain unknown chunks:
738
739  * At the end of the file as described in [Extended WebP file
740    header](#extended_header) section.
741  * At the end of ANMF chunks as described in the
742    [Animation](#animation) section.
743
744Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their
745original order (unless they specifically intend to modify these chunks).
746
747### Assembling the Canvas From Frames
748
749Here we provide an overview of how a reader MUST assemble a canvas in the case
750of an animated image.
751
752The process begins with creating a canvas using the dimensions given in the
753'VP8X' chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus
754One + 1` pixels high. The `Loop Count` field from the 'ANIM' chunk controls how
755many times the animation process is repeated. This is `Loop Count - 1` for
756non-zero `Loop Count` values or infinitely if `Loop Count` is zero.
757
758At the beginning of each loop iteration the canvas is filled using the
759background color from the 'ANIM' chunk or an application defined color.
760
761'ANMF' chunks contain individual frames given in display order. Before rendering
762each frame, the previous frame's `Disposal method` is applied.
763
764The rendering of the decoded frame begins at the Cartesian coordinates (`2 *
765Frame X`, `2 * Frame Y`) using the top-left corner of the canvas as the origin.
766`Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels
767high are rendered onto the canvas using the `Blending method`.
768
769The canvas is displayed for `Frame Duration` milliseconds. This continues until
770all frames given by 'ANMF' chunks have been displayed. A new loop iteration is
771then begun or the canvas is left in its final state if all iterations have been
772completed.
773
774The following pseudocode illustrates the rendering process. The notation
775_VP8X.field_ means the field in the 'VP8X' chunk with the same description.
776
777~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
778assert VP8X.flags.hasAnimation
779canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
780         background color ANIM.background_color.
781loop_count ← ANIM.loopCount
782dispose_method ← Dispose to background color
783if loop_count == 0:
784  loop_count = ∞
785frame_params ← nil
786assert next chunk in image_data is ANMF
787for loop = 0..loop_count - 1
788  clear canvas to ANIM.background_color or application defined color
789  until eof or non-ANMF chunk
790    frame_params.frameX = Frame X
791    frame_params.frameY = Frame Y
792    frame_params.frameWidth = Frame Width Minus One + 1
793    frame_params.frameHeight = Frame Height Minus One + 1
794    frame_params.frameDuration = Frame Duration
795    frame_right = frame_params.frameX + frame_params.frameWidth
796    frame_bottom = frame_params.frameY + frame_params.frameHeight
797    assert VP8X.canvasWidth >= frame_right
798    assert VP8X.canvasHeight >= frame_bottom
799    for subchunk in 'Frame Data':
800      if subchunk.tag == "ALPH":
801        assert alpha subchunks not found in 'Frame Data' earlier
802        frame_params.alpha = alpha_data
803      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
804        assert bitstream subchunks not found in 'Frame Data' earlier
805        frame_params.bitstream = bitstream_data
806    render frame with frame_params.alpha and frame_params.bitstream
807      on canvas with top-left corner at (frame_params.frameX,
808      frame_params.frameY), using blending method
809      frame_params.blendingMethod.
810    canvas contains the decoded image.
811    Show the contents of the canvas for
812    frame_params.frameDuration * 1ms.
813    dispose_method = frame_params.disposeMethod
814~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
815
816
817Example File Layouts
818--------------------
819
820A lossy encoded image with alpha may look as follows:
821
822~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
823RIFF/WEBP
824+- VP8X (descriptions of features used)
825+- ALPH (alpha bitstream)
826+- VP8 (bitstream)
827~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
828
829A losslessly encoded image may look as follows:
830
831~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
832RIFF/WEBP
833+- VP8X (descriptions of features used)
834+- XYZW (unknown chunk)
835+- VP8L (lossless bitstream)
836~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
837
838A lossless image with ICC profile and XMP metadata may
839look as follows:
840
841~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
842RIFF/WEBP
843+- VP8X (descriptions of features used)
844+- ICCP (color profile)
845+- VP8L (lossless bitstream)
846+- XMP  (metadata)
847~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
848
849An animated image with Exif metadata may look as follows:
850
851~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
852RIFF/WEBP
853+- VP8X (descriptions of features used)
854+- ANIM (global animation parameters)
855+- ANMF (frame1 parameters + data)
856+- ANMF (frame2 parameters + data)
857+- ANMF (frame3 parameters + data)
858+- ANMF (frame4 parameters + data)
859+- EXIF (metadata)
860~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
861
862[vp8spec]:  https://datatracker.ietf.org/doc/html/rfc6386
863[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
864[iccspec]: https://www.color.org/icc_specs2.xalter
865[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
866[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
867[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
868[rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174
869