rfc9649.original.xml | rfc9649.xml | |||
---|---|---|---|---|
<?xml version="1.0" encoding="US-ASCII"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE rfc [ | <!DOCTYPE rfc [ | |||
<!ENTITY nbsp " "> | <!ENTITY nbsp " "> | |||
<!ENTITY zwsp "​"> | <!ENTITY zwsp "​"> | |||
<!ENTITY nbhy "‑"> | <!ENTITY nbhy "‑"> | |||
<!ENTITY wj "⁠"> | <!ENTITY wj "⁠"> | |||
]> | ]> | |||
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" | |||
submissionType="IETF" | submissionType="IETF" | |||
category="info" | category="info" | |||
consensus="true" | consensus="true" | |||
docName="draft-zern-webp-15" | docName="draft-zern-webp-15" | |||
number="9649" | ||||
ipr="trust200902" | ipr="trust200902" | |||
obsoletes="" | obsoletes="" | |||
updates="" | updates="" | |||
xml:lang="en" | xml:lang="en" | |||
tocInclude="true" | tocInclude="true" | |||
tocDepth="4" | tocDepth="4" | |||
symRefs="true" | symRefs="true" | |||
sortRefs="true" | sortRefs="true" | |||
version="3"> | version="3"> | |||
<front> | <front> | |||
<title>WebP Image Format</title> | <title>WebP Image Format</title> | |||
<seriesInfo name="Internet-Draft" value="draft-zern-webp-15" /> | <seriesInfo name="RFC" value="9649"/> | |||
<seriesInfo status="informational" name="" value="draft-zern-webp-15" /> | ||||
<author fullname="James Zern" initials="J." surname="Zern"> | <author fullname="James Zern" initials="J." surname="Zern"> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street>1600 Amphitheatre Parkway</street> | <street>1600 Amphitheatre Parkway</street> | |||
<city>Mountain View</city> | <city>Mountain View</city> | |||
<region>CA</region> | <region>CA</region> | |||
<code>94043</code> | <code>94043</code> | |||
<country>United States of America</country> | <country>United States of America</country> | |||
</postal> | </postal> | |||
skipping to change at line 54 ¶ | skipping to change at line 54 ¶ | |||
<address> | <address> | |||
<email>pascal.massimino@gmail.com</email> | <email>pascal.massimino@gmail.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author fullname="Jyrki Alakuijala" initials="J." surname="Alakuijala"> | <author fullname="Jyrki Alakuijala" initials="J." surname="Alakuijala"> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
<address> | <address> | |||
<email>jyrki.alakuijala@gmail.com</email> | <email>jyrki.alakuijala@gmail.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<date year="2024" month="April"/> | <date year="2024" month="November"/> | |||
<area>art</area> | <area>art</area> | |||
<keyword>VP8</keyword> | <keyword>VP8</keyword> | |||
<keyword>WebP</keyword> | <keyword>WebP</keyword> | |||
<abstract> | <abstract> | |||
<t>This document defines the WebP image format and registers a media type | <t>This document defines the WebP image format and registers a media type | |||
supporting its use.</t> | supporting its use.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
skipping to change at line 87 ¶ | skipping to change at line 87 ¶ | |||
image pixel data, including alpha (transparency) information. Lossy | image pixel data, including alpha (transparency) information. Lossy | |||
compression is achieved using VP8 intra-frame encoding <xref | compression is achieved using VP8 intra-frame encoding <xref | |||
target="RFC6386"/>. The <xref target="webp-lossless">lossless | target="RFC6386"/>. The <xref target="webp-lossless">lossless | |||
algorithm</xref> stores and restores the pixel values exactly, | algorithm</xref> stores and restores the pixel values exactly, | |||
including the color values for fully transparent pixels. A universal algo rithm for sequential data compression | including the color values for fully transparent pixels. A universal algo rithm for sequential data compression | |||
<xref target="LZ77"/>, <xref target="Huffman">prefix coding</xref>, | <xref target="LZ77"/>, <xref target="Huffman">prefix coding</xref>, | |||
and a color cache are used for compression of the bulk data.</t> | and a color cache are used for compression of the bulk data.</t> | |||
</section> | </section> | |||
<section anchor="webp-container" numbered="true" toc="default"> | <section anchor="webp-container" numbered="true" toc="default"> | |||
<name>WebP Container Specification</name> | <name>WebP Container Specification</name> | |||
<t>Note that this section is based on the documentation in the <xref | <aside><t>Note that this section is based on the documentation in the <xref | |||
target="webp-riff-src">libwebp source repository</xref>.</t> | target="webp-riff-src">libwebp source repository</xref>.</t></aside> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Introduction (from "WebP Container Specification")</name> | <name>Introduction (from "WebP Container Specification")</name> | |||
<t>WebP is an image format that uses either (i) the VP8 intra-frame | <t>WebP is an image format that uses either (i) the VP8 intra-frame | |||
encoding <xref target="RFC6386"/> to compress image data in a lossy | encoding <xref target="RFC6386"/> to compress image data in a lossy | |||
way or (ii) the <xref target="webp-lossless">WebP lossless | way or (ii) the <xref target="webp-lossless">WebP lossless | |||
encoding</xref>. These encoding schemes should make it more | encoding</xref>. These encoding schemes should make it more | |||
efficient than older formats, such as JPEG, GIF, and PNG. It is o ptimized for fast | efficient than older formats, such as JPEG, GIF, and PNG. It is o ptimized for fast | |||
image transfer over the network (for example, for websites). The WebP | image transfer over the network (for example, for websites). The WebP | |||
format has feature parity (color profile, metadata, animation, | format has feature parity (color profile, metadata, animation, | |||
etc.) with other formats as well. This section describes the | etc.) with other formats as well. This section describes the | |||
skipping to change at line 248 ¶ | skipping to change at line 248 ¶ | |||
</section> | </section> | |||
<section anchor="simple-file-format-lossy" numbered="true" toc="default"> | <section anchor="simple-file-format-lossy" numbered="true" toc="default"> | |||
<name>Simple File Format (Lossy)</name> | <name>Simple File Format (Lossy)</name> | |||
<t>This layout <bcp14>SHOULD</bcp14> be used if the image requires lossy encoding and | <t>This layout <bcp14>SHOULD</bcp14> 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 supported | the extended format. Files with this layout are smaller and supported | |||
by older software.</t> | by older software.</t> | |||
<t> | ||||
Simple WebP (lossy) file format: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>Simple WebP (Lossy) File Format</name> | <name>Simple WebP (Lossy) File Format</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t> | ||||
'VP8 ' Chunk: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>'VP8 ' Chunk</name> | <name>'VP8 ' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>VP8 data: <em>Chunk Size</em> bytes</dt> | <dt>VP8 data: <em>Chunk Size</em> bytes</dt> | |||
<dd>VP8 bitstream data.</dd> | <dd>VP8 bitstream data.</dd> | |||
</dl> | </dl> | |||
<t>Note that the fourth character in the 'VP8 ' FourCC is an ASCII space | <aside><t>Note that the fourth character in the 'VP8 ' FourCC is an ASCII | |||
(0x20).</t> | space | |||
(0x20).</t></aside> | ||||
<t>The VP8 bitstream format specification is described in <xref | <t>The VP8 bitstream format specification is described in <xref | |||
target="RFC6386"/>. Note that the VP8 frame header contains the VP8 | target="RFC6386"/>.</t><aside><t>Note that the VP8 frame header contains the VP8 | |||
frame width and height. That is assumed to be the width and height of | frame width and height. That is assumed to be the width and height of | |||
the canvas.</t> | the canvas.</t></aside> | |||
<t>The VP8 specification describes how to decode the image into Y'CbCr | <t>The VP8 specification describes how to decode the image into Y'CbCr | |||
format. To convert to RGB, <xref target="rec601">Recommendation 601</xre f> <bcp14>SHOULD</bcp14> | format. To convert to RGB, <xref target="rec601">Recommendation 601</xre f> <bcp14>SHOULD</bcp14> | |||
be used. Applications <bcp14>MAY</bcp14> use another conversion method , but visual | be used. Applications <bcp14>MAY</bcp14> use another conversion method , but visual | |||
results may differ among decoders.</t> | results may differ among decoders.</t> | |||
</section> | </section> | |||
<section anchor="simple-file-format-lossless" numbered="true" | <section anchor="simple-file-format-lossless" numbered="true" | |||
toc="default"> | toc="default"> | |||
<name>Simple File Format (Lossless)</name> | <name>Simple File Format (Lossless)</name> | |||
<t>Note: Older readers may not support files using the lossless | <aside><t>Note: Older readers may not support files using the lossless | |||
format.</t> | format.</t></aside> | |||
<t>This layout <bcp14>SHOULD</bcp14> be used if the image requires lossle ss encoding | <t>This layout <bcp14>SHOULD</bcp14> be used if the image requires lossle ss 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.</t> | features provided by the extended format.</t> | |||
<t> | ||||
Simple WebP (lossless) file format: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>Simple WebP (Lossless) File Format</name> | <name>Simple WebP (Lossless) File Format</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t> | ||||
'VP8L' Chunk: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>'VP8L' Chunk</name> | <name>'VP8L' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>VP8L data: <em>Chunk Size</em> bytes</dt> | <dt>VP8L data: <em>Chunk Size</em> bytes</dt> | |||
<dd>VP8L bitstream data.</dd> | <dd>VP8L bitstream data.</dd> | |||
</dl> | </dl> | |||
<t>The specification of the VP8L bitstream can be found in <xref | <t>The specification of the VP8L bitstream can be found in <xref | |||
target="webp-lossless"/>. Note that the VP8L header contains the | target="webp-lossless"/>.</t><aside><t>Note that the VP8L header contai ns the | |||
VP8L image width and height. That is assumed to be the width and | VP8L image width and height. That is assumed to be the width and | |||
height of the canvas.</t> | height of the canvas.</t></aside> | |||
</section> | </section> | |||
<section anchor="ext-file-form" numbered="true" toc="default"> | <section anchor="ext-file-form" numbered="true" toc="default"> | |||
<name>Extended File Format</name> | <name>Extended File Format</name> | |||
<t>Note: Older readers may not support files using the extended | <aside><t>Note: Older readers may not support files using the extended | |||
format.</t> | format.</t></aside> | |||
<t>An extended format file consists of:</t> | <t>An extended format file consists of:</t> | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li>A 'VP8X' Chunk with information about features used in the | <li>A 'VP8X' Chunk with information about features used in the | |||
file.</li> | file.</li> | |||
<li>An optional 'ICCP' Chunk with a color profile.</li> | <li>An optional 'ICCP' Chunk with a color profile.</li> | |||
<li>An optional 'ANIM' Chunk with animation control data.</li> | <li>An optional 'ANIM' Chunk with animation control data.</li> | |||
<li>Image data.</li> | <li>Image data.</li> | |||
<li>An optional 'EXIF' Chunk with Exif metadata.</li> | <li>An optional 'EXIF' Chunk with Exif metadata.</li> | |||
<li>An optional 'XMP ' Chunk with XMP metadata.</li> | <li>An optional 'XMP ' Chunk with XMP metadata.</li> | |||
skipping to change at line 387 ¶ | skipping to change at line 373 ¶ | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li>An optional <xref target="alpha">alpha subchunk</xref>.</li> | <li>An optional <xref target="alpha">alpha subchunk</xref>.</li> | |||
<li>A <xref target="bitstream-vp8vp8l">bitstream subchunk</xref>.</li> | <li>A <xref target="bitstream-vp8vp8l">bitstream subchunk</xref>.</li> | |||
</ul> | </ul> | |||
<t>For an <em>animated image</em>, the <em>image data</em> consists of | <t>For an <em>animated image</em>, the <em>image data</em> consists of | |||
multiple frames. More details about frames can be found in <xref | multiple frames. More details about frames can be found in <xref | |||
target="animation"/>.</t> | target="animation"/>.</t> | |||
<t>All chunks necessary for reconstruction and color correction, that is | <t>All chunks necessary for reconstruction and color correction, that is, | |||
'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ' and 'VP8L', | 'VP8X', 'ICCP', 'ANIM', 'ANMF', 'ALPH', 'VP8 ', and 'VP8L', | |||
<bcp14>MUST</bcp14> appear in the order described earlier. Readers | <bcp14>MUST</bcp14> appear in the order described earlier. Readers | |||
<bcp14>SHOULD</bcp14> fail when chunks necessary for reconstruction and | <bcp14>SHOULD</bcp14> fail when chunks necessary for reconstruction and | |||
color correction are out of order.</t> | color correction are out of order.</t> | |||
<t><xref target="metadata">Metadata</xref> and <xref | <t><xref target="metadata">Metadata</xref> and <xref | |||
target="unknown-chunks">unknown</xref> chunks MAY appear out of | target="unknown-chunks">unknown chunks</xref> MAY appear out of | |||
order.</t> | order.</t> | |||
<aside><t>Rationale: The chunks necessary for reconstruction should | <aside><t>Rationale: The chunks necessary for reconstruction should | |||
appear first in the file to allow a reader to begin decoding an image | appear first in the file to allow a reader to begin decoding an image | |||
before receiving all of the data. An application may benefit from | before receiving all of the data. An application may benefit from | |||
varying the order of metadata and custom chunks to suit the | varying the order of metadata and custom chunks to suit the | |||
implementation.</t></aside> | implementation.</t></aside> | |||
<t> | ||||
Extended WebP file header: | ||||
</t> | ||||
<figure anchor="extended_header"> | <figure anchor="extended_header"> | |||
<name>Extended WebP File Header</name> | <name>Extended WebP File Header</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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) | | |||
| | | | | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
skipping to change at line 467 ¶ | skipping to change at line 450 ¶ | |||
<t>Future specifications may add more fields. Unknown fields <bcp14>MUST< /bcp14> be | <t>Future specifications may add more fields. Unknown fields <bcp14>MUST< /bcp14> be | |||
ignored.</t> | ignored.</t> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Chunks</name> | <name>Chunks</name> | |||
<section anchor="animation" numbered="true" toc="default"> | <section anchor="animation" numbered="true" toc="default"> | |||
<name>Animation</name> | <name>Animation</name> | |||
<t>An animation is controlled by 'ANIM' and 'ANMF' Chunks.</t> | <t>An animation is controlled by 'ANIM' and 'ANMF' Chunks.</t> | |||
<t anchor="anim_chunk">'ANIM' Chunk:</t> | <figure anchor="anim_chunk"> | |||
<t>For an animated image, this chunk contains the <em>global | ||||
parameters</em> of the animation.</t> | ||||
<figure> | ||||
<name>'ANIM' Chunk</name> | <name>'ANIM' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t>For an animated image, this chunk contains the <em>global | ||||
parameters</em> of the animation.</t> | ||||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>Background Color: 32 bits (<em>uint32</em>)</dt> | <dt>Background Color: 32 bits (<em>uint32</em>)</dt> | |||
<dd> | <dd> | |||
<t>The default background color of the canvas in [Blue, Green, | <t>The default background color of the canvas in [Blue, Green, | |||
Red, Alpha] byte order. This color <bcp14>MAY</bcp14> be used t o fill the | Red, Alpha] byte order. This color <bcp14>MAY</bcp14> be used t o fill the | |||
unused space on the canvas around the frames, as well as the | unused space on the canvas around the frames, as well as the | |||
transparent pixels of the first frame. The background color is | transparent pixels of the first frame. The background color is | |||
also used when the Disposal method is <tt>1</tt>.</t> | also used when the Disposal method is <tt>1</tt>.</t> | |||
<t>Note:</t> | <t>Notes:</t> | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li>The background color <bcp14>MAY</bcp14> contain a nonopaque alpha value, | <li>The background color <bcp14>MAY</bcp14> contain a nonopaque alpha value, | |||
even if the <em>Alpha</em> flag in the <xref | even if the <em>Alpha</em> flag in the <xref | |||
target="extended_header">'VP8X' Chunk</xref> is unset.</li> | target="extended_header">'VP8X' Chunk</xref> is unset.</li> | |||
<li>Viewer applications <bcp14>SHOULD</bcp14> treat the backgro und color value | <li>Viewer applications <bcp14>SHOULD</bcp14> treat the backgro und color value | |||
as a hint and are not required to use it.</li> | as a hint and are not required to use it.</li> | |||
<li>The canvas is cleared at the start of each loop. The | <li>The canvas is cleared at the start of each loop. The | |||
background color <bcp14>MAY</bcp14> be used to achieve this.< /li> | background color <bcp14>MAY</bcp14> be used to achieve this.< /li> | |||
</ul> | </ul> | |||
</dd> | </dd> | |||
<dt>Loop Count: 16 bits (<em>uint16</em>)</dt> | <dt>Loop Count: 16 bits (<em>uint16</em>)</dt> | |||
<dd>The number of times to loop the animation. If it is <tt>0</tt>, this means | <dd>The number of times to loop the animation. If it is <tt>0</tt>, this means | |||
infinitely.</dd> | infinitely.</dd> | |||
</dl> | </dl> | |||
<t>This chunk <bcp14>MUST</bcp14> appear if the <em>Animation</em> fl ag in the 'VP8X' | <t>This chunk <bcp14>MUST</bcp14> appear if the <em>Animation</em> fl ag in the 'VP8X' | |||
Chunk is set. If the <em>Animation</em> flag is not set and this | Chunk is set. If the <em>Animation</em> flag is not set and this | |||
chunk is present, it <bcp14>MUST</bcp14> be ignored.</t> | chunk is present, it <bcp14>MUST</bcp14> be ignored.</t> | |||
<t>'ANMF' Chunk:</t> | ||||
<t>For animated images, this chunk contains information about a | ||||
<em>single</em> frame. If the <em>Animation flag</em> is not set, | ||||
then this chunk <bcp14>SHOULD NOT</bcp14> be present.</t> | ||||
<figure> | <figure> | |||
<name>'ANMF' Chunk</name> | <name>'ANMF' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 line 545 ¶ | skipping to change at line 520 ¶ | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
... | Frame Height Minus One | | ... | Frame Height Minus One | | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Frame Duration | Reserved |B|D| | | Frame Duration | Reserved |B|D| | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
: Frame Data : | : Frame Data : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t>For animated images, this chunk contains information about a | ||||
<em>single</em> frame. If the <em>Animation flag</em> is not set, | ||||
then this chunk <bcp14>SHOULD NOT</bcp14> be present.</t> | ||||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>Frame X: 24 bits (<em>uint24</em>)</dt> | <dt>Frame X: 24 bits (<em>uint24</em>)</dt> | |||
<dd>The X coordinate of the upper left corner of the frame is | <dd>The X coordinate of the upper left corner of the frame is | |||
<tt>Frame X * 2</tt>.</dd> | <tt>Frame X * 2</tt>.</dd> | |||
<dt>Frame Y: 24 bits (<em>uint24</em>)</dt> | <dt>Frame Y: 24 bits (<em>uint24</em>)</dt> | |||
<dd>The Y coordinate of the upper left corner of the frame is | <dd>The Y coordinate of the upper left corner of the frame is | |||
<tt>Frame Y * 2</tt>.</dd> | <tt>Frame Y * 2</tt>.</dd> | |||
<dt>Frame Width Minus One: 24 bits (<em>uint24</em>)</dt> | <dt>Frame Width Minus One: 24 bits (<em>uint24</em>)</dt> | |||
<dd>The <em>1-based</em> width of the frame. The frame width is | <dd>The <em>1-based</em> width of the frame. The frame width is | |||
<tt>1 + Frame Width Minus One</tt>.</dd> | <tt>1 + Frame Width Minus One</tt>.</dd> | |||
skipping to change at line 623 ¶ | skipping to change at line 602 ¶ | |||
dst.RGB * dst.A * (1 - src.A / 255)) / blend.A | dst.RGB * dst.A * (1 - src.A / 255)) / blend.A | |||
]]></sourcecode> | ]]></sourcecode> | |||
</li> | </li> | |||
<li>Alpha-blending <bcp14>SHOULD</bcp14> be done in linear co lor space by | <li>Alpha-blending <bcp14>SHOULD</bcp14> be done in linear co lor space by | |||
taking into account the <xref target="color-profile">color | taking into account the <xref target="color-profile">color | |||
profile</xref> of the image. If the color profile is not | profile</xref> of the image. If the color profile is not | |||
present, standard RGB (sRGB) is to be assumed. (Note th at sRGB also | present, standard RGB (sRGB) is to be assumed. (Note th at sRGB also | |||
needs to be linearized due to a gamma of ~2.2.)</li> | needs to be linearized due to a gamma of ~2.2.)</li> | |||
</ul> | </ul> | |||
</dd> | </dd> | |||
<dt>Frame Data: <em>Chunk Size</em> - <tt>16</tt> bytes</dt> | <dt>Frame Data: <em>Chunk Size</em> bytes - <tt>16</tt></dt> | |||
<dd><t>Consists of:</t> | <dd><t>Consists of:</t> | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li>An optional <xref target="alpha">alpha subchunk</xref> | <li>An optional <xref target="alpha">alpha subchunk</xref> | |||
for the frame.</li> | for the frame.</li> | |||
<li>A <xref target="bitstream-vp8vp8l">bitstream | <li>A <xref target="bitstream-vp8vp8l">bitstream | |||
subchunk</xref> for the frame.</li> | subchunk</xref> for the frame.</li> | |||
<li>An optional list of <xref | <li>An optional list of <xref | |||
target="unknown-chunks">unknown chunks</xref>.</li> | target="unknown-chunks">unknown chunks</xref>.</li> | |||
</ul> | </ul> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>Note: The 'ANMF' payload, <em>Frame Data</em>, consists | <aside><t>Note: The 'ANMF' payload, <em>Frame Data</em>, consists | |||
of individual <em>padded</em> chunks, as described by the <xref | of individual <em>padded</em> chunks, as described by the <xref | |||
target="riff-file-format">RIFF file format</xref>.</t> | target="riff-file-format">RIFF file format</xref>.</t></aside> | |||
</section> | </section> | |||
<section anchor="alpha" numbered="true" toc="default"> | <section anchor="alpha" numbered="true" toc="default"> | |||
<name>Alpha</name> | <name>Alpha</name> | |||
<figure> | <figure> | |||
<name>'ALPH' Chunk</name> | <name>'ALPH' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 line 683 ¶ | skipping to change at line 662 ¶ | |||
<li><tt>0</tt>: None.</li> | <li><tt>0</tt>: None.</li> | |||
<li><tt>1</tt>: Horizontal filter.</li> | <li><tt>1</tt>: Horizontal filter.</li> | |||
<li><tt>2</tt>: Vertical filter.</li> | <li><tt>2</tt>: Vertical filter.</li> | |||
<li><tt>3</tt>: Gradient filter.</li> | <li><tt>3</tt>: Gradient filter.</li> | |||
</ul> | </ul> | |||
<t>For each pixel, filtering is performed using the following | <t>For each pixel, filtering is performed using the following | |||
calculations. Assume the alpha values surrounding the current | calculations. Assume the alpha values surrounding the current | |||
<tt>X</tt> position are labeled as:</t> | <tt>X</tt> position are labeled as:</t> | |||
<figure> | <figure> | |||
<name>Pixels Used in Alpha Filtering</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
C | B | | C | B | | |||
---+---+ | ---+---+ | |||
A | X | | A | X | | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t>We seek to compute the alpha value at position X. First, a | <t>We seek to compute the alpha value at position X. First, a | |||
prediction is made depending on the filtering method:</t> | prediction is made depending on the filtering method:</t> | |||
skipping to change at line 735 ¶ | skipping to change at line 715 ¶ | |||
(x-1, 0) on the left.</li> | (x-1, 0) on the left.</li> | |||
</ul> | </ul> | |||
</dd> | </dd> | |||
<dt>Compression method (C): 2 bits</dt> | <dt>Compression method (C): 2 bits</dt> | |||
<dd><t>The compression method used:</t> | <dd><t>The compression method used:</t> | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li><tt>0</tt>: No compression.</li> | <li><tt>0</tt>: No compression.</li> | |||
<li><tt>1</tt>: Compressed using the WebP lossless format.</li> | <li><tt>1</tt>: Compressed using the WebP lossless format.</li> | |||
</ul> | </ul> | |||
</dd> | </dd> | |||
<dt>Alpha bitstream: <em>Chunk Size</em> - <tt>1</tt> bytes</dt> | <dt>Alpha bitstream: <em>Chunk Size</em> bytes - <tt>1</tt></dt> | |||
<dd>Encoded alpha bitstream.</dd> | <dd>Encoded alpha bitstream.</dd> | |||
</dl> | </dl> | |||
<t>This optional chunk contains encoded alpha data for this frame. A | <t>This optional chunk contains encoded alpha data for this frame. A | |||
frame containing a 'VP8L' Chunk <bcp14>SHOULD NOT</bcp14> contain t his chunk.</t> | frame containing a 'VP8L' Chunk <bcp14>SHOULD NOT</bcp14> contain t his chunk.</t> | |||
<aside><t>Rationale: The transparency information is already part of the | <aside><t>Rationale: The transparency information is already part of the | |||
'VP8L' Chunk.</t></aside> | 'VP8L' Chunk.</t></aside> | |||
<t>The alpha channel data is stored as uncompressed raw data | <t>The alpha channel data is stored as uncompressed raw data | |||
(when the compression method is '0') or compressed using the | (when the compression method is '0') or compressed using the | |||
lossless format (when the compression method is '1').</t> | lossless format (when the compression method is '1').</t> | |||
<ul spacing="normal"> | <ul spacing="normal"> | |||
<li>Raw data: This consists of a byte sequence of length = width * | <li>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.</li> | order.</li> | |||
<li><t>Lossless format compression: The byte sequence is a | <li><t>Lossless format compression: The byte sequence is a | |||
compressed image-stream (as described in <xref | compressed image-stream (as described in <xref | |||
target="webp-lossless"/>) of implicit dimensions width x | target="webp-lossless"/>) of implicit dimensions width x | |||
height. That is, this image-stream does NOT contain any | height. That is, this image-stream does NOT contain any | |||
headers describing the image dimensions.</t> | headers describing the image dimensions.</t></li></ul> | |||
<t>Rationale: The dimensions are already known from other sources, | <aside><t>Rationale: The dimensions are already known from other so | |||
so storing them again would be redundant and prone to errors.</t> | urces, | |||
<t>Once the image-stream is decoded into Alpha, Red, Green, Blue (A | so storing them again would be redundant and prone to errors.</t></ | |||
RGB) color values, | aside> | |||
<ul empty="true"> | ||||
<li><t>Once the image-stream is decoded into Alpha, Red, Green, Bl | ||||
ue (ARGB) color values, | ||||
following the process described in the lossless format | following the process described in the lossless format | |||
specification, the transparency information must be extracted | specification, the transparency information must be extracted | |||
from the green channel of the ARGB quadruplet.</t> | from the green channel of the ARGB quadruplet.</t></li></ul> | |||
<t>Rationale: The green channel is allowed extra transformation | <aside><t>Rationale: The green channel is allowed extra transform | |||
ation | ||||
steps in the specification -- unlike the other channels -- that | steps in the specification -- unlike the other channels -- that | |||
can improve compression.</t></li> | can improve compression.</t></aside> | |||
</ul> | ||||
</section> | </section> | |||
<section anchor="bitstream-vp8vp8l" numbered="true" toc="default"> | <section anchor="bitstream-vp8vp8l" numbered="true" toc="default"> | |||
<name>Bitstream (VP8/VP8L)</name> | <name>Bitstream (VP8/VP8L)</name> | |||
<t>This chunk contains compressed bitstream data for a single | <t>This chunk contains compressed bitstream data for a single | |||
frame.</t> | frame.</t> | |||
<t>A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' | <t>A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' | |||
(note the significant fourth-character space) as its FourCC, | (note the significant fourth-character space) as its FourCC, | |||
<em>or</em> (ii) a 'VP8L' Chunk, using 'VP8L' as its FourCC.</t> | <em>or</em> (ii) a 'VP8L' Chunk, using 'VP8L' as its FourCC.</t> | |||
<t>The formats of' VP8 ' and 'VP8L' Chunks are as described in Sectio ns <xref | <t>The formats of' VP8 ' and 'VP8L' Chunks are as described in Sectio ns <xref | |||
target="simple-file-format-lossy" format="counter"/> and <xref | target="simple-file-format-lossy" format="counter"/> and <xref | |||
skipping to change at line 810 ¶ | skipping to change at line 790 ¶ | |||
target="ICC">ICC specification</xref> for details.</t> | target="ICC">ICC specification</xref> for details.</t> | |||
<t>If this chunk is not present, sRGB <bcp14>SHOULD</bcp14> be assume d.</t> | <t>If this chunk is not present, sRGB <bcp14>SHOULD</bcp14> be assume d.</t> | |||
</section> | </section> | |||
<section anchor="metadata" numbered="true" toc="default"> | <section anchor="metadata" numbered="true" toc="default"> | |||
<name>Metadata</name> | <name>Metadata</name> | |||
<t>Metadata can be stored in 'EXIF' or 'XMP ' Chunks.</t> | <t>Metadata can be stored in 'EXIF' or 'XMP ' Chunks.</t> | |||
<t>There <bcp14>SHOULD</bcp14> be at most one chunk of each type ('EX IF' and 'XMP '). If there are more such chunks, readers <bcp14>MAY</bcp14> ignor e all except | <t>There <bcp14>SHOULD</bcp14> be at most one chunk of each type ('EX IF' and 'XMP '). If there are more such chunks, readers <bcp14>MAY</bcp14> ignor e all except | |||
the first one.</t> | the first one.</t> | |||
<t>The chunks are defined as follows:</t> | <t>The chunks are defined as follows:</t> | |||
<t> | ||||
'EXIF' Chunk: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>'EXIF' Chunk</name> | <name>'EXIF' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>Exif Metadata: <em>Chunk Size</em> bytes</dt> | <dt>Exif Metadata: <em>Chunk Size</em> bytes</dt> | |||
<dd>Image metadata in <xref target="Exif"/> format.</dd> | <dd>Image metadata in <xref target="Exif"/> format.</dd> | |||
</dl> | </dl> | |||
<t> | ||||
'XMP ' Chunk: | ||||
</t> | ||||
<figure> | <figure> | |||
<name>'XMP ' Chunk</name> | <name>'XMP ' Chunk</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
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 : | |||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<dl newline="true" spacing="normal" indent="4"> | <dl newline="true" spacing="normal" indent="4"> | |||
<dt>XMP Metadata: <em>Chunk Size</em> bytes</dt> | <dt>XMP Metadata: <em>Chunk Size</em> bytes</dt> | |||
<dd>Image metadata in <xref target="XMP"/> format.</dd> | <dd>Image metadata in <xref target="XMP"/> format.</dd> | |||
</dl> | </dl> | |||
<t>Note that the fourth character in the 'XMP ' FourCC is an ASCII sp | <aside><t>Note that the fourth character in the 'XMP ' FourCC is an A | |||
ace | SCII space | |||
(0x20).</t> | (0x20).</t></aside> | |||
<t>Additional guidance about handling metadata can be found in the | <t>Additional guidance about handling metadata can be found in the | |||
Metadata Working Group's <xref target="MWG">"Guidelines For | Metadata Working Group's <xref target="MWG">"Guidelines For | |||
Handling Image Metadata"</xref>.</t> | Handling Image Metadata"</xref>.</t> | |||
</section> | </section> | |||
<section anchor="unknown-chunks" numbered="true" toc="default"> | <section anchor="unknown-chunks" numbered="true" toc="default"> | |||
<name>Unknown Chunks</name> | <name>Unknown Chunks</name> | |||
<t>A RIFF chunk (described in <xref | <t>A RIFF chunk (described in <xref | |||
target="riff-file-format"/>) whose <em>FourCC</em> is | target="riff-file-format"/>) whose <em>FourCC</em> is | |||
different from any of the chunks described in this section is | different from any of the chunks described in this section is | |||
considered an <em>unknown chunk</em>.</t> | considered an <em>unknown chunk</em>.</t> | |||
skipping to change at line 918 ¶ | skipping to change at line 892 ¶ | |||
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.</t> | in its final state if all iterations have been completed.</t> | |||
<t>The following pseudocode illustrates the rendering process. The | <t>The following pseudocode illustrates the rendering process. The | |||
notation <em>VP8X.field</em> means the field in the 'VP8X' Chunk | notation <em>VP8X.field</em> means the field in the 'VP8X' Chunk | |||
with the same description.</t> | with the same description.</t> | |||
<sourcecode type="pseudocode"><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
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 line 946 ¶ | skipping to change at line 921 ¶ | |||
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 | |||
]]></sourcecode> | ]]></sourcecode> | |||
</section> | </section> | |||
skipping to change at line 1010 ¶ | skipping to change at line 986 ¶ | |||
+- ANMF (frame4 parameters + data) | +- ANMF (frame4 parameters + data) | |||
+- EXIF (metadata) | +- EXIF (metadata) | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="webp-lossless" numbered="true" toc="default"> | <section anchor="webp-lossless" numbered="true" toc="default"> | |||
<name>Specification for WebP Lossless Bitstream</name> | <name>Specification for WebP Lossless Bitstream</name> | |||
<t>Note that this section is based on the documentation in the <xref | <aside><t>Note that this section is based on the documentation in the <xref | |||
target="webp-lossless-src">libwebp source repository</xref>.</t> | target="webp-lossless-src">libwebp source repository</xref>.</t></aside> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Abstract (from "Specification for WebP Lossless Bitstream")</name> | <name>Abstract (from "Specification for WebP Lossless Bitstream")</name> | |||
<t>WebP lossless is an image format for lossless compression of ARGB | <t>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 0. | exactly, including the color values for pixels whose alpha value is 0. | |||
The format uses subresolution images, recursively embedded into the | The format uses subresolution images, recursively embedded into the | |||
format itself, for storing statistical data about the images, such as | format itself, for storing statistical data about the images, such as | |||
the used entropy codes, spatial predictors, color space conversion, | the used entropy codes, spatial predictors, color space conversion, | |||
and color table. A universal algorithm for sequential data compression <xref target="LZ77"/>, prefix coding, and a color cache are used for | and color table. A universal algorithm for sequential data compression <xref target="LZ77"/>, prefix coding, and a color cache are used for | |||
compression of the bulk data. Decoding speeds faster than PNG have | compression of the bulk data. Decoding speeds faster than PNG have | |||
skipping to change at line 1196 ¶ | skipping to change at line 1172 ¶ | |||
// Decode transform data. | // Decode transform data. | |||
... | ... | |||
} | } | |||
// Decode actual image data. | // Decode actual image data. | |||
]]></sourcecode> | ]]></sourcecode> | |||
<t>If a transform is present, then the next two bits specify the | <t>If a transform is present, then the next two bits specify the | |||
transform type. There are four types of transforms.</t> | transform type. There are four types of transforms.</t> | |||
<table align="left"> | <table align="left"> | |||
<name>Transform Types</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th>Transform</th> | <th>Transform</th> | |||
<th>Bit</th> | <th>Bit</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td>PREDICTOR_TRANSFORM</td> | <td>PREDICTOR_TRANSFORM</td> | |||
<td>0</td> | <td>0</td> | |||
skipping to change at line 1275 ¶ | skipping to change at line 1252 ¶ | |||
]]></sourcecode> | ]]></sourcecode> | |||
<t>There are 14 different prediction modes. In each prediction mode, | <t>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.</t> | pixels whose values are already known.</t> | |||
<t>We chose the neighboring pixels (TL, T, TR, and L) of the current | <t>We chose the neighboring pixels (TL, T, TR, and L) of the current | |||
pixel (P) as follows:</t> | pixel (P) as follows:</t> | |||
<figure> | <figure> | |||
<name>Neighboring Pixels of the Current Pixel (P)</name> | ||||
<artwork name="" type="ascii-art" align="left" alt=""><![CDATA[ | <artwork name="" type="ascii-art" align="left" alt=""><![CDATA[ | |||
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 | |||
]]></artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t>where TL means top-left, T means top, TR means top-right, and L mean s left. At the | <t>where TL means top-left, T means top, TR means top-right, and L mean s left. At the | |||
time of predicting a value for P, all O, TL, T, TR, and L pixels have | 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 pixels are | already been processed, and the P pixel and all X pixels are | |||
unknown.</t> | unknown.</t> | |||
<t>Given the preceding neighboring pixels, the different prediction mod es | <t>Given the preceding neighboring pixels, the different prediction mod es | |||
are defined as follows.</t> | are defined as follows.</t> | |||
<table align="left"> | <table align="left"> | |||
<name>Prediction Modes</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th>Mode</th> | <th>Mode</th> | |||
<th>Predicted Value of Each Channel of the Current Pixel</th> | <th>Predicted Value of Each Channel of the Current Pixel</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td>0</td> | <td>0</td> | |||
<td>0xff000000 (represents solid black color in ARGB)</td> | <td>0xff000000 (represents solid black color in ARGB)</td> | |||
skipping to change at line 1415 ¶ | skipping to change at line 1394 ¶ | |||
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); | |||
} | } | |||
]]></sourcecode> | ]]></sourcecode> | |||
<t>There are special handling rules for some border pixels. If there | <t>There are special handling rules for some border pixels. If there | |||
is a prediction transform, regardless of the mode [0..13] for these | is 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 | is 0xff000000, all pixels on the top row are L-pixel, and | |||
all pixels on the leftmost column are T-pixel.</t> | all pixels on the leftmost column are T-pixel.</t> | |||
<t>Addressing the TR-pixel for pixels on the rightmost column is | <t>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.</t> | as the TR-pixel.</t> | |||
<t>The final pixel value is obtained by adding each channel of the | <t>The final pixel value is obtained by adding each channel of the | |||
skipping to change at line 1507 ¶ | skipping to change at line 1486 ¶ | |||
<t>A conversion from the 8-bit unsigned representation | <t>A conversion from the 8-bit unsigned representation | |||
(<tt>uint8</tt>) to the 8-bit signed one (<tt>int8</tt>) is required | (<tt>uint8</tt>) to the 8-bit signed one (<tt>int8</tt>) is required | |||
before calling <tt>ColorTransformDelta()</tt>. | before calling <tt>ColorTransformDelta()</tt>. | |||
The signed value should be interpreted as an 8-bit two's complement number (that is: uint8 range [128..255] is mapped | The signed value should be interpreted as an 8-bit two's complement number (that is: uint8 range [128..255] is mapped | |||
to the [-128..-1] range of its converted int8 value).</t> | to the [-128..-1] range of its converted int8 value).</t> | |||
<t>The multiplication is to be done using more precision (with at | <t>The multiplication is to be done using more precision (with at | |||
least 16-bit precision). The sign extension property of the shift | least 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.</t> | unsigned shifting are consistent with each other.</t> | |||
<t>Now, we describe the contents of color transform data so that | <t>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:</t> | number of bits, just like the predictor transform:</t> | |||
<sourcecode type="c"><![CDATA[ | <sourcecode type="c"><![CDATA[ | |||
int size_bits = ReadBits(3) + 2; | int size_bits = ReadBits(3) + 2; | |||
int block_width = 1 << size_bits; | int block_width = 1 << size_bits; | |||
skipping to change at line 1643 ¶ | skipping to change at line 1622 ¶ | |||
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.</t> | image width respectively.</t> | |||
<aside><t>Pixel bundling allows for a more efficient | <aside><t>Pixel bundling allows for a more efficient | |||
joint distribution entropy coding of neighboring pixels and gives | joint distribution entropy coding of neighboring pixels and gives | |||
some arithmetic coding-like benefits to the entropy code, but it can | some arithmetic coding-like benefits to the entropy code, but it can | |||
only be used when there are 16 or fewer unique values.</t></aside> | only be used when there are 16 or fewer unique values.</t></aside> | |||
<t><tt>color_table_size</tt> specifies how many pixels are | <t><tt>color_table_size</tt> specifies how many pixels are | |||
combined:</t> | combined:</t> | |||
<table align="left"> | <table align="left"> | |||
<name>Color Table Size to Bundled Pixel Bit Width Mapping</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th>color_table_size</th> | <th>color_table_size</th> | |||
<th>width_bits value</th> | <th>width_bits value</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td>1..2</td> | <td>1..2</td> | |||
<td>3</td> | <td>3</td> | |||
skipping to change at line 1723 ¶ | skipping to change at line 1703 ¶ | |||
<li>ARGB image: Stores the actual pixels of the image.</li> | <li>ARGB image: Stores the actual pixels of the image.</li> | |||
<li>Entropy image: Stores the meta prefix | <li>Entropy image: Stores the meta prefix | |||
codes (see <xref | codes (see <xref | |||
target="decoding-of-meta-prefix-codes">"Decoding of Meta Prefix Cod es"</xref>).</li> | target="decoding-of-meta-prefix-codes">"Decoding of Meta Prefix Cod es"</xref>).</li> | |||
<li>Predictor image: Stores the metadata for the predictor transform (see <xref | <li>Predictor image: Stores the metadata for the predictor transform (see <xref | |||
target="predictor-transform">"Predictor Transform"</xref>).</li> | target="predictor-transform">"Predictor Transform"</xref>).</li> | |||
<li>Color transform image: Created by | <li>Color transform image: Created by | |||
<tt>ColorTransformElement</tt> values (defined in <xref | <tt>ColorTransformElement</tt> values (defined in <xref | |||
target="color-transform">"Color Transform"</xref>) for different | target="color-transform">"Color Transform"</xref>) for different | |||
blocks of the image.</li> | blocks of the image.</li> | |||
<li>Color indexing image: An array of size | <li>Color indexing image: An array of the size of | |||
<tt>color_table_size</tt> (up to 256 ARGB values) storing the | <tt>color_table_size</tt> (up to 256 ARGB values) that stores the | |||
metadata for the color | metadata for the color | |||
indexing transform (see <xref target="color-indexing-transform" >"Color Indexing Transform"</xref>).</li> | indexing transform (see <xref target="color-indexing-transform" >"Color Indexing Transform"</xref>).</li> | |||
</ol> | </ol> | |||
</section> | </section> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Encoding of Image Data</name> | <name>Encoding of Image Data</name> | |||
<t>The encoding of image data is independent of its role.</t> | <t>The encoding of image data is independent of its role.</t> | |||
<t>The image is first divided into a set of fixed-size blocks | <t>The image is first divided into a set of fixed-size blocks | |||
skipping to change at line 1799 ¶ | skipping to change at line 1779 ¶ | |||
stored as they are (without an entropy code).</t> | stored as they are (without an entropy code).</t> | |||
<aside><t>Rationale: This approach reduces the storage requirement | <aside><t>Rationale: This approach reduces the storage requirement | |||
for the entropy code. Also, large values are usually rare, so | for the entropy code. Also, large values are usually rare, so | |||
extra bits would be used for very few values in the image. Thus, | extra bits would be used for very few values in the image. Thus, | |||
this approach results in better compression overall.</t></aside> | this approach results in better compression overall.</t></aside> | |||
<t>The following table denotes the prefix codes and extra bits used | <t>The following table denotes the prefix codes and extra bits used | |||
for storing different ranges of values.</t> | for storing different ranges of values.</t> | |||
<t>Note: The maximum backward reference length is limited to 4096. | <aside><t>Note: The maximum backward reference length is limited to 4 096. | |||
Hence, only the first 24 prefix codes (with the respective extra | Hence, only the first 24 prefix codes (with the respective extra | |||
bits) are meaningful for length values. For distance values, | bits) are meaningful for length values. For distance values, | |||
however, all the 40 prefix codes are valid.</t> | however, all the 40 prefix codes are valid.</t></aside> | |||
<table align="left"> | <table align="left"> | |||
<name>Value to Prefix Code and Extra Bits Mapping</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th>Value Range</th> | <th>Value Range</th> | |||
<th>Prefix Code</th> | <th>Prefix Code</th> | |||
<th>Extra Bits</th> | <th>Extra Bits</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td>1</td> | <td>1</td> | |||
skipping to change at line 1920 ¶ | skipping to change at line 1901 ¶ | |||
112</tt>].</li> | 112</tt>].</li> | |||
<li>Pixels that are in the same row as the current pixel and are up | <li>Pixels that are in the same row as the current pixel and are up | |||
to 8 columns to the left of the current pixel [<tt>8</tt> such | to 8 columns to the left of the current pixel [<tt>8</tt> such | |||
pixels].</li> | pixels].</li> | |||
</ul> | </ul> | |||
<t>The mapping between distance code <tt>distance_code</tt> and the n eighboring | <t>The mapping between distance code <tt>distance_code</tt> and the n eighboring | |||
pixel offset <tt>(xi, yi)</tt> is as follows:</t> | pixel offset <tt>(xi, yi)</tt> is as follows:</t> | |||
<figure> | <figure> | |||
<name>Distance Code to Neighboring Pixel Offset Mapping</name> | ||||
<artwork name="" type="ascii-art" align="left" alt=""><![CDATA[ | <artwork name="" type="ascii-art" align="left" alt=""><![CDATA[ | |||
(0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), | (0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), | |||
(-1, 2), (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), | (-1, 2), (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), | |||
(1, 3), (-1, 3), (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), | (1, 3), (-1, 3), (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), | |||
(-3, 2), (0, 4), (4, 0), (1, 4), (-1, 4), (4, 1), (-4, 1), | (-3, 2), (0, 4), (4, 0), (1, 4), (-1, 4), (4, 1), (-4, 1), | |||
(3, 3), (-3, 3), (2, 4), (-2, 4), (4, 2), (-4, 2), (0, 5), | (3, 3), (-3, 3), (2, 4), (-2, 4), (4, 2), (-4, 2), (0, 5), | |||
(3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0), (1, 5), (-1, 5), | (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0), (1, 5), (-1, 5), | |||
(5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2), (4, 4), | (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2), (4, 4), | |||
(-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0), | (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0), | |||
(1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), | (1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), | |||
skipping to change at line 2112 ¶ | skipping to change at line 2094 ¶ | |||
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; | |||
} | } | |||
]]></sourcecode> | ]]></sourcecode> | |||
<aside><t>The two symbols should be different. Duplicate symbols are | <aside><t>The two symbols should be different. Duplicate symbols are | |||
allowed, but inefficient.</t></aside> | allowed, but inefficient.</t></aside> | |||
<t>Note: Another special case is when <em>all</em> prefix code | <aside><t>Note: Another special case is when <em>all</em> prefix code | |||
lengths are <em>zeros</em> (an empty prefix code). For example, a | lengths are <em>zeros</em> (an empty prefix code). For example, a | |||
prefix code for distance can be empty if there are no backward | prefix code for distance can be empty if there are no backward | |||
references. Similarly, prefix codes for alpha, red, and blue can | references. Similarly, prefix codes for alpha, red, and blue can | |||
be empty if all pixels within the same meta prefix code are | be empty if all pixels within the same meta prefix code are | |||
produced using the color cache. However, this case doesn't need | produced using the color cache. However, this case doesn't need | |||
special handling, as empty prefix codes can be coded as those | special handling, as empty prefix codes can be coded as those | |||
containing a single symbol <tt>0</tt>.</t> | containing a single symbol <tt>0</tt>.</t></aside> | |||
</section> | </section> | |||
<section anchor="normal-code-length"> | <section anchor="normal-code-length"> | |||
<name>Normal Code Length Code</name> | <name>Normal Code Length Code</name> | |||
<t>The code lengths of the prefix code fit in 8 bits and are read | <t>The code lengths of the prefix code fit in 8 bits and are read | |||
as follows. First, <tt>num_code_lengths</tt> specifies the number | as follows. First, <tt>num_code_lengths</tt> specifies the number | |||
of code lengths.</t> | of code lengths.</t> | |||
<sourcecode type="c"><![CDATA[ | <sourcecode type="c"><![CDATA[ | |||
int num_code_lengths = 4 + ReadBits(4); | int num_code_lengths = 4 + ReadBits(4); | |||
skipping to change at line 2295 ¶ | skipping to change at line 2277 ¶ | |||
</section> | </section> | |||
<section anchor="decoding-entropy-coded-image-data" numbered="true" | <section anchor="decoding-entropy-coded-image-data" numbered="true" | |||
toc="default"> | toc="default"> | |||
<name>Decoding Entropy-Coded Image Data</name> | <name>Decoding Entropy-Coded Image Data</name> | |||
<t>For the current position (x, y) in the image, the decoder first | <t>For the current position (x, y) in the image, the decoder first | |||
identifies the corresponding prefix code group (as explained in | identifies the corresponding prefix code group (as explained in | |||
the last section). Given the prefix code group, the pixel is read | the last section). Given the prefix code group, the pixel is read | |||
and decoded as follows.</t> | and decoded as follows.</t> | |||
<t>Next, read symbol S from the bitstream using prefix code #1. | <t>Next, read symbol S from the bitstream using prefix code #1.</t> | |||
Note that S is any integer in the range <tt>0</tt> to | <aside><t>Note that S is any integer in the range <tt>0</tt> to | |||
<tt>(256 + 24 + </tt> <xref | <tt>(256 + 24 + color_cache_size - 1)</tt>. See <xref | |||
target="color-cache-coding"><tt>color_cache_size</tt></xref><tt> - | target="color-cache-coding"/> for details about | |||
1)</tt>.</t> | <tt>color_cache_size</tt>.</t></aside> | |||
<t>The interpretation of S depends on its value:</t> | <t>The interpretation of S depends on its value:</t> | |||
<ol spacing="normal" type="1"> | <ol spacing="normal" type="1"> | |||
<li><t>If S < 256</t> | <li><t>If S < 256</t> | |||
<ol spacing="normal" type="i"> | <ol spacing="normal" type="i"> | |||
<li>Use S as the green component.</li> | <li>Use S as the green component.</li> | |||
<li>Read red from the bitstream using prefix code #2.</li> | <li>Read red from the bitstream using prefix code #2.</li> | |||
<li>Read blue from the bitstream using prefix code #3.</li> | <li>Read blue from the bitstream using prefix code #3.</li> | |||
<li>Read alpha from the bitstream using prefix code #4.</li> | <li>Read alpha from the bitstream using prefix code #4.</li> | |||
</ol> | </ol> | |||
skipping to change at line 2343 ¶ | skipping to change at line 2325 ¶ | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Overall Structure of the Format</name> | <name>Overall Structure of the Format</name> | |||
<t>Below is a view into the format in Augmented Backus-Naur Form <xref | <t>Below is a view into the format in Augmented Backus-Naur Form <xref | |||
target="RFC5234"/> <xref target="RFC7405"/>. It does not cover all deta ils. The end-of-image (EOI) | target="RFC5234"/> <xref target="RFC7405"/>. It does not cover all deta ils. The end-of-image (EOI) | |||
is only implicitly coded into the number of pixels (image_width * | is only implicitly coded into the number of pixels (image_width * | |||
image_height).</t> | image_height).</t> | |||
<t>Note that <tt>*element</tt> means <tt>element</tt> can be repeated 0 o | <aside><t>Note that <tt>*element</tt> means <tt>element</tt> can be repea | |||
r more times. <tt>5element</tt> | ted 0 or more times. <tt>5element</tt> | |||
means <tt>element</tt> is repeated exactly 5 times. <tt>%b</tt> represents a bin | means <tt>element</tt> is repeated exactly 5 times. <tt>%b</tt> represents a bin | |||
ary value.</t> | ary value.</t></aside> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Basic Structure</name> | <name>Basic Structure</name> | |||
<sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"><![CDATA[ | |||
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 | |||
skipping to change at line 2414 ¶ | skipping to change at line 2396 ¶ | |||
prefix-code = simple-prefix-code / normal-prefix-code | prefix-code = simple-prefix-code / normal-prefix-code | |||
simple-prefix-code = ; see "Simple Code Length Code" for details | simple-prefix-code = ; see "Simple Code Length Code" for details | |||
normal-prefix-code = ; see "Normal Code Length Code" for details | normal-prefix-code = ; see "Normal Code Length Code" for details | |||
lz77-coded-image = | lz77-coded-image = | |||
*((argb-pixel / lz77-copy / color-cache-code) lz77-coded-image) | *((argb-pixel / lz77-copy / color-cache-code) lz77-coded-image) | |||
]]></sourcecode> | ]]></sourcecode> | |||
<t>The following is a possible example sequence:</t> | <t>The following is a possible example sequence:</t> | |||
<sourcecode><![CDATA[ | <sourcecode type="abnf"><![CDATA[ | |||
RIFF-header image-size %b1 subtract-green-tx | RIFF-header image-size %b1 subtract-green-tx | |||
%b1 predictor-tx %b0 color-cache-info | %b1 predictor-tx %b0 color-cache-info | |||
%b0 prefix-codes lz77-coded-image | %b0 prefix-codes lz77-coded-image | |||
]]></sourcecode> | ]]></sourcecode> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="Security" numbered="true" toc="default"> | <section anchor="Security" numbered="true" toc="default"> | |||
<name>Security Considerations</name> | <name>Security Considerations</name> | |||
skipping to change at line 2436 ¶ | skipping to change at line 2418 ¶ | |||
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 or | uninitialized data usage, null pointer dereferences, resource (disk or | |||
memory) exhaustion, and extended resource usage (long running time) as | memory) exhaustion, and extended resource usage (long running time) as | |||
part of the demuxing and decoding process. In particular, | 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 bro wsers or | unknown and possibly unsafe sources -- both clients (for example, web bro wsers or | |||
email clients) and servers (for example, applications that accept uploade d | email clients) and servers (for example, applications that accept uploade d | |||
images). These may result in arbitrary code execution, information | images). These may result in arbitrary code execution, information | |||
leakage (memory layout and contents), or crashes and thereby allow a | leakage (memory layout and contents), or crashes and thereby allow a | |||
device to be compromised or cause a denial of service to an application | device to be compromised or cause a denial of service to an application | |||
using the format <xref target="cve.mitre.org-libwebp"/> <xref | using the format <xref target="mitre-libwebp"/> <xref | |||
target="crbug-security"/>.</t> | target="issues-security"/>.</t> | |||
<t>The format does not employ "active content" but does allow metadata | <t>The format does not employ "active content" but does allow metadata | |||
(for example, <xref target="XMP"/> and <xref target="Exif"/>) and custom ch unks to be | (for example, <xref target="XMP"/> and <xref target="Exif"/>) and custom ch unks to be | |||
embedded in a file. Applications that interpret these chunks may be | embedded in a file. Applications that interpret these chunks may be | |||
subject to security considerations for those formats.</t> | subject to security considerations for those formats.</t> | |||
</section> | </section> | |||
<section anchor="Interop" numbered="true" toc="default"> | <section anchor="Interop" numbered="true" toc="default"> | |||
<name>Interoperability Considerations</name> | <name>Interoperability Considerations</name> | |||
<t>The format is defined using little-endian byte ordering (see <xref | <t>The format is defined using little-endian byte ordering (see <xref | |||
target="RFC2781" section="3.1"/>), but demuxing and decoding are | target="RFC2781" section="3.1"/>), but demuxing and decoding are | |||
possible on platforms using a different ordering with the appropriate | possible on platforms using a different ordering with the appropriate | |||
conversion. | 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 | |||
(<xref target="webp-container"/>) are required for decoding of the image. | (<xref target="webp-container"/>) are required for decoding of the image. | |||
These have been finalized but were extended in the format's early | These have been finalized, but they were extended in the format's early | |||
stages, so some older readers may not support lossless or animated image | stages, so some older readers may not support lossless or animated image | |||
decoding.</t> | decoding.</t> | |||
</section> | </section> | |||
<section anchor="IANA" numbered="true" toc="default"> | <section anchor="IANA" numbered="true" toc="default"> | |||
<name>IANA Considerations</name> | <name>IANA Considerations</name> | |||
<t>IANA has registered the 'image/webp' media type <xref | <t>IANA has registered the 'image/webp' media type <xref | |||
target="RFC2046"/>.</t> | target="RFC2046"/>.</t> | |||
<section anchor="webp-media-type" numbered="true" toc="default"> | <section anchor="webp-media-type" numbered="true" toc="default"> | |||
<name>The 'image/webp' Media Type</name> | <name>The 'image/webp' Media Type</name> | |||
<t>This section contains the media type registration details per <xref | <t>This section contains the media type registration details per <xref | |||
target="RFC6838"/>.</t> | target="RFC6838"/>.</t> | |||
<section numbered="true" toc="default"> | <section numbered="true" toc="default"> | |||
<name>Registration Details</name> | <name>Registration Details</name> | |||
<!-- RFC Editor Note: Remove this text element after updating. --> | ||||
<t><strong>RFC Editor Note:</strong> Replace RFC XXXX / rfcXXXX with | ||||
the published RFC number.</t> | ||||
<dl newline="false" spacing="normal"> | <dl newline="false" spacing="normal"> | |||
<dt>Type name:</dt> <dd>image</dd> | <dt>Type name:</dt> <dd>image</dd> | |||
<dt>Subtype name:</dt> <dd>webp</dd> | <dt>Subtype name:</dt> <dd>webp</dd> | |||
<dt>Required parameters:</dt> <dd>N/A</dd> | <dt>Required parameters:</dt> <dd>N/A</dd> | |||
<dt>Optional parameters:</dt> <dd>N/A</dd> | <dt>Optional parameters:</dt> <dd>N/A</dd> | |||
<dt>Encoding considerations:</dt> <dd>Binary. The <xref target="RFC46 48">Base64 | <dt>Encoding considerations:</dt> <dd>Binary. The <xref target="RFC46 48">Base64 | |||
encoding</xref> should be used on transports that cannot accommodate | encoding</xref> should be used on transports that cannot accommodate | |||
binary data directly.</dd> | binary data directly.</dd> | |||
<dt>Security considerations:</dt> <dd>See RFC XXXX, <xref target="Sec | <dt>Security considerations:</dt> <dd>See RFC 9649, <xref target="Sec | |||
urity"/>.</dd> | urity"/>.</dd> | |||
<dt>Interoperability considerations:</dt> <dd>See RFC XXXX, <xref tar | <dt>Interoperability considerations:</dt> <dd>See RFC 9649, <xref tar | |||
get="Interop"/>.</dd> | get="Interop"/>.</dd> | |||
<dt>Published specification:</dt> <dd>RFC XXXX</dd> | <dt>Published specification:</dt> <dd>RFC 9649</dd> | |||
<dt>Applications that use this media type:</dt> <dd>Applications that are used to | <dt>Applications that use this media type:</dt> <dd>Applications that are used to | |||
display and process images, especially when smaller image file sizes | display and process images, especially when smaller image file sizes | |||
are important.</dd> | are important.</dd> | |||
<dt>Fragment identifier considerations:</dt> <dd>N/A</dd> | <dt>Fragment identifier considerations:</dt> <dd>N/A</dd> | |||
<dt>Additional information:</dt> | <dt>Additional information:</dt> | |||
<dd><t><br/></t> | <dd><t><br/></t> | |||
<dl spacing="compact"> | <dl spacing="compact"> | |||
<dt>Deprecated alias names for this type:</dt> <dd>N/A</dd> | <dt>Deprecated alias names for this type:</dt> <dd>N/A</dd> | |||
<dt>Magic number(s):</dt> <dd>The first 4 bytes are 0x52, 0x49, 0x46, 0x46 | <dt>Magic number(s):</dt> <dd>The first 4 bytes are 0x52, 0x49, 0x46, 0x46 | |||
skipping to change at line 2506 ¶ | skipping to change at line 2485 ¶ | |||
('WEBPVP8').</dd> | ('WEBPVP8').</dd> | |||
<dt>File extension(s):</dt> <dd>webp</dd> | <dt>File extension(s):</dt> <dd>webp</dd> | |||
<dt>Apple Uniform Type Identifier:</dt> <dd>org.webmproject.webp conf orms to | <dt>Apple Uniform Type Identifier:</dt> <dd>org.webmproject.webp conf orms to | |||
public.image</dd> | public.image</dd> | |||
<dt>Object Identifiers:</dt> <dd>N/A</dd> | <dt>Object Identifiers:</dt> <dd>N/A</dd> | |||
</dl></dd> | </dl></dd> | |||
<dt>Person & email address to contact for further information:</dt> | <dt>Person & email address to contact for further information:</dt> | |||
<dd>James Zern <jzern@google.com></dd></dl> | <dd>James Zern <jzern@google.com></dd></dl> | |||
<dl newline="false" spacing="normal"> | <dl newline="false" spacing="normal"> | |||
<dt>Intended usage:</dt> <dd>COMMON</dd> | ||||
<dt>Restrictions on usage:</dt> <dd>N/A</dd> | <dt>Restrictions on usage:</dt> <dd>N/A</dd> | |||
<dt>Author:</dt> | <dt>Author:</dt> | |||
<dd>James Zern <jzern@google.com></dd> | <dd>James Zern <jzern@google.com></dd> | |||
</dl> | <dt>Change controller:</dt><dd>IETF</dd> | |||
<dl newline="false" spacing="compact"> | ||||
<dt>Change controller:</dt><dd></dd> | ||||
<dt></dt><dd>IETF</dd> | ||||
</dl> | ||||
<dl newline="false" spacing="normal"> | ||||
<dt>Intended usage:</dt> <dd>COMMON</dd> | ||||
</dl> | </dl> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
</middle> | </middle> | |||
<back> | <back> | |||
<references> | <references> | |||
<name>References</name> | <name>References</name> | |||
<references> | <references> | |||
<name>Normative References</name> | <name>Normative References</name> | |||
skipping to change at line 2612 ¶ | skipping to change at line 2585 ¶ | |||
<author> | <author> | |||
<organization>Adobe Inc.</organization> | <organization>Adobe Inc.</organization> | |||
</author> | </author> | |||
</front> | </front> | |||
</reference> | </reference> | |||
</references> | </references> | |||
<references> | <references> | |||
<name>Informative References</name> | <name>Informative References</name> | |||
<reference anchor="crbug-security" target="https://bugs.chromium. | <reference anchor="mitre-libwebp" | |||
org/p/webp/issues/list?q=label%3ASecurity"> | ||||
<front> | ||||
<title>libwebp Security Issues</title> | ||||
<author> | ||||
<organization/> | ||||
</author> | ||||
</front> | ||||
</reference> | ||||
<reference anchor="cve.mitre.org-libwebp" | ||||
target="https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=libwebp"> | target="https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=libwebp"> | |||
<front> | <front> | |||
<title>libwebp CVE List</title> | <title>libwebp CVE List</title> | |||
<author> | <author> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="GIF-spec" | <reference anchor="GIF-spec" | |||
skipping to change at line 2656 ¶ | skipping to change at line 2620 ¶ | |||
Codes</title> | Codes</title> | |||
<author initials="D." surname="Huffman"> | <author initials="D." surname="Huffman"> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date month="September" year="1952" /> | <date month="September" year="1952" /> | |||
</front> | </front> | |||
<seriesInfo name="DOI" value="10.1109/JRPROC.1952.273898"/> | <seriesInfo name="DOI" value="10.1109/JRPROC.1952.273898"/> | |||
<refcontent>Proceedings of the Institute of Radio Engineers, Vol. 40, Issue 9 , pp. 1098-1101</refcontent> | <refcontent>Proceedings of the Institute of Radio Engineers, Vol. 40, Issue 9 , pp. 1098-1101</refcontent> | |||
</reference> | </reference> | |||
<reference anchor="issues-security" target="https://issues.webmpr | ||||
oject.org/issues?q=componentid:1618983%2B%20(%22Restrict-View-Security%22%20OR%2 | ||||
0type:vulnerability)"> | ||||
<front> | ||||
<title>libwebp Security Issues</title> | ||||
<author> | ||||
<organization/> | ||||
</author> | ||||
</front> | ||||
</reference> | ||||
<reference anchor="JPEG-spec" | <reference anchor="JPEG-spec" | |||
target="https://www.w3.org/Graphics/JPEG/itu-t81.pdf"> | target="https://www.w3.org/Graphics/JPEG/itu-t81.pdf"> | |||
<front> | <front> | |||
<title>Information Technology - Digital Compression and Coding of Con tinuous-Tone Still Images - Requirements and Guidelines</title> | <title>Information Technology - Digital Compression and Coding of Con tinuous-Tone Still Images - Requirements and Guidelines</title> | |||
<author> | <author> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
<date month="September" year="1992"/> | <date month="September" year="1992"/> | |||
</front> | </front> | |||
<seriesInfo name="ITU-T Recommendation" value="T.81"/> | <seriesInfo name="ITU-T Recommendation" value="T.81"/> | |||
skipping to change at line 2708 ¶ | skipping to change at line 2681 ¶ | |||
target="https://www.loc.gov/preservation/digital/formats/fdd/fdd000025.shtml"> | target="https://www.loc.gov/preservation/digital/formats/fdd/fdd000025.shtml"> | |||
<front> | <front> | |||
<title>RIFF (Resource Interchange File Format)</title> | <title>RIFF (Resource Interchange File Format)</title> | |||
<author> | <author> | |||
<organization/> | <organization/> | |||
</author> | </author> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="webp-lossless-src" | <reference anchor="webp-lossless-src" | |||
target="https://chromium.googlesource.com/webm/libwebp/+/refs/tags/webp -rfcXXXX/doc/webp-lossless-bitstream-spec.txt"> | target="https://chromium.googlesource.com/webm/libwebp/+/refs/tags/webp -rfc9649/doc/webp-lossless-bitstream-spec.txt"> | |||
<front> | <front> | |||
<title>WebP Lossless Bitstream Specification</title> | <title>WebP Lossless Bitstream Specification</title> | |||
<author initials="J." surname="Alakuijala" | <author initials="J." surname="Alakuijala" | |||
fullname="Jyrki Alakuijala"> | fullname="Jyrki Alakuijala"> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
</author> | </author> | |||
<date month="October" year="2023" /> | <date month="July" year="2024" /> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="webp-lossless-study" target="https://developer s.google.com/speed/webp/docs/webp_lossless_alpha_study"> | <reference anchor="webp-lossless-study" target="https://developer s.google.com/speed/webp/docs/webp_lossless_alpha_study"> | |||
<front> | <front> | |||
<title>Lossless and Transparency Encoding in WebP</title> | <title>Lossless and Transparency Encoding in WebP</title> | |||
<author initials="J." surname="Alakuijala" | <author initials="J." surname="Alakuijala" | |||
fullname="Jyrki Alakuijala"> | fullname="Jyrki Alakuijala"> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
</author> | </author> | |||
<author initials="V." surname="Rabaud" | <author initials="V." surname="Rabaud" | |||
fullname="Vincent Rabaud"> | fullname="Vincent Rabaud"> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
</author> | </author> | |||
<date month="August" year="2017" /> | <date month="August" year="2017" /> | |||
</front> | </front> | |||
</reference> | </reference> | |||
<reference anchor="webp-riff-src" target="https://chromium.googlesour ce.com/webm/libwebp/+/refs/tags/webp-rfcXXXX/doc/webp-container-spec.txt"> | <reference anchor="webp-riff-src" target="https://chromium.googlesour ce.com/webm/libwebp/+/refs/tags/webp-rfc9649/doc/webp-container-spec.txt"> | |||
<front> | <front> | |||
<title>WebP RIFF Container</title> | <title>WebP RIFF Container</title> | |||
<author> | <author> | |||
<organization>Google LLC</organization> | <organization>Google LLC</organization> | |||
</author> | </author> | |||
<date month="April" year="2024" /> | <date month="July" year="2024" /> | |||
</front> | </front> | |||
</reference> | </reference> | |||
</references> | </references> | |||
</references> | </references> | |||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 66 change blocks. | ||||
127 lines changed or deleted | 105 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |