| 131 | // Windows bitmap files stored with 4, 8, 16, 24, or 32 bits per pixel. |
| 132 | |
| 133 | flag FReadBmp(Bitmap *b, FILE *file, flag fNoHeader) |
| 134 | { |
| 135 | byte *pb, bR, bG, bB, ch, ch2; |
| 136 | KV rgkv[256], kv; |
| 137 | int cbExtra, cb, x, y, z, k, i, m, n; |
| 138 | long l; |
| 139 | |
| 140 | // BitmapFileHeader |
| 141 | if (!fNoHeader) { |
| 142 | ch = getbyte(); ch2 = getbyte(); |
| 143 | if (ch != 'B' || ch2 != 'M') { |
| 144 | PrintError("This file does not look like a Windows bitmap.\n"); |
| 145 | return fFalse; |
| 146 | } |
| 147 | skiplong(); |
| 148 | skipword(); skipword(); |
| 149 | skiplong(); |
| 150 | } |
| 151 | |
| 152 | // BitmapInfo / BitmapInfoHeader |
| 153 | cbExtra = getlong(); |
| 154 | x = NAbs((int)getlong()); y = NAbs((int)getlong()); |
| 155 | skipword(); z = getword(); |
| 156 | l = getlong(); |
| 157 | if (l != 0/*BI_RGB*/ && l != 3/*BI_BITFIELDS*/) { |
| 158 | PrintError("This Windows bitmap can't be uncompressed.\n"); |
| 159 | return fFalse; |
| 160 | } |
| 161 | for (i = 0; i < 3; i++) { |
| 162 | skiplong(); |
| 163 | } |
| 164 | k = getlong(); skiplong(); |
| 165 | for (cbExtra -= 40; cbExtra > 0; cbExtra--) |
| 166 | skipbyte(); |
| 167 | if (l == 3/*BI_BITFIELDS*/) |
| 168 | for (i = 0; i < 3; i++) { |
| 169 | skiplong(); |
| 170 | } |
| 171 | if (!(z == 4 || z == 8 || z == 16 || z == 24 || z == 32)) { |
| 172 | PrintError("This Windows bitmap has bad number of bits per pixel.\n"); |
| 173 | return fFalse; |
| 174 | } |
| 175 | |
| 176 | // RgbQuad |
| 177 | // Data |
| 178 | if (!FAllocateBmp(b, x, y)) |
| 179 | return fFalse; |
| 180 | |
| 181 | // Figure out the bytes per row in this color bitmap. |
| 182 | if (z == 32) |
| 183 | cb = x << 2; |
| 184 | else if (z == 24) |
| 185 | cb = x * 3; |
| 186 | else if (z == 16) { |
| 187 | for (i = 0; i < 12; i++) |
| 188 | skipbyte(); |
| 189 | cb = x << 1; |
| 190 | } else { |
no test coverage detected