位打包LZW短语编号

时间:2014-04-21 01:09:19

标签: java compression bits lzw

我目前正在研究LZW压缩的java实现。到目前为止,我的编码器工作原理。读取文件并输出将通过管道传送到位打包器的短语编号。

我现在必须将这些短语编号打包到一个文件中,我不确定如何进行此过程。此外,我们为编码设置了最大位数为20.因此,当编码的数字超过编码它们所需的20位时,我们重置trie并开始构建新的trie。

所以我们必须打包的第一组数字将是0-255 然后256-511等等所以我知道有些将被打包为8位然后9位,依此类推。

如果可以提供任何指导,可以从哪里开始,看哪些内容可能会有所帮助

1 个答案:

答案 0 :(得分:2)

LZW压缩通常以比符号大小一位的位数开始。因此,如果符号是8位值,则初始位大小通常为9.这对于字典值0..255和字典中的前256个代码就足够了。通常LZW也有一些特殊的预定义代码,如“清除”代码和“停止”代码,它们作为符号0x100和0x101附加到符号集。它们并非严格要求,但非常有用。

此外,您有一个最大位数来限制字典的增长。在你的情况下,它是20,所以你的字典最多可以容纳1048576个条目。要写入可变长度位代码,可以使用足够宽的寄存器来保存最大位数。在您的情况下,32位或64位无符号整数是合适的。 (如果你的目标是64位处理器,请使用后者。)所以基本上,你保持一个位移计数器,最初设置为0,并将位移位/写入寄存器直到它溢出。然后将整个寄存器写入流并移位/复制剩余的位。最后,您必须将寄存器中的最新位刷新到流中,如果有的话。

真的很容易。您不需要任何特殊的位计数处理,因为LZW读写器就何时增加位数达成了一致。一些LZW实现(例如TIFF 6.0)在编写适合旧大小的最后一个代码之前增加了计数(所谓的“早期更改”)。其他人(例如GIF)在后期增加它,这更有效。您可以自由选择您编写的符号的位顺序。只需要编码器和解码器就此达成一致。再一次,现有的LZW实现使用不同的位顺序:GIF将它们从最不重要的写入到最重要的,反之亦然。 LSB-to-MSB变体通常更容易实现。

请注意,这是一个常见的误解,即字典需要在字典填满后立即清除。实际上,我发现LZW压缩在大多数情况下要好得多,如果你只是继续填充目录,直到最后发出最大宽度代码。这是因为字典现在反映了输入流的统计分布并发出了有效的代码。只有当分布随时间发生显着变化时才需要明确,因此字典变得不充分。

GIF和TIFF的常见LZW解码器会在字典填满后自动清除字典,而不是等待清除代码。这是“坏习惯”,甚至在最近的GIF规范附带的注释中明确弃用,但是,如果想要与所有读者兼容,编码器不应该使用清晰的代码进行赌博。