Closed Raclamusi closed 6 months ago
ありがとうございます! v0.6.15 での実装に向け確認を進めます。
この BMP デコーダ、Siv3D とは独立して、BMP のロードに特化した 1 つの C or C++ ヘッダオンリーライブラリとして公開・メンテすると需要がありそうだなと思いました。
分かりやすい名前と README, ベンチマーク等を用意すれば、長期的に star を稼げるリポジトリになりそうです。
LoadInfoFromMemory(const unsigned char* memory)
LoadImageFromMemory(const unsigned char* memory, unsigned char* pixels)
みたいな API が提供されれば、Siv3D から使いたいです。
調べてみると BMP のフォーマットは本当に種類が多いんですね。X4R4G4B4 みたいなのも見かけました。マイナーなものも含めて網羅性を表でアピールすると、使われるライブラリになると思います。
Merged. Great job!
1204 の実装です。
BMPDecoder
を 1 bit 、4 bit 、および 16 bit のビット深度を持つ BMP に対応させ、すべてのビット深度に対応するようにしました。 それにあたっていくつかの修正、変更を加えました。各コミットについて、以下で説明します。
バッファの確保に Array を使うよう変更
従来の実装では、バッファの確保に失敗した際に透明な画像を返すようになっています。 これは、よく使われている失敗時に空の
Image
を返すという仕様と一貫性がなく、また、そもそもstd::malloc()
を使用するのはナンセンスです。 そのため、バッファの確保にArray
を使用するよう変更しました。パレット用領域を色数に合わせて動的確保するよう変更
従来の実装では、8-bit BMP を読み込む際にパレットの色数を 256 色(最大)として領域をスタックに用意し、パレットデータを読み込んでいます。 しかし、実際には
BMPHeader::biClrUsed
の値によってパレットの色数は変化するため、常に 256 色読み込もうとすると、色数が 256 色より少ないときに画像データ領域を誤ってパレットデータとして読んでしまうことになります。 そのため、パレット用領域をBMPHeader::biClrUsed
などの関連するヘッダの値によって決まる色数の分だけArray
動的確保し、指定された分だけ読み込むよう修正しました。BMPHeader::bfOffBits を参照するよう変更
従来の実装では、ヘッダ、パレットデータのすぐ後から画像データを読み込んでいます。 しかし、BMP 画像ファイルではヘッダ、パレットデータの後に追加情報や意味のない領域が挟まることがあります。 実際の画像データの開始位置は
BMPHeader::bfOffBits
により示されます。 そのため、ヘッダ、パレットデータを読み込んだ後のファイルの読み込み位置がBMPHeader::bfOffBits
より小さいとき、BMPHeader::bfOffBits
まで読み込み位置を変更するよう修正しました。1-bit, 4-bit BMP に対応
1-bit, 4-bit BMP に対応しました。
16-bit BMP に対応
16-bit BMP に対応しました。 16-bit BMP は R5G5B5 形式と R5G6B5 形式がありますが、R5G5B5 形式にのみ対応しています。 R5G6B5 形式は従来の実装と同様に以下に示す条件分岐によってはじかれます。
https://github.com/Siv3D/OpenSiv3D/blob/33ec9281b6968592a6835ec1772d7571fc94228f/Siv3D/src/Siv3D/ImageFormat/BMP/BMPDecoder.cpp?ts=4#L93-L97
不正なビット深度に対して失敗ログを出すよう変更
不正なビット深度の BMP を読み込んだとき、失敗ログを出力して空の
Image
を返すよう変更しました。 このコードに到達した際、既に確保したImage
が無駄になりますが、滅多にないことなので目をつぶりました。末尾の空白を削除
気になったので、末尾の空白を削除しました。