GIF(Graphics Interchange Format)是CompuServe公司开发的图像文件存储格式,1987年开发的GIF文件格式版本号是GIF87a,1989年进行了扩充,扩充后的版本号定义为GIF89a。
一,
概述:
GIF文件由文件头,描述块,彩色表,数据块,扩展块和结束符构成,GIF87a和GIF89a的区别在于:后者较前者增加了扩展块,从功能上看即提供了对透明色和多帧动画的支持。 二, 格式详解:
约定:
i: 以下图示括号中出现的“B”代表字节(Byte),而“b”则代表字节中的位(bit)。 ii:两个字节以上数的存放顺序为低字节在前。
iii:文件格式中出现的大小尺寸等均为unsigned数据类型,单位为字节或像素。 iv:各描述结构块以在文件中出现的先后顺序而排列。 v:符号约定:*表示名词解释 ,#表示效果演示 ,【】表示参考文献。 1,Header结构:
Signature(3B)Version(3B)
说明:Signature 为“GIF”3个字符;Version 为“87a”或“89a”3个字符。 2,Logical Screen Descriptor结构:
Logical ScreenWidth(2B)Logical ScreenDepth(2B)Packet fields(1B)Background Color Index(1B)Pixel AspectRatio(1B)Global Color Table Flag(1b)Color Resolution(3b)SortFlag(1b)Global Color TableSize(3b) 说明:Logical Screen Width 和Logical Screen Depth 均以像素为单位。
Packet fields 中最高位为全局颜色表标志,即为1时表明Logical Screen Descriptor后面跟的是全局颜色表。
Color Resolution 的值加1代表颜色表中每种基色用多少位表示,如为“111”时
表示每种基色用8位表示,则颜色表中每项为3Byte。由于该值有时可为0,一般在解码程序中,该3位不作处理,而直接由Global
Color Table Size 算出颜色表大小。
Sort Flag 表示重要颜色排序标志,标志为1时,表示颜色表中重要的颜色排在前面,有利于颜色数较少的解码器选择最好的颜色。一般该标志为0,不作处理。
Global Color Table 的值加1作为2的幂,算得的数即为颜色表的项数,实际上
颜色表每项由RGB三基色构成,每种基色占一个字节,则颜色表占字
节数为项数的3倍。由于最大值为“111”,故颜色表的项数最多为256
项,即256种颜色,8位每基色则颜色表大小为768 Bytes。
Note:“256种颜色”是指这256种颜色是编码器在由24位原始位图数据生成
GIF文件时从262K色中选取的,生成的图像一样可以很鲜艳#。
Background Color Index 表示背景颜色索引值*。可以这样理解:在指定大小显示区,GIF图像的大小可能小于显示区域大小,显示区中剩余的区域则一律用背景颜色索引值在全局颜色表中对应的颜色填充。在实际解码过程中,在显示图像之前可将显示区域全部用该颜色填充。
*颜色索引值:颜色索引值是一个在颜色表中的序号值,即该序号对应的颜色值。
Pixel Aspect Ratio 表示像素宽高比,一般为0,不作处理,直接以Logical Screen 宽
和高作处理。如该项不为0,则参照GIF89a标准【1】计算。 3,Global Color Table 结构:
Red 0Green 0Blue 0Red 255Green 255Blue 255
颜色表每项由3原色RGB表示,依次排放,大小由前面的Logical Screen Descriptor
决定。一般GIF图像用256色,每种基色用8位,则有768个字节大小的颜色表。 4,Image Descriptor 结构:
ImageSeparator(1B)ImageLeft position(2B)ImageTop position(2B)ImageWidth(2B)ImageDepth(2B)PacketFields(1B)
Local ColorTable Flag(1b)Interlace Flag(1b)SortFlag(1b)Reserved(2b)Local Color TableSize(3b)
Image Separator 固定为0x2C(ASCII码中代表“,”)。
Image Left position + Image Top position 表示Image Descriptor 后面跟的一幅图像(块)起始点相对(逻辑)屏幕原点(令其为最左上角点)的位移。
Image Width + Image Depth 表示Image Descriptor 后面跟的一幅图像(块)的实际宽
和高,不应该超过Logical Screen Width 和Logical Screen Depth的大小。
以上四项信息在显示多帧图像(动画)时尤其要注意,因为每帧更新的区域有可能都不一样#。
Local Color Table Flag 局部颜色表标志,为1时表示Image Descriptor后面跟的是下幅
图像所用的颜色表,此时Global Color Table(全局颜色表)无效。
Note:对于GIF中的一幅图像,可能只有全局颜色表(如静态图像,GIF87a图像和大部分多帧动画),可能没有全局颜色表而每幅图像有各自的局部颜色表(GIF电影片断动画较常见),可能两种颜色表都有(即为上面考虑的情况),也可能两种颜色表都没有(此种情况要用系统颜色表,本文不作考虑)。 Interlace Flag 交错显示标志,为1时表示图像数据是以隔行方式存放的。最初GIF标
准设置此标志的目的是考虑到通信设备间传输速度不理想情况下,用这
种方式存放和显示图像,就可以在图像显示完成之前看到这幅图像的概貌,慢慢的变清晰,而不觉得显示时间过长。具体扫描行顺序参见GIF89a
标准【1】。作为单机显示系统来讲,可以采取逐次行显示方式,也可以采取逐次全屏显示方式(此时将看不到交错效果),依据显示系统的刷新显示性能,解码程序设计者可以选择权衡的。
Sort Flag 与Global Color Table中Sort Flag含义相同。 Reserved 保留。
Local Color Table Size 局部颜色表大小,计算方法与Global Color Table中的方法一致。 5,Local Color Table 结构:
与Global Color Table 结构一致,因而处理方式也与后者一样。要注意的是,遇到
Local Color Table 时,Global Color Table 对Local Color Table对应的图像无效,即用此时用Local Color Table 取代Global Color Table。
6,Table Based Image Data 结构:
GIF文件格式所采用的是LZW图像压缩算法,它是一种基于String Table的字典压
缩算法,具体算法过程参见LZW Data Compression【2】。 压缩后的数据组织结构如下:
LZW Code Size 表示表示一个像素索引值所用的最少比特位数,如:该值为0x08
时表示解码后的每个像素索引值为8位(一个字节,可以表示256种颜色)。
Block 压缩图像数据块,Block Size 用一个unsigned char型数表示块的大小(单
位为Byte),因此每块最大可为255 Bytes,Block Data存放的是压缩图像数
据。压缩后的图像Block在一幅图像域*中可以有若干个。
*图像域: 由每个Image Descriptor后面对应的Local Color Table(possible) ,Table
Based Image Data block和Extension block(possible)构成。包含了在Image Descriptor指定位置显示一幅图像的所有信息和数据。
Block Terminator 固定为0x00,表示该幅图像域的结束。
以下描述的是扩展块,由GIF89a标准【1】支持
LZW CodeBlockSize(1B)Size(1B)BlockData(NB)(May be repeat N Blocks)BlockSize(1B)BlockData(NB)BlockTerminator(1B)约定:Extension Introducer 扩展导入符,固定为0x21(ASCII码中代表“!”)。
Application Label 应用扩展块标签,值为0x00~0xFF。
Block Terminator 固定为0x00。 7,Application Extension结构:
ExtensionIntroducer 0x21ApplicationLabel 0xFFBlockSize(1B)ApplicationInformation(11B)ApplicationData(NB)BlockTerminator(1B) Block Size 表示Application Data 的大小。
Application Information 为11Bytes的应用程序信息,包含制作GIF文件的应用程
序的相关信息。前8字节为应用程序标示符(程序名称),
后3字节为应用程序识别码。
Application Data 为Block Size 字节的数据。
8,Comment Extension 结构:
Block Size 表示Comment Data 的大小。 Comment Data 用来说明图形,作者和其他任何非图形数据和控制信息的文本信息。 9, Graphic Control Extension 结构:
Graphic ControlExtensionLabel 0xF9Introducer 0x21BlockSize(1B)PacketFields(1B)Delay Time(2B)TransparentBlock Color Index(1B)Terminator(1B)ExtensionGraphic ControlIntroducer 0x21Label 0xFEBlockSize(1B)Comment Data(NB)BlockTerminator(1B)Reserved(3b)DisplayMethod(3b)User InputFlag(1b)TransparentColor Flag(1b)Block Size 的值应该固定为0x04,即块数据大小为4Bytes。
Display Method 一般值为1,即不作其他特殊处理。其他值处理方式参见GIF89a【1】 User Input Flag 用户输入标志,为1时表示处理完该图像域后等待用户的输入后才
开始下一图像域的处理。
Delay Time 表示处理完该图像域到开始处理下一个图像域的延迟时间,单位是
1/100秒。
Note:如果同时出现User Input Flag 置位和Delay Time不为0的情况下,则在 Delay Time定时到之前有用户输入,或者没有用户输入而Delay Time定时到这两种情况下,都会触发下一图像域的处理。 Transparent Color Flag 表示透明颜色索引标志,该标志置位表示透明颜色索引有效。 Transparent Color Index 表示透明颜色索引,在透明颜色索引有效情况下,解码所得
颜色索引与该索引值相等时,数据将不作处理(不更新对应
像素)。
Note:什么是透明?透明一般用在多帧图像显示中,例如计划对第一幅图像的一
小块区域做更新,而实际上第二幅图像的Image Descriptor指定的区域要比预期的大。对于编码器而言,这多余位置的数据就相当于编码成了透明色索引,解码器解码时就知道这些数据可以不处理,从效果上看就像那些像素是“透明”的,没有破坏第一幅图像的对应区域。如果没有考虑透明处理,那么相应区域就将被刷新为索引色(一般是黑色),这是我们不希望看到的。 10,Plain Text Extension 结构:
ExtensionIntroducer 0x21Plain TextLabel 0x01BlockSize(1B)Plain TextControl info(12B)Plain TextData(NB)Block Terminator(1B) Block Size 表示Plain Text Data 的大小。
Plain Text Control information 文本网格,字符及其颜色的信息。 Plain Text Data 表示要显示的Plain Text 信息。 Extension block 小结
Extension block 并非是显示图像必须的,除Graphic Control Extension block外,上面列的所有Extension block都是对GIF文件的一些解释信息,一般在应用中很难看到这些信息,幸运的是,对于只要求显示图像为目的解码器设计者,我们也不关心这些信息,可以直接跳过。对于多帧图像(动画效果),Graphic Control Extension block将是必须的,因为它包含了图像间的延时及透明处理。
11,Trailer结构:
Trailer(1B)
Trailer 作为整个GIF文件的结束符,固定为0x3B(ASCII码中代表“;”)。
三, 附录:
1,压缩图像存发方式
LZW编码器输出的是变长的Code(9~11位),然而计算机存发信息是以字节为单位
的,这样Code数据就要进行Byte Package处理。 如右图所示,假设Code是5位编码流输出, 令为aaaaabbbbbcccccdddddeeeee
则数据将是由低位到高位,依字节顺序来排列的。
0bbbaaaaa1dcccccbb2eeeedddd2,效果评估
由于LZW算法是一种优秀的通用无失真压缩算法,用于文本和线条轮廓明显的图像的压缩将有其他算法无法比拟的效果。
(1)线条轮廓画 (2)颜色层次分明的图像 可以获得极高的压缩比 一样可以显示多种鲜艳的颜色
(3)渐变色处理 GIF vs. JPEG
对于颜色层次不是很分明的图像,可以考虑 用JPEG算法压缩图像。从JPEG的算法过程
可以看出,由于对图像块做了均值和DCT变 换,图像有一种平滑过渡的感觉。而同样的 GIF图像压缩后再还原显示的效果就不太理想, 这是由于LZW算法在解码过程中各像素值是 不相关的,而颜色表中只有256种颜色,因此 就造成了像素间颜色的突变。
右图是两种格式图像在放大后的对比,可以看 到GIF图像在渐变色区域又很多“斑点”,而 JPEG图像就不明显了。这个例子充分说明了 LZW算法本身是一个无损压缩算法,但用在图 像压缩处理中,就不可避免的要丢失一些颜色
信息,从而对图像造成了“有损”压缩效果。
此外,在处理这样的图像时,JPEG的压缩比*也明显高于GIF的压缩比。 *JPEG压缩比:JPEG算法的压缩比可以由编码器自由调整。
3,专利与开发
1984 年, T. A. Welch 再LZ77,LZ78算法基础上发表了名为“高性能数据压缩技术( A Technique for High Performance Data Compression )”的论文,描述了他在 Sperry 研究中心(该研究中心后来并入了 Unisys 公司)的研究成果,这是 LZ78 算法的一个变种,也就是后来非常有名的 LZW 算法。随后,LZW算法顺理成章成为Unisys 公司的专利。而Unisys则将它授权给了CompuServe公司来开发后来的我们常见的GIF标准。随着计算机技术和网络技术的大发展,两家公司觉得GIF大为有利可图,于是在1994年年底两家公司联合作出声明:凡是在开发的应用软件中编写和显示GIF文件都要复专利授权费给Unisys! 这项声明直接导致了Free Software人士开发开放的PNG格式(类似于GIF)用以抗衡GIF。不
过幸运的是20年后,即2003年6月20日其在美国的专利已过期,而在2004
年6,7月份间,LZW算法在加拿大,法国,日本,德国等注册国的专利也纷纷过期。
4,参考文献
【1】GRAPHICS INTERCHANGE FORMAT(sm) Version 89a ©1987,1988,1989,1990 Copyright CompuServe Incorporated Columbus, Ohio
【2】Nelson, M.R. : \"LZW Data Compression\
因篇幅问题不能全部显示,请点此查看更多更全内容