GIF文件格式與結構

GIF是圖像交換格式(Graphics Interchange Format)的簡稱,它是由美國CompuServe公司在1987年所提出的圖像文件格式,它最初的目的是希望每個BBS的使用者能夠通過GIF圖像 文件輕易存儲並交換圖像數據,這也就是它爲什麼被稱爲圖像交換格式的原因了。

GIF文件格式採用了一種經過改進的LZW壓縮算法,通常我們稱 之爲GIF-LZW算法。這是一種無損的壓縮算法,壓縮效率也比較高,並且GIF支持在一幅GIF文件中存放多幅彩色圖像,並且可以按照一定的順序和時間 間隔將多幅圖像依次讀出並顯示在屏幕上,這樣就可以形成一種簡單的動畫效果。儘管GIF最多隻支持256色,但是由於它具有極佳的壓縮效率並且可以做成動 畫而早已被廣泛接納采用。下面筆者詳細介紹GIF文件的格式。

GIF圖像文件是以塊的形式來存儲圖像信息,其中的塊又稱爲區域結構。按照其中 塊的特徵又可以將所有的塊分成三大類,分別是控制塊(Control Block)、圖像描述塊(Graphic Rendering Block)和特殊用途塊(Special Purpose Block)。控制塊包含了控制數據流的處理以及硬件參數的設置,其成員主要包括文件頭信息、邏輯屏幕描述塊、圖像控制擴充塊和文件結尾塊。圖像描述塊包 含了在顯示設備上描述圖像所需的信息,其成員包括圖像描述塊、全局調色板、局部調色板、圖像壓縮數據和圖像說明擴充塊。特殊用途塊包含了與圖像數據處理無 直接關係的信息,其成員包括圖像註釋擴充塊和應用程序擴充塊。下面詳細介紹每一個塊的詳細結構。


1. 文件頭信息

GIF的文件頭只有六個字節,其結構定義如下:
typedef struct gifheader
{
      BYTE bySignature[3];
      BYTE byVersion[3];

}  GIFHEADER;

其中,bySignature爲GIF文件標示碼,其固定值爲“GIF”,使用者可以通過該域來判斷一個圖像文件是否是GIF圖像格式的文件。 byVersion表明GIF文件的版本信息。其取值固定爲“87a”和“89a”。分別表示GIF文件的版本爲GIF87a或GIF89a。這兩個版本 有一些不同,GIF87a公佈的時間爲1987年,該版本不支持動畫和一些擴展屬性。GIF89a是1989年確定的一個版本標準,只有89a版本才支持 動畫、註釋擴展和文本擴展。


2. 邏輯屏幕描述塊

邏輯屏幕(Logical Screen)是一個虛擬屏幕(Virtual Screen),它相當於畫布,所有的操作都是在它的基礎上進行的,同時它也決定了圖像的長度和寬度。邏輯屏幕描述塊共佔有七個字節,其具體結構定義如下:

typedef struct gifscrdesc
{
      WORD wWidth;
      WORD wDepth;
      struct globalflag
         {
            BYTE PalBits   : 3;
            BYTE SortFlag  : 1;
            BYTE ColorRes  : 3;
            BYTE GlobalPal : 1;
         }  GlobalFlag;
      BYTE byBackground;
      BYTE byAspect;
}  GIFSCRDESC;
其中,wWidth用來指定邏輯屏幕的寬度,wDepth用來指定邏輯屏幕的高度,glaobalflag爲全域性數據,它的總長度爲一個字節,其中前 三位(第0位到第2位)指定全局調色板的位數,可以通過該值來計算全局調色板的大小。第3位表明全局調色板中的RGB顏色值是否按照使用率進行從高到底的 次序排序的。第4到第6位指定圖像的色彩分辨率。第7位指明GIF文件中是否具有全局調色板,其值取1表示有全局調色板,爲0表示沒有全局調色板。一個 GIF文件可以有全局調色板也可以沒有全局調色板,如果定義了全局調色板並且沒有定義某一幅圖像的局部調色板,則本幅圖像採用全局調色板;如果某一幅圖像 定義的自己的局部調色板,則該幅圖像使用自己的局部調色板。如果沒有定義全局調色板,則GIF文件中的每一幅圖像都必須定義自己的局部調色板。全局調色板 必須緊跟在邏輯屏幕描述塊的後面,其大小由GlobalFlag.PalBits決定,其最大長度爲768(3*256)字節。全局調色板的數據是按照 RGBRGB…..RGB的方式存儲的。byBackground用來指定邏輯屏幕的背景顏色,也就相當於是畫布的顏色。當圖像長寬小於邏輯屏幕的大小 時,未被圖像覆蓋部分的顏色值由該值對應的全局調色板中的索引顏色值確定。如果沒有全局調色板,該值無效,默認背景顏色爲黑色。byAspect用來指定 邏輯屏幕的像素的長寬比例。


3. 圖像描述塊

一幅GIF圖像文件中可以存儲多幅圖像,並且這些圖像沒有固定的存放次序。爲了區分兩幅 圖像,GIF採用了一個字節的識別碼(Image Separator)來判斷下面的數據是否是圖像描述塊。圖像描述塊以0x2C開始,定義緊接着它的圖像的性質,包括圖像相對於邏輯屏幕邊界的偏移量、圖 像大小以及有無局部調色板和調色板的大小。圖像描述塊由10個字節組成:
  typedef struct gifimage
  {
        WORD wLeft;
        WORD wTop;
        WORD wWidth;
        WORD wDepth;
        struct localflag
           {
              BYTE PalBits   : 3;
              BYTE Reserved  : 2;
              BYTE SortFlag  : 1;
              BYTE Interlace : 1;
              BYTE LocalPal  : 1;
           }  LocalFlag;
   }  GIFIMAGE;
其中,wLeft用來指定圖像相對邏輯屏幕左上角的X座標,以象素爲單位。wTop用來指定圖像相對邏輯屏幕左上角的Y座標。wWdith和 wDepth分別用來指定圖像的寬度和高度。LocalFlag用來指定區域性數據,也就是具體一幅圖像的屬性。LocalFlag的總長度爲一個字節, 其中的前三位用來指定局部調色板的位數,可以根據該值來計算局部調色板的大小。第4位到第5位爲保留位,沒有使用,其值固定爲0。第6位指明局部調色板中 的RGB顏色值是否經過排序,其值爲1表示調色板中的RGB顏色值是按照其使用率從高到底的次序進行排序。第7位表示GIF圖像是否以交錯方式存儲,其取 值爲1表示以交錯的方式進行存儲。當圖像是按照交錯方式存儲時,其圖像數據的處理可以分爲4個階段:第一階段從第0行開始,每次間隔8行進行處理;第二階 段從第4行開始,每次間隔8行進行處理;第三階段從第2行開始,每次間隔4行進行處理;第四階段從第1行開始,每次間隔2行進行處理,這樣當完成第一階段 時就可以看到圖像的概貌,當處理完第二階段時,圖像會變得清晰一些;當處理完第三階段時,圖像處理完成一半,清晰效果也進一步增強,當完成第四階段,圖像 處理完畢,顯示出完整清晰的整幅圖像。以交錯方式存儲是GIF文件格式的一個重要的特點,也是GIF文件格式的一個重要的優點。以交錯方式存儲的圖像的好 處就是無需將整個圖像文件解壓完成就可以看到圖像的概貌,這樣可以減少用戶的等待時間。第8位指明GIF圖像是否含有局部調色板,如果含有局部調色板,則 局部調色板的內容應當緊跟在圖像描述塊的後面。


4. 圖像壓縮數據

圖像壓縮數據是按照GIF-LZW壓縮編碼後存儲於圖像壓縮數據塊 中的。GIF-LZW編碼是一種經過改良的LZW編碼方式,它是一種無損壓縮的編碼方法。GIF-LZW編碼方法是將原始數據中的重複字符串建立一個字符 串表,然後用該重複字符串在字符串表中的索引來替代原始數據以達到壓縮的目的。由於GIF-LZW壓縮編碼的需要,必須首先存儲GIF-LZW的最小編碼 長度以供解碼程序使用,然後再存儲編碼後的圖像數據。編碼後的圖像數據是一個個數據子塊的方式存儲的,每個數據子塊的最大長度爲256字節。數據子塊的第 一個字節指定該數據子塊的長度,接下來的數據爲數據子塊的內容。如果某個數據子塊的第一個字節數值爲0,即該數據子塊中沒有包含任何有用數據,則該子塊稱 爲塊終結符,用來標識數據子塊到此結束。


5. 圖像控制擴充塊

圖像控制擴充塊是可選的,只應用於89a版本,它描述了與圖像控制相關 的參數。一般情況下,圖像控制擴充塊位於一個圖像塊(包括圖像標識符、局部顏色列表和圖像數據)或文本擴展塊的前面,用來控制跟在它後面的第一個圖像(或 文本)的渲染(Render)形式,組成結構如下:
  typedef struct gifcontrol
  {
        BYTE byBlockSize;
        struct flag
           {
              BYTE Transparency   : 1;
              BYTE UserInput      : 1;
              BYTE DisposalMethod : 3;
              BYTE Reserved       : 3;
           }  Flag;
        WORD wDelayTime;
        BYTE byTransparencyIndex;
        BYTE byTerminator;
  }  GIFCONTROL;
其中,byBlockSize用來指定該圖像控制擴充塊的長度,其取值固定爲4。Flag用來描述圖像控制相關數據,它的長度爲1個字節。它的第0位用 來指定圖像中是否具有透明性的顏色,如果該位爲1,這表明圖像中某種顏色具有透明性,該顏色由參數byTransparencyIndex指定。第一位用 來判斷在顯示一幅圖像後,是否需要用戶輸入後再進行下一個動作。如果該位爲1,則表示應用程序在進行下一個動作之前需要用戶輸入。第2-4位用來指定圖像 顯示後的處理方式,當該值爲0時,表示沒有指定任何處理方式;當該值爲1時,表明不進行任何處理動作;當該值爲2時,表明圖像顯示後以背景色擦去;當該值 爲3時,表明圖像顯示後恢復原先的背景圖像。第5-7位爲保留位,沒有任何含義,固定爲0。wDelayTime用來指定應用程序進行下一步操作之前延遲 的時間,單位爲0.01秒。如果Flag.UserInput和wDelayTime都設定了,則以先發者爲主,如果沒有到指定的延遲時間即有用戶輸入, 則應用程序直接進行下一步操作。如果到達延遲時間後還沒有用戶輸入,應用程序也直接進入下一步操作。byTransparenceIndex用來指定圖像 中透明色的顏色索引,指定的透明色將不在顯示設備上顯示。byTerminator爲塊終結符,其值固定爲0。


6. 圖像說明擴充塊

圖像說明擴充塊又可以稱爲圖像文本擴展塊,它用來繪製一個簡單的文本圖像,這一部分由用來繪製的純文本數據(7位的 ASCII字符)和控制繪製的參數等組成。繪製文本藉助於一個文本框(Text Grid)來定義邊界,在文本框中劃分多個單元格,每個字符佔用一個單元,繪製時按從左到右、從上到下的順序依次進行,直到最後一個字符或者佔滿整個文本 框(之後的字符將被忽略,因此定義文本框的大小時應該注意到是否可以容納整個文本),繪製文本的顏色使用全局顏色列表,沒有則可以使用一個已經保存的前一 個顏色列表。另外,圖形文本擴展塊也屬於圖形塊(Graphic Rendering Block),可以在它前面定義圖形控制擴展對它的表現形式進一步修改。圖像說明擴充塊的組成:
  typedef struct gifplaintext
  {
        BYTE byBlockSize;
        WORD wTextGridLeft;
        WORD wTextGridTop;
        WORD wTextGridWidth;
        WORD wTextGridDepth;
        BYTE byCharCellWidth;
        BYTE byCharCellDepth;
        BYTE byForeColorIndex;
        BYTE byBackColorIndex;
  }  GIFPLAINTEXT;
其中,byBlockSize用來指定該圖像擴充塊的長度,其取值固定爲13。wTextGridLeft用來指定文字顯示方格相對於邏輯屏幕左上角的 X座標(以像素爲單位)。wTextGridTop用來指定文字顯示方格相對於邏輯屏幕左上角的Y座標。wTextGridWidth用來指定文字顯示方 格的寬度。wTextGridDepth用來指定文字顯示方格的高度。byCharCellWidth用來指定字符的寬度, byCharCellDepth用來指定字符的高度。byForeColorIndex用來指定字符的前景色,byBackColorIndex用來指定 字符的背景色。


7. 圖像註釋擴充塊

圖像註釋擴充塊包含了圖像的文字註釋說明,可以用來記錄圖形、版權、描述等任何的非圖形和控制的 純文本數據(7位的ASCII字符),註釋擴展並不影響對圖象數據流的處理,解碼器完全可以忽略它。存放位置可以是數據流的任何地方,最好不要妨礙控制和 數據塊,推薦放在數據流的開始或結尾。在GIF中用識別碼0xFE來判斷一個擴充塊是否爲圖像註釋擴充塊。圖像註釋擴充塊中的數據子塊個數不限,必須通過 塊終結符來判斷該擴充塊是否結束。


8. 應用程序擴充塊

應用程序擴充塊包含了製作該GIF圖像文件的應用程序的信息,GIF中用識別碼0xFF來判斷一個擴充塊是否爲應用程序擴充塊。它的結構定義如下:
  typedef struct gifapplication
  {
        BYTE byBlockSize;
        BYTE byIdentifier[8];
        BYTE byAuthentication[3];
  }  GIFAPPLICATION;
其中,byBlockSize用來指定該應用程序擴充塊的長度,其取值固定爲12。byIdentifier用來指定應用程序名稱。byAuthentication用來指定應用程序的識別碼。


9. 文件結尾塊

文件結尾塊爲GIF圖像文件的最後一個字節,其取值固定爲0x3B


  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章