* Reads bitmap headers, and palette (if any) */
| 242 | * Reads bitmap headers, and palette (if any) |
| 243 | */ |
| 244 | bool BmpReadHeader(RandomAccessFile &file, BmpInfo &info, BmpData &data) |
| 245 | { |
| 246 | info = {}; |
| 247 | |
| 248 | /* Reading BMP header */ |
| 249 | if (file.ReadWord() != 0x4D42) return false; // signature should be 'BM' |
| 250 | file.SkipBytes(8); // skip file size and reserved |
| 251 | info.offset = file.ReadDword() + file.GetStartPos(); |
| 252 | |
| 253 | /* Reading info header */ |
| 254 | uint32_t header_size = file.ReadDword(); |
| 255 | if (header_size < 12) return false; // info header should be at least 12 bytes long |
| 256 | |
| 257 | info.os2_bmp = (header_size == 12); // OS/2 1.x or windows 2.x info header is 12 bytes long |
| 258 | |
| 259 | if (info.os2_bmp) { |
| 260 | info.width = file.ReadWord(); |
| 261 | info.height = file.ReadWord(); |
| 262 | header_size -= 8; |
| 263 | } else { |
| 264 | info.width = file.ReadDword(); |
| 265 | info.height = file.ReadDword(); |
| 266 | header_size -= 12; |
| 267 | } |
| 268 | |
| 269 | if (file.ReadWord() != 1) return false; // BMP can have only 1 plane |
| 270 | |
| 271 | info.bpp = file.ReadWord(); |
| 272 | if (info.bpp != 1 && info.bpp != 4 && info.bpp != 8 && info.bpp != 24) { |
| 273 | /* Only 1 bpp, 4 bpp, 8bpp and 24 bpp bitmaps are supported */ |
| 274 | return false; |
| 275 | } |
| 276 | |
| 277 | /* Reads compression method if available in info header*/ |
| 278 | if ((header_size -= 4) >= 4) { |
| 279 | info.compression = file.ReadDword(); |
| 280 | header_size -= 4; |
| 281 | } |
| 282 | |
| 283 | /* Only 4-bit and 8-bit rle compression is supported */ |
| 284 | if (info.compression > 2 || (info.compression > 0 && !(info.bpp == 4 || info.bpp == 8))) return false; |
| 285 | |
| 286 | if (info.bpp <= 8) { |
| 287 | /* Reads number of colours if available in info header */ |
| 288 | if (header_size >= 16) { |
| 289 | file.SkipBytes(12); // skip image size and resolution |
| 290 | info.palette_size = file.ReadDword(); // number of colours in palette |
| 291 | file.SkipBytes(header_size - 16); // skip the end of info header |
| 292 | } |
| 293 | |
| 294 | uint maximum_palette_size = 1U << info.bpp; |
| 295 | if (info.palette_size == 0) info.palette_size = maximum_palette_size; |
| 296 | |
| 297 | /* More palette colours than palette indices is not supported. */ |
| 298 | if (info.palette_size > maximum_palette_size) return false; |
| 299 | |
| 300 | data.palette.resize(info.palette_size); |
| 301 |
no test coverage detected