@@ -113,7 +113,9 @@ bool BitmapInfo::load_from(BITMAPINFO* bi) {
113113 alpha_mask = 0xff000000 ;
114114 break ;
115115 case 24 :
116- case 8 : // We return 8bpp images as 24bpp
116+ case 8 : // We return 8bpp, 4bpp and 1bpp images as 24bpp
117+ case 4 :
118+ case 1 :
117119 red_mask = 0xff0000 ;
118120 green_mask = 0xff00 ;
119121 blue_mask = 0xff ;
@@ -268,6 +270,70 @@ bool BitmapInfo::to_image(image& output_img) const {
268270 }
269271 break ;
270272 }
273+
274+ case 4 : {
275+ assert (bi);
276+
277+ const int colors = 16 ;
278+ std::vector<uint32_t > palette (colors);
279+ for (int c=0 ; c<colors; ++c) {
280+ palette[c] =
281+ (bi->bmiColors [c].rgbRed << spec.red_shift ) |
282+ (bi->bmiColors [c].rgbGreen << spec.green_shift ) |
283+ (bi->bmiColors [c].rgbBlue << spec.blue_shift );
284+ }
285+
286+ const uint8_t * src = (((uint8_t *)bi) + bi->bmiHeader .biSize + sizeof (RGBQUAD)*colors);
287+ const uint8_t * srcY = src;
288+
289+ for (long y = 0 ; y < spec.height ; ++y, srcY += stride, src = srcY) {
290+ char * dst = img.data () + (topY + direction * y) * spec.bytes_per_row ;
291+
292+ for (unsigned long x=0 ; x<spec.width ; ++x, dst+=3 ) {
293+ int idx = src[x / 2 ];
294+ if (x & 1 )
295+ idx &= 0x0f ;
296+ else
297+ idx >>= 4 ;
298+
299+ if (idx < 0 )
300+ idx = 0 ;
301+ else if (idx >= colors)
302+ idx = colors-1 ;
303+
304+ *((uint32_t *)dst) = palette[idx];
305+ }
306+ }
307+ break ;
308+ }
309+
310+ case 1 : {
311+ assert (bi);
312+
313+ const int colors = 2 ;
314+ std::vector<uint32_t > palette (colors);
315+ for (int c=0 ; c<colors; ++c) {
316+ palette[c] =
317+ (bi->bmiColors [c].rgbRed << spec.red_shift ) |
318+ (bi->bmiColors [c].rgbGreen << spec.green_shift ) |
319+ (bi->bmiColors [c].rgbBlue << spec.blue_shift );
320+ }
321+
322+ const uint8_t * src = (((uint8_t *)bi) + bi->bmiHeader .biSize + sizeof (RGBQUAD)*colors);
323+ const uint8_t * srcY = src;
324+
325+ for (long y = 0 ; y < spec.height ; ++y, srcY += stride, src = srcY) {
326+ char * dst = img.data () + (topY + direction * y) * spec.bytes_per_row ;
327+
328+ for (unsigned long x=0 ; x<spec.width ; ++x, dst+=3 ) {
329+ const int idx = (src[x / 8 ] & (128 >> (x & 7 )) ? 1 : 0 );
330+
331+ *((uint32_t *)dst) = palette[idx];
332+ }
333+ }
334+ break ;
335+ }
336+
271337 }
272338
273339 std::swap (output_img, img);
0 commit comments