読者です 読者をやめる 読者になる 読者になる

ごちゃログぴこっ

はなまるデジタル創作紀行(DTM、TAS、いろいろな技術)

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の値を、そうでない場合は、おそらくパレット番号を格納します。