BMPファイルフォーマット(OS/2)

作成:

前回は Windows ビットマップのヘッダについて説明した。 今回は OS/2 のヘッダについて説明する。

情報ヘッダ(BITMAPCOREHEADER)

OS/2ビットマップの場合、情報ヘッダとして使われるのが以下の BITMAPCOREHEADER だ。

typedef struct tagBITMAPCOREHEADER {
  DWORD bcSize;
  WORD  bcWidth;
  WORD  bcHeight;
  WORD  bcPlanes;
  WORD  bcBitCount;
} BITMAPCOREHEADER, *PBITMAPCOREHEADER;

MSDNでは BITMAPCOREHEADER structure に説明がある。

構成要素としては BITMAPINFOHEADER をシンプルにした構成で、各パラメータの意味も同一である。 ただし、幅と高さを表す bcWidth と bcHeight はそれぞれ WORD つまり、符号なし 16bit 整数である点が異なる。 符号なしなので、当然トップダウン形式は存在しない。 biCompresion に該当するパラメータもないため、ビットフィールドやランレングス圧縮も存在しない。 bcBitCount として有効な値は、1, 4, 8, 24 である。16 や 32 はOS/2形式では不正な値となる。

OS/2 ビットマップというとこのヘッダを使用したものになるが、 OS/2 では後に、このヘッダを拡張した仕様を定義し、そちらの利用を推奨している。

カラーパレット(RGBTRIPLE)

情報ヘッダが BITMAPCOREHEADER の場合、カラーパレットの色表現に利用されるのは RGBQUAD ではなく、 RGBTRIPLE である。 なお、今後、他の情報ヘッダを紹介していくが、 RGBTRIPLE が利用されるのは情報ヘッダが BITMAPCOREHEADER の場合のみで、 ほかは全て RGBQUAD が利用される。 MSDNでは RGBTRIPLE structure に説明がある。

typedef struct tagRGBTRIPLE {
  BYTE rgbtBlue;
  BYTE rgbtGreen;
  BYTE rgbtRed;
} RGBTRIPLE;

名前から推測できたと思うが、 RGBTRIPLE は 3Byte の構造体で、 BGR の順に格納される。 RGBQUAD の Reserve 領域がないバージョンである。

検証中に見つけたのだが、 PaintShop Pro では OS/2 形式の BMP の出力が可能である。 しかし、カラーパレットの領域サイズを 3Byte ではなく 4Byte で計算してしまっているバグがあった。 具体的には、カラーパレット自体は RGBTRIPLE で出力されているのだが、 BITMAPFILEHEADER の bfOffBits の値がヘッダ+パレットの色数×4になっていた。 そのため自分自身でも正常に読み込めない出力なってしまっていた。 メジャーな画像編集ソフトでもこのようなバグが放置されているぐらいなので、 一般にはほぼ使用されていないと考えても良さそうである。 なお、バグを確認したバージョンは X3 であり、 X8 では修正されていた。 過去のバージョンに遡ると、 6 では正常な出力で 9 では間違った出力になっていた。 少なくとも 5 バージョンにわたってバグが放置されていたようである。

情報ヘッダ(BITMAPINFOHEADER2)

OS/2 ビットマップのヘッダは拡張され、新しく BITMAPINFOHEADER2 が定義されている。 OS/2 ではこのヘッダの利用が推奨されているらしい。 この拡張は Windows と袂を分けた後のもので、 Windows 側ではこのヘッダは定義されていない。 つまりMSDNにはドキュメントがない。 また、 IBM も正確なドキュメントを公開しているわけではないようで、私が探した範囲ではあまりよいドキュメントがなかった。 以下の説明では殆どについて確証のある情報ではないことをご容赦願いたい。

定義としては以下の様な構造になっている、 型定義も Windows SDK のものとは異なっているが、それぞれどういう意味かは推測できるだろう。

typedef struct _BITMAPINFOHEADER2 {
  ULONG  cbFix;
  ULONG  cx;
  ULONG  cy;
  USHORT cPlanes;
  USHORT cBitCount;
  ULONG  ulCompression;
  ULONG  cbImage;
  ULONG  cxResolution;
  ULONG  cyResolution;
  ULONG  cclrUsed;
  ULONG  cclrImportant;
  USHORT usUnits;
  USHORT usReserved;
  USHORT usRecording;
  USHORT usRendering;
  ULONG  cSize1;
  ULONG  cSize2;
  ULONG  ulColorEncoding;
  ULONG  ulIdentifier;
} BITMAPINFOHEADER2;

各メンバーの意味は以下のようになっている。

cbFix
このヘッダのサイズ、この形式では64となる、他の形式と同様にこの値を元にどのヘッダなのかを識別する。
cx
画像の横方向のピクセル数。符号なし32bit数。
cy
画像の縦方向のピクセル数。符号なし32bit数。
cPlanes
プレーンの数、通常1固定
cBitCount
1ピクセルを表現するのに使われるビット数。
ulComplession
圧縮方式、Windowsビットマップと同様に非圧縮とランレングス圧縮が定義されている。 それ以外にも24bitのランレングス圧縮やハフマン符号化なども定義されているとの情報も見つけたが、 詳細な情報が得られず、探した範囲では対応しているソフトが見つからなかった。
cbImage
ヘッダを除いた画像領域のデータサイズ。
cxResolution
横方向の解像度情報。単位は usUnits で定義する。
cyResolution
縦方向の解像度情報。単位は usUnits で定義する。
cclrUsed
使用するカラーパレットの色数。0の場合ビット数の最大値が設定されたものとみなす。
cclrImportant
カラーパレットのうち画像を構成するのに最低限必要な色数。0の場合全色が必要であることを意味する。
usUnits
cxResolution / cyResolution の単位
usReserved
予約領域。0である必要がある。
usRecording
ビットマップの保存方式、ボトムアップ形式のみ定義されている。
usRendering
ハーフトーン化した際に使用したアルゴリズムを記述する。
cSize1
usRenderingと合わせてエラーやパターンを記述する。
cSize2
usRenderingと合わせてパターンを記述する。
ulColorEncoding
色の表現方法を定義する。
ulIdentifier
予約領域

一部わからない部分があり、ごまかしているが、 前半部分は Windows ビットマップの BITMAPINFOHEADER とほぼ同じ構造になっている。 後半部分は BITMAPINFOHEADER にはない情報であるが、 私が知るかぎりではこの領域の情報を有効活用しているアプリケーションはなかった。 実際に読みだすコードの説明では BITMAPINFOHEADER にない情報については無視している。 また、フィールドの有効な値の範囲についてや、定義値についても正確な情報が得られなかったため、 BITMAPINFOHEADER と同じ定義であるという前提で説明する。

また、RGBTRIPLE のところで説明しているが、 RGBTRIPLE が使われるのは BITMAPCOREHEADER の時のみである。 つまり、BITMAPINFOHEADER2 を用いた形式は OS/2 ビットマップに分類されるが、 カラーパレットのデータ構造は RGBQUAD なので注意いただきたい。