0

I am trying to make an simple-png image file from scratch, using hex editor. enter image description here

Bytes before the highlighted region are for PNG file header and IHDR. Which states that I am trying to make an

  1. 10 x 10 Png file
  2. Greyscale color space
  3. 1 bit depth (bi-level)
  4. Deflate Compression?
  5. Adaptive Filtering?
  6. No interlace

The bytes highlighted are a placeholder for the future length of the IDAT field.

Question:- Now I am unsure on what (or How?) am I supposed to put the image data in the IDAT field?

I am aware of Pixel values of an image being an matrix of MxN dimensions. Being displayed somewhat like:

[ (255, 255, 255), (255, 255, 255) ... (255, 255, 255)] 
[ (255, 255, 255), (255, 255, 255) ... (255, 255, 255)] 
[ (255, 255, 255), (255, 255, 255) ... (255, 255, 255)]
[ (255, 255, 255), (255, 255, 255) ... (255, 255, 255)] 

The Pixel values of an White RGB image, where top left tuple is the color value of pixel at (0, 0) and bottom right being the one for (m-1, n-1).

Now how am I supposed to code that into the IDAT header's data structure? What I am trying to know is how values like above (pixel values) are transformed into the deflate block?

P.S.:- I am not so literate on the workings of Deflate or the filtering algorithms used wherein the png file. I have read the RFC 2083 and Wikipedia page of the Png file. I have also read all relevant answers on stack exchange.

Vasu Deo.S
  • 1,820
  • 1
  • 11
  • 23
  • RF 2083 *only* defines deflate compression, and no other alternative. you'll have to use it, or figure out if amendments were published that allow for a simpler compression (or none). – Christoph Rackwitz Dec 23 '21 at 15:36
  • @ChristophRackwitz I have nothing against Deflate compression. What I was asking is ***how does the compression and filteration works on pixel data (matrix of pixel values)***? – Vasu Deo.S Dec 23 '21 at 15:56
  • If that's your question, then put it in the question. – Mark Adler Dec 29 '21 at 07:35
  • [This](https://www.w3.org/TR/PNG-Chunks.html) and [this](https://www.w3.org/TR/PNG-Compression.html) (linked from the first) seems really promising as a good source – Nearoo Jan 01 '22 at 14:47
  • Try if `gzip -8 my_pixels.bin -c > my_pixels_compressed.bin` works to compress the bytestream generated according to above sources. In the source I read you can use `zlib` to compress the IDAT stream, which is used by `gzip`. Not a solution, but a potentail path to a solution. – Nearoo Jan 01 '22 at 14:54
  • If you bounty 200 reps I'll try it out myself in write an anser :) – Nearoo Jan 01 '22 at 14:57

2 Answers2

1

The IDAT content is a deflate stream, which is compressed data. Deflate is documented in RFC 1951, and is far too complicated to fit in an answer here.

The data that is compressed is filtered rows of pixels, where each row is preceded by one byte identifying the filter used for that row.

For your example, each pixel is a single bit, so ten bits occupies two bytes (with the low six bits of the second byte left unused). Each row is then three bytes total. The ten rows are 30 bytes. The 30 bytes are then compressed to a deflate stream.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
0

Since I can't comment yet, I'll post an answer.

In that case you would probably use 6 bytes of hex for each color (#RRGGBB). A list of pixels with the following RGB values: 255 0 255, 0 0 255, 255 255 255 would become: ff00ff 0000ff ffffff.

According to this question all bytes are concatenated within the IDAT, so you should get something like: ff00ff0000ffffffff.

But I'm not 100% sure if this is correct, in fact I have a similar question.

Luna
  • 27
  • 5