| 395 | } |
| 396 | |
| 397 | std::optional<Header> readHeader(std::ifstream &file) |
| 398 | { |
| 399 | Header header; |
| 400 | header.idLength = read8(file); |
| 401 | header.colormapType = read8(file); |
| 402 | |
| 403 | auto imageTypeIdx = read8(file); |
| 404 | switch (imageTypeIdx) |
| 405 | { |
| 406 | case 0: |
| 407 | header.imageType = ImageType::NoImage; |
| 408 | break; |
| 409 | case 1: |
| 410 | header.imageType = ImageType::UncompressedIndexed; |
| 411 | break; |
| 412 | case 2: |
| 413 | header.imageType = ImageType::UncompressedRgb; |
| 414 | break; |
| 415 | case 3: |
| 416 | header.imageType = ImageType::UncompressedGray; |
| 417 | break; |
| 418 | case 9: |
| 419 | header.imageType = ImageType::RleIndexed; |
| 420 | break; |
| 421 | case 10: |
| 422 | header.imageType = ImageType::RleRgb; |
| 423 | break; |
| 424 | case 11: |
| 425 | header.imageType = ImageType::RleGray; |
| 426 | break; |
| 427 | default: |
| 428 | break; |
| 429 | } |
| 430 | |
| 431 | header.colormapOrigin = read16(file); |
| 432 | header.colormapLength = read16(file); |
| 433 | header.colormapDepth = read8(file); |
| 434 | header.xOrigin = read16(file); |
| 435 | header.yOrigin = read16(file); |
| 436 | header.width = read16(file); |
| 437 | header.height = read16(file); |
| 438 | header.bitsPerPixel = read8(file); |
| 439 | header.imageDescriptor = read8(file); |
| 440 | |
| 441 | header.leftToRight = (!(header.imageDescriptor & 0x10)); |
| 442 | header.topToBottom = (header.imageDescriptor & 0x20); |
| 443 | |
| 444 | // Invalid image size |
| 445 | if (header.width == 0 || header.height == 0) |
| 446 | return {}; |
| 447 | |
| 448 | // Skip ID string (idLength bytes) |
| 449 | if (header.idLength > 0) |
| 450 | { |
| 451 | auto i = header.idLength; |
| 452 | while (i--) |
| 453 | { |
| 454 | auto chr = read8(file); |
no test coverage detected