放气压缩规范说明

Deflate compression spec clarification(s)

我对这个问题的希望(见:底部)是尽可能多地展示我对放气过程的了解,并且我可以在我(可能非常)误导的地方收到更正。希望最后,这个问题可以成为一个方便的资源。

Zlib header

前两个字节等同于 header 用于格式为 (credit)

的 zlib 压缩
---CMF---  ---FLG---
0111.1000  1101.0101
CINF -CM-  +-||
           | |+- FCHECK
           | +-- FDICT
           +---- FLEVEL

RFC 1950,从右到左:

  1. FCHECK (1.0101) - 验证 CMF 和 FLG 作为 16 位无符号整数是 31 的倍数

  2. FDICT (0) - 如果设置,表示紧跟在 FLG

  3. 之后的预设 DICT
  4. FLEVEL (11) - 压缩 "intensity" [0-3]

  5. CM (1000) - 用于压缩方法,其中CM = 8 == "deflate"压缩方法

  6. CINF(0111) - 表示使用的滑动大小window,其中CINF=7 == 32K滑动window

数据块header

NEW BYTE 中接下来的三位等于霍夫曼编码块的 header:

---CMF---  ---FLG---  NEW BYTE
0111.1000  1101.0101  11101100
                           |-|
                           | +- BFINAL
                           +--- BTYPE

RFC 1951 从右到左:

  1. BFINAL (0) - 如果这是最后一个数据块,则设置为 (1)

  2. BTYPE (10) - 霍夫曼编码:(00)none; (01)固定霍夫曼码; (10) 动态代码; (11)无效

霍夫曼编码

从这里我将推导出 BTYPE = (10)

的假设

以下值立即进行:

NEW BYTE                NXT BYTE                  
(11101)100       ->     101)(11101)   ->   0111111(1
       |-|
       | +- BFINAL
       +--- BTYPE
  1. HLIT (11101) - length/literal 代码的 5 位数,添加了 257 (257-286)

  2. HDIST (11101) - 距离码的5位数,加1 (1-32)

  3. 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的位之后,继续后面的位,使用生成的霍夫曼码读取码长。