LZW编码和GIF文件格式

时间:2015-01-05 22:57:19

标签: c++ gif lzw

我正在尝试了解如何在C ++中创建.gif文件。到目前为止,我认为除了LZW编码的工作原理外,我理解了所有内容。这是我用标签生成的文件:

47 49 46 38 39 61 -header
0A 00 01 00 91 00 -logical screen descriptor
00 00 FF 00 FF 00 -color table [green,red,yellow,black]
00 FF FF 00 00 00
00 21 F9 04 00 00 -graphics control extension
00 00 00 2C 00 00 -image descriptor
00 00 0A 00 01 00 -(10 pixels wide x 1 pixel tall)
00 02 04 8A 05 00 -encoded image
3B                -terminator

此处再次没有用于复制/粘贴目的的标签:47 49 46 38 39 61 05 00 04 00 91 00 00 00 FF 00 FF 00 00 FF FF 00 00 00 00 21 F9 04 00 00 00 00 00 2C 00 00 00 00 0A 00 01 00 00 02 04 8A 05 00 3B

我在理解02 04 8A 05如何转换为图片yryryggyry方面遇到了很多麻烦。我知道02是最小代码大小,04是图像块的长度,我想我已经确定了清晰的EOI代码,但我不知道理解中间的代码。

8A       05
10001010 00000101
100|01010 00000|101
 ^      ????     ^
 clear code      EOI code

到目前为止,我从.gif规范中获得了最多的信息: http://www.w3.org/Graphics/GIF/spec-gif89a.txt

这个网站也很有帮助: http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp

由于

编辑*

我观看了评论中链接的Youtube视频,并手动为彩色流“yryryggyry”编码图像:

Color table-012=gry

2   1   2   1   2   0   0   2   1   2
010 001 010 001 010 000 000 010 001 010

current next output dict
010     001  010    21 6
001     010  001    12 7
010     001  -      -
001     010  110    121 8
010     000  010    212 9
000     000  000    00  10
000     010  1010   002 11
010     001  -      -
001     010  110    -
010     -    010    -

outputs-100 010 001 110 010 000 1010 110 010 101

01010101 4th 55
10101000 3rd A8
00101100 2nd 2C
01010100 1st 54

Code-54 2C A8 55

我一定是犯了一个错误,因为这段代码生成的图像是“yr”而不是“yryryggyry”

我将尝试重做工作,看看我是否得到了不同的答案

1 个答案:

答案 0 :(得分:1)

也许你在第4行犯了一个错误:     001 010 110 121 8

在第3行," 010"被忽略,所以你必须先将它添加到第4行。 在第4行,它来到:

current  next  output    dict
010 001  010   010 001   212   8

这是我的解决方案(也是手动创建的):

LZW for yryryggyry

更新

终于找到了原因:

  

编码数据时,只要写出等于2 ^(当前代码大小)-1的代码,就会增加代码大小。如果要从代码解码到索引,则需要在将代码值(等于2 ^(当前代码大小)-1)添加到代码表时立即增加代码大小。也就是说,下次你抓住下一部分时,再抓一个。

作者意味着当你要输出2 ^(当前代码大小) - 1时你应该增加你的单词大小,但是可能有一个不同的解释似乎也是合理的:

  

当您将#(2 ^当前代码大小)项添加到代码表时,下一个输出应该增加其字大小。

在作者的例子中也是正确的,这是我更喜欢的解释。

这是你的榜样(" yryryggyry"):

output sequence:
    #4 #2 #1 #6 #2 #0 #0 #8 #5

当您即将输出#6时,您需要添加" yry"进入代码表,索引为#8。

由于8 = 2 ^当前字大小

(current word size = 2(original) + 1(reserved) = 3)

下一个输出应该增加字长,所以#2变成4位字。

最终输出序列是:

4   100
2   010
1   001
6   110
2   0010
0   0000
0   0000
8   1000
5   0101

编码后,它们变为

54 2C 00 58

所以数据块是

02            -minimum word size     
04            -data length
54 2c 00 58   -data
00            -data block terminator