A PNG file is its signature followed by chunks. Every chunk has the same four-part layout, so a reader can step over any chunk it does not understand. This page covers the signature, the chunk layout, the meaning of a chunk’s type letters, the CRC, and the rules for which chunks may appear and in what order. All multi-byte integers in a PNG are big-endian (most significant byte first).
The signature
Every PNG file starts with the same eight bytes. Each one catches a way a file can be damaged in transfer.
| Offset | Value | Purpose |
|---|---|---|
| 0 | 89 | High bit set: flags a system that strips the eighth bit, and stops the file being taken for text. |
| 1 to 3 | 50 4E 47 | The letters PNG, so the file is recognisable in a hex dump. |
| 4, 5 | 0D 0A | A DOS line ending; a transfer that changes line endings breaks the signature. |
| 6 | 1A | Ctrl-Z, which stops the MS-DOS TYPE command printing the rest of the file. |
| 7 | 0A | A Unix line ending, the reverse of the test at bytes 4 and 5. |
Chunk layout
Each chunk has four fields. The data may be empty, and its length has a maximum of 231 − 1 bytes.
| Field | Size | Meaning |
|---|---|---|
| Length | 4 bytes | The number of bytes of data, not counting the length, type or CRC. Below 231. |
| Type | 4 bytes | Four ASCII letters, A to Z or a to z, naming the chunk (see chunk types). |
| Data | Length bytes | The chunk’s contents. |
| CRC | 4 bytes | A CRC-32 of the type and data (see the CRC). |
Chunk types
The case of each letter of the type carries a flag: bit 5 of the byte, value 32, is 0 for upper case and 1 for lower case. A reader reads these from the bytes without needing to recognise the chunk.
| Letter | Upper case (bit 5 = 0) | Lower case (bit 5 = 1) |
|---|---|---|
| First (ancillary bit) | Critical: a reader must understand it to show the image. | Ancillary: a reader may ignore it. |
| Second (private bit) | Public: defined by the specification, or registered. | Private: an application’s own. |
| Third (reserved bit) | Reserved; must be upper case in this version of PNG. | The file does not conform to this version. |
| Fourth (safe-to-copy bit) | Unsafe: only copy to a modified file if you understand it. | Safe: may be copied even if the image data changed. |
IHDR, for example, is critical, public and unsafe to copy; tEXt is ancillary, public and safe to copy. A
critical chunk a reader does not recognise means it cannot show the image.
The CRC
The CRC covers the chunk’s type and data, but not its length. It is the CRC-32 used by zlib and gzip:
the reflected polynomial 0xEDB88320, a register started at all ones, bytes taken lowest
bit first, and the final value complemented. It is stored most significant byte first.
Chunk order
IHDR comes first and IEND last. All IDAT chunks follow one another with nothing between them. Otherwise the following table, from the
W3C PNG Third Edition, gives each chunk’s multiplicity and position. A chunk not listed may appear anywhere between IHDR and IEND unless the register gives a rule for it.
| Chunk | Multiple? | Order |
|---|---|---|
| IHDR | No | First |
| PLTE | No | Before the first IDAT |
| IDAT | Yes | Consecutive |
| IEND | No | Last |
| acTL | No | Before IDAT |
| cHRM | No | Before PLTE and IDAT |
| cICP | No | Before PLTE and IDAT |
| gAMA | No | Before PLTE and IDAT |
| iCCP | No | Before PLTE and IDAT; sRGB should then be absent |
| mDCV | No | Before PLTE and IDAT |
| cLLI | No | Before PLTE and IDAT |
| sBIT | No | Before PLTE and IDAT |
| sRGB | No | Before PLTE and IDAT; iCCP should then be absent |
| bKGD | No | After PLTE, before IDAT |
| hIST | No | After PLTE, before IDAT |
| tRNS | No | After PLTE, before IDAT |
| eXIf | No | Before IDAT |
| fcTL | Yes | One may come before IDAT; the others come after it |
| pHYs | No | Before IDAT |
| sPLT | Yes | Before IDAT; each must have a different name |
| fdAT | Yes | After IDAT |
| tIME | No | None |
| iTXt | Yes | None |
| tEXt | Yes | None |
| zTXt | Yes | None |
The rules for tRNS, bKGD and hIST apply to any file with a PLTE, including a truecolour image with a suggested palette. The registered extensions have their own placement rules, given on their page.
In the explorer
The explorer reads every chunk into named fields, checks its CRC, and reports any chunk out of place against the rules above.