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