GIF画像について解説します。
GIF(ジフ)とは「グラフィックス・インタチェンジ・フォーマット」の略で、旧くからウェブで用いられている画像形式です。
西暦1987年(昭和62年)に米国のコンピュサーヴ社(現AOL社)が自社のパソコン通信サーヴィスで画像のやり取りを可能にするためのフォーマットとして策定、西暦1989年(平成元年)には更に拡張したGIF89a規格も策定されました。
GIF画像形式の主な特徴は以下の通りです。
かつては、基幹技術であるLZW圧縮技術に特許問題が絡んだため、代替技術としてPNG画像も考案されましたが、今でも「枯れた技術」として一部を除く一般ユーザの間で高い支持を受けております。
GIF画像ファイルを作成するに当たって、以下の約束事があります。
2オクテットからなる数値データは、下位オクテットから収納されます(リトルエンディアン)。
画像データはビット数不定のバイナリデータですが、データの下位ビットが収納先の下位ビットに対応します。
また、この結果収納先の最後のオクテットは上位ビットが空く事があります。
GIF画像ファイルは、幾つかのブロックから成り立ちます。
具体的には、ファイルの先頭から、以下のような配列となります。
一画像のデータ(以下のデータが個数分入る)
GIF画像ファイルの先頭に必ず無ければならないブロックです。
シグネーチャとは直訳すると「署名」と言う意味で、ここでは「GIF」と言う文字が入ります。
本システムを含むGIFデコーダは必ずこのデータを確認してから処理しなければなりません。
ヴァージョンは現在のところ、西暦1987年(昭和62年)策定の「87a」と西暦1989年(平成元年)策定の「89a」の二つのみとなっております。
実際には本システムでは87aヴァージョンも89aヴァージョンも同じように処理できます。
GIF画像における拡張ブロックとは、GIF画像の機能を拡張するために定義されたブロックで、アプリケーションにより様々な使い方が出来ます。
後述のコントロールブロックはこの拡張ブロックの一種(仕様書により定義されたもの)となります。
実際には本システムではコントロールブロックを除いて全て無視しますが、無視するためにも拡張ブロックの構造を明らかにしておく必要があります。
拡張ブロックの構造は以下の通りです。
小ブロックは 1オクテット〜256オクテットからなるブロックで、必要な情報を表すためにはいくつでも並べる事が出来ます。
先頭は内容の大きさ( 0〜255)、その後に小ブロックの内容が入りますが、特に先頭が「 0」の小ブロック(内容を持たない小ブロック)は小ブロック列の終わり、すなわち当該拡張ブロックの終わりを意味します。
GIF画像における画像情報ブロックには、GIF画像ファイル全体に亘って有効な情報が入ります。
画像ファイル共通のパレットに関する情報です。
特に個別パレットが指定されていない画像データは、このパレットに従います。
具体的には、共通パレットを用いる場合は第 7ビットを 1にして、実際に利用する色数のビット数から 1を引いた値( 0〜 7)を第 0〜第 2ビットと第 4〜第 6ビットにそれぞれ入れます。
共通パレットが定義されている場合は、この位置にパレットデータが入ります。
具体的な内容は、パレット番号0から順に、赤・緑・青成分が 1オクテットづつ入ります。
尚、実際に利用されるされないに拘らず、定義されうる全てのパレットコードに対してパレットデータが割当てられていなければなりません。
すなわち、17色しか用いていない場合でも、色数が 5ビット(17〜32色)の場合は32色分のパレットを用意しなければなりません。
GIF画像におけるコントロールブロックは、拡張ブロックの一種で、アニメーションGIFまたは透過GIFを実現するために用いられます。
本システムでは、透過GIFを行うか否かを判断するためだけにこのブロックを解析しております。
具体的には以下のようになります。
コントロールブロックの第一小ブロックは 5オクテットからなります。
すなわち、内容 4オクテットを表す「 4」と言うデータと内容 4オクテットから成ります。
内容は以下の通りになります。
透過するか否かなどの情報が入ります。
透過GIFにするには、このオクテットの第0ビットを1にします。
アニメーションの場合、画像をずらすタイミングを指定します。
透過GIFのみを利用するなら、この値は「0」で構わない事になります。
GIF画像のメインとなるものです。
GIF画像形式は、PNG画像などの他の画像形式と異なり、一本のファイルに複数の画像データが入り得ます。
ブロックの構成は以下の通りになります。
共通画像情報によって指定された枠内での相対座標で、X座標・Y座標の順に入ります。
画像データの幅・高さの順で入ります。
当該画像データのみで有効な個別パレット(局所(ローカル)パレット)に関する情報と、インタレース扱いにするか否かに関する情報が入ります。
具体的には、個別パレットを用いる場合は第 7ビットを 1にして、実際に利用する色数のビット数から 1を引いた値( 0〜 7)を第 0〜第 2ビットに入れます。
またインタレースを用いる場合は第 6ビットを 1にします。
個別パレットが定義されている場合、この箇所に個別パレット情報が入ります。
具体的な内容は、パレット番号 0から順に、赤・緑・青成分が 1オクテットづつ入ります。
尚、実際に利用されるされないに拘らず、定義され得る全てのパレットコードに対してパレットデータが割当てられていなければなりません。
データ本体は、まずLZW圧縮における最小ビット数のデータ( 1オクテット)で始まり、以後256オクテット以内の小ブロックが続きます。
小ブロックは、内容の大きさを表す 1オクテットと内容からなります。
先頭の 1オクテットが「 0」の小ブロックはそこで小ブロックの並びが終わると言う事を意味します。つまり、小ブロックの先頭が「 0」で無い限りその内容を取得し続け、先頭が「 0」である小ブロックを検出したらそこで処理は完了するという事になります。
十六進数で[3B]となるデータを収めた 1オクテットのブロックで、GIF画像ファイルの一番最後に必ず設置されていなければなりません。
上述の通り、GIF画像形式には西暦1987年(昭和62年)策定のGIF87a形式と西暦1989年(平成元年)策定のGIF89a形式の二つのヴァージョンがあります。
これらのヴァージョンの違いとして、GIF89a形式では拡張ブロックが定義されたと言うのがあります。
これにより、GIF89a形式ではGIF87a形式に以下の機能が追加されました。
GIF画像においては、複数の画像を一本のファイルに纏めて封入する事が出来ます。
これを利用して、アニメーションを実現させる事も出来ますが、そのためにはGIF89a形式にしなければなりません。
GIF画像でアニメーションを実現したい場合は、ネットスケープ拡張ブロックを共通画像情報ブロックの直後に設置します。
ネットスケープ拡張ブロックはネットスケープ社が自社ブラウザに搭載するために策定したもので、他社ブラウザでもGIFアニメーションに対応している製品なら、全て同様にサポートされます。
参考までに、ネットスケープ拡張ブロックの具体的なフォーマットを解説しておきます。
内容の長さを表す3のあと、以下の情報が入ります。
繰返しの範囲は、当該アニメーションGIF画像ファイル全体に亘ります。
一般に公開されているGIF連結スクリプト「gifcat.pl」は、一つのGIF画像に複数の画像データを収納出来る
事に着目したものです。
具体的には、連結されるGIF画像の共通画像情報ブロックや画像情報ブロックを切り出して、並べ替えるという処理を行っております。
GIF画像においては、圧縮前・展開後の画像データは、一番上のラインから一番下のラインへ、各ラインは左端から右端へ、 1ピクセルを 1オクテットで表します。
但し、インタレース扱いとなっている場合は、このラインを入れ替える事で、画像展開完了前に全体に亘って画像を描画する事が出来るようにします。
具体的には、インタレース扱いでは、以下の順に入れ替えられます。
GIF画像の基幹技術である圧縮アルゴリズムについて、簡単に説明します。
基本的には、LZW圧縮アルゴリズムを拡張したものです。
LZW圧縮は、LZ77圧縮を改良したもので、予め読込んだデータを辞書登録する事で、圧縮効率を高めると言うものです。
展開の際には、読込んだデータをもとに辞書を作成して行き、圧縮された符号を検出した場合はその符号が示すデータを辞書から取り出して行きます。
LZW圧縮アルゴリズムは、長い間米国ユニシス社の特許となっておりましたが、平成16年 6月20日、日本国内における特許権が失効しました。
本家米国では西暦2003年(平成15年) 6月20日に特許権が失効しており、一番最後まで残った加国も西暦2004年(平成16年) 7月 7日に失効し、もはやGIF画像におけるLZW圧縮アルゴリズムの利用は何の問題も無くなっております。