Other
アイコン・ファイルのフォーマット
アイコンには悩まされた。いろいろ不可解だった。
ICONDIRENTRYについて
bWidthやbHeightが0の場合、それらは256を意味する。
8ビットカラー以上の場合、bColorCountは0。28 = 256はBYTEの範囲を超えているので、しかたない。アイコンのカラーのビット数は1, 4, 8, 16, 24, 32のいずれかなので、bColorCountは0, 2, 16のいずれか。
[不思議1] 値としては明らかにビット数より色数のほうが大きいのに、bColorCountはBYTE、wBitCountはWORDで定義されている。
dwImageOffsetは、対応のICONIMAGEの位置であり、ファイル先頭からのオフセット。
BITMAPINFOHEADERについて
BITMAPINFOHEADERで使用するのはbiSize, biWidth, biHeight, biPlanes, biBitCount, biSizeImageだけで、他はmust be 0。
[不思議2] biHeightはXORマスクとANDマスクをくっつけた高さ。ANDマスクはXORマスクと同じ幅と高さでなので、結局、XORマスクの2倍の高さになる。これがなかなかわからなかった。ちなみに“くっつける(combine)”とは上下にくっつけることらしい。前後にも左右にもくっつけない。
biSizeImageはXORマスクのバイト数だが、この値は無視されるような気がする。アイコン・ファイルを読み込むときも、自分でバイト数を計算したほうが良さそうだ。
WidthBytes = 4 * ((biBitCount * biWidth + 31) / 32);
biSizeImage = WidthBytes * biHeight;
ICONIMAGEについて
カラーテーブルが必要ない場合、つまり16ビットカラー以上の場合、icColorsはない。
icXORは“XORマスク”と説明されているが、マスクではないと思う。DIBのビットマップデータ。各行ごとに4バイト境界に合わせる。アイコンの大きさはだいたい決まっているので、たいていピッタリだと思う。
icANDは1ビットカラーのDIBのビットマップデータ。icXORと同様に、各行ごとに4バイト境界に合わせる。32ビットカラーならicXORがアルファ値を含んでいるのでicANDは不要と思うが、ないとは限らない。また、24ビットカラーでもicANDはあるべきだと思うが、ない場合もあり、よくわからない。アイコン・ファイルを保存するときは、必要なくても0で埋めておいたほうが良いような気がする。
※「4バイト境界に合わせる」というのは、バイト数を4で割った余り(剰余)が0になるように0~3バイトを追加すること。実際は上の例示のように、ビット数から計算する。
(参照)http://msdn.microsoft.com/en-us/library/ms997538.aspx
(2016/05/14 初稿)
(2016/05/25 更新)