APNG Specification: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 5: Line 5:
* Vladimir Vukicevic <vladimir@pobox.com>
* Vladimir Vukicevic <vladimir@pobox.com>
* Andrew Smith <asmith15@learn.senecac.on.ca>
* Andrew Smith <asmith15@learn.senecac.on.ca>
= Big Important Note =
The chunk names in this specification will be changed to aCTl, fCTl and fDAt. Please consider any APNGs with acTl, fcTl and fdAt to be useless after that change happens.


= Overview =
= Overview =
Line 20: Line 24:
To be recognized as an APNG, an `acTl` chunk must appear in the stream before any `IDAT` chunks. The `acTl` structure is described in the next section.
To be recognized as an APNG, an `acTl` chunk must appear in the stream before any `IDAT` chunks. The `acTl` structure is described in the next section.


An `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.
An `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. If there is no fCTl chunk before IDAT, then frame 0 is intialized to RGBA(0,0,0,0) and the IDAT chunks are not used.


Subsequent frames are encoded in `fdAt` chunks containing almost the same structure of content as IDAT chunks. Information for each frame about placement and rendering is stored in `fcTl` chunks.  The full layout of `fdAt` and `fcTl` chunks is described below.
Subsequent frames are encoded in `fdAt` chunks containing almost the same structure of content as IDAT chunks. Information for each frame about placement and rendering is stored in `fcTl` chunks.  The full layout of `fdAt` and `fcTl` chunks is described below.


Note: 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.
Note: 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.
== Terminology ==
The "canvas" is the area on the output device on which the images are to be written.  The contents of the canvas are not available to the decoder.
The "output buffer" is a pixel array with dimensions specified by the width and height parameters of the PNG IHDR chunk.  Conceptually, the images are constructed in the output buffer and then written to the canvas.  The contents of the output buffer are available to the decoder.  The corner pixels of the output buffer are mapped to the corners of the canvas.


== Chunk Sequence Numbers ==
== Chunk Sequence Numbers ==
Line 30: Line 40:
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 orderng restrictions on ancillary chunks.
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 orderng restrictions on ancillary chunks.


Sequence numbers must start at 0 and increment by one.
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 table below illustrates the use of sequence numbers for images with more than one frame and more than one `fdAt` chunk:
The table below illustrates the use of sequence numbers for images with more than one frame and more than one `fdAt` chunk:
Line 41: Line 51:
     ....
     ....


If a decoder detects that the chunks are in the wrong order it must either treat the condition as an error or correct the order using the sequence numbers.
or, when frame 0 is implicitly a transparent black frame:
 
    Sequence number    Chunk
    0                  fCTl describing frame 1
    1                  first fDAt for frame 1
    2                  second fDAt for frame 1
    ....
 
APNG viewers must abandon the APNG chunks in a datastream with out-of-order APNG chunks and display frame 0 instead. APNG-aware PNG editors should restore them to correct order using the sequence numbers.


== `acTl`: The Animation Control Chunk ==
== `acTl`: The Animation Control Chunk ==


The `acTl` chunk is an ancillary chunk as defined in the PNG Specification. It must appear before the first `IDAT` chunk within a valid PNG stream. If the color type of the image is 3 (indexed-color) the `acTl` chunk must appear after the `PLTE` chunk.
The `acTl` chunk is an ancillary chunk as defined in the PNG Specification. It must appear before the first `IDAT` chunk within a valid PNG stream.


The `acTl` chunk contains:
The `acTl` chunk contains:
Line 68: Line 86:


* For the first frame, the `fcTl` chunk must appear before the first `IDAT` chunk. Position relative to the `acTl` chunk is not specified.
* For the first frame, the `fcTl` chunk must appear before the first `IDAT` chunk. Position relative to the `acTl` chunk is not specified.
* For the second frame, the `fcTl` chunk must appear immediately after the `IDAT` chunks from the first frame and immediately before the fdAt chunks for the second frame.
* For the second frame, the `fcTl` chunk must appear after the `IDAT` chunks from the first frame and before the fdAt chunks for the second frame.
* For any subsequent frames, the `fcTl` chunk for the frame N must appear immediately after the `fdAt` chunks from the frame N-1 and immediately before the fdAt chunks for the frame N.
* For any subsequent frames, the `fcTl` chunk for the frame N must appear after the `fdAt` chunks from the frame N-1 and before the fdAt chunks for the frame N.
* Other ancillary chunks are allowed to appear among the APNG chunks, including between fDAt chunks. Decoders must ignore such chunks.


The `fcTl` chunk is mandatory for every frame. More than one `fcTl` chunk per frame is not allowed.
The fCTl chunk is mandatory for every frame except for frame 0. When it is present for frame 0, decoders must render frame 0 from the data in the IDAT chunks.  When it is not present for frame 0, frame 0 is a transparent black frame (all pixels are RGBA(0,0,0,0)) and the IDAT chunks are ignored. More than one fCTl chunk per frame is not allowed.


Format:
Format:
Line 85: Line 104:
     24    render_op            (byte)          Type of canvas area disposal to be done after rendering this frame
     24    render_op            (byte)          Type of canvas area disposal to be done after rendering this frame


The frame must be rendered within the region defined by the `width`, `height`, `x_offset` and `y_offset` from the `fcTl`, and the width and height from the `IHDR`.
The frame must be rendered within the region defined by the `width`, `height`, `x_offset` and `y_offset` from the `fcTl`, and the width and height from the `IHDR` chunk.


The width and height cannot be bigger than (respectively) the width and height specified in the `IHDR` chunk. The value of both the width and the height must be greater than 0.
The width and height must be greater than zero and must not be bigger than (respectively) the width and height specified in the IHDR chunk.


For frame 0 the width and height fields must equal the width and height from the `IHDR` chunk. Also for frame 0 the `x_offset` and `y_offset` fields must be 0. No part of the region may fall outside the canvas defined by frame 0.
For frame 0 the width and height fields must equal the width and height from the `IHDR` chunk. Also for frame 0 the `x_offset` and `y_offset` fields must be 0. No part of the region may fall outside the area defined by frame 0.


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 `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.
Line 98: Line 117:
     +-------------------------------+
     +-------------------------------+
     | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
     | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
     +-------------|---|---|---|---|-+
     +-----------------|---|---|---|-+
                  |  |  +---+---+------ bits 0-2: dispose_op
                      |  +---+---+------ bits 0-2: dispose_op
                  |  |
                      |
                  |  +------------------ bit 3: APNG_RENDER_OP_BLEND_FLAG
                      +------------------ bit 3: APNG_RENDER_OP_BLEND_FLAG
                  |
 
                  +---------------------- bit 4: APNG_RENDER_OP_SKIP_FRAME


Bits 5 through 7 are reserved and must be 0.
Bits 4 through 7 are reserved and must be 0.


Valid values for `dispose_op` are:
Valid values for `dispose_op` are:
Line 122: Line 140:


`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.
`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.
APNG_RENDER_OP_BLEND_FLAG must be 0 for frame 0.


If `APNG_RENDER_OP_SKIP_FRAME` is not 0, 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 is explicitly disabled by the user, the viewer should display frame 0 even if `APNG_RENDER_OP_SKIP_FRAME` is not 0 on frame 0.  This provides content authors with a means to provide a still image to be used in lieu of the full animation.
If `APNG_RENDER_OP_SKIP_FRAME` is not 0, 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 is explicitly disabled by the user, the viewer should display frame 0 even if `APNG_RENDER_OP_SKIP_FRAME` is not 0 on frame 0.  This provides content authors with a means to provide a still image to be used in lieu of the full animation.
Line 129: Line 149:
The `fdAt` chunk has the same purpose as an `IDAT` chunk. It has the same data structure as an `IDAT` chunk, except a sequence number is appended in the beginning.
The `fdAt` chunk has the same purpose as an `IDAT` chunk. It has the same data structure as an `IDAT` chunk, except a sequence number is appended in the beginning.


Each frame must contain at least one fDAt chunk. There may be multiple `fdAt` chunks for any one frame; if so, they shall appear consecutively with no other intervening chunks. 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 a complete PNG image, including the filter byte at the beginning of each scanline.
Each frame must contain at least one fDAt chunk. 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 a complete PNG image, including the filter byte at the beginning of each scanline. It utilizes the same bit depth, color type, compression method, filter method, interlace method, and palette (if any) as the main image.
 
It utilizes the same bit depth, color type, compression method, filter
method, interlace method, and palette (if any) as the main image.


Format:
Format:
Line 144: Line 161:
If the PNG oFFs chunk is present, it supplies offsets of the canvas that are in addition to the frame's "x_offset" and "y_offset".
If the PNG oFFs chunk is present, it supplies offsets of the canvas that are in addition to the frame's "x_offset" and "y_offset".


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.
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.


= Revisions to this Specification =
= Revisions to this Specification =
Line 220: Line 237:


* Reintroduced the width and height fields in fcTl
* Reintroduced the width and height fields in fcTl
== From 0.7 ==
* Removed 'hidden' flag, instead only the first frame can be hidden and it is signaled with a missing fcTl
* IDAT, fcTl and fdAt are no longer required to have no other chunks in between them


= Test Encoder and Sample Images =
= Test Encoder and Sample Images =
48

edits

Navigation menu