Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode the IDAT chunk of a PNG file with no compression

I created a few 4x4 pixel, 16-bit grayscale, images in Photoshop and saved them as non-compressed, no interlace, PNG files. I am trying to write a program to extract the image data from these files but I have become a bit confused with the IDAT chunk. This is for self-education purposes, so I am not using a library.

Here is the hex code for the IDAT chunk of one of the images where every pixel is white.

hex code

I have color coded what I believe I understand at this point.

Red = Ignore because it is part of the IEND chunk and not relevant to IDAT.
Yellow = Chunk information. The first 4 yellow bytes are the data length. Second 4 yellows bytes are the chunk identifier. The last 4 yellow bytes at the end of the image are the Cyclic Redundancy Check.
Blue = zlib compression format information. Where the first blue byte is the compression method and compression information. The second blue byte is Flag information. The last four blue bytes near the bottom of the image are the ADLER-32 checksum. I am assuming there is no DICTID in this case.
Grey = Information for the Deflate compression algorithm. In the first grey byte, bit one is the last block marker and bits two and three are the encoding method. The rest of the first grey byte is ignored. Since this method is the non-compressed method, the second and third grey bytes are the length of the data bytes in the block and the fourth and fifth grey byte are the one's compliment of the second and third grey bytes.
No Box = The Image data compressed with the LZ77 algorithm (no Huffman code because of uncompressed method) with the algorithm using 8-bits for potential duplicates length and 15-bits for search back distance.

Either I am understanding something incorrectly or I am not understanding how to decode the bytes in the image with no box using the LZ77 algorithm correctly. If someone can please correct me or show what I am not understanding I would greatly appreciate it. Thank you.

like image 537
Kevin Baker Avatar asked Aug 22 '16 03:08

Kevin Baker


People also ask

What is Idat in PNG?

The IDAT chunk contains the output datastream of the compression algorithm. To read the image data, reverse this process. There can be multiple IDAT chunks; if so, they must appear consecutively with no other intervening chunks. The compressed datastream is then the concatenation of the contents of all the IDAT chunks.

What is a chunk PNG?

A PNG file is composed of an 8-byte signature header, followed by any number of chunks that contain control data / metadata / image data. Each chunk contains three standard fields – 4-byte length, 4-byte type code, 4-byte CRC – and various internal fields that depend on the chunk type.

Does PNG support 16 bit?

As with RGB and gray+alpha, PNG supports 8 and 16 bits per sample for RGBA or 32 and 64 bits per pixel, respectively. Pixels are always stored in RGBA order, and the alpha channel is not premultiplied.


1 Answers

Top row: 01 ff fd 00 00 00 00 00 00 ("sub" filter, first pixel is fffd, subsequent pixels are each the same as the pixel to its left (difference = 0)

Remaining 3 rows: 02 00 00 00 00 00 00 00 00 ("up" filter, all same as row above)

Last block: 01 00 00 ff ff (last byte marker 01, len 0000, ~len ffff)

So the image is 4x4, all pixels are 16-bit fffd, which is almost white.

If you had used filter-type 0 for all bytes, it might have been clearer to understand; the rows would each have been 00 ff fd ff fd ff fd ff fd

By the way, the IEND chunk should have 4 more bytes (the CRC); either something is wrong with your encoder or you edited them out of the picture of the hex dump.

like image 172
Glenn Randers-Pehrson Avatar answered Nov 08 '22 17:11

Glenn Randers-Pehrson