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