如何读取和解码 png 图像文件中的 zlib 块和放气块
How to read and decode zlib block and deflate block in a png image file
最近我开始为 fun.And 编写一个 png 解码器以了解格式和压缩我已经阅读了以下内容
PNG(便携式网络图形)规范,版本 1.2)
RFC 1950(“ZLIB 压缩数据格式规范”)
RFC 1951(“DEFLATE 压缩数据格式规范”)
因此我对格式和压缩有了一个简单的了解。
所以一开始我决定实现一个简单的解码器来解码一个简单的 png 图像文件,为此我选择了一个简单的 png 图像,其中包含一个 IDAT 块,其中包含一个 zlib 块和 deflate 块。
使用的图像文件是这个
Image file used for decoding
我已经从图像文件中提取了 zlib 块,在十六进制编辑器中它看起来像这样
Hex view of IDAT CHUNK
而红色部分的二进制表示是这样的
Binary representation of zlib block
现在,根据我阅读规范的理解,我将其解码如下
Decoded binary representation of zlib block
BFINAL=最后一个区块
BTYPE=动态哈夫曼
HLIT=29
HDIST=29
HCLEN=11
绿色部分为码长字母的(HCLEN+4)个码长
读长如下6,6,0,2,3,3,5,4,4,4,3,6,4,6,5
以上码位长度生成的霍夫曼码如下
Generated huffman code
并将它们分配到相应的长度字母表后如下(注意:长度字母表18未使用,因为其代码长度为零)
Assigned huffman codes
现在,当我开始使用分配的霍夫曼代码解码 literal/length 字母的霍夫曼代码的 (HLIT+257) 代码长度的霍夫曼代码时,我得到的第一个解码字母为 16 ,但这是不可能的,因为字母表 16 是复制以前的代码长度字母表,但这是不可能的,因为它是第一个解码字母表。
因此我对格式的理解有一些错误,我似乎无法理解,这就是我需要帮助的地方。
您表示代码的方式没有意义,因为您显示的是一堆不属于代码的零,因此您无法判断它们的长度。与它们在字节中的显示方式相比,您还以相反的方式显示了代码。
更重要的是,不知何故你把作业弄错了。以下是正确的代码,仅显示代码中的位,位顺序正确,赋值正确:
00 - 0
010 - 7
110 - 8
001 - 11
0101 - 5
1101 - 6
0011 - 10
1011 - 12
00111 - 9
10111 - 13
001111 - 3
101111 - 4
011111 - 16 (followed by two bits, +3 is the repeat count)
111111 - 17 (followed by three bits, +3 is the zeros count)
第一个码长码是001111
,表示文字0的码长是3。
最近我开始为 fun.And 编写一个 png 解码器以了解格式和压缩我已经阅读了以下内容
PNG(便携式网络图形)规范,版本 1.2)
RFC 1950(“ZLIB 压缩数据格式规范”)
RFC 1951(“DEFLATE 压缩数据格式规范”)
因此我对格式和压缩有了一个简单的了解。
所以一开始我决定实现一个简单的解码器来解码一个简单的 png 图像文件,为此我选择了一个简单的 png 图像,其中包含一个 IDAT 块,其中包含一个 zlib 块和 deflate 块。
使用的图像文件是这个 Image file used for decoding
我已经从图像文件中提取了 zlib 块,在十六进制编辑器中它看起来像这样 Hex view of IDAT CHUNK
而红色部分的二进制表示是这样的 Binary representation of zlib block
现在,根据我阅读规范的理解,我将其解码如下 Decoded binary representation of zlib block
BFINAL=最后一个区块
BTYPE=动态哈夫曼
HLIT=29
HDIST=29
HCLEN=11
绿色部分为码长字母的(HCLEN+4)个码长
读长如下6,6,0,2,3,3,5,4,4,4,3,6,4,6,5
以上码位长度生成的霍夫曼码如下 Generated huffman code
并将它们分配到相应的长度字母表后如下(注意:长度字母表18未使用,因为其代码长度为零) Assigned huffman codes
现在,当我开始使用分配的霍夫曼代码解码 literal/length 字母的霍夫曼代码的 (HLIT+257) 代码长度的霍夫曼代码时,我得到的第一个解码字母为 16 ,但这是不可能的,因为字母表 16 是复制以前的代码长度字母表,但这是不可能的,因为它是第一个解码字母表。
因此我对格式的理解有一些错误,我似乎无法理解,这就是我需要帮助的地方。
您表示代码的方式没有意义,因为您显示的是一堆不属于代码的零,因此您无法判断它们的长度。与它们在字节中的显示方式相比,您还以相反的方式显示了代码。
更重要的是,不知何故你把作业弄错了。以下是正确的代码,仅显示代码中的位,位顺序正确,赋值正确:
00 - 0
010 - 7
110 - 8
001 - 11
0101 - 5
1101 - 6
0011 - 10
1011 - 12
00111 - 9
10111 - 13
001111 - 3
101111 - 4
011111 - 16 (followed by two bits, +3 is the repeat count)
111111 - 17 (followed by three bits, +3 is the zeros count)
第一个码长码是001111
,表示文字0的码长是3。