algorithm - 解析 GIF 栅格数据 - LZW

标签 algorithm gif decoding lzw

我一直在尝试在 PHP 中解压缩 GIF,似乎除了 LZW 解压缩之外的所有内容。我已保存显示的图像:sample image

这张图片是 3 x 5 的:

Blue  Black Black
Black Blue  Black
Black Black Black
White White White
White White White

我决定用二进制手动检查并解析这个文件。人工解析结果如下。我仍然不知道如何在这里解码栅格数据。有人可以分解栅格数据如何变成图像吗?我已经能够分解一张图片,但没有别的(不是这张图片)。我已经发布了我对这应该如何分解的理解,但我显然做错了。

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

我的尝试

10000100
01101110
00100111
11000001
01011101

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

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

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

我一直在使用的资源:

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

最佳答案

GIF 解析器

您说您想编写自己的 GIF 解析器以了解其工作原理。我建议您查看任何包含 GIF 阅读器的库的源代码,例如实际引用实现 GIFLIB .相关的源文件是dgif_lib.c ;开始at slurp用于解码,或跳转到 LZW decompression implementation .

这是您的图像解码方式。

我认为问题在于您错误地将输入字节拆分为 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

现在,GIF packs LZW codes into bytes in LSB-first order.因此,第一个代码存储为第一个字节的 3 个最低有效位;第二个代码为接下来的3位;等等。在您的示例中(第一个字节:0x84 = 10000100),因此前两个代码是 100(清除)和 000(蓝色)。整个事情

01011101 11000001 00100111 01101110 10000100

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

0101 1101 1100 0001 0010 0111 0110 111 010 000 100

解码为:

     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
...

因此输出开始(换行到 3 列):

blue  black black
black blue  black
black black ...

这就是你想要的。

关于algorithm - 解析 GIF 栅格数据 - LZW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203731/

相关文章:

algorithm - 多边形的对角线是在里面还是在外面?

algorithm - 什么是 "d-smooth sequences?"

ios - UIImagePickerController 无法正确显示 GIF

python - 如何解决这个奇怪的Python编码问题?

algorithm - 如何从任意大的任意基数转换为另一个

algorithm - 从大列表中获取最大的 n 个元素时应该使用哪种算法?

python - Google appengine 将本地 gif 作为电子邮件附件发送

image - 动画 GIF - 避免存储重复的帧两次

javascript - 如何在 javascript 中处理可能的 HTML 编码值

java - Php 编码 - Java 解码(URL 部分)