伪代码:如何从位和字节解码PNG文件?

时间:2018-06-01 07:36:51

标签: image algorithm bitmap png pseudocode

我一直试图通过逆向工程我在GIMP中创建的.png文件来解决这个问题。它是4x4像素。我的目标是将原始像素解码出文件,目的是将其反转以进行编码。

这是文件的完整十六进制转储:

89504E47 0D0A1A0A 0000000D 49484452 00000004 00000004  
08020000 00269309 29000000 3F494441 54081D01 3400CBFF  
01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0  
403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21  
93EDB11F 3063136F 4733525A 00000000 49454E44 AE426082  

根据spec,我们从PNG签名开始,这是前8个字节。

  

89504E47 0D0A1A0A

然后我们重复" chunk"结构,这个文件有3"块",标题(IHDR),图像数据(IDAT),然后是结束" chunk" (IEND)。

每个块被安排成:块数据长度的前4个字节,数据类型的接下来的4个字节,然后是实际数据的n个字节,然后是循环冗余校验的4个字节(CRC )数据类型和实际数据部分。

通过......

  

0000000D

块的数据长度(13个字节)。

  

49484452

是块的类型(IHDR)。

  

00000004 00000004 08020000 00

是块的数据(4字节宽度,高度; 1字节位深度,颜色类型,压缩方法,滤波方法,隔行扫描方法)。

  

269309 29

是数据和类型的CRC(设法让代码从here开始解决。

  

000000 3F

是下一个块的数据长度(63字节)。

  

494441 54

是块的类型(IDAT)。

  

081D01 3400CBFF 01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0 403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21 93EDB11F 3063136F

是块的实际数据(压缩和过滤的图像数据)。

所以我的实际问题是如何将最后一部分解码为原始像素?

根据spec,我必须首先解压缩数据(INFLATE?),然后不过滤它(??)以留下像素的扫描线(我的目标)。

如果这可以用伪代码解释那将是惊人的!否则,我对Swift很熟悉,而对C ...则不太熟悉

3 个答案:

答案 0 :(得分:3)

你的问题对于伪代码来说过于宽泛 - 或者至少是可操作的伪代码 - 如果我们足够高,你已经知道了基础:1。解压缩,2。不过滤,3。利润。

由于你在评论中说明你想自己做所有事情,我建议你首先实现默认的解压缩算法,ZLIB CM = 8“deflate”,这在https://www.ietf.org/rfc/rfc1951.txt等中有详细描述。

答案 1 :(得分:3)

本书解释了程序员的解码过程:

https://www.amazon.com/Compressed-Image-File-Formats-JPEG/dp/0201604434

整个过程是复杂的,以适应SO答案的空间。 PNG使用两种不同的压缩方法:LZ和Huffman编码。

答案 2 :(得分:2)

我认为pngcheck会对你有很大帮助:

pngcheck -vv result.png

示例输出

File: result.png (334985 bytes)
  chunk IHDR at offset 0x0000c, length 13
    600 x 450 image, 24-bit RGB, non-interlaced
  chunk IDAT at offset 0x00025, length 65536
    zlib: deflated, 32K window, default compression
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4
      1 4 4 1 4 1 4 1 4 4 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1
      1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1 1 1 4 4 1 4 1 1 4
      4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 (96 out of 450)
  chunk IDAT at offset 0x10031, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1
      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 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 (188 out of 450)
  chunk IDAT at offset 0x2003d, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 4 4 4 4 4 4 4 4 1 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 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 1 4 4 4 4 4 4 4 4 (273 out of 450)
  chunk IDAT at offset 0x30049, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 1 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 4
      4 4 4 4 4 4 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4
      4 4 4 4 1 4 4 4 (356 out of 450)
  chunk IDAT at offset 0x40055, length 65536
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 4 4 4 1 4 4 4 4 4 4 4 1 4 4 4 4 4 4 4 4 4 4 4 4
      4 4 4 1 4 4 4 4 4 4 4 1 1 1 4 4 1 4 4 1 1 1 4 4 4
      4 4 1 1 1 4 1 4 4 4 1 4 1 4 4 4 1 4 1 4 4 4 4 4 4
      4 1 1 4 1 4 4 1 4 1 (441 out of 450)
  chunk IDAT at offset 0x50061, length 7188
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      4 1 1 4 4 4 4 1 4 (450 out of 450)
  chunk IEND at offset 0x51c81, length 0
No errors detected in result.png (8 chunks, 58.6% compression).