Other

ビットマップ・フォーマット

ファイル・イメージ
BITMAPFILEHEADER
INFOHEADER (*1)
one of following:
• BITMAPCOREHEADER
• BITMAPINFOHEADER
• BITMAPV4HEADER
• BITMAPV5HEADER
color mask (*2)
• DWORD RedMask
• DWORD GreenMask
• DWORD BlueMask
color table (*3)
one of following:
• array of RGBTRIPLE
• array of RGBQUAD
(undefined)
bitmap data
profile data (*4)

(*1) BITMAPCOREHEADER, BITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADERのいずれか。BITMAPCOREHEADERとBITMAPV4HEADERはBITMAPINFOHEADERとBITMAPV5HEADERに取って代わられた。BITMAPCOREHEADERとBITMAPV4HEADERは下位互換のために存在する。BITMAPV5HEADERはBITMAPV4HEADERを拡張したもの、BITMAPV4HEADERはBITMAPINFOHEADERを拡張したものだが、BITMAPCOREHEADERは他の構造体と互換性がないので注意が必要。どの構造体なのかはSizeメンバーで判断する。BITMAPCOREHEADERを含むものはOS2ビットマップ、BITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADERのいずれかを含むものはWindowsビットマップと呼ばれる。
(*2) BI_BITFIELDビットマップのための赤、緑、青のカラーマスク(3つのDWORDメンバー)はBITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADERの直後に続く。BITMAPV4HEADER, BITMAPV5HEADERは赤、緑、青のマスクの追加メンバーを含む。関数がBI_BITFIELDSを持つLPBITMAPINFO受け取るときには、カラーマスクはヘッダの直後に置かれ、それに続いて、もしあればカラーテーブルを配置する。BITMAPCOREHEADERはカラーマスクをサポートしない。BI_BITFIELDSではないならカラーマスクは持たない。
(*3) 一般的に16, 24, 32 bits-per-pixel (bpp) のビットマップはカラーテーブルを含まないが、含むこともできる。1, 4, 8bppのビットマップはbppベースの最大サイズでカラーテーブルを持っていなければならない。最大サイズは2のbpp乗。1ビットなら最大2色、4ビットなら最大16色、8ビットなら最大256色。INFOHEADERがBITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADERのいずれか(Windowsビットマップ)ならば、カラーテーブルの構成要素はRGBQUADだが、INFOHEADERがBITMAPCOREHEADER(OS2ビットマップ)の場合には、カラーテーブルは常に最大サイズで、その構成要素はRGBTRIPLEとなっている。
(*4) プロファイル・データはプロファイル・ファイル名(リンク・プロファイル)または実際のプロファイル・ビット(埋め込みプロファイル)のどちらかを示す。プロファイル・データはもしあればカラーテーブルの後に配置される。しかし、関数がパックされたDIBを受け取るときは、ファイル・フォーマットのように、それはビットマップ・データの後ろになる。プロファイル・データは唯一BITMAPV5HEADERのために存在する。

カラーテーブルの終わりからビットマップ・データの始まりまでは未定義領域。

最大値またはデフォルト値は省略される傾向にあるようだ。1, 4, 8bppのビットマップのカラーテーブルの要素数(ClrUsedおよびClrImportantメンバー)は、最大値であるなら「0」となっていることもある。ビットマップ・データのサイズ(SizeImageメンバー)も、bppと幅および高さによって計算できるものと同じなら「0」となっていることが多い。これらは、おそらくBITMAPINFOHEADERにコンバートされたBITMAPCOREHEADERを考慮している。

カラーテーブル、ビットマップ・サイズは、デコードするときには考慮しなければならないが、CreateDIBSection関数によってDIBを作成するときには利用されない。カラーテーブルはSetDIBColorTable関数を使って、別途設定してやる必要があるし、ビットマップ・データを操作するためのバッファのサイズは構造体のSizeImageメンバーによらない。GetObject関数によってDIBSECTIONを得ると、CreateDIBSection関数に渡したものと同じものが返ってくる。使い方次第だが、頭から信用できるものではない。