@@ -302,7 +302,13 @@ bool fmt2bmp(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixf
302
302
* out_len = 0 ;
303
303
304
304
int pix_count = width * height ;
305
- size_t out_size = (pix_count * 3 ) + BMP_HEADER_LEN ;
305
+
306
+ // With BMP, 8-bit greyscale requires a palette.
307
+ // For a 640x480 image though, that's a savings
308
+ // over going RGB-24.
309
+ int bpp = (format == PIXFORMAT_GRAYSCALE ) ? 1 : 3 ;
310
+ int palette_size = (format == PIXFORMAT_GRAYSCALE ) ? 4 * 256 : 0 ;
311
+ size_t out_size = (pix_count * bpp ) + BMP_HEADER_LEN + palette_size ;
306
312
uint8_t * out_buf = (uint8_t * )_malloc (out_size );
307
313
if (!out_buf ) {
308
314
ESP_LOGE (TAG , "_malloc failed! %u" , out_size );
@@ -314,45 +320,51 @@ bool fmt2bmp(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixf
314
320
bmp_header_t * bitmap = (bmp_header_t * )& out_buf [2 ];
315
321
bitmap -> reserved = 0 ;
316
322
bitmap -> filesize = out_size ;
317
- bitmap -> fileoffset_to_pixelarray = BMP_HEADER_LEN ;
323
+ bitmap -> fileoffset_to_pixelarray = BMP_HEADER_LEN + palette_size ;
318
324
bitmap -> dibheadersize = 40 ;
319
325
bitmap -> width = width ;
320
326
bitmap -> height = - height ;//set negative for top to bottom
321
327
bitmap -> planes = 1 ;
322
- bitmap -> bitsperpixel = 24 ;
328
+ bitmap -> bitsperpixel = bpp * 8 ;
323
329
bitmap -> compression = 0 ;
324
- bitmap -> imagesize = pix_count * 3 ;
330
+ bitmap -> imagesize = pix_count * bpp ;
325
331
bitmap -> ypixelpermeter = 0x0B13 ; //2835 , 72 DPI
326
332
bitmap -> xpixelpermeter = 0x0B13 ; //2835 , 72 DPI
327
333
bitmap -> numcolorspallette = 0 ;
328
334
bitmap -> mostimpcolor = 0 ;
329
335
330
- uint8_t * rgb_buf = out_buf + BMP_HEADER_LEN ;
336
+ uint8_t * palette_buf = out_buf + BMP_HEADER_LEN ;
337
+ uint8_t * pix_buf = palette_buf + palette_size ;
331
338
uint8_t * src_buf = src ;
332
339
340
+ if (palette_size > 0 ) {
341
+ // Grayscale palette
342
+ for (int i = 0 ; i < 256 ; ++ i ) {
343
+ for (int j = 0 ; j < 3 ; ++ j ) {
344
+ * palette_buf = i ;
345
+ palette_buf ++ ;
346
+ }
347
+ // Reserved / alpha channel.
348
+ * palette_buf = 0 ;
349
+ palette_buf ++ ;
350
+ }
351
+ }
333
352
334
353
//convert data to RGB888
335
354
if (format == PIXFORMAT_RGB888 ) {
336
- memcpy (rgb_buf , src_buf , pix_count * 3 );
355
+ memcpy (pix_buf , src_buf , pix_count * 3 );
337
356
} else if (format == PIXFORMAT_RGB565 ) {
338
357
int i ;
339
358
uint8_t hb , lb ;
340
359
for (i = 0 ; i < pix_count ; i ++ ) {
341
360
hb = * src_buf ++ ;
342
361
lb = * src_buf ++ ;
343
- * rgb_buf ++ = (lb & 0x1F ) << 3 ;
344
- * rgb_buf ++ = (hb & 0x07 ) << 5 | (lb & 0xE0 ) >> 3 ;
345
- * rgb_buf ++ = hb & 0xF8 ;
362
+ * pix_buf ++ = (lb & 0x1F ) << 3 ;
363
+ * pix_buf ++ = (hb & 0x07 ) << 5 | (lb & 0xE0 ) >> 3 ;
364
+ * pix_buf ++ = hb & 0xF8 ;
346
365
}
347
366
} else if (format == PIXFORMAT_GRAYSCALE ) {
348
- int i ;
349
- uint8_t b ;
350
- for (i = 0 ; i < pix_count ; i ++ ) {
351
- b = * src_buf ++ ;
352
- * rgb_buf ++ = b ;
353
- * rgb_buf ++ = b ;
354
- * rgb_buf ++ = b ;
355
- }
367
+ memcpy (pix_buf , src_buf , pix_count );
356
368
} else if (format == PIXFORMAT_YUV422 ) {
357
369
int i , maxi = pix_count / 2 ;
358
370
uint8_t y0 , y1 , u , v ;
@@ -364,14 +376,14 @@ bool fmt2bmp(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixf
364
376
v = * src_buf ++ ;
365
377
366
378
yuv2rgb (y0 , u , v , & r , & g , & b );
367
- * rgb_buf ++ = b ;
368
- * rgb_buf ++ = g ;
369
- * rgb_buf ++ = r ;
379
+ * pix_buf ++ = b ;
380
+ * pix_buf ++ = g ;
381
+ * pix_buf ++ = r ;
370
382
371
383
yuv2rgb (y1 , u , v , & r , & g , & b );
372
- * rgb_buf ++ = b ;
373
- * rgb_buf ++ = g ;
374
- * rgb_buf ++ = r ;
384
+ * pix_buf ++ = b ;
385
+ * pix_buf ++ = g ;
386
+ * pix_buf ++ = r ;
375
387
}
376
388
}
377
389
* out = out_buf ;
0 commit comments