|
31 | 31 | #include <istream> |
32 | 32 | #include <cstring> |
33 | 33 |
|
34 | | -#define BI_RGB 0 |
35 | | -#define BI_RLE8 1 |
36 | | -#define BI_RLE4 2 |
| 34 | +/* BMP compression methods */ |
| 35 | +#define BI_RGB 0 |
| 36 | +#define BI_RLE8 1 |
| 37 | +#define BI_RLE4 2 |
| 38 | +#define BI_BITFIELDS 3 |
| 39 | + |
37 | 40 |
|
38 | 41 | namespace LV { |
39 | 42 |
|
@@ -286,6 +289,8 @@ namespace LV { |
286 | 289 | fp.read (reinterpret_cast<char*> (&bf_bits), 4); |
287 | 290 | bf_bits = VISUAL_ENDIAN_LEI32 (bf_bits); |
288 | 291 |
|
| 292 | + auto dib_header_pos = fp.tellg (); |
| 293 | + |
289 | 294 | /* Read the info structure size */ |
290 | 295 | fp.read (reinterpret_cast<char*> (&bi_size), 4); |
291 | 296 | bi_size = VISUAL_ENDIAN_LEI32 (bi_size); |
@@ -341,13 +346,19 @@ namespace LV { |
341 | 346 | return nullptr; |
342 | 347 | } |
343 | 348 |
|
344 | | - if (bi_compression > 3) { |
| 349 | + if (bi_compression >= BI_BITFIELDS) { |
345 | 350 | visual_log (VISUAL_LOG_ERROR, "Bitmap uses an invalid or unsupported compression scheme"); |
346 | 351 | fp.seekg (saved_stream_pos); |
347 | 352 | return nullptr; |
348 | 353 | } |
349 | 354 |
|
350 | 355 | /* Load the palette */ |
| 356 | + |
| 357 | + /* Skip past DIB header to color table */ |
| 358 | + /* BI_BITFIELDS and BI_ALPHABITFIELDS are unsupported, so there are |
| 359 | + no bitmasks after the DIB header. */ |
| 360 | + fp.seekg (dib_header_pos + std::streampos {bi_size}, std::ios::beg); |
| 361 | + |
351 | 362 | if (bi_bitcount < 24) { |
352 | 363 | if (bi_clrused == 0) { |
353 | 364 | /* When the colors used variable is zero, use the |
@@ -385,6 +396,8 @@ namespace LV { |
385 | 396 | if (palette) |
386 | 397 | video->set_palette (*palette); |
387 | 398 |
|
| 399 | + /* Read and decode image data */ |
| 400 | + |
388 | 401 | /* Set to the beginning of image data, note that MickeySoft likes stuff upside down .. */ |
389 | 402 | fp.seekg (bf_bits, std::ios::beg); |
390 | 403 |
|
|
0 commit comments