我目前正在为了学习目的编写一个小型PNG图像I/O库。我的问题如下:
我创建了一个仅有2x2像素的小PNG图像,并在十六进制编辑器中打开以研究其内容。这是我使用GIMP创建并用"9"压缩存储的图像。
(请注意,这是原始2x2像素图像的放大图像 ;) )
现在,前两个字节
这最终让我得到以下字节:
为了更好地理解DEFLATE,我试图手动“解压”这个序列,至少在我足够理解它以编写一个小工具之前。但是我很快就卡住了。
RFC 1951(“DEFLATE压缩数据格式规范”)指出,每个编码块都以三位头开始。一位表示这是否是最后一个块,另外两个块表示压缩方法。由于我假设编码器仅使用一个块(意味着第一个块自动是最后一个),并使用非静态Huffmann树,因此我正在寻找位序列“101”,但我找不到它(也没有找到其他可能的标题“100”或“110”)。
此外,RFC还指出,必须有两个两字节值LEN和NLEN存储块的长度,其中NLEN是LEN的一补数,但是我仍然无法找到满足此条件的四个字节。我甚至不会开始寻找任何可能代表两个Huffmann树的东西。
我阅读了RFC 1951和1950("ZLIB压缩数据格式规范"),以及有关zlib、DEFLATE、LZ77和Huffman编码的维基百科文章,还有一些网上的小而不太有用的文章和一些Stack Overflow上的答案,但都无法帮助我理解。
如果能得到任何帮助或提示,我将非常感激!
我创建了一个仅有2x2像素的小PNG图像,并在十六进制编辑器中打开以研究其内容。这是我使用GIMP创建并用"9"压缩存储的图像。
(请注意,这是原始2x2像素图像的放大图像 ;) )
00 00 00 FF 00 00 00 00 FF 00 FF 00
没有 alpha 通道时存储。
(我在这里只是为了清晰起见说明。我知道压缩,并没有期望在文件中看到这个字节模式)。
我提取了 IDAT 块并去掉了块标识符(“IDAT”)和尾部的 CRC 值,得到了这个字节序列:
08 D7 05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06 0F FE 02 FE
现在,前两个字节
08 D7
包含编码块的信息。最后四个字节0F FE 02 FE
必须是ADLER32校验和。这最终让我得到以下字节:
05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06
用二进制表示,这些字节是:
0000 0101 1100 0001 0000 0001 0000 0001
0000 0000 0000 0000 0000 0000 1000 0000
0001 0000 1111 1111 0100 1111 0001 0111
0001 0000 0100 1000 0000 0110
为了更好地理解DEFLATE,我试图手动“解压”这个序列,至少在我足够理解它以编写一个小工具之前。但是我很快就卡住了。
RFC 1951(“DEFLATE压缩数据格式规范”)指出,每个编码块都以三位头开始。一位表示这是否是最后一个块,另外两个块表示压缩方法。由于我假设编码器仅使用一个块(意味着第一个块自动是最后一个),并使用非静态Huffmann树,因此我正在寻找位序列“101”,但我找不到它(也没有找到其他可能的标题“100”或“110”)。
此外,RFC还指出,必须有两个两字节值LEN和NLEN存储块的长度,其中NLEN是LEN的一补数,但是我仍然无法找到满足此条件的四个字节。我甚至不会开始寻找任何可能代表两个Huffmann树的东西。
我阅读了RFC 1951和1950("ZLIB压缩数据格式规范"),以及有关zlib、DEFLATE、LZ77和Huffman编码的维基百科文章,还有一些网上的小而不太有用的文章和一些Stack Overflow上的答案,但都无法帮助我理解。
如果能得到任何帮助或提示,我将非常感激!
infgen
不会计算未压缩数据的校验值以查看其是否正确。 - Mark Adler