gif
图片格式解析
飘飘白云
整理
参考
:
网络中文gif资料
简介:
GIF(Graphics Interchange Format)
是
CompuServe
公司
开发
的
图
像文件存
储
格式,
1987
年
开发
的
GIF
文件格式版本号是
GIF87a
,
1989
年
进
行了
扩
充,
扩
充后的版本号定
义为
GIF89a
。
GFI
图
像文件以数据
块
(block)
为单
位来存
储图
像的相
关
信息。一个
GIF
文件由表示
图
形
/
图
像的数据
块
、数据子
块
以及
显
示
图
形
/
图
像的控制信息
块组
成,称
为
GIF
数据流
(Data Stream)
。数据流中的所有控制信息
块
和数据
块
都必
须
在文件
头
(Header)
和文件
结
束
块
(Trailer)
之
间
。
GIF
文件格式采用了
LZW(Lempel-Ziv Walch)
压缩
算法来存
储图
像数据,定
义
了允
许
用
户为图
像
设
置背景的透明
(transparency)
属性。此外,
GIF
文件格式可在一个文件中存放多幅彩色
图
形
/
图
像。如果在
GIF
文件中存放有多幅
图
,它
们
可以像演幻灯片那
样显
示或者像
动
画那
样
演示。
GIF
语
法
.
语
法是用来表达序列的一
种
符号形式,并用
这
个表达序列中的一些
对
象来形成更大的
对
象。
语
法也用于表达在
给
定的位置出
现对
象的数目。在此
给
出的
语
法用来
说
明形成
gif
数据流的
块
序列,用一些
规则
列表来表达。下面列出用于
gif
语
法的符号定
义
。
图
例
: <>
语
法
词
::=
符号定
义
* 0
个或更多的事件
发
生
+ 1
个或更多的事件
发
生
|
替代元素
[]
可
选
元素
gif
语
法的符号定
义
:
<GIF
数据流
> ::=
头
部
<
逻辑视
屏
> <
数据
>*
尾
记录
这
个
规则
将
<Gif
数据流
>
实
体定
义
如下。它必
须
以
头
部
开
始,
头
部后面接一个
逻辑视
屏
实
体,
该实
体
药
用其他
规则
来定
义
。最后,数据
实
体接
结
束符。数据
实
体后面的
*
表示数据
实
体可以在此位置出
现
0
或多次。
语
法
:
<Gif
数据流
> ::=
头
部
<
逻辑视
屏
> <
数据
>*
尾
记录
<
逻辑视
屏
> ::=
逻辑视
屏描述
块
[
全局色表
]
<
数据
> ::= <
成象
块
> |<
特殊用途
块
>
<
成象
块
> ::= [
图
象控制
扩
充
] <
成象
块
>
<
成象
块
> ::= <
基于表的
图
象
> |
纯
文本
扩
充
< 基于表的 图 象 > ::= 图 象描述符 [ 局部色表 ] 图 象数据
< 特殊用途 块 > ::= 应 用 扩 充 | 注 释扩 充
< 基于表的 图 象 > ::= 图 象描述符 [ 局部色表 ] 图 象数据
< 特殊用途 块 > ::= 应 用 扩 充 | 注 释扩 充
gif
数据流中的数据
块
可以分
为
三
组
:控制
块
、成象
块
和特殊用途
块
。
控制
块
,如:
头
部、
逻辑视
屏描述
块
、
图
像控制
扩
充和尾
记录
,包含用于控制
处
理数据流或
设
置硬件参数的信息。
成像
块
,如:
图
像描述符和
纯
文本
扩
充,包含用于在
显
示
设备
上成像的信息和数据。
特殊用途
块
,如:注
释扩
充和
应
用
扩
充,包含那些既不用于
处
理数据流也不用于在
显
示
设备
上成象的信息。
除了
逻辑视
屏描述
块
和全局色表之外,特殊用途
块
的作用域是整个数据流,而其他控制
块
的作用域是有限的,
仅
限于
对
他
们
后面的成象
块
起作用。特
殊用途
块
不
对
任何控制
块
构成限制,它
对
于解
码过
程来
说
是透明的。成象
块
及
扩
充用于控制
块
及
扩
充的作用域限定。
块
的
标记
分
为
三段:除尾
记录
0x3b
之外,
0x00
~
0x7f
用于成象
块
;0x80
~
0xf9
用于控制
块
;
0xfa
~
0xff
用于特殊用途
块
。解
码
器通
过识别块标记
来
处
理
块
的作用域。
解释
:
色表
- gif
格式利用色表来
显
示基于光
栅
的
图
像。色表分
为
全局色表和局部色表。全局色表
对
于那些没有
设
置局部色表的
图
像起作用。全局色表的作用域是整个数据流。局部色表
对
于
紧
接在其后的
单张图
像起作用。
这
两
种
色表都是可
选
的。
/*
全局色表这东西是我们感兴趣的东西
,
它有点像
png
格式定义种的调色板
,
如果要修改
gif
图片的颜色
,
哈哈
,
修改这个全局色表就可以
.
如果有全局色表块
,
那么它一定从
gif
流的
14
个字节开始
(
头部
6
个
+
逻辑视频描述块
7
个
)
。
*/
以下是各数据块的说明
,
如果注明为版本
89a
的话
,
则说明这个数据块不会在
87a
版的协议中出现
.
头
部
(6
个字节
)
标识
符
(
3
字
节
) ---GIF
版本
(
3
字
节
)
---
87a (or 89a)
逻辑视
屏描述
块
逻辑
屏幕
宽
(
2
字
节
)
逻辑
屏幕高
(
2
字
节
)
Packed Fields
(
1
字
节
)
背景色索引
(
1
字
节
)
象素高
宽
比
(
1
字
节
)
Packed Fields
说明
:
全局色表
标
志
1 Bit
颜
色方案
3 Bits
短
标
志
1 Bit
全局色表尺寸
3 Bits
解释
:
背景
颜
色索引
-
为
背景
颜
色指向全局色表。背景
颜
色是指那些没有背
图
像覆盖的
视
屏部分的
颜
色。若全局色表
标
志位置
为
0
,
则该
字段也被
值
0
,并且被忽略。
象素高
宽
比
-
用于
计
算原
图
像中像素的近似高
宽
比。如果
该
字段的
值为
非
0
,
则
象素的高
宽
比由下面的公式
计
算
:
高
宽
比
= (
象素高
宽
比
+ 15) / 64
该
字段的取
值
范
围
从最
宽
的比
值
4
:
1
到最高的比
值
1
:
4
,
递
增的
步
幅
为
1/64
。
取 值 : 0 - 没有比 值 , 1 ~ 255 - 用于 计 算的 值 。
取 值 : 0 - 没有比 值 , 1 ~ 255 - 用于 计 算的 值 。
全局色表
标
志
-
指示有没有全局色表,如果
该标
志位置
1
,
则
全局色表会
紧
接在
该块
之后出
现
。
该
位也用于解
释
是否
选
用背景
颜
色索引字段。若
该
位置
1
,
则
背景
颜
色索引字段的
值
将指向背景
颜
色表。
色彩方案
-
提供
给
原始
图
像的
每
个
颜
色的位数减
1
。
这
个
值
代表
图
像中所使用的整个
调
色板的大小,而不是
图
像中所使用的
颜
色的数量。例如,若
该
字段的
值为
3
,
则图
像中所使用的
调
色板的
每
个色
值
占
4
位。
短
标
志
-
表明全局色表是否被排序。如果
该
位置
1
,
则
全局色表按照重要性
递
减的原
则进
行了排序。典型地,是按照
颜
色的使用
频
度
进
行
递
减排序,使用
频
度最高的
颜
色排在色表的最前面。
这样
便可帮助解
码
器
选择
最好的
颜
色子集来成象。
全局色表的尺寸
-
如果全局色表
标
志位置
1
,
则该
字段的
值记录
全局色表中所占用的字
节
数。
全局色表
该块
包含一个按照字
节顺
序表示
红
-
绿
-
蓝
三元色的色表。全局色表用于那些没有局部色表
的
图
像和
纯
文本
扩
充。在
逻辑视
屏描述
块
中的全局色表
标
志位置
1
时
表示有全局色表。全局色表
紧
接在
逻辑视
屏描述
块
之后,占用的字
节
数
为
:
3*2^
(全局色表尺寸
+1
)
数据组成格式为:
Red 0
Green 0
Blue 0
……
Red n
Green n
Blue n
图
像控制
扩
充
(
版本
-89a)
图
像控制
扩
充包含在
处
理一个成象
块时
所需的参数。
扩
充只包括一个数据子
块
。
该块
是可
选
的。通常只有一个
图
像控制
扩
充在成象
块
之前。
这
也是在一个数据流中
对
成象控制
扩
充的唯一限制。
数据组成格式为:
扩
充
导
入符
(
1
字
节
)
图
象控制
标记
(
1
字
节
)
块
尺寸
(
1
字
节
)
<Packed Fields>
延
长时间
(
2
字
节
)
透明
颜
色索引
(
1
字
节
)
块结
束
(
1
字
节
)
Packed Fields
说明
:
保留
3 Bits
配置方法
3 Bits
用
户输
入
标
志
1 Bit
透明
颜
色
标
志
1 Bit
解释
:
扩
充引入
-
用于
识别
一个
扩
充
块
的
开
始,
该
字段
为
固定
值
0x21
。
图
像控制
标
号
-
识别
当前
块
是否
为图
形控制
扩
充。
该
字段
为
固定
值
0xF9
。
块
尺寸
-
块
中所包含的字
节
数。从
块
尺寸字段
开
始到快
结
束符(不含
结
束符)。
该
字段包含固定
值
4
。
配置方法
-
指示
图
像
显
示后的
处
理方法。
值
:
0 -
无指定的配置,解
码
器不需要做任何
处
理。
1 -
不做配
值
。
图
像将被留在原位置。
2 -
恢
复
背景
颜
色。
图
像所占的区域必
须备
恢
复为
背景
颜
色。
3 -
恢
复
以前的
颜
色。解
码
器需要将
图
像区域恢
复为
原来成象的
颜
色。
4-7 -
未定
义
。
用
户输
入
标
志
-
说
明在
继续处
理之前是否需要用
户输
入。可以和
输
入延
时
一起使用。
透明
标
志
-
表明在透明索引字段是否
给
定透明索引。
延
时
-
如果不
为
0,
该
字段指定以
1/100
秒
为单
位的
时
延数。
透明索引
-
如果遇到透明索引,
则显
示
设备
的相
关
象素不被改
变
,
继续处
理下一个象素。
块终
止符
-
这
个
0
长
度字段
标
志着
图
像控制
扩
充得
结
束。
图
像描述符
每
一幅
图
像必
须
在
逻辑视
屏描述
块
中所定
义
的
逻辑视
屏界限之内。
图
像描述符包含
处
理一个基于
图
像的表的必要参数。在
这
个
块
中
给
定的坐
标
是参照
逻辑视
屏的像素坐
标
。
该块
是一个成象
块
,在其前面可以
选择
加上一个或多个控制
块
,如:
图
像控制
扩
充,或者是后面接有局部色表;
图
像描述符后面
总
是
图
像数据。它是一幅
图
所必需的。一幅
图
像
对应
一个
图
像描述符。
数据组成格式为:
图
象分隔符
(
1
字
节
)
图
象左坐
标
(
2
字
节
)
图
象
顶
坐
标
(
2
字
节
)
图
象
宽
度
(
2
字
节
)
图
象高度
(
2
字
节
)
(
2
字
节
)
<Packed Fields>
(
1
字
节
)
Packed Fields
说明
:
局部色表
标
志
1 Bit
隔行
处
理
标
志
1 Bit
短
标
志
1 Bit
保留
2 Bits
局部色表尺寸
3 Bits
解释
:
图
像分隔符
-
用于
识别图
像描述符的
开
始。取固定
值
0x2c
局部色表
该块
包含一个按照
红
-
绿
-
兰
三原色的
顺
序排列的色表。
该
表作用于
紧
跟其后的
图
像
数据
。当局不色表
标
志位置
1
时
,
该
表出
现
,且其后
紧
跟
图
像的描述符,它所包含的字
节
数等于
3*2^
(局部色表尺寸
+1
)
数据组成格式为:
Red 0
Green 0
Blue 0
……
Red n
Green n
Blue n
基于表的
图
像数据
基于表的
图
像数据由一系列子
块组
成,
每
个子
块
最多
255
字
节
,包含一个
为图
中
每
个象素所指定的有效色表的索引。索引的
顺
序用
LZW
算法
进
行
编码
。
数据组成格式为:
LZW
最小
编码
尺寸
(
1
字
节
)
图
象数据
数据子
块
(
n
字
节
)
解释
:
LZW
最小
编码
尺寸
:
该
字
节
用于决定在
图
像数据中用
LZW
编码
最初的位数。
注
释扩
充
(
版本
-89a)
注
释扩
充包含
实际
不属于
gif
数据流的文本信息。它适用于包括
图
像注
释
、描述或者任何其他非控制和非
图
像数据。注
释扩
充将被解
码
器忽略,或者被保留到以后
处
理。在任何情况下注
释扩
充也不能中断
对
数据流的
处
理。
该块
是可
选
的;在数据流中的出
现
量不加限制。
数据组成格式为:
扩
充
导
入符
(
1
字
节
)
注
释标记
(
1
字
节
)
注
释
数据
数据子
块
(
n
字
节
)
块结
束符
(
1
字
节
)
解释
:
扩
充
导
入符
-
标识扩
充的
开
始。
该
字段
为
固定
值
0x21
。
注
释标
号
-
标
示某
块为
注
释扩
充。
该
段
为
固定
值
0xFE
。
注
释
数据
-
按照子
块顺
序,
每
个注
释
最少
1
字
节
最多
255
字
节
。序列
结
尾用
块结
束符
标识
。
块结
束符
-
用来
标识
注
释扩
充的
结
束。
纯
文本
扩
充
(
版本
-89a)
纯
文本
扩
充包括
纯
文本数据和将数据
显
示
为图
像所必需的参数。文本数据将用
7
位可印刷
ASCII
码
字符
编码
。文本数据用在
块
字段中定
义
的
单
元格字符元素来成象。
每
个字符用一个
单
元成象。
该块
使用全局色表。它可以被
图
形控制
扩
充来修改。
该块为
可
选块
。
数据组成格式为:
扩
充
导
入符
(
1
字
节
)
纯
文本
标记
(
1
字
节
)
块
尺寸
(
1
字
节
)
文本格左坐
标
(
2
字
节
)
文本格
顶
坐
标
(
2
字
节
)
文本格
宽
度
(
2
字
节
)
文本格高度
(
2
字
节
)
字符
单
元
宽
度
(
1
字
节
)
字符
单
元
宽
度
(
1
字
节
)
文本前景色索引
(
1
字
节
)
文本背景色索引
(
1
字
节
)
纯
文本数据
数据子
块
(
n
字
节
)
块结
束符
(
1
字
节
)
解释
:
扩
充
导
入符
-
标识
一个
扩
充
块
的
开
始。取固定
值
0x21.
纯
文本
标记
-
标识
当前
块为
原文
扩
充。取固定
值
0x01.
块
尺寸
-
扩
充中的字
节
数,取固定
值
12.
文本格左位置
-
逻辑视
屏的左
边
,用象素表示的左
边
列数,
文本格
顶
位置
-
逻辑视
屏的上
边
,用象素表示的上
边
行数。
原文数据
-
子
块
序列,
每
个子
块
最少
1
字
节
最多
255
字
节
。
该
序列遇到
块结
束符
时结
束。
块结
束符
– 0
,
用来
标
志
块结
束。
应
用
扩
充
(
版本
-89a)
应
用
扩
充包含
应
用
说
明信息;它遵守如下所述的
扩
充
块
的
语
法,
块标记为
0xff.
数据组成格式为:
扩
充
导
入符
(
1
字
节
)
扩
充
标记
(
1
字
节
)
块
尺寸
(
2
字
节
)
应
用
标识
符
(
8
字
节
)
应
用
证
明
码
(
3
字
节
)
应
用数据
数据子
块
(
n
字
节
)
块结
束符
(
1
字
节
)
解释
:
扩
充引入符
-
定
义该块
位
扩
充
块
。取固定
值
0x21.
应
用
扩
充
标记
-
标识该块为应
用
扩
充
块
。取固定
值
0xFF.
块
尺寸
-
指示
该块
中包含的字
节
数。取固定
值
11.
应
用
标识
符
- 8
格可印刷
ASCII
字符用来
标识该应
用所属的
应
用
扩
充。
应
用
证
明
码
- 3
格字
节
的序列用于
证
明
应
用
标识
符。一个
应
用程序可以一
种
算法来
计
算一个二
进
制
码
来唯一地
识别这
个
应
用是否数于
这
个
应
用
扩
充。
尾
记录
该块为
一个
单
字段
块
,用来指示
该
数据流的
结
束。取固定
值
0x3b.