http://halicery.com/Image Decoders/PNG/Interlaced PNG.html

Interlaced PNG

PNG uses its own interlace technique (Adam7 is the name) to help to progressively display big PNG images over slow network connection. It's a 7-pass decoding process.

Download this series of 7 images of PNG 7-pass interlace.

The basis is a 8x8 image tile, which will be filled in during the 7 decoding passes:

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

An example

Suppose a 43 x 10 image. This is the empty, uncompressed BMP image in memory to be filled in with decoded pixel values:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The first interlace pass contains this 6 x 2 sized sub-image:

1 1 1 1 1 1 
1 1 1 1 1 1 

which will scatter around in the final image after decoding:

1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . . . . . . 1 . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The second interlace pass decodes a 5 x 2 sized sub-image:

2 2 2 2 2 
2 2 2 2 2 

then after the second pass:

1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The 3rd interlace pass decodes a 11 x 1 sized sub-image:

3 3 3 3 3 3 3 3 3 3 3 

then after the 3rd pass:

1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . . 3 . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . . . 2 . . . 1 . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The 4th interlace pass contains this 11 x 3 sized sub-image:

4 4 4 4 4 4 4 4 4 4 4 
4 4 4 4 4 4 4 4 4 4 4 
4 4 4 4 4 4 4 4 4 4 4 

then after the 4th pass:

1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The 5th interlace pass contains this sub-image:

5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5

then after the 5th pass:

1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4 . 3 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5 . 5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4 . 2 . 4 . 1 . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The 6th interlace pass decodes a 21 x 5 sized sub-image:

6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 

then the 6th pass:

1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 

The remaining (odd lines) come from the last 7th sub-picture:

1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5 6 5 5 6 5 6 5 6 5
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4 6 3 6 4
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5 6 5
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4 6 2 6 4 6 1 6 4
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 

In the decoder

When the PNG to be decoded is interlaced, first we have to compute the size of each sub-image. In each directions (x; y) by a division.

Then after decoding the sub-images, the result is scattered in the final image by 4 parameters: x0, y0 to start with, and a step-parameter. For each Adam7 sub-image these parameters are stored in an array. Taken out of the decoder's source code:

static struct Adam { int x0, y0, stx, sty, log2stx, log2sty } 
ADAM7[] = {
{ 0,0,8,8, 3,3 },
{ 4,0,8,8, 3,3 },
{ 0,4,4,8, 2,3 },
{ 2,0,4,4, 2,2 },
{ 0,2,2,4, 1,2 },
{ 1,0,2,2, 1,1 },
{ 0,1,1,2, 0,1 }
};	

Mon Feb 11 10:24:38 UTC+0100 2019 © A. Tarpai