如何压缩 .GIF 文件的 LZW 编码图像数据?

How do you compress image data for LZW encoding for .GIF files?

我无法理解如何压缩 .gif 文件的 89a specification 图像数据。比如说我正在尝试制作一个 3x2 .GIF。让我构造一个示例颜色代码 table 并演练一个 [我认为正确的] 示例。

Color code | Color
------------------
0          | Brown
1          | Red
2          | Green
3          | Black

我要创建的图像是这样的。

3x2 pixels (6 pixels total)
----------
Br Br Br
Br R  Br

使用 LZW 进行压缩让我完成了这个过程。这是我得到的最终代码table。

Code table
----------
# | code
0 | 0
1 | 1
2 | 2
3 | 3
4 | clear
5 | eoi // end of information
6 | 0 0
7 | 0 0 0
8 | 0 1
9 | 1 0

最终值为 4 0 6 0 1 0 5 这是我的代码。因为我写出了一个代码 0 0 0,这个代码值等于 7,所以我不得不将我的代码大小从 3 > 4 位增加到后续代码。所以,这是我的图像数据的字节(来自我的代码 table)。

100  - 4
000  - 0
110  - 6
0000 - 0
0001 - 1
0000 - 0
0101 - 5

我最终将图像数据编码为

10000100 - 132
00100001 - 33
10100000 - 160
00000000 - 0

最终在我的最终 .gif 文件中看起来像这样(我在与图像数据对应的值两边加上括号)

47 49 46 38 39 61 03 00 02 00 f1 00 00 b9 7a 56    
ff 00 00 00 ff 00 00 00 00 21 ff 0b 4e 45 54 53 
43 41 50 45 32 2e 30 03 01 ff ff 00 21 f9 04 04 
64 00 00 00 2c 00 00 00 00 03 00 02 00 00 [02 04     
84 21 a0 00 00] 3b 

// Explanation
02 - Minimum LZW code size
04 - Data sub-block of 4 bytes
84 - 132 in decimal
21 - 33 in decimal
a0 - 160 in decimal
00 - 0 in decimal
00 - Termination byte

我的图像看起来像这样(为什么这里是绿色而不是红色?)。我把图像放大了,因为 2x3 像素有点难以阅读。

有什么基本的东西是我遗漏的吗?感谢你花时间和我一起看看这个。

发现错误,出在压缩LZW图像数据时的代码大小。

当您在使用 LZW 压缩图像数据时创建代码 table 时,您需要在添加等于 2^(代码大小)的代码时增加代码大小。因此,我没有在添加代码 7 | 0 0 0 后将代码大小增加一(如上面的 table 所示),而是需要在添加 8 | 0 1 后将代码大小增加一(因为8 = 2^(代码大小 == 3)).

这是通过增加代码大小来改变图像数据的方式

100  - 4
000  - 0
110  - 6
000  - 0
0001 - 1
0000 - 0
0101 - 5

然后,生成的图像数据字节发生了怎样的变化。

10000100 - 132
00010001 - 17
01010000 - 80

我将数据放在方括号中以显示与完整 .gif 数据的比较,以显示发生的变化(应用修复后)。这与上面的 .gif 文件相同。

47 49 46 38 39 61 03 00 02 00 f1 00 00 b9 7a 56 
ff 00 00 00 ff 00 00 00 00 21 ff 0b 4e 45 54 53
43 41 50 45 32 2e 30 03 01 ff ff 00 21 f9 04 04
64 00 00 00 2c 00 00 00 00 03 00 02 00 00 [02 03
84 11 50 00] 3b 

// Explanation
02 - Minimum LZW code size
03 - Data sub-block of 3 bytes
84 - 132 in decimal
11 - 17 in decimal
50 - 80 in decimal
00 - Termination byte