LZW 算法 variable-length 解码过程的问题
Issues with LZW algorithm variable-length decoding procedure
设置
假设我有:
位图的 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-compressed、variable-length-encoded 字节流(包括 LZW 代码大小 header 和 sub-block 标记),表示相同的数字序列:
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
和 8
的 initial code width
。
问题
我正在尝试从字节流中导出初始数字序列(整数数组)。
根据我的阅读,这里的过程是获取 initial code width
,扫描 right-to-left,一次读取 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)
代码宽度应该增加了一个
问题
我怎么知道在读取 variable-length-encoded 字节流时何时增加代码宽度?我是否拥有解压缩此字节流所需的所有必要信息?我在概念上是否遗漏了什么?
更新:
经过与 greybeard 的长时间讨论 - 我发现我错误地读取了二进制字符串:00000000 00000011 00
应被解释为 256, 1
。字节流不是读作big-endian。
粗略地说,如果你正在解码一个字节流,你会在每次读取 2^N-1 个代码时增加读取的位数,其中 N 是当前代码宽度。
解压缩,您应该以与压缩器大致相同的方式构建字典。您知道一旦压缩器 可能 使用对于当前宽度来说太宽的代码,您就需要增加代码宽度。
只要词典未满(未分配最大代码),就会为每个(常规)代码分配一个新代码(不是 Clear Code或信息结束代码)。
对于您 link 编辑的 presentation 中的示例,当第二个 6
为 "transmitted" 时分配 8
- 您需要切换到在读取下一个代码之前四位。
(这是示例与您的 series of numbers
不同的地方 - link 表示 4, 1, 6, 6, 2, 9
。)
设置
假设我有:
位图的 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-compressed、variable-length-encoded 字节流(包括 LZW 代码大小 header 和 sub-block 标记),表示相同的数字序列:
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
和
8
的initial code width
。
问题
我正在尝试从字节流中导出初始数字序列(整数数组)。
根据我的阅读,这里的过程是获取 initial code width
,扫描 right-to-left,一次读取 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)
代码宽度应该增加了一个
问题
我怎么知道在读取 variable-length-encoded 字节流时何时增加代码宽度?我是否拥有解压缩此字节流所需的所有必要信息?我在概念上是否遗漏了什么?
更新:
经过与 greybeard 的长时间讨论 - 我发现我错误地读取了二进制字符串:00000000 00000011 00
应被解释为 256, 1
。字节流不是读作big-endian。
粗略地说,如果你正在解码一个字节流,你会在每次读取 2^N-1 个代码时增加读取的位数,其中 N 是当前代码宽度。
解压缩,您应该以与压缩器大致相同的方式构建字典。您知道一旦压缩器 可能 使用对于当前宽度来说太宽的代码,您就需要增加代码宽度。
只要词典未满(未分配最大代码),就会为每个(常规)代码分配一个新代码(不是 Clear Code或信息结束代码)。
对于您 link 编辑的 presentation 中的示例,当第二个 6
为 "transmitted" 时分配 8
- 您需要切换到在读取下一个代码之前四位。
(这是示例与您的 series of numbers
不同的地方 - link 表示 4, 1, 6, 6, 2, 9
。)