BMPファイルのバイナリ構造の解説。
BMPファイルのバイナリ構造は、データの先頭から順に以下のような構成要素を持つ。
このうち、ビットフィールドとカラーパレットについては情報ヘッダの内容次第で存在しないことがある。
また、イメージデータは情報ヘッダの内容によって形式が大きく変わる。
なお、BMPバイナリ中にある2バイト及び4バイトの整数値データのバイトオーダはリトルエンディアンであり、符号付き整数値の場合は最上位ビットを符号ビットとする2の補数表現を用いる。
Windows環境しか考慮しないのであればバイトオーダを気にする必要はないが、プラットフォームに依存しないコードを記述する際には留意すること*1。
ファイルヘッダはBMPファイルのバイナリ構造において最初に現れる必要があり、以下の構成要素を持つ。
要素 | バイト数 |
---|---|
ファイルタイプ | 2 |
ファイルサイズ | 4 |
予約1 | 2 |
予約2 | 2 |
イメージデータオフセット | 4 |
以下に各構成要素の詳細を述べる。
'B'
、2バイト目が 'M'
となる。0
を格納しても構わない。0
を格納するべきである。0
を格納しても構わない。0
以外であった場合は信用するべきである。Win32 SDK環境では、これらの構成を定義した BITMAPFILEHEADER
構造体が存在する。
1
2
3
4
5
6
7
| - | | | | | ! |
|
情報ヘッダはファイルヘッダのすぐ後に続いて現れる必要があり、以下の4種類が存在する。
これらのうち、現在一般的なBMPファイルに使われているのはINFOタイプである。
エンコーダはこのタイプさえ書き出せるならば問題はなく、デコーダは最低でもこのタイプに対応する必要がある。
どの情報ヘッダタイプにおいても最初の4バイトは必ずヘッダサイズとなる。
よって複数のタイプに対応するデコーダは、まず最初の4バイトを読み取り、その数値で情報ヘッダタイプを判別する。
COREタイプはOS/2で使われていた情報ヘッダ形式で、以下の構成要素を持つ。
要素 | バイト数 |
---|---|
ヘッダサイズ | 4 |
幅 | 2 |
高さ | 2 |
プレーン数 | 2 |
ピクセル毎のビット数 | 2 |
以下に各構成要素の詳細を述べる。
12
となる。1
以上でなければならない。1
となる。1
、 4
、 8
、 24
のいずれかとなる。0
、 16
、 32
は無効である。Win32 SDK環境では、これらの構成を定義した BITMAPCOREHEADER
構造体が存在する。
1
2
3
4
5
6
7
| - | | | | | ! |
|
INFOタイプは最も標準的な情報ヘッダ形式で、以下の構成要素を持つ。
なお、INFOタイプはV4タイプ及びV5タイプに内包されているため、これらのタイプに対応するデコーダはINFOタイプについて考慮する必要はない。
要素 | バイト数 |
---|---|
ヘッダサイズ | 4 |
幅 | 4 |
高さ | 4 |
プレーン数 | 2 |
ピクセル毎のビット数 | 2 |
圧縮タイプ | 4 |
イメージデータサイズ | 4 |
水平解像度 | 4 |
垂直解像度 | 4 |
カラーインデックス数 | 4 |
重要インデックス数 | 4 |
以下に各構成要素の詳細を述べる。
40
となる。1
以上でなければならない。0
であってはならない。1
となる。0
、 1
、 4
、 8
、 16
、 24
、 32
のいずれかとなり、この値によって圧縮タイプの取りうる値が変わる。0
(Win32 SDK環境では定数 BI_RGB
と同値)0
であってはならない。1
(Win32 SDK環境では定数 BI_RLE8
と同値)8
でなければならない。2
(Win32 SDK環境では定数 BI_RLE4
と同値)4
でなければならない。3
(Win32 SDK環境では定数 BI_BITFIELDS
と同値)16
か 32
でなければならない。4
(Win32 SDK環境では定数 BI_JPEG
と同値)0
でなければならない。5
(Win32 SDK環境では定数 BI_PNG
と同値)0
でなければならない。0
か 3
である場合、この値を 0
にしても構わない。0
を格納しても構わず、厳密でないデコーダはこれらの値を無視しても構わない。0
でピクセル毎のビット数が 8
以下の場合、色数は2をピクセル毎のビット数の値で累乗した数になる。0
である場合、全ての色が重要色となる。Win32 SDK環境では、これらの構成を定義した BITMAPINFOHEADER
構造体が存在する。
1
2
3
4
5
6
7
8
9
10
11
12
13
| - | | | | | | | | | | | ! |
|
V4タイプはINFOタイプを拡張した情報ヘッダ形式で、以下の構成要素を持つ。
なお、V4タイプはV5タイプに内包されているため、V5タイプに対応するデコーダはV4タイプについて考慮する必要はない。
以下に各構成要素の詳細を述べる。
40
、 52
、 56
、 60
、 96
、 108
のいずれかの値となり、 108
よりも小さい場合は情報ヘッダの後半部分が切り捨てられる。108
として全構成要素を書き出すことが望ましいと思われる。3
の場合のみ意味を持ち、各色成分のカラーマスク値が入る。0
で完全に背景を透過する。0
(Win32 SDK環境では定数 LCS_CALIBRATED_RGB
と同値)となる。0
以外であった場合、この情報ヘッダはV5タイプである可能性がある。0
の場合のみ意味を持ち、各色成分に対応したCIEXYZカラーモデルの各座標(三刺激値)が符号付き整数値で入る。0
の場合のみ意味を持ち、各色成分に対応したガンマ値が入る。LOGCOLORSPACE
構造体の解説によると、8〜15ビットが整数部、16〜23ビットが小数部の固定小数点数とのこと*2。Win32 SDK環境では、これらの構成を定義した BITMAPV4HEADER
構造体が存在する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| - | | | | | | | | | | | | | | | | | | | | ! |
|
V5タイプはV4タイプを更に拡張した情報ヘッダ形式で、以下の構成要素を持つ。
なお、V5タイプに対応することでINFOタイプ及びV4タイプにも対応できる。
以下に各構成要素の詳細を述べる。
40
、 52
、 56
、 60
、 96
、 108
、 112
、 120
、 124
のいずれかの値となり、 124
よりも小さい場合は情報ヘッダの後半部分が切り捨てられる。124
として全構成要素を書き出すことが望ましいと思われる。0
(Win32 SDK環境では定数 LCS_CALIBRATED_RGB
と同値)0x73524742
または 'sRGB'
(Win32 SDK環境では定数 LCS_sRGB
と同値)0x57696E20
または 'Win '
(Win32 SDK環境では定数 LCS_WINDOWS_COLOR_SPACE
と同値)0x4C494E4B
または 'LINK'
(Win32 SDK環境では定数 PROFILE_LINKED
と同値)0x4D424544
または 'MBED'
(Win32 SDK環境では定数 PROFILE_EMBEDDED
と同値)0
の場合のみ、V4タイプの対応する値と同様の意味を持つ。1
(Win32 SDK環境では定数 LCS_GM_BUSINESS
と同値)2
(Win32 SDK環境では定数 LCS_GM_GRAPHICS
と同値)4
(Win32 SDK環境では定数 LCS_GM_IMAGES
と同値)8
(Win32 SDK環境では定数 LCS_GM_ABS_COLORIMETRIC
と同値)'LINK'
あるいは 'MBED'
の場合のみ意味を持ち、色空間プロフィールデータの格納位置が情報ヘッダの先頭からのバイト単位でのオフセットとして符号無し整数値で入る。'LINK'
の場合'\0'
(ヌル文字)で終わる文字列である。'MBED'
の場合'LINK'
あるいは 'MBED'
の場合のみ意味を持ち、色空間プロフィールデータのバイト単位でのサイズが符号無し整数値で入る。0
を格納するべきである。Win32 SDK環境では、これらの構成を定義した BITMAPV5HEADER
構造体が存在する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| - | | | | | | | | | | | | | | | | | | | | | | | | ! |
|
ビットフィールドは、以下の条件をすべて満たす場合のみ存在する。
なお、V4タイプ及びV5タイプにおいてヘッダサイズが 52
以上の場合、ビットフィールドは情報ヘッダに内包される。
ビットフィールドは、存在するならば情報ヘッダのすぐ後に続いて現れる必要があり、以下の構成要素を持つ。
要素 | バイト数 |
---|---|
赤成分のカラーマスク | 4 |
緑成分のカラーマスク | 4 |
青成分のカラーマスク | 4 |
なお、ピクセル毎のビット数が 16
または 32
ではあるが圧縮タイプが 0
でありビットフィールドが存在しない場合、デコーダは以下の値を既定のビットフィールドとして読み込みを続ける。
エンコーダは、以下の値をビットフィールドとして用いる場合、圧縮タイプを 0
としてビットフィールドを省略できる。
16
の場合要素 | 値 |
---|---|
赤成分のカラーマスク | 0x00007C00 |
緑成分のカラーマスク | 0x000003E0 |
青成分のカラーマスク | 0x0000001F |
32
の場合要素 | 値 |
---|---|
赤成分のカラーマスク | 0x00FF0000 |
緑成分のカラーマスク | 0x0000FF00 |
青成分のカラーマスク | 0x000000FF |
値の詳細については、ビットフィールドのページを参照のこと。
カラーパレットは、以下の条件の片方、もしくは両方を満たす場合のみ存在する。
1
、 4
、 8
のいずれかの値である場合。1
以上である場合。ピクセル毎のビット数が 16
以上であってもカラーインデックス数が 1
以上ならばカラーパレットは存在することに注意すること。
その場合のカラーパレットは主に減色時の色の指針をデコーダに与えるものであるが、定義はされておらず、デコーダはその内容を無視しても構わない。
カラーパレットは、存在するならば情報ヘッダのすぐ後に続いて現れる必要があり、情報ヘッダのタイプによって以下の2種類のどちらかが色数分だけ列挙される。
なお、ビットフィールドが存在する場合、情報ヘッダではなくビットフィールドのすぐ後に続いて現れる必要がある。
要素 | バイト数 |
---|---|
青成分値 | 1 |
緑成分値 | 1 |
赤成分値 | 1 |
RGBTRIPLE
構造体が存在する。
1
2
3
4
5
| - | | | ! |
|
要素 | バイト数 |
---|---|
青成分値 | 1 |
緑成分値 | 1 |
赤成分値 | 1 |
予約 | 1 |
RGBQUAD
構造体が存在する。
1
2
3
4
5
6
| - | | | | ! |
|
列挙なので、例えばQUADタイプの場合は次の図のようなバイト並びになる。
色数は、情報ヘッダがINFOタイプ、V4タイプ、V5タイプで、かつカラーインデックス数が 1
以上ならばその値分の数になる。
そうでなければ、2をピクセル毎のビット数で乗算した数になる。
すなわち、ピクセル毎のビット数が 1
ならば2色、 4
ならば16色、 8
ならば256色になる。
構成要素である各色成分値は 0
から 255
までの値をとり、その色要素がどれだけ強いかを表す。
これら色要素は光の三原色を表し、全てが 0
ならば黒、全てが 255
ならば白となる。
QUADタイプの予約要素には通常 0
が入るが、この値をα成分値(透明度情報)として利用するデコーダも存在する。
イメージデータは、ファイルヘッダのイメージデータオフセットが 0
の場合は上述した構成要素群のすぐ後に続いて現れる必要があり、 1
以上の場合はその値に従った位置に現れる必要がある。
ただし、イメージデータオフセットの示す位置が上述の構成要素群の格納位置と被る場合、厳密なデコーダは例外として扱い、厳密でないデコーダはその値が 0
であるものとして扱う。
イメージデータは、情報ヘッダがINFOタイプ、V4タイプ、V5タイプのいずれかで、圧縮タイプが 1
または 2
である場合、RLEを用いて圧縮されている。
その場合のイメージデータの内容はRLEによる圧縮のページを参照のこと。
また、圧縮タイプが 4
または 5
である場合、イメージデータはJPEG形式及びPNG形式のデータそのものである。
JPEG形式及びPNG形式の詳細については本文書の範疇を超えるため解説しない。
このセクションでは、圧縮タイプが 0
または 3
の非圧縮イメージデータについて解説する。
イメージデータは行データの羅列から成り、行データはピクセルデータの羅列から成る。
そして各々のピクセルデータは、情報ヘッダのピクセル毎のビット数が示すビット単位のサイズになる。
イメージデータ内における行データの整列順は、イメージ表示時に下に来る行ほど最初に格納されるボトムアップ形式である。
例えば、次のイメージの様に表示されるBMPファイルがあるとする。
この時、行データの格納順は、最下行の黒が一番最初になり、最上行の白が一番最後になる。
ただし、情報ヘッダがINFOタイプ、V4タイプ、V5タイプのいずれかで、その高さの値がマイナスである場合、イメージの高さはその値の絶対値となり、行データの整列順は上に来る行ほど先に格納されるトップダウン形式となる。
行データは、文字通りイメージの横1行を表すデータで、上述の通りピクセルデータの羅列である。
更に、行データは必ず4バイトの整数倍のサイズでなければならない。
エンコーダは、行内の全ピクセルデータの合計サイズが4バイトの整数倍サイズではない場合、4バイトの整数倍サイズになるように0を追加する必要がある。
例えば、幅が5ピクセルの8ビットBMP(1ピクセルが1バイト)の場合、行内の全ピクセルデータの合計サイズは5バイトであるため、4バイトの整数倍である8バイトにするために、次の図のようにする必要がある。
情報ヘッダの幅の値が Width 、ピクセル毎のビット数の値が BitCount のとき、行データのサイズ LineSize は次の式により求まる。
なお、この式中の []
はガウス記号であり、 [N]
は N を超えない最大の整数を表す。
LineSize=[(Width×BitCount+31)÷32]×4
この式により求まった LineSize に情報ヘッダの高さの値の絶対値を掛けることでイメージデータのサイズが求まる。
デコーダはそのようにして求めたイメージデータのサイズを信用して読み込み用のメモリを確保すべきである。
ピクセルデータは、イメージ中の1ピクセル(別の言い方をするなら1ドット)を表すデータで、情報ヘッダのピクセル毎のビット数によって以下の形式が存在する。
1
、 4
、 8
のいずれかの場合の形式。16
または 32
の場合の形式。24
の場合の形式で、ピクセルデータは以下の構成になる。
要素 | バイト数 |
---|---|
青成分値 | 1 |
緑成分値 | 1 |
赤成分値 | 1 |
16^16 formatという説明は、整数部16ビット、小数部16ビットの固定小数点数という意味であると考えられる。