| rfc9649.original | rfc9649.txt | |||
|---|---|---|---|---|
| Network Working Group J. Zern | Internet Engineering Task Force (IETF) J. Zern | |||
| Internet-Draft P. Massimino | Request for Comments: 9649 P. Massimino | |||
| Intended status: Informational J. Alakuijala | Category: Informational J. Alakuijala | |||
| Expires: 6 October 2024 Google LLC | ISSN: 2070-1721 Google LLC | |||
| April 2024 | November 2024 | |||
| WebP Image Format | WebP Image Format | |||
| draft-zern-webp-15 | ||||
| Abstract | Abstract | |||
| This document defines the WebP image format and registers a media | This document defines the WebP image format and registers a media | |||
| type supporting its use. | type supporting its use. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This document is not an Internet Standards Track specification; it is | |||
| provisions of BCP 78 and BCP 79. | published for informational purposes. | |||
| Internet-Drafts are working documents of the Internet Engineering | ||||
| Task Force (IETF). Note that other groups may also distribute | ||||
| working documents as Internet-Drafts. The list of current Internet- | ||||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | ||||
| Internet-Drafts are draft documents valid for a maximum of six months | This document is a product of the Internet Engineering Task Force | |||
| and may be updated, replaced, or obsoleted by other documents at any | (IETF). It represents the consensus of the IETF community. It has | |||
| time. It is inappropriate to use Internet-Drafts as reference | received public review and has been approved for publication by the | |||
| material or to cite them other than as "work in progress." | Internet Engineering Steering Group (IESG). Not all documents | |||
| approved by the IESG are candidates for any level of Internet | ||||
| Standard; see Section 2 of RFC 7841. | ||||
| This Internet-Draft will expire on 3 October 2024. | Information about the current status of this document, any errata, | |||
| and how to provide feedback on it may be obtained at | ||||
| https://www.rfc-editor.org/info/rfc9649. | ||||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2024 IETF Trust and the persons identified as the | Copyright (c) 2024 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents | |||
| license-info) in effect on the date of publication of this document. | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| Please review these documents carefully, as they describe your rights | publication of this document. Please review these documents | |||
| and restrictions with respect to this document. Code Components | carefully, as they describe your rights and restrictions with respect | |||
| extracted from this document must include Revised BSD License text as | to this document. Code Components extracted from this document must | |||
| described in Section 4.e of the Trust Legal Provisions and are | include Revised BSD License text as described in Section 4.e of the | |||
| provided without warranty as described in the Revised BSD License. | Trust Legal Provisions and are provided without warranty as described | |||
| in the Revised BSD License. | ||||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction | |||
| 2. WebP Container Specification . . . . . . . . . . . . . . . . 3 | 2. WebP Container Specification | |||
| 2.1. Introduction (from "WebP Container Specification") . . . 3 | 2.1. Introduction (from "WebP Container Specification") | |||
| 2.2. Terminology & Basics . . . . . . . . . . . . . . . . . . 4 | 2.2. Terminology & Basics | |||
| 2.3. RIFF File Format . . . . . . . . . . . . . . . . . . . . 5 | 2.3. RIFF File Format | |||
| 2.4. WebP File Header . . . . . . . . . . . . . . . . . . . . 6 | 2.4. WebP File Header | |||
| 2.5. Simple File Format (Lossy) . . . . . . . . . . . . . . . 6 | 2.5. Simple File Format (Lossy) | |||
| 2.6. Simple File Format (Lossless) . . . . . . . . . . . . . . 7 | 2.6. Simple File Format (Lossless) | |||
| 2.7. Extended File Format . . . . . . . . . . . . . . . . . . 8 | 2.7. Extended File Format | |||
| 2.7.1. Chunks . . . . . . . . . . . . . . . . . . . . . . . 11 | 2.7.1. Chunks | |||
| 2.7.1.1. Animation . . . . . . . . . . . . . . . . . . . . 11 | 2.7.1.1. Animation | |||
| 2.7.1.2. Alpha . . . . . . . . . . . . . . . . . . . . . . 14 | 2.7.1.2. Alpha | |||
| 2.7.1.3. Bitstream (VP8/VP8L) . . . . . . . . . . . . . . 17 | 2.7.1.3. Bitstream (VP8/VP8L) | |||
| 2.7.1.4. Color Profile . . . . . . . . . . . . . . . . . . 17 | 2.7.1.4. Color Profile | |||
| 2.7.1.5. Metadata . . . . . . . . . . . . . . . . . . . . 18 | 2.7.1.5. Metadata | |||
| 2.7.1.6. Unknown Chunks . . . . . . . . . . . . . . . . . 19 | 2.7.1.6. Unknown Chunks | |||
| 2.7.2. Canvas Assembly from Frames . . . . . . . . . . . . . 19 | 2.7.2. Canvas Assembly from Frames | |||
| 2.7.3. Example File Layouts . . . . . . . . . . . . . . . . 21 | 2.7.3. Example File Layouts | |||
| 3. Specification for WebP Lossless Bitstream . . . . . . . . . . 22 | 3. Specification for WebP Lossless Bitstream | |||
| 3.1. Abstract (from "Specification for WebP Lossless | 3.1. Abstract (from "Specification for WebP Lossless Bitstream") | |||
| Bitstream") . . . . . . . . . . . . . . . . . . . . . . . 22 | ||||
| 3.2. Introduction (from "Specification for WebP Lossless | 3.2. Introduction (from "Specification for WebP Lossless | |||
| Bitstream") . . . . . . . . . . . . . . . . . . . . . . . 23 | Bitstream") | |||
| 3.3. Nomenclature . . . . . . . . . . . . . . . . . . . . . . 24 | 3.3. Nomenclature | |||
| 3.4. RIFF Header . . . . . . . . . . . . . . . . . . . . . . . 25 | 3.4. RIFF Header | |||
| 3.5. Transforms . . . . . . . . . . . . . . . . . . . . . . . 26 | 3.5. Transforms | |||
| 3.5.1. Predictor Transform . . . . . . . . . . . . . . . . . 27 | 3.5.1. Predictor Transform | |||
| 3.5.2. Color Transform . . . . . . . . . . . . . . . . . . . 31 | 3.5.2. Color Transform | |||
| 3.5.3. Subtract Green Transform . . . . . . . . . . . . . . 33 | 3.5.3. Subtract Green Transform | |||
| 3.5.4. Color Indexing Transform . . . . . . . . . . . . . . 34 | 3.5.4. Color Indexing Transform | |||
| 3.6. Image Data . . . . . . . . . . . . . . . . . . . . . . . 36 | 3.6. Image Data | |||
| 3.6.1. Roles of Image Data . . . . . . . . . . . . . . . . . 36 | 3.6.1. Roles of Image Data | |||
| 3.6.2. Encoding of Image Data . . . . . . . . . . . . . . . 36 | 3.6.2. Encoding of Image Data | |||
| 3.6.2.1. Prefix-Coded Literals . . . . . . . . . . . . . . 37 | 3.6.2.1. Prefix-Coded Literals | |||
| 3.6.2.2. LZ77 Backward Reference . . . . . . . . . . . . . 37 | 3.6.2.2. LZ77 Backward Reference | |||
| 3.6.2.3. Color Cache Coding . . . . . . . . . . . . . . . 40 | 3.6.2.3. Color Cache Coding | |||
| 3.7. Entropy Code . . . . . . . . . . . . . . . . . . . . . . 41 | 3.7. Entropy Code | |||
| 3.7.1. Overview . . . . . . . . . . . . . . . . . . . . . . 41 | 3.7.1. Overview | |||
| 3.7.2. Details . . . . . . . . . . . . . . . . . . . . . . . 41 | 3.7.2. Details | |||
| 3.7.2.1. Decoding and Building the Prefix Codes . . . . . 42 | 3.7.2.1. Decoding and Building the Prefix Codes | |||
| 3.7.2.2. Decoding of Meta Prefix Codes . . . . . . . . . . 44 | 3.7.2.2. Decoding of Meta Prefix Codes | |||
| 3.7.2.3. Decoding Entropy-Coded Image Data . . . . . . . . 46 | 3.7.2.3. Decoding Entropy-Coded Image Data | |||
| 3.8. Overall Structure of the Format . . . . . . . . . . . . . 47 | 3.8. Overall Structure of the Format | |||
| 3.8.1. Basic Structure . . . . . . . . . . . . . . . . . . . 47 | 3.8.1. Basic Structure | |||
| 3.8.2. Structure of Transforms . . . . . . . . . . . . . . . 47 | 3.8.2. Structure of Transforms | |||
| 3.8.3. Structure of the Image Data . . . . . . . . . . . . . 47 | 3.8.3. Structure of the Image Data | |||
| 4. Security Considerations | ||||
| 4. Security Considerations . . . . . . . . . . . . . . . . . . . 48 | 5. Interoperability Considerations | |||
| 5. Interoperability Considerations . . . . . . . . . . . . . . . 49 | 6. IANA Considerations | |||
| 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 49 | 6.1. The 'image/webp' Media Type | |||
| 6.1. The 'image/webp' Media Type . . . . . . . . . . . . . . . 49 | 6.1.1. Registration Details | |||
| 6.1.1. Registration Details . . . . . . . . . . . . . . . . 49 | 7. References | |||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 50 | 7.1. Normative References | |||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 50 | 7.2. Informative References | |||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 52 | Authors' Addresses | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 53 | ||||
| 1. Introduction | 1. Introduction | |||
| WebP is an image file format based on the Resource Interchange File | WebP is an image file format based on the Resource Interchange File | |||
| Format (RIFF) [RIFF-spec] (Section 2) that supports lossless and | Format (RIFF) [RIFF-spec] (Section 2) that supports lossless and | |||
| lossy compression as well as alpha (transparency) and animation. It | lossy compression as well as alpha (transparency) and animation. It | |||
| covers use cases similar to JPEG [JPEG-spec], PNG [RFC2083], and the | covers use cases similar to JPEG [JPEG-spec], PNG [RFC2083], and the | |||
| Graphics Interchange Format (GIF) [GIF-spec]. | Graphics Interchange Format (GIF) [GIF-spec]. | |||
| WebP consists of two compression algorithms used to reduce the size | WebP consists of two compression algorithms used to reduce the size | |||
| of image pixel data, including alpha (transparency) information. | of image pixel data, including alpha (transparency) information. | |||
| Lossy compression is achieved using VP8 intra-frame encoding | Lossy compression is achieved using VP8 intra-frame encoding | |||
| [RFC6386]. The lossless algorithm (Section 3) stores and restores | [RFC6386]. The lossless algorithm (Section 3) stores and restores | |||
| the pixel values exactly, including the color values for fully | the pixel values exactly, including the color values for fully | |||
| transparent pixels. A universal algorithm for sequential data | transparent pixels. A universal algorithm for sequential data | |||
| compression [LZ77], prefix coding [Huffman], and a color cache are | compression [LZ77], prefix coding [Huffman], and a color cache are | |||
| used for compression of the bulk data. | used for compression of the bulk data. | |||
| 2. WebP Container Specification | 2. WebP Container Specification | |||
| Note that this section is based on the documentation in the libwebp | | Note that this section is based on the documentation in the | |||
| source repository [webp-riff-src]. | | libwebp source repository [webp-riff-src]. | |||
| 2.1. Introduction (from "WebP Container Specification") | 2.1. Introduction (from "WebP Container Specification") | |||
| WebP is an image format that uses either (i) the VP8 intra-frame | WebP is an image format that uses either (i) the VP8 intra-frame | |||
| encoding [RFC6386] to compress image data in a lossy way or (ii) the | encoding [RFC6386] to compress image data in a lossy way or (ii) the | |||
| WebP lossless encoding (Section 3). These encoding schemes should | WebP lossless encoding (Section 3). These encoding schemes should | |||
| make it more efficient than older formats, such as JPEG, GIF, and | make it more efficient than older formats, such as JPEG, GIF, and | |||
| PNG. It is optimized for fast image transfer over the network (for | PNG. It is optimized for fast image transfer over the network (for | |||
| example, for websites). The WebP format has feature parity (color | example, for websites). The WebP format has feature parity (color | |||
| profile, metadata, animation, etc.) with other formats as well. This | profile, metadata, animation, etc.) with other formats as well. This | |||
| skipping to change at page 6, line 51 ¶ | skipping to change at line 278 ¶ | |||
| contents of individual chunks are described in the following | contents of individual chunks are described in the following | |||
| sections. | sections. | |||
| 2.5. Simple File Format (Lossy) | 2.5. Simple File Format (Lossy) | |||
| This layout SHOULD be used if the image requires lossy encoding and | This layout SHOULD be used if the image requires lossy encoding and | |||
| does not require transparency or other advanced features provided by | does not require transparency or other advanced features provided by | |||
| the extended format. Files with this layout are smaller and | the extended format. Files with this layout are smaller and | |||
| supported by older software. | supported by older software. | |||
| Simple WebP (lossy) file format: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | | | | | | |||
| | WebP file header (12 bytes) | | | WebP file header (12 bytes) | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : 'VP8 ' Chunk : | : 'VP8 ' Chunk : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 3: Simple WebP (Lossy) File Format | Figure 3: Simple WebP (Lossy) File Format | |||
| 'VP8 ' Chunk: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('VP8 ') | | | ChunkHeader('VP8 ') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : VP8 data : | : VP8 data : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 4: 'VP8 ' Chunk | Figure 4: 'VP8 ' Chunk | |||
| VP8 data: _Chunk Size_ bytes | VP8 data: _Chunk Size_ bytes | |||
| VP8 bitstream data. | VP8 bitstream data. | |||
| Note that the fourth character in the 'VP8 ' FourCC is an ASCII space | | Note that the fourth character in the 'VP8 ' FourCC is an ASCII | |||
| (0x20). | | space (0x20). | |||
| The VP8 bitstream format specification is described in [RFC6386]. | The VP8 bitstream format specification is described in [RFC6386]. | |||
| Note that the VP8 frame header contains the VP8 frame width and | ||||
| height. That is assumed to be the width and height of the canvas. | | Note that the VP8 frame header contains the VP8 frame width and | |||
| | height. That is assumed to be the width and height of the | ||||
| | canvas. | ||||
| The VP8 specification describes how to decode the image into Y'CbCr | The VP8 specification describes how to decode the image into Y'CbCr | |||
| format. To convert to RGB, Recommendation 601 [rec601] SHOULD be | format. To convert to RGB, Recommendation 601 [rec601] SHOULD be | |||
| used. Applications MAY use another conversion method, but visual | used. Applications MAY use another conversion method, but visual | |||
| results may differ among decoders. | results may differ among decoders. | |||
| 2.6. Simple File Format (Lossless) | 2.6. Simple File Format (Lossless) | |||
| Note: Older readers may not support files using the lossless format. | | Note: Older readers may not support files using the lossless | |||
| | format. | ||||
| This layout SHOULD be used if the image requires lossless encoding | This layout SHOULD be used if the image requires lossless encoding | |||
| (with an optional transparency channel) and does not require advanced | (with an optional transparency channel) and does not require advanced | |||
| features provided by the extended format. | features provided by the extended format. | |||
| Simple WebP (lossless) file format: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | | | | | | |||
| | WebP file header (12 bytes) | | | WebP file header (12 bytes) | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : 'VP8L' Chunk : | : 'VP8L' Chunk : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 5: Simple WebP (Lossless) File Format | Figure 5: Simple WebP (Lossless) File Format | |||
| 'VP8L' Chunk: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('VP8L') | | | ChunkHeader('VP8L') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : VP8L data : | : VP8L data : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 6: 'VP8L' Chunk | Figure 6: 'VP8L' Chunk | |||
| VP8L data: _Chunk Size_ bytes | VP8L data: _Chunk Size_ bytes | |||
| VP8L bitstream data. | VP8L bitstream data. | |||
| The specification of the VP8L bitstream can be found in Section 3. | The specification of the VP8L bitstream can be found in Section 3. | |||
| Note that the VP8L header contains the VP8L image width and height. | ||||
| That is assumed to be the width and height of the canvas. | | Note that the VP8L header contains the VP8L image width and | |||
| | height. That is assumed to be the width and height of the | ||||
| | canvas. | ||||
| 2.7. Extended File Format | 2.7. Extended File Format | |||
| Note: Older readers may not support files using the extended format. | | Note: Older readers may not support files using the extended | |||
| | format. | ||||
| An extended format file consists of: | An extended format file consists of: | |||
| * A 'VP8X' Chunk with information about features used in the file. | * A 'VP8X' Chunk with information about features used in the file. | |||
| * An optional 'ICCP' Chunk with a color profile. | * An optional 'ICCP' Chunk with a color profile. | |||
| * An optional 'ANIM' Chunk with animation control data. | * An optional 'ANIM' Chunk with animation control data. | |||
| * Image data. | * Image data. | |||
| skipping to change at page 9, line 21 ¶ | skipping to change at line 390 ¶ | |||
| For a _still image_, the _image data_ consists of a single frame, | For a _still image_, the _image data_ consists of a single frame, | |||
| which is made up of: | which is made up of: | |||
| * An optional alpha subchunk (Section 2.7.1.2). | * An optional alpha subchunk (Section 2.7.1.2). | |||
| * A bitstream subchunk (Section 2.7.1.3). | * A bitstream subchunk (Section 2.7.1.3). | |||
| For an _animated image_, the _image data_ consists of multiple | For an _animated image_, the _image data_ consists of multiple | |||
| frames. More details about frames can be found in Section 2.7.1.1. | frames. More details about frames can be found in Section 2.7.1.1. | |||
| All chunks necessary for reconstruction and color correction, that is | All chunks necessary for reconstruction and color correction, that | |||
| 'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ' and 'VP8L', MUST | is, 'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ', and 'VP8L', MUST | |||
| appear in the order described earlier. Readers SHOULD fail when | appear in the order described earlier. Readers SHOULD fail when | |||
| chunks necessary for reconstruction and color correction are out of | chunks necessary for reconstruction and color correction are out of | |||
| order. | order. | |||
| Metadata (Section 2.7.1.5) and unknown (Section 2.7.1.6) chunks MAY | Metadata (Section 2.7.1.5) and unknown chunks (Section 2.7.1.6) MAY | |||
| appear out of order. | appear out of order. | |||
| | Rationale: The chunks necessary for reconstruction should | | Rationale: The chunks necessary for reconstruction should | |||
| | appear first in the file to allow a reader to begin decoding an | | appear first in the file to allow a reader to begin decoding an | |||
| | image before receiving all of the data. An application may | | image before receiving all of the data. An application may | |||
| | benefit from varying the order of metadata and custom chunks to | | benefit from varying the order of metadata and custom chunks to | |||
| | suit the implementation. | | suit the implementation. | |||
| Extended WebP file header: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | | | | | | |||
| | WebP file header (12 bytes) | | | WebP file header (12 bytes) | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('VP8X') | | | ChunkHeader('VP8X') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| skipping to change at page 11, line 21 ¶ | skipping to change at line 470 ¶ | |||
| Future specifications may add more fields. Unknown fields MUST be | Future specifications may add more fields. Unknown fields MUST be | |||
| ignored. | ignored. | |||
| 2.7.1. Chunks | 2.7.1. Chunks | |||
| 2.7.1.1. Animation | 2.7.1.1. Animation | |||
| An animation is controlled by 'ANIM' and 'ANMF' Chunks. | An animation is controlled by 'ANIM' and 'ANMF' Chunks. | |||
| 'ANIM' Chunk: | ||||
| For an animated image, this chunk contains the _global parameters_ of | ||||
| the animation. | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('ANIM') | | | ChunkHeader('ANIM') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Background Color | | | Background Color | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Loop Count | | | Loop Count | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 8: 'ANIM' Chunk | Figure 8: 'ANIM' Chunk | |||
| For an animated image, this chunk contains the _global parameters_ of | ||||
| the animation. | ||||
| Background Color: 32 bits (_uint32_) | Background Color: 32 bits (_uint32_) | |||
| The default background color of the canvas in [Blue, Green, Red, | The default background color of the canvas in [Blue, Green, Red, | |||
| Alpha] byte order. This color MAY be used to fill the unused | Alpha] byte order. This color MAY be used to fill the unused | |||
| space on the canvas around the frames, as well as the transparent | space on the canvas around the frames, as well as the transparent | |||
| pixels of the first frame. The background color is also used | pixels of the first frame. The background color is also used | |||
| when the Disposal method is 1. | when the Disposal method is 1. | |||
| Note: | Notes: | |||
| * The background color MAY contain a nonopaque alpha value, even | * The background color MAY contain a nonopaque alpha value, even | |||
| if the _Alpha_ flag in the 'VP8X' Chunk (Figure 7) is unset. | if the _Alpha_ flag in the 'VP8X' Chunk (Figure 7) is unset. | |||
| * Viewer applications SHOULD treat the background color value as | * Viewer applications SHOULD treat the background color value as | |||
| a hint and are not required to use it. | a hint and are not required to use it. | |||
| * The canvas is cleared at the start of each loop. The | * The canvas is cleared at the start of each loop. The | |||
| background color MAY be used to achieve this. | background color MAY be used to achieve this. | |||
| Loop Count: 16 bits (_uint16_) | Loop Count: 16 bits (_uint16_) | |||
| The number of times to loop the animation. If it is 0, this | The number of times to loop the animation. If it is 0, this | |||
| means infinitely. | means infinitely. | |||
| This chunk MUST appear if the _Animation_ flag in the 'VP8X' Chunk is | This chunk MUST appear if the _Animation_ flag in the 'VP8X' Chunk is | |||
| set. If the _Animation_ flag is not set and this chunk is present, | set. If the _Animation_ flag is not set and this chunk is present, | |||
| it MUST be ignored. | it MUST be ignored. | |||
| 'ANMF' Chunk: | ||||
| For animated images, this chunk contains information about a _single_ | ||||
| frame. If the _Animation flag_ is not set, then this chunk SHOULD | ||||
| NOT be present. | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('ANMF') | | | ChunkHeader('ANMF') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Frame X | ... | | Frame X | ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| ... Frame Y | Frame Width Minus One ... | ... Frame Y | Frame Width Minus One ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| ... | Frame Height Minus One | | ... | Frame Height Minus One | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Frame Duration | Reserved |B|D| | | Frame Duration | Reserved |B|D| | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : Frame Data : | : Frame Data : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 9: 'ANMF' Chunk | Figure 9: 'ANMF' Chunk | |||
| For animated images, this chunk contains information about a _single_ | ||||
| frame. If the _Animation flag_ is not set, then this chunk SHOULD | ||||
| NOT be present. | ||||
| Frame X: 24 bits (_uint24_) | Frame X: 24 bits (_uint24_) | |||
| The X coordinate of the upper left corner of the frame is Frame X | The X coordinate of the upper left corner of the frame is Frame X | |||
| * 2. | * 2. | |||
| Frame Y: 24 bits (_uint24_) | Frame Y: 24 bits (_uint24_) | |||
| The Y coordinate of the upper left corner of the frame is Frame Y | The Y coordinate of the upper left corner of the frame is Frame Y | |||
| * 2. | * 2. | |||
| Frame Width Minus One: 24 bits (_uint24_) | Frame Width Minus One: 24 bits (_uint24_) | |||
| The _1-based_ width of the frame. The frame width is 1 + Frame | The _1-based_ width of the frame. The frame width is 1 + Frame | |||
| skipping to change at page 13, line 24 ¶ | skipping to change at line 566 ¶ | |||
| Reserved: 6 bits | Reserved: 6 bits | |||
| MUST be 0. Readers MUST ignore this field. | MUST be 0. Readers MUST ignore this field. | |||
| Blending method (B): 1 bit | Blending method (B): 1 bit | |||
| Indicates how transparent pixels of _the current frame_ are to be | Indicates how transparent pixels of _the current frame_ are to be | |||
| blended with corresponding pixels of the previous canvas: | blended with corresponding pixels of the previous canvas: | |||
| * 0: Use alpha-blending. After disposing of the previous frame, | * 0: Use alpha-blending. After disposing of the previous frame, | |||
| render the current frame on the canvas using alpha-blending | render the current frame on the canvas using alpha-blending | |||
| (Section 2.7.1.1, Paragraph 10, Item 16.4.2). If the current | (Section 2.7.1.1, Paragraph 8, Item 16.4.2). If the current | |||
| frame does not have an alpha channel, assume the alpha value | frame does not have an alpha channel, assume the alpha value | |||
| is 255, effectively replacing the rectangle. | is 255, effectively replacing the rectangle. | |||
| * 1: Do not blend. After disposing of the previous frame, | * 1: Do not blend. After disposing of the previous frame, | |||
| render the current frame on the canvas by overwriting the | render the current frame on the canvas by overwriting the | |||
| rectangle covered by the current frame. | rectangle covered by the current frame. | |||
| Disposal method (D): 1 bit | Disposal method (D): 1 bit | |||
| Indicates how _the current frame_ is to be treated after it has | Indicates how _the current frame_ is to be treated after it has | |||
| been displayed (before rendering the next frame) on the canvas: | been displayed (before rendering the next frame) on the canvas: | |||
| * 0: Do not dispose. Leave the canvas as is. | * 0: Do not dispose. Leave the canvas as is. | |||
| * 1: Dispose to the background color. Fill the _rectangle_ on | * 1: Dispose to the background color. Fill the _rectangle_ on | |||
| the canvas covered by the _current frame_ with the background | the canvas covered by the _current frame_ with the background | |||
| color specified in the 'ANIM' Chunk (Section 2.7.1.1, | color specified in the 'ANIM' Chunk (Figure 8). | |||
| Paragraph 2). | ||||
| Notes: | Notes: | |||
| * The frame disposal only applies to the _frame rectangle_, that | * The frame disposal only applies to the _frame rectangle_, that | |||
| is, the rectangle defined by _Frame X_, _Frame Y_, _frame | is, the rectangle defined by _Frame X_, _Frame Y_, _frame | |||
| width_, and _frame height_. It may or may not cover the whole | width_, and _frame height_. It may or may not cover the whole | |||
| canvas. | canvas. | |||
| * Alpha-blending: | * Alpha-blending: | |||
| skipping to change at page 14, line 23 ¶ | skipping to change at line 611 ¶ | |||
| blend.RGB = | blend.RGB = | |||
| (src.RGB * src.A + | (src.RGB * src.A + | |||
| dst.RGB * dst.A * (1 - src.A / 255)) / blend.A | dst.RGB * dst.A * (1 - src.A / 255)) / blend.A | |||
| * Alpha-blending SHOULD be done in linear color space by taking | * Alpha-blending SHOULD be done in linear color space by taking | |||
| into account the color profile (Section 2.7.1.4) of the image. | into account the color profile (Section 2.7.1.4) of the image. | |||
| If the color profile is not present, standard RGB (sRGB) is to | If the color profile is not present, standard RGB (sRGB) is to | |||
| be assumed. (Note that sRGB also needs to be linearized due | be assumed. (Note that sRGB also needs to be linearized due | |||
| to a gamma of ~2.2.) | to a gamma of ~2.2.) | |||
| Frame Data: _Chunk Size_ - 16 bytes | Frame Data: _Chunk Size_ bytes - 16 | |||
| Consists of: | Consists of: | |||
| * An optional alpha subchunk (Section 2.7.1.2) for the frame. | * An optional alpha subchunk (Section 2.7.1.2) for the frame. | |||
| * A bitstream subchunk (Section 2.7.1.3) for the frame. | * A bitstream subchunk (Section 2.7.1.3) for the frame. | |||
| * An optional list of unknown chunks (Section 2.7.1.6). | * An optional list of unknown chunks (Section 2.7.1.6). | |||
| Note: The 'ANMF' payload, _Frame Data_, consists of individual | | Note: The 'ANMF' payload, _Frame Data_, consists of individual | |||
| _padded_ chunks, as described by the RIFF file format (Section 2.3). | | _padded_ chunks, as described by the RIFF file format | |||
| | (Section 2.3). | ||||
| 2.7.1.2. Alpha | 2.7.1.2. Alpha | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('ALPH') | | | ChunkHeader('ALPH') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| |Rsv| P | F | C | Alpha Bitstream... | | |Rsv| P | F | C | Alpha Bitstream... | | |||
| skipping to change at page 15, line 35 ¶ | skipping to change at line 672 ¶ | |||
| * 3: Gradient filter. | * 3: Gradient filter. | |||
| For each pixel, filtering is performed using the following | For each pixel, filtering is performed using the following | |||
| calculations. Assume the alpha values surrounding the current X | calculations. Assume the alpha values surrounding the current X | |||
| position are labeled as: | position are labeled as: | |||
| C | B | | C | B | | |||
| ---+---+ | ---+---+ | |||
| A | X | | A | X | | |||
| Figure 11 | Figure 11: Pixels Used in Alpha Filtering | |||
| We seek to compute the alpha value at position X. First, a | We seek to compute the alpha value at position X. First, a | |||
| prediction is made depending on the filtering method: | prediction is made depending on the filtering method: | |||
| * Method 0: predictor = 0 | * Method 0: predictor = 0 | |||
| * Method 1: predictor = A | * Method 1: predictor = A | |||
| * Method 2: predictor = B | * Method 2: predictor = B | |||
| skipping to change at page 16, line 35 ¶ | skipping to change at line 720 ¶ | |||
| pixels at location (x, 0) are predicted using the location | pixels at location (x, 0) are predicted using the location | |||
| (x-1, 0) on the left. | (x-1, 0) on the left. | |||
| Compression method (C): 2 bits | Compression method (C): 2 bits | |||
| The compression method used: | The compression method used: | |||
| * 0: No compression. | * 0: No compression. | |||
| * 1: Compressed using the WebP lossless format. | * 1: Compressed using the WebP lossless format. | |||
| Alpha bitstream: _Chunk Size_ - 1 bytes | Alpha bitstream: _Chunk Size_ bytes - 1 | |||
| Encoded alpha bitstream. | Encoded alpha bitstream. | |||
| This optional chunk contains encoded alpha data for this frame. A | This optional chunk contains encoded alpha data for this frame. A | |||
| frame containing a 'VP8L' Chunk SHOULD NOT contain this chunk. | frame containing a 'VP8L' Chunk SHOULD NOT contain this chunk. | |||
| | Rationale: The transparency information is already part of the | | Rationale: The transparency information is already part of the | |||
| | 'VP8L' Chunk. | | 'VP8L' Chunk. | |||
| The alpha channel data is stored as uncompressed raw data (when the | The alpha channel data is stored as uncompressed raw data (when the | |||
| compression method is '0') or compressed using the lossless format | compression method is '0') or compressed using the lossless format | |||
| skipping to change at page 17, line 10 ¶ | skipping to change at line 742 ¶ | |||
| * Raw data: This consists of a byte sequence of length = width * | * Raw data: This consists of a byte sequence of length = width * | |||
| height, containing all the 8-bit transparency values in scan | height, containing all the 8-bit transparency values in scan | |||
| order. | order. | |||
| * Lossless format compression: The byte sequence is a compressed | * Lossless format compression: The byte sequence is a compressed | |||
| image-stream (as described in Section 3) of implicit dimensions | image-stream (as described in Section 3) of implicit dimensions | |||
| width x height. That is, this image-stream does NOT contain any | width x height. That is, this image-stream does NOT contain any | |||
| headers describing the image dimensions. | headers describing the image dimensions. | |||
| Rationale: The dimensions are already known from other sources, so | | Rationale: The dimensions are already known from other sources, | |||
| storing them again would be redundant and prone to errors. | | so storing them again would be redundant and prone to errors. | |||
| Once the image-stream is decoded into Alpha, Red, Green, Blue | Once the image-stream is decoded into Alpha, Red, Green, Blue | |||
| (ARGB) color values, following the process described in the | (ARGB) color values, following the process described in the | |||
| lossless format specification, the transparency information must | lossless format specification, the transparency information must | |||
| be extracted from the green channel of the ARGB quadruplet. | be extracted from the green channel of the ARGB quadruplet. | |||
| Rationale: The green channel is allowed extra transformation steps | | Rationale: The green channel is allowed extra transformation | |||
| in the specification -- unlike the other channels -- that can | | steps in the specification -- unlike the other channels -- that | |||
| improve compression. | | can improve compression. | |||
| 2.7.1.3. Bitstream (VP8/VP8L) | 2.7.1.3. Bitstream (VP8/VP8L) | |||
| This chunk contains compressed bitstream data for a single frame. | This chunk contains compressed bitstream data for a single frame. | |||
| A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' | A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' | |||
| (note the significant fourth-character space) as its FourCC, _or_ | (note the significant fourth-character space) as its FourCC, _or_ | |||
| (ii) a 'VP8L' Chunk, using 'VP8L' as its FourCC. | (ii) a 'VP8L' Chunk, using 'VP8L' as its FourCC. | |||
| The formats of' VP8 ' and 'VP8L' Chunks are as described in Sections | The formats of' VP8 ' and 'VP8L' Chunks are as described in Sections | |||
| skipping to change at page 18, line 21 ¶ | skipping to change at line 799 ¶ | |||
| 2.7.1.5. Metadata | 2.7.1.5. Metadata | |||
| Metadata can be stored in 'EXIF' or 'XMP ' Chunks. | Metadata can be stored in 'EXIF' or 'XMP ' Chunks. | |||
| There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). | There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). | |||
| If there are more such chunks, readers MAY ignore all except the | If there are more such chunks, readers MAY ignore all except the | |||
| first one. | first one. | |||
| The chunks are defined as follows: | The chunks are defined as follows: | |||
| 'EXIF' Chunk: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('EXIF') | | | ChunkHeader('EXIF') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : Exif Metadata : | : Exif Metadata : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 13: 'EXIF' Chunk | Figure 13: 'EXIF' Chunk | |||
| Exif Metadata: _Chunk Size_ bytes | Exif Metadata: _Chunk Size_ bytes | |||
| Image metadata in [Exif] format. | Image metadata in [Exif] format. | |||
| 'XMP ' Chunk: | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 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 | 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 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ChunkHeader('XMP ') | | | ChunkHeader('XMP ') | | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| : XMP Metadata : | : XMP Metadata : | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 14: 'XMP ' Chunk | Figure 14: 'XMP ' Chunk | |||
| XMP Metadata: _Chunk Size_ bytes | XMP Metadata: _Chunk Size_ bytes | |||
| Image metadata in [XMP] format. | Image metadata in [XMP] format. | |||
| Note that the fourth character in the 'XMP ' FourCC is an ASCII space | | Note that the fourth character in the 'XMP ' FourCC is an ASCII | |||
| (0x20). | | space (0x20). | |||
| Additional guidance about handling metadata can be found in the | Additional guidance about handling metadata can be found in the | |||
| Metadata Working Group's "Guidelines For Handling Image Metadata" | Metadata Working Group's "Guidelines For Handling Image Metadata" | |||
| [MWG]. | [MWG]. | |||
| 2.7.1.6. Unknown Chunks | 2.7.1.6. Unknown Chunks | |||
| A RIFF chunk (described in Section 2.3) whose _FourCC_ is different | A RIFF chunk (described in Section 2.3) whose _FourCC_ is different | |||
| from any of the chunks described in this section is considered an | from any of the chunks described in this section is considered an | |||
| _unknown chunk_. | _unknown chunk_. | |||
| skipping to change at page 21, line 7 ¶ | skipping to change at line 891 ¶ | |||
| continues until all frames given by 'ANMF' Chunks have been | continues until all frames given by 'ANMF' Chunks have been | |||
| displayed. A new loop iteration is then begun, or the canvas is left | displayed. A new loop iteration is then begun, or the canvas is left | |||
| in its final state if all iterations have been completed. | in its final state if all iterations have been completed. | |||
| The following pseudocode illustrates the rendering process. The | The following pseudocode illustrates the rendering process. The | |||
| notation _VP8X.field_ means the field in the 'VP8X' Chunk with the | notation _VP8X.field_ means the field in the 'VP8X' Chunk with the | |||
| same description. | same description. | |||
| VP8X.flags.hasAnimation MUST be TRUE | VP8X.flags.hasAnimation MUST be TRUE | |||
| canvas <- new image of size VP8X.canvasWidth x VP8X.canvasHeight with | canvas <- new image of size VP8X.canvasWidth x VP8X.canvasHeight with | |||
| background color ANIM.background_color. | background color ANIM.background_color or | |||
| application-defined color. | ||||
| loop_count <- ANIM.loopCount | loop_count <- ANIM.loopCount | |||
| dispose_method <- Dispose to background color | dispose_method <- Dispose to background color | |||
| if loop_count == 0: | if loop_count == 0: | |||
| loop_count = inf | loop_count = inf | |||
| frame_params <- nil | frame_params <- nil | |||
| next chunk in image_data is ANMF MUST be TRUE | next chunk in image_data is ANMF MUST be TRUE | |||
| for loop = 0..loop_count - 1 | for loop = 0..loop_count - 1 | |||
| clear canvas to ANIM.background_color or application-defined color | clear canvas to ANIM.background_color or application-defined color | |||
| until eof or non-ANMF chunk | until eof or non-ANMF chunk | |||
| frame_params.frameX = Frame X | frame_params.frameX = Frame X | |||
| skipping to change at page 21, line 35 ¶ | skipping to change at line 920 ¶ | |||
| VP8X.canvasHeight >= frame_bottom MUST be TRUE | VP8X.canvasHeight >= frame_bottom MUST be TRUE | |||
| for subchunk in 'Frame Data': | for subchunk in 'Frame Data': | |||
| if subchunk.tag == "ALPH": | if subchunk.tag == "ALPH": | |||
| alpha subchunks not found in 'Frame Data' earlier MUST be | alpha subchunks not found in 'Frame Data' earlier MUST be | |||
| TRUE | TRUE | |||
| frame_params.alpha = alpha_data | frame_params.alpha = alpha_data | |||
| else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L": | else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L": | |||
| bitstream subchunks not found in 'Frame Data' earlier MUST | bitstream subchunks not found in 'Frame Data' earlier MUST | |||
| be TRUE | be TRUE | |||
| frame_params.bitstream = bitstream_data | frame_params.bitstream = bitstream_data | |||
| apply dispose_method. | ||||
| render frame with frame_params.alpha and frame_params.bitstream | render frame with frame_params.alpha and frame_params.bitstream | |||
| on canvas with top-left corner at (frame_params.frameX, | on canvas with top-left corner at (frame_params.frameX, | |||
| frame_params.frameY), using Blending method | frame_params.frameY), using Blending method | |||
| frame_params.blendingMethod. | frame_params.blendingMethod. | |||
| canvas contains the decoded image. | canvas contains the decoded image. | |||
| Show the contents of the canvas for | Show the contents of the canvas for | |||
| frame_params.frameDuration * 1 ms. | frame_params.frameDuration * 1 ms. | |||
| dispose_method = frame_params.disposeMethod | dispose_method = frame_params.disposeMethod | |||
| 2.7.3. Example File Layouts | 2.7.3. Example File Layouts | |||
| skipping to change at page 22, line 41 ¶ | skipping to change at line 976 ¶ | |||
| +- ANMF (frame1 parameters + data) | +- ANMF (frame1 parameters + data) | |||
| +- ANMF (frame2 parameters + data) | +- ANMF (frame2 parameters + data) | |||
| +- ANMF (frame3 parameters + data) | +- ANMF (frame3 parameters + data) | |||
| +- ANMF (frame4 parameters + data) | +- ANMF (frame4 parameters + data) | |||
| +- EXIF (metadata) | +- EXIF (metadata) | |||
| Figure 18: An Animated Image with Exif Metadata | Figure 18: An Animated Image with Exif Metadata | |||
| 3. Specification for WebP Lossless Bitstream | 3. Specification for WebP Lossless Bitstream | |||
| Note that this section is based on the documentation in the libwebp | | Note that this section is based on the documentation in the | |||
| source repository [webp-lossless-src]. | | libwebp source repository [webp-lossless-src]. | |||
| 3.1. Abstract (from "Specification for WebP Lossless Bitstream") | 3.1. Abstract (from "Specification for WebP Lossless Bitstream") | |||
| WebP lossless is an image format for lossless compression of ARGB | WebP lossless is an image format for lossless compression of ARGB | |||
| images. The lossless format stores and restores the pixel values | images. The lossless format stores and restores the pixel values | |||
| exactly, including the color values for pixels whose alpha value is | exactly, including the color values for pixels whose alpha value is | |||
| 0. The format uses subresolution images, recursively embedded into | 0. The format uses subresolution images, recursively embedded into | |||
| the format itself, for storing statistical data about the images, | the format itself, for storing statistical data about the images, | |||
| such as the used entropy codes, spatial predictors, color space | such as the used entropy codes, spatial predictors, color space | |||
| conversion, and color table. A universal algorithm for sequential | conversion, and color table. A universal algorithm for sequential | |||
| skipping to change at page 26, line 50 ¶ | skipping to change at line 1173 ¶ | |||
| +==========================+=====+ | +==========================+=====+ | |||
| | PREDICTOR_TRANSFORM | 0 | | | PREDICTOR_TRANSFORM | 0 | | |||
| +--------------------------+-----+ | +--------------------------+-----+ | |||
| | COLOR_TRANSFORM | 1 | | | COLOR_TRANSFORM | 1 | | |||
| +--------------------------+-----+ | +--------------------------+-----+ | |||
| | SUBTRACT_GREEN_TRANSFORM | 2 | | | SUBTRACT_GREEN_TRANSFORM | 2 | | |||
| +--------------------------+-----+ | +--------------------------+-----+ | |||
| | COLOR_INDEXING_TRANSFORM | 3 | | | COLOR_INDEXING_TRANSFORM | 3 | | |||
| +--------------------------+-----+ | +--------------------------+-----+ | |||
| Table 1 | Table 1: Transform Types | |||
| The transform type is followed by the transform data. Transform data | The transform type is followed by the transform data. Transform data | |||
| contains the information required to apply the inverse transform and | contains the information required to apply the inverse transform and | |||
| depends on the transform type. The inverse transforms are applied in | depends on the transform type. The inverse transforms are applied in | |||
| the reverse order that they are read from the bitstream, that is, | the reverse order that they are read from the bitstream, that is, | |||
| last one first. | last one first. | |||
| Next, we describe the transform data for different types. | Next, we describe the transform data for different types. | |||
| 3.5.1. Predictor Transform | 3.5.1. Predictor Transform | |||
| skipping to change at page 28, line 15 ¶ | skipping to change at line 1232 ¶ | |||
| We chose the neighboring pixels (TL, T, TR, and L) of the current | We chose the neighboring pixels (TL, T, TR, and L) of the current | |||
| pixel (P) as follows: | pixel (P) as follows: | |||
| O O O O O O O O O O O | O O O O O O O O O O O | |||
| O O O O O O O O O O O | O O O O O O O O O O O | |||
| O O O O TL T TR O O O O | O O O O TL T TR O O O O | |||
| O O O O L P X X X X X | O O O O L P X X X X X | |||
| X X X X X X X X X X X | X X X X X X X X X X X | |||
| X X X X X X X X X X X | X X X X X X X X X X X | |||
| Figure 19 | Figure 19: Neighboring Pixels of the Current Pixel (P) | |||
| where TL means top-left, T means top, TR means top-right, and L means | where TL means top-left, T means top, TR means top-right, and L means | |||
| left. At the time of predicting a value for P, all O, TL, T, TR, and | left. At the time of predicting a value for P, all O, TL, T, TR, and | |||
| L pixels have already been processed, and the P pixel and all X | L pixels have already been processed, and the P pixel and all X | |||
| pixels are unknown. | pixels are unknown. | |||
| Given the preceding neighboring pixels, the different prediction | Given the preceding neighboring pixels, the different prediction | |||
| modes are defined as follows. | modes are defined as follows. | |||
| +======+======================================================+ | +======+======================================================+ | |||
| skipping to change at page 29, line 37 ¶ | skipping to change at line 1274 ¶ | |||
| +------+------------------------------------------------------+ | +------+------------------------------------------------------+ | |||
| | 10 | Average2(Average2(L, TL), Average2(T, TR)) | | | 10 | Average2(Average2(L, TL), Average2(T, TR)) | | |||
| +------+------------------------------------------------------+ | +------+------------------------------------------------------+ | |||
| | 11 | Select(L, T, TL) | | | 11 | Select(L, T, TL) | | |||
| +------+------------------------------------------------------+ | +------+------------------------------------------------------+ | |||
| | 12 | ClampAddSubtractFull(L, T, TL) | | | 12 | ClampAddSubtractFull(L, T, TL) | | |||
| +------+------------------------------------------------------+ | +------+------------------------------------------------------+ | |||
| | 13 | ClampAddSubtractHalf(Average2(L, T), TL) | | | 13 | ClampAddSubtractHalf(Average2(L, T), TL) | | |||
| +------+------------------------------------------------------+ | +------+------------------------------------------------------+ | |||
| Table 2 | Table 2: Prediction Modes | |||
| Average2 is defined as follows for each ARGB component: | Average2 is defined as follows for each ARGB component: | |||
| uint8 Average2(uint8 a, uint8 b) { | uint8 Average2(uint8 a, uint8 b) { | |||
| return (a + b) / 2; | return (a + b) / 2; | |||
| } | } | |||
| The Select predictor is defined as follows: | The Select predictor is defined as follows: | |||
| uint32 Select(uint32 L, uint32 T, uint32 TL) { | uint32 Select(uint32 L, uint32 T, uint32 TL) { | |||
| skipping to change at page 30, line 45 ¶ | skipping to change at line 1324 ¶ | |||
| int ClampAddSubtractFull(int a, int b, int c) { | int ClampAddSubtractFull(int a, int b, int c) { | |||
| return Clamp(a + b - c); | return Clamp(a + b - c); | |||
| } | } | |||
| int ClampAddSubtractHalf(int a, int b) { | int ClampAddSubtractHalf(int a, int b) { | |||
| return Clamp(a + (a - b) / 2); | return Clamp(a + (a - b) / 2); | |||
| } | } | |||
| There are special handling rules for some border pixels. If there is | There are special handling rules for some border pixels. If there is | |||
| a prediction transform, regardless of the mode [0..13] for these | a predictor transform, regardless of the mode [0..13] for these | |||
| pixels, the predicted value for the left-topmost pixel of the image | pixels, the predicted value for the left-topmost pixel of the image | |||
| is 0xff000000, all pixels on the top row are L-pixel, and all pixels | is 0xff000000, all pixels on the top row are L-pixel, and all pixels | |||
| on the leftmost column are T-pixel. | on the leftmost column are T-pixel. | |||
| Addressing the TR-pixel for pixels on the rightmost column is | Addressing the TR-pixel for pixels on the rightmost column is | |||
| exceptional. The pixels on the rightmost column are predicted by | exceptional. The pixels on the rightmost column are predicted by | |||
| using the modes [0..13], just like pixels not on the border, but the | using the modes [0..13], just like pixels not on the border, but the | |||
| leftmost pixel on the same row as the current pixel is instead used | leftmost pixel on the same row as the current pixel is instead used | |||
| as the TR-pixel. | as the TR-pixel. | |||
| skipping to change at page 32, line 38 ¶ | skipping to change at line 1408 ¶ | |||
| A conversion from the 8-bit unsigned representation (uint8) to the | A conversion from the 8-bit unsigned representation (uint8) to the | |||
| 8-bit signed one (int8) is required before calling | 8-bit signed one (int8) is required before calling | |||
| ColorTransformDelta(). The signed value should be interpreted as an | ColorTransformDelta(). The signed value should be interpreted as an | |||
| 8-bit two's complement number (that is: uint8 range [128..255] is | 8-bit two's complement number (that is: uint8 range [128..255] is | |||
| mapped to the [-128..-1] range of its converted int8 value). | mapped to the [-128..-1] range of its converted int8 value). | |||
| The multiplication is to be done using more precision (with at least | The multiplication is to be done using more precision (with at least | |||
| 16-bit precision). The sign extension property of the shift | 16-bit precision). The sign extension property of the shift | |||
| operation does not matter here; only the lowest 8 bits are used from | operation does not matter here; only the lowest 8 bits are used from | |||
| the result, and there the sign extension shifting and unsigned | the result, and in these bits, the sign extension shifting and | |||
| shifting are consistent with each other. | unsigned shifting are consistent with each other. | |||
| Now, we describe the contents of color transform data so that | Now, we describe the contents of color transform data so that | |||
| decoding can apply the inverse color transform and recover the | decoding can apply the inverse color transform and recover the | |||
| original red and blue values. The first 3 bits of the color | original red and blue values. The first 3 bits of the color | |||
| transform data contain the width and height of the image block in | transform data contain the width and height of the image block in | |||
| number of bits, just like the predictor transform: | number of bits, just like the predictor transform: | |||
| int size_bits = ReadBits(3) + 2; | int size_bits = ReadBits(3) + 2; | |||
| int block_width = 1 << size_bits; | int block_width = 1 << size_bits; | |||
| int block_height = 1 << size_bits; | int block_height = 1 << size_bits; | |||
| skipping to change at page 35, line 29 ¶ | skipping to change at line 1539 ¶ | |||
| +==================+==================+ | +==================+==================+ | |||
| | 1..2 | 3 | | | 1..2 | 3 | | |||
| +------------------+------------------+ | +------------------+------------------+ | |||
| | 3..4 | 2 | | | 3..4 | 2 | | |||
| +------------------+------------------+ | +------------------+------------------+ | |||
| | 5..16 | 1 | | | 5..16 | 1 | | |||
| +------------------+------------------+ | +------------------+------------------+ | |||
| | 17..256 | 0 | | | 17..256 | 0 | | |||
| +------------------+------------------+ | +------------------+------------------+ | |||
| Table 3 | Table 3: Color Table Size to | |||
| Bundled Pixel Bit Width Mapping | ||||
| width_bits has a value of 0, 1, 2, or 3. A value of 0 indicates no | width_bits has a value of 0, 1, 2, or 3. A value of 0 indicates no | |||
| pixel bundling is to be done for the image. A value of 1 indicates | pixel bundling is to be done for the image. A value of 1 indicates | |||
| that two pixels are combined, and each pixel has a range of [0..15]. | that two pixels are combined, and each pixel has a range of [0..15]. | |||
| A value of 2 indicates that four pixels are combined, and each pixel | A value of 2 indicates that four pixels are combined, and each pixel | |||
| has a range of [0..3]. A value of 3 indicates that eight pixels are | has a range of [0..3]. A value of 3 indicates that eight pixels are | |||
| combined, and each pixel has a range of [0..1], that is, a binary | combined, and each pixel has a range of [0..1], that is, a binary | |||
| value. | value. | |||
| The values are packed into the green component as follows: | The values are packed into the green component as follows: | |||
| skipping to change at page 36, line 37 ¶ | skipping to change at line 1594 ¶ | |||
| 2. Entropy image: Stores the meta prefix codes (see "Decoding of | 2. Entropy image: Stores the meta prefix codes (see "Decoding of | |||
| Meta Prefix Codes" (Section 3.7.2.2)). | Meta Prefix Codes" (Section 3.7.2.2)). | |||
| 3. Predictor image: Stores the metadata for the predictor transform | 3. Predictor image: Stores the metadata for the predictor transform | |||
| (see "Predictor Transform" (Section 3.5.1)). | (see "Predictor Transform" (Section 3.5.1)). | |||
| 4. Color transform image: Created by ColorTransformElement values | 4. Color transform image: Created by ColorTransformElement values | |||
| (defined in "Color Transform" (Section 3.5.2)) for different | (defined in "Color Transform" (Section 3.5.2)) for different | |||
| blocks of the image. | blocks of the image. | |||
| 5. Color indexing image: An array of size color_table_size (up to | 5. Color indexing image: An array of the size of color_table_size | |||
| 256 ARGB values) storing the metadata for the color indexing | (up to 256 ARGB values) that stores the metadata for the color | |||
| transform (see "Color Indexing Transform" (Section 3.5.4)). | indexing transform (see "Color Indexing Transform" | |||
| (Section 3.5.4)). | ||||
| 3.6.2. Encoding of Image Data | 3.6.2. Encoding of Image Data | |||
| The encoding of image data is independent of its role. | The encoding of image data is independent of its role. | |||
| The image is first divided into a set of fixed-size blocks (typically | The image is first divided into a set of fixed-size blocks (typically | |||
| 16x16 blocks). Each of these blocks are modeled using their own | 16x16 blocks). Each of these blocks are modeled using their own | |||
| entropy codes. Also, several blocks may share the same entropy | entropy codes. Also, several blocks may share the same entropy | |||
| codes. | codes. | |||
| skipping to change at page 38, line 5 ¶ | skipping to change at line 1660 ¶ | |||
| an entropy code). | an entropy code). | |||
| | Rationale: This approach reduces the storage requirement for | | Rationale: This approach reduces the storage requirement for | |||
| | the entropy code. Also, large values are usually rare, so | | the entropy code. Also, large values are usually rare, so | |||
| | extra bits would be used for very few values in the image. | | extra bits would be used for very few values in the image. | |||
| | Thus, this approach results in better compression overall. | | Thus, this approach results in better compression overall. | |||
| The following table denotes the prefix codes and extra bits used for | The following table denotes the prefix codes and extra bits used for | |||
| storing different ranges of values. | storing different ranges of values. | |||
| Note: The maximum backward reference length is limited to 4096. | | Note: The maximum backward reference length is limited to 4096. | |||
| Hence, only the first 24 prefix codes (with the respective extra | | Hence, only the first 24 prefix codes (with the respective | |||
| bits) are meaningful for length values. For distance values, | | extra bits) are meaningful for length values. For distance | |||
| however, all the 40 prefix codes are valid. | | values, however, all the 40 prefix codes are valid. | |||
| +=================+=============+============+ | +=================+=============+============+ | |||
| | Value Range | Prefix Code | Extra Bits | | | Value Range | Prefix Code | Extra Bits | | |||
| +=================+=============+============+ | +=================+=============+============+ | |||
| | 1 | 0 | 0 | | | 1 | 0 | 0 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | 2 | 1 | 0 | | | 2 | 1 | 0 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | 3 | 2 | 0 | | | 3 | 2 | 0 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| skipping to change at page 38, line 40 ¶ | skipping to change at line 1695 ¶ | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | 3072..4096 | 23 | 10 | | | 3072..4096 | 23 | 10 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | ... | ... | ... | | | ... | ... | ... | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | 524289..786432 | 38 | 18 | | | 524289..786432 | 38 | 18 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| | 786433..1048576 | 39 | 18 | | | 786433..1048576 | 39 | 18 | | |||
| +-----------------+-------------+------------+ | +-----------------+-------------+------------+ | |||
| Table 4 | Table 4: Value to Prefix Code and Extra | |||
| Bits Mapping | ||||
| The pseudocode to obtain a (length or distance) value from the prefix | The pseudocode to obtain a (length or distance) value from the prefix | |||
| code is as follows: | code is as follows: | |||
| if (prefix_code < 4) { | if (prefix_code < 4) { | |||
| return prefix_code + 1; | return prefix_code + 1; | |||
| } | } | |||
| int extra_bits = (prefix_code - 2) >> 1; | int extra_bits = (prefix_code - 2) >> 1; | |||
| int offset = (2 + (prefix_code & 1)) << extra_bits; | int offset = (2 + (prefix_code & 1)) << extra_bits; | |||
| return offset + ReadBits(extra_bits) + 1; | return offset + ReadBits(extra_bits) + 1; | |||
| skipping to change at page 39, line 48 ¶ | skipping to change at line 1751 ¶ | |||
| (-6, 2), (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), | (-6, 2), (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), | |||
| (6, 3), (-6, 3), (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), | (6, 3), (-6, 3), (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), | |||
| (-5, 5), (7, 1), (-7, 1), (4, 6), (-4, 6), (6, 4), (-6, 4), | (-5, 5), (7, 1), (-7, 1), (4, 6), (-4, 6), (6, 4), (-6, 4), | |||
| (2, 7), (-2, 7), (7, 2), (-7, 2), (3, 7), (-3, 7), (7, 3), | (2, 7), (-2, 7), (7, 2), (-7, 2), (3, 7), (-3, 7), (7, 3), | |||
| (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5), (8, 0), (4, 7), | (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5), (8, 0), (4, 7), | |||
| (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6), (-6, 6), | (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6), (-6, 6), | |||
| (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7), | (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7), | |||
| (-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), | (-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), | |||
| (8, 7) | (8, 7) | |||
| Figure 20 | Figure 20: Distance Code to Neighboring Pixel Offset Mapping | |||
| For example, the distance code 1 indicates an offset of (0, 1) for | For example, the distance code 1 indicates an offset of (0, 1) for | |||
| the neighboring pixel, that is, the pixel above the current pixel (0 | the neighboring pixel, that is, the pixel above the current pixel (0 | |||
| pixel difference in the X direction and 1 pixel difference in the Y | pixel difference in the X direction and 1 pixel difference in the Y | |||
| direction). Similarly, the distance code 3 indicates the top-left | direction). Similarly, the distance code 3 indicates the top-left | |||
| pixel. | pixel. | |||
| The decoder can convert a distance code distance_code to a scan-line | The decoder can convert a distance code distance_code to a scan-line | |||
| order distance dist as follows: | order distance dist as follows: | |||
| skipping to change at page 43, line 5 ¶ | skipping to change at line 1895 ¶ | |||
| symbol0 = ReadBits(1 + 7 * is_first_8bits); | symbol0 = ReadBits(1 + 7 * is_first_8bits); | |||
| code_lengths[symbol0] = 1; | code_lengths[symbol0] = 1; | |||
| if (num_symbols == 2) { | if (num_symbols == 2) { | |||
| symbol1 = ReadBits(8); | symbol1 = ReadBits(8); | |||
| code_lengths[symbol1] = 1; | code_lengths[symbol1] = 1; | |||
| } | } | |||
| | The two symbols should be different. Duplicate symbols are | | The two symbols should be different. Duplicate symbols are | |||
| | allowed, but inefficient. | | allowed, but inefficient. | |||
| Note: Another special case is when _all_ prefix code lengths are | | Note: Another special case is when _all_ prefix code lengths | |||
| _zeros_ (an empty prefix code). For example, a prefix code for | | are _zeros_ (an empty prefix code). For example, a prefix code | |||
| distance can be empty if there are no backward references. | | for distance can be empty if there are no backward references. | |||
| Similarly, prefix codes for alpha, red, and blue can be empty if all | | Similarly, prefix codes for alpha, red, and blue can be empty | |||
| pixels within the same meta prefix code are produced using the color | | if all pixels within the same meta prefix code are produced | |||
| cache. However, this case doesn't need special handling, as empty | | using the color cache. However, this case doesn't need special | |||
| prefix codes can be coded as those containing a single symbol 0. | | handling, as empty prefix codes can be coded as those | |||
| | containing a single symbol 0. | ||||
| 3.7.2.1.2. Normal Code Length Code | 3.7.2.1.2. Normal Code Length Code | |||
| The code lengths of the prefix code fit in 8 bits and are read as | The code lengths of the prefix code fit in 8 bits and are read as | |||
| follows. First, num_code_lengths specifies the number of code | follows. First, num_code_lengths specifies the number of code | |||
| lengths. | lengths. | |||
| int num_code_lengths = 4 + ReadBits(4); | int num_code_lengths = 4 + ReadBits(4); | |||
| The code lengths are themselves encoded using prefix codes; lower- | The code lengths are themselves encoded using prefix codes; lower- | |||
| skipping to change at page 46, line 15 ¶ | skipping to change at line 2046 ¶ | |||
| The decoder then uses prefix code group prefix_group to decode the | The decoder then uses prefix code group prefix_group to decode the | |||
| pixel (x, y), as explained in Section 3.7.2.3. | pixel (x, y), as explained in Section 3.7.2.3. | |||
| 3.7.2.3. Decoding Entropy-Coded Image Data | 3.7.2.3. Decoding Entropy-Coded Image Data | |||
| For the current position (x, y) in the image, the decoder first | For the current position (x, y) in the image, the decoder first | |||
| identifies the corresponding prefix code group (as explained in the | identifies the corresponding prefix code group (as explained in the | |||
| last section). Given the prefix code group, the pixel is read and | last section). Given the prefix code group, the pixel is read and | |||
| decoded as follows. | decoded as follows. | |||
| Next, read symbol S from the bitstream using prefix code #1. Note | Next, read symbol S from the bitstream using prefix code #1. | |||
| that S is any integer in the range 0 to (256 + 24 + color_cache_size | ||||
| (Section 3.6.2.3)- 1). | | Note that S is any integer in the range 0 to (256 + 24 + | |||
| | color_cache_size - 1). See Section 3.6.2.3 for details about | ||||
| | color_cache_size. | ||||
| The interpretation of S depends on its value: | The interpretation of S depends on its value: | |||
| 1. If S < 256 | 1. If S < 256 | |||
| i. Use S as the green component. | i. Use S as the green component. | |||
| ii. Read red from the bitstream using prefix code #2. | ii. Read red from the bitstream using prefix code #2. | |||
| iii. Read blue from the bitstream using prefix code #3. | iii. Read blue from the bitstream using prefix code #3. | |||
| skipping to change at page 47, line 4 ¶ | skipping to change at line 2085 ¶ | |||
| v. Read extra bits for the distance from the bitstream. | v. Read extra bits for the distance from the bitstream. | |||
| vi. Determine backward-reference distance D from the distance | vi. Determine backward-reference distance D from the distance | |||
| prefix code and the extra bits read. | prefix code and the extra bits read. | |||
| vii. Copy L pixels (in scan-line order) from the sequence of | vii. Copy L pixels (in scan-line order) from the sequence of | |||
| pixels starting at the current position minus D pixels. | pixels starting at the current position minus D pixels. | |||
| 3. If S >= 256 + 24 | 3. If S >= 256 + 24 | |||
| i. Use S - (256 + 24) as the index into the color cache. | i. Use S - (256 + 24) as the index into the color cache. | |||
| ii. Get ARGB color from the color cache at that index. | ii. Get ARGB color from the color cache at that index. | |||
| 3.8. Overall Structure of the Format | 3.8. Overall Structure of the Format | |||
| Below is a view into the format in Augmented Backus-Naur Form | Below is a view into the format in Augmented Backus-Naur Form | |||
| [RFC5234] [RFC7405]. It does not cover all details. The end-of- | [RFC5234] [RFC7405]. It does not cover all details. The end-of- | |||
| image (EOI) is only implicitly coded into the number of pixels | image (EOI) is only implicitly coded into the number of pixels | |||
| (image_width * image_height). | (image_width * image_height). | |||
| Note that *element means element can be repeated 0 or more times. | | Note that *element means element can be repeated 0 or more | |||
| 5element means element is repeated exactly 5 times. %b represents a | | times. 5element means element is repeated exactly 5 times. %b | |||
| binary value. | | represents a binary value. | |||
| 3.8.1. Basic Structure | 3.8.1. Basic Structure | |||
| format = RIFF-header image-header image-stream | format = RIFF-header image-header image-stream | |||
| RIFF-header = %s"RIFF" 4OCTET %s"WEBPVP8L" 4OCTET | RIFF-header = %s"RIFF" 4OCTET %s"WEBPVP8L" 4OCTET | |||
| image-header = %x2F image-size alpha-is-used version | image-header = %x2F image-size alpha-is-used version | |||
| image-size = 14BIT 14BIT ; width - 1, height - 1 | image-size = 14BIT 14BIT ; width - 1, height - 1 | |||
| alpha-is-used = 1BIT | alpha-is-used = 1BIT | |||
| version = 3BIT ; 0 | version = 3BIT ; 0 | |||
| image-stream = optional-transform spatially-coded-image | image-stream = optional-transform spatially-coded-image | |||
| skipping to change at page 48, line 48 ¶ | skipping to change at line 2177 ¶ | |||
| overflows, out-of-bounds reads and writes to both heap and stack, | overflows, out-of-bounds reads and writes to both heap and stack, | |||
| uninitialized data usage, null pointer dereferences, resource (disk | uninitialized data usage, null pointer dereferences, resource (disk | |||
| or memory) exhaustion, and extended resource usage (long running | or memory) exhaustion, and extended resource usage (long running | |||
| time) as part of the demuxing and decoding process. In particular, | time) as part of the demuxing and decoding process. In particular, | |||
| implementations reading this format are likely to take input from | implementations reading this format are likely to take input from | |||
| unknown and possibly unsafe sources -- both clients (for example, web | unknown and possibly unsafe sources -- both clients (for example, web | |||
| browsers or email clients) and servers (for example, applications | browsers or email clients) and servers (for example, applications | |||
| that accept uploaded images). These may result in arbitrary code | that accept uploaded images). These may result in arbitrary code | |||
| execution, information leakage (memory layout and contents), or | execution, information leakage (memory layout and contents), or | |||
| crashes and thereby allow a device to be compromised or cause a | crashes and thereby allow a device to be compromised or cause a | |||
| denial of service to an application using the format | denial of service to an application using the format [mitre-libwebp] | |||
| [cve.mitre.org-libwebp] [crbug-security]. | [issues-security]. | |||
| The format does not employ "active content" but does allow metadata | The format does not employ "active content" but does allow metadata | |||
| (for example, [XMP] and [Exif]) and custom chunks to be embedded in a | (for example, [XMP] and [Exif]) and custom chunks to be embedded in a | |||
| file. Applications that interpret these chunks may be subject to | file. Applications that interpret these chunks may be subject to | |||
| security considerations for those formats. | security considerations for those formats. | |||
| 5. Interoperability Considerations | 5. Interoperability Considerations | |||
| The format is defined using little-endian byte ordering (see | The format is defined using little-endian byte ordering (see | |||
| Section 3.1 of [RFC2781]), but demuxing and decoding are possible on | Section 3.1 of [RFC2781]), but demuxing and decoding are possible on | |||
| platforms using a different ordering with the appropriate conversion. | platforms using a different ordering with the appropriate conversion. | |||
| The container is based on RIFF and allows extension via user-defined | The container is based on RIFF and allows extension via user-defined | |||
| chunks, but nothing beyond the chunks defined by the container format | chunks, but nothing beyond the chunks defined by the container format | |||
| (Section 2) are required for decoding of the image. These have been | (Section 2) are required for decoding of the image. These have been | |||
| finalized but were extended in the format's early stages, so some | finalized, but they were extended in the format's early stages, so | |||
| older readers may not support lossless or animated image decoding. | some older readers may not support lossless or animated image | |||
| decoding. | ||||
| 6. IANA Considerations | 6. IANA Considerations | |||
| IANA has registered the 'image/webp' media type [RFC2046]. | IANA has registered the 'image/webp' media type [RFC2046]. | |||
| 6.1. The 'image/webp' Media Type | 6.1. The 'image/webp' Media Type | |||
| This section contains the media type registration details per | This section contains the media type registration details per | |||
| [RFC6838]. | [RFC6838]. | |||
| 6.1.1. Registration Details | 6.1.1. Registration Details | |||
| *RFC Editor Note:* Replace RFC XXXX / rfcXXXX with the published RFC | ||||
| number. | ||||
| Type name: image | Type name: image | |||
| Subtype name: webp | Subtype name: webp | |||
| Required parameters: N/A | Required parameters: N/A | |||
| Optional parameters: N/A | Optional parameters: N/A | |||
| Encoding considerations: Binary. The Base64 encoding [RFC4648] | Encoding considerations: Binary. The Base64 encoding [RFC4648] | |||
| should be used on transports that cannot accommodate binary data | should be used on transports that cannot accommodate binary data | |||
| directly. | directly. | |||
| Security considerations: See RFC XXXX, Section 4. | Security considerations: See RFC 9649, Section 4. | |||
| Interoperability considerations: See RFC XXXX, Section 5. | Interoperability considerations: See RFC 9649, Section 5. | |||
| Published specification: RFC 9649 | ||||
| Published specification: RFC XXXX | ||||
| Applications that use this media type: Applications that are used to | Applications that use this media type: Applications that are used to | |||
| display and process images, especially when smaller image file | display and process images, especially when smaller image file | |||
| sizes are important. | sizes are important. | |||
| Fragment identifier considerations: N/A | Fragment identifier considerations: N/A | |||
| Additional information: | Additional information: | |||
| Deprecated alias names for this type: N/A | Deprecated alias names for this type: N/A | |||
| Magic number(s): The first 4 bytes are 0x52, 0x49, 0x46, 0x46 | Magic number(s): The first 4 bytes are 0x52, 0x49, 0x46, 0x46 | |||
| skipping to change at page 50, line 25 ¶ | skipping to change at line 2247 ¶ | |||
| next 7 bytes are 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38 | next 7 bytes are 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38 | |||
| ('WEBPVP8'). | ('WEBPVP8'). | |||
| File extension(s): webp | File extension(s): webp | |||
| Apple Uniform Type Identifier: org.webmproject.webp conforms to | Apple Uniform Type Identifier: org.webmproject.webp conforms to | |||
| public.image | public.image | |||
| Object Identifiers: N/A | Object Identifiers: N/A | |||
| Person & email address to contact for further information: James | Person & email address to contact for further information: James | |||
| Zern <jzern@google.com> | Zern <jzern@google.com> | |||
| Intended usage: COMMON | ||||
| Restrictions on usage: N/A | Restrictions on usage: N/A | |||
| Author: James Zern <jzern@google.com> | Author: James Zern <jzern@google.com> | |||
| Change controller: | Change controller: IETF | |||
| IETF | ||||
| Intended usage: COMMON | ||||
| 7. References | 7. References | |||
| 7.1. Normative References | 7.1. Normative References | |||
| [Exif] Camera & Imaging Products Association (CIPA) and Japan | [Exif] Camera & Imaging Products Association (CIPA) and Japan | |||
| Electronics and Information Technology Industries | Electronics and Information Technology Industries | |||
| Association (JEITA), "Exchangeable image file format for | Association (JEITA), "Exchangeable image file format for | |||
| digital still cameras: Exif Version 2.3", CIPA DC- | digital still cameras: Exif Version 2.3", CIPA DC- | |||
| 008-2012, JEITA CP-3451C, December 2012, | 008-2012, JEITA CP-3451C, December 2012, | |||
| skipping to change at page 52, line 18 ¶ | skipping to change at line 2333 ¶ | |||
| [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
| 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
| May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| [XMP] Adobe Inc., "XMP Specification", | [XMP] Adobe Inc., "XMP Specification", | |||
| <https://www.adobe.com/devnet/xmp.html>. | <https://www.adobe.com/devnet/xmp.html>. | |||
| 7.2. Informative References | 7.2. Informative References | |||
| [crbug-security] | ||||
| "libwebp Security Issues", | ||||
| <https://bugs.chromium.org/p/webp/issues/ | ||||
| list?q=label%3ASecurity>. | ||||
| [cve.mitre.org-libwebp] | ||||
| "libwebp CVE List", <https://cve.mitre.org/cgi-bin/ | ||||
| cvekey.cgi?keyword=libwebp>. | ||||
| [GIF-spec] CompuServe Incorporated, "Graphics Interchange | [GIF-spec] CompuServe Incorporated, "Graphics Interchange | |||
| Format(sm)", Version 89a, July 1990, | Format(sm)", Version 89a, July 1990, | |||
| <https://www.w3.org/Graphics/GIF/spec-gif89a.txt>. | <https://www.w3.org/Graphics/GIF/spec-gif89a.txt>. | |||
| [Huffman] Huffman, D., "A Method for the Construction of Minimum- | [Huffman] Huffman, D., "A Method for the Construction of Minimum- | |||
| Redundancy Codes", Proceedings of the Institute of Radio | Redundancy Codes", Proceedings of the Institute of Radio | |||
| Engineers, Vol. 40, Issue 9, pp. 1098-1101, | Engineers, Vol. 40, Issue 9, pp. 1098-1101, | |||
| DOI 10.1109/JRPROC.1952.273898, September 1952, | DOI 10.1109/JRPROC.1952.273898, September 1952, | |||
| <https://doi.org/10.1109/JRPROC.1952.273898>. | <https://doi.org/10.1109/JRPROC.1952.273898>. | |||
| [issues-security] | ||||
| "libwebp Security Issues", | ||||
| <https://issues.webmproject.org/ | ||||
| issues?q=componentid:1618983%2B%20(%22Restrict-View- | ||||
| Security%22%20OR%20type:vulnerability)>. | ||||
| [JPEG-spec] | [JPEG-spec] | |||
| "Information Technology - Digital Compression and Coding | "Information Technology - Digital Compression and Coding | |||
| of Continuous-Tone Still Images - Requirements and | of Continuous-Tone Still Images - Requirements and | |||
| Guidelines", ITU-T Recommendation T.81, ISO/IEC 10918-1, | Guidelines", ITU-T Recommendation T.81, ISO/IEC 10918-1, | |||
| September 1992, | September 1992, | |||
| <https://www.w3.org/Graphics/JPEG/itu-t81.pdf>. | <https://www.w3.org/Graphics/JPEG/itu-t81.pdf>. | |||
| [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for | [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for | |||
| Sequential Data Compression", IEEE Transactions on | Sequential Data Compression", IEEE Transactions on | |||
| Information Theory, Vol. 23, Issue 3, pp. 337-343, | Information Theory, Vol. 23, Issue 3, pp. 337-343, | |||
| DOI 10.1109/TIT.1977.1055714, May 1977, | DOI 10.1109/TIT.1977.1055714, May 1977, | |||
| <https://doi.org/10.1109/TIT.1977.1055714>. | <https://doi.org/10.1109/TIT.1977.1055714>. | |||
| [mitre-libwebp] | ||||
| "libwebp CVE List", <https://cve.mitre.org/cgi-bin/ | ||||
| cvekey.cgi?keyword=libwebp>. | ||||
| [MWG] Metadata Working Group, "Guidelines For Handling Image | [MWG] Metadata Working Group, "Guidelines For Handling Image | |||
| Metadata", Version 2.0, November 2010, | Metadata", Version 2.0, November 2010, | |||
| <https://web.archive.org/web/20180919181934/ | <https://web.archive.org/web/20180919181934/ | |||
| http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf>. | http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf>. | |||
| [RFC2083] Boutell, T., "PNG (Portable Network Graphics) | [RFC2083] Boutell, T., "PNG (Portable Network Graphics) | |||
| Specification Version 1.0", RFC 2083, | Specification Version 1.0", RFC 2083, | |||
| DOI 10.17487/RFC2083, March 1997, | DOI 10.17487/RFC2083, March 1997, | |||
| <https://www.rfc-editor.org/info/rfc2083>. | <https://www.rfc-editor.org/info/rfc2083>. | |||
| [RIFF-spec] | [RIFF-spec] | |||
| "RIFF (Resource Interchange File Format)", | "RIFF (Resource Interchange File Format)", | |||
| <https://www.loc.gov/preservation/digital/formats/fdd/ | <https://www.loc.gov/preservation/digital/formats/fdd/ | |||
| fdd000025.shtml>. | fdd000025.shtml>. | |||
| [webp-lossless-src] | [webp-lossless-src] | |||
| Alakuijala, J., "WebP Lossless Bitstream Specification", | Alakuijala, J., "WebP Lossless Bitstream Specification", | |||
| October 2023, | July 2024, | |||
| <https://chromium.googlesource.com/webm/libwebp/+/refs/ | <https://chromium.googlesource.com/webm/libwebp/+/refs/ | |||
| tags/webp-rfcXXXX/doc/webp-lossless-bitstream-spec.txt>. | tags/webp-rfc9649/doc/webp-lossless-bitstream-spec.txt>. | |||
| [webp-lossless-study] | [webp-lossless-study] | |||
| Alakuijala, J. and V. Rabaud, "Lossless and Transparency | Alakuijala, J. and V. Rabaud, "Lossless and Transparency | |||
| Encoding in WebP", August 2017, | Encoding in WebP", August 2017, | |||
| <https://developers.google.com/speed/webp/docs/ | <https://developers.google.com/speed/webp/docs/ | |||
| webp_lossless_alpha_study>. | webp_lossless_alpha_study>. | |||
| [webp-riff-src] | [webp-riff-src] | |||
| Google LLC, "WebP RIFF Container", April 2024, | Google LLC, "WebP RIFF Container", July 2024, | |||
| <https://chromium.googlesource.com/webm/libwebp/+/refs/ | <https://chromium.googlesource.com/webm/libwebp/+/refs/ | |||
| tags/webp-rfcXXXX/doc/webp-container-spec.txt>. | tags/webp-rfc9649/doc/webp-container-spec.txt>. | |||
| Authors' Addresses | Authors' Addresses | |||
| James Zern | James Zern | |||
| Google LLC | Google LLC | |||
| 1600 Amphitheatre Parkway | 1600 Amphitheatre Parkway | |||
| Mountain View, CA 94043 | Mountain View, CA 94043 | |||
| United States of America | United States of America | |||
| Phone: +1 650 253-0000 | Phone: +1 650 253-0000 | |||
| Email: jzern@google.com | Email: jzern@google.com | |||
| End of changes. 69 change blocks. | ||||
| 193 lines changed or deleted | 186 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||