== DIB_FORM ========================================================== DIBフォーマット概要 Editorial copyright (C) 1995 Toshinobu Yashiro 1995/03/22 Original 1995/03/25 Release 1.0.2 ---------------------------------------------------------- DIB_FORM --  当ドキュメントは会議室においてFAQと化したDIBフォーマット、いわゆるBMP フォーマットについての質問に業を煮やし、その概要をContrailこと八城がま とめたものである。当ドキュメントを元にマイクロソフト並びにOEM各社に質 問することはご遠慮願いたい。また不明な点、あるいは誤りと見られる点があ る場合には、FGALAV/MES2に書き込んで頂ければ幸いである。  ドキュメント中に出てくる名詞等は一般に各社の商標である場合が多いが、 特に断って書くことはしていない。書籍をはじめとした商品ならともかく、こ のようなドキュメントにまでも何々はどこそこの商標ですと列記され、それを 読まされるのは苦痛なものである(ついでに書くのも面倒である)。  それとくれぐれも断っておくが、当ドキュメントはプログラマ向けに書いた ものであり、さらには画像を扱うための最低限の知識は持っているものとして いる。パレットって何?と言われるような場合は、当ドキュメントを読む以前 の勉強が全く足りてないので、それなりの文献を読んでからにして頂きたい。 一般常識程度の内容をまとめた友人と共に執筆した本があるので、一応でもそ れを勧めておく。 CG あ・ら・もーど -機械じかけのキャンバス- \2,600  八城/別府/大城/阿部共著 秀和システムトレーディング刊  ISBN4-87966-350-6 CG あ・ら・もーど3 \2,800  八城/別府共著 秀和システムトレーディング刊  ISBN4-87966-422-7 ====================================================================== 1 ・・・・ 参照されたい文献等 ----------------------------------------------------------------------  当ドキュメントはあくまでも概略であり、詳細な内容についてはSDKのマニ ュアルを参照されたい。ここで「SDKって何?」なんて、トボけた質問はしない ように。Windowsに関係するアプリを作成する場合にはSDKは必要不可欠なもの であるし、マニュアルだけも翔泳社から出ているので、これらを手にすること をお勧めする。DIBフォーマットが関係しているのは、以下の二冊である。 プログラマーズリファレンス Vol.3 \5,000  メッセージ、構造体、マクロ  ISBN4-88135-044-7 プログラマーズリファレンス Vol.4 \3,700  リソース  ISBN4-88135-045-5  決して安い本ではないが、繰り返される質問を見ていると業務を前提として いる節があり、そうであるのなら購入するのが筋であろう。仮にフリーである のなら「急いでいます」なんてセリフは出てこないはずである。フリーソフト 作者が自腹でSDKを買い、あるいは各自で文献を調べているのに、業務でやろ うとしている者が聞いて済ませるのは何かが間違っていないだろうか。 ====================================================================== 2 ・・・・ ファイル構造 ----------------------------------------------------------------------  DIB(Device Independent Bitmaps)フォーマット(以下単にDIBと略記)には大 きく分けてOS/2と、Windows 3.Xで採用されているものとの二種類のヘッダが 存在する。さらにはWindows 2.Xの頃の形式もあるが、それについては触れな いことにする。イメージおよびファイル構造そのものには大差がなく、Windows アプリにおいてはAPIがヘッダの違いを吸収するために差異を意識する必要は ないはずであるが、自前でヘッダを読む場合には注意しなければならない。 1.必ず先頭に来るヘッダ  「BM」で始まるなど、DIBの識別のために必要なヘッダがまずある。後述の  BITMAPFILEHEADER構造体を参照のこと。 2.OS/2,Windowsで異なるヘッダ  主にイメージサイズや色数など、イメージフォーマットとして必要と思われ  る情報が格納されるヘッダがくる。OS/2とWindowsでサイズなどが異なるが、  該当構造体のサイズが最初の変数に格納されているため、ここを見れば識別  は可能である。WindowsはOS/2用のヘッダを拡張した感じであるが、変数の  サイズが変わっているところがあるため、あまり横着な読み方はしない方が  よい。後述のBITMAPINFOHEADER/BITMAPCOREHEADER構造体を参照のこと。 3.カラーインデックス  俗にパレットなどと呼ばれるものである。普通にはパレットが存在しないモ  ノクロイメージにもカラーインデックスが必要とされる点に注意されたい。  さらにはフルカラーイメージであっても持てるようでもある。これもOS/2と  Windowsで形式が異なり、後述のRGBQUAD/RGBTRIPLE構造体を参照のこと。 4.イメージ  実際のイメージが格納される。他の画像フォーマットと異なり、画面の左下  が起点になっていることに注意。つまり他のフォーマットと同じようにファ  イルの先頭から読めば、上下が反転した逆像(左右は反転しない)となってし  まう。さらにはイメージがラインごとに4バイトの整数倍、すなわちダブル  ワード単位になっている必要がある。詳細は後述。 5.ゴミ  XMODEMなどファイルサイズを伝えないプロトコルによって転送された場合、  ファイル末尾にパケットサイズに満たない分だけのゴミが付くことがある。  そのため、ファイル末尾からのオフセットで読むことは避けなくてはならな  い。BITMAPFILEHEADERのbfSizeから得られるファイルサイズと、イメージサ  イズから計算すれば、ファイルのどの位置から読むべきかはわかるはずであ  る。  以上の点を踏まえて構造を構造体で示すと以下のようになろうか。 +------------------+------------------+ | Windows 3.X | OS/2 | +------------------+------------------+ | BITMAPFILEHEADER | BITMAPFILEHEADER | | BITMAPINFOHEADER | BITMAPCOREHEADER | +------------------+------------------+ | RGBQUAD[n] | RGBTRIPLE[n] | <- ない場合もある +------------------+------------------+ | 実際のイメージ | +-------------------------------------+ | ゴミ | <- ないのが本当ではあるが +-------------------------------------+ ====================================================================== 4 ・・・・ 構造体 ----------------------------------------------------------------------  DIBにおいて用いられる構造体の構造を以下に示す。「int」とは16bit幅、す なわちshortである点に注意していただきたい。それと「signed」は省略してあ るが、処理系によっては「signed」を明示した方がよい場合もある。なお、SDK においてはWindowsにあわせてDWORD/WORD/UINTのような表記が用いられている が、ここではすべてDOSにあわせることにした。 ・BITMAPFILEHEADER ---------------------------------------------------  Windows、OS/2に共通である。実際にどちらであるのかは、後続の構造体の  最初のダブルワード(unsigned long)で識別できる。bfSizeの値は当構造体  以降のサイズではなく、ファイル全体のサイズである。 typedef struct tagBITMAPFILEHEADER { unsigned int bfType; // must be "BM" unsigned long bfSize; // ファイルサイズ(バイト) unsigned int bfReserved1; // リザーブ unsigned int bfReserved2; // リザーブ unsigned long bfOffBits; // イメージまでのオフセット } BITMAPFILEHEADER; ・BITMAPINFOHEADER ---------------------------------------------------  主にWindows形式で用いられる。 typedef struct tagBITMAPINFOHEADER { unsigned long biSize; // 当構造体のサイズ(バイト) long biWidth; // イメージの幅 [*1] long biHeight; // イメージの高さ [*1] unsigned int biPlanes; // must be 1 unsigned int biBitCount; // 色数 [*2] unsigned long biCompression; // 圧縮タイプ [*3] unsigned long biSizeImage; // イメージのサイズ [*3] long biXPixPerMeter; // 水平解像度 [*4] long biYPixPerMeter; // 垂直解像度 [*4] unsigned long biClrUsed; // →カラーテーブルを参照 unsigned long biClrImporant; // →カラーテーブルを参照 } BITMAPINFOHEADER; ・BITMAPCOREHEADER ---------------------------------------------------  OS/2形式のヘッダであるが、BITMAPFILEHEADERの使用が推奨されているため  リードだけに留め、保存作成の際には用いない方がよいと思われる。 typedef struct tagBITMAPCOREHEADER { unsigned long bcSize; // 当構造体のサイズ(バイト) int bcWidth; // イメージの幅 [*1] int bcHeight; // イメージの高さ [*1] unsigned int bcPlanes; // must be 1 unsigned int bcBitCount; // 色数 [*2] } BITMAPCOREHEADER; ・RGBQUAD/RGBTRIPLE --------------------------------------------------  以下に示すのはRGBQUADであり、RGBTRIPLEにおいては「rgbReserved」がなく  なるだけである。 typedef struct tagRGBQUAD { unsigned char rgbBlue; // 青の輝度 unsigned char rgbGreen; // 緑の輝度 unsigned char rgbRed; // 赤の輝度 unsigned char rgbReserved; // must be 0 } RGBQUAD; [*1] イメージの高さと幅 単位はいずれもピクセルで、普通にはドットと呼ばれるものである。 [*2] ピクセルあたりのビット数 すなわち色数のことである。DIBにおいては1(モノクロ)、4(16色)、8(256色)、 24(1677万色)が定義されており、必ず1/4/8/24のいずれかの数字である必要が ある。なお、OS/2の新しい形式には15もしくは16が追加されているようである が未調査である。 [*3] 圧縮タイプ イメージが圧縮されているか否かを示す。BI_RGB(0)では非圧縮、BI_RLE4(2) ではBitCount=4のランレングス圧縮、BI_RLE8(1)はBitCount=8のランレングス 圧縮である。なおBI_RGB(非圧縮)の場合には、後続のSizeImageを「0」にする。 [*4] 解像度 メートルあたりの解像度をピクセルサイズで表す。見ているソフトが稀である ため、普通には「0」でも構わないようである。ちなみに300dpiだと11800あたり の値となる。ディスプレイにあわせた96dpiなら3780になる。インチべったり の国で生まれた癖に変なところでメートル法を取り入れるのは止めて欲しいも のだ(苦笑)。 ====================================================================== 5 ・・・・ カラーテーブルと色数による違い ----------------------------------------------------------------------  カラーテーブルはRGBQUAD/RGBTRIPLE構造体(以下RGBQUADと略記)の配列とし て格納されている。BITMAPINFO(CORE)HEADERのBitCount、およびClrUsed/Clr Importantの値によって微妙に扱いが変わってくる(苦笑)。配列内においては、 重要な色の順に配置することが望ましいとされているが、これはWindowsのタ コな減色システム故の制限であろうから、一般には特に意識する必要はないだ ろう。 ・BitCount == 1  モノクロフォーマットではあるが、二つのRGBQUADが必要になる。イメージ  はビットのON/OFFで表現され、ビットが「0」の場合は最初のRGBQUADの値で、  「1」の場合は二番目の値で表示される。すなわち白地に緑のようなイメージ  も可能である。  イメージが0x56(10011010)、RGBQUADがFF/FF/FF/00と00/FF/00/00であると  すると実際の表示は「緑白白緑緑白緑白」となる。このようにRGBQUADに設  定する値によっては白黒であってもビットの意味を逆転させることもでき  る。 ・BitCount == 4  16色フォーマットになり、16個のRGBQUADが必要になる。98風に表現すれば  1677万色中16色、という感じであろうか。イメージはRGBQUADの何番目の色  になるのかのインデックスで示され、1ピクセルの表現には4bit(ニブル)が  用いられる。  イメージが0x38の場合には、最初の4ビットは3であるからRGBQUADの3番目の  色で、次の4ビットが8であるからRGBQUADの8番目の色で表現される。 ・BitCount == 8  256色フォーマットになり、256個のRGBQUADが必要になる。例え17色しか使  っていないとしても、RGBQUAD[256]は必ず必要になる点に注意。1ピクセル  の表現に8bitすなわち1バイトが必要になる他はBitCount==4の場合と同一で  ある。 ・BitCount == 24  24bit = 1677万色のいわゆるフルカラーフォーマットになる。RGBQUADは含  まれず、RGB順の各1バイト、都合3バイトで1ピクセルを表す。点順次のフル  カラーベタフォーマットと同じ格納方法である。Q0/RGBフォーマットの上下  がひっくり返り、DIBのヘッダが付いていると考えた方が早いだろうか。 ・ClrUsed  実際に使われているRGBQUADの個数が格納され、「0」の場合はBitCountと同じ  であると扱われる。厳密に色数を数えることは稀であろうし、設定したから  と言ってRGBQUADの配列数が減らせるわけでもなく、さらに後述のような特  殊な扱いがなされるので、「0」にした方がよいと思われる。「0」だとBitCount  分の色数がすべて使われているものとして扱われる。 ・(ClrUsed != 0) && (BitCount != 24)  解釈し辛かったのでSDKを参照のこと :-) ・(ClrUsed != 0) && (BitCount == 24)  フルカラーフォーマットであるにも関わらず、カラーテーブルが存在するこ  とを意味する。減色用だろうか? この場合は「ClrUsed」個のRGBQUADが存在  する。この形式は未だ見たことがないが、それなりの対応は必要であろう。  いずれにせよWindowsアプリでなければファイル末尾から読むなどの工夫が  必要になるため、減色操作などの参考にするのでなければ無視しても差し支  えないと思われる。 ・ClrImportant  カラーテーブル内の幾つの色が重要なのかが格納される。「0」であればすべ  ての色が重要であると扱われる・・・・が、「ClrUsed」とあわせて結局何のため  に存在するメンバなのか理解に苦しむところである(苦笑)。 ====================================================================== 6 ・・・・ イメージ ----------------------------------------------------------------------  各色数におけるイメージの格納方法については「カラーテーブル」において触 れたので、そこでは扱わなかった注意事項を主にしたい。  まず実際のイメージの格納方法であるが、99×99のフルカラーデータを仮定 してみよう。イメージにおける座標を図式化すると以下のようになる。 DIBの場合 普通のイメージフォーマットの場合 ( 0,98) +-----------+ (98,98) ( 0, 0) +----------+ (98, 0) | | | | | | | | ( 0, 0) +-----------+ (98, 0) ( 0,98) +----------+ (98,98)  すなわちローダなどであれば画面の下から表示する必要があり、他のフォー マットと同様に画面の上から表示、あるいは他フォーマットへの変換を考えて いるのであればファイルの末尾(に近い位置)からファイルの先頭へと読んでい くことになる。ついでに右下が起点であれば単純に逆転するだけで読めたもの を、なぜこのような仕様にしたのか理解に苦しむ。  座標の起点を念頭において、ファイル中のオフセットとして表すと以下のよ うになる。イメージの各ラインはlong境界に揃える必要があるため、それに満 たない場合はNULLを満たす必要がある。そのために実際のイメージサイズは99 ×99×3の29403バイトではなく、99×3をlongに切り上げた300×99の29700バ イトになる。つまり99×99でも100×99でもイメージ部のサイズは変わらない。  図中の55バイトなどのオフセットは固定的なものでなく、ヘッダの形式、カ ラーテーブルの有無によって変わってくることは言うまでもない。bfOffBits をそのまま利用するのが手っ取り早いだろう。 +-------+-------+--+-------+-------+ +---------+ ( 0,98) | 29455 | 29458 | | 29746 | 29749 | (98,98) | NULL(3) | | 29155 | 29158 | | 29446 | 29449 | | NULL(3) | | | | | | | | | | 355 | 358 | | 646 | 594 | | NULL(3) | ( 0, 0) | 55 | 58 | | 346 | 349 | (98, 0) | NULL(3) | +-------+-------+--+-------+-------+ +---------+  ファイルの末尾からライン分だけseekして読むと、ファイル末尾にゴミがあ った場合の対処ができないため、ヘッダの情報から最上行のイメージが始まる 位置、上図においては29455バイトを求め、そこへseekしてから読むことにな る。非常にバタ臭いコーディングをすれば以下のようになるであろうか。 LineNeed = (biWidth * biBitCount) / 8; // ライン分所用バイト if(LineNeed % 4) LineNeed = (((LineNeed / 4) + 1) * 4); // DWORD整列化 pos = bfOffBits + LineNeed * (biHeight - 1); // 最上行の位置 fseek(fp,pos,SEEK_SET); fread(buff,LineNeed,1,fp); for(i=1;i<=biHeight;i++) { pos -= LineNeed * 2; fseek(fp,pos,SEEK_SET); fread(buff,LineNeed,1,fp); }  実際にはライン数分だけseekを繰り返すととんでもなく遅くなるので、バッ ファに数ライン分を一括して読み、出力の順で対処するのが妥当であろう。 ====================================================================== 7 ・・・・ 圧縮 ----------------------------------------------------------------------  DIBにおいては16/256色のイメージに限り圧縮方法が用意されている。BMPは ベタだから・・・・などという批判は的外れである。が、その圧縮はランレングス に過ぎず、非圧縮の方がいくらかマシな代物でしかない。非圧縮(BI_RGB)とは 異なり、行ごとにダブルワード境界に揃える必要はない代わりに、データごと にワード境界に揃える必要がある。さらには圧縮後のイメージサイズがSize Imageに格納されているし、格納しなければならない。 ・BI_RLE8  8bit/256色用の圧縮方法で、コード化モードと絶対モードと呼ばれる二種類  の方法が用意されており、必要に応じて混在して使用される。  コード化モードは常に二バイト(ワードではない)で構成され、第二バイトが  カラーインデックスを示し、第一バイトがその連続する数を示す非常に単純  な方法である。以下の例ではカラーテーブルの2F番目の色が4ピクセル連続  することを意味する。つまり最低でも三つの同じ色のピクセルが連続してい  ない限り圧縮効果がない。ただし圧縮効果はなくとも、絶対化モードが使え  ない時なども使う必要がある(下の段)。  +------------------------------------------------------------------+  | 04 2F -> 2F 2F 2F 2F |  | 01 3E -> 3E |  +------------------------------------------------------------------+  コード化モードは各種エスケープに用いられることもあり、その場合は第一  バイトが「00h」となる。その意味は以下の通り。  +-------------+----------------------------------------------------+  | 00 00 | 行の終端を意味する |  | 00 01 | イメージそのものの終端を意味する |  | 00 02 hh vv | 現在位置から水平にhhピクセル、垂直にvvピクセルのオ | | | フセットで次のデータが始まることを意味する |  +-------------+----------------------------------------------------+  オフセットデータはバイト、すなわち「unsigned」であるため、現在位置より  も左あるいは下に移動することはできない。また移動、すなわちスキップし  た部分のイメージの扱いが明記されていないのは困りものである。一般的に  はカラーテーブルの0番目の色で埋めることになるのだろうか? ローダで  あれば透明色扱いにした方がよいかも知れない。  絶対モードはコード化モードの延長のようなもので、第二バイトが03h〜FFh  の値を取り、第二バイトは続くデータのバイト数を意味する。要するに圧縮  できなかったデータをベタで入れるためのモードである。ただしエスケープ  とぶつかる2ピクセル以下の非連続データの場合は1ピクセルずつコード化モ  ードで記録するしかない。  絶対モードでもワード境界に整列する必要があり、第二バイトが奇数である  場合には「NULL」が余計にくっつくことになる。以下の例を見れば用意に想像  できるはずだが、圧縮することで逆にデータが大きくなることもあり得る。  +------------------------------------------------------------------+  | 00 04 21 1F 69 78 -> 21 1F 69 78 |  | 00 05 45 96 3E 16 10 00 -> 45 96 3E 16 10 |  +------------------------------------------------------------------+  コード化モードと絶対化モードが混在した、すなわち実際に遭遇するであろ  うデータは以下のようになる。わかりやすいようにデータの区切りには「.」を  入れてみた。きちんとバイト数をカウントしながら展開しないと、途中に00h  が混ざったときにパニックになることだろう。かと言ってワードで読むとエ  イディアンが壁になるのだが。  +------------------------------------------------------------------+  | Origin : 03 22 00 05 2A 9D C8 59 40 00 04 E9 03 00 |  | Split : 03 22 . 00 05 2A 9D C8 59 40 00 . 00 04 E9 . 03 00 |  | Expand : 22 22 22 . 2A 9D C8 59 40 . E9 E9 E9 E9 . 00 00 00 |  +------------------------------------------------------------------+  | 04 A2 00 00 00 03 CF 69 45 00 02 01 01 00 03 EF C9 62 00 |  | 04 A2 . 00 00 . 00 03 CF 69 45 . 00 02 01 01 . 00 03 EF C9 62 00 |  | A2 A2 A2 A2 |  | 行の終端 |  | CF 69 45 |  | 水平1ピクセル , 垂直1ピクセル移動 |  | EF C9 62 |  +------------------------------------------------------------------+  展開とは逆に圧縮するのは、かなり面倒な作業になると思われる。  +------------------------------------------------------------------+  | 01 00 00 37 37 37 -> End |  | FF FF D5 00 00 00 |  | DE DE DE DE 39 2F |  | Start -> 05 00 8A 36 5F 9C |  +------------------------------------------------------------------+  | 連続していないため絶対化 00 06 05 00 8A 36 5F 9C |  | 行の終端 00 00 |  | DEhが4バイト連続 04 DE |  | 連続してないがコード化 01 39 01 2F |  | 行の終端 00 00 |  | 連続が2バイトだがコード化 02 FF |  | 連続してないがコード化 01 D5 |  | 00hが3バイト連続 03 37 |  | 行の終端 00 00 |  | 01hが1バイト 01 01 |  | 00hが2バイト連続 02 00 |  | 37hが3バイト連続 03 37 |  | イメージの終端 00 01 |  +------------------------------------------------------------------+ ・BI_RLE4  4bit/16色用の圧縮方法で、その圧縮はバイト単位でなされる。すなわち2ピ  クセルを同時に扱う必要がある他はBI_RLE8と同じである。ピクセルとの対  応はニブル単位でなされ、例えば3Fhとあれば最初のピクセルは3番目の色、  次のピクセルがFh番目の色となる。つまりタイリングが多用される16色デー  タには比較的向いていると思われるが、絶対化モードではワード境界に揃え  る必要があるのも同じで、三つ目の例のようなことも起こりうる。  +------------------------------------------------------------------+  | 03 29 -> 2 9 2 |  | 00 07 9C 32 FE 90 -> 9 C 3 2 F E 9 |  | 00 05 19 82 30 00 -> 1 9 8 2 3 |  +------------------------------------------------------------------+ ・サンプル  以下はRLEのヘッダ部分をダンプしたものである。 ・BITMAPFILEHEADER相当部 0000 42 4D 12 8B 00 00 00 00-00 00 76 00 00 00 BM........v... ・BITMAPINFOHEADER相当部 0000 28 00 (. 0010 00 00 80 02 00 00 90 01-00 00 01 00 04 00 02 00 ................ 0020 00 00 9C 8A 00 00 00 00-00 00 00 00 00 00 10 00 ..怺............ 0030 00 00 10 00 00 00 ...... ・RGBQUAD[16]相当部 ※98の4096色中16色を記録する場合は、例えばAhはA0hとするのではなく、AAh  にする必要がある。なぜだかはよく考えてみよう。逆は単にshr 4で済む。 0030 00 00-00 00 00 00 EE 00 EE 22 ..............." 0040 44 00 AA 00 00 00 00 00-BB 00 88 77 FF 00 FF EE D.ェ.....サ....... 0050 DD 00 88 88 88 00 00 BB-00 00 00 00 88 00 11 CC .......サ.......フ 0060 EE 00 33 EE FF 00 55 99-DD 00 AA CC FF 00 CC EE ..3...U吽.ェフ..フ. 0070 FF 00 FF FF FF 00 ...... ・イメージ部 ※0078hや007AhがFFhではなくてFEhになっている点に注目。 0070 04 00-FE FF FE FF 7C FF 04 00 ............|... 0080 00 00 02 00 FE FF FE FF-80 FF 02 00 00 00 02 0F ................ 0090 FE FF FE FF 80 FF 02 F0-00 00 02 0F FE FF FE FF ................ 00A0 80 FF 02 F0 00 00 FE FF-FE FF 84 FF 00 00 FE FF ................ 00B0 FE FF 84 FF 00 00 FE FF-FE FF 84 FF 00 00 FE FF ................ 00C0 FE FF 84 FF 00 00 FE FF-FE FF 84 FF 00 00 FE FF ................ 00D0 FE FF 84 FF 00 00 FE FF-FE FF 84 FF 00 00 FE FF ................ 00E0 FE FF 84 FF 00 00 FE FF-30 FF 00 04 F0 00 FE FF ........0....... 00F0 50 FF 00 00 FE FF 30 FF-00 06 0F FF 0F 00 FE FF P.....0......... <<以下省略>> ====================================================================== 8 ・・・・ その他 ----------------------------------------------------------------------  以上でDIBの構造等についての解説は終わりであるが、文中で触れなかった その他の注意事項についても簡単にまとめておく。 ・拡張子について  多くは「.BMP」であるが、Windowsのスタートアップイメージのように圧縮し  てあるものは「.RLE」の拡張子を持つものもある。またリソースコンパイラな  どでは「.DIB」を利用することもある。そのため対応するツールを作る場合に  は、拡張子を「.BMP」に固定してはならない。 ・ヘッダについて  これまで幸いにして見たことはないが、マックバイナリヘッダが付いたDIB  のことも考え、先頭に「BM」がなければさっさと諦めるのではなく、128バイ  トほどスキップして再度読み込むくらいの配慮が欲しい。 ・RLEの連鎖数について  記憶が定かではないが、ツールによって上限をFFhとするかFEhとするかの違  いがあるそうなので、圧縮する際には連鎖数をFEhに留めておいた方が無難  であると思われる。サンプルデータのダンプを参照のこと。 ・RGBQUADについて  Windowsが内部的に扱うデータ(クリップボードへの転送か?)である場合に  は、RGBQUADの内容を設定しない方がよいとされる場合がある。気にする必  要があるのはWindowsアプリだけのため、詳細はSDKを参照されたい。 ・サンプルソースについて  これらのドキュメントにつきものであるサンプルソースなどは一切付属して  いない。 ====================================================================== 9 ・・・・ 著作権について ----------------------------------------------------------------------  当ドキュメントはSDKなどを元に独自に調査した結果をまとめたものである。 事実の列記に過ぎない部分もあるため、著作権ではなく、編集著作権の方を留 保することにしたい。以下の点に留意されたし。 1.転載は要事前承諾  間違いの指摘などを含めた転載先からの反応の書き込み(メール不可)、及び  アフターケアができることが最低条件になる。文中に八城のミス以外でわか  らない言葉があるようであれば、転載されない方が無難であろう。当然、商  利用の場合も要事前承諾である。 2.免責  当ドキュメントの記述については極力正しくなるように心がけてはいるが、  実際のファイル構造やSDKなどに記載されているものが優先する。当ドキュ  メントの記載を正しいものとして運用し、その結果何らかの損害を被ったと  しても、それはそれ以上調べなかった運用者側の責任であり、八城には一切  の責任がないものとする。 3.改訂について  当ドキュメントは誤りの発見や新しい情報が得られた場合には予告なく改訂  される。 ・連絡先 contrail@mix.or.jp PFG00771@niftyserve.or.jp NIFTY/FGALAV/MES2 == DIB_FORM ========================================================== DIBフォーマット概要 Editorial copyright (C) 1995 Toshinobu Yashiro 1995/03/22 Original 1995/03/25 Release 1.0.2 1995/05/06 Release 1.0.3 ---------------------------------------------------------- DIB_FORM -- 以下を差し替えて読むこと。 ====================================================================== 4 ・・・・ 構造体 【補追】 ---------------------------------------------------------------------- [*] Windows形式(BITMAPINFOHEADER)、OS/2形式(BITMAPCOREHEADER)の他に、   構造体のサイズが64バイトのヘッダもあるようであるが、詳細は未調査で   ある。これまでの遷移からするとBITMAPINFOHEADERに何かしら余計なもの   が付いているだけではないかと考えられ、biSize/bcSizeの値を信じてス   キップするようにした方がよいと思われる。 ====================================================================== 5 ・・・・ カラーテーブルと色数による違い 【訂正】 ---------------------------------------------------------------------- ・BitCount == 24  24bit = 1677万色のいわゆるフルカラーフォーマットになる。RGBQUADは含  まれず、「BGR」順の各1バイト、都合3バイトで1ピクセルを表す。他の  フォーマットとは異なってRGB順ではない点に注意。 ====================================================================== 7 ・・・・ 圧縮 【補追】 ----------------------------------------------------------------------  コード化モードは各種エスケープに用いられることもあり、その場合は第一  バイトが「00h」となる。その意味は以下の通り。  +-------------+----------------------------------------------------+  | 00 00 | 行の終端を意味する |  | 00 01 | イメージそのものの終端を意味する |  | | この場合には行の終端である「00 00」がないこともある |  | 00 02 hh vv | 現在位置から水平にhhピクセル、垂直にvvピクセルのオ | | | フセットで次のデータが始まることを意味する |  +-------------+----------------------------------------------------+ ====================================================================== 8 ・・・・ その他 【新規】 ---------------------------------------------------------------------- ・実際のファイル構造を過度に信用しない  bfOffBitsを参照するように書いたが、ファイルによってはこれを信用して  よいものと悪いものがある。ヘッダを参照しつつ、実際には各々の位置を計  算で求めるようにした方が確実であろう。とにかく「何も信じるべきものが  ない」これがDIBフォーマットの現実である(苦笑)。基準はあってもそれが  守られていないのであればないのと同じとしか言いようがない。 以上。