短い答え
GIFは、カンバスと、その上に塗る長方形の一覧と、その長方形の中の数字が何色を指すのかを決める色表からできています。長方形はそれぞれ3つのものを持っています。どれだけの時間そのままにしておくか、そのあとそれをどうするか、そして必要なら自分専用の色表です。
この形式で驚かれることのほとんどは、その一覧から出てきます。GIFがやたら大きいなら、長方形が毎回カンバス全体になっているか、色表が300個入っているかです。再生が遅すぎるなら、待ち時間がどのブラウザも下回らない床より下だからです。尾を引くなら、後始末と呼ばれる欄のせいです。
手元のファイルがどれなのかを見るには、GIF解析を開いてドロップしてください。このページの残りは、その数字が何を意味するのかの話です。
コマは長方形であって、絵ではありません
GIFを再生された形でしか見たことがない人が驚くのはここです。コマは、その瞬間のアニメーションの絵ではありません。位置と大きさを自分で持つ長方形で、前のコマが残していったものの上に塗られます。
その長方形はカンバス全体でもかまいませんし、できの悪いファイルではいつも全体です。しかしGIFは、前のコマから変わった部分だけを持つことも許されています。絵の大半が止まっている場面では、それが12 MBのファイルと900 KBのファイルの差になります。ほとんど動かない画面の録画が小さく収まるのも、同じ録画が雑な変換器を通ると小さく収まらないのも、これが理由です。
どちらを持っているのかは、再生を眺めても分かりません。見た目は同じです。分かる唯一の方法は、各コマが何を持っているのかを見ることで、解析にその表示があるのはまさにこのためです。各コマが持っているものだけに切り替えると、透明な背景の上に小さな形が並んでいるか、それとも絵全体が何度も並んでいるかが分かります。前者ならエンコーダーは仕事をしていますし、後者ならしていません。
この形式のどこにも動き補償はありません。動画のコーデックがするように「前と同じだが4画素左」という形で保存されることは、決してありません。変わった長方形だけを持つという工夫が、GIFに残された唯一の節約であり、そしてそれは大きな節約です。
待ち時間と、どのブラウザも守らせる床
各コマは、そのコマをどれだけ保つかを100分の1秒の単位で持ちます。形式にはその単位しかないので、ファイルが求められるいちばん速い値は0.01秒、つまり毎秒100コマで、いちばん長い値は約655秒です。
ただし毎秒100コマは手に入りません。どのブラウザも、0.02秒を下回る待ち時間を0.10に切り上げます。この規則は1996年のNetscape Navigatorに書き込まれました。当時の回る地球儀や「工事中」のアニメーションのために書かれ、以後のブラウザはすべてそれを写しました。取り除いたものはなく、これから取り除くものもありません。
ですから、すべてのコマが0.01秒と書かれたGIFは、毎秒100コマではなく毎秒10コマで再生されます。作った側が思っていたより10倍遅く動くわけですが、ファイルはそれをまったく匂わせません。中の待ち時間は、要求されたとおりの値だからです。これはこの形式でいちばんよくある驚きで、解析が長さを2つ出すのもそのためです。ファイルが言う長さと、ブラウザが実際にそうする長さの2つです。
直し方は、どこでファイルを作るにせよ、0.01ではなく0.02と書くことです。それで毎秒50コマになり、それが本当の天井で、たいていの用途には十分すぎるほど速い値です。実際には0.05秒、つまり毎秒20コマあたりが、求める値としてちょうどよい上限です。
待ち時間はもうひとつ教えてくれます。全部同じ値なら、そのファイルは一定の間隔のコマから作られています。値がばらついているなら、たとえばここが0.04であちらが0.11なら、何かが動画を変換する途中でコマを落とし、その穴を埋めるために隣を引き伸ばしています。そして最後の1つだけが他よりずっと長いなら、それは意図したものです。繰り返しの前にアニメーションをひと呼吸置かせる方法がそれです。
後始末。尾を引くかどうかを決める欄
どのコマも、自分の時間が終わったとき画面に何を残すかを持っています。答えは4つあり、知っておく値打ちがあります。アニメーションがおかしく見える4通りのうち3つまでが、この欄の間違いだからです。
- そのまま置く。次のコマがその上から塗ります。コマが不透明で互いを完全に覆う場合に正しく、消す作業がないぶんいちばん安上がりです。
- 背景まで消す。次のコマが来る前に、そのコマの長方形が拭われます。透明を使うならこれが要ります。これがないと、次のコマの透けている部分から前のコマが見えてしまい、別々の絵のアニメーションが絵の山に変わります。
- 下にあったものを戻す。このコマが描く前にカンバスにあったものが戻されます。止まった背景の上を小さなものが動く映像はこう保存されます。各コマはその物体を描き、そのあと背景が戻り、書かれるのは物体の長方形だけです。
- 指定なし。ファイルが何も言っていません。どの表示ソフトも「そのまま置く」として扱いますし、たいていはそれで正しく、ときどきそれが透明なGIFが尾を引く原因になります。
仕様と現実が別れる点がひとつあります。「背景まで消す」は、ファイルの先頭に書かれた背景色を指していますが、どのブラウザもその色を無視して透明に消します。25年前からそうです。その背景色が出ることを当てにしたファイルは、作った人が作った道具の中では正しく見え、それ以外のどこでも間違って見えます。
色表と、それが要する768バイト
GIFの画素は色ではありません。最大256色の表を指す番号で、その1色は3バイトで保存されます。したがって満杯の表は768バイトです。ファイルは全体で1つの表を共有することも、コマごとに持つことも、両方持つこともできます。
どちらの持ち方も正当で、引き換えにするものが違います。
- 共有の表1つなら、ファイル全体で768バイトで済み、色はコマの間で落ち着きます。GIFのちらつき、つまり動画から作ったファイルにあるあの不快な揺らぎは、多くの場合パレットがコマごとに跳ねているだけです。
- コマごとの表は、共有の表にない色を各コマが使えるようにします。場面が丸ごと変わるときに効きます。代償は毎回768バイトです。300コマのアニメーションなら、画素を1つも保存しないうちに色表だけで230 KBです。
もうひとつ、静かな代償があります。色表の長さは2のべき乗でなければならないので、9色しか使わないコマにも16色の表がつき、130色のコマには256色の表がつきます。多少の切り上げは避けられません。画素が一度も参照しない5000色を表が申告しているファイルとなると、話は別です。それは、実際にコマに入った絵とは別の絵のために作られたパレットです。解析は使われていない項目に印をつけるので、その形がひと目で分かります。
バイトが実際に行く先
GIFのバイトは、数えるほどしかない場所のどれかにあります。ファイルが大きすぎると決める前に、それがどこなのかを知っておく値打ちがあります。
- 圧縮された画素。健全なファイルではほぼすべてです。絵そのものをLZWに通したもので、これは1984年の圧縮方式です。表計算の画面を想定して設計されたため、べた塗りには強く、写真には弱いという性格になっています。
- 色表。上のとおり、満杯の表1つあたり768バイトです。
- コマごとの見出し。1コマにつき時間の8バイトと記述の11バイト。ふつうのファイルでは無視できますが、極小のコマが2000枚あるアニメーションでは38 KBになります。
- ブロックの梱包。圧縮されたデータは最大255バイトずつに切られ、それぞれの前に長さの1バイトが付きます。256バイトにつき約1バイトで、避けようがなく、ほかでは見えないので見ておく価値があります。
- メタデータ。コメント、カラープロファイル、XMPの塊です。本当にばかげた結果を生むのはこれで、画像編集ソフトが何年も前の編集を記した40 KBのXMLを置いていくことがあり、小さなGIFではそれがファイルの大半になります。それを描く表示ソフトはひとつもありません。
当て推量ではなく表として眺める理由は、答えがファイルごとに違い、直し方が答えから決まるからです。95 %が圧縮された画素のファイルは、単に絵が多いだけで、コマを減らすか、寸法を小さくするか、色を減らすしかありません。30 %が色表のファイルや40 %がXMPのファイルは、ずっと安上がりな問題を抱えています。
繰り返しは形式の一部ではありません
GIFの仕様には、アニメーションが繰り返すと書く欄がありません。繰り返しは、Netscapeが1995年に考え出したブロックから来ています。中にNETSCAPE2.0という文字列が入った「アプリケーション拡張」で、それでも皆が実装し、いまではインターネット上のあらゆるアニメーションGIFに入っています。
つまり、そのブロックがないファイルは、どのブラウザでもちょうど1回再生して止まり、作った人には壊れて見えます。アニメーションが1回しか流れないなら、そのブロックが抜けています。真っ先に確かめる値打ちのあるもののひとつで、どの表示ソフトでも目には見えません。
ブロックは回数を指定することもできます。5回再生して止まる、といった具合です。0はいつまでもという意味で、ほとんどのファイルにはそう書かれています。
GIFが運べるそのほかのもの
絵をひとつも持たず、どの表示ソフトも読み飛ばすブロックが3つあります。
- コメント。自由な文章で、たいていはファイルを書いたソフトの名前、ときには作者が公開するつもりのなかったものです。表示するものはなく、ファイルの複製はすべてそれを運びます。
- XMP。AdobeのXMLメタデータです。何がいつ編集したか、ときには誰が編集したかまで入ります。末尾に258バイトの魔法の尾がついてきますが、これはブロックの長さのつじつまを合わせる仕掛けで、素直に読むと画面いっぱいのバイナリが出てくる原因でもあります。
- プレーンテキスト。1989年の仕様にある、表示ソフトに対して絵の上へマス目状に文字を描くよう頼むブロックです。実装したものは何もありません。ファイルにこれが入っていても、そこに書かれた文字が現れることはありません。
この3つは、ファイルをどこかへ送る前に知っておく値打ちがあります。GIFのうちあなたについて何かを語りうる部分であり、何かが意図して取り除かないかぎり、複製にも再アップロードにも生き残るからです。
壊れたファイルを読む
GIFは途中で切れます。止まったダウンロード、壊れかけのディスクから救い出したファイル、アプリが半分だけ書いたもの。形式が索引つきの構造ではなくブロックの流れなので、途中で切れたGIFはたいてい切れた所までは読めます。切れ目より前のコマはどれも無傷で完全です。
これは知っておくとよいことです。たいていのソフトはそのファイルをただ受け付けないからです。読める所まで読んで、どこで止まったかを言う解析なら、少なくともどれだけ生き残ったのか、欠けたのが1コマなのか最後の200コマなのかを教えてくれます。
逆の問題もあります。ファイルの終わりの印よりあとに居座っているバイトです。どのデコーダーもその印で止まるので、それらは読まれることも描かれることもなく、たいていは何かの手違いで先頭のファイルに継ぎ足された2つ目のファイルです。純粋な重りで、切り落としても失うものはありません。
これらのどれにもアップロードは要りません
GIFの構造を読むのは重い仕事ではありません。ブロックの一覧をたどることと、小さな展開器がひとつあるだけです。そしてそれをサーバーでやるためにファイルを送る技術的な理由は、これまで一度もありませんでした。ここのGIF解析は、ブロックをたどることも、LZWも、画面に描くコマも、バイトの内訳も、すべてページの中で済ませています。
この作業では、それがほかの多くの作業より大事です。いちばん中を見たくなるファイルは、たいてい人に渡すのがいちばん不安なファイルでもあるからです。救い出したもの、誰かから送られてきたもの、まだ読んでいないコメント欄が入っているもの。ファイルのアップロードについての長い話は、このサイトのどこよりもここに当てはまります。