HTTPで無圧縮GIFの利用


経緯
 CGIカウンタでGIFを生成しているが、LZWの特許に抵触しないように
無圧縮GIFを使うようにした。
 電波が飛んで来たためである。

問題点
 サイズが大きくなる(無圧縮だから)

問題点の解決
 HTTPプロトコルでは、Content-Encodingを指定することで転送データ
にエンコードをかけた形で送ることができます。
 通常のブラウザであれば、エンコード形式としてgzipがサポートされ
ています。
 ということは、無圧縮GIFをgzipで圧縮してしかるべきヘッダーをつけ
て送り出してやればサイズの問題も解決できます。
 が、netscapeはimg srcでは、gzipエンコードを使えないのであった。

実際の方法
 HTTP_ACCEPT_ENCODINGを調べて、gzipに対応しているかどうか確認し
ます。
 ネットスケープは、"gzip"を、IEは"gzip、 deflate"を指定してきます。
古いブラウザでは、x-gzipを指定してくるかもしれません。

 対応していなければ、しょうがないので、無圧縮のまま送り出します。
対応していることが確認できたら、データをgzipで圧縮し、ヘッダーに
  Content-Encoding: gzip
  Content-Transfer-Encoding: gzip
をつけて送り出します。

Content-Transfer-EncodingはHTTPでは必要ないと思いますが、念のため
つけています。
HTTP_ACCEPT_ENCODINGがx-gzipだった場合は、Content-Encodingもx-gzip
にしなければいけません。
 ちなみに、netscapeはx-gzipでもgzipでも受け付けますが、IEはx-gzip
は受け付けません。

GIFの無圧縮化
 方法は簡単です。
 lzwでは、過去にあったパターンをそのパターン番号に置きかえることで
圧縮しています。
 過去にないパターンの時は、新しいデータをそのままコード化しています。
 ということは、過去に同じパターンがあったとしても常に新しいデータだ
としてコード化してやれば、展開プログラムは正しく復元します。
 つまり辞書部分をすっぱりなくして、データをそのままコード化すれば、
できあがりです。

CGI以外でのgzip化無圧縮GIFの利用
 webサーバー次第ですが、apacheは標準でEncodingにgzipを使用できるよう
になっています。
 apacheのhttp.confでAddEncoding x-gzip gzと指定してあればなにもしない
で使用できます。
 *.gifをgzipで圧縮して、*.gif.gzを作ります。サーバーには、*.gif.gzの
みを置きます。htmlからは、何も考えずに、*.gifを参照するように書きます。

 ブラウザからgzipエンコードを受け付けないといわれない限り、apacheは
*.gif.gzをgzipエンコードされているgifと言って送ってきます。
 ちなみにgzipを受け付けない(ACCEPT-ENCODING: noneとか)と言ってリク
エストを送ると、apacheはgzipされたのならばあるんだけどと答えてきます。

追記1:
 Netscapeでinline画像に使えないことが判明。
追記2:
 IE5以上を判別して使ってみたが、ふとしたことで表示できなくなるようで
 こちらもアウト。
追記3:
 Content-Lengthを出してやれば、IEで表示できなくなるのは回避できる模様。
 ZLIBを改造して、Content-Lengthを出して運用中。
 いまのところ不具合報告は見かけない。