gdフォーマット概要 (not gd2)
libgdのソースコードを眺めつつ、gdフォーマットの内容をまとめてみます。EmuLuaのために調べましたが、通常はgdフォーマットを直接操作せず、一般的なフォーマットをライブラリにやりとりさせる方法が望ましいでしょう。自らの目でより詳細な情報について確かめたい場合、libgdのソースコードに含まれるgd_gd.cを読むとよいでしょう。
gdのフォーマットにはgdとgd2の2種類があるようです。古い形式であるgdフォーマットは、名前からするとgd 2.x以降の更新はなさそうな印象を受けますが、実際はそうでもなさそうです。この先の説明でいくらか1.xや2.xというバージョン表記が出てきますが、これはgdのバージョンを指すものであって、gd2フォーマットは無関係です。
数値はビッグエンディアンで格納されています。
Header
gdフォーマットはgdライブラリ内部で画像データを取り扱うための簡素な形式で、無圧縮のビットマップファイルをさらに簡略化したようなフォーマットです。そのため、ヘッダもあまり複雑でない、とても単純な形をしています。
Size | Note |
---|---|
2 | 65534 = truecolor, 65535 = non-truecolor. truecolorであるかどうかを示します。1.xの頃はこのフィールドが画像の幅であったため、このような値を設定することになっています。 |
2 | im->sx. width (px). 画像の幅です。 |
2 | im->sy. height (px). 画像の高さです。 |
以上の共通部に続いて色の情報が続きます。truecolorかどうかでヘッダに書かれる情報が少し変わってきます。
Size | Note |
---|---|
1 | im->trueColor. 0 = non-truecolor, otherwise = truecolor (usually 1). truecolorかどうかを示します。ヘッダとの食い違いがないよう注意。1.xにこのフィールドはありません。 |
2 | [non-truecolor only!] im->colorsTotal. 画像で使用されている色(パレット)の数を示します。1.xでは必ず存在する1バイトのフィールドです。 |
4 | im->transparent. 画像の透過色です。未使用時には-1(0ffffffffh)を入れておけばよいようです。1.xでは必ず存在する2バイトのフィールドで、未使用時は257です。 |
4*256 | [non-truecolor only!] R,G,B,Aの順に1バイトデータを並べてパレットを表現します。ソースコードを見る限りでは、パレットの個数はgdMaxColors個固定で、gdMaxColors = 256 であることはgd.hの中で定義されています。1.xの場合、Aは存在しません。 |
※gdのRGBAは互換性のため、A = 00h...7fh であり(0 = opaque [不透明], 127 = transparent [透過])、最上位ビットは使用しないことになっています。8bitとの間での入出力には注意が必要です。
ヘッダは以上です。truecolorであれば、2+2+2+1+4の計11バイトをヘッダに持ちます。
Pixels
画像データは至って単純で、左上から右下に向かってピクセルデータを格納しているのみです。ソースコードを抜粋してみましょう。
if (im->trueColor) { for (y = 0; (y < sy); y++) { for (x = 0; (x < sx); x++) { int pix; if (!gdGetInt (&pix, in)) { goto fail2; } im->tpixels[y][x] = pix; } } } else { for (y = 0; (y < sy); y++) { for (x = 0; (x < sx); x++) { int ch; ch = gdGetC (in); if (ch == EOF) { goto fail2; } /* ROW-MAJOR IN GD 1.3 */ im->pixels[y][x] = ch; } } }
truecolorであればA,R,G,Bの値を、そうでない場合は、おそらくパレット番号を格納します。