GIF文件格式表
GIF文件格式表
地狱门神(F.R.C.)整理
数据区 |
数据块 |
数据 |
数据类型 |
长度 |
描述 |
样例数据 |
Header DA |
Info DB |
Identifier |
String |
6 |
标志符,GIF87a或GIF89a |
47494638 3961(GIF89a) |
Width |
Int16 |
2 |
宽度 |
4000 |
||
Height |
Int16 |
2 |
高度 |
4000 |
||
Global Color Table Flag |
Bit |
1 Bit |
当置位时表示有全局调色板 |
12 |
||
Bits Per Pixel |
Bit |
3 Bit |
Bits Per Pixel + 1 表示色深 |
1112 |
||
Sort Flag |
Bit |
1 Bit |
分类标志,不用,置0 |
02 |
||
Global Color Table Size |
Bit |
3 Bit |
2^(Global Color Table Size + 1)表示全局调色板大小 |
1112 |
||
Background Color |
Byte |
1 |
背景色索引(在全局颜色列表中的,如果没有全局颜色列表,该值没有意义) |
00 |
||
Pixel Aspect Radio |
Byte |
1 |
不用,固定为0 |
00 |
||
Global Palette DB |
Red |
Byte |
1 |
索引0的红色分量 |
00 |
|
Green |
Byte |
1 |
索引0的绿色分量 |
00 |
||
Blue |
Byte |
1 |
索引0的蓝色分量 |
00 |
||
数量为2^(Global Color Table Size + 1) |
||||||
Data DA |
Image DB / Control DB |
|
|
|
图像块,以0x2C开始 / 控制块,以0x21开始 |
|
多个 |
||||||
Trailer DA |
|
Trailer |
Byte |
1 |
终结器,固定为0x3B |
3B |
图象块
数据块 |
小数据块 |
数据 |
数据类型 |
长度 |
描述 |
样例数据 |
Image DB |
Info Sub-DB |
Introducer |
Byte |
1 |
固定为0x2C |
2C |
Offset X |
Int16 |
2 |
X方向偏移量,通常取0 |
00 |
||
Offset Y |
Int16 |
2 |
Y方向偏移量,通常取0 |
00 |
||
Width |
Int16 |
2 |
宽度 |
4000 |
||
Height |
Int16 |
2 |
高度 |
4000 |
||
Local Color Table Flag |
Bit |
1 Bit |
当置位时表示有局部调色板 |
12 |
||
Interlace Flag |
Bit |
1 Bit |
交织标志,置位时图象数据使用交织方式排列,否则使用顺序排列。
交织图象按下面的方法处理光栅数据: 创建四个通道保存数据,每个通道提取不同行的数据:
下面的例子演示了提取交织图象数据的顺序: 0 ------------------- 1 1 ------------------- 4 2 ------------------- 3 3 ------------------- 4 4 ------------------- 2 5 ------------------- 4 6 ------------------- 3 7 ------------------- 4 8 ------------------- 1 9 ------------------- 4 10 ------------------- 3 11 ------------------- 4 12 ------------------- 2 13 ------------------- 4 14 ------------------- 3 15 ------------------- 4 16 ------------------- 1 17 ------------------- 4 18 ------------------- 3 19 ------------------- 4 |
12 |
||
Sort Flag |
Bit |
1 Bit |
分类标志,不用,置0 |
02 |
||
Reserved |
Bit |
2 Bit |
保留,固定为0 |
002 |
||
Local Color Table Size |
Bit |
3 Bit |
2^(Local Color Table Size+1)表示局部调色板大小 |
1112 |
||
Local Palette Sub-DB |
||||||
Red |
Byte |
1 |
索引0的红色分量 |
00 |
||
Green |
Byte |
1 |
索引0的绿色分量 |
00 |
||
Blue |
Byte |
1 |
索引0的蓝色分量 |
00 |
||
当Local Color Table Flag置位时才存在,数量为2^(Local Color Table Size + 1) |
||||||
LZW Data Sub-DB |
Start Code Size |
Byte |
1 |
LZW编码初始码表大小的位数,通常就等于图象的色深。但单色图像不能为1,必须为2或以上 |
08 |
|
Data Size |
Byte |
1 |
后面数据的长度,通常最大为0xFE |
FE |
||
Data |
Byte |
Data Size |
LZW编码数据 |
|
||
Data Length和Data不断重复,直到遇到终结器,所有的Data串联起来组成LZW编码数据流 |
||||||
Block Terminator |
Byte |
1 |
块终结器,固定值0 |
00 |
图形扩展控制块(需要GIF89a)
数据块 |
数据 |
数据类型 |
长度 |
描述 |
样例数据 |
Graphic Control Extension DB |
Extension Introducer |
Byte |
1 |
标识这是一个扩展块,固定为0x21 |
21 |
Graphic Control Label |
Byte |
1 |
标识这是一个图形控制扩展块,固定为0xF9 |
F9 |
|
Block Size |
Byte |
1 |
不包括块终结器,固定值4 |
04 |
|
Reserved |
Bit |
3 Bit |
保留,固定为0 |
0002 |
|
Disposal Method |
Bit |
3 Bit |
处置方法:指出处置图形的方法,当值为: |
0002 |
|
Use Input Flag |
Bit |
1 Bit |
用户输入标志:指出是否期待用户有输入之后才继续进行下去,置位表示期待,值否表示不期待。用户输入可以是按回车键、鼠标点击等,可以和延迟时间一起使用,在设置的延迟时间内用户有输入则马上继续进行,或者没有输入直到延迟时间到达而继续 |
02 |
|
Transparent Color Flag |
Bit |
1 Bit |
透明颜色标志:置位表示使用透明颜色 |
12 |
|
Delay Time |
Int16 |
2 |
延迟时间,单位1/100秒,如果值不为1,表示暂停规定的时间后再继续往下处理数据流 |
2800 |
|
Transparent Color Index |
Byte |
1 |
透明色索引 |
00 |
|
Block Terminator |
Byte |
1 |
块终结器,固定值0 |
00 |
其他控制块(需要GIF89a,由于基本不用,不再列出,可参见[1])
数据块 |
数据 |
数据类型 |
长度 |
描述 |
样例数据 |
Graphic Control Extension DB |
Extension Introducer |
Byte |
1 |
标识这是一个扩展块,固定为0x21 |
21 |
Control Label |
Byte |
1 |
标识这是一个什么控制扩展块: 0x01 - 图形文本扩展块 0xFE - 注释块 0xFF - 应用程序扩展块 |
FE |
|
Data Size |
Byte |
1 |
后面数据的长度,通常最大为0xFE |
FE |
|
Data |
Byte |
Data Size |
数据 |
|
|
Data Length和Data不断重复,直到遇到终结器 |
|||||
Block Terminator |
Byte |
1 |
块终结器,固定值0 |
00 |
注意:
1、所有的整数数据类型都是little-endian的。所有字节内部数据均以上为高位,下为低位,如(abbbcddd)2是按a、bbb、c、ddd的顺序表示的。
2、压缩方法:可变长LZW压缩算法(Variable-Length_Code Lempel Ziv Walch Compression)。
[1]等文档此处讲述不太清楚,有误导的嫌疑。为方便起见,在此列出伪码,以供参考,其中:
StartCodeSize表示LZW编码长度的初始大小。
ClearCode表示初始化一个编译表,Clear Code + 1表示编码数据流的结束。
ReadSrc、WriteSrc、ReadTar、WriteTar分别表示读取原数据流、写入原数据流、读取编码数据流、写入编码数据流。
原数据流是字节流,而编码数据流是可变长度流,需要编译成固定的8-bit长度的字符流,编译顺序是从右往左。
下面是一个具体例子:编译5位长度编码到8位字符
0 | b | b | b | a | a | a | a | a |
1 | d | c | c | c | c | c | b | b |
2 | e | e | e | e | d | d | d | d |
3 | g | g | f | f | f | f | f | e |
4 | h | h | h | h | h | g | g | g |
... | ||||||||
N |
Function LZW(ByVal SrcBytes As Char()) As Char()
TarBytes = New List(Of Char)()
CodeSize = StartCodeSize
SrcPos = 0
TarPos = 0
Dim Table As New List(Of String)
Dim RTable As New Hashtable
For n As Integer = 0 To 2 ^ StartCodeSize - 1
Table.Add(Chr(n))
RTable.Add(Chr(n), n)
Next
Table.Add("CC")
Table.Add("EC")
Dim ClearCode As Integer = 2 ^ StartCodeSize
Dim OverflowCode As Integer = 2 ^ (StartCodeSize + 1)
Dim Prefix As String = ""
Dim IndexOfPrefix As Integer
Dim Root As Char
WriteTar(2 ^ StartCodeSize)
Dim CurStr As String
While True
Root = Chr(ReadSrc())
If EOF Src Then Exit While
CurStr = Prefix & Root
If RTable.ContainsKey(CurStr) Then
IndexOfPrefix = RTable(CurStr)
Prefix = CurStr
Else
WriteTar(IndexOfPrefix)
If Table.Count = OverflowCode Then
If OverflowCode = 4096 Then
WriteTar(Asc(Root))
WriteTar(2 ^ StartCodeSize)
Table.RemoveRange(2 ^ (StartCodeSize) + 2, Table.Count – 2 ^ (StartCodeSize) - 2)
RTable.Clear()
For n As Integer = 0 To 2 ^ StartCodeSize - 1
RTable.Add(Chr(n), n)
Next
CodeSize = StartCodeSize
OverflowCode = 2 ^ (StartCodeSize + 1)
Prefix = ""
Continue While
Else
CodeSize += 1
OverflowCode = OverflowCode * 2
End If
End If
Table.Add(CurStr)
RTable.Add(CurStr, Table.Count - 1)
Prefix = Root
IndexOfPrefix = Asc(Root)
End If
End While
WriteTar(IndexOfPrefix)
WriteTar(ClearCode + 1)
Return TarBytes
End Function
Function UnLZW(ByVal TarBytes As Char()) As Char()
SrcBytes = New List(Of Char)()
CodeSize = StartCodeSize
SrcPos = 0
TarPos = 0
Dim Table As New List(Of String)
For n As Integer = 0 To 2 ^ StartCodeSize - 1
Table.Add(Chr(n))
Next
Table.Add("CC")
Table.Add("EC")
Dim ClearCode As Integer = 2 ^ StartCodeSize
Dim OverflowCode As Integer = 2 ^ (StartCodeSize + 1)
Dim CurStr As String
Dim cur As Integer = ReadTar()
cur = ReadTar()
WriteSrc(Table(cur))
Dim old As Integer = cur
cur = ReadTar()
While True
Select Case cur
Case ClearCode
Table.RemoveRange(2 ^ (StartCodeSize) + 2, Table.Count – 2 ^ (StartCodeSize) - 2)
CodeSize = StartCodeSize
OverflowCode = 2 ^ (StartCodeSize + 1)
cur = ReadTar()
WriteSrc(Table(cur))
Case ClearCode + 1
Exit While
Case Else
If cur <= Table.Count - 1 Then
WriteSrc(Table(cur))
Table.Add(Table(old) & Table(cur)(0))
Else
CurStr = Table(old) & Table(old)(0)
WriteSrc(CurStr)
Table.Add(CurStr)
End If
If Table.Count = OverflowCode AndAlso OverflowCode <> 4096 Then
CodeSize += 1
OverflowCode = OverflowCode * 2
End If
End Select
If EOF Tar Then Exit While
old = cur
cur = ReadTar()
End While
Return SrcBytes
End Function
伪码是从实际代码改写而来,略有点长。
3、位图数据:
每个像素按照从上到下从左到右的顺序排列。
参考:
[1]GIF文档,foenix,http://asp.6to23.com/iseesoft/devdoc/imgdoc/gif.htm