Image fragment specification in container spec

Change-Id: If8cad296738465df4327dfb6b44efa7e0356070e
This commit is contained in:
Urvang Joshi 2012-10-30 16:06:36 -07:00
parent 391f9db9fa
commit 001b930219

View File

@ -13,7 +13,7 @@ end of this file.
WebP Container Specification WebP Container Specification
============================ ============================
_Working Draft, v0.7, 20121102_ _Working Draft, v0.8, 20121102_
* TOC placeholder * TOC placeholder
@ -46,6 +46,15 @@ for:
* **Color Profile.** An image may have an embedded ICC profile as described * **Color Profile.** An image may have an embedded ICC profile as described
by the [International Color Consortium][iccspec]. by the [International Color Consortium][iccspec].
* **Image Fragmentation.** A single bitstream in WebP has an inherent
limitation for width or height of 2^14 pixels, and, when using VP8, a 512
KiB limit on the size of the first compressed partition. To support larger
images, the format supports images that are composed of multiple fragments,
each encoded as a separate bitstream. All fragments logically form a single
image: they have common metadata, color profile, etc. Image fragmentation
may also improve efficiency for larger images, e.g., grass can be encoded
differently than sky.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC 2119][]. document are to be interpreted as described in [RFC 2119][].
@ -60,8 +69,10 @@ matrix of pixels, we will call it the _canvas_ of the image.
Below are additional terms used throughout this document: Below are additional terms used throughout this document:
Code that reads WebP files is referred to as a _reader_, while _Reader/Writer_
code that writes them is referred to as a _writer_.
: Code that reads WebP files is referred to as a _reader_, while code that
writes them is referred to as a _writer_.
_uint16_ _uint16_
@ -76,6 +87,7 @@ _uint32_
: A 32-bit, little-endian, unsigned integer. : A 32-bit, little-endian, unsigned integer.
_1-based_ _1-based_
: An unsigned integer field storing values offset by `-1`. e.g., Such a field : An unsigned integer field storing values offset by `-1`. e.g., Such a field
would store value _25_ as _24_. would store value _25_ as _24_.
@ -257,14 +269,30 @@ An extended format file consists of:
* An optional 'ICCP' chunk with color profile. * An optional 'ICCP' chunk with color profile.
* An optional 'ALPH' chunk with transparency information. * Image data (described below).
* The image bitstream contained in either a 'VP8 ' or 'VP8L' chunk.
* 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.
The image can be fragmented or non-fragmented, as will be described in the
[Extended WebP file header](#extended_header) section.
For a _non-fragmented_ image, the _image data_ consists of:
* An optional 'ALPH' chunk with transparency information.
* The image bitstream contained in either a 'VP8 ' or 'VP8L' chunk.
For a _fragmented_ image, the _image data_ consists of multiple fragments,
where each fragment consists of:
* A 'FRGM' chunk with the fragment information.
* An optional 'ALPH' chunk with transparency information.
* The bitstream for the fragment contained in either a 'VP8 ' or 'VP8L' chunk.
All chunks SHOULD be placed in the same order as listed above. If a chunk All chunks SHOULD be placed in the same order as listed above. If a chunk
appears in the wrong place, the file is invalid, but readers MAY parse the appears in the wrong place, the file is invalid, but readers MAY parse the
file, ignoring the chunks that come too late. file, ignoring the chunks that come too late.
@ -276,6 +304,7 @@ ignoring late chunks should make programs that need to do a full search
give the same results as the ones stopping early. give the same results as the ones stopping early.
Extended WebP file header: Extended WebP file header:
{:#extended_header}
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@ -284,7 +313,7 @@ Extended WebP file header:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8X') | | ChunkHeader('VP8X') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X| R | Reserved | |Rsv|I|L|E|X|R|F| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Canvas Width Minus One | ... | Canvas Width Minus One | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@ -301,7 +330,7 @@ ICC profile (I): 1 bit
Alpha (L): 1 bit Alpha (L): 1 bit
: Set if the file contains some (or all) images with transparency information : Set if any of the frames of the image contain transparency information
("alpha"). ("alpha").
EXIF metadata (E): 1 bit EXIF metadata (E): 1 bit
@ -312,10 +341,14 @@ XMP metadata (X): 1 bit
: Set if the file contains XMP metadata. : Set if the file contains XMP metadata.
Reserved (R): 2 bits Reserved (R): 1 bit
: SHOULD be `0`. : SHOULD be `0`.
Image Fragmentation (F): 1 bit
: Set if the image is represented by fragments.
Reserved: 24 bits Reserved: 24 bits
: SHOULD be `0`. : SHOULD be `0`.
@ -336,6 +369,48 @@ Future specifications MAY add more fields.
### Chunks ### Chunks
#### Image Fragments
For images that are represented by fragments, this chunk contains data for
a single fragment. If the _Image Fragmentation Flag_ is not set, then this chunk
SHOULD NOT be present.
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('FRGM') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fragment X | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Fragment Y | Fragment Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fragment X: 24 bits (_uint24_)
: The X coordinate of the upper left corner of the fragment is `Fragment X * 2`
Fragment Y: 24 bits (_uint24_)
: The Y coordinate of the upper left corner of the fragment is `Fragment Y * 2`
Fragment Data: _Chunk Size_ - `6` bytes
: It contains:
* An optional [alpha subchunk](#alpha) for the fragment.
* The [bitstream subchunk](#bitstream-vp8vp8l) for the fragment.
Note: The width and height of the fragment is obtained from the bitstream
subchunk.
The fragments of an image SHOULD have the following properties:
* They collectively cover the whole canvas.
* No pair of fragments have any overlapping region on the canvas.
* No portion of any fragment should be located outside of the canvas.
#### Alpha #### Alpha
0 1 2 3 0 1 2 3
@ -390,8 +465,8 @@ where `clip(v)` is equal to:
* v otherwise * v otherwise
The final value is derived by adding the decompressed value `X` to the The final value is derived by adding the decompressed value `X` to the
predictor and using modulo-256 arithmetic to wrap the [256-511] range predictor and using modulo-256 arithmetic to wrap the \[256-511\] range
into the [0-255] one: into the \[0-255\] one:
`alpha = (predictor + X) % 256` `alpha = (predictor + X) % 256`
@ -417,10 +492,10 @@ Alpha bitstream: _Chunk Size_ - `1` bytes
: Encoded alpha bitstream. : Encoded alpha bitstream.
This optional chunk contains encoded alpha data for the image. An image This optional chunk contains encoded alpha data for this frame. A frame
containing a 'VP8L' chunk SHOULD NOT contain this chunk. containing a 'VP8L' chunk SHOULD NOT contain this chunk.
**Rationale**: The transparency information of the image is already part **Rationale**: The transparency information of the frame is already part
of the 'VP8L' chunk. of the 'VP8L' chunk.
The alpha channel data is stored as uncompressed raw data (when The alpha channel data is stored as uncompressed raw data (when
@ -528,6 +603,42 @@ Metadata Working Group's [Guidelines for Handling Metadata][metadata].
A file MAY contain other unknown chunks. Readers SHOULD ignore these chunks. A file MAY contain other unknown chunks. Readers SHOULD ignore these chunks.
Writers SHOULD preserve them in their original order. Writers SHOULD preserve them in their original order.
### Assembling the Canvas from fragments
Here we provide an overview of how 'FRGM' chunks are used to assemble the
canvas in case of a fragmented-image. The notation _VP8X.field_ means the field
in the 'VP8X' chunk with the same description.
Displaying a _fragmented image_ canvas MUST be equivalent to the following
pseudocode:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
assert VP8X.flags.hasFragments
canvas ← new black image of size VP8X.canvasWidth x VP8X.canvasHeight.
frgm_params ← nil
for chunk in image_data:
assert chunk.tag is "FRGM"
frgm_params.fragmentX = Fragment X
frgm_params.fragmentY = Fragment Y
for subchunk in 'Fragment Data':
if subchunk.tag == "ALPH":
assert alpha subchunks not found in 'Fragment Data' earlier
frgm_params.alpha = alpha_data
else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
assert bitstream subchunks not found in 'Fragment Data' earlier
frgm_params.bitstream = bitstream_data
frgm_params.fragmentWidth = Width extracted from bitstream subchunk
frgm_params.fragmentHeight = Height extracted from bitstream subchunk
assert VP8X.canvasWidth >=
frgm_params.fragmentX + frgm_params.fragmentWidth
assert VP8X.canvasHeight >=
frgm_params.fragmentY + frgm_params.fragmentHeight
assert fragment has the properties mentioned in "Image Fragments" section.
render fragment with frame_params.alpha and frame_params.bitstream on canvas
with top-left corner in (frgm_params.fragmentX, frgm_params.fragmentY).
canvas contains the decoded canvas.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example file layouts Example file layouts
-------------------- --------------------
@ -560,6 +671,17 @@ RIFF/WEBP
+- XMP (metadata) +- XMP (metadata)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A fragmented image may look as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RIFF/WEBP
+- VP8X (descriptions of features used)
+- FRGM (fragment1 parameters + data)
+- FRGM (fragment2 parameters + data)
+- FRGM (fragment3 parameters + data)
+- FRGM (fragment4 parameters + data)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[vp8spec]: http://tools.ietf.org/html/rfc6386 [vp8spec]: http://tools.ietf.org/html/rfc6386
[webpllspec]: https://gerrit.chromium.org/gerrit/gitweb?p=webm/libwebp.git;a=blob;f=doc/webp-lossless-bitstream-spec.txt;hb=master [webpllspec]: https://gerrit.chromium.org/gerrit/gitweb?p=webm/libwebp.git;a=blob;f=doc/webp-lossless-bitstream-spec.txt;hb=master
[iccspec]: http://www.color.org/icc_specs2.xalter [iccspec]: http://www.color.org/icc_specs2.xalter