Changes

Jump to: navigation, search

APNG Specification

12,846 bytes added, 19:14, 16 June 2006
Importing APNG spec
APNG 0.4 <i>[DRAFT]</i>

Authors:
* Stuart Parmenter <pavlov@pavlov.net>
* Vladimir Vukicevic <vladimir@pobox.com>

= 1. Overview =

APNG is an extension of the [PNG][pngspec] format, adding support for animated images. It is intended to be a replacement for simple animated images that have traditionally used the [GIF][gifspec] 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 decode the first frame of an APNG and treat it as a normal single-frame PNG.

= 2. Structure =

An APNG stream is a normal PNG stream as defined in the [PNG Specification][pngspec], with two additional chunks describing the animation and providing additional frame data. The first frame of an animation, frame 0, is encoded as a normal PNG. This frame is what decoders that do not understand the APNG chunks will display.

The size of the first frame defines the boundaries of the entire animation; hence, if extra space will be needed for later frames that is unused in the first frame, the first frame should be appropriately padded with fully transparent regions.

To be recognized as an APNG, an `aCTL` chunk should appear the stream before any `IDAT` chunks. If an `aCTL` appears after an `IDAT` chunk, a decoder must ignore it and treat the stream as a single-frame PNG. The `aCTL` structure is described in the next section.

A `fCTL` chunk must also appear before `IDAT`, providing frame information for the first frame encoded in the PNG stream's `IDAT` chunks, known as frame 0.

Subsequent frames are encoded in `aDAT` chunks, containing information about placement and rendering of a frame in `fCTL` chunks, as well as frame data encoded as normal PNG streams. The full layout of the `aDAT` chunk is described in section 2.2.

== 2.1. `aCTL`: The Animation Control Chunk ==

Note: For purposes of chunk descriptions, an "unsigned int" shall be a 32-bit unsigned integer in network byte order; a "signed int" shall be a 32-bit signed integer in network byte order; an "unsigned short" shall be a 16-bit unsigned integer in network byte order; a "byte" shall be a 8-bit unsigned integer.

The `aCTL` chunk is an ancillary chunk as defined in the PNG Specification. It must appear before an `IDAT` chunk within a valid PNG stream.

Format:

byte
0 num_iterations (unsigned int) Number of times to loop this APNG. 0 indicates infinite looping.

`num_iterations` indicates the number of iterations 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 non-skipped frame at the end of the last iteration.

== 2.2 `aDAT`: The Animation Data Chunk ==

The `aDAT` chunk contains a stream of images to be used as frames for the animation. Any `aDAT` chunks must follow any `IDAT` chunks.

Format:

byte
0 sequence_number (unsigned int) Sequence number of this aDAT chunk, starting with 0
4 remaining stream data

The `sequence_number` shall begin with 0 for the first `aDAT` in the PNG stream, and increase by one with each subsequent PNG stream. The length of the stream data is determined by the length of the `aDAT` chunk, minus the size of the `sequence_number`. If only one `aDAT` chunk is present in the PNG stream, all frames must be encoded within its data section. If more than one `aDAT` chunk is present, the first chunk (that is, the chunk with `sequence_number` 0) must have empty stream data to allow the decoder to check for the most common out-of-order errors by looking at the `sequence_number` of the next frame. All `aDAT` chunks must be adjacent in the PNG stream.

The stream data within the `aDAT` consists of a stream of PNG chunks, with each frame beginning with a `fCTL` chunk, followed by an `IHDR`, and then containing normal PNG image chunks followed by one or more `IDAT` chunks providing the data for the frame. No `IEND` is to be written for these embedded streams; instead, a `fCTL` chunk indicates that the frame has ended and provides control information for the next frame. For the final frame of the image, its end is indicated by an end of the `aDAT` data section, and a PNG chunk after the `aDAT` that is not another `aDAT`. **(??? Do we want an explicit `fEND` or something here?)**

Each frame must be of the same color type as the parent stream. Each frame's region, as defined by its width and height (specified in the `IHDR`) and its x and y offset (specified in the `fCTL`, described below) must lie within the first image canvas.

Encoders are strongly encouraged to use a single `aDAT` chunk whenever possible,
to remove the chance of out of order chunks. Should a decoder receive an APNG stream with missing or out of order `aDAT` chunks, it is under no obligation to attempt to reorder the chunks and may treat that case as an error condition.

== 2.3 `fCTL`: The Frame Control Chunk ==

Format:

byte
0 x_offset (unsigned int) X position at which to render this frame
4 y_offset (unsigned int) Y position at which to render this frame
8 delay_num (unsigned short) Frame delay fraction numerator
10 delay_den (unsigned short) Frame delay fraction denominator
12 render_op (byte) Type of canvas area disposal to be done after rendering this frame

The `delay_num` and `delay_den` parameters together specify a fraction indicating the delay after 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 on the delay.

The frame is rendered within the region defined by the `x_offset` and `y_offset` from the `fCTL`, and the width and height from this frame's `IHDR`. For frame 0, the `x_offset` and `y_offset` fields must be 0. Should parts
of the region fall outside the canvas defined by frame 0, rendering is to be clipped to that canvas.

The `render_op` parameter specifies contains flags describing how the frame is to be disposed before rendering the next frame; it also specifies whether the frame is to be alpha blended into the current canvas content, or whether it should completely replace its region in the canvas. Valid render_op flags are:

bit
+-------------------------------+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------|---|---|---|---|-+
| | +---+---+------ bits 0-2: dispose_op
| |
| +------------------ bit 3: APNG_RENDER_OP_BLEND_FLAG
|
+---------------------- bit 4: APNG_RENDER_OP_SKIP_FRAME

Bits 5 through 7 are reserved and must be set to 0. Valid values for `dispose_op` are:

value:
0 APNG_RENDER_OP_DISPOSE_NONE
1 APNG_RENDER_OP_DISPOSE_BACKGROUND
2 APNG_RENDER_OP_DISPOSE_PREVIOUS

* `APNG_RENDER_OP_DISPOSE_NONE`: no disposal is done on this frame before rendering the next; its contents are left on the canvas. This is the default.
* `APNG_RENDER_OP_DISPOSE_BACKGROUND`: the frame's region is to be cleared to the background color. If no `bKGD` chunk is specified, the result is fully transparent black (r, g, b, and a all 0).
* `APNG_RENDER_OP_DISPOSE_PREVIOUS`: the frame's region is to be reverted to the previous contents.

`APNG_RENDER_OP_BLEND_FLAG` may be added to any of the above disposal perations. If this flag is not set, all color components of the frame, including alpha, overwrite the current contents of the frame's canvas region. If the BLEND_FLAG is set the frame should be composited onto the canvas based on its alpha, using a simple OVER operation:

Csrc - component of pixel in the frame
Asrc - alpha component of a pixel in the frame
Cdst - component of pixel in the canvas region
C - resulting component value to be rendered in the canvas region

C = Csrc * Asrc + Cdst * (1 - Asrc)

`APNG_RENDER_OP_BLEND_FLAG` is not valid for color types 0 (greyscale without alpha) or 2 (truecolor without alpha). It is valid for type 3 (indexed) images; however, the resulting pixel values may not be present in the specified palette. It is always valid for type 4 (greyscale with alpha) and type 6 (truecolor with alpha) images.

If `APNG_RENDER_OP_SKIP_FRAME` is present, then the decoder should not render the current frame as part of the animation. Though this flag can be set on any frame and must be honored, it is most useful for frame 0, to prevent the frame that would be visible to PNG viewers not supporting animation from being part of the animated frame set. If animation in the viewer is not desired or explicitly disabled by the user, the viewer should display frame 0 even if `SKIP_FRAME` is set on frame 0. This provides content authors with a means to provide a still image to be used in lieu of the full animation.

= 3. Interaction with other PNG chunks =

== 3.1. `PLTE` and `tRNS` chunks ==

Should `PLTE` or `tRNS` chunks be valid for the PNG stream's color type, any `PLTE` or `tRNS` specified in the enclosing stream is to be treated as a global palette or transparency, and applied to each frame. Individual frames may override the global values by including their own `PLTE` or `tRNS` between
their `IHDR` and `IDAT` chunks; such a local palette or transparency only applies to the frame where it is specified.

A local palette or transparency should have no effect on any content in the canvas other than the frame currently being rendered. Specifically, palette
animation is not supported -- the RGBA values of previously rendered content still visible on the canvas are not to be changed by a local palette.

== 3.2. Colour space chunks ==

Colour space chunks, as defined in section 11.3.3 of the PNG specification, shall only be valid in the enclosing stream and apply to all the frames within the stream. Any Colour space chunks within individual frames should be ignored by a decoder.

== 3.3. Other chunks ==

Chunks other than those specifically mentioned here should apply to the overall stream's canvas area, including chunks such as `bKGD`, `hIST`, `oFFs`, etc.

= 4. Revisions to this Specification ==

== From 0.1 ==

* Renamed chunks to `anIm` and `frAm` to comply with chunk naming conventions in the PNG spec.

* Added a more detailed explanation of APNG structure in Section 2.

* Added information for png interaction with other chunks in section 3.2.

* Changed `frAm` chunk offsets and delay into signed integers.

== From 0.2 ==

* Changed `frAm` chunk to `afRa` to avoid conflict with MNG `FRAM` chunk.

* Changed format: instead of sequences of IHDR..IDAT..IEND, frames other than frame 0 are stored in `afRa` chunks.

* Added `start_frame` to `anIm` to indicate which frame the animation should start on.

* Removed `num_frames` from `anIm` chunk

== From 0.3 ==

* Added `aCTL`, `aDAT`, `fCTL` chunk descriptions as per the latest png-list discussion

* Added section 4, "Interactions with other PNG chunks"; described global and local palettes and
transparency

* Changed `oFFs` chunk section to refer to more general chunks

* Updated `aDAT` description to indicate that all frames must either be in a single chunk, or that the first
chunk must have empty data.

* Added notice that each frame's region (x,y,width,height) must lie completely within the parent PNG canvas

* Fixed dispose_op description (after, not before)

* Changed dipose_op to render_op; added disposal description; added BLEND flag

* Changed delay_time to a delay numerator and denominator, for specifying delays that don't into integer
numbers of milliseconds.

* Added note to clarify that palette animation is not supported.

* Removed start_frame from aCTL; require fCTL for frame 0; added SKIP_FRAME fCTL flag.

= 5. Test Encoder and Sample Images =

_Coming soon_

= A. References =

[pngspec]: http://www.w3.org/TR/PNG/ "Portable Network Graphics (PNG) Specification (Second Edition)"
* http://www.w3.org/TR/PNG/ "Portable Network Graphics (PNG) Specification (Second Edition)"

[pngext]: http://www.libpng.org/pub/png/spec/register/pngext-1.2.0-pdg.html "Extensions to the PNG Specification, Version 1.2.0"
* http://www.libpng.org/pub/png/spec/register/pngext-1.2.0-pdg.html "Extensions to the PNG Specification, Version 1.2.0"

[gifspec]: http://www.w3.org/Graphics/GIF/spec-gif89a.txt "Graphics Interchange Format 89a"
* http://www.w3.org/Graphics/GIF/spec-gif89a.txt "Graphics Interchange Format 89a"
Confirm, emeritus
792
edits

Navigation menu