
A word on PNG
PNG stands for Portable Network Graphics. This is an image file format described in the RFC 2083 document which this post is largely based on. Any software writing or reading PNG files must implement the mandatory aspects of this RFC and can implement the non-mandatory ones. This post focuses on the question “How is a PNG file built?”.
General structure of a PNG file
To get how a PNG file is built, here is the general structure:
- Start of the file: PNG header signature on 8 bytes: decimal: 137 80 78 71 13 10 26 10 hexadecimal: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
- Chunks
PNG chunks
PNG chunks are portions of data organized as follows:
Field name | Field length in bytes | Comment |
Length of data field | 4 | Can be 0 |
Chunk type | 4 | In ASCII |
Data | Length of data field | |
CRC | 4 | See below |
CRC as ISO 3309 on fields Chunk type and Data with polynomial x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 .
PNG chunk type name conventions
Property bits of the chunk type field:
Property | Bit of the chunk type field | What if 0 | What if 1 |
Ancillary | Byte 1 bit 5 | Critical (ex: IHDR) | Ancillary (ex: tIME) |
Private | Byte 2 bit 5 | Public (PNG spec) | Private (unregistered) |
Reserved | Byte 3 bit 5 | Should be 0 | |
Safe to copy | Byte 4 bit 5 | Not safe to copy (0 for critical) | Safe to copy |
PNG chunk types
Critical chunks in this order:
Chunk | Name | Multi | Order constraints |
IHDR | Image header | No | First |
PLTE | Palette | No | Mandatory for color type 3 (color palette) Optional for color types 2 and 4 (color) |
IDAT | Image data | Yes | Multiple IDATs must be consecutive |
IEND | Image trailer | No | Last with empty data field |
Ancillary chunks:
Chunk | Name | Multi | Order constraints |
cHRM | Primary chromaticities and white point | No | Before PLTE and IDAT |
gAMA | Image gamma | No | Before PLTE and IDAT |
sBIT | Significant bits | No | Before PLTE and IDAT |
bKGD | Background color | No | After PLTE; before IDAT |
hIST | Image histogram | No | After PLTE; before IDAT |
tRNS | Transparency | No | After PLTE; before IDAT |
pHYs | Physical pixel dimensions | No | After PLTE; before IDAT |
tIME | Image last-modification time | No | None |
tEXt | Textual data | Yes | None |
zTXt | Compressed textual data | Yes | None |
Note that the PNG format supports that encoders write additional unrecognized public or private chunks. So that, a reader needs to be able to read them without errors.
PNG chunk IHDR image header
IHDR image header PNG chunk is made of the following fields:
Field | Size in bytes | Possible values |
Width | 4 | Pixels (> 0) |
Height | 4 | Pixels (> 0) |
Bit depth | 1 | 1, 2, 4, 8, 16 depends on color type |
Color type | 1 | 0, 2, 3, 4, 6 |
Compression method | 1 | 0 for deflate/inflate |
Filter method | 1 | 0 for adaptive filtering |
Interlace method | 1 | 0 for no interlace 1 for ADAM7 |
Color type
The color type is the sum of 3 variables:
- 1 if palette is used
- 2 if color is used
- 4 if alpha channel (opacity/transparency) is used
Note that palette use is only possible with color and without alpha channel. Therefore, color type can only take the values of 0, 2, 3, 4, and 6.
Bit depth
The bit depth is the number of bits per sample or per palette index. The differences between the sample and the pixel are that a pixel is represented by two samples in case of alpha channel and that the sample bit depth is always 8 in case of palette. Possible values for the bit depth are powers of 2 from 1 to 16: 1, 2, 4, 8, 16. Though, possible values depend on the color type:
Color type | Allowed bit depths | Pixel description |
0 (grayscale) | 1, 2, 4, 8, 16 (any) | grayscale sample |
2 (color) | 8, 16 (>4) | RGB sample |
3 (palette + color) | 1, 2, 4, 8 (<16) | Palette index (requires PLTE chunk) |
4 (grayscale + alpha) | 8, 16 (>4) | grayscale sample + alpha sample |
6 (color + alpha) | 8, 16 (>4) | RGB sample + alpha sample |
Compression method
The deflate/inflate compression method is implemented by the zlib library. This is the same algorithm as the one used for the gz file format.
Adaptive filter method
The adaptive filter method which purpose is to prepare the data with less complexity for the deflate compression allows 5 filter types encoded at the beginning of the IDAT scanlines:
1st byte of scanline | Name | Formula |
0 | None | |
1 | Sub | byte(x) += byte(x-bpp) % 256 |
2 | Up | byte(x) += byte(prior(x)) % 256 |
3 | Average | byte(x) += floor((byte(x-bpp)+byte(prior(x)))/2) % 256 |
4 | Paeth | a = left b = above c = above left p = a + b – c paeth(a,b,c) = closest{a,b,c}(p) byte(x) += paeth(byte(x-bpp),byte(prior(x)),byte(prior(x-bpp))) % 256 |
The filtering applied to bytes, not pixels. This applies to alpha channel as well. When the image is interlaced, the filtering is applied per scanline, byte, not per pixel/pixel row. Filtering is not applied when interlaced subimage is empty. Left byte is zero for 1st byte. Prior scanline is zero for 1st scanline (or interlaced pass). Filter uses decoded previous byte/scanline.
bpp = nb bytes per pixel rounded up
nb bytes per pixel = ceil(nb channels * bitdepth / 8)
ADAM7 interlacing
ADAM7 interlacing allows an improved progressive display. Please refer to progressive reading of PNG for more details on this topic. This comes usually at the cost of more space used but not always as shown in this article.
Interpretation of interlaced data is mandatory even if image is not displayed progressively
Method 0 -> no interlacing -> left to right, top to bottom
Method 1 -> ADAM7 -> image is cut in 8-by-8 pixels pattern through 7 passes as follows:
1 6 4 6 2 6 4 6
7 7 7 7 7 7 7 7
5 6 5 6 5 6 5 6
7 7 7 7 7 7 7 7
3 6 4 6 3 6 4 6
7 7 7 7 7 7 7 7
5 6 5 6 5 6 5 6
7 7 7 7 7 7 7 7
Filters apply to interlaced scanlines. All the scanlines within a pass have the same number of pixels. There is a special case when the side is smaller than 5 pixels, then, some passes are empty, then there is no filter type byte for those empty passes.
PLTE the palette chunk
The palette chunk contains 1 to 256 three bytes RGB colors. The number of colors in the palette must be within what bit depth allows (2^4 = 16 colors maximum for bit depth 4 for example). This chunk is necessary for color type 3 (palette + color) and optional for color types 2 and 6 (color and color + alpha). Each pixel value is the number of the palette entry encoding its color. This means that a palette encoded PNG can represent 1 to 256 colors chosen among 2 ^ (3 * 8) = 16,777,216 possible RGB colors where 2 is the binary possibilities of bits, 3 is the number of bytes (RGB) and 8 is the number of bits for each byte.
For more details on the possibilities offered by the PNG format regarding the number of colors, please refer to Colors in PNG.
IDAT image data chunks
IDAT chunks are made of image scanlines as defined by IHDR. Each scanline starts with the filter type encoded on one byte. The compression is not done per data chunk but on the continuation of the chunks. Data chunks can be zero length.
Text chunks
Text chunks are encoded as tEXt or zTXt if compressed. They can describe arbitrary keyword-text pairs. RFC recommends ISO 8859-1 (Latin-1) encoding. Keyword is encoded on 1-79 bytes, followed by a 0x00 byte and followed by the text for the rest of the chunk data. Keywords can repeat. A PNG file can contain any number of text chunks. Here is a list of RFC recommended text keywords and their intended use:
Keyword | Intended use |
Title | Short (one line) title or caption for image |
Author | Name of image’s creator |
Description | Description of image (possibly long) |
Copyright | Copyright notice |
Creation Time | Time of original image creation |
Software | Software used to create the image |
Disclaimer | Legal disclaimer |
Warning | Warning of nature of content |
Source | Device used to create the image |
Comment | Miscellaneous comment; conversion from GIF comment |
Note that PNG files can embed XMP in iTXt chunks with keyword “XML:com.adobe.xmp”.
Also, PNG files can contain EXIF data in eXIf chunks.
Other chunks
For the other non mandatory chunk types not described in details in this post, please refer to the section below for more readings.
Other readings on how a PNG file is built
PNG (Portable Network Graphics) Specification Version 1.0
PNG The Definitive Guide Paperback
Leave a comment
Thanks for your visit. I hope this post helped you understand how a PNG file is built. I would be very excited to know what you think of this explanation on how PNG files are built through the comments section below.