xref: /aosp_15_r20/external/webp/doc/webp-container-spec.txt (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
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 to
24compress image data in a lossy way or (ii) the WebP lossless encoding. These
25encoding schemes should make it more efficient than older formats, such as JPEG,
26GIF, and PNG. It is optimized for fast image transfer over the network (for
27example, for websites). The WebP format has feature parity (color profile,
28metadata, animation, etc.) with other formats as well. This document describes
29the structure of a WebP file.
30
31The WebP container (that is, the RIFF container for WebP) allows feature support
32over and above the basic use case of WebP (that is, a file containing a single
33image encoded as a VP8 key frame). The WebP container provides additional
34support for the following:
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 Exchangeable Image File
40    Format (Exif) or Extensible Metadata Platform (XMP) format.
41
42  * Transparency: An image may have transparency, that is, an alpha channel.
43
44  * Color Profile: An image may have an embedded ICC profile as described
45    by the [International Color Consortium][iccspec].
46
47  * Animation: An image may have multiple frames with pauses between them,
48    making it an animation.
49
50Terminology & Basics
51--------------------
52
53The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
54"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
55document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][]
56when, and only when, they appear in all capitals, as shown here.
57
58A WebP file contains either a still image (that is, an encoded matrix of pixels)
59or an [animation](#animation). Optionally, it can also contain transparency
60information, a color profile and metadata. We refer to the matrix of pixels as
61the _canvas_ of the image.
62
63Bit numbering in chunk diagrams starts at `0` for the most significant bit
64('MSB 0'), as described in [RFC 1166][].
65
66Below are additional terms used throughout this document:
67
68_Reader/Writer_
69
70: Code that reads WebP files is referred to as a _reader_, while code that
71  writes them is referred to as a _writer_.
72
73_uint16_
74
75: A 16-bit, little-endian, unsigned integer.
76
77_uint24_
78
79: A 24-bit, little-endian, unsigned integer.
80
81_uint32_
82
83: A 32-bit, little-endian, unsigned integer.
84
85_FourCC_
86
87: A four-character code (FourCC) is a _uint32_ created by concatenating four
88  ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and
89 'AAAA' (0x41414141) are treated as different _FourCCs_.
90
91_1-based_
92
93: An unsigned integer field storing values offset by `-1`, for example, such a
94  field would store value _25_ as _24_.
95
96_ChunkHeader('ABCD')_
97
98: Used to describe the _FourCC_ and _Chunk Size_ header of individual chunks,
99  where 'ABCD' is the FourCC for the chunk. This element's size is 8 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 -- which 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 4 GiB 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 are 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
194'VP8 ' 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 that the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20).
210
211The VP8 bitstream format specification is described in [VP8 Data Format and
212Decoding Guide][rfc 6386]. 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, [Recommendation BT.601][rec601] SHOULD be used. Applications MAY
217use another conversion 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
241'VP8L' 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 a 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 necessary for reconstruction and color correction, that is 'VP8X',
294'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ' and 'VP8L', MUST appear in the order
295described earlier. Readers SHOULD fail when chunks necessary for reconstruction
296and color correction are out of order.
297
298[Metadata](#metadata) and [unknown](#unknown-chunks) chunks MAY appear out of
299order.
300
301**Rationale:** The chunks necessary for reconstruction should appear first in
302the file to allow a reader to begin decoding an image before receiving all of
303the data. An application may benefit from varying the order of metadata and
304custom chunks to suit the implementation.
305
306Extended WebP file header:
307{:#extended_header}
308
309     0                   1                   2                   3
310     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
311    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
312    |                                                               |
313    |                   WebP file header (12 bytes)                 |
314    |                                                               |
315    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
316    |                      ChunkHeader('VP8X')                      |
317    |                                                               |
318    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
319    |Rsv|I|L|E|X|A|R|                   Reserved                    |
320    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
321    |          Canvas Width Minus One               |             ...
322    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323    ...  Canvas Height Minus One    |
324    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
325
326Reserved (Rsv): 2 bits
327
328: MUST be `0`. Readers MUST ignore this field.
329
330ICC profile (I): 1 bit
331
332: Set if the file contains an 'ICCP' Chunk.
333
334Alpha (L): 1 bit
335
336: Set if any of the frames of the image contain transparency information
337  ("alpha").
338
339Exif metadata (E): 1 bit
340
341: Set if the file contains Exif metadata.
342
343XMP metadata (X): 1 bit
344
345: Set if the file contains XMP metadata.
346
347Animation (A): 1 bit
348
349: Set if this is an animated image. Data in 'ANIM' and 'ANMF' Chunks should be
350  used to control the animation.
351
352Reserved (R): 1 bit
353
354: MUST be `0`. Readers MUST ignore this field.
355
356Reserved: 24 bits
357
358: MUST be `0`. Readers MUST ignore this field.
359
360Canvas Width Minus One: 24 bits
361
362: _1-based_ width of the canvas in pixels.
363  The actual canvas width is `1 + Canvas Width Minus One`.
364
365Canvas Height Minus One: 24 bits
366
367: _1-based_ height of the canvas in pixels.
368  The actual canvas height is `1 + Canvas Height Minus One`.
369
370The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
371
372Future specifications may add more fields. Unknown fields MUST be ignored.
373
374### Chunks
375
376#### Animation
377
378An animation is controlled by 'ANIM' and 'ANMF' Chunks.
379
380'ANIM' Chunk:
381{:#anim_chunk}
382
383For an animated image, this chunk contains the _global parameters_ of the
384animation.
385
386     0                   1                   2                   3
387     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
388    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
389    |                      ChunkHeader('ANIM')                      |
390    |                                                               |
391    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
392    |                       Background Color                        |
393    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
394    |          Loop Count           |
395    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
396
397Background Color: 32 bits (_uint32_)
398
399: The default background color of the canvas in \[Blue, Green, Red, Alpha\]
400  byte order. This color MAY be used to fill the unused space on the canvas
401  around the frames, as well as the transparent pixels of the first frame.
402  The background color is also used when the Disposal method is `1`.
403
404**Note**:
405
406  * The background color MAY contain a non-opaque alpha value, even if the
407    _Alpha_ flag in the ['VP8X' Chunk](#extended_header) is unset.
408
409  * Viewer applications SHOULD treat the background color value as a hint and
410    are not required to use it.
411
412  * The canvas is cleared at the start of each loop. The background color MAY be
413    used to achieve this.
414
415Loop Count: 16 bits (_uint16_)
416
417: The number of times to loop the animation. If it is `0`, this means
418  infinitely.
419
420This chunk MUST appear if the _Animation_ flag in the 'VP8X' Chunk is set.
421If the _Animation_ flag is not set and this chunk is present, it MUST be
422ignored.
423
424'ANMF' Chunk:
425
426For animated images, this chunk contains information about a _single_ frame.
427If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
428
429     0                   1                   2                   3
430     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
431    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
432    |                      ChunkHeader('ANMF')                      |
433    |                                                               |
434    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
435    |                        Frame X                |             ...
436    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
437    ...          Frame Y            |   Frame Width Minus One     ...
438    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
439    ...             |           Frame Height Minus One              |
440    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
441    |                 Frame Duration                |  Reserved |B|D|
442    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
443    :                         Frame Data                            :
444    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
445
446Frame X: 24 bits (_uint24_)
447
448: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
449
450Frame Y: 24 bits (_uint24_)
451
452: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
453
454Frame Width Minus One: 24 bits (_uint24_)
455
456: The _1-based_ width of the frame.
457  The frame width is `1 + Frame Width Minus One`.
458
459Frame Height Minus One: 24 bits (_uint24_)
460
461: The _1-based_ height of the frame.
462  The frame height is `1 + Frame Height Minus One`.
463
464Frame Duration: 24 bits (_uint24_)
465
466: The time to wait before displaying the next frame, in 1-millisecond units.
467  Note that the interpretation of the Frame Duration of 0 (and often <= 10) is
468  defined by the implementation. Many tools and browsers assign a minimum
469  duration similar to GIF.
470
471Reserved: 6 bits
472
473: MUST be `0`. Readers MUST ignore this field.
474
475Blending method (B): 1 bit
476
477: Indicates how transparent pixels of _the current frame_ are to be blended
478  with corresponding pixels of the previous canvas:
479
480    * `0`: Use alpha-blending. After disposing of the previous frame, render the
481      current frame on the canvas using [alpha-blending](#alpha-blending). If
482      the current frame does not have an alpha channel, assume the alpha value
483      is 255, effectively replacing the rectangle.
484
485    * `1`: Do not blend. After disposing of the previous frame, render the
486      current frame on the canvas by overwriting the rectangle covered by the
487      current frame.
488
489Disposal method (D): 1 bit
490
491: Indicates how _the current frame_ is to be treated after it has been
492  displayed (before rendering the next frame) on the canvas:
493
494    * `0`: Do not dispose. Leave the canvas as is.
495
496    * `1`: Dispose to the background color. Fill the _rectangle_ on the canvas
497      covered by the _current frame_ with the background color specified in the
498      ['ANIM' Chunk](#anim_chunk).
499
500**Notes**:
501
502  * The frame disposal only applies to the _frame rectangle_, that is, the
503    rectangle defined by _Frame X_, _Frame Y_, _frame width_, and _frame
504    height_. It may or may not cover the whole canvas.
505
506{:#alpha-blending}
507  * Alpha-blending:
508
509    Given that each of the R, G, B, and A channels is 8 bits, and the RGB
510    channels are _not premultiplied_ by alpha, the formula for blending
511    'dst' onto 'src' is:
512
513~~~~~
514    blend.A = src.A + dst.A * (1 - src.A / 255)
515    if blend.A = 0 then
516      blend.RGB = 0
517    else
518      blend.RGB =
519          (src.RGB * src.A +
520           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
521~~~~~
522
523  * Alpha-blending SHOULD be done in linear color space, by taking into account
524    the [color profile](#color-profile) of the image. If the color profile is
525    not present, standard RGB (sRGB) is to be assumed. (Note that sRGB also
526    needs to be linearized due to a gamma of ~2.2.)
527
528Frame Data: _Chunk Size_ - `16` bytes
529
530: Consists of:
531
532  * An optional [alpha subchunk](#alpha) for the frame.
533
534  * A [bitstream subchunk](#bitstream-vp8vp8l) for the frame.
535
536  * An optional list of [unknown chunks](#unknown-chunks).
537
538**Note**: The 'ANMF' payload, _Frame Data_, consists of individual
539_padded_ chunks, as described by the [RIFF file format](#riff-file-format).
540
541#### Alpha
542
543     0                   1                   2                   3
544     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
545    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
546    |                      ChunkHeader('ALPH')                      |
547    |                                                               |
548    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
549    |Rsv| P | F | C |     Alpha Bitstream...                        |
550    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
551
552Reserved (Rsv): 2 bits
553
554: MUST be `0`. Readers MUST ignore this field.
555
556Preprocessing (P): 2 bits
557
558: These _informative_ bits are used to signal the preprocessing that has
559  been performed during compression. The decoder can use this information to
560  for example, dither the values or smooth the gradients prior to display.
561
562    * `0`: No preprocessing.
563    * `1`: Level reduction.
564
565Decoders are not required to use this information in any specified way.
566
567Filtering method (F): 2 bits
568
569: The filtering methods used are described as follows:
570
571    * `0`: None.
572    * `1`: Horizontal filter.
573    * `2`: Vertical filter.
574    * `3`: Gradient filter.
575
576For each pixel, filtering is performed using the following calculations.
577Assume the alpha values surrounding the current `X` position are labeled as:
578
579     C | B |
580    ---+---+
581     A | X |
582
583We seek to compute the alpha value at position `X`. First, a prediction is
584made depending on the filtering method:
585
586  * Method `0`: predictor = 0
587  * Method `1`: predictor = A
588  * Method `2`: predictor = B
589  * Method `3`: predictor = clip(A + B - C)
590
591where `clip(v)` is equal to:
592
593  * 0    if v < 0,
594  * 255  if v > 255, or
595  * v    otherwise
596
597The final value is derived by adding the decompressed value `X` to the
598predictor and using modulo-256 arithmetic to wrap the \[256..511\] range
599into the \[0..255\] one:
600
601`alpha = (predictor + X) % 256`
602
603There are special cases for the left-most and top-most pixel positions. For
604example, the top-left value at location (0, 0) uses 0 as the predictor value.
605Otherwise:
606
607  * For horizontal or gradient filtering methods, the left-most pixels at
608    location (0, y) are predicted using the location (0, y-1) just above.
609  * For vertical or gradient filtering methods, the top-most pixels at
610    location (x, 0) are predicted using the location (x-1, 0) on the left.
611
612Compression method (C): 2 bits
613
614: The compression method used:
615
616    * `0`: No compression.
617    * `1`: Compressed using the WebP lossless format.
618
619Alpha bitstream: _Chunk Size_ - `1` bytes
620
621: Encoded alpha bitstream.
622
623This optional chunk contains encoded alpha data for this frame. A frame
624containing a 'VP8L' Chunk SHOULD NOT contain this chunk.
625
626**Rationale**: The transparency information is already part of the 'VP8L'
627Chunk.
628
629The alpha channel data is stored as uncompressed raw data (when the
630compression method is '0') or compressed using the lossless format
631(when the compression method is '1').
632
633  * Raw data: This consists of a byte sequence of length = width * height,
634    containing all the 8-bit transparency values in scan order.
635
636  * Lossless format compression: The byte sequence is a compressed
637    image-stream (as described in ["WebP Lossless Bitstream Format"]
638    [webpllspec]) of implicit dimensions width x height. That is, this
639    image-stream does NOT contain any headers describing the image dimensions.
640
641    **Rationale**: The dimensions are already known from other sources,
642    so storing them again would be redundant and prone to error.
643
644    Once the image-stream is decoded into Alpha, Red, Green, Blue (ARGB) color
645    values, following the process described in the lossless format
646    specification, the transparency information must be extracted from the
647    *green* channel of the ARGB quadruplet.
648
649    **Rationale**: The green channel is allowed extra transformation
650    steps in the specification -- unlike the other channels -- that can
651    improve compression.
652
653#### Bitstream (VP8/VP8L)
654
655This chunk contains compressed bitstream data for a single frame.
656
657A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' (note the
658significant fourth-character space) as its FourCC, _or_ (ii) a 'VP8L' Chunk,
659using 'VP8L' as its FourCC.
660
661The formats of 'VP8 ' and 'VP8L' Chunks are as described in sections
662[Simple File Format (Lossy)](#simple-file-format-lossy)
663and [Simple File Format (Lossless)](#simple-file-format-lossless), respectively.
664
665#### Color Profile
666
667     0                   1                   2                   3
668     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
669    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
670    |                      ChunkHeader('ICCP')                      |
671    |                                                               |
672    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
673    :                       Color Profile                           :
674    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
675
676Color Profile: _Chunk Size_ bytes
677
678: ICC profile.
679
680This chunk MUST appear before the image data.
681
682There SHOULD be at most one such chunk. If there are more such chunks, readers
683MAY ignore all except the first one.
684See the [ICC Specification][iccspec] for details.
685
686If this chunk is not present, sRGB SHOULD be assumed.
687
688#### Metadata
689
690Metadata can be stored in 'EXIF' or 'XMP ' Chunks.
691
692There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there
693are more such chunks, readers MAY ignore all except the first one.
694
695The chunks are defined as follows:
696
697'EXIF' Chunk:
698
699     0                   1                   2                   3
700     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
701    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
702    |                      ChunkHeader('EXIF')                      |
703    |                                                               |
704    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
705    :                        Exif Metadata                          :
706    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
707
708Exif Metadata: _Chunk Size_ bytes
709
710: Image metadata in Exif format.
711
712'XMP ' Chunk:
713
714     0                   1                   2                   3
715     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
716    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
717    |                      ChunkHeader('XMP ')                      |
718    |                                                               |
719    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
720    :                        XMP Metadata                           :
721    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
722
723XMP Metadata: _Chunk Size_ bytes
724
725: Image metadata in XMP format.
726
727Note that the fourth character in the 'XMP ' FourCC is an ASCII space (0x20).
728
729Additional guidance about handling metadata can be found in the
730Metadata Working Group's ["Guidelines for Handling Metadata"][metadata].
731
732#### Unknown Chunks
733
734A RIFF chunk (described in the [RIFF File Format](#riff-file-format) section)
735whose FourCC is different from any of the chunks described in this document, is
736considered an _unknown chunk_.
737
738**Rationale**: Allowing unknown chunks gives a provision for future extension
739of the format and also allows storage of any application-specific data.
740
741A file MAY contain unknown chunks:
742
743  * at the end of the file, as described in [Extended WebP file
744    header](#extended_header) section, or
745  * at the end of 'ANMF' Chunks, as described in the
746    [Animation](#animation) section.
747
748Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their
749original order (unless they specifically intend to modify these chunks).
750
751### Canvas Assembly from Frames
752
753Here we provide an overview of how a reader MUST assemble a canvas in the case
754of an animated image.
755
756The process begins with creating a canvas using the dimensions given in the
757'VP8X' Chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus
758One + 1` pixels high. The `Loop Count` field from the 'ANIM' Chunk controls how
759many times the animation process is repeated. This is `Loop Count - 1` for
760nonzero `Loop Count` values or infinite if the `Loop Count` is zero.
761
762At the beginning of each loop iteration, the canvas is filled using the
763background color from the 'ANIM' Chunk or an application-defined color.
764
765'ANMF' Chunks contain individual frames given in display order. Before rendering
766each frame, the previous frame's `Disposal method` is applied.
767
768The rendering of the decoded frame begins at the Cartesian coordinates (`2 *
769Frame X`, `2 * Frame Y`), using the top-left corner of the canvas as the origin.
770`Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels
771high are rendered onto the canvas using the `Blending method`.
772
773The canvas is displayed for `Frame Duration` milliseconds. This continues until
774all frames given by 'ANMF' Chunks have been displayed. A new loop iteration is
775then begun, or the canvas is left in its final state if all iterations have been
776completed.
777
778The following pseudocode illustrates the rendering process. The notation
779_VP8X.field_ means the field in the 'VP8X' Chunk with the same description.
780
781~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
782VP8X.flags.hasAnimation MUST be TRUE
783canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
784         background color ANIM.background_color.
785loop_count ← ANIM.loopCount
786dispose_method ← Dispose to background color
787if loop_count == 0:
788  loop_count = ∞
789frame_params ← nil
790next chunk in image_data is ANMF MUST be TRUE
791for loop = 0..loop_count - 1
792  clear canvas to ANIM.background_color or application-defined color
793  until eof or non-ANMF chunk
794    frame_params.frameX = Frame X
795    frame_params.frameY = Frame Y
796    frame_params.frameWidth = Frame Width Minus One + 1
797    frame_params.frameHeight = Frame Height Minus One + 1
798    frame_params.frameDuration = Frame Duration
799    frame_right = frame_params.frameX + frame_params.frameWidth
800    frame_bottom = frame_params.frameY + frame_params.frameHeight
801    VP8X.canvasWidth >= frame_right MUST be TRUE
802    VP8X.canvasHeight >= frame_bottom MUST be TRUE
803    for subchunk in 'Frame Data':
804      if subchunk.tag == "ALPH":
805        alpha subchunks not found in 'Frame Data' earlier MUST be
806          TRUE
807        frame_params.alpha = alpha_data
808      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
809        bitstream subchunks not found in 'Frame Data' earlier MUST
810          be TRUE
811        frame_params.bitstream = bitstream_data
812    render frame with frame_params.alpha and frame_params.bitstream
813      on canvas with top-left corner at (frame_params.frameX,
814      frame_params.frameY), using Blending method
815      frame_params.blendingMethod.
816    canvas contains the decoded image.
817    Show the contents of the canvas for
818    frame_params.frameDuration * 1 ms.
819    dispose_method = frame_params.disposeMethod
820~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
821
822
823Example File Layouts
824--------------------
825
826A lossy-encoded image with alpha may look as follows:
827
828~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
829RIFF/WEBP
830+- VP8X (descriptions of features used)
831+- ALPH (alpha bitstream)
832+- VP8 (bitstream)
833~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
834
835A lossless-encoded image may look as follows:
836
837~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
838RIFF/WEBP
839+- VP8X (descriptions of features used)
840+- VP8L (lossless bitstream)
841+- XYZW (unknown chunk)
842~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
843
844A lossless image with an ICC profile and XMP metadata may
845look as follows:
846
847~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
848RIFF/WEBP
849+- VP8X (descriptions of features used)
850+- ICCP (color profile)
851+- VP8L (lossless bitstream)
852+- XMP  (metadata)
853~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
854
855An animated image with Exif metadata may look as follows:
856
857~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
858RIFF/WEBP
859+- VP8X (descriptions of features used)
860+- ANIM (global animation parameters)
861+- ANMF (frame1 parameters + data)
862+- ANMF (frame2 parameters + data)
863+- ANMF (frame3 parameters + data)
864+- ANMF (frame4 parameters + data)
865+- EXIF (metadata)
866~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
867
868[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
869[iccspec]: https://www.color.org/icc_specs2.xalter
870[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
871[rec601]: https://www.itu.int/rec/R-REC-BT.601
872[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
873[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
874[rfc 6386]: https://datatracker.ietf.org/doc/html/rfc6386
875[rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174
876