diff options
| author | sommersoft <sommersoft@gmail.com> | 2019-02-26 04:29:16 +0000 |
|---|---|---|
| committer | sommersoft <sommersoft@gmail.com> | 2019-02-26 04:29:16 +0000 |
| commit | 9d20380bd43f0cc0d6eb638be1b20fc44d198eb7 (patch) | |
| tree | 91b58f2da718d03f710603bdef173206cc15d664 /shared-module/displayio | |
| parent | 4a9f05a44f18615a1adeacfcae329d3090188550 (diff) | |
| parent | 2c9fbb5d40c457e87a4c0db3906960484f3668c0 (diff) | |
Merge branch 'master' into new_freq_in
Diffstat (limited to 'shared-module/displayio')
| -rw-r--r-- | shared-module/displayio/OnDiskBitmap.c | 63 | ||||
| -rw-r--r-- | shared-module/displayio/OnDiskBitmap.h | 5 |
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; |
