12
votes

Trying to understand PNG format.

Consider this PNG Image:

enter image description here

The Image is taken from here

In Hex Editor , it looks like this:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 80 00 00 00 44 08 02 00 00 00 
C6 25 AA 3E 00 00 00 C2 49 44 41 54 78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F 
B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 00 80 
00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 
00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 64 4B 94 F5 98 7C D1 F4 92 5C 5C 3E CF 9C 3F 
73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39 
C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00 
01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 37 DB 
68 03 20 FB ED 96 65 00 00 00 00 49 45 4E 44 AE 42 60 82

Equivalent characters:

‰PNG........IHDR...€...D.....Æ%ª>...ÂIDATx^íÔ..Ã0.@Ñ·4Ýÿÿo³tVê‰.l(sâª4I.‡ÖþØ{‰
»R.;‡þ..€.......@....... ....€.......@....... ...Ô^jdK”õ˜|Ñô’\\>Ïœ?sqX_¯
‹y[î–¶GëñêÑζãu;湕.ÇÎ.9ɯÆ3“{f7Ï«¿ùÉ/.€.......@....... ....€.......@....... ..Œ7Ûh. 
ûí–e....IEND®B`‚

The same is shown in following Screenshot of the HEX Editor:

enter image description here

I am trying to reverse engineer this image to extract the header part and the RGB pixel values. I read about the PNG and also here , and so far I have noted the following about this Image:

The IHDR chunk must appear FIRST. It contains:

Width:              4 bytes
Height:             4 bytes
Bit depth:          1 byte
Color type:         1 byte
Compression method: 1 byte
Filter method:      1 byte
Interlace method:   1 byte

Below I am starting reading the HEX Data in sequence:

1- First 8-bytes: This is the 8-Byte signature

 89 50 4E 47 0D 0A 1A 0A

Equivalently this is : %PNG as can be seen in HEX Editor

A valid PNG image must contain an IHDR chunk, one or more IDAT chunks, and an IEND chunk.

2- Chunk: Length

 00 00 00 0D

3-Chunk: Chunk Type

 49 48 44 52

Which is IHDR.

http://www.w3.org/TR/PNG-Chunks.html

4- Chunk: Width of the Image (in Decimal 128)

00 00 00 80

5- Chunk: Height of the image (in Decimal 68)

00 00 00 44

6- Chunk: BIT DEPTH (1 byte )

08

7- Chunk: Color Type

02

8- Compression method

00

9- Filter method:

00

10- Interlace method:

00

11- What is the following data?

C6 25 AA 3E 00 00 00 C2

12-- IDAT

49 44 41 54

13- What is this data (after IDAT):

78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 64 4B 94 F5 98 7C D1 F4 92 5C 5C 3E CF 9C 3F 73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39 C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 37 DB 68 03 20 FB ED 96 65 00 00 00 00

14- IEND:

49 45 4E 44

15- Last 4 bytes

 AE 42 60 82

What are these ?

Can some help me understand, points 11, 13 and 15 above? And where are the Pixel values? The Image is having (128 x 68 pixels)

Purpose of knowing these details:

Once I know these details, I will generate my own 16 bit PNG image. I already have pixel values, so my job would be to introduce headers etc.
I dont know if there is software that can perform this job.

UPDATE

I understand now because of compression, I would not be able to locate the pixel values.

I got the idea that I can write a file in OpenCV and save it as png. Well now my direct question is: I have a binary file having gray-scale 16 bit-pixel values. Can I write this in OpenCV as 16 bit PNG ?

3

3 Answers

4
votes

Although it might be interesting to learn about what PNG Images actually are, and how the image is actually represented in the file, you don't need to know this to generate a PNG file.

Note that PNG uses lossless compression, which means you won't get two bytes per pixel.

You can generate your image in a program and output it in PNG format using many of the libraries that there are out there. For example, you can make your image in OpenCV and then output it with imWrite. One of the parameters can make it output to a PNG.


If you have the gray-scale 16-bit pixel values, then you can put them into a Mat.

Then convert that to an IplImage: Converting cv::Mat to IplImage*

Then you can output it to a file.

3
votes

Just for completeness (eboix's answer is right on the spot)

11- What is the following data?

C6 25 AA 3E 00 00 00 C2

Each chunk ends with a CRC (4 bytes), and starts with 4 bytes that tell its length. So, C6 25 AA 3E is the CRC of the previous chunk (IHDR) and 00 00 00 C2 (194) is the length of the following (IDAT) chunk.

In the same way, the last 4 bytes is the CRC of the IEND chunk.

3
votes

I did not look too carefully but from looking at the structure...

Q11. C6 25 AA 3E = CRC32 00 00 00 C2 = Size of next chunk

Q13. check the png spec's you referred to earlier that looks like the IDAT chunk you allready know the compression applied to it!

Q15. AE 42 60 82 = CRC32