玄関コンピュータの部屋各種解説コーナーCGファイル概説

2.2 仕様

ファイルヘッダ
ビットマップヘッダBITMAPINFO
ビットマップヘッダ

カラーマップ
カラーマップ
オプション
ビットマップイメージデータ

BMPファイルは大きく分けると左図のようなブロックからできています。 また、マルチバイトデータはIntelの規約に従い下位バイトが先に保存されます。 つまり、メモリ上の並び方と逆転するわけです。

(1) ファイルヘッダ(BITMAPFILEHEADER)

オフセット内容(バイト数)
0ファイル識別子(2)
固定値"BM"(424DH)
2ファイルサイズ(4)
バイト単位
6予約1(2)
固定値0
8予約2(2)
固定値0
10ビットマップイメージデータ開始位置(4)
バイト単位のオフセット値

このファイルヘッダはWindowsとOS/2で共通な部分です。

1) ファイル識別子(bfType)

ビットマップファイルであることを識別するためのデータで、常にASCII文字の「BM(424DH、16進)」です。

2) ファイルサイズ(bfSize)

BMPファイルのファイルサイズをバイト単位で表した値です。 このデータを利用すると、アプリケーションプログラムがBMPファイルを読み込む場合に、確保すべきメモリ量をあらかじめ計算することができます。

3) 予約1と予約2(bfReserved1、bfReserved2)

将来の仕様拡張用の予約領域で、現在は固定値0です。

4) ビットマップイメージデータ開始位置(bfOffbits)

ファイル中でのイメージデータの開始位置をバイト単位で表したオフセット値です。 このデータを利用すると、アプリケーションプログラムがビットマップヘッダ部分をスキップして、イメージデータ部分に直接アクセスすることができます。

(2) ビットマップヘッダ(BITMAPINFOHEADER)

オフセット内容(バイト数)
14ヘッダサイズ(4)
固定値40
18イメージの横幅(4)
ピクセル単位
22イメージの高さ(4)
ピクセル単位
26プレーン数(2)
固定値1
281ピクセル当たりのビット数(2)
1,4,8,24
30圧縮形式(4)
0,1
34圧縮後のイメージサイズ(4)
バイト単位
38水平解像度(4)
ピクセル/メートル
42垂直解像度(4)
ピクセル/メートル
46使用色数(4)
21ピクセル当たりのビット数以内
50重要な色数(4)
使用色数以内

このビットマップヘッダはWindows独自のもので、カラーマップ部分と合わせてBITMAPINFOと呼ばれます。

1) ヘッダサイズ(biSize)

ビットマップヘッダのサイズをバイト単位で表した値で、常に固定値40です。 OS/2のBMPファイルはヘッダサイズが12であり、このデータによって両者を区別することができます。

2) イメージの横幅と高さ(biWidth、biHeight)

画像の横幅(水平方向)と高さ(垂直方向)をピクセル単位で表した値です。

3) プレーン数(biPlanes)

ビットマッププレーンの数です。 このデータはビットマップイメージデータをプレーン優先フォーマットで保存した場合のプレーン数のことで、フレームバッファそのもののプレーン数ではありません。 したがって、カラーマップモデルやピクセル優先フォーマットの場合は1になります。

現在のところBMPファイルはプレーン優先フォーマットをサポートしていませんから、常に固定値1です。

4) 1ピクセル当たりのビット数(biBitCount)

フレームバッファの深さで、1、4、8、24の4種類があります。

5) 圧縮形式(biCompressin)

圧縮法を表す値で、0が非圧縮、1がRLE圧縮です。

6) 圧縮後のイメージサイズ(biSizeImage)

圧縮後のビットマップイメージデータのサイズをバイト単位で表した値です。 非圧縮の場合は圧縮しないビットマップイメージデータのサイズか、もしくは0が入っています。

7) 水平解像度と垂直解像度(biXPelsPerMeter、biYPelsPerMeter)

ディスプレイの水平方向と垂直方向の解像度をピクセル/メートル単位で表した値です。 このデータを利用して、画像を保存したディスプレイ上に表示されていた時の画像の実寸を計算することができます。 しかし画像表示プログラムがこのデータを利用することはほとんどなく、実質的には無視されるデータです。(^^;)

8) 使用色数(biClrUsed)

画像で使用されている色数を表す値であると同時に、カラーマップのエントリ数でもあります。 カラーマップの最大エントリ数は2biBitCount、つまり1ピクセル当たりのビット数が1、4、8ビットの場合、それぞれ2、16、256個となりますが、このデータはその値より小さい場合もあります。 カラーマップのエントリ数が最大エントリ数と等しい場合は、このデータが0の時もあります。

また1ピクセル当たりのビット数が24の場合はダイレクトカラーモデルであり、カラーマップはありませんが、カラーテーブルの推奨サイズを示すためにこのデータが0ではない場合もあります。 このあたりの仕様の不明瞭さは、全くもってプログラマ泣かせです。(~.~)

9) 重要な色数(biClrImportant)

使用色数のうち画像にとって重要な色の数を表す値で、それらの重要色はカラーマップの先頭の方に配置されている必要があります。 このデータが0の場合は使用色数すべてを重要色として扱います。 このパラメータはWindowsシステムが独自の目的で利用する特殊なもので、一般にはほとんど利用されていません。

このパラメータを利用した例としては、Windows95の起動画面における擬似アニメーション表示があります。 「Windows95」というロゴを表示する起動画面は、ルートディレクトリの下にある「LOGO.SYS」という名前のBMPファイルを表示しています。 この画面の下部のチラチラと動いている青い帯状の部分は、重要色以後のカラーパレットの色を使って描かれており、そのカラーパレットを順に入れ替えることによって擬似アニメーション表示を行っているのです。

DOS/V系のWindows95では256色のLOGO.SYSファイルを用い、重要色数を236として最後部の20個のカラーパレットを擬似アニメ表示に利用しています。 それに対してPC-98系のWindows95では16色のLOGO.SYSファイルを用い、重要色数を9として最後部の7個のカラーパレットを擬似アニメ表示に利用しています。 この重要色数を0または使用色数と同じ値に設定した場合は、カラーパレットの色の入れ替えは行われず擬似アニメ表示はされません。

ペイントブラシのようなグラフィックエディタを利用してLOGO.SYSファイルの内容を修正しますと、自分だけのオリジナルな起動画面を表示させることができます。 しかし通常のグラフィックエディタは重要色数を0に設定してファイルに保存しますので、LOGO.SYSファイルを修正した場合、擬似アニメ表示は行われなくなってしまいます。 そのような場合には、修正されたLOGO.SYSファイルの重要色数を正しい色数に訂正すれば、再び擬似アニメ表示が行われるようになります。 そのためのフリーソフトもありますが、自分で作成するのも比較的簡単です。 自作の画像ファイル変換ソフトgfcにその機能を入れたため、僕のWin95の起動画面は「Windows99」になっています。(^^)v

(3) カラーマップ(RGBQUAD)

オフセット内容(バイト数)
54カラーマップエントリ0番の青の値(1)
0-255
55カラーマップエントリ0番の緑の値(1)
0-255
56カラーマップエントリ0番の赤の値(1)
0-255
57予約(1)
固定値0
::

カラーマップの内容を保存したブロックで、1ピクセルあたりのビット数biBitCountが1、4、8ビットの場合に存在し、24ビットの場合は存在しません。 biBitCountが1ビットの場合もカラーマップが存在しますから、1ビットの場合は「モノクロモデル」ではなく「2色カラーモデル」となります。

1) カラーマップエントリ(rgbBlue、rgbGreen、rgbRed、rgbReserved)

カラーマップエントリは青(rgbBlue)・緑(rgbGreen)・赤(rgbRed)の値を表す1バイトの符号無し整数が3個と、値0の予約バイト(rgbReserved)が1バイトあり、全体として4バイトで構成されています。 通常、カラーマップのエントリ数biClrUsedは2・16・256ですが、場合によってはそれよりも少ないこともあります。 そして、カラーマップブロック全体のサイズはbiClrUsed×4バイトとなります。

(4) ビットマップイメージデータ

フレームバッファの内容を保存したブロックで、ディスプレイ上の画像の一番下の行から上へ1行単位で保存されます。 行中のピクセルは左端から順番に保存され、各行のバイト数が4の倍数になるように、行の末尾に値0のバイトデータがパディングされます。 このため、非圧縮の場合のイメージデータサイズbiSizeImageは次のようになります。(int()は切り捨てによる整数化関数です)

1行バイト数=int([int({biWidth×biBitCount+7}/8)+3]/4)×4
biSizeImage=1行バイト数×biHeight

1ピクセルあたりのビット数が4と8の場合はRLE方式で圧縮されることがありますので、biSizeImageはこの値とは異なります。

1) 1ピクセルあたり1ビットの場合

ビット
76543210
P0P1P2P3P4P5P6P7
(最下行左端から8ピクセル分)
:

行の左端から8ピクセル分ずつが1バイトにパックされます。 バイト中では上位ビットから順にパックされ、バイトの途中で行が終了した時は、下位ビットに0がパディングされます。

2) 1ピクセルあたり4ビットの場合

ビット
76543210
P0P1
(最下行左端から2ピクセル分)
:

行の左端から2ピクセル分ずつが1バイトにパックされます。 バイト中では上位4ビットから順にパックされ、バイトの途中で行が終了した時は下位4ビットに0がパディングされます。 このデータは4ビット単位のRLE方式で圧縮される場合があります。

3) 1ピクセルあたり8ビットの場合

P0
最下行左端のピクセル
P1
最下行左端から2番目のピクセル
:

行の左端から1ピクセル1バイトで保存されます。 このデータは8ビット単位のRLE方式で圧縮される場合があります。

4) 1ピクセルあたり24ビットの場合

P0のB
最下行左端のピクセルの青の値
P0のG
最下行左端のピクセルの緑の値
P0のR
最下行左端のピクセルの赤の値
:

行の左端から1ピクセル3バイトのピクセル優先フォーマットで保存されます。 ピクセル中のRGBの値はB・G・Rの順に並びます。