MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / BmpRead4Rle

Function BmpRead4Rle

src/bmp.cpp:71–140  ·  view source on GitHub ↗

* Reads a 4-bit RLE compressed bitmap * The bitmap is converted to a 8 bpp bitmap */

Source from the content-addressed store, hash-verified

69 * The bitmap is converted to a 8 bpp bitmap
70 */
71static inline bool BmpRead4Rle(RandomAccessFile &file, BmpInfo &info, BmpData &data)
72{
73 uint x = 0;
74 uint y = info.height - 1;
75 uint8_t *pixel = &data.bitmap[y * static_cast<size_t>(info.width)];
76 while (y != 0 || x < info.width) {
77 if (file.AtEndOfFile()) return false; // the file is shorter than expected
78
79 uint8_t n = file.ReadByte();
80 uint8_t c = file.ReadByte();
81 if (n == 0) {
82 switch (c) {
83 case 0: // end of line
84 x = 0;
85 if (y == 0) return false;
86 pixel = &data.bitmap[--y * static_cast<size_t>(info.width)];
87 break;
88
89 case 1: // end of bitmap
90 return true;
91
92 case 2: { // delta
93 if (file.AtEndOfFile()) return false;
94 uint8_t dx = file.ReadByte();
95 uint8_t dy = file.ReadByte();
96
97 /* Check for over- and underflow. */
98 if (x + dx >= info.width || x + dx < x || dy > y) return false;
99
100 x += dx;
101 y -= dy;
102 pixel = &data.bitmap[y * info.width + x];
103 break;
104 }
105
106 default: { // uncompressed
107 uint i = 0;
108 while (i++ < c) {
109 if (file.AtEndOfFile() || x >= info.width) return false;
110 uint8_t b = file.ReadByte();
111 *pixel++ = GB(b, 4, 4);
112 x++;
113 if (i++ < c) {
114 if (x >= info.width) return false;
115 *pixel++ = GB(b, 0, 4);
116 x++;
117 }
118 }
119 /* Padding for 16 bit align */
120 file.SkipBytes(((c + 1) / 2) % 2);
121 break;
122 }
123 }
124 } else {
125 /* Apparently it is common to encounter BMPs where the count of
126 * pixels to be written is higher than the remaining line width.
127 * Ignore the superfluous pixels instead of reporting an error. */
128 uint i = 0;

Callers 1

BmpReadBitmapFunction · 0.85

Calls 4

GBFunction · 0.85
AtEndOfFileMethod · 0.80
SkipBytesMethod · 0.80
ReadByteMethod · 0.45

Tested by

no test coverage detected