LZW算法可变长度解码过程的问题

时间:2016-12-21 16:41:34

标签: algorithm language-agnostic lzw

设置

说我有:

  • LZW压缩位图产生的一系列数字:

    256 1 258 258 0 261 261 259 260 262 0 264 1 266 267 258 2 273 2 262 259 274 275 270 278 259 262 281 265 276 264 270 268 288 264 257
    
  • LZW压缩,可变长度编码的字节流(包括LZW代码大小标题和子块标记),代表同一系列数字:

    00001000 00101001 00000000 00000011 00001000 00010100 00001000 10100000 
    01100000 11000001 10000001 00000100 00001101 00000010 01000000 00011000 
    01000000 11100001 01000010 10000001 00000010 00100010 00001010 00110000 
    00111000 01010000 11100010 01000100 10000111 00010110 00000111 00011010 
    11001100 10011000 10010000 00100010 01000010 10000111 00001100 01000001 
    00100010 00001100 00001000 00000000
    
  • initial code width 8

问题

我正在尝试从字节流派生初始数字序列(整数数组)。

根据我的阅读,这里的过程是采用initial code width,从右向左扫描,一次读取initial code width + 1位,从字节流中提取整数。 例如

iteration #1:   1001011011100/001/    yield return 4
iteration #2:   1001011011/100/001    yield return 1
iteration #3:   1001011/011/100001    yield return 6
iteration #4:   1001/011/011100001    yield return 6

此过程不适用于迭代#5,它将产生1:

iteration #5:   1/001/011011100001    yield return 1 (expected 9)

代码宽度应该增加一个。

问题

在读取可变长度编码的字节流时,我怎么知道何时增加代码宽度?我是否拥有解压缩此字节流所需的所有必要信息?我在概念上遗漏了什么吗?

UPDATE:

经过与greybeard的长时间讨论后 - 我发现我正在错误地读取二进制字符串:00000000 00000011 00将被解释为256, 1。字节流读取为big-endian。

粗略地说,如果要解码字节流,每次读取2 ^ N-1个代码时,都会增加读取的位数,其中N是当前代码宽度。

1 个答案:

答案 0 :(得分:2)

解压缩,您应该以与压缩器大致相同的方式构建字典。您知道,一旦压缩器 使用的代码对于当前宽度来说太宽,您就需要增加代码宽度。

只要字典未满(未分配最大代码),就会为每个(常规)代码分配一个新代码(清除代码或信息结束代码)。

使用您链接的presentation中的示例,在第二个8被“传输”时分配6 - 您需要在读取下一个代码之前切换到4位。 / p>

(这是示例和您的series of numbers不同之处 - 链接显示为4, 1, 6, 6, 2, 9。)