GIF ファイル形式
Graphics Interchange Format — インデックスカラーの画像と簡易アニメーション。
- MIME タイプ
- image/gif
- 拡張子
- .gif
- カテゴリ
- 画像
マジックナンバー(ファイル署名)
| 0x00000000 | 474946383961 | GIF89a | 'GIF89a' (or 'GIF87a') |
GIF 形式について
GIF は 1 フレームあたり 256 色のパレットに制限される一方、ループアニメーションと 1 ビットの透過に対応しており、それがミーム時代まで生き延びた理由です。ヘッダは仕様バージョンを示す ASCII 文字列 GIF87a か GIF89a で、その直後に 7 バイトの論理画面記述子が続き、キャンバスの大きさとグローバルカラーテーブルの構成を伝えます。そこから先はブロックの連なりで、それぞれ 1 バイトで始まります。2C なら画像、21 なら拡張ブロック、3B ならファイルの終わりです。画素はパレットのインデックスを LZW で圧縮し、画像ごとに可変長の符号ストリームを 1 本持ちます。写真の GIF が元の JPEG より大きくなりがちなのはそのためです。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 3 | Signature | 47 49 46、ASCII の GIF。どちらのバージョンでも固定で、仕様のどの版を受け入れるかを決めずに検出器が頼れるのはこの 3 バイトだけです。 |
| 3 | 3 | Version | 87a なら 38 37 61、89a なら 38 39 61。これは画像データではなく、この先どの種類のブロックが現れてよいかについての申告で、エンコーダは実際に使った機能を満たす最小のバージョンを書くことになっています。 |
| 6 | 2 | Logical screen width | キャンバス幅をピクセルで表すリトルエンディアンの 16 ビット。バイト順に注意してください。GIF は PNG より古く、数値を逆順に格納するので、40 00 は 16384 ではなく 64 です。キャンバスは個々のフレームの大きさとは限りません。 |
| 8 | 2 | Logical screen height | キャンバス高さのリトルエンディアン 16 ビット。個々のフレームはファイルの後ろで自分の位置と大きさを持ち、これよりずっと小さいこともあります。アニメーション GIF が変化していない部分を送り直さずに済むのは、まさにこの仕組みです。 |
| 10 | 1 | Packed screen descriptor fields | ビット 7 が立っていればグローバルカラーテーブルが続きます。ビット 6〜4 は元画像の色分解能、ビット 3 はソートフラグ。ビット 2〜0 が N を保持し、テーブルには 2 の (N+1) 乗個のエントリが入ります。よくある値 6 なら 128 色、7 なら 256 色すべてです。 |
| 11 | 1 | Background colour index | グローバルカラーテーブルへのインデックスで、どのフレームも塗っていないキャンバス領域に使われます。ほとんどのデコーダはこれを無視して未描画部分を透明として扱うので、あるビューアでは正しく見えて別のビューアでは色の縁が出る GIF は、このバイトをめぐって揉めています。 |
| 12 | 1 | Pixel aspect ratio | 0 は情報なしという意味で、事実上すべてのファイルがそう書いています。それ以外の値 V は画素アスペクト比が (V + 15) / 64 であることを表す、正方形でない画素を持つディスプレイ時代の名残です。 |
| 13 | variable | Global colour table | パックドバイトのビット 7 が立っているときだけ存在し、その場合はちょうど 2 の (N+1) 乗 × 3 バイトの RGB 三つ組が並びます。128 エントリなら 384 バイトです。N を読み違えると以降のバイトオフセットが全部ずれるので、1 バイトの編集で GIF を壊す手段としては最も効果的です。 |
| -1 | 1 | Trailer | ASCII のセミコロンにあたる 3B が 1 バイト、これでファイルが終わります。後ろに何があっても無視され、これが無いことがダウンロード途中切れの最速の判定材料です。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| GIF87a/GIF89a | 違いはオフセット 3 の 3 バイトだけで、ヘッダの他の部分は同じです。89a で追加されたのはグラフィック制御拡張、つまりフレーム遅延・廃棄方法・透過色インデックスを運ぶ 21 F9 ブロックと、アプリケーション拡張です。したがってアニメーションするファイルや透過を少しでも持つファイルは 89a を名乗らなければなりません。不透明な静止画なら 87a を名乗っても嘘ではなく、macOS の sips などは今もそう書きます。 |
| Netscape looping extension | GIF 仕様にはアニメーションをループさせる規定がありません。あの挙動は 21 FF 0B に続けて ASCII 11 バイトの NETSCAPE2.0 を書いたアプリケーション拡張ブロックから来ていて、その後ろのサブブロックの 2 バイト目と 3 バイト目がリトルエンディアンのループ回数、0 なら無限です。先頭数百バイトから 4E 45 54 53 43 41 50 45 を探してください。無ければ、エディタの画面で何度回っていようと再生は 1 回きりです。 |
| PNG | 89 50 4E 47 と 47 49 46。透過付きの可逆なインデックス画像という点で用途が重なりますが、その用途では PNG の完勝です。透過は 1 インデックスではなく完全なアルファ、色は 256 色パレットではなくチャンネルあたり最大 16 ビット、圧縮率も上。GIF に残された唯一の強みは、video 要素なしでアニメーションすることだけです。 |
| WebP | アニメーション WebP は同じ仕事をはるかに少ないバイト数でこなす RIFF ファイルで、オフセット 0 に 52 49 46 46、オフセット 8 に 57 45 42 50、オフセット 12 にアニメーションフラグを立てた VP8X チャンクが並びます。今どきのチャットや SNS の多くは、アップロードされた GIF を WebP や MP4 に変換したうえで、同じ .gif の URL で配信し続けています。 |
よくある壊れ方
- 途中切れ。ヘッダとパレットは無事なのでビューアはキャンバスの大きさを把握し、届いた分のフレームだけ描いて止まります。末尾に 3B のトレーラが無いことが決め手で、最後のフレームが途中までしか届いていない場合は LZW ストリームが尽きたところが単色の帯になります。
- グローバルカラーテーブルのサイズが誤っている場合。オフセット 10 のバイトの下位 3 ビットが後続するパレットのバイト数を決めるので、ニブルが 1 つ狂っただけで最初のブロックの開始位置が数百バイトずれ、他のバイトがすべて正しくてもファイルは読めなくなります。
- LZW ストリームの同期ずれ。符号は可変長でバイト境界をまたいで詰め込まれ、位置合わせの仕組みがないので、1 ビット反転するとそのフレームの残りが斜めのノイズになります。フレームごとにストリームが独立しているため、被害は次の画像ブロックで止まり、アニメーションの最後まで伝播することはありません。
- Netscape アプリケーション拡張の消失。未知の拡張ブロックを保持しないツールを通して再エンコードするとループ回数が黙って落ち、無限に回っていたアニメーションが 1 回で止まるようになります。ファイルとして不正なところは何もないので、どのツールも問題を報告しません。
- 廃棄方法の書き換え。各グラフィック制御拡張にある 3 ビットの廃棄フィールドが、次のフレームを描く前に今のフレームを消すかどうかを決めます。変換ツールが誤った値を書くと、フレームが前のフレームの上に積み重なっていく、あの尾を引く描画になります。ファイル自体は正しく、ただアニメーションの仕方が間違っているだけです。
この形式の現在地
GIF は 10 年前に引退していてもおかしくない形式ですが、消える気配はありません。理由はひとつ、video 要素もコーデックのライセンスも再生ボタンも要らずに、あらゆるレンダラ、メールクライアント、チャット、Wiki の中でそのまま動く唯一のアニメーション画像形式だからです。短いループクリップなら、アニメーション WebP やミュートした MP4 のほうが数分の一のサイズでしかも高画質だとしても、いちばん摩擦の少ない選択肢であり続けています。大手プラットフォームの多くが .gif のアップロードを受け付けたうえで裏で WebP や H.264 に変換し、URL の拡張子だけ据え置いているのはそのためです。静止画としての出番はもう完全にありません。1 フレーム 256 色と完全透過 1 色というパレットではあらゆる面で PNG に負けますし、かつて敬遠された LZW 特許も 2004 年に切れました。今も本当に価値があるのは、小さな UI アニメーションやスピナー、そして地味ですが、ファイル本体より周りの HTTP ヘッダのほうが大きいマーケティングメールの 1 ピクセル計測画像です。
GIF ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
GIF と混同しやすい形式です。先頭バイトを見比べてください。