Skip to content

Commit ac034d0

Browse files
committed
PixelBuf: Add support for 2D buffers
1 parent ae751a1 commit ac034d0

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

shared-bindings/_pixelbuf/PixelBuf.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,15 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t
7272
//|
7373
STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
7474
mp_arg_check_num(n_args, kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
75-
enum { ARG_size, ARG_byteorder, ARG_brightness, ARG_auto_write, ARG_header, ARG_trailer };
75+
enum { ARG_size, ARG_byteorder, ARG_brightness, ARG_auto_write, ARG_header, ARG_trailer, ARG_width };
7676
static const mp_arg_t allowed_args[] = {
7777
{ MP_QSTR_size, MP_ARG_REQUIRED | MP_ARG_INT },
7878
{ MP_QSTR_byteorder, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_BGR) } },
7979
{ MP_QSTR_brightness, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
8080
{ MP_QSTR_auto_write, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
8181
{ MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
8282
{ MP_QSTR_trailer, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
83+
{ MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
8384
};
8485
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
8586
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -89,7 +90,11 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
8990

9091
mp_buffer_info_t header_bufinfo;
9192
mp_buffer_info_t trailer_bufinfo;
93+
int width = -1;
9294

95+
if (args[ARG_width].u_obj != mp_const_none) {
96+
width = MP_OBJ_SMALL_INT_VALUE(args[ARG_width].u_obj);
97+
}
9398
if (!mp_get_buffer(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ)) {
9499
header_bufinfo.buf = NULL;
95100
header_bufinfo.len = 0;
@@ -114,7 +119,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
114119
self->base.type = &pixelbuf_pixelbuf_type;
115120
common_hal__pixelbuf_pixelbuf_construct(self, args[ARG_size].u_int,
116121
&byteorder_details, brightness, args[ARG_auto_write].u_bool, header_bufinfo.buf,
117-
header_bufinfo.len, trailer_bufinfo.buf, trailer_bufinfo.len);
122+
header_bufinfo.len, trailer_bufinfo.buf, trailer_bufinfo.len, width);
118123

119124
return MP_OBJ_FROM_PTR(self);
120125
}
@@ -277,6 +282,27 @@ STATIC mp_obj_t pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t value) {
277282
}
278283
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_fill);
279284

285+
STATIC size_t pixelbuf_get_index(mp_obj_t self_in, mp_obj_t index_in) {
286+
size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in);
287+
int16_t width = common_hal__pixelbuf_pixelbuf_get_width(self_in);
288+
if(width != -1 && MP_OBJ_IS_TYPE(index_in, &mp_type_tuple)) {
289+
size_t x = mp_get_index(mp_obj_get_type(self_in),
290+
width,
291+
mp_obj_tuple_subscr(index_in,
292+
MP_OBJ_NEW_SMALL_INT(0),
293+
MP_OBJ_SENTINEL),
294+
false);
295+
size_t y = mp_get_index(mp_obj_get_type(self_in),
296+
common_hal__pixelbuf_pixelbuf_get_height(self_in),
297+
mp_obj_tuple_subscr(index_in,
298+
MP_OBJ_NEW_SMALL_INT(1),
299+
MP_OBJ_SENTINEL),
300+
false);
301+
return x + width * y;
302+
} else {
303+
return mp_get_index(self_in, length, index_in, false);
304+
}
305+
}
280306

281307
//| .. method:: __getitem__(index)
282308
//|
@@ -353,8 +379,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
353379
}
354380
#endif
355381
} else { // Single index rather than slice.
356-
size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in);
357-
size_t index = mp_get_index(mp_obj_get_type(self_in), length, index_in, false);
382+
size_t index = pixelbuf_get_index(self_in, index_in);
358383

359384
if (value == MP_OBJ_SENTINEL) { // Get
360385
return common_hal__pixelbuf_pixelbuf_get_pixel(self_in, index);

shared-bindings/_pixelbuf/PixelBuf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const mp_obj_type_t pixelbuf_pixelbuf_type;
3333

3434
void common_hal__pixelbuf_pixelbuf_construct(pixelbuf_pixelbuf_obj_t *self, size_t n,
3535
pixelbuf_byteorder_details_t* byteorder, mp_float_t brightness, bool auto_write, uint8_t* header,
36-
size_t header_len, uint8_t* trailer, size_t trailer_len);
36+
size_t header_len, uint8_t* trailer, size_t trailer_len, int width);
3737

3838
// These take mp_obj_t because they are called on subclasses of PixelBuf.
3939
uint8_t common_hal__pixelbuf_pixelbuf_get_bpp(mp_obj_t self);
@@ -42,6 +42,8 @@ void common_hal__pixelbuf_pixelbuf_set_brightness(mp_obj_t self, mp_float_t brig
4242
bool common_hal__pixelbuf_pixelbuf_get_auto_write(mp_obj_t self);
4343
void common_hal__pixelbuf_pixelbuf_set_auto_write(mp_obj_t self, bool auto_write);
4444
size_t common_hal__pixelbuf_pixelbuf_get_len(mp_obj_t self_in);
45+
int common_hal__pixelbuf_pixelbuf_get_width(mp_obj_t self_in);
46+
int common_hal__pixelbuf_pixelbuf_get_height(mp_obj_t self_in);
4547
mp_obj_t common_hal__pixelbuf_pixelbuf_get_byteorder_string(mp_obj_t self);
4648
void common_hal__pixelbuf_pixelbuf_fill(mp_obj_t self, mp_obj_t item);
4749
void common_hal__pixelbuf_pixelbuf_show(mp_obj_t self);

shared-module/_pixelbuf/PixelBuf.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ static pixelbuf_pixelbuf_obj_t* native_pixelbuf(mp_obj_t pixelbuf_obj) {
4141

4242
void common_hal__pixelbuf_pixelbuf_construct(pixelbuf_pixelbuf_obj_t *self, size_t n,
4343
pixelbuf_byteorder_details_t* byteorder, mp_float_t brightness, bool auto_write,
44-
uint8_t* header, size_t header_len, uint8_t* trailer, size_t trailer_len) {
44+
uint8_t* header, size_t header_len, uint8_t* trailer, size_t trailer_len, int width) {
4545

4646
self->pixel_count = n;
4747
self->byteorder = *byteorder; // Copied because we modify for dotstar
4848
self->bytes_per_pixel = byteorder->is_dotstar ? 4 : byteorder->bpp;
4949
self->auto_write = false;
50+
self->width = width;
5051

5152
size_t pixel_len = self->pixel_count * self->bytes_per_pixel;
5253
self->transmit_buffer_obj = mp_obj_new_bytes_of_zeros(header_len + pixel_len + trailer_len);
@@ -80,6 +81,16 @@ size_t common_hal__pixelbuf_pixelbuf_get_len(mp_obj_t self_in) {
8081
return self->pixel_count;
8182
}
8283

84+
int common_hal__pixelbuf_pixelbuf_get_width(mp_obj_t self_in) {
85+
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
86+
return self->width;
87+
}
88+
89+
int common_hal__pixelbuf_pixelbuf_get_height(mp_obj_t self_in) {
90+
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
91+
return self->width == -1 ? -1 : (int)self->pixel_count / self->width;
92+
}
93+
8394
uint8_t common_hal__pixelbuf_pixelbuf_get_bpp(mp_obj_t self_in) {
8495
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
8596
return self->byteorder.bpp;

shared-module/_pixelbuf/PixelBuf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ typedef struct {
5050
mp_obj_base_t base;
5151
size_t pixel_count;
5252
size_t bytes_per_pixel;
53+
int16_t width;
5354
pixelbuf_byteorder_details_t byteorder;
5455
mp_float_t brightness;
5556
mp_obj_t transmit_buffer_obj;

0 commit comments

Comments
 (0)