Skip to content

OnDiskBitmap: INCOMPATIBLE CHANGE: Allow them to use palettes #4823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion shared-bindings/displayio/OnDiskBitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
//|
//| with open("/sample.bmp", "rb") as f:
//| odb = displayio.OnDiskBitmap(f)
//| face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
//| face = displayio.TileGrid(odb, pixel_shader=odb.pixel_shader)
//| splash.append(face)
//| # Wait for the image to load.
//| board.DISPLAY.refresh(target_frames_per_second=60)
Expand Down Expand Up @@ -127,8 +127,29 @@ const mp_obj_property_t displayio_ondiskbitmap_height_obj = {

};

//| pixel_shader: Union[ColorConverter, Palette]
//| """The image's pixel_shader. The type depends on the underlying
//| bitmap's structure. The pixel shadder can be modified (e.g., to set the
//| transparent pixel or, for paletted images, to update the palette"""
//|
STATIC mp_obj_t displayio_ondiskbitmap_obj_get_pixel_shader(mp_obj_t self_in) {
displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_displayio_ondiskbitmap_get_pixel_shader(self);
}

MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_pixel_shader_obj, displayio_ondiskbitmap_obj_get_pixel_shader);

const mp_obj_property_t displayio_ondiskbitmap_pixel_shader_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_pixel_shader_obj,
(mp_obj_t)MP_ROM_NONE,
(mp_obj_t)MP_ROM_NONE},
};


STATIC const mp_rom_map_elem_t displayio_ondiskbitmap_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_ondiskbitmap_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_ondiskbitmap_pixel_shader_obj) },
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_ondiskbitmap_width_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_ondiskbitmap_locals_dict, displayio_ondiskbitmap_locals_dict_table);
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/displayio/OnDiskBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *b
int16_t x, int16_t y);

uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self);

mp_obj_t common_hal_displayio_ondiskbitmap_get_pixel_shader(displayio_ondiskbitmap_t *self);
uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H
2 changes: 1 addition & 1 deletion shared-module/displayio/ColorConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "py/obj.h"
#include "shared-module/displayio/Palette.h"

typedef struct {
typedef struct displayio_colorconverter {
mp_obj_base_t base;
bool dither;
uint8_t input_colorspace;
Expand Down
63 changes: 42 additions & 21 deletions shared-module/displayio/OnDiskBitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
*/

#include "shared-bindings/displayio/OnDiskBitmap.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/Palette.h"
#include "shared-module/displayio/ColorConverter.h"
#include "shared-module/displayio/Palette.h"

#include <string.h>

Expand Down Expand Up @@ -63,6 +67,11 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
self->width = read_word(bmp_header, 9);
self->height = read_word(bmp_header, 11);

displayio_colorconverter_t *colorconverter = m_new_obj(displayio_colorconverter_t);
colorconverter->base.type = &displayio_colorconverter_type;
common_hal_displayio_colorconverter_construct(colorconverter, false, DISPLAYIO_COLORSPACE_RGB888);
self->colorconverter = colorconverter;

if (bits_per_pixel == 16) {
if (((header_size >= 56)) || (self->bitfield_compressed)) {
self->r_bitmask = read_word(bmp_header, 27);
Expand All @@ -74,25 +83,41 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
self->g_bitmask = 0x3e0;
self->b_bitmask = 0x1f;
}
} else if (indexed && self->bits_per_pixel != 1) {
} else if (indexed) {
if (number_of_colors == 0) {
number_of_colors = 1 << bits_per_pixel;
}
uint16_t palette_size = number_of_colors * sizeof(uint32_t);
uint16_t palette_offset = 0xe + header_size;

self->palette_data = m_malloc(palette_size, false);
displayio_palette_t *palette = m_new_obj(displayio_palette_t);
palette->base.type = &displayio_palette_type;
common_hal_displayio_palette_construct(palette, number_of_colors);

f_rewind(&self->file->fp);
f_lseek(&self->file->fp, palette_offset);
if (number_of_colors > 1) {
uint16_t palette_size = number_of_colors * sizeof(uint32_t);
uint16_t palette_offset = 0xe + header_size;

UINT palette_bytes_read;
if (f_read(&self->file->fp, self->palette_data, palette_size, &palette_bytes_read) != FR_OK) {
mp_raise_OSError(MP_EIO);
}
if (palette_bytes_read != palette_size) {
mp_raise_ValueError(translate("Unable to read color palette data"));
uint32_t *palette_data = m_malloc(palette_size, false);

f_rewind(&self->file->fp);
f_lseek(&self->file->fp, palette_offset);

UINT palette_bytes_read;
if (f_read(&self->file->fp, palette_data, palette_size, &palette_bytes_read) != FR_OK) {
mp_raise_OSError(MP_EIO);
}
if (palette_bytes_read != palette_size) {
mp_raise_ValueError(translate("Unable to read color palette data"));
}
for (uint16_t i = 0; i < palette_size; i++) {
common_hal_displayio_palette_set_color(palette, i, palette_data[i]);
}
m_free(palette_data);
} else {
common_hal_displayio_palette_set_color(palette, 0, 0x0);
common_hal_displayio_palette_set_color(palette, 1, 0xffffff);
}
self->palette = palette;

} else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) {
mp_raise_ValueError_varg(translate("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size);
}
Expand Down Expand Up @@ -148,15 +173,7 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
uint8_t offset = (x % pixels_per_byte) * self->bits_per_pixel;
uint8_t mask = (1 << self->bits_per_pixel) - 1;

uint8_t index = (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask;
if (self->bits_per_pixel == 1) {
if (index == 1) {
return 0xFFFFFF;
} else {
return 0x000000;
}
}
return self->palette_data[index];
return (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask;
} else if (bytes_per_pixel == 2) {
if (self->g_bitmask == 0x07e0) { // 565
red = ((pixel_data & self->r_bitmask) >> 11);
Expand Down Expand Up @@ -185,3 +202,7 @@ uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *
uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self) {
return self->width;
}

mp_obj_t common_hal_displayio_ondiskbitmap_get_pixel_shader(displayio_ondiskbitmap_t *self) {
return MP_OBJ_FROM_PTR(self->pixel_shader_base);
}
8 changes: 6 additions & 2 deletions shared-module/displayio/OnDiskBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,14 @@ typedef struct {
uint32_t r_bitmask;
uint32_t g_bitmask;
uint32_t b_bitmask;
bool bitfield_compressed;
pyb_file_obj_t *file;
union {
mp_obj_base_t *pixel_shader_base;
struct displayio_palette *palette;
struct displayio_colorconverter *colorconverter;
};
bool bitfield_compressed;
uint8_t bits_per_pixel;
uint32_t *palette_data;
} displayio_ondiskbitmap_t;

#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKBITMAP_H
2 changes: 1 addition & 1 deletion shared-module/displayio/Palette.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ typedef struct {
bool opaque;
} displayio_output_pixel_t;

typedef struct {
typedef struct displayio_palette {
mp_obj_base_t base;
_displayio_color_t *colors;
uint32_t color_count;
Expand Down