http://halicery.com/2Image Decoders/PNG/The PNG file.html

PNG file structure

      8-byte 
    SIGNATURE

| % P N G . . . . | .. CHUNK .. .. | .. CHUNK .. .. .. .. .. .. | .. CHUNK .. .. .. .. .. .. .. | .. CHUNK .. | 

The chunks

Each CHUNK consists of four parts (the boxes are bytes):

     +---+---+---+---+   +---+---+---+---+   +---+--- - - --+---+---+---+---+   +---+---+---+---+
     |   |   |   |   |   |   |   |   |   |   |                              |   |   |   |   |   |
     +---+---+---+---+   +---+---+---+---+   +---+--- - - --+---+---+---+---+   +---+---+---+---+
          Length            Chunk Type          Chunk Data (Length bytes)             CRC


 "Critical chunks (must appear in this order, except PLTE is optional):   

        Name   Multiple  Ordering constraints

        IHDR    No       Must be first
        PLTE    No       Before IDAT (optional)
        IDAT    Yes      Multiple IDATs must be consecutive
        IEND    No       Must be last"

This decoder supports only critical chunks (the others are quite client-dependent) with multiple IDAT:

   SIG..IHDR...PLTE........IDAT..................IDAT...........................IDAT..........IEND    

Traversing the chunk structure

Read SIG
{
  Length <- GetDWord 
  Type <- GetDWord 
  seek(Length)
  CRC <- GetDWord
}
until (Type == IEND)

The IDAT chunk(s)

Concatenation of all IDAT contains a zlib-compressed bit-stream using the Deflate algorithm. The first

"There can be multiple IDAT chunks; if so, they must appear consecutively with no other intervening chunks." (http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html)

IDAT .. .. .. .. .. .. .. .. .. .. ..  IDAT .. .. .. .. .. .. ..  IDAT .. .. .. .. ..  
               |
               |
               | NextByte
               |
          +-------- inflate --------+   
          |                         |
          |                         |  ------> uncompressed data bytes
          |                         |   
          |                         |                                                                                                                        
          +-------------------------+                                                                                    
                                                                                                 
           I wanted to implement 'transparently' for inflate() to get the next byte from the compressed datastream.
           It simply calls back a function (NextByte) set by the client (run-time binding, OS dev habits..). 
           Again, allocated buffers vs. speed to 'concatenate' or not the IDAT chunks.  
      
           Inflate v1:  output buffer is the Window buffer (full deflate buffer) Good for small png-s. 
           Inflate v2:  NO output buffer: call returns one byte of inflated data. 32K Window buffer. Good for big png-s.

Concatenation of all IDAT contains a zlib-compressed bit-stream (lsb-first)


zlib-block......zlib-block......zlib-block......zlib-block (final zlib-block has first bit set, bfinal)


zlib-block:

    
     HEAD   HT DEFINITIONS           COMPRESSED DATA               EOD
    \____/\_______________/\_____________________________________/\___/
    
 
    [0][10][10010][10010][1110][010][110][000]...[001][01][01001][1110][010]...........[0001][010][1110][10010]....[10][......COMPRESSED DATA......][EOD]
    \_/\__/\_____/\_____/\____/\_____________________/\________________________________/\______________________________/\__________________________/\___/
bfinal btype hlit  hdist  hclen     len-of-len           len-of-literals/ptr-lenghts           len-of-distance            
                                                                                                                             |
                                       / \                       / \                              / \                        |
                                      2   x                     x   x                            x   x                       |
                                         / \                   / \ / \                          / \ / \                       ----- literal
                                                              4  x x  x                        4  7 x  x                      ----- length/dist
                                                                /\ /\ /\                            /\ /\                     ----- EOD
                                         
                                                  ..we build 3 Huffman trees..

Sun Nov 22 14:48:28 UTC+0100 2015 © A. Tarpai