Browse Source

extmod/modframebuf: Add 2-bit color format (GS2_HMSB).

This format is used in 2-color LED matrices and in e-ink displays like
SSD1606.
pull/3422/merge
Petr Viktorin 7 years ago
committed by Damien George
parent
commit
34247465c3
  1. 4
      docs/library/framebuf.rst
  2. 30
      extmod/modframebuf.c
  3. 62
      tests/extmod/framebuf2.py
  4. 57
      tests/extmod/framebuf2.py.exp

4
docs/library/framebuf.rst

@ -148,6 +148,10 @@ Constants
Red Green Blue (16-bit, 5+6+5) color format Red Green Blue (16-bit, 5+6+5) color format
.. data:: framebuf.GS2_HMSB
Grayscale (2-bit) color format
.. data:: framebuf.GS4_HMSB .. data:: framebuf.GS4_HMSB
Grayscale (4-bit) color format Grayscale (4-bit) color format

30
extmod/modframebuf.c

@ -54,6 +54,7 @@ typedef struct _mp_framebuf_p_t {
// constants for formats // constants for formats
#define FRAMEBUF_MVLSB (0) #define FRAMEBUF_MVLSB (0)
#define FRAMEBUF_RGB565 (1) #define FRAMEBUF_RGB565 (1)
#define FRAMEBUF_GS2_HMSB (5)
#define FRAMEBUF_GS4_HMSB (2) #define FRAMEBUF_GS4_HMSB (2)
#define FRAMEBUF_MHLSB (3) #define FRAMEBUF_MHLSB (3)
#define FRAMEBUF_MHMSB (4) #define FRAMEBUF_MHMSB (4)
@ -130,6 +131,30 @@ STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, i
} }
} }
// Functions for GS2_HMSB format
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1;
uint8_t mask = 0x3 << shift;
uint8_t color = (col & 0x3) << shift;
*pixel = color | (*pixel & (~mask));
}
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
uint8_t pixel = ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1;
return (pixel >> shift) & 0x3;
}
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
for (int xx=x; xx < x+w; xx++) {
for (int yy=y; yy < y+h; yy++) {
gs2_hmsb_setpixel(fb, xx, yy, col);
}
}
}
// Functions for GS4_HMSB format // Functions for GS4_HMSB format
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) { STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
@ -184,6 +209,7 @@ STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,
STATIC mp_framebuf_p_t formats[] = { STATIC mp_framebuf_p_t formats[] = {
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect}, [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect}, [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
[FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect}, [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, [FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
@ -240,6 +266,9 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
case FRAMEBUF_MHMSB: case FRAMEBUF_MHMSB:
o->stride = (o->stride + 7) & ~7; o->stride = (o->stride + 7) & ~7;
break; break;
case FRAMEBUF_GS2_HMSB:
o->stride = (o->stride + 3) & ~3;
break;
case FRAMEBUF_GS4_HMSB: case FRAMEBUF_GS4_HMSB:
o->stride = (o->stride + 1) & ~1; o->stride = (o->stride + 1) & ~1;
break; break;
@ -579,6 +608,7 @@ STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, { MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
{ MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, { MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) }, { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) },
{ MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) },
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) }, { MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) },
{ MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) }, { MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) },
{ MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) }, { MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) },

62
tests/extmod/framebuf2.py

@ -0,0 +1,62 @@
try:
import framebuf
except ImportError:
print("SKIP")
raise SystemExit
def printbuf():
print("--8<--")
for y in range(h):
for x in range(w):
print('%u' % ((buf[(x + y * w) // 4] >> ((x & 3) << 1)) & 3), end='')
print()
print("-->8--")
w = 8
h = 5
buf = bytearray(w * h // 4)
fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS2_HMSB)
# fill
fbuf.fill(3)
printbuf()
fbuf.fill(0)
printbuf()
# put pixel
fbuf.pixel(0, 0, 1)
fbuf.pixel(3, 0, 2)
fbuf.pixel(0, 4, 3)
fbuf.pixel(3, 4, 2)
printbuf()
# get pixel
print(fbuf.pixel(0, 4), fbuf.pixel(1, 1))
# scroll
fbuf.fill(0)
fbuf.pixel(2, 2, 3)
printbuf()
fbuf.scroll(0, 1)
printbuf()
fbuf.scroll(1, 0)
printbuf()
fbuf.scroll(-1, -2)
printbuf()
w2 = 2
h2 = 3
buf2 = bytearray(w2 * h2 // 4)
fbuf2 = framebuf.FrameBuffer(buf2, w2, h2, framebuf.GS2_HMSB)
# blit
fbuf2.fill(0)
fbuf2.pixel(0, 0, 1)
fbuf2.pixel(0, 2, 2)
fbuf2.pixel(1, 0, 1)
fbuf2.pixel(1, 2, 2)
fbuf.fill(3)
fbuf.blit(fbuf2, 3, 3, 0)
fbuf.blit(fbuf2, -1, -1, 0)
fbuf.blit(fbuf2, 16, 16, 0)
printbuf()

57
tests/extmod/framebuf2.py.exp

@ -0,0 +1,57 @@
--8<--
33333333
33333333
33333333
33333333
33333333
-->8--
--8<--
00000000
00000000
00000000
00000000
00000000
-->8--
--8<--
10020000
00000000
00000000
00000000
30020000
-->8--
3 0
--8<--
00000000
00000000
00300000
00000000
00000000
-->8--
--8<--
00000000
00000000
00000000
00300000
00000000
-->8--
--8<--
00000000
00000000
00000000
00030000
00000000
-->8--
--8<--
00000000
00300000
00000000
00030000
00000000
-->8--
--8<--
33333333
23333333
33333333
33311333
33333333
-->8--
Loading…
Cancel
Save