Bureaucrats, canmove, Confirmed users, Interface administrators
3,153
edits
(increased restriction for blend_op and dispose_op) |
(note main metabug) |
||
| (27 intermediate revisions by 7 users not shown) | |||
| Line 1: | Line 1: | ||
APNG | {{note|Please see the [https://www.w3.org/TR/png-3/ PNG 3e specification] at W3C which has incorporated the APNG Specification}} | ||
Main meta-bug: | |||
* [https://bugzilla.mozilla.org/show_bug.cgi?id=495609 495609: Implement PNG Third Edition (incorporated prior APNG spec)] | |||
{{historical}} | |||
APNG 1.0 | |||
Authors: | Authors: | ||
* Stuart Parmenter <pavlov@pavlov.net> | * Stuart Parmenter <pavlov@pavlov.net> | ||
* Vladimir Vukicevic <vladimir@pobox.com> | * Vladimir Vukicevic <vladimir@pobox.com> | ||
* Andrew Smith < | * Andrew Smith <asmith16@littlesvr.ca> | ||
= Overview = | = Overview = | ||
APNG is an extension of the [PNG | APNG is an extension of the [http://www.w3.org/TR/PNG/ PNG] format, adding support for animated images. It is intended to be a replacement for simple animated images that have traditionally used the [http://www.w3.org/Graphics/GIF/spec-gif89a.txt GIF] format, while adding support for 24-bit images and 8-bit transparency. APNG is a simpler alternative to MNG, providing a spec suitable for the most common usage of animated images on the Internet. | ||
APNG is backwards-compatible with PNG; any PNG decoder should be able to ignore the APNG-specific chunks and display a single image. | APNG is backwards-compatible with PNG; any PNG decoder should be able to ignore the APNG-specific chunks and display a single image. | ||
| Line 22: | Line 21: | ||
The "default image" is the image described by the standard `IDAT` chunks, and is the image that is displayed by decoders that do not support APNG. | The "default image" is the image described by the standard `IDAT` chunks, and is the image that is displayed by decoders that do not support APNG. | ||
The "canvas" is the area on the output device on which the frames are to be displayed. The contents of the canvas are not necessarily available to the decoder. As per the PNG Specification, if a `bKGD` chunk exists it may be used to fill the canvas if there is no | The "canvas" is the area on the output device on which the frames are to be displayed. The contents of the canvas are not necessarily available to the decoder. As per the PNG Specification, if a `bKGD` chunk exists it may be used to fill the canvas if there is no preferable background. | ||
The "output buffer" is a pixel array with dimensions specified by the width and height parameters of the PNG `IHDR` chunk. Conceptually, each frame is constructed in the output buffer before being composited onto the canvas. The contents of the output buffer are available to the decoder. The | The "output buffer" is a pixel array with dimensions specified by the width and height parameters of the PNG `IHDR` chunk. Conceptually, each frame is constructed in the output buffer before being composited onto the canvas. The contents of the output buffer are available to the decoder. The corners of the output buffer are mapped to the corners of the canvas. | ||
"Fully transparent black" means red, green, blue and alpha components are all set to zero. | "Fully transparent black" means red, green, blue and alpha components are all set to zero. | ||
For purposes of chunk descriptions, an "unsigned int" shall be a 32-bit unsigned integer in network byte order limited to the range 0 to (2^31)-1; an "unsigned short" shall be a 16-bit unsigned integer in network byte order; a "byte" shall be an 8-bit unsigned integer. | For purposes of chunk descriptions, an "unsigned int" shall be a 32-bit unsigned integer in network byte order limited to the range 0 to (2^31)-1; an "unsigned short" shall be a 16-bit unsigned integer in network byte order with the range 0 to (2^16)-1; a "byte" shall be an 8-bit unsigned integer with the range 0 to (2^8)-1. | ||
== Error Handling == | == Error Handling == | ||
| Line 36: | Line 35: | ||
= Structure = | = Structure = | ||
An APNG stream is a normal PNG stream as defined in the [PNG Specification | An APNG stream is a normal PNG stream as defined in the [http://www.w3.org/TR/PNG/ PNG Specification], with three additional chunk types describing the animation and providing additional frame data. | ||
To be recognized as an APNG, an `acTL` chunk must appear in the stream before any `IDAT` chunks. The `acTL` structure is described below. | |||
Conceptually, at the beginning of each play the output buffer must be completely initialized to a fully transparent black rectangle, with width and height dimensions from the `IHDR` chunk. | |||
The default image may be included as the first frame of the animation by the presence of a single `fcTL` chunk before `IDAT`. Otherwise, the default image is not part of the animation | The default image may be included as the first frame of the animation by the presence of a single `fcTL` chunk before `IDAT`. Otherwise, the default image is not part of the animation. | ||
Subsequent frames are encoded in `fdAT` chunks | Subsequent frames are encoded in `fdAT` chunks, which have the same structure as `IDAT` chunks, except preceded by a sequence number. Information for each frame about placement and rendering is stored in `fcTL` chunks. The full layout of `fdAT` and `fcTL` chunks is described below. | ||
The boundaries of the entire animation are specified by the width and height parameters of the PNG `IHDR` chunk, regardless of whether the default image is part of the animation. The default image should be appropriately padded with fully transparent pixels if extra space will be needed for later frames. | The boundaries of the entire animation are specified by the width and height parameters of the PNG `IHDR` chunk, regardless of whether the default image is part of the animation. The default image should be appropriately padded with fully transparent pixels if extra space will be needed for later frames. | ||
Each frame is identical for each play, therefore it is safe for applications to cache the frames. | |||
== Chunk Sequence Numbers == | == Chunk Sequence Numbers == | ||
The `fcTL` and `fdAT` chunks have a 4 byte sequence number. Both chunk types share the sequence. The purpose of this number is to detect (and optionally correct) sequence errors in an Animated PNG, since the PNG specification does not impose | The `fcTL` and `fdAT` chunks have a 4 byte sequence number. Both chunk types share the sequence. The purpose of this number is to detect (and optionally correct) sequence errors in an Animated PNG, since the PNG specification does not impose ordering restrictions on ancillary chunks. | ||
The first `fcTL` chunk must contain sequence number 0, and the sequence numbers in the remaining `fcTL` and `fdAT` chunks must be in order, with no gaps or duplicates. | The first `fcTL` chunk must contain sequence number 0, and the sequence numbers in the remaining `fcTL` and `fdAT` chunks must be in order, with no gaps or duplicates. | ||
| Line 57: | Line 60: | ||
Sequence number Chunk | Sequence number Chunk | ||
0 `fcTL` first frame ( | (none) `acTL` | ||
0 `fcTL` first frame | |||
(none) `IDAT` first frame / default image | |||
1 `fcTL` second frame | 1 `fcTL` second frame | ||
2 first `fdAT` for second frame | 2 first `fdAT` for second frame | ||
| Line 66: | Line 71: | ||
Sequence number Chunk | Sequence number Chunk | ||
(none) `acTL` | |||
(none) `IDAT` default image | |||
0 `fcTL` first frame | 0 `fcTL` first frame | ||
1 first `fdAT` for first frame | 1 first `fdAT` for first frame | ||
| Line 81: | Line 88: | ||
byte | byte | ||
0 num_frames (unsigned int) Number of frames | 0 num_frames (unsigned int) Number of frames | ||
4 | 4 num_plays (unsigned int) Number of times to loop this APNG. 0 indicates infinite looping. | ||
`num_frames` indicates the total number of frames in the animation. This must equal the number of `fcTL` chunks. 0 is not a valid value. 1 is a valid value for a single-frame APNG. If this value does not equal the actual number of frames it should be treated as an error. | `num_frames` indicates the total number of frames in the animation. This must equal the number of `fcTL` chunks. 0 is not a valid value. 1 is a valid value for a single-frame APNG. If this value does not equal the actual number of frames it should be treated as an error. | ||
` | `num_plays` indicates the number of times that this animation should play; if it is 0, the animation should play indefinitely. If nonzero, the animation should come to rest on the final frame at the end of the last play. | ||
== `fcTL`: The Frame Control Chunk == | == `fcTL`: The Frame Control Chunk == | ||
| Line 122: | Line 129: | ||
`y_offset` + `height` <= `IHDR` height | `y_offset` + `height` <= `IHDR` height | ||
The `delay_num` and `delay_den` parameters together specify a fraction indicating the | The `delay_num` and `delay_den` parameters together specify a fraction indicating the time to display the current frame, in seconds. If the denominator is 0, it is to be treated as if it were 100 (that is, `delay_num` then specifies 1/100ths of a second). If the the value of the numerator is 0 the decoder should render the next frame as quickly as possible, though viewers may impose a reasonable lower bound. | ||
Frame timings should be independent of the time required for decoding and display of each frame, so that animations will run at the same rate regardless of the performance of the decoder implementation. | |||
`dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). | `dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). | ||
| Line 136: | Line 145: | ||
* APNG_DISPOSE_OP_BACKGROUND: the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame. | * APNG_DISPOSE_OP_BACKGROUND: the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame. | ||
* APNG_DISPOSE_OP_PREVIOUS: the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame. | * APNG_DISPOSE_OP_PREVIOUS: the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame. | ||
If the first `fcTL` chunk uses a `dispose_op` of APNG_DISPOSE_OP_PREVIOUS it should be treated as APNG_DISPOSE_OP_BACKGROUND. | |||
`blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. | `blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. | ||
| Line 145: | Line 156: | ||
1 APNG_BLEND_OP_OVER | 1 APNG_BLEND_OP_OVER | ||
If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region. If `blend_op` is APNG_BLEND_OP_OVER the frame should be composited onto the output buffer based on its alpha, using a simple OVER operation as described in the "Alpha Channel Processing" section of the PNG specification [PNG-1.2]. Note that | If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region. If `blend_op` is APNG_BLEND_OP_OVER the frame should be composited onto the output buffer based on its alpha, using a simple OVER operation as described in the "Alpha Channel Processing" section of the PNG specification [PNG-1.2]. Note that the second variation of the sample code is applicable. | ||
Note that for the first frame the two blend modes are functionally equivalent due to the clearing of the output buffer at the beginning of each play. | |||
The `fcTL` chunk corresponding to the default image | The `fcTL` chunk corresponding to the default image, if it exists, has these restrictions: | ||
* The `x_offset` and `y_offset` fields must be 0. | * The `x_offset` and `y_offset` fields must be 0. | ||
* The `width` and `height` fields must equal the corresponding fields from the `IHDR` chunk. | * The `width` and `height` fields must equal the corresponding fields from the `IHDR` chunk. | ||
As noted earlier, | As noted earlier, the output buffer must be completely initialized to fully transparent black at the beginning of each play. This is to ensure that each play of the animation will be identical. Decoders are free to avoid an explicit clear step as long as the result is guaranteed to be identical. For example, if the default image is included in the animation, and uses a `blend_op` of APNG_BLEND_OP_SOURCE, clearing is not necessary because the entire output buffer will be overwritten. | ||
Note, at the end of the fcTL chunk is a 32-bit CRC checksum. The checksum is calculated using the fcTL chunk and includes the 'fcTL' bytes. | |||
== `fdAT`: The Frame Data Chunk == | == `fdAT`: The Frame Data Chunk == | ||
| Line 163: | Line 172: | ||
The `fdAT` chunk has the same purpose as an `IDAT` chunk. It has the same structure as an `IDAT` chunk, except preceded by a sequence number. | The `fdAT` chunk has the same purpose as an `IDAT` chunk. It has the same structure as an `IDAT` chunk, except preceded by a sequence number. | ||
At least one `fdAT` chunk is required for each frame. The compressed datastream is then the concatenation of the contents of the data fields of all the `fdAT` chunks within a frame. When decompressed, the datastream is the complete pixel data of a PNG image, including the filter byte at the beginning of each scanline, similar to the uncompressed data of all the `IDAT` chunks. It utilizes the same bit depth, color type, compression method, filter method, interlace method, and palette (if any) as the default image. | |||
Format: | Format: | ||
| Line 173: | Line 182: | ||
Each frame inherits every property specified by any critical or ancillary chunks before the first `IDAT` in the file, except the width and height, which come from the `fcTL` chunk. | Each frame inherits every property specified by any critical or ancillary chunks before the first `IDAT` in the file, except the width and height, which come from the `fcTL` chunk. | ||
If the PNG ` | If the PNG `pHYs` chunk is present, the APNG images and their `x_offset` and `y_offset` values must be scaled in the same way as the main image. Conceptually, such scaling occurs while mapping the output buffer onto the canvas. | ||
= MIME type = | |||
APNG can be identified using the <code>image/apng</code> MIME type. | |||
= Revisions to this Specification = | = Revisions to this Specification = | ||
| Line 264: | Line 275: | ||
* Split render_op into dispose_op and blend_op | * Split render_op into dispose_op and blend_op | ||
== From 0.10 == | |||
* No changes | |||
= Test Encoder and Sample Images = | = Test Encoder and Sample Images = | ||
Sample images are available from the APNG implementation page at http://littlesvr.ca/apng/ | *Sample images are available from the APNG implementation page at http://littlesvr.ca/apng/ | ||
*An encoder (open source) is available in Mozilla versions newer than alpha 4. | |||
*An application (open source) using the Mozilla encoder to assemble APNGs available here: http://littlesvr.ca/apng/apngedit.html | |||
= A. References = | = A. References = | ||
*http://www.w3.org/TR/PNG/ "Portable Network Graphics (PNG) Specification (Second Edition)" | |||
* http:// | *http://pmt.sourceforge.net/specs/png-1.2-pdg.html "Extensions to the PNG Specification, Version 1.2.0" | ||
*http://www.w3.org/Graphics/GIF/spec-gif89a.txt "Graphics Interchange Format 89a" | |||
*http://www.animatedpng.com "APNG Project - official Site" | |||
* http://www. | |||
= B. Tests = | |||
* http:// | * http://philip.html5.org/tests/apng/tests.html | ||