mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-25 13:18:22 +01:00
Image fragment specification in container spec
Change-Id: If8cad296738465df4327dfb6b44efa7e0356070e
This commit is contained in:
parent
391f9db9fa
commit
001b930219
@ -13,7 +13,7 @@ end of this file.
|
||||
WebP Container Specification
|
||||
============================
|
||||
|
||||
_Working Draft, v0.7, 20121102_
|
||||
_Working Draft, v0.8, 20121102_
|
||||
|
||||
|
||||
* TOC placeholder
|
||||
@ -46,6 +46,15 @@ for:
|
||||
* **Color Profile.** An image may have an embedded ICC profile as described
|
||||
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",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
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:
|
||||
|
||||
Code that reads WebP files is referred to as a _reader_, while
|
||||
code that writes them is referred to as a _writer_.
|
||||
_Reader/Writer_
|
||||
|
||||
: Code that reads WebP files is referred to as a _reader_, while code that
|
||||
writes them is referred to as a _writer_.
|
||||
|
||||
_uint16_
|
||||
|
||||
@ -76,6 +87,7 @@ _uint32_
|
||||
: A 32-bit, little-endian, unsigned integer.
|
||||
|
||||
_1-based_
|
||||
|
||||
: An unsigned integer field storing values offset by `-1`. e.g., Such a field
|
||||
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 'ALPH' chunk with transparency information.
|
||||
|
||||
* The image bitstream contained in either a 'VP8 ' or 'VP8L' chunk.
|
||||
* Image data (described below).
|
||||
|
||||
* An optional 'EXIF' chunk with EXIF 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
|
||||
appears in the wrong place, the file is invalid, but readers MAY parse the
|
||||
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.
|
||||
|
||||
Extended WebP file header:
|
||||
{:#extended_header}
|
||||
|
||||
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
|
||||
@ -284,7 +313,7 @@ Extended WebP file header:
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| ChunkHeader('VP8X') |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|Rsv|I|L|E|X| R | Reserved |
|
||||
|Rsv|I|L|E|X|R|F| Reserved |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Canvas Width Minus One | ...
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
@ -301,7 +330,7 @@ ICC profile (I): 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").
|
||||
|
||||
EXIF metadata (E): 1 bit
|
||||
@ -312,10 +341,14 @@ XMP metadata (X): 1 bit
|
||||
|
||||
: Set if the file contains XMP metadata.
|
||||
|
||||
Reserved (R): 2 bits
|
||||
Reserved (R): 1 bit
|
||||
|
||||
: SHOULD be `0`.
|
||||
|
||||
Image Fragmentation (F): 1 bit
|
||||
|
||||
: Set if the image is represented by fragments.
|
||||
|
||||
Reserved: 24 bits
|
||||
|
||||
: SHOULD be `0`.
|
||||
@ -336,6 +369,48 @@ Future specifications MAY add more fields.
|
||||
|
||||
### 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
|
||||
|
||||
0 1 2 3
|
||||
@ -390,8 +465,8 @@ where `clip(v)` is equal to:
|
||||
* v otherwise
|
||||
|
||||
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
|
||||
into the [0-255] one:
|
||||
predictor and using modulo-256 arithmetic to wrap the \[256-511\] range
|
||||
into the \[0-255\] one:
|
||||
|
||||
`alpha = (predictor + X) % 256`
|
||||
|
||||
@ -417,10 +492,10 @@ Alpha bitstream: _Chunk Size_ - `1` bytes
|
||||
|
||||
: 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.
|
||||
|
||||
**Rationale**: The transparency information of the image is already part
|
||||
**Rationale**: The transparency information of the frame is already part
|
||||
of the 'VP8L' chunk.
|
||||
|
||||
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.
|
||||
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
|
||||
--------------------
|
||||
|
||||
@ -560,6 +671,17 @@ RIFF/WEBP
|
||||
+- 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
|
||||
[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
|
||||
|
Loading…
Reference in New Issue
Block a user