| 44 | ~PCXImageLoader() override = default; |
| 45 | |
| 46 | sp<OpenApoc::Image> loadImage(IFile &file) override |
| 47 | { |
| 48 | auto size = file.size(); |
| 49 | auto path = file.systemPath(); |
| 50 | auto data = file.readAll(); |
| 51 | if (size < sizeof(struct PcxHeader) + 256 * 3) |
| 52 | { |
| 53 | LogInfo("File \"%s\" size %u too small for PCX header + palette\n", path, |
| 54 | static_cast<unsigned>(size)); |
| 55 | return nullptr; |
| 56 | } |
| 57 | struct PcxHeader *header = reinterpret_cast<struct PcxHeader *>(&data[0]); |
| 58 | |
| 59 | if (header->Identifier != PcxIdentifier) |
| 60 | { |
| 61 | LogInfo("File \"%s\" had invalid PCX identifier 0x%02x", path, |
| 62 | static_cast<unsigned>(header->Identifier)); |
| 63 | return nullptr; |
| 64 | } |
| 65 | |
| 66 | if (header->Encoding != 1) |
| 67 | { |
| 68 | LogWarning("File \"%s\" had invalid PCX Encoding 0x%02x", path, |
| 69 | static_cast<unsigned>(header->Encoding)); |
| 70 | return nullptr; |
| 71 | } |
| 72 | |
| 73 | if (header->BitsPerPixel != 8) |
| 74 | { |
| 75 | LogWarning("File \"%s\" had invalid PCX BitsPerPixel 0x%02x", path, |
| 76 | static_cast<unsigned>(header->BitsPerPixel)); |
| 77 | return nullptr; |
| 78 | } |
| 79 | |
| 80 | if (header->NumBitPlanes != 1) |
| 81 | { |
| 82 | LogWarning("File \"%s\" had invalid PCX NumBitPlanes 0x%02x", path, |
| 83 | static_cast<unsigned>(header->NumBitPlanes)); |
| 84 | return nullptr; |
| 85 | } |
| 86 | |
| 87 | uint8_t pal = data[size - (256 * 3) - 1]; |
| 88 | if (pal != 0x0C) |
| 89 | { |
| 90 | LogWarning("File \"%s\" had invalid PCX palette identifier byte 0x%02x", path, |
| 91 | static_cast<unsigned>(pal)); |
| 92 | return nullptr; |
| 93 | } |
| 94 | |
| 95 | auto p = mksp<Palette>(256); |
| 96 | |
| 97 | const uint8_t *palette_data = reinterpret_cast<uint8_t *>(&data[size - (256 * 3)]); |
| 98 | for (unsigned i = 0; i < 256; i++) |
| 99 | { |
| 100 | uint8_t r = *palette_data++; |
| 101 | uint8_t g = *palette_data++; |
| 102 | uint8_t b = *palette_data++; |
| 103 | Colour c{r, g, b, 255}; |