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 | September 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 | |||
skipping to change at page 5, line 40 ¶ | skipping to change at line 222 ¶ | |||
| Chunk FourCC | | | Chunk FourCC | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Chunk Size | | | Chunk Size | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
: Chunk Payload : | : Chunk Payload : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
Figure 1: 'RIFF' Chunk Structure | Figure 1: 'RIFF' Chunk Structure | |||
Chunk FourCC: 32 bits | Chunk FourCC: 32 bits | |||
ASCII four-character code used for chunk identification. | The ASCII four-character code used for chunk identification. | |||
Chunk Size: 32 bits (_uint32_) | Chunk Size: 32 bits (_uint32_) | |||
The size of the chunk in bytes, not including this field, the | The size of the chunk in bytes, not including this field, the | |||
chunk identifier, or padding. | chunk identifier, or padding. | |||
Chunk Payload: _Chunk Size_ bytes | Chunk Payload: _Chunk Size_ bytes | |||
The data payload. If _Chunk Size_ is odd, a single padding byte | The data payload. If _Chunk Size_ is odd, a single padding byte | |||
-- which MUST be 0 to conform with RIFF [RIFF-spec] -- is added. | -- which MUST be 0 to conform with RIFF [RIFF-spec] -- is added. | |||
| Note: RIFF has a convention that all uppercase chunk FourCCs | | Note: RIFF has a convention that all uppercase chunk FourCCs | |||
skipping to change at page 7, line 41 ¶ | skipping to change at line 316 ¶ | |||
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 space | |||
(0x20). | (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 | 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. | 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, ITU-R Recommendation 601 [rec601] SHOULD | |||
used. Applications MAY use another conversion method, but visual | be 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. | |||
skipping to change at page 8, line 43 ¶ | skipping to change at line 366 ¶ | |||
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. | Note that the VP8L header contains the VP8L image width and height. | |||
That is assumed to be the width and height of the canvas. | 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 the following: | |||
* 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 | |||
* An optional 'EXIF' Chunk with Exif metadata. | * an optional 'EXIF' Chunk with Exif metadata | |||
* An optional 'XMP ' Chunk with XMP metadata. | * an optional 'XMP ' Chunk with XMP metadata | |||
* An optional list of unknown chunks (Section 2.7.1.6). | * an optional list of unknown chunks (Section 2.7.1.6) | |||
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 the following: | |||
* 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: | Extended WebP file header: | |||
skipping to change at page 11, line 46 ¶ | skipping to change at line 499 ¶ | |||
Figure 8: 'ANIM' Chunk | Figure 8: 'ANIM' Chunk | |||
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. | |||
skipping to change at page 12, line 19 ¶ | skipping to change at line 521 ¶ | |||
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: | 'ANMF' Chunk: | |||
For animated images, this chunk contains information about a _single_ | For animated images, this chunk contains information about a _single_ | |||
frame. If the _Animation flag_ is not set, then this chunk SHOULD | frame. If the _Animation_ flag is not set, then this chunk SHOULD | |||
NOT be present. | 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 | ... | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
skipping to change at page 13, line 19 ¶ | skipping to change at line 569 ¶ | |||
Frame Duration: 24 bits (_uint24_) | Frame Duration: 24 bits (_uint24_) | |||
The time to wait before displaying the next frame, in | The time to wait before displaying the next frame, in | |||
1-millisecond units. Note that the interpretation of the Frame | 1-millisecond units. Note that the interpretation of the Frame | |||
Duration of 0 (and often <= 10) is defined by the implementation. | Duration of 0 (and often <= 10) is defined by the implementation. | |||
Many tools and browsers assign a minimum duration similar to GIF. | Many tools and browsers assign a minimum duration similar to GIF. | |||
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 10, 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 (Section 2.7.1.1, | |||
Paragraph 2). | Paragraph 2). | |||
Notes: | Notes: | |||
skipping to change at page 14, line 24 ¶ | skipping to change at line 621 ¶ | |||
(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_ - 16 bytes | |||
Consists of: | Consists of the following: | |||
* 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, i.e., _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') | | |||
| | | | | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
skipping to change at page 16, line 4 ¶ | skipping to change at line 696 ¶ | |||
* Method 1: predictor = A | * Method 1: predictor = A | |||
* Method 2: predictor = B | * Method 2: predictor = B | |||
* Method 3: predictor = clip(A + B - C) | * Method 3: predictor = clip(A + B - C) | |||
where clip(v) is equal to: | where clip(v) is equal to: | |||
* 0 if v < 0, | * 0 if v < 0, | |||
* 255 if v > 255, or | * 255 if v > 255, or | |||
* v otherwise. | * v otherwise. | |||
The final value is derived by adding the decompressed value X to | The final value is derived by adding the decompressed value X to | |||
the predictor and using modulo-256 arithmetic to wrap the | the predictor and using modulo-256 arithmetic to wrap the | |||
[256..511] range into the [0..255] one: | [256..511] range into the [0..255] one: | |||
alpha = (predictor + X) % 256 | alpha = (predictor + X) % 256 | |||
There are special cases for the left-most and top-most pixel | There are special cases for the leftmost and topmost pixel | |||
positions. | positions. | |||
For example, the top-left value at location (0, 0) uses 0 as the | For example, the top-left value at location (0, 0) uses 0 as the | |||
predictor value. Otherwise: | predictor value. Otherwise: | |||
* For horizontal or gradient filtering methods, the left-most | * For horizontal or gradient filtering methods, the leftmost | |||
pixels at location (0, y) are predicted using the location (0, | pixels at location (0, y) are predicted using the location (0, | |||
y-1) just above. | y-1) just above. | |||
* For vertical or gradient filtering methods, the top-most | * For vertical or gradient filtering methods, the topmost pixels | |||
pixels at location (x, 0) are predicted using the location | at location (x, 0) are predicted using the location (x-1, 0) | |||
(x-1, 0) on the left. | 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_ - 1 bytes | |||
Encoded alpha bitstream. | Encoded alpha bitstream. | |||
skipping to change at page 17, line 26 ¶ | skipping to change at line 766 ¶ | |||
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 steps | |||
in the specification -- unlike the other channels -- that can | in the specification -- unlike the other channels -- that can | |||
improve compression. | 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 | |||
(note the significant fourth-character space) as its FourCC, _or_ | the significant fourth-character space) as its FourCC _or_ (ii) a | |||
(ii) a 'VP8L' Chunk, using 'VP8L' as its FourCC. | '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 | |||
2.5 and 2.6, respectively. | 2.5 and 2.6, respectively. | |||
2.7.1.4. Color Profile | 2.7.1.4. Color Profile | |||
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('ICCP') | | | ChunkHeader('ICCP') | | |||
skipping to change at page 19, line 19 ¶ | skipping to change at line 853 ¶ | |||
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_. | |||
| Rationale: Allowing unknown chunks gives a provision for future | | Rationale: Allowing unknown chunks gives a provision for future | |||
| extension of the format and also allows storage of any | | extensions of the format and also allows storage of any | |||
| application-specific data. | | application-specific data. | |||
A file MAY contain unknown chunks: | A file MAY contain unknown chunks: | |||
* at the end of the file, as described in Section 2.7, or | * at the end of the file, as described in Section 2.7, or | |||
* at the end of 'ANMF' Chunks, as described in Section 2.7.1.1. | * at the end of 'ANMF' Chunks, as described in Section 2.7.1.1. | |||
Readers SHOULD ignore these chunks. Writers SHOULD preserve them in | Readers SHOULD ignore these chunks. Writers SHOULD preserve them in | |||
their original order (unless they specifically intend to modify these | their original order (unless they specifically intend to modify these | |||
chunks). | chunks). | |||
2.7.2. Canvas Assembly from Frames | 2.7.2. Canvas Assembly from Frames | |||
Here, we provide an overview of how a reader MUST assemble a canvas | Here, we provide an overview of how a reader MUST assemble a canvas | |||
in the case of an animated image. | in the case of an animated image. | |||
The process begins with creating a canvas using the dimensions given | The process begins with creating a canvas using the dimensions given | |||
in the 'VP8X' Chunk, Canvas Width Minus One + 1 pixels wide by Canvas | in the 'VP8X' Chunk: Canvas Width Minus One + 1 pixels wide by Canvas | |||
Height Minus One + 1 pixels high. The Loop Count field from the | Height Minus One + 1 pixels high. The Loop Count field from the | |||
'ANIM' Chunk controls how many times the animation process is | 'ANIM' Chunk controls how many times the animation process is | |||
repeated. This is Loop Count - 1 for nonzero Loop Count values or | repeated. This is Loop Count - 1 for nonzero Loop Count values or | |||
infinite if the Loop Count is zero. | infinite if the Loop Count is zero. | |||
At the beginning of each loop iteration, the canvas is filled using | At the beginning of each loop iteration, the canvas is filled using | |||
the background color from the 'ANIM' Chunk or an application-defined | the background color from the 'ANIM' Chunk or an application-defined | |||
color. | color. | |||
'ANMF' Chunks contain individual frames given in display order. | 'ANMF' Chunks contain individual frames given in display order. | |||
Before rendering each frame, the previous frame's Disposal method is | Before rendering each frame, the previous frame's Disposal method is | |||
applied. | applied. | |||
The rendering of the decoded frame begins at the Cartesian | The rendering of the decoded frame begins at the Cartesian | |||
coordinates (2 * Frame X, 2 * Frame Y), using the top-left corner of | coordinates (2 * Frame X, 2 * Frame Y), using the top-left corner of | |||
the canvas as the origin. Frame Width Minus One + 1 pixels wide by | the canvas as the origin. Frame Width Minus One + 1 pixels wide by | |||
Frame Height Minus One + 1 pixels high are rendered onto the canvas | Frame Height Minus One + 1 pixels high is rendered onto the canvas | |||
using the Blending method. | using the Blending method. | |||
The canvas is displayed for Frame Duration milliseconds. This | The canvas is displayed for Frame Duration milliseconds. This | |||
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. | |||
skipping to change at page 22, line 46 ¶ | skipping to change at line 991 ¶ | |||
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 libwebp | |||
source repository [webp-lossless-src]. | 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 format is an image format for lossless compression of | |||
images. The lossless format stores and restores the pixel values | ARGB images. The lossless format stores and restores the pixel | |||
exactly, including the color values for pixels whose alpha value is | values exactly, including the color values for pixels whose alpha | |||
0. The format uses subresolution images, recursively embedded into | value is 0. The format uses subresolution images, recursively | |||
the format itself, for storing statistical data about the images, | embedded into the format itself, for storing statistical data about | |||
such as the used entropy codes, spatial predictors, color space | the images, such as the used entropy codes, spatial predictors, color | |||
conversion, and color table. A universal algorithm for sequential | space conversion, and color table. A universal algorithm for | |||
data compression [LZ77], prefix coding, and a color cache are used | sequential data compression [LZ77], prefix coding, and a color cache | |||
for compression of the bulk data. Decoding speeds faster than PNG | are used for compression of the bulk data. Decoding speeds faster | |||
have been demonstrated, as well as 25% denser compression than can be | than PNG have been demonstrated, as well as 25% denser compression | |||
achieved using today's PNG format [webp-lossless-study]. | than can be achieved using today's PNG format [webp-lossless-study]. | |||
3.2. Introduction (from "Specification for WebP Lossless Bitstream") | 3.2. Introduction (from "Specification for WebP Lossless Bitstream") | |||
This section describes the compressed data representation of a WebP | This section describes the compressed data representation of a WebP | |||
lossless image. | lossless image. | |||
In this section, we extensively use C programming language syntax | In this section, we extensively use C programming language syntax | |||
[ISO.9899.2018] to describe the bitstream and assume the existence of | [ISO.9899.2018] to describe the bitstream and assume the existence of | |||
a function for reading bits, ReadBits(n). The bytes are read in the | a function for reading bits, ReadBits(n). The bytes are read in the | |||
natural order of the stream containing them, and bits of each byte | natural order of the stream containing them, and bits of each byte | |||
skipping to change at page 24, line 14 ¶ | skipping to change at line 1051 ¶ | |||
3.3. Nomenclature | 3.3. Nomenclature | |||
ARGB | ARGB | |||
A pixel value consisting of alpha, red, green, and blue values. | A pixel value consisting of alpha, red, green, and blue values. | |||
ARGB image | ARGB image | |||
A two-dimensional array containing ARGB pixels. | A two-dimensional array containing ARGB pixels. | |||
color cache | color cache | |||
A small hash-addressed array to store recently used colors to be | A small, hash-addressed array to store recently used colors to be | |||
able to recall them with shorter codes. | able to recall them with shorter codes. | |||
color indexing image | color indexing image | |||
A one-dimensional image of colors that can be indexed using a | A one-dimensional image of colors that can be indexed using a | |||
small integer (up to 256 within WebP lossless). | small integer (up to 256 within WebP lossless). | |||
color transform image | color transform image | |||
A two-dimensional subresolution image containing data about | A two-dimensional subresolution image containing data about | |||
correlations of color components. | correlations of color components. | |||
skipping to change at page 26, line 4 ¶ | skipping to change at line 1136 ¶ | |||
int image_height = ReadBits(14) + 1; | int image_height = ReadBits(14) + 1; | |||
The 14-bit precision for image width and height limits the maximum | The 14-bit precision for image width and height limits the maximum | |||
size of a WebP lossless image to 16384x16384 pixels. | size of a WebP lossless image to 16384x16384 pixels. | |||
The alpha_is_used bit is a hint only and SHOULD NOT impact decoding. | The alpha_is_used bit is a hint only and SHOULD NOT impact decoding. | |||
It SHOULD be set to 0 when all alpha values are 255 in the picture | It SHOULD be set to 0 when all alpha values are 255 in the picture | |||
and 1 otherwise. | and 1 otherwise. | |||
int alpha_is_used = ReadBits(1); | int alpha_is_used = ReadBits(1); | |||
The version_number is a 3-bit code that MUST be set to 0. Any other | The version_number is a 3-bit code that MUST be set to 0. Any other | |||
value MUST be treated as an error. | value MUST be treated as an error. | |||
int version_number = ReadBits(3); | int version_number = ReadBits(3); | |||
3.5. Transforms | 3.5. Transforms | |||
The transforms are reversible manipulations of the image data that | The transforms are reversible manipulations of the image data that | |||
can reduce the remaining symbolic entropy by modeling spatial and | can reduce the remaining symbolic entropy by modeling spatial and | |||
color correlations. They can make the final compression more dense. | color correlations. They can make the final compression more dense. | |||
An image can go through four types of transforms. A 1 bit indicates | An image can go through four types of transforms. A 1 bit indicates | |||
the presence of a transform. Each transform is allowed to be used | the presence of a transform. Each transform is allowed to be used | |||
only once. The transforms are used only for the main-level ARGB | only once. The transforms are used only for the main-level ARGB | |||
image; the subresolution images (color transform image, entropy | image; the subresolution images (color transform image, entropy | |||
image, and predictor image) have no transforms, not even the 0 bit | image, and predictor image) have no transforms, not even the 0 bit | |||
indicating the end of transforms. | indicating the end of transforms. | |||
| Typically, an encoder would use these transforms to reduce the | | Note: Typically, an encoder would use these transforms to | |||
| Shannon entropy in the residual image. Also, the transform | | reduce the Shannon entropy in the residual image. Also, the | |||
| data can be decided based on entropy minimization. | | transform data can be decided based on entropy minimization. | |||
while (ReadBits(1)) { // Transform present. | while (ReadBits(1)) { // Transform present. | |||
// Decode transform type. | // Decode transform type. | |||
enum TransformType transform_type = ReadBits(2); | enum TransformType transform_type = ReadBits(2); | |||
// Decode transform data. | // Decode transform data. | |||
... | ... | |||
} | } | |||
// Decode actual image data. | // Decode actual image data. | |||
skipping to change at page 27, line 41 ¶ | skipping to change at line 1221 ¶ | |||
#define DIV_ROUND_UP(num, den) (((num) + (den) - 1) / (den)) | #define DIV_ROUND_UP(num, den) (((num) + (den) - 1) / (den)) | |||
int transform_width = DIV_ROUND_UP(image_width, 1 << size_bits); | int transform_width = DIV_ROUND_UP(image_width, 1 << size_bits); | |||
The transform data contains the prediction mode for each block of the | The transform data contains the prediction mode for each block of the | |||
image. It is a subresolution image where the green component of a | image. It is a subresolution image where the green component of a | |||
pixel defines which of the 14 predictors is used for all the | pixel defines which of the 14 predictors is used for all the | |||
block_width * block_height pixels within a particular block of the | block_width * block_height pixels within a particular block of the | |||
ARGB image. This subresolution image is encoded using the same | ARGB image. This subresolution image is encoded using the same | |||
techniques described in Section 3.6. | techniques described in Section 3.6. | |||
The number of block columns, transform_width, is used in two- | The number of block columns, i.e., transform_width, is used in two- | |||
dimensional indexing. For a pixel (x, y), one can compute the | dimensional indexing. For a pixel (x, y), one can compute the | |||
respective filter block address by: | respective filter block address by: | |||
int block_index = (y >> size_bits) * transform_width + | int block_index = (y >> size_bits) * transform_width + | |||
(x >> size_bits); | (x >> size_bits); | |||
There are 14 different prediction modes. In each prediction mode, | There are 14 different prediction modes. In each prediction mode, | |||
the current pixel value is predicted from one or more neighboring | the current pixel value is predicted from one or more neighboring | |||
pixels whose values are already known. | pixels whose values are already known. | |||
skipping to change at page 30, line 47 ¶ | skipping to change at line 1336 ¶ | |||
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 prediction 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 pixels, and all pixels | |||
on the leftmost column are T-pixel. | on the leftmost column are T pixels. | |||
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. | |||
The final pixel value is obtained by adding each channel of the | The final pixel value is obtained by adding each channel of the | |||
predicted value to the encoded residual value. | predicted value to the encoded residual value. | |||
void PredictorTransformOutput(uint32 residual, uint32 pred, | void PredictorTransformOutput(uint32 residual, uint32 pred, | |||
uint8* alpha, uint8* red, | uint8* alpha, uint8* red, | |||
uint8* green, uint8* blue) { | uint8* green, uint8* blue) { | |||
*alpha = ALPHA(residual) + ALPHA(pred); | *alpha = ALPHA(residual) + ALPHA(pred); | |||
*red = RED(residual) + RED(pred); | *red = RED(residual) + RED(pred); | |||
*green = GREEN(residual) + GREEN(pred); | *green = GREEN(residual) + GREEN(pred); | |||
skipping to change at page 34, line 29 ¶ | skipping to change at line 1504 ¶ | |||
255, and all red and blue values are set to 0. | 255, and all red and blue values are set to 0. | |||
The transform data contains the color table size and the entries in | The transform data contains the color table size and the entries in | |||
the color table. The decoder reads the color indexing transform data | the color table. The decoder reads the color indexing transform data | |||
as follows: | as follows: | |||
// 8-bit value for the color table size | // 8-bit value for the color table size | |||
int color_table_size = ReadBits(8) + 1; | int color_table_size = ReadBits(8) + 1; | |||
The color table is stored using the image storage format itself. The | The color table is stored using the image storage format itself. The | |||
color table can be obtained by reading an image, without the RIFF | color table can be obtained by reading an image without the RIFF | |||
header, image size, and transforms, assuming the height of 1 pixel | header, image size, and transforms, assuming the height of 1 pixel | |||
and the width of color_table_size. The color table is always | and the width of color_table_size. The color table is always | |||
subtraction-coded to reduce image entropy. The deltas of palette | subtraction-coded to reduce image entropy. The deltas of palette | |||
colors contain typically much less entropy than the colors | colors typically contain much less entropy than the colors | |||
themselves, leading to significant savings for smaller images. In | themselves, leading to significant savings for smaller images. In | |||
decoding, every final color in the color table can be obtained by | decoding, every final color in the color table can be obtained by | |||
adding the previous color component values by each ARGB component | adding the previous color component values by each ARGB component | |||
separately and storing the least significant 8 bits of the result. | separately and storing the least significant 8 bits of the result. | |||
The inverse transform for the image is simply replacing the pixel | The inverse transform for the image is simply replacing the pixel | |||
values (which are indices to the color table) with the actual color | values (which are indices to the color table) with the actual color | |||
table values. The indexing is done based on the green component of | table values. The indexing is done based on the green component of | |||
the ARGB color. | the ARGB color. | |||
skipping to change at page 35, line 10 ¶ | skipping to change at line 1530 ¶ | |||
argb = color_table[GREEN(argb)]; | argb = color_table[GREEN(argb)]; | |||
If the index is equal to or larger than color_table_size, the argb | If the index is equal to or larger than color_table_size, the argb | |||
color value should be set to 0x00000000 (transparent black). | color value should be set to 0x00000000 (transparent black). | |||
When the color table is small (equal to or less than 16 colors), | When the color table is small (equal to or less than 16 colors), | |||
several pixels are bundled into a single pixel. The pixel bundling | several pixels are bundled into a single pixel. The pixel bundling | |||
packs several (2, 4, or 8) pixels into a single pixel, reducing the | packs several (2, 4, or 8) pixels into a single pixel, reducing the | |||
image width respectively. | image width respectively. | |||
| Pixel bundling allows for a more efficient joint distribution | | Note: Pixel bundling allows for a more efficient joint | |||
| entropy coding of neighboring pixels and gives some arithmetic | | distribution entropy coding of neighboring pixels and gives | |||
| coding-like benefits to the entropy code, but it can only be | | some arithmetic coding-like benefits to the entropy code, but | |||
| used when there are 16 or fewer unique values. | | it can only be used when there are 16 or fewer unique values. | |||
color_table_size specifies how many pixels are combined: | color_table_size specifies how many pixels are combined: | |||
+==================+==================+ | +==================+==================+ | |||
| color_table_size | width_bits value | | | color_table_size | width_bits value | | |||
+==================+==================+ | +==================+==================+ | |||
| 1..2 | 3 | | | 1..2 | 3 | | |||
+------------------+------------------+ | +------------------+------------------+ | |||
| 3..4 | 2 | | | 3..4 | 2 | | |||
+------------------+------------------+ | +------------------+------------------+ | |||
skipping to change at page 40, line 30 ¶ | skipping to change at line 1785 ¶ | |||
where distance_map is the mapping noted above, and image_width is the | where distance_map is the mapping noted above, and image_width is the | |||
width of the image in pixels. | width of the image in pixels. | |||
3.6.2.3. Color Cache Coding | 3.6.2.3. Color Cache Coding | |||
Color cache stores a set of colors that have been recently used in | Color cache stores a set of colors that have been recently used in | |||
the image. | the image. | |||
| Rationale: This way, the recently used colors can sometimes be | | Rationale: This way, the recently used colors can sometimes be | |||
| referred to more efficiently than emitting them using the other | | referred to more efficiently than emitting them using the other | |||
| two methods (described in Sections 3.6.2.1 and 3.6.2.2). | | two methods (as described in Sections 3.6.2.1 and 3.6.2.2). | |||
Color cache codes are stored as follows. First, there is a 1-bit | Color cache codes are stored as follows. First, there is a 1-bit | |||
value that indicates if the color cache is used. If this bit is 0, | value that indicates if the color cache is used. If this bit is 0, | |||
no color cache codes exist, and they are not transmitted in the | no color cache codes exist, and they are not transmitted in the | |||
prefix code that decodes the green symbols and the length prefix | prefix code that decodes the green symbols and the length prefix | |||
codes. However, if this bit is 1, the color cache size is read next: | codes. However, if this bit is 1, the color cache size is read next: | |||
int color_cache_code_bits = ReadBits(4); | int color_cache_code_bits = ReadBits(4); | |||
int color_cache_size = 1 << color_cache_code_bits; | int color_cache_size = 1 << color_cache_code_bits; | |||
skipping to change at page 41, line 42 ¶ | skipping to change at line 1843 ¶ | |||
1. Decoding and building the prefix codes. | 1. Decoding and building the prefix codes. | |||
2. Meta prefix codes. | 2. Meta prefix codes. | |||
3. Entropy-coded image data. | 3. Entropy-coded image data. | |||
For any given pixel (x, y), there is a set of five prefix codes | For any given pixel (x, y), there is a set of five prefix codes | |||
associated with it. These codes are (in bitstream order): | associated with it. These codes are (in bitstream order): | |||
* *Prefix code #1*: Used for green channel, backward-reference | *Prefix code #1*: Used for green channel, backward-reference length, | |||
length, and color cache. | and color cache. | |||
* *Prefix code #2, #3, and #4*: Used for red, blue, and alpha | *Prefix code #2, #3, and #4*: Used for red, blue, and alpha | |||
channels, respectively. | channels, respectively. | |||
* *Prefix code #5*: Used for backward-reference distance. | *Prefix code #5*: Used for backward-reference distance. | |||
From here on, we refer to this set as a *prefix code group*. | From here on, we refer to this set as a *prefix code group*. | |||
3.7.2.1. Decoding and Building the Prefix Codes | 3.7.2.1. Decoding and Building the Prefix Codes | |||
This section describes how to read the prefix code lengths from the | This section describes how to read the prefix code lengths from the | |||
bitstream. | bitstream. | |||
The prefix code lengths can be coded in two ways. The method used is | The prefix code lengths can be coded in two ways. The method used is | |||
specified by a 1-bit value. | specified by a 1-bit value. | |||
skipping to change at page 42, line 51 ¶ | skipping to change at line 1899 ¶ | |||
using 8 bits. | using 8 bits. | |||
int is_first_8bits = ReadBits(1); | int is_first_8bits = ReadBits(1); | |||
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 | | Note: The two symbols should be different. Duplicate symbols | |||
| allowed, but inefficient. | | are allowed but inefficient. | |||
Note: Another special case is when _all_ prefix code lengths are | Note: Another special case is when _all_ prefix code lengths are | |||
_zeros_ (an empty prefix code). For example, a prefix code for | _zeros_ (an empty prefix code). For example, a prefix code for | |||
distance can be empty if there are no backward references. | 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 if all | |||
pixels within the same meta prefix code are produced using the color | pixels within the same meta prefix code are produced using the color | |||
cache. However, this case doesn't need special handling, as empty | cache. However, this case doesn't need special handling, as empty | |||
prefix codes can be coded as those containing a single symbol 0. | 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- | |||
level code lengths, code_length_code_lengths, first have to be read. | level code lengths, i.e., code_length_code_lengths, first have to be | |||
The rest of those code_length_code_lengths (according to the order in | read. The rest of those code_length_code_lengths (according to the | |||
kCodeLengthCodeOrder) are zeros. | order in kCodeLengthCodeOrder) are zeros. | |||
int kCodeLengthCodes = 19; | int kCodeLengthCodes = 19; | |||
int kCodeLengthCodeOrder[kCodeLengthCodes] = { | int kCodeLengthCodeOrder[kCodeLengthCodes] = { | |||
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | |||
}; | }; | |||
int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros | int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros | |||
for (i = 0; i < num_code_lengths; ++i) { | for (i = 0; i < num_code_lengths; ++i) { | |||
code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3); | code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3); | |||
} | } | |||
skipping to change at page 45, line 47 ¶ | skipping to change at line 2037 ¶ | |||
int num_prefix_codes = 5 * num_prefix_groups; | int num_prefix_codes = 5 * num_prefix_groups; | |||
Given a pixel (x, y) in the ARGB image, we can obtain the | Given a pixel (x, y) in the ARGB image, we can obtain the | |||
corresponding prefix codes to be used as follows: | corresponding prefix codes to be used as follows: | |||
int position = | int position = | |||
(y >> prefix_bits) * prefix_image_width + (x >> prefix_bits); | (y >> prefix_bits) * prefix_image_width + (x >> prefix_bits); | |||
int meta_prefix_code = (entropy_image[position] >> 8) & 0xffff; | int meta_prefix_code = (entropy_image[position] >> 8) & 0xffff; | |||
PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code]; | PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code]; | |||
where we have assumed the existence of PrefixCodeGroup structure, | where we have assumed the existence of the PrefixCodeGroup structure, | |||
which represents a set of five prefix codes. Also, | which represents a set of five prefix codes. Also, | |||
prefix_code_groups is an array of PrefixCodeGroup (of size | prefix_code_groups is an array of PrefixCodeGroup (of size | |||
num_prefix_groups). | num_prefix_groups). | |||
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. Note | |||
that S is any integer in the range 0 to (256 + 24 + color_cache_size | that S is any integer in the range 0 to (256 + 24 + color_cache_size | |||
(Section 3.6.2.3)- 1). | (Section 3.6.2.3)- 1). | |||
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. | |||
iv. Read alpha from the bitstream using prefix code #4. | iv. Read alpha from the bitstream using prefix code #4. | |||
2. If S >= 256 & S < 256 + 24 | 2. If S >= 256 & S < 256 + 24: | |||
i. Use S - 256 as a length prefix code. | i. Use S - 256 as a length prefix code. | |||
ii. Read extra bits for the length from the bitstream. | ii. Read extra bits for the length from the bitstream. | |||
iii. Determine backward-reference length L from length prefix | iii. Determine backward-reference length L from length prefix | |||
code and the extra bits read. | code and the extra bits read. | |||
iv. Read the distance prefix code from the bitstream using | iv. Read the distance prefix code from the bitstream using | |||
prefix code #5. | prefix code #5. | |||
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). | |||
skipping to change at page 49, line 32 ¶ | skipping to change at line 2211 ¶ | |||
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 2250 ¶ | |||
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, | |||
<https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf>. | <https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf>. | |||
[ICC] International Color Consortium, "Image technology colour | [ICC] International Color Consortium, "Image technology colour | |||
management -- Architecture, profile format, and data | management - Architecture, profile format, and data | |||
structure", Profile version 4.3.0.0, REVISION of | structure", Profile version 4.3.0.0, REVISION of | |||
ICC.1:2004-10, Specification ICC.1:2010, December 2010, | ICC.1:2004-10, Specification ICC.1:2010, December 2010, | |||
<https://www.color.org/specification/ICC1v43_2010-12.pdf>. | <https://www.color.org/specification/ICC1v43_2010-12.pdf>. | |||
[ISO.9899.2018] | [ISO.9899.2018] | |||
International Organization for Standardization, | International Organization for Standardization, | |||
"Information technology -- Programming languages -- C", | "Information technology - Programming languages - C", | |||
Fourth Edition, ISO/IEC 9899:2018, June 2018, | Fourth Edition, ISO/IEC 9899:2018, June 2018, | |||
<https://www.iso.org/standard/74528.html>. | <https://www.iso.org/standard/74528.html>. | |||
[rec601] ITU, "Studio encoding parameters of digital television for | [rec601] ITU-R, "Studio encoding parameters of digital television | |||
standard 4:3 and wide screen 16:9 aspect ratios", ITU-R | for standard 4:3 and wide-screen 16:9 aspect ratios", | |||
Recommendation BT.601, March 2011, | ITU-R Recommendation BT.601-7, March 2011, | |||
<https://www.itu.int/rec/R-REC-BT.601/>. | <https://www.itu.int/rec/R-REC-BT.601/>. | |||
[RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet | [RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet | |||
numbers", RFC 1166, DOI 10.17487/RFC1166, July 1990, | numbers", RFC 1166, DOI 10.17487/RFC1166, July 1990, | |||
<https://www.rfc-editor.org/info/rfc1166>. | <https://www.rfc-editor.org/info/rfc1166>. | |||
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail | [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail | |||
Extensions (MIME) Part Two: Media Types", RFC 2046, | Extensions (MIME) Part Two: Media Types", RFC 2046, | |||
DOI 10.17487/RFC2046, November 1996, | DOI 10.17487/RFC2046, November 1996, | |||
<https://www.rfc-editor.org/info/rfc2046>. | <https://www.rfc-editor.org/info/rfc2046>. | |||
skipping to change at page 52, line 32 ¶ | skipping to change at line 2350 ¶ | |||
[cve.mitre.org-libwebp] | [cve.mitre.org-libwebp] | |||
"libwebp CVE List", <https://cve.mitre.org/cgi-bin/ | "libwebp CVE List", <https://cve.mitre.org/cgi-bin/ | |||
cvekey.cgi?keyword=libwebp>. | 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 IRE, vol. 40, no. 9, | |||
Engineers, Vol. 40, Issue 9, pp. 1098-1101, | pp. 1098-1101, DOI 10.1109/JRPROC.1952.273898, September | |||
DOI 10.1109/JRPROC.1952.273898, September 1952, | 1952, <https://doi.org/10.1109/JRPROC.1952.273898>. | |||
<https://doi.org/10.1109/JRPROC.1952.273898>. | ||||
[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/ | |||
September 1992, | IEC 10918-1:1993(E), 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, no. 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>. | |||
[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, Wayback Machine archive, November | |||
<https://web.archive.org/web/20180919181934/ | 2010, <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)", From the | |||
Library of Congress, Sustainability of Digital Formats, | ||||
<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, | October 2023, | |||
<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", Google LLC, 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", April 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. 80 change blocks. | ||||
189 lines changed or deleted | 186 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |