解析GIF栅格数据 - LZW

tey*_*non 9 algorithm gif decoding lzw

我一直在尝试用PHP解压缩GIF,并且似乎除了LZW减压之外还有其他一切.我保存了一张显示的图片:样本图像

这张图片是3 x 5像这样:

Blue  Black Black
Black Blue  Black
Black Black Black
White White White
White White White
Run Code Online (Sandbox Code Playgroud)

我决定在Binary中手动完成并解析此文件.手动解析的结果如下.我仍然坚持如何在这里解码栅格数据.有人可以分解栅格数据如何成为图像吗?我已经能够分解一个图像,但没有别的(不是这个图像).我已经发布了我应该如何分解的理解,但我显然做错了.

01000111 G
01001001 I
01000110 F
00111000 8
00111001 9
01100001 a

Screen Descriptor
WIDTH
00000011 3
00000000

00000101 5
00000000

10010001 GCM (1), CR (001), BPP (001), CD = 2, COLORS = 4

00000000 BGCOLOR Index

00000000 Aspect Ratio

GCM
BLUE
00110101 | 53
00000000 | 0
11000001 | 193

WHITE
11111111 | 255
11111111 | 255
11111111 | 255

BLACK
00000000 | 0
00000000 | 0
00000000 | 0

00000000 | 0
00000000 | 0
00000000 | 0

Extension
00100001 | 21
Function Code
11111001 | F9
Length
00000100 | 4
00000000
00000000
00000000
00000000
Terminator
00000000

Local Descriptor
00101100 Header
XPOS
00000000 | 0
00000000

YPOS
00000000 | 0
00000000

Width
00000011 | 3
00000000

Height
00000101 | 5
00000000

Flags
00000000 (LCM = 0, Interlaced = 0, Sorted = 0, Reserved = 0, Pixel Bits = 0)

RASTER DATA
Initial Code Size
00000010 | 2
Length
00000101 | 5

Data
10000100
01101110
00100111
11000001
01011101

Terminator
00000000

00111011 | ;
00000000
Run Code Online (Sandbox Code Playgroud)

我的尝试

10000100
01101110
00100111
11000001
01011101
Run Code Online (Sandbox Code Playgroud)

初始代码大小= 3一次读取2位

10
00
Append last bit to first (010)
String becomes 010 or 2. 2 would be color # 3 or BLACK
Run Code Online (Sandbox Code Playgroud)

在这一点上,我已经错了.第一种颜色应该是蓝色.

我一直在使用的资源:

http://www.daubnet.com/en/file-format-gif http://en.wikipedia.org/wiki/Graphics_Interchange_Format http://www.w3.org/Graphics/GIF/spec-gif87.txt

Mec*_*ail 13

GIF解析器

你说你想编写自己的GIF解析器,以了解它是如何工作的.我建议你查看任何包含GIF阅读器的库的源代码,例如事实上的参考实现GIFLIB.相关的源文件是dgif_lib.c; 开始slurp用于解码,或跳转到LZW压缩的实现.

这是您的图像解码方式.

我认为问题在于您错误地将输入字节拆分为LZW代码.

颜色数量是(0b001 + 1) * 2 = 4.

代码大小从2 + 1 = 3位开始.

所以最初的字典是

000 = color 0 = [blue]
001 = color 1 = [white]
010 = color 2 = [black]
011 = color 3 = [black]
100 = clear dictionary
101 = end of data
Run Code Online (Sandbox Code Playgroud)

现在,GIF将LZW代码以LSB优先顺序打包成字节.因此,第一代码被存储为第一字节的3个最低有效位; 第二个代码作为接下来的3位; 等等.在您的示例中(第一个字节:0x84= 10000100),前两个代码因此100(清除)和000(蓝色).整个东西

01011101 11000001 00100111 01101110 10000100
Run Code Online (Sandbox Code Playgroud)

被分成代码(在读取最高3位代码后切换到4位组111),如

0101 1101 1100 0001 0010 0111 0110 111 010 000 100
Run Code Online (Sandbox Code Playgroud)

这解释为:

     last
code code
 100      clear dictionary
 000      output [blue] (1st pixel)
 010  000 new code in table:
              output 010 = [black]
              add 110 = old + 1st byte of new = [blue black] to table
 111  010 new code not in table:
              output last string followed by copy of first byte, [black black]
              add 111 = [black black] to table
              111 is largest possible 3-bit code, so switch to 4 bits
0110 0111 new code in table:
              output 0110 = [blue black]
              add 1000 = old + 1st byte of new = [black black blue] to table
0111 0110 new code in table:
              output 0111 = [black black]
              add 1001 = old + 1st byte of new = [blue black black] to table
...
Run Code Online (Sandbox Code Playgroud)

所以输出开始(包装到3列):

blue  black black
black blue  black
black black ...
Run Code Online (Sandbox Code Playgroud)

这就是你想要的.