【发布时间】:2018-11-11 07:07:49
【问题描述】:
我一直试图通过对我在 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,我们从前8个字节的PNG签名开始。
89504E47 0D0A1A0A
然后我们有重复的“块”结构,这个文件有 3 个“块”、标题 (IHDR)、图像数据 (IDAT) 和结尾的“块” (IEND)。
每个chunk被排列成:前4个字节为chunk数据长度,后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 936F 3061>
是块的实际数据(经过压缩和过滤的图像数据)。
所以我的实际问题是如何将最后一部分解码为原始像素?
根据spec,我必须首先解压缩数据(INFLATE?),然后对其进行过滤(??)以留下像素扫描线(我的目标)。
如果这可以用伪代码来解释,那就太棒了!否则我对 Swift 很熟悉,而对 C 则不太熟悉...
【问题讨论】:
-
我知道您想严格执行此操作以应对挑战,否则您应该使用预先存在的库。
-
您确定要实现 zlib 组件,还是可以使用库进行解压和/或过滤? zlib 的伪代码并不小,部分原因是需要考虑变体。
-
我更喜欢实现zlib;拜访图书馆并不能真正教会我任何东西。如果不是伪代码,只是分解成更简单的步骤,我可以自己研究?
-
如果我在哪里,我会从 GIF ... as it is well documented 开始,并提供示例(请参阅其中的 3MF 链接)并包含非常相似的压缩算法。完成后移至png。另一种可能性是使用 zlib 并在工作时用您自己的代码一个一个地替换 zlib 调用。遗憾的是我自己没有做 PNG 解码器/编码器(我使用 pngDelphi),所以无法提供更多详细信息,但我确实做了PCX,GIF,DDS,SGI,SVG,EMF,WMF 和更多的解码器/编码器过去(因为我需要他们)
-
无论如何,你应该添加一些代码以及你到底卡在哪里,这样这个有趣的问题就不会因为太宽泛或离题而被关闭....
标签: image algorithm bitmap png pseudocode