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