@@ -31,6 +31,54 @@ namespace IMCodec
3131 uint32_t biClrImportant;
3232 };
3333
34+ struct BitmapInfoHeaderV2 : BitmapInfoHeader
35+ {
36+ uint32_t bV4RedMask;
37+ uint32_t bV4GreenMask;
38+ uint32_t bV4BlueMask;
39+ };
40+
41+ struct BitmapInfoHeaderV3 : BitmapInfoHeaderV2
42+ {
43+ uint32_t bV4AlphaMask;
44+ };
45+
46+
47+ using FixedPoint2Dot30 = int32_t ;
48+
49+
50+ struct CIEXYZCoords
51+ {
52+ FixedPoint2Dot30 ciexyzX;
53+ FixedPoint2Dot30 ciexyzY;
54+ FixedPoint2Dot30 ciexyzZ;
55+ };
56+
57+ struct CIEXYZTriplet
58+ {
59+ CIEXYZCoords red;
60+ CIEXYZCoords green;
61+ CIEXYZCoords blue;
62+ };
63+
64+
65+ struct BitmapInfoHeaderV4 : BitmapInfoHeaderV3
66+ {
67+ uint32_t bV4CSType;
68+ CIEXYZTriplet bV4Endpoints;
69+ uint32_t bV4GammaRed;
70+ uint32_t bV4GammaGreen;
71+ uint32_t bV4GammaBlue;
72+ };
73+
74+ struct BitmapInfoHeaderV5 : BitmapInfoHeaderV4
75+ {
76+ uint32_t bV5Intent;
77+ uint32_t bV5ProfileData;
78+ uint32_t bV5ProfileSize;
79+ uint32_t bV5Reserved;
80+ };
81+
3482 enum class BitmapCompression
3583 {
3684 RGB = 0x0000 ,
@@ -49,7 +97,7 @@ namespace IMCodec
4997 class CodecBMP : public IImagePlugin
5098 {
5199 private:
52- PluginProperties mPluginProperties ;
100+ PluginProperties mPluginProperties ;
53101 public:
54102 inline thread_local static bool sIsLoading = false ;
55103
@@ -70,9 +118,9 @@ namespace IMCodec
70118 }
71119 )
72120 {
73-
121+
74122 }
75-
123+
76124 const PluginProperties& GetPluginProperties () override
77125 {
78126 return mPluginProperties ;
@@ -97,6 +145,25 @@ namespace IMCodec
97145 return sizeRemaininBuffer >= requiredSize;
98146 }
99147
148+ size_t ResolveBmpVersion (const BitmapInfoHeader* info)
149+ {
150+ switch (info->biSize )
151+ {
152+ case sizeof (BitmapInfoHeader) :
153+ return 1 ;
154+ case sizeof (BitmapInfoHeaderV2) :
155+ return 2 ;
156+ case sizeof (BitmapInfoHeaderV3) :
157+ return 3 ;
158+ case sizeof (BitmapInfoHeaderV4) :
159+ return 4 ;
160+ case sizeof (BitmapInfoHeaderV5) :
161+ return 5 ;
162+ default :
163+ LL_EXCEPTION (LLUtils::Exception::ErrorCode::InvalidState, " Bitmap version not found" );
164+ }
165+ }
166+
100167 // Base abstract methods
101168 ImageResult Decode (const std::byte* buffer, std::size_t size, [[maybe_unused]] ImageLoadFlags loadFlags, const Parameters& params, ImageSharedPtr& out_image) override
102169 {
@@ -111,22 +178,30 @@ namespace IMCodec
111178 {
112179 const BitmapInfoHeader* bmpInfoPtr = reinterpret_cast <const BitmapInfoHeader*>(buffer + sizeof (BitmapFileHeader));
113180 const BitmapInfoHeader& bmpInfo = *bmpInfoPtr;
114- const uint8_t * baseSourceAddress = reinterpret_cast <const uint8_t *>(bmpInfoPtr + 1 );
181+
182+ const size_t bitmapVersion = ResolveBmpVersion (bmpInfoPtr);
183+
184+ const uint8_t * baseSourceAddress = reinterpret_cast <const uint8_t *>(bmpInfoPtr) + bmpInfo.biSize ;
115185 BitmapCompression compression = static_cast <BitmapCompression>(bmpInfo.biCompression );
116- if (compression == BitmapCompression::BitFields)
117- {
118- // TODO: implement RGBMasks for 16 bit and 32 bit images.
119- [[maybe_unused]] const uint32_t * RGBMasks = reinterpret_cast <const uint32_t *>(baseSourceAddress);
120- baseSourceAddress += sizeof (uint32_t ) * 4 ;
121- }
122186
123187 switch (compression)
124188 {
125189 case BitmapCompression::RGB:
126190 // no compression.
127191 break ;
128192 case BitmapCompression::BitFields:
129- // No compression but add add masks to color data.
193+ if (bitmapVersion == 2 )
194+ {
195+ // RGB mask
196+ // TODO: implement BitFields compression
197+ // const BitmapInfoHeaderV2* headerV2 = reinterpret_cast<const BitmapInfoHeaderV2*>(bmpInfoPtr);
198+ }
199+ else if (bitmapVersion > 2 )
200+ {
201+ // RGB mask
202+ // TODO: implement BitFields compression
203+ // const BitmapInfoHeaderV3* headerV3 = reinterpret_cast<const BitmapInfoHeaderV3*>(bmpInfoPtr);
204+ }
130205 break ;
131206 default :
132207 LL_EXCEPTION_NOT_IMPLEMENT (" Bitmap compression type is not supported" );
0 commit comments