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