【问题标题】:Deflate compression spec clarification(s)放气压缩规格说明
【发布时间】:2015-11-05 01:57:23
【问题描述】:

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

Zlib 头文件

前两个字节相当于 zlib 压缩的标头,格式为 (credit)

---CMF---  ---FLG---
0111.1000  1101.0101
CINF -CM-  +-||
           | |+- FCHECK
           | +-- FDICT
           +---- FLEVEL

RFC 1950,从右到左:

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

  2. FDICT (0) - 如果设置,则表示预设 DICT 紧跟在 FLG 之后

  3. FLEVEL (11) - 压缩“强度”[0-3]

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

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

数据块头

NEW BYTE 中接下来的三位相当于 Huffman 编码块的标头:

---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) - 5 位长度/文字代码,添加 257 (257-286)

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

  3. HCLEN (1111) - 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

我的问题

上面括号中的最后几位会被扔掉吗?

【问题讨论】:

  • 我不会投反对票,但我怀疑这个问题的价值。 1)这不是关于 PNG,而是关于 ZLIB/deflate 规范(PNG 使用 ZLIB/deflate 在这里无关紧要 - “解耦层”的概念对于工程来说是必不可少的)。 2)这不是一个真正的具体问题,而是使用一个特殊的例子来帮助理解 ZLIB/deflate 格式的细节(这对其他人几乎没有帮助)3)假装有点奇怪(尽管也许也值得称赞)了解位级别的 ZLIB 流,特别是如果您不了解 Huffman 压缩
  • ... 并且在问题标题的上下文中闻起来很有趣:您通常不需要理解这么低级别的东西来理解 PNG 格式。 4) 看这里stackoverflow.com/questions/26018811/…
  • 我想我理解这个领域的东西的定义是能够编码它。就像在程序中解码器一样。但我会争论这个问题的价值,真正掌握字节的文件 I/O 是一个很好的练习,甚至是单个位。它还涉及字节序。作为一名受过大学教育的 CS 学生,我在所有领域都很薄弱。可能题主写错了,能改吗?应该是,如果可以的话?我对包含 PNG 的(可能很糟糕)逻辑是,大量搜索 deflate 自然会涉及 PNG。我相信这是值得学习的好东西。
  • @leonbloy 另外,在我看来,堆栈溢出的最佳功能之一是真正深入的答案,可以消除任何混淆并提出执行 X 的最佳方法。我试图模仿或引起社区这样的回答
  • @MarcusJ 我最初做这一切是因为我正在研究 PNG 文件。 IDAT 块的结构与我在上面的布局完全相同。从 zlib 标头开始,然后是数据块标头,然后是霍夫曼代码,然后是编码数据。 0x78 的第一个字节与我上面的示例相同(包含 CINF 和 CM 的 CMF 字节)

标签: c++ binary zlib huffman-code deflate


【解决方案1】:

没有。在放气流中,您跳过位以转到字节边界的唯一时间是存储块 (00),或者读取最后一个块中的结束代码时。在代码长度代码长度的位之后,您继续使用后续位以使用生成的霍夫曼代码来读取代码长度。

【讨论】:

  • 感谢 Adler 博士的回复。我发现了你的 puff.c 程序,并从构造函数中借了一部分。即,它测试过度订阅/不完整长度集的部分,并且在构建第一棵树(代码长度代码)时,它在我测试过的五个图像上返回负值。你能解释一下为什么吗?我测试过的图像来自 gimp(创建)或互联网(下载)。它们的 BTYPE 都为 2,我读入了上述值。我还与 puff.c 进行了交叉检查,并且正在读取正确的位。再次感谢。
  • 您可能没有读取正确的位,或者您没有正确解释它们。
  • 谢谢,我会检查我的实现
猜你喜欢
  • 2012-12-09
  • 2015-02-27
  • 2014-02-03
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多