【问题标题】:How do I represent an LZW output in bytes?如何以字节表示 LZW 输出?
【发布时间】:2018-03-17 10:04:33
【问题描述】:

我找到了 LZW 算法的实现,我想知道如何将它的输出(一个 int 列表)表示为字节数组。

我曾尝试使用一个字节,但如果输入很长,字典有超过 256 个条目,因此我无法转换。

然后我尝试添加一个额外的字节来指示用于存储值的字节数,但在这种情况下,我必须为每个值使用 2 个字节,这压缩得不够。

如何优化?

【问题讨论】:

  • (如果标记为compression,此帖子将获得更多可见性。)

标签: compression byte lzw


【解决方案1】:

作为位,而不是字节。您只需要一个简单的例程,将任意数量的位写入字节流。它只是保留一个一字节的缓冲区,您可以将位放入其中,直到您有八位。然后写比字节,清除缓冲区,然后重新开始。另一方面,这个过程是相反的。

当你到达末尾时,如果不为空,只需写入最后一个字节缓冲区,其余位设置为零。

您只需计算在当前压缩状态下每个符号需要多少位。从流中提取位时,另一侧也可以做出同样的决定。

【讨论】:

  • 好主意,但如何解压缩输出?我应该再次将比特流解密为一个 int 列表,我怎么知道一个 int 是否以多少位表示?
  • 你在解压端重构压缩过程,然后你就知道下一个符号是多少位了。
  • 我不确定我是否明白这一点。如果我在 LZW 中压缩一个字符串并得到 [12, 284] 作为输出,然后我转换为位:1100 100011100。现在我输出 8 位并用零完成剩余的位:11001000 00011100 -> [200, 28]。现在从 [200, 28] 我如何回到 [12, 284]?
  • 第一个符号中的位数是固定的。在标准的 Unix 压缩 LZW 格式中,它是九位。每个后续符号中的位数由前面的数据确定(随着字典的增长而上升),因此在解码下一个符号之前在解压缩端都是已知的。
  • 您可以查看source code for compress了解更多信息。
【解决方案2】:

在他 1984 年关于 LZW 的文章中,T.A.韦尔奇实际上并未说明如何“编码代码”,而是描述了将“输入字符串转换为固定长度的代码”,继续“普遍使用 12 位代码”。 (允许三个八位字节和两个代码之间的双射映射。)
BSD compress(1) command 并没有真正遵循,而是引入了一个标头,有趣的部分是用于编码 LZW 输出代码最大 位数的规范,允许解压器适当地调整解压表的大小,或者以可控的方式提前失败。 (但对于第一个,)代码仅使用必要的整数位数进行编码,从 9 开始。
另一种方法是使用Arithmetic Coding尤其是如果使用不同于每个代码的模型都同样可能

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 2021-03-30
    • 2013-02-03
    • 1970-01-01
    • 2013-10-29
    • 2021-12-10
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    相关资源
    最近更新 更多