プログラミング/BMPファイル仕様/バイナリ構造 のバックアップ(No.3)


BMPファイルのバイナリ構造の解説。

概要

BMPファイルのバイナリ構造は、データの先頭から順に以下のような構成要素を持つ。

  1. ファイルヘッダ
  2. 情報ヘッダ
  3. ビットフィールド
  4. カラーパレット
  5. イメージデータ

このうち、ビットフィールドカラーパレットについては情報ヘッダの内容次第で存在しないことがある。
また、イメージデータ情報ヘッダの内容によって形式が大きく変わる。

なお、BMPバイナリ中にある2バイト及び4バイトの整数値データのバイトオーダはリトルエンディアンであり、符号付き整数値の場合は最上位ビットを符号ビットとする2の補数表現を用いる。
Windows環境しか考慮しないのであればバイトオーダを気にする必要はないが、プラットフォームに依存しないコードを記述する際には留意すること*1

ファイルヘッダ

ファイルヘッダはBMPファイルのバイナリ構造において最初に現れる必要があり、以下の構成要素を持つ。

以下に各構成要素の詳細を述べる。

ファイルタイプ(2バイト)
ファイルがBMPファイルであることを示すもので、1バイト目が 'B' 、2バイト目が 'M' となる。
エンコーダは必ずこの値を格納するべきで、デコーダはこの値であるかをチェックするべきである。
ファイルサイズ(4バイト)
BMPファイル全体のバイト単位でのサイズが符号無し整数値で入る。
ただし、厳密でないエンコーダはこの値を計算せずに 0 を格納しても構わない。
デコーダはこの値を利用する必要はなく、また信用するべきでもない。
予約1(2バイト)
予約2(2バイト)
これら2要素は将来の拡張用に予約されており、エンコーダは 0 を格納するべきである。
デコーダはこれらの値を無視して構わない。
イメージデータオフセット(4バイト)
BMPファイルの最初からイメージデータの先頭までのバイト単位でのオフセットが符号無し整数値で入る。
ただし、厳密でないエンコーダは 0 を格納しても構わない。
デコーダは、この値が 0 以外であった場合は信用するべきである。

Win32 SDK環境では、これらの構成を定義した BITMAPFILEHEADER 構造体が存在する。

すべて開くすべて閉じる
  1
  2
  3
  4
  5
  6
  7
-
|
|
|
|
|
!
typedef struct tagBITMAPFILEHEADER { 
  WORD    bfType; 
  DWORD   bfSize; 
  WORD    bfReserved1; 
  WORD    bfReserved2; 
  DWORD   bfOffBits; 
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

情報ヘッダ

情報ヘッダファイルヘッダのすぐ後に続いて現れる必要があり、以下の4種類が存在する。

これらのうち、現在一般的なBMPファイルに使われているのはINFOタイプである。
エンコーダはこのタイプさえ書き出せるならば問題はなく、デコーダは最低でもこのタイプに対応する必要がある。

どの情報ヘッダタイプにおいても最初の4バイトは必ずヘッダサイズとなる。
よって複数のタイプに対応するデコーダは、まず最初の4バイトを読み取り、その数値で情報ヘッダタイプを判別する。

COREタイプ

COREタイプOS/2で使われていた情報ヘッダ形式で、以下の構成要素を持つ。

以下に各構成要素の詳細を述べる。

ヘッダサイズ(4バイト)
情報ヘッダのバイト単位でのサイズが符号無し整数値で入る。
COREタイプでは必ず 12 となる。
エンコーダは必ずこの値を格納するべきで、デコーダはこの値を用いて情報ヘッダを判別する。
(2バイト)
高さ(2バイト)
イメージのピクセル単位での幅と高さが符号無し整数値で入る。
値は 1 以上でなければならない。
プレーン数(2バイト)
イメージのプレーン数(チャンネル数)が符号無し整数値で入る。
BMPファイルでは必ず 1 となる。
エンコーダは必ずこの値を格納するべきで、厳密でないデコーダはこの値を無視しても構わない。
ピクセル毎のビット数(2バイト)
イメージデータにおいて1ピクセルを表現するのに必要なビット数が符号無し整数値で入る。
COREタイプでは 14824 のいずれかとなる。
他のタイプと違い、 01632 は無効である。

Win32 SDK環境では、これらの構成を定義した BITMAPCOREHEADER 構造体が存在する。

すべて開くすべて閉じる
  1
  2
  3
  4
  5
  6
  7
-
|
|
|
|
|
!
typedef struct tagBITMAPCOREHEADER {
  DWORD   bcSize; 
  WORD    bcWidth; 
  WORD    bcHeight; 
  WORD    bcPlanes; 
  WORD    bcBitCount; 
} BITMAPCOREHEADER, *PBITMAPCOREHEADER;

INFOタイプ

INFOタイプは最も標準的な情報ヘッダ形式で、以下の構成要素を持つ。
なお、INFOタイプはV4タイプ及びV5タイプに内包されているため、これらのタイプに対応するデコーダはINFOタイプについて考慮する必要はない。

以下に各構成要素の詳細を述べる。

ヘッダサイズ(4バイト)
情報ヘッダのバイト単位でのサイズが符号無し整数値で入る。
INFOタイプでは必ず 40 となる。
エンコーダは必ずこの値を格納するべきで、デコーダはこの値を用いて情報ヘッダを判別する。
(4バイト)
イメージのピクセル単位での幅が符号付き整数値で入る。
値は 1 以上でなければならない。
高さ(4バイト)
イメージのピクセル単位での高さが符号付き整数値で入る。
値は 0 であってはならない。
また、トップダウン形式の場合は高さの値にマイナスの符号を付ける。
プレーン数(2バイト)
イメージのプレーン数(チャンネル数)が符号無し整数値で入る。
BMPファイルでは必ず 1 となる。
エンコーダは必ずこの値を格納するべきで、厳密でないデコーダはこの値を無視しても構わない。
ピクセル毎のビット数(2バイト)
イメージデータにおいて1ピクセルを表現するのに必要なビット数が符号無し整数値で入る。
値は 0148162432 のいずれかとなり、この値によって圧縮タイプの取りうる値が変わる。
圧縮タイプ(4バイト)
イメージデータの形式を表す符号無し整数値で、以下のいずれかの値が入る。
0 (Win32 SDK環境では定数 BI_RGB と同値)
標準の非圧縮形式であることを示す。
ピクセル毎のビット数0 であってはならない。
1 (Win32 SDK環境では定数 BI_RLE8 と同値)
8ビットのRLE形式であることを示す。
ピクセル毎のビット数8 でなければならない。
2 (Win32 SDK環境では定数 BI_RLE4 と同値)
4ビットのRLE形式であることを示す。
ピクセル毎のビット数4 でなければならない。
3 (Win32 SDK環境では定数 BI_BITFIELDS と同値)
ビットフィールドを持つ非圧縮形式であることを示す。
ピクセル毎のビット数1632 でなければならない。
4 (Win32 SDK環境では定数 BI_JPEG と同値)
JPEG形式であることを示す。
ピクセル毎のビット数0 でなければならない。
5 (Win32 SDK環境では定数 BI_PNG と同値)
PNG形式であることを示す。
ピクセル毎のビット数0 でなければならない。
イメージデータサイズ(4バイト)
イメージデータのバイト単位でのサイズが符号無し整数値で入る。
エンコーダは、圧縮タイプ03 である場合、この値を 0 にしても構わない。
デコーダはこの値を利用する必要はなく、また信用するべきでもない。
水平解像度(4バイト)
垂直解像度(4バイト)
イメージの横方向及び縦方向の1メートル当たりのピクセル数が符号無し整数値で入る。
エンコーダはこれらの情報が不要ならば 0 を格納しても構わず、厳密でないデコーダはこれらの値を無視しても構わない。
カラーインデックス数(4バイト)
カラーパレットに格納される色数が符号無し整数値で入る。
この値が 0ピクセル毎のビット数8 以下の場合、色数は2をピクセル毎のビット数の値で累乗した数になる。
すなわち1ビットならば2色、4ビットならば16色、8ビットならば256色となる。
重要インデックス数(4バイト)
カラーパレットに格納されている色のうち、正確に表示すべき重要色の数が符号無し整数値で入る。
先頭から数えてこの値の分の色が重要色として定義される。
この値が 0 である場合、全ての色が重要色となる。
厳密でないデコーダはこの値を無視しても構わない。

Win32 SDK環境では、これらの構成を定義した BITMAPINFOHEADER 構造体が存在する。

すべて開くすべて閉じる
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
-
|
|
|
|
|
|
|
|
|
|
|
!
typedef struct tagBITMAPINFOHEADER{
  DWORD  biSize; 
  LONG   biWidth; 
  LONG   biHeight; 
  WORD   biPlanes; 
  WORD   biBitCount; 
  DWORD  biCompression; 
  DWORD  biSizeImage; 
  LONG   biXPelsPerMeter; 
  LONG   biYPelsPerMeter; 
  DWORD  biClrUsed; 
  DWORD  biClrImportant; 
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

V4タイプ

V4タイプINFOタイプを拡張した情報ヘッダ形式で、以下の構成要素を持つ。
なお、V4タイプはV5タイプに内包されているため、V5タイプに対応するデコーダはV4タイプについて考慮する必要はない。

以下に各構成要素の詳細を述べる。

ヘッダサイズ(4バイト)
情報ヘッダのバイト単位でのサイズが符号無し整数値で入る。
V4タイプでは 4052566096108 のいずれかの値となり、 108 よりも小さい場合は情報ヘッダの後半部分が切り捨てられる。
ただし、エンコーダはこの値を 108 として全構成要素を書き出すことが望ましいと思われる。
デコーダはこの値を用いて情報ヘッダを判別し、この値のサイズ分だけデータを読み込んで解析するようにする。
(4バイト)
高さ(4バイト)
プレーン数(2バイト)
ピクセル毎のビット数(2バイト)
圧縮タイプ(4バイト)
イメージデータサイズ(4バイト)
水平解像度(4バイト)
垂直解像度(4バイト)
カラーインデックス数(4バイト)
重要インデックス数(4バイト)
これらの値はINFOタイプの対応する値と同様の意味を持つ。
詳しくはINFOタイプを参照のこと。
赤成分のカラーマスク(4バイト)
緑成分のカラーマスク(4バイト)
青成分のカラーマスク(4バイト)
これらの値は圧縮タイプ3 の場合のみ意味を持ち、各色成分のカラーマスク値が入る。
データの意味はビットフィールドと同様であるため、詳しくはそちらを参照のこと。
α成分のカラーマスク(4バイト)
α成分(透明度情報)のカラーマスク値が入る。
データの意味はビットフィールドと同様であるため、詳しくはそちらを参照のこと。
α成分自体は値が小さいほど透明度が上がり、 0 で完全に背景を透過する。
透明度情報を扱わないデコーダはこの値を無視しても構わない。
色空間タイプ(4バイト)
色空間タイプを示す定数が符号無し整数値で入る。
V4タイプの場合、この値は必ず 0 (Win32 SDK環境では定数 LCS_CALIBRATED_RGB と同値)となる。
この値が 0 以外であった場合、この情報ヘッダはV5タイプである可能性がある。
赤成分に対するCIEXYZのX座標(4バイト)
赤成分に対するCIEXYZのY座標(4バイト)
赤成分に対するCIEXYZのZ座標(4バイト)
緑成分に対するCIEXYZのX座標(4バイト)
緑成分に対するCIEXYZのY座標(4バイト)
緑成分に対するCIEXYZのZ座標(4バイト)
青成分に対するCIEXYZのX座標(4バイト)
青成分に対するCIEXYZのY座標(4バイト)
青成分に対するCIEXYZのZ座標(4バイト)
これらの値は色空間タイプの値が 0 の場合のみ意味を持ち、各色成分に対応したCIEXYZカラーモデルの各座標が符号付き整数値で入る。
厳密でないデコーダはこれらの値を無視しても構わない。
CIEXYZカラーモデルについての詳細はAdobe Systemsの技術情報等を参照のこと。
Win32 SDKにおける実装に関してはMASAPICO'S PageColor Management のメモ書き等が参考になる。
赤成分に対するガンマ値(4バイト)
緑成分に対するガンマ値(4バイト)
青成分に対するガンマ値(4バイト)
これらの値は色空間タイプの値が 0 の場合のみ意味を持ち、各色成分に対応したガンマ値が入る。
データの形式はMSDN Libraryの BITMAPV4HEADER の解説によると16^16 formatとのことだが、詳細不明。
厳密でないデコーダはこれらの値を無視しても構わない。

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
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
typedef struct {
  DWORD        bV4Size;
  LONG         bV4Width;
  LONG         bV4Height;
  WORD         bV4Planes;
  WORD         bV4BitCount;
  DWORD        bV4V4Compression;
  DWORD        bV4SizeImage;
  LONG         bV4XPelsPerMeter;
  LONG         bV4YPelsPerMeter;
  DWORD        bV4ClrUsed;
  DWORD        bV4ClrImportant;
  DWORD        bV4RedMask;
  DWORD        bV4GreenMask;
  DWORD        bV4BlueMask;
  DWORD        bV4AlphaMask;
  DWORD        bV4CSType;
  CIEXYZTRIPLE bV4Endpoints;
  DWORD        bV4GammaRed;
  DWORD        bV4GammaGreen;
  DWORD        bV4GammaBlue;
} BITMAPV4HEADER, *PBITMAPV4HEADER;

V5タイプ

V5タイプV4タイプを更に拡張した情報ヘッダ形式で、以下の構成要素を持つ。
なお、V5タイプに対応することでINFOタイプ及びV4タイプにも対応できる。

以下に各構成要素の詳細を述べる。

ヘッダサイズ(4バイト)
情報ヘッダのバイト単位でのサイズが符号無し整数値で入る。
V5タイプでは 4052566096108112120124 のいずれかの値となり、 124 よりも小さい場合は情報ヘッダの後半部分が切り捨てられる。
ただし、エンコーダはこの値を 124 として全構成要素を書き出すことが望ましいと思われる。
デコーダはこの値を用いて情報ヘッダを判別し、この値のサイズ分だけデータを読み込んで解析するようにする。
(4バイト)
高さ(4バイト)
プレーン数(2バイト)
ピクセル毎のビット数(2バイト)
圧縮タイプ(4バイト)
イメージデータサイズ(4バイト)
水平解像度(4バイト)
垂直解像度(4バイト)
カラーインデックス数(4バイト)
重要インデックス数(4バイト)
これらの値はINFOタイプの対応する値と同様の意味を持つ。
詳しくはINFOタイプを参照のこと。
赤成分のカラーマスク(4バイト)
緑成分のカラーマスク(4バイト)
青成分のカラーマスク(4バイト)
α成分のカラーマスク(4バイト)
これらの値はV4タイプの対応する値と同様の意味を持つ。
詳しくはV4タイプを参照のこと。
色空間タイプ(4バイト)
色空間タイプを示す符号無し整数値で、以下のいずれかの値が入る。
0 (Win32 SDK環境では定数 LCS_CALIBRATED_RGB と同値)
V4タイプと同様の色空間情報を持つことを示す。
0x73524742 または 'sRGB' (Win32 SDK環境では定数 LCS_sRGB と同値)
sRGB色空間情報を持つことを示す。
0x57696E20 または 'Win ' (Win32 SDK環境では定数 LCS_WINDOWS_COLOR_SPACE と同値)
Windows標準の色空間であることを示す。
0x4C494E4B または 'LINK' (Win32 SDK環境では定数 PROFILE_LINKED と同値)
色空間プロフィールファイルのパスがBMPファイル中に含まれていることを示す。
0x4D424544 または 'MBED' (Win32 SDK環境では定数 PROFILE_EMBEDDED と同値)
色空間プロフィールがBMPファイル中に含まれていることを示す。
赤成分に対するCIEXYZのX座標(4バイト)
赤成分に対するCIEXYZのY座標(4バイト)
赤成分に対するCIEXYZのZ座標(4バイト)
緑成分に対するCIEXYZのX座標(4バイト)
緑成分に対するCIEXYZのY座標(4バイト)
緑成分に対するCIEXYZのZ座標(4バイト)
青成分に対するCIEXYZのX座標(4バイト)
青成分に対するCIEXYZのY座標(4バイト)
青成分に対するCIEXYZのZ座標(4バイト)
赤成分に対するガンマ値(4バイト)
緑成分に対するガンマ値(4バイト)
青成分に対するガンマ値(4バイト)
これらの値は、色空間タイプの値が 0 の場合のみ、V4タイプの対応する値と同様の意味を持つ。
詳しくはV4タイプを参照のこと。
sRGB色空間タイプ(4バイト)
sRGB色空間を示す符号無し整数値で、以下のいずれかの値が入る。
これらの値は全てICCによって定義された国際色彩協会標準(ICC32)に基づいている。
厳密でないデコーダはこの値を無視しても構わない。
1 (Win32 SDK環境では定数 LCS_GM_BUSINESS と同値)
例えば図やグラフといった、色相や明度の保存に重点を置いたイメージであることを示す。
国際色彩協会標準の対応する名称は"Saturation"である。
2 (Win32 SDK環境では定数 LCS_GM_GRAPHICS と同値)
例えばロゴやデザイン画といった、カラーアピアランスの一致に重点を置いたイメージであることを示す。
国際色彩協会標準の対応する名称は"Relative Colorimetric"である。
4 (Win32 SDK環境では定数 LCS_GM_IMAGES と同値)
例えば写真や風景画といった、比色分析の正確さに重点を置いたイメージであることを示す。
国際色彩協会標準の対応する名称は"Perceptual"である。
8 (Win32 SDK環境では定数 LCS_GM_ABS_COLORIMETRIC と同値)
例えばプレビューといった、比色の絶対値の保存が必要なイメージであることを示す。
国際色彩協会標準の対応する名称は"Absolute Colorimetric"である。
色空間プロフィールオフセット(4バイト)
この値は色空間タイプの値が 'LINK' あるいは 'MBED' の場合のみ意味を持ち、色空間プロフィールデータの格納位置が情報ヘッダの先頭からのバイト単位でのオフセットとして符号無し整数値で入る。
各色空間タイプにおける色空間プロフィールデータの内容を以下に示す。
厳密でないデコーダはこの値を無視しても構わない。
色空間タイプが 'LINK' の場合
プロフィールデータは色空間プロフィールファイルのパスを表す '\0' (ヌル文字)で終わる文字列である。
色空間タイプが 'MBED' の場合
プロフィールデータは色空間プロフィールサイズ分の埋め込みデータである。
色空間プロフィールサイズ(4バイト)
この値は色空間タイプの値が 'LINK' あるいは 'MBED' の場合のみ意味を持ち、色空間プロフィールデータのバイト単位でのサイズが符号無し整数値で入る。
色空間プロフィールデータを利用しないデコーダはこの値を無視して構わない。
予約(4バイト)
将来の拡張用に予約されており、エンコーダは 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
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
typedef struct { 
  DWORD        bV5Size; 
  LONG         bV5Width; 
  LONG         bV5Height; 
  WORD         bV5Planes; 
  WORD         bV5BitCount; 
  DWORD        bV5Compression; 
  DWORD        bV5SizeImage; 
  LONG         bV5XPelsPerMeter; 
  LONG         bV5YPelsPerMeter; 
  DWORD        bV5ClrUsed; 
  DWORD        bV5ClrImportant; 
  DWORD        bV5RedMask; 
  DWORD        bV5GreenMask; 
  DWORD        bV5BlueMask; 
  DWORD        bV5AlphaMask; 
  DWORD        bV5CSType; 
  CIEXYZTRIPLE bV5Endpoints; 
  DWORD        bV5GammaRed; 
  DWORD        bV5GammaGreen; 
  DWORD        bV5GammaBlue; 
  DWORD        bV5Intent; 
  DWORD        bV5ProfileData; 
  DWORD        bV5ProfileSize; 
  DWORD        bV5Reserved; 
} BITMAPV5HEADER, *PBITMAPV5HEADER;

*1 説明文中でもリトルエンディアンを前提とした記述をしている箇所がある。