Portable Network Graphics
- Extension: PNG
- MIME Types:
- png: image/png or image/x-png
File header
A PNG file starts with an 8-byte signature. The hexadecimal byte values are 89 50 4E 47 0D 0A 1A 0A. Each of the header bytes is there for a specific reason [1]:
Byte(s) | Purpose |
---|---|
89 | Has the high bit set to detect transmission systems that do not support 8 bit data and to reduce the chance that a text file is mistakenly interpreted as a PNG, or visa versa. |
50 4E 47 | In ASCII, the letters "PNG", allowing a person to identify the format easily if it is viewed in a text editor. |
0D 0A | A DOS style newline (CRLF) to detect DOS-UNIX line ending conversion of the data. |
1A | A byte that stops display of the file under DOS when the command TYPE has been used |
0A | A unix newline (LF) to detect UNIX-DOS line ending conversion. |
"Chunks" within the file
After the header come a series of chunks each of which conveys certain information about the image. Chunks declare themselves as critical or ancillary, and a program encountering an ancillary chunk that it does not understand can safely ignore it. This chunk-based structure is designed to allow the PNG format to be extended while maintaining compatibility with older versions.
The chunks each have a header specifying their size and type. This is immediately followed by the actual data, and then the checksum of the data. Chunks are given a 4 letter case sensitive name. The case of the different letters in the name provides the decoder with some information on the nature of chunks it does not recognise.
The case of the first letter indicates if the Chunk is essential or not. If the first letter is uppercase, the chunk is essential. If not, the chunk is ancillary. Essential chunks contain information that is necessary to read the file. If a decoder encounters an essential chunk it does not recognise, it must abort reading the file.
The case of the second letter indicates if the chunk is "public" (either in the specification or the registry of special purpose public chunks) or "private" (not standardised). Uppercase is public and lowercase is private. This ensures that public and private chunk names can never conflict with each other.
The third letter must be uppercase to conform to the PNG specification. It is reserved for future expansion.
The case of the fourth letter indicates if a chunk is safe to copy by editors that do not recognise it. If lowercase the chunk may be safely copied regardless of the extent of modifications to the file. If uppercase it may only be copied if the modifications have not touched any critical chunks.
Essential chunks
A decoder must be able to interpret these to read and render a PNG file.
- IHDR must be the first chunk, it contains the header.
- PLTE contains the palette; list of colors.
- IDAT contains the image, which may be split among multiple IDAT chunks. Doing so increases filesize slightly, but makes it possible to generate a PNG in a streaming manner.
- IEND marks the image end.
Metadata chunks
Other image attributes that can be stored in PNG files include gamma values, background color, and textual metadata information. PNG also supports color management through the inclusion of ICC color space profiles.
- bKGD gives the default background color. It is intended for use when there is no better choice available, such as in standalone image viewers (but not web browsers).
- cHRM gives the white balance.
- gAMA specifies gamma.
- hIST can store the histogram, or total amount of each color in the image.
- iCCP is an ICC color profile.
- iTXt contains international (UTF-8) text, compressed or not.
- pHYs holds the intended pixel size and/or aspect ratio of the image.
- sBIT (significant bits) indicates the color-accuracy of the source data.
- sPLT suggests a palette to use if the full range of colors is unavailable.
- sRGB indicates that the standard sRGB color space is used.
- tEXt can store text that can be represented in ISO 8859-1, with one name=value pair for each chunk.
- tIME stores the time that the image was last changed.
- tRNS contains transparency information. For indexed images, it stores alpha channel values for one or more palette entries. For truecolor and greyscale images, it stores a single pixel value that is to be regarded as fully transparent.
- zTXt contains compressed text with the same limits as tEXt.
The lowercase first letter in these chunks indicates that they are not needed for the PNG specification. The lowercase last letter in some chunks indicates that they are safe to copy, even if the application concerned does not understand them.
Animation chunks
Animation control chunks must appear before the IDAT chunk. If they appear after the IDAT chunk they should be ignored (according to the spec)
Control Chunks:
- aCTL (Animation Control Chunk)
offset 0: unsigned 32bits: Number of times to loop this APNG. 0 indicates infinite looping.
- fCTL (Frame Control Chunk)
offset: 0: unsigned 32bits: X position at which to render this frame offset: 4: unsigned 32bits: Y position at which to render this frame offset: 8: unsigned 16bits: Frame delay fraction numerator offset: 10: unsigned 16bits: Frame delay fraction denominator offset: 12: byte (signed/unsigned?) Type of canvas area disposal to be done after rendering this frame
Data Chunks:
- aDAT (Animation Data Chunk)
offset: 0: unsigned 32bits: Sequence number of this aDAT chunk, starting with 0 offset: 4: remaining stream data
Chunks that are re-appropriated.
- PLTE (Palette Chunk)
- tRNS (Transparency Chunk)
These chunks are treated as Global Palette and Global Transparency. The palette and transparency can be changed for any frame by adding a PLTE or tRNS chunk between the frame's IHDR and IDAT chunks.
Colour depth
PNG images can either use palette-indexed color or be made up of one or more channels (numerical values directly representing quantities about the pixels). When there is more than one channel in an image all channels have the same number of bits allocated per pixel (known as the bitdepth of the channel). Although the PNG specification always talks about the bitdepth of channels, most software and users generally talk about the total number of bits per pixel (sometimes also referred to as bitdepth or color depth).
The number of channels will depend on whether the image is greyscale or color and whether it has an alpha channel. PNG allows the following combinations of channels:
- greyscale
- greyscale and alpha (level of transparency for each pixel)
- red, green and blue (rgb/truecolor)
- red, green, blue and alpha
Type | Bit depth per channel | ||||
---|---|---|---|---|---|
1 | 2 | 4 | 8 | 16 | |
indexed (color type 3) | yes | yes | yes | yes | no |
greyscale (color type 0) | yes | yes | yes | yes | yes |
greyscale & alpha (color type 4) |
no | no | no | yes | yes |
truecolor (RGB - color type 2) |
no | no | no | yes | yes |
truecolor & alpha (RGBA - color type 6) |
no | no | no | yes | yes |
With indexed color images, the palette is always stored at a depth of 8 bits per channel. The palette must not have more entries than the image bitdepth allows for but it may have fewer (so if an image for example only uses 90 colors there is no need to have palette entries for all 256).
Indexed color PNGs are allowed to have 1, 2, 4 or 8 bits per pixel by the standard; greyscale images with no alpha channel allow for 1, 2, 4, 8 or 16 bits per pixel. Everything else uses a bitdepth per channel of either 8 or 16. The combinations this allows are given in the table above. The standard requires that decoders can read all supported color formats but many image editors can only produce a small subset of them.
Transparency of image
PNG offers a variety of transparency options. With truecolor and greyscale images either a single pixel value can be declared as transparent or an alpha channel can be added. For paletted images, alpha values can be added to palette entries. The number of such values stored may be less than the total number of palette entries, in which case the remaining entries are considered fully opaque.
The scanning of pixel values for binary transparency is supposed to be performed before any color reduction to avoid pixels becoming unintentionally transparent. This is most likely to pose an issue for systems that can decode 16 bits per channel images (as they must to be compliant with the specification) but only output at 8 bits per channel (the norm for all but the highest end systems).
Compression
PNG uses a non-patented lossless data compression algorithm known as DEFLATE. This method is combined with prediction, where for each image line, a filter method is chosen that predicts the color of each pixel based on the colors of previous pixels and subtracts the predicted color of the pixel from the actual color. An image line filtered in this way is often more compressible than the raw image line would be, especially if it is similar to the line above (since DEFLATE has no understanding that an image is a 2D entity, and instead just sees the image data as a stream of bytes).
Interlacing
PNG offers an optional 2-dimensional, 7-pass interlacing scheme – the Adam7 algorithm. This is more sophisticated than GIF's 1-dimensional, 4-pass scheme, and allows a clearer low-resolution image to be visible earlier in the transfer. However, as a 7-pass scheme, it tends to reduce the data's compressibility more than simpler schemes.
Animation
PNG does not offer animation. MNG is an image format that supports animation and is based on the ideas and some of the chunks of PNG but is a complex system and does not offer fallback to single image display like GIF does. APNG is another image format based on PNG that supports animation and is simpler than MNG. APNG offers fallback to single image display for PNG decoders that do not support APNG. APNG is now supported in firefox trunk so will likely see wider use. For iPhone/iPad developers, the AVAnimator library is available to add APNG support.
APNG Samples (with GIF animations for comparison)