目录

免责声明 ———————————1
序 —————————————–1
许可 —————————————1
关于本文档 ——————————2
总则 ————————————–2
版本号 ———————————–2
编码器 ———————————–3
解码器 ———————————–3
守则 ————————————–3
关于建议 ——————————–4
关于颜色表 —————————–4
块,扩展和作用域 ——————–4
块大小 ———————————–5
使用GIF作为嵌入式协议 ————-5
数据子块 ——————————–5
块结束符 ——————————–6
头 —————————————–7
逻辑屏幕标识符 ————————8
全局颜色表 ——————————10
图像标识符 ——————————11
局部颜色表 ——————————13
基于表格的图像数据 ——————-14
图像控制扩展 —————————-15
注释扩展 ———————————-17
纯文本扩展 ——————————-18
应用程序扩展 —————————-21
Trailer ————————————23
快速参考表 ——————————24
GIF语法 ———————————-25
术语表 ————————————27
约定 —————————————28
交错图像 ———————————29
变长编码LZW压缩 ———————30
在线功能对话 —————————33

1. 免责声明

以上资料如有更改,恕不另行通知。在任何情况下,CompuServe 公司都不承担损害赔偿责任,包括因使用或无法使用信息而导致的任何收入损失、利润损失或其他附带或间接损害;CompuServe 公司对信息的适用性不作任何声明。

2. 序

本文档定义了图形交换格式(sm)。这个规范定义了版本 89a,它是版本 87a 的扩展。

此处指定的图形交换格式(sm)应被视为完整的;任何偏离它的行为都应该被认为是无效的,包括但不限于,在控制或数据块中使用保留的或未定义的字段,在块内部或块之间包含无关的数据,使用格式中没有特别列出的方法或算法,等等。一般而言,本文档中未指明的任何偏离、扩展或修改都应被视为违反格式,应当避免。

3. 许可

图形交换格式(c)是 CompuServe 公司的版权财产。只有 CompuServe 公司有权以任何方式定义、重新定义、增强、更改、修改或更改格式的定义。

CompuServe 公司特此授予在计算机软件中使用图形交换格式(sm)的有限的、非独占的、免版税的许可;使用 GIF(sm) 的计算机软件必须在用户和技术文档中承认 CompuServe 公司对图形交换格式及其服务标记的所有权。使用 GIF 的计算机软件,在没有用户或技术文档的情况下分发或可能分发时,必须在屏幕或打印机上显示一条消息,确认 CompuServe 对图形交换格式和服务标记的所有权。可以使用如下的消息:

"The Graphics Interchange Format(c) is the Copyright property of
  CompuServe Incorporated. GIF(sm) is a Service Mark property of
  CompuServe Incorporated."  

如需更多信息,请联系:

CompuServe Incorporated  
Graphics Technology Department  
5000 Arlington Center Boulevard  
Columbus, Ohio  43220  
U. S. A.    

CompuServe公司与所有希望在本文件更正或修订后收到副本的个人和组织保持了一个邮件列表。这项服务是免费提供的;请提供您的邮寄地址。

4. 关于本文档

本文档详细描述了图形交换格式的定义。本文档旨在作为编程参考;建议在编程之前仔细阅读整个文档,因为各个部分是相互依赖的。每个格式块都有一个单独的部分。在每个部分中,标记为 需要的版本的子部分指的是如果在数据流中使用了相应的块,编码器将必须使用的版本号。每个部分中,用一个图表描述了块中的各个字段;这些图表是垂直画的;图中的顶部字节首先出现在数据流中。一个字节内的位被画在最有效的左边。多字节数字字段顺序为最低有效字节优先。数值常量表示为十六进制数,前面加“0x”。字节内的位字段按从最高有效位到最低有效位的顺序描述。

5. 总则

图形交换格式(sm)定义了一种用于位图数据在线传输和交换的协议,其方式与创建或显示所用的硬件无关。

图形交换格式是根据用于图形重建的相关参数和数据的块和子块来定义的。GIF 数据流是协议块和子块的序列,表示图形的集合。通常,假设数据流中的图形在某种程度上是相关的,并共享一些控制信息;建议编码器尝试将相关图形组合在一起,以最小化处理过程中的硬件更改和最小化控制信息开销。同样的,不相关的图形或需要重新设置硬件参数的图形应尽可能单独编码。

数据流可能起源于本地,如从文件中读取时,也可能起源于远程,如通过数据通信线传输时。格式的定义假设使用无错误的传输层协议进行通信;格式对错误检测和错误纠正没有规定。

GIF 数据流必须在上下文中进行解释,也就是说,应用程序必须依赖数据流外部的信息来调用解码器过程。

6. 版本号

数据流标头中的版本号旨在标识解码器可以完全处理数据流所需的最小功能集。编码器应该使用包含数据流中所有数据块都使用的尽可能早的版本号。在这个文档中的每个块部分中,都有一个标记为 需要的版本 的条目,它指定了包含相应块的最早版本号。编码器应尽可能使用覆盖数据流中所有块的最早版本号;不必要地使用新版本号将阻碍某些解码器的处理过程。

7. 编码器

编码器就是用来创建 GIF 数据流的程序。从光栅数据和其他信息中,编码器产生用于重建原始图形所必要的控制和数据块。

编码器有以下主要职责。

- 在数据流中包含重建图形所需的所有必要信息。  

- 确保数据流用尽可能早的版本号进行标记,以覆盖其中所有块的定义;这是为了确保最多的解码器可以处理数据流。  

- 确保以解码过程最优的方式对图形进行编码。尽可能避免冗余信息。  

- 尽可能避免对图形进行分组,因为在解码过程中可能需要重新设置硬件参数。  

- 将每个字段的每个位设置为零(关闭),指定为保留。注意,逻辑屏幕描述符和图像描述符中的一些字段在版本 87a 中保留,但在版本 89a 中使用。  

8. 解码器

解码器是用来处理 GIF 数据流的程序。它按顺序处理数据流,解析各种块和子块,使用控制信息设置硬件和流程参数,并解释数据以呈现图形。

解码器有以下主要职责。

- 按顺序处理数据流中的每个图形,除控制信息中指定的延迟外,没有其他延迟。  

- 将其硬件参数设置为尽可能接近数据流中包含的控制信息。  

9. 守则

当且仅当编码器或解码器完全符合并正确实现与该版本相关的标准定义时,才称其符合图形交换格式的给定版本。编码器或解码器可能符合给定的版本号,而不符合某些后续版本。

10. 关于建议

本文档中的每个区块部分都包含一个标记为“推荐”的条目;本节列出了一组建议,旨在指导和组织特定块的使用。这些建议是为了使编码器和解码器的功能更有效,以及最佳地利用通信带宽。建议遵循这些建议。

11. 关于颜色表

GIF格式利用颜色表来渲染基于光栅的图形。颜色表可以有两种作用域:全局作用域或局部作用域。全局颜色表用于数据流中没有与之关联的局部颜色表的所有图形。全局颜色表的范围是整个数据流。一个局部颜色表总是与紧跟着它的图形相关联;局部颜色表的范围仅限于那一个图形。局部颜色表取代全局颜色表,即如果数据流包含全局颜色表,而图像有关联的局部颜色表,解码器必须保存全局颜色表,使用局部颜色表渲染图像,然后恢复全局颜色表。这两种颜色表都是可选的,使得数据流可以在没有颜色表的情况下包含大量图形。出于这个原因,建议解码器保存使用的最后一个全局颜色表,直到遇到另一个全局颜色表。这样,既不包含全局颜色表也不包含局部颜色表的数据流可以使用保存的最后一个全局颜色表进行处理。如果使用了来自前一个流的全局颜色表,该表将成为当前流的全局颜色表。这是为了减少由颜色表引起的开销。特别是,如果相关数据流中的所有图像都可以用同一个表呈现,建议编码器只使用一个全局颜色表。如果根本没有可用的颜色表,解码器可以自由使用系统颜色表或它自己的表。在这种情况下,解码器可以使用具有其硬件所能支持的尽可能多的颜色的颜色表;建议这样的表的前两项是黑色和白色的,这样就可以充分地渲染单色图像。

GIF格式的定义允许数据流只包含标题、逻辑屏幕描述符、全局颜色表和GIFTrailer。这样的数据流将用于加载带有全局颜色表的解码器,为后续没有任何颜色表的数据流做准备。

12. 块,扩展和作用域

块可以分为三组:控制块,图形渲染块和特殊用途块。控制块,如头部、逻辑屏幕描述符、图形控制扩展和Trailer,包含用于控制数据流过程的信息或用于设置硬件参数的信息。图形渲染块,像图像描述符和纯文本扩展等,包含用于在显示设备上呈现图形的信息和数据。特殊目的块,像注释扩展和应用程序扩展,既不用于控制数据流的过程,也不包含用于在显示设备上呈现图形的信息或数据。除了逻辑屏幕描述符和全局颜色表的作用域是整个数据流外,其它所有其他控制块的作用域都是有限的,仅限于它们后面的图形渲染块。特殊目的块不划分任何控制块的范围;特殊目的块对解码过程是透明的。图形渲染块和扩展被用作控制块和扩展的范围分隔符。用于标识标记块的标签分为三个范围:0x00-0x7F(0-127) 是图形渲染块,不包括 Trailer(0x3B);0x80-0xF9(128-249) 是控制块; 0xFA-0xFF(250-255) 是特殊用途块。定义这些范围是为了使解码器能够通过适当地识别块标签来处理块作用域,即使在块本身不能被处理的情况下也是如此。

13. 块大小

块中的块大小字段用于计算块中剩余的字节数,不包括块大小字段本身,也不包括块终止符(如果有的话)。数据块以外的块的长度是固定的;提供块大小字段是为了方便跳过它们,而不是允许它们的大小在未来更改。数据块和子块的长度是可变的,以适应数据量。

14. 使用GIF作为嵌入式协议

作为一种嵌入式协议,GIF 可能是更大的应用程序协议的一部分,在这些协议中,GIF 被用来渲染图形。在这种情况下,应用程序协议可以定义一个包含GIF数据流的块。然后,应用程序将在遇到 GIF 类型的块时调用 GIF 解码器。推荐使用这种方法来支持使用应用程序扩展 (Application Extensions),这会成为所有其他不处理它们的应用程序的开销。因为 GIF 数据流必须在上下文中处理,所以应用程序必须依赖于在流本身之外识别 GIF 数据流的一些方法。

15. 数据子块

a. 描述。数据子块是包含数据的单元。它们没有标签,这些块在那些格式中指定了数据块的控制块的上下文中处理。Data 子块的第一个字节表示后面的数据字节数。一个数据子块可以包含 0 到 255 个数据字节。块的大小不包含块大小字节本身,因此,空子块地一个块大小字节为 0x00 的子块。  

b. 需要的版本。87a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    Block Size    字节  
        +--------------+  
    1   |                      |  
        +-                  -+  
    2   |                      |  
        +-                  -+  
    3   |                      |  
        +-                  -+  
         |                      |    Data Values    字节  
        +-                  -+  
    up|                     |  
        +-   . . . .      -+  
    to |                     |  
        +-                 -+  
         |                      |  
        +-                 -+  
    255|                   |  
        +-------------+  

    i) 块大小 - 数据子块中的字节数;大小必须在 0 到 255 字节之间,闭区间。  

    ii) 数据值 - 任何 8 位值。必须有与块大小字段指定的相同数量的数据值。  

d. 扩展和作用域。这种类型的块总是作为较大单元的一部分出现。它没有自己的作用域。  

e. 建议。无。

16. 块结束符

a. 描述。此零长度数据子块用于终止数据子块序列。它在块大小字段的位置上包含一个字节,不包含数据。  

b. 需要的版本。87a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    Block Size    字节  
        +--------------+    

    i) 块大小 - 数据子块中的字节数;这个字段包含固定的值 0x00。  

    ii) 数据值 - 这个块不包含任何数据。  

d. 扩展和作用域。此块终止紧挨着前面的数据子块序列。此块不能被任何扩展修改。  

e. 建议。无。
a. 描述。头部在上下文中标识 GIF 数据流。签名字段标记了数据流的开始,版本字段标识了解码器完全处理数据流所需的一组功能。这个块是 必须的;每个数据流必须有一个头部。  

b. 需要的版本。不适用。此块不受版本号的约束。此块必须出现在每个数据流的开头。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    签名    3字节  
        +-                  -+  
    1   |                      |  
        +-                  -+  
    2   |                      |  
        +-                  -+  
    3   |                      |  
        +--------------+  
    4   |                      |    版本    3字节  
        +-                  -+  
    5   |                     |  
        +-                 -+  
    6   |                     |  
        +-------------+  

    i) 签名 - 标识 GIF 数据流;这个字段包含固定值 'GIF'。  

    ii) 版本 - 用于格式化数据流的版本号。标识解码器完全处理数据流内容所需的最小功能集。  
        1990年7月10号的版本号:"87a" - 1987.5
                                                        "89a" - 1990.7
        版本号的顺序是从87开始的前两位数字递增(87,88,…,99,00,…,85,86),从第三个字符开始按字母递增。  

    iii) 扩展和作用域。这个块的作用域是整个数据流。此块不能被任何扩展修改。  

d. 建议。
    
    i) 签名 - 该字段标识GIF数据流的开始;它不打算为识别数据提供唯一的签名。建议GIF数据流由应用程序在外部识别。(GIF数据流的在线识别请参阅附录G。)  

    ii) 版本 - 编码器:编码器应该使用尽可能早的版本号,该版本号定义了数据流中使用的所有块。当组合两个或多个数据流时,应对结果数据流使用最新的单个版本号。解码器:解码器应尽量处理数据流;如果遇到它无法完全处理的版本号,它应该在警告用户数据可能是不完整的之后,尝试尽其最大能力处理数据流。  

18. 逻辑屏幕标识符

a. 描述。逻辑屏幕标识符包含定义显示设备的区域所需的参数,图像将在该区域内呈现。该块中的坐标是相对于虚拟屏幕的左上角给出的;它们不一定指的是显示设备上的绝对坐标。这意味着它们可以在基于窗口的环境中引用窗口坐标,也可以在使用打印机时引用打印机坐标。  

    这个块是必须的;每个数据流必须有一个逻辑屏幕标识符。  

b. 需要的版本。不适用。此块不受版本号的约束。此块必须出现在紧跟头部的后边。  

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    逻辑屏幕宽    无符号  
        +-                  -+  
    1   |                      |  
        +--------------+  
    2   |                      |    逻辑屏幕高    无符号  
        +-                  -+  
    3   |                      |  
        +--------------+  
    4   ||      ||            |    <packed Fields>    见下方  
        +--------------+  
    5   |                     |    背景色索引    字节  
        +--------------+  
    6   |                     |    像素宽高比    字节  
        +-------------+  

    <Packed Fields>  =  全局颜色表标志位    1比特  
                        颜色分辨率    3比特  
                        排序标志位    1比特  
                        全局颜色表大小    3比特  

    i) 逻辑屏幕宽 - 图像将在显示设备中渲染的逻辑屏幕的宽度(以像素为单位)。  

    ii) 逻辑屏幕高 - 图像将在显示设备中渲染的逻辑屏幕的高度(以像素为单位)。  

    iii) 全局颜色表标志位 - 指示存在全局颜色表的标志;如果设置了该标志位,则全局颜色表将立即跟随逻辑屏幕标识符。该标志位还选择背景颜色索引的解释;如果设置了该标志位,则背景色索引字段的值应作为背景色的表索引。(这个字段是字节的最高位。)  

    值:0 - 后面没有全局颜色表,背景色索引字段没有意义。  
             1 - 后面紧跟一个全局颜色表,背景色索引字段是有意义的。  

    iv) 颜色分辨率 - 原始图像每个原色可用的比特数,减 1。这个值表示从图形中选择颜色的整个调色板的大小,而不是图形中实际使用的颜色的数量。例如,如果这个字段中的值是 3,那么原始图像的调色板每个原色有 4 位可用来创建图像。应该设置此值以指示原始调色板的丰富程度,即使不是整个调色板中的所有颜色都可以在源计算机上使用。

    v) 排序标志位 - 指示是否对全局颜色表进行了排序。如果设置了该标志位,则会按重要性递减的顺序对全局颜色表进行排序。通常情况下,顺序是频率递减,最频繁的颜色在前面。这有助于解码器在可用颜色较少的情况下选择最佳的颜色子集;解码器可以使用表的初始段来呈现图形。

        值:0 - 未排序。
                 1 - 按重要性程序递减排序。最重要的颜色在最先。
    
    vi) 全局颜色表大小 - 如果全局颜色表标志位设置为1,则该字段的值用于计算全局颜色表所包含的字节数。要确定颜色表的实际大小,将2取[该字段的值+ 1]次冥。即使没有指定全局颜色表,也可以按照上述公式设置该字段,以便解码器可以选择最好的图形模式来显示流。(该字段由字节中最低有效的3位组成。)   

    vii) 背景色索引 - 背景色在全局颜色表中的索引。背景色是用于屏幕上没有被图像覆盖的像素的颜色。如果全局颜色表标志位设置为(零),该字段应该为零并且应该被忽略。

    viii) 像素宽高比 - 用于计算原始图像中像素的纵横比近似值的因子。如果字段的值不为0,则根据公式计算长宽比的近似值:  

    Aspect Ratio = (Pixel Aspect Ratio + 15) / 64

    像素长宽比被定义为像素的宽度除以它的高度的商。该字段的值范围允许最宽像素为4:1,最高像素为1:4,增量为1/64。

        值:0 - 未给出宽高比信息。
                 1..255 - 计算中使用的值。

d. 扩展和作用域。这个块的作用域是整个数据流。此块不能被任何扩展修改。

e. 建议。无。 

19. 全局颜色表

a. 描述。该块包含一个颜色表,它是表示红绿蓝三元组的字节序列。全局颜色表用于没有局部颜色表的图像和纯文本扩展。它的存在是通过在逻辑屏幕描述符中设置为1的全局颜色表标志来标记的;如果存在,它立即在逻辑屏幕标识符后面,并且它包含的字节数等于

    3 x 2^(全局颜色表大小+1) 。

这个块是可选的;每个数据流最多可以有一个全局颜色表 。

b. 需要的版本。87a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    红    字节  
        +-                  -+  
    1   |                      |    绿    字节  
        +-                  -+  
    2   |                      |    蓝    字节 
        +-                  -+  
    3   |                      |    红1    字节  
        +-                  -+  
         |                      |    绿1    字节  
        +-                  -+  
    up|                     |  
        +-   . . . .      -+  
    to |                     |  
        +-                 -+  
         |                      |    绿255    字节  
        +-                 -+  
    767|                   |    蓝255    字节  
        +-------------+  

d. 扩展和作用域。这个块的作用域是整个数据流。此块不能被任何扩展修改。  

e. 建议。无。

20. 图像标识符

a. 描述。数据流中的每个图像都由一个图像标识符、一个可选的局部颜色表和图像数据组成。每个图像必须符合逻辑屏幕的边界,如逻辑屏幕描述符中定义的那样。  

图像描述符包含处理基于表的图像所需的参数。这个块中给出的坐标是指逻辑屏幕中的坐标,以像素为单位。该块是一个图形渲染块,前面可选地有一个或多个控制块,如图形控制扩展,后面可选地有一个本地颜色表;图像描述符后面总是跟着图像数据。  

这个块是图像所必需的。数据流中的每个图像必须有一个图像描述符。每个数据流可能存在无限数量的图像。

b. 需要的版本。87a。  

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    图像分隔符    字节  
        +--------------+  
    1   |                      |    图像左边位置    无符号  
        +-                  -+  
    2   |                      |  
        +--------------+  
    3   |                      |    图像顶部位置    无符号  
        +-                  -+  
    4   |                      |  
        +--------------+  
    5   |                      |    图像宽    无符号  
        +-                  -+  
    6   |                      |  
        +--------------+  
    7   |                      |    图像高    无符号  
        +-                  -+  
    8   |                      |  
        +--------------+  
    9   | | | |  |            |    <Packed Fields>    见下方  
        +--------------+  

    <Packed Fields>  =    局部颜色表标志位    1 比特
                            交错标志位    1 比特
                            排序标志位    1 比特
                            保留位    2 比特
                            局部颜色表大小    3 比特
    
    i) 图像分隔符 - 标识图像标识符的开头。该字段包含固定值0x2C。  

    ii) 图像左边位置 - 图像左边缘相对于逻辑屏幕左边缘的列数(以像素为单位)。逻辑屏幕的最左边一列是 0。

    iii) 图像顶部位置 - 图像上边缘相对于逻辑屏幕上边缘的行数(以像素为单位)。逻辑屏幕的顶部行是 0。  

    iv) 图像宽 - 以像素为单位的图像宽度。  

    v) 图像高 - 以像素为单位的图像高度。  

    vi) 局部颜色表标志位 - 表示紧接在此图像标识符后面的本地颜色表的存在。(该字段是字节的最高位。)  

        值:0 - 本地颜色表不存在。如果可以使用全局颜色表。  
                 1 - 本地颜色表存在,并紧跟在此图像标识符之后。  
    
    vii) 交错标志位 - 指示图像是否交错。图像以四通道交错图案交错;详见附录E。  

        值:0 - 图像没有交错。  
                 1 - 图像交错了。  

    viii) 排序标志位 - 指示是否对“本地颜色表”进行排序。如果设置了标志,则按重要性递减的顺序对本地颜色表进行排序。通常情况下,顺序是频率递减,最频繁的颜色在前面。这有助于解码器在可用颜色较少的情况下选择最佳的颜色子集;解码器可以使用表的初始段来呈现图形。  

        值:0 - 没有排序。  
                 1 - 按重要性程序递减排序。最重要的颜色在最先。  
    
    ix) 局部颜色表大小 - 如果局部颜色表标志设置为1,则该字段的值用于计算局部颜色表中包含的字节数。要确定颜色表的实际大小,将2取[该字段的值+ 1]次冥。如果没有指定局部颜色表,该值应该为0。(该字段由字节中最低有效的3位组成)  

d. 扩展和作用域。该块的范围是它后面的基于表的图像数据块。此块可以通过图形控制扩展进行修改。  

e. 建议。无。

21. 局部颜色表

a. 描述。该块包含一个颜色表,它是表示红绿蓝三元组的字节序列。紧跟其后的图像使用局部颜色表。它的存在是通过在图像描述符中将本地颜色表标志设置为1来标记的;如果存在,它立即在图像标识符后面,并且它包含的字节数等于

    3 x 2^(局部颜色表大小+1) 。

如果存在,此颜色表将临时成为活动颜色表,并使用它处理后面的图像。这个块是可选的;每个图像标识符最多只能出现一个局部颜色表,其作用域是与它前面的图像标识符相关联的单个图像。

b. 需要的版本。87a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    红    字节  
        +-                  -+  
    1   |                      |    绿    字节  
        +-                  -+  
    2   |                      |    蓝    字节 
        +-                  -+  
    3   |                      |    红1    字节  
        +-                  -+  
         |                      |    绿1    字节  
        +-                  -+  
    up|                     |  
        +-   . . . .      -+  
    to |                     |  
        +-                 -+  
         |                      |    绿255    字节  
        +-                 -+  
    767|                   |    蓝255    字节  
        +-------------+  

d. 扩展和作用域。该块的范围是紧跟着它的基于表的图像数据块。此块不能被任何扩展修改。  

e. 建议。无。

22. 基于表格的图像数据

a. 描述。基于表的图像的图像数据由一系列子块组成,每个子块的大小最多为 255 个字节,包含了活动颜色表的索引,表示图像中的每个像素。像素索引按从左到右和从上到下的顺序排列。每个索引必须在活动颜色表的大小范围内,从0开始。索引序列是使用可变长代码的LZW算法编码的,如附录F所述。  

b. 需要的版本。87a。

c. 语法规则。图像数据格式如下所示:  

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    LZW最小编码大小    字节  
        +-------------+  

        +=========+  
    3  |                       |  
         /                      /    图像数据    数据子块  
        |                       |  
        +=========+  
    
    i) LZW 最小编码大小。这个字节决定了图像数据中用于LZW编码的初始位数,如附录F所述。  

d. 扩展和作用域。这个块没有作用域,它包含栅格数据。用于修改基于表格的图像的扩展必须出现在相应的图像描述符之前。  

e. 建议。无。

23. 图像控制扩展

a. 描述。图形控制扩展包含处理图形呈现块时使用的参数。这个扩展的范围是后面最跟的第一个图形渲染块。扩展只包含一个数据子块。
这个块是可选的;图形呈现块前面最多可以有一个图形控制扩展块。这是对数据流中可能包含的图形控制扩展块数量的唯一限制。

b. 需要的版本。89a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    扩展导引符    字节  
        +--------------+  
    1   |                      |    图形控制标签    字节  
        +--------------+  

        +--------------+  
    0   |                      |    块大小    字节  
        +--------------+  
    1   |        |      |  |  |    <Packed Fields>    见下方  
        +--------------+  
    2   |                      |    延迟时间    无符号 
        +-                  -+  
    3   |                      |  
        +--------------+  
    4   |                      |    透明色索引    字节  
        +--------------+  

        +--------------+  
    0  |                      |    块结束符    字节  
        +-------------+  

        <Packed Fields>  =  保留位    3 比特
                        清除方式    3 比特
                        用户输入标志位    1 比特
                        透明度标志位    1 比特

    i) 扩展导引符 - 标识扩展块的开始。该字段包含固定值 0x21。  

    ii) 图形控制标签 - 标识当前块为图形控制扩展。该字段包含固定值 0xF9。  

    iii) 块大小 - 块中的字节数,从块大小字段之后,直到但不包括块终止符。该字段包含固定值 4。

    iv) 清除方式 - 指示图形显示后如何被处理的方式。  

        值:0 - 没有指定处理。解码器不需要采取任何操作。
                 1 - 不清除。图形将被保留在原地。  
                 2 - 恢复到背景色。图形使用的区域必须恢复为背景色。  
                 3 - 恢复到之前的。解码器需要用呈现图形之前的内容恢复被图形覆盖的区域。
                 4-7 - 待定义
    
    v) 用户输入标志位 - 指示在继续之前是否需要用户输入。如果设置了标志,则在用户输入后才会继续处理。用户输入的性质是由应用程序决定的(回车,鼠标按钮点击等)。

        值:0 - 不需要用户输入
                 1 - 需要用户输入
    
    当使用延迟时间并设置用户输入标志位时,将在接收到用户输入或延迟时间到期时继续进行处理,两者以先发生的时间为准。

    vi) 透明度标志位 - 指示透明度指数字段中是否给出了透明度指数。(该字段是字节的最低有效位)  

        值:0 - 未给出透明度指数
                 1 - 给出了透明度指数
    
    vii) 延迟时间 - 如果不是0,则该字段指定在继续处理数据流之前要等待的百分之一(1/100)秒数。在呈现图形后,时钟立即开始滴答作响。该字段可以与用户输入标志字段一起使用。

    viii) 透明度指数 - 透明度指数是这样的,当遇到时,显示设备的对应像素不被修改,处理继续到下一个像素。当且仅当透明度标志位设置为1时,指数才会出现。

    ix) 块结束符 - 这个零长度的数据块标志着图形控制扩展的结束。  

d. 扩展和作用域。这个扩展的范围是它后面的图形渲染块;在这个块和它的目标之间可能存在其他扩展块。该块可以修改图像标识符块和纯文本扩展块。  

e. 建议。  

    i) 清除方式 - “恢复到上一层”模式用于图形的小部分;使用这种模式对解码器存储需要保存的图形部分提出了严格的要求。因此,这种模式应该慎用。此模式不打算保存整个图形或图形的大片区域;在这种情况下,编码器应该尽一切努力使要恢复的图形部分在数据流中是独立的图形。如果解码器无法保存标记为“恢复到上一层”的图形区域,建议解码器恢复到背景色。

    ii) 用户输入标志位 - 当设置了标志位,表示期望用户输入时,解码器可以发出铃声(0x07)来提醒用户期望输入。在没有指定延迟时间的情况下,解码器应该无限期地等待用户输入。建议编码器不要在没有指定延迟时间的情况下设置用户输入标志位。  

24. 注释扩展

a. 描述。注释扩展包含文本信息,这不是GIF数据流中实际图形的一部分。它适用于包含关于图形、字幕、描述或任何其他类型的非控制和非图形数据的注释。注释扩展可能被解码器忽略,也可能被保存以供以后处理;在任何情况下,注释扩展都不应中断或干扰数据流的处理。  

这个块是可选的,数据流中可以出现任意数量的注释扩展块。

b. 需要的版本。89a。

c. 语法规则。图像数据格式如下所示:  

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    扩展导引符    字节  
        +-------------+  
    1   |                      |    注释标签    字节  
        +-------------+  

        +=========+  
        |                       |  
    N |                       |    注释数据    数据子块  
        |                       |  
        +=========+  

        +--------------+  
    0   |                      |    块结束符    字节  
        +-------------+  

    i) 扩展导引符 - 标识扩展块的开始。该字段包含固定值 0x21。  

    ii) 注释标签 - 标识块为注释扩展块。该字段包含固定值 0xFE。

    iii) 注释数据 - 子块的序列,每个子块的大小不超过 255 个字节且至少 1 个字节,其大小在数据之前的一个字节中。序列的结束由块结束符标记。  

    iv) 块结束符 - 这个零长度的数据块标志着注释扩展块的结束。

d. 扩展和作用域。这个块没有作用域,且不能被任何扩展块修改。  

e. 建议。
    
    i) 数据 - 这个区块是为人类设计的。它应该包含使用7位ASCII字符集的文本。此块不应用于存储自定义处理的控制信息。

    ii) 位置 - 这个块可以出现在数据流中可以开始一个块的任何点上;但是,建议注释扩展不要干扰控制块或数据块;它们应尽可能位于数据流的开头或结尾。

25. 纯文本扩展

a. 描述。纯文本扩展包含文本数据和将该数据以简单形式呈现为图形所必需的参数。文本数据将用 7 位可打印的 ASCII 字符进行编码。文本数据使用由块字段中的参数定义的字符单元格网格呈现。每个字符都呈现在一个单独的单元格中。此块中的文本数据将呈现为单行距字符,每个单元格一个字符,具有最合适的字体和大小。有关更多信息,请参见下面的建议部分。数据字符从块的数据部分按顺序获取,并在单元格中呈现,从网格中的左上角单元格开始,从左到右,从上到下。文本数据一直呈现,直到到达数据的末尾或填充字符网格。字符网格包含整数数量的单元格;在单元格尺寸不允许整数的情况下,分数单元格必须被丢弃;编码器必须小心地准确指定网格尺寸,以免发生这种情况。这个块需要一个全局颜色表可用;该块使用的颜色引用流中的全局颜色表(如果流中有全局颜色表),如果保存了前一个流中的全局颜色表,则引用前一个流中的全局颜色表。此块是一个图形呈现块,因此它可以被图形控制扩展名修改。这个块是可选的;数据流中可以出现任意数量的纯文本扩展块。

b. 需要的版本。89a。

c. 语法规则。图像数据格式如下所示:  

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    扩展导引符    字节  
        +-------------+  
    1   |                      |    纯文本标签    字节  
        +-------------+  

        +--------------+  
    0   |                      |    块大小    字节  
        +-------------+  
    1   |                      |    文本格左边位置    无符号  
        +-                  -+  
    2   |                      |  
        +-------------+  
    3   |                      |    文本格顶部位置    无符号  
        +-                  -+  
    4   |                      |  
        +-------------+  
    5   |                      |    文本格宽度    无符号  
        +-                  -+  
    6   |                      |  
        +-------------+  
    7   |                      |    文本格高度    无符号  
        +-                  -+  
    8   |                      |  
        +-------------+  
    9   |                      |    字符单元宽    字节  
        +-------------+  
    10 |                      |    字符单元高    字节  
        +-------------+  
    11 |                      |    文本前景色索引    字节  
        +-------------+  
    12 |                      |    文本背景色索引    字节  
        +-------------+  

        +=========+  
        |                       |  
    N |                       |    纯文本数据    数据子块  
        |                       |  
        +=========+  

        +--------------+  
    0   |                      |    块结束符    字节  
        +-------------+  

    i) 扩展导引符 - 标识扩展块的开始。该字段包含固定值 0x21。  

    ii) 纯文本标签 - 标识当前块为纯文本扩展块。该字段包含固定值 0x01。

    iii) 块大小 - 扩展中的字节数,在“块大小”字段之后,直到但不包括数据部分的开头。该字段包含固定值 12。  

    iv) 文本格左边位置 - 文本网格左边缘相对于逻辑屏幕左边缘的列数(以像素为单位)。  

    v) 文本格顶部位置 - 文本网格上边缘相对于逻辑屏幕上边缘的行数(以像素为单位)。  

    vi) 文本格宽度 - 以像素为单位的文本格宽度。  

    vii) 文本格高度 - 以像素为单位的文本格高度。  

    viii) 字符单元宽  - 网格中每个单元格的宽度(以像素为单位)。 

    ix) 字符单元高 - 网格中每个单元格的高度(以像素为单位)。

    x) 文本前景色索引 - 用于渲染文本前景色的颜色在全局颜色表中的索引。  

    xi) 文本背景色索引 - 用于渲染文本背景色的颜色在全局颜色表中的索引。

    xii) 纯文本数据 - 子块的序列,每个子块的大小不超过255个字节和至少1个字节,其大小在数据之前的一个字节中。序列的结束由块终止符标记。

    xiii) 块结束符 - 这个零长度的数据块标志着纯文本扩展块的结束。

d. 扩展和作用域。此块的作用域是其中包含的纯文本数据块。此块可以通过图形控制扩展进行修改。  

e. 建议。假定纯文本扩展中的数据是预先格式化的。字体和大小的选择由解码器自行决定。如果遇到小于0x20或大于0xf7的字符,建议解码器显示一个空格字符(0x20)。编码器应该使用网格和单元格尺寸,使整数数量的单元格在水平和垂直方向上都适合网格。为了广泛的兼容性,字符单元面积需要在 8 x 8 或 8 x 16 之间;考虑一个图像的不寻常大小的文本。

26. 应用程序扩展

a. 描述。应用扩展包含特定于应用程序的信息;它符合扩展块语法,如下所述,它的块标签是0xFF。

b. 需要的版本。89a。

c. 语法规则。图像数据格式如下所示:  

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    扩展导引符    字节  
        +-------------+  
    1   |                      |    扩展标签    字节  
        +-------------+  

        +--------------+  
    0   |                      |    块大小    字节  
        +-------------+  
    1   |                      |  
        +-                  -+  
    2   |                      |  
        +-                  -+  
    3   |                      |    应用程序标识符    8字节  
        +-                  -+  
    4   |                      |  
        +-                  -+  
    5   |                      |  
        +-                  -+  
    6   |                      |  
        +-                  -+  
    7   |                      |  
        +-                  -+  
    8   |                      |  
        +-------------+  
    9   |                      |  
        +-                  -+  
    10 |                      |    应用程序认证码    3字节  
        +-                  -+  
    11 |                      |  
        +-------------+  


        +=========+  
        |                       |  
        |                       |    应用程序数据    数据子块  
        |                       |  
        |                       |  
        +=========+  

        +--------------+  
    0   |                      |    块结束符    字节  
        +-------------+  

    i) 扩展导引符 - 标识此块是一个扩展块。该字段包含固定值 0x21。  

    ii) 应用程序扩展标签 - 标识此块为应用程序扩展块。该字段包含固定值 0xff。

    iii) 块大小 - 此扩展块中的字节数,在块大小字段之后,直到但不包括应用程序数据的开头。该字段包含固定值11。  

    iv) 应用程序标识符 - 八个可打印ASCII字符的序列,用于标识拥有应用程序扩展名的应用程序。  

    v) 应用程序认证码 - 用于验证应用程序标识符的三个字节序列。应用程序可以使用一种算法来计算二进制代码,以唯一地将其标识为拥有应用程序扩展的应用程序。  

d. 扩展和作用域。此块没有作用域。此块不可以被任何扩展块修改。  

e. 建议。无。

27. Trailer

a. 描述。该块是指示GIF数据流结束的单字段块。它包含固定值0x3B。  

b. 需要的版本。87a。

c. 语法规则。

        7 6 5 4 3 2 1 0    Field Name    Type  
        +--------------+  
    0   |                      |    GIF Trailer    字节  
        +--------------+    

d. 扩展和作用域。这个块没有作用域,它终止了GIF数据流。此块不能被任何扩展修改。  

e. 建议。无。

附录A. 快速参考表

块名 是否必需 标签 扩展 版本
应用程序扩展 可选 (*) 0xFF(255) 89a
注释扩展 可选 (*) 0xFE(254) 89a
全局颜色表 可选 (1) 87a
图像控制扩展 可选 (*) 0xF9(249) 89a
头部 必需 (1) N/A
图像标识符 可选 (*) 0x2C(044) 87a(89a)
局部颜色表 可选 (*) 87a
逻辑屏幕标识符 必需 (1) 87a(89a)
纯文本扩展 可选 (*) 0x01(001) 89a
Trailer 必需 (1) 0x3B(059) 87a

无标签块

块名 是否必需 标签 扩展 版本
头部 必需 (1) N/A
逻辑屏幕标识符 必需 (1) 87a(89a)
全局颜色表 可选 (1) 87a
局部颜色表 可选 (*) 87a

图像渲染块

块名 是否必需 标签 扩展 版本
纯文本扩展 可选 (*) 0x01(001) 89a
图像标识符 可选 (*) 0x2C(044) 87a(89a)

控制块

块名 是否必需 标签 扩展 版本
图像控制扩展 可选 (*) 0xF9(249) 89a

特殊用处块

块名 是否必需 标签 扩展 版本
Trailer 必需 (1) 0x3B(059) 87a
注释扩展 可选 (*) 0xFE(254) 89a
应用程序扩展 可选 (*) 0xFF(255) 89a

说明:(1) 如果存在的话,最多出现一次 (*) 出现 0 或更多次 (+) 出现 1 或更多次

注意:标头不受版本号的影响。(89a)逻辑屏幕标识符和图像标识符保留了它们从版本 87a 到版本 89a 的语法,但是一些在版本 87a 下保留的字段在版本 89a 下仍在使用。

附录B. GIF语法

语法是一种表示法,它表示特定对象形成较大对象的顺序。还使用语法来表示在给定位置可能出现的对象的数量。这里给出的语法表示构成GIF数据流的块序列。语法是通过列出它的规则来给出的。每条规则都包括左边,后面是某种形式的等号,然后是右边。在规则中,右边描述了左边的定义。右边由一系列实体组成,可能存在特殊符号。下面的说明定义了GIF语法中使用的符号。

说明: <> 语法词 ::= 定义符号 * 出现 0 或更多次 + 出现 1 或更多次 | 替代元素 [] 可选元素

示例:

<GIF  Data Stream> ::= Header <Logical Screen> <Data>* Trailer  

该规则定义了实体如下所示。它必须以 Header 开头。Header 后面是一个名为 Logical Screen 的实体,它由下面的另一个规则定义。逻辑屏幕后面是实体 Data,它也在下面由另一个规则定义。最后,实体数据后面是 Trailer。因为没有定义 Header 或 Trailer 的规则,这意味着这些块在文档中定义。实体 Data 后面有一个特殊的符号 (*),这意味着在这个位置,实体 Data 可以重复任何次数,包括 0 次。关于这个主题的进一步阅读,请参考编程语言的标准文本。

语法

<GIF Data Stream> ::= Header <Logical Screen> <Data>* Trailer  

<Logical Screen> ::= Logical Screen Descriptor [Global Color Table]  

<Data> ::= <Graphic Block> | <Special-Purpose Block>  

<Graphic Block> ::= [Graphic Control Extension] <Graphic-Rendering Block>  

<Graphic-Rendering Block> ::=  <Table-Based Image> | Plain Text Extension  

<Table-Based Image> ::= Image Descriptor [Local Color Table] Image Data  

<Special-Purpose Block> ::= Application Extension  |  Comment Extension  

注意:语法表明,GIF数据流可以只包含头部、逻辑屏幕描述符、全局颜色表和GIF Trailer。此特殊情况用于加载带有全局颜色表的GIF解码器,为后续不使用任何颜色表的数据流做准备。

附录C. 术语表

活跃颜色表 - 用于渲染下一个图形的颜色表。如果下一个图形是一个有相关联的局部颜色表的图像,则活动颜色表就是与该图像关联的局部颜色表。如果下一个图形是一个没有局部颜色表或是纯文本扩展的图像,则活动颜色表是与数据流关联的全局颜色表(如果有的话);如果数据流中没有全局颜色表,则活动颜色表是从前一个数据流中保存的颜色表,或由解码器提供的颜色表。

块 - 组成协议单元的字节集合。通常,这个术语包括标记块和未标记块,以及扩展。

数据流 - GIF数据流由表示图像和图形的块和子块以及在显示设备上呈现它们的控制信息组成。数据流中的所有控制和数据块必须在头部和尾部之前。

解码器 - 一种能够处理GIF数据流以呈现其中包含的图像和图形的程序。

编码器 - 一种能够捕获和格式化图像和图形光栅数据的程序,遵循图形交换格式的定义。

扩展 - 一个由扩展导引符 0x21 标记的协议块。

扩展导引符 - 定义一个扩展的标签 0x21。

图形 - 可以通过一些算法呈现在屏幕上的数据。“图形”一词比“图像”一词更笼统;除了图像,术语图形还包括使用字符位图呈现的文本等数据。

图像 - 表示图片或图画的数据;图像由称为图像光栅的像素数组表示。

光栅 - 表示图像的像素值数组。

附录D. 约定

动画 - 图形交换格式并不打算作为动画的平台,尽管它可以以有限的方式实现。

字节顺序 - 除非另有说明,多字节数字字段以最低有效字节优先排序。

颜色索引 - 颜色索引总是引用活动颜色表,要么全局颜色表,要么局部颜色表。

颜色顺序 - 除非另有说明,所有三元组 RGB 颜色值都按红-绿-蓝顺序指定。

颜色表 - 这两个颜色表,全局和局部的,都是可选的;如果存在全局颜色表,则对数据流中未给出局部颜色表的每个图像使用全局颜色表;如果存在的话,则局部颜色表将覆盖全局颜色表。但是,如果这两个颜色表都不存在,应用程序可以自由使用任意颜色表。如果几个数据流中的图形是相关的,并且都使用相同的颜色表,编码器可以将颜色表作为第一个数据流中的全局颜色表,而让后续数据流没有全局颜色表或任何局部颜色表;通过这种方式,消除了表的开销。建议解码器保存以前的全局颜色表,以便与后面的数据流一起使用,以防它既不包含全局颜色表也不包含任何局部颜色表。一般来说,这允许应用程序使用过去的颜色表、符号来降低开销。

扩展块 - 扩展是使用扩展导引符标记块的开始,后跟标识扩展类型的块标签来定义的。扩展码是范围从0x00到0xFF的数字,包括。特殊用途扩展对解码器是透明的,在在线传输数据流时可以省略。GIF功能对话框为接收方提供了请求传输所有块的条件;在这方面的默认状态是不传输特殊用途块。

保留字段 - 所有保留字段的每个位都被设置为零(关闭)。

附录E. 交错图像

交错图像的行按下列顺序排列:

组1:每 8 行,从第 0 行开始。    (Pass1)  
组2:每 8 行,从第 4 行开始。    (Pass2)  
组3:每 4 行,从第 2 行开始。    (Pass3)  
组4:每 2 行,从第 1 行开始。    (Pass4)  

下面的例子说明了交错图像的行是如何排序的。

Row Number                                        Interlace Pass

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

附录F. 变长编码LZW压缩

变长编码LZW压缩是Lempel-Ziv压缩算法的一种变体,该算法使用变长码替换在原始数据中检测到的模式。算法使用一个从在原始数据中遇到的模式中创建的编码或转换表。将每个新模式输入到表中,并使用其索引在压缩流中替换它。

压缩器从输入流中获取数据,并使用遇到的模式构建一个代码或转换表;每个新模式被输入到代码表中,它的索引被添加到输出流中;当遇到自上次代码表刷新以来检测到的模式时,将其来自代码表的索引放在输出流上,从而实现数据压缩。解压器从压缩后的数据流中取得输入并从中创建出代码或转换表;在处理压缩的数据流时,使用代码对代码表进行索引,并将相应的数据放在解压缩的输出流上,从而实现数据解压缩。下面将解释算法的细节。算法的变长编码基于初始代码大小(lzw -初始代码大小),它指定了用于压缩代码的初始比特数。当压缩器在输入流中检测到的模式数超过用当前位数可编码的模式数时,每个LZW码的位数加1。

表示实际输出图像的光栅数据流可以表示为:

     7 6 5 4 3 2 1 0
    +---------------+
    | LZW 编码大小 |
    +---------------+

    +---------------+ ----+
    |  块大小          |     |
    +---------------+     |
    |                         |     +-- 必要的话重复多次
    |  数据字节     |     |   
    |                         |     |
    +---------------+ ----+

    . . .       . . . ------- 终止LZW压缩数据的代码
           必须出现在块结束符之前.
    +---------------+
    |0 0 0 0 0 0 0 0|  块结束符
    +---------------+

将图像从一系列像素值转换为传输或存储的字符流涉及几个步骤。这些步骤主要是:

  1. 确定代码大小 - 定义表示实际数据所需的比特数。

  2. 压缩数据 - 将一系列图像像素压缩为一系列压缩代码。

  3. 构建一系列字节 - 获取压缩代码集,并将其转换为 8 位字节的字符串。

  4. 打包字节 - 将字节集打包到前面有字符计数和输出的块中。

确定代码大小

压缩数据流的第一个字节是一个值,指示表示实际像素值集所需的最小位数。通常这将与颜色位的数量相同。然而,由于一些算法的限制,具有一个彩色位的黑白图像必须被指示为具有 2 的代码大小。

这个代码大小值还意味着压缩代码的开头必须至少 1 比特长。

压缩数据

LZW算法将一系列数据值转换为一系列代码,这些代码可以是原始值,也可以是指定一系列值的代码。使用文本字符作为类比,输出代码由一个字符或表示字符串的代码组成。

GIF中使用的LZW算法与标准LZW算法在算法上匹配,但有以下差异:

  1. 定义了一个特殊的清除编码,它可以将所有压缩/解压参数和表重置为初始状态。该编码的值是2**<编码大小>。例如,如果指示的编码大小为 4 (图像为 4 位/像素),则清除编码值将为 16 ( 10000 二进制)。清除编码可以出现在图像数据流中的任何一点,因此需要LZW算法像新的数据流开始一样处理后续的编码。编码器应该输出一个清除编码作为每个图像数据流的第一个编码。

  2. 定义了显式指示图像数据流结束的信息结束代码。当遇到此代码时,LZW处理将终止。它必须是编码器为图像输出的最后一个代码。该代码的值是<清除编码>+1。

  3. 第一个可用的压缩码值是<清除编码>+2。

  4. 输出代码的长度是可变的,从<代码大小>+1比特每个编码开始,到每个编码12位。这定义了4095 (0xFFF)的最大代码值。当LZW码值超过当前码长时,码长加1。然后必须修改这些编码的打包/拆包,以反映新的编码长度。

构建 8 位字节

因为用于GIF的LZW压缩创建了一系列可变长度的代码,每个代码在 3 到 12 位之间,这些代码必须转换成一系列 8 位字节,这将是实际存储或传输的字符。这为图像提供了额外的压缩。这些代码形成了一个比特流,就好像它们从右向左排列,然后一次取下 8 个比特输出。

假设每个字符的字符数组为8位,并使用5位代码进行打包,示例布局将类似于:

+---------------+
0|               |    bbbaaaaa
+---------------+
1|               |    dcccccbb
 +---------------+
2|               |    eeeedddd
 +---------------+
3|               |    ggfffffe
 +---------------+
4|               |    hhhhhggg
 +---------------+
       . . .
 +---------------+
N|               |
 +---------------+

注意,物理包装安排将随着每个压缩代码的比特数的变化而变化,但概念保持不变。

打包字节

一旦创建了字节,它们将被分组到用于输出的块中,在每个0到255字节的块前面加上一个字符计数字节。字节数为零的块终止给定图像的光栅数据流。这些块就是GIF图像的实际输出。这种块格式的副作用是允许解码程序在必要时通过读取块计数然后跳过数据来读取实际图像数据。

延伸阅读

[1] Ziv, J. and Lempel, A. : “A Universal Algorithm for Sequential Data Compression”, IEEE Transactions on Information Theory, May 1977.
[2] Welch, T. : “A Technique for High-Performance Data Compression”, Computer, June 1984.
[3] Nelson, M.R. : “LZW Data Compression”, Dr. Dobb’s Journal, October 1989.

附录G. 在线功能对话

注:本节目前(1990年7月10日)正在修订中;这里提供的信息应作为一般指南使用。基于这些信息编写的代码应该以一种灵活的方式进行设计,以适应由于修订而产生的任何更改。

下面定义的序列用于通过交互式通信线路在GIF发送方和GIF接收方之间进行中介控制。这些序列不适用于涉及静态GIF文件下载和不被视为GIF文件的一部分的应用程序。

GIF功能查询

GIF 功能查询序列由主机发出,并请求交互式GIF解码器返回一个响应消息,该响应消息定义了解码器的图形参数。这包括返回有关可用屏幕尺寸、支持的位/颜色数量和支持的颜色细节数量的信息。GIF功能查询的转义序列定义为:

ESC[>0g           0x1B 0x5B 0x3E 0x30 0x67  
GIF功能响应

GIF 功能响应消息由交互式GIF解码器返回,并为软件支持的所有图形模式定义解码器的显示能力。注意,这也可以包括图形打印机和显示器屏幕。此消息的一般格式为:

#version;protocol{;dev, width, height, color-bits, color-res}...<CR>   

'#'            GIF 能力响应标识符字符.  
version        GIF 格式版本号;  初始值 '87a'.   
protocol='0'   解码器传输不支持端到端协议作为直接的8位数据流.    
protocol='1'   是否可以使用CIS B+纠错协议将GIF数据从主机直接交互传输到显示器.  
dev = '0'      屏幕参数设置如下.   
dev = '1'      打印机参数设置如下.   
width          支持的最大显示宽度(像素).   
height         支持的最大显示高度(像素).   
color-bits     每像素支持的比特数。因此,支持的颜色的数量是2**颜色位.   
color-res      硬件调色板中支持的每个颜色组件的位数。如果color-res为'0',则没有可用的硬件调色板表.   

注意,GIF 功能响应中的所有值都以ASCII十进制数字的形式返回,并且消息以回车字符结束。

下面的GIF功能响应消息描述了三种标准的IBM PC增强图形适配器配置,没有打印机;GIF数据流可在纠错协议内处理:

#87a;1;0,320,200,4,0;0,640,200,2,2;0,640,350,4,2<CR>  
进入GIF图形模式

目前定义了两个序列来调用交互式GIF解码器。它们之间唯一的区别是选择了不同的输出媒体。这些序列是:

ESC[>1g     在屏幕上显示 GIF 图像  

              0x1B 0x5B 0x3E 0x31 0x67  

ESC[>2g   直接将图像显示到连接的图形打印机。图像也可以选择性地显示在屏幕上。  

              0x1B 0x5B 0x3E 0x32 0x67

注意,结束每个序列的’g’字符是小写的。

互动环境

从交互式应用程序传输GIF图像数据的假定环境是从主机到微的完整8位数据流。所有256个字符的代码必须是可转移的。为通信建立8位数据路径通常由主机应用程序负责。然而,它取决于支持GIF的接收通信程序能够接收并将所有256个8位代码传递给GIF解码器软件。


参考
翻译工具: