放气压缩规范说明
Deflate compression spec clarification(s)
我对这个问题的希望(见:底部)是尽可能多地展示我对放气过程的了解,并且我可以在我(可能非常)误导的地方收到更正。希望最后,这个问题可以成为一个方便的资源。
Zlib header
前两个字节等同于 header 用于格式为 (credit)
的 zlib 压缩
---CMF--- ---FLG---
0111.1000 1101.0101
CINF -CM- +-||
| |+- FCHECK
| +-- FDICT
+---- FLEVEL
从 RFC 1950,从右到左:
FCHECK (1.0101) - 验证 CMF 和 FLG 作为 16 位无符号整数是 31 的倍数
FDICT (0) - 如果设置,表示紧跟在 FLG
之后的预设 DICT
FLEVEL (11) - 压缩 "intensity" [0-3]
CM (1000) - 用于压缩方法,其中CM = 8 == "deflate"压缩方法
CINF(0111) - 表示使用的滑动大小window,其中CINF=7 == 32K滑动window
数据块header
NEW BYTE 中接下来的三位等于霍夫曼编码块的 header:
---CMF--- ---FLG--- NEW BYTE
0111.1000 1101.0101 11101100
|-|
| +- BFINAL
+--- BTYPE
从 RFC 1951 从右到左:
BFINAL (0) - 如果这是最后一个数据块,则设置为 (1)
BTYPE (10) - 霍夫曼编码:(00)none; (01)固定霍夫曼码; (10) 动态代码; (11)无效
霍夫曼编码
从这里我将推导出 BTYPE = (10)
的假设
以下值立即进行:
NEW BYTE NXT BYTE
(11101)100 -> 101)(11101) -> 0111111(1
|-|
| +- BFINAL
+--- BTYPE
HLIT
(11101) - length/literal 代码的 5 位数,添加了 257 (257-286)
HDIST
(11101) - 距离码的5位数,加1 (1-32)
HCLEN
(1111) - code-length 代码的 4 位数,添加 4 (4-19)
紧随其后的是HCLEN
(不要忘记+4)3位字段,其中值按顺序分配给此序列:
16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15
因为 HCLEN = 19,所以使用了整个序列
该序列中0
的代码长度表示未使用相应的符号。
作为图形示例,读取 19x3 位后我们有六个额外位(括号中的额外位):
NXT BYTE 00000000 00000000 00000000 00000000 00000000 00000000 [000000](00
我的问题
上面括号中的最后几位,被扔掉了吗?
没有。在 deflate 流中,您跳过位以转到字节边界的唯一时间是针对存储块 (00),或者读取最后一个块中的结束代码时。在码长code lengths的位之后,继续后面的位,使用生成的霍夫曼码读取码长。
我对这个问题的希望(见:底部)是尽可能多地展示我对放气过程的了解,并且我可以在我(可能非常)误导的地方收到更正。希望最后,这个问题可以成为一个方便的资源。
Zlib header
前两个字节等同于 header 用于格式为 (credit)
的 zlib 压缩---CMF--- ---FLG---
0111.1000 1101.0101
CINF -CM- +-||
| |+- FCHECK
| +-- FDICT
+---- FLEVEL
从 RFC 1950,从右到左:
FCHECK (1.0101) - 验证 CMF 和 FLG 作为 16 位无符号整数是 31 的倍数
FDICT (0) - 如果设置,表示紧跟在 FLG
之后的预设 DICT
FLEVEL (11) - 压缩 "intensity" [0-3]
CM (1000) - 用于压缩方法,其中CM = 8 == "deflate"压缩方法
CINF(0111) - 表示使用的滑动大小window,其中CINF=7 == 32K滑动window
数据块header
NEW BYTE 中接下来的三位等于霍夫曼编码块的 header:
---CMF--- ---FLG--- NEW BYTE
0111.1000 1101.0101 11101100
|-|
| +- BFINAL
+--- BTYPE
从 RFC 1951 从右到左:
BFINAL (0) - 如果这是最后一个数据块,则设置为 (1)
BTYPE (10) - 霍夫曼编码:(00)none; (01)固定霍夫曼码; (10) 动态代码; (11)无效
霍夫曼编码
从这里我将推导出 BTYPE = (10)
的假设以下值立即进行:
NEW BYTE NXT BYTE
(11101)100 -> 101)(11101) -> 0111111(1
|-|
| +- BFINAL
+--- BTYPE
HLIT
(11101) - length/literal 代码的 5 位数,添加了 257 (257-286)HDIST
(11101) - 距离码的5位数,加1 (1-32)HCLEN
(1111) - code-length 代码的 4 位数,添加 4 (4-19)
紧随其后的是HCLEN
(不要忘记+4)3位字段,其中值按顺序分配给此序列:
16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15
因为 HCLEN = 19,所以使用了整个序列
该序列中0
的代码长度表示未使用相应的符号。
作为图形示例,读取 19x3 位后我们有六个额外位(括号中的额外位):
NXT BYTE 00000000 00000000 00000000 00000000 00000000 00000000 [000000](00
我的问题
上面括号中的最后几位,被扔掉了吗?
没有。在 deflate 流中,您跳过位以转到字节边界的唯一时间是针对存储块 (00),或者读取最后一个块中的结束代码时。在码长code lengths的位之后,继续后面的位,使用生成的霍夫曼码读取码长。