summaryrefslogtreecommitdiff
path: root/shared-module/displayio
diff options
context:
space:
mode:
Diffstat (limited to 'shared-module/displayio')
-rw-r--r--shared-module/displayio/OnDiskBitmap.c63
-rw-r--r--shared-module/displayio/OnDiskBitmap.h5
2 files changed, 59 insertions, 9 deletions
diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c
index aa2ca3e10..bc3064632 100644
--- a/shared-module/displayio/OnDiskBitmap.c
+++ b/shared-module/displayio/OnDiskBitmap.c
@@ -38,13 +38,13 @@ static uint32_t read_word(uint16_t* bmp_header, uint16_t index) {
void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, pyb_file_obj_t* file) {
// Load the wave
self->file = file;
- uint16_t bmp_header[24];
+ uint16_t bmp_header[69];
f_rewind(&self->file->fp);
UINT bytes_read;
- if (f_read(&self->file->fp, bmp_header, 48, &bytes_read) != FR_OK) {
+ if (f_read(&self->file->fp, bmp_header, 138, &bytes_read) != FR_OK) {
mp_raise_OSError(MP_EIO);
}
- if (bytes_read != 48 ||
+ if (bytes_read != 138 ||
memcmp(bmp_header, "BM", 2) != 0) {
mp_raise_ValueError(translate("Invalid BMP file"));
}
@@ -53,15 +53,35 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
self->data_offset = read_word(bmp_header, 5);
uint32_t header_size = read_word(bmp_header, 7);
+ uint16_t bits_per_pixel = bmp_header[14];
uint32_t compression = read_word(bmp_header, 15);
- if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124) ||
+ uint32_t number_of_colors = read_word(bmp_header, 23);
+ self->bitfield_compressed = (compression == 3);
+
+ self->grayscale = ((bits_per_pixel == 8) && (number_of_colors == 256));
+ if (bits_per_pixel == 16){
+ if (((header_size == 124) || (header_size == 56)) && (self->bitfield_compressed)) {
+ self->r_bitmask = read_word(bmp_header, 27);
+ self->g_bitmask = read_word(bmp_header, 29);
+ self->b_bitmask = read_word(bmp_header, 31);
+
+ if (!((self->r_bitmask == 0xf800) && (self->g_bitmask == 0x07e0) && (self->b_bitmask == 0x001f))){
+ mp_raise_ValueError_varg(translate("Only 16bpp RGB 565 supported for bitfield compressed BMPs; R:%x G:%x B:%x"),
+ self->r_bitmask, self->g_bitmask, self->b_bitmask);
+ }
+ } else if (header_size == 40){ // no bitmasks means 5:5:5
+ self->r_bitmask = 0x7c00;
+ self->g_bitmask = 0x3e0;
+ self->b_bitmask = 0x1f;
+ }
+
+ } else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124) ||
!(compression == 0)) {
mp_raise_ValueError_varg(translate("Only Windows format, uncompressed BMP supported %d"), header_size);
}
- // TODO(tannewt): Support bitfield compressed colors since RGB565 can be produced by the GIMP.
- uint16_t bits_per_pixel = bmp_header[14];
- if (bits_per_pixel < 24) {
- mp_raise_ValueError_varg(translate("Only true color (24 bpp or higher) BMP supported %x"), bits_per_pixel);
+
+ if (bits_per_pixel < 16 && !(self->grayscale)) {
+ mp_raise_ValueError_varg(translate("Only true color (24 bpp or higher), 16bpp 565 and 555, and 8bpp grayscale BMP supported %d"), bits_per_pixel);
}
self->bytes_per_pixel = bits_per_pixel / 8;
self->width = read_word(bmp_header, 9);
@@ -87,7 +107,32 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
uint32_t pixel = 0;
uint32_t result = f_read(&self->file->fp, &pixel, self->bytes_per_pixel, &bytes_read);
if (result == FR_OK) {
- return pixel;
+ uint32_t tmp = 0;
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+ if (self->grayscale){
+ red = pixel;
+ green = pixel;
+ blue = pixel;
+ tmp = (red << 16 | green << 8 | blue);
+ return tmp;
+ } else if (self->bytes_per_pixel == 2) {
+ if (self->bitfield_compressed){
+ red =((pixel & self->r_bitmask) >>11);
+ green = ((pixel & self->g_bitmask) >>5);
+ blue = ((pixel & self->b_bitmask) >> 0);
+ } else {
+ red =((pixel & self->r_bitmask) >>10);
+ green = ((pixel & self->g_bitmask) >>4);
+ blue = ((pixel & self->b_bitmask) >> 0);
+ }
+ tmp = (red << 19 | green << 10 | blue << 3);
+ return tmp;
+ }else {
+ return pixel;
+ }
+
}
return 0;
}
diff --git a/shared-module/displayio/OnDiskBitmap.h b/shared-module/displayio/OnDiskBitmap.h
index 31d6c9550..2102863d6 100644
--- a/shared-module/displayio/OnDiskBitmap.h
+++ b/shared-module/displayio/OnDiskBitmap.h
@@ -40,6 +40,11 @@ typedef struct {
uint16_t height;
uint16_t data_offset;
uint16_t stride;
+ uint32_t r_bitmask;
+ uint32_t g_bitmask;
+ uint32_t b_bitmask;
+ bool bitfield_compressed;
+ bool grayscale;
pyb_file_obj_t* file;
uint8_t bytes_per_pixel;
} displayio_ondiskbitmap_t;