8000 Merge pull request #3260 from rhooper/pixelbuf-iterable · ricardoquesada/circuitpython@6e5c2b3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e5c2b3

Browse files
authored
Merge pull request adafruit#3260 from rhooper/pixelbuf-iterable
Make pixelbuf support iterables and floats
2 parents dcbd3b4 + 16ff7b1 commit 6e5c2b3

File tree

5 files changed

+61
-34
lines changed

5 files changed

+61
-34
lines changed

locale/circuitpython.pot

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,7 @@ msgid "can't assign to expression"
19581958
msgstr ""
19591959

19601960
#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c
1961+
#: shared-module/_pixelbuf/PixelBuf.c
19611962
msgid "can't convert %q to %q"
19621963
msgstr ""
19631964

@@ -3155,10 +3156,6 @@ msgstr ""
31553156
msgid "tuple/list has wrong length"
31563157
msgstr ""
31573158

3158-
#: shared-bindings/_pixelbuf/PixelBuf.c
3159-
msgid "tuple/list required on RHS"
3160-
msgstr ""
3161-
31623159
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
31633160
#: shared-bindings/busio/UART.c
31643161
msgid "tx and rx cannot both be None"

ports/atmel-samd/boards/bdmicro_vina_m0/mpconfigboard.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ CIRCUITPY_BITBANGIO = 0
1515
CIRCUITPY_I2CPERIPHERAL = 0
1616
CIRCUITPY_VECTORIO = 0
1717

18-
CFLAGS_INLINE_LIMIT = 60
18+
CFLAGS_INLINE_LIMIT = 50
1919
SUPEROPT_GC = 0

shared-bindings/_pixelbuf/PixelBuf.c

Lines changed: 19 additions & 19 deletions
< 8000 td data-grid-cell-id="diff-8c513b8abc944da570cc140ae9a6858a79fcbad23fd607e8e5967e5d9489fb4f-308-322-2" data-line-anchor="diff-8c513b8abc944da570cc140ae9a6858a79fcbad23fd607e8e5967e5d9489fb4fR322" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell right-side-diff-cell left-side">

Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
#include "shared-module/_pixelbuf/PixelBuf.h"
4141
#include "shared-bindings/digitalio/DigitalInOut.h"
4242

43+
#ifdef CIRCUITPY_ULAB
44+
#include "extmod/ulab/code/ndarray.h"
45+
#endif
46+
4347
extern const int32_t colorwheel(float pos);
4448

4549
static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t* parsed);
@@ -305,6 +309,16 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
305309

306310
size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in);
307311
mp_seq_get_fast_slice_indexes(length, index_in, &slice);
312+
static mp_obj_tuple_t flat_item_tuple = {
313+
.base = {&mp_type_tuple},
314+
.len = 0,
315+
.items = {
316+
mp_const_none,
317+
mp_const_none,
318+
mp_const_none,
319+
mp_const_none,
320+
}
321+
};
308322
309323
size_t slice_len;
310324
if (slice.step > 0) {
@@ -326,27 +340,13 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
326340
} else { // Set
327341
#if MICROPY_PY_ARRAY_SLICE_ASSIGN
328342

329-
if (!(MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple))) {
330-
mp_raise_ValueError(translate("tuple/list required on RHS"));
331-
}
343+
size_t num_items = mp_obj_get_int(mp_obj_len(value));
332344

333-
mp_obj_t *src_objs;
334-
size_t num_items;
335-
if (MP_OBJ_IS_TYPE(value, &mp_type_list)) {
336-
mp_obj_list_t *t = MP_OBJ_TO_PTR(value);
337-
num_items = t->len;
338-
src_objs = t->items;
339-
} else {
340-
mp_obj_tuple_t *l = MP_OBJ_TO_PTR(value);
341-
num_items = l->len;
342-
src_objs = l->items;
343-
}
344-
if (num_items != slice_len) {
345-
mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."),
346-
slice_len, num_items);
345+
if (num_items != slice_len && num_items != (slice_len * common_hal__pixelbuf_pixelbuf_get_bpp(self_in))) {
346+
mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."), slice_len, num_items);
347347
}
348-
349-
common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.step, slice_len, src_objs);
348+
common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.step, slice_len, value,
349+
num_items != slice_len ? &flat_item_tuple : mp_const_none);
350350
return mp_const_none;
351351
#else
352352
return MP_OBJ_NULL; // op not supported

shared-bindings/_pixelbuf/PixelBuf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ void common_hal__pixelbuf_pixelbuf_fill(mp_obj_t self, mp_obj_t item);
4747
void common_hal__pixelbuf_pixelbuf_show(mp_obj_t self);
4848
mp_obj_t common_hal__pixelbuf_pixelbuf_get_pixel(mp_obj_t self, size_t index);
4949
void common_hal__pixelbuf_pixelbuf_set_pixel(mp_obj_t self, size_t index, mp_obj_t item);
50-
void common_hal__pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t* values);
50+
void common_hal__pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t* values, mp_obj_tuple_t *flatten_to);
5151

5252
#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H

shared-module/_pixelbuf/PixelBuf.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ void common_hal__pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_float_t b
132132
}
133133
}
134134

135+
uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) {
136+
if (MP_OBJ_IS_SMALL_INT(obj)) {
137+
return MP_OBJ_SMALL_INT_VALUE(obj);
138+
} else if (MP_OBJ_IS_INT(obj)) {
139+
return mp_obj_get_int_truncated(obj);
140+
} else if (mp_obj_is_float(obj)) {
141+
return (uint8_t)mp_obj_get_float(obj);
142+
}
143+
mp_raise_TypeError_varg(
144+
translate("can't convert %q to %q"), mp_obj_get_type_qstr(obj), MP_QSTR_int);
145+
}
146+
135147
void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t* self, mp_obj_t color, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* w) {
136148
pixelbuf_byteorder_details_t *byteorder = &self->byteorder;
137149
// w is shared between white in NeoPixels and brightness in dotstars (so that DotStars can have
@@ -142,8 +154,8 @@ void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t* self, mp_obj_t color, uint8_
142154
*w = 0;
143155
}
144156

145-
if (MP_OBJ_IS_INT(color)) {
146-
mp_int_t value = mp_obj_get_int_truncated(color);
157+
if (MP_OBJ_IS_INT(color) || mp_obj_is_float(color)) {
158+
mp_int_t value = MP_OBJ_IS_INT(color) ? mp_obj_get_int_truncated(color) : mp_obj_get_float(color);
147159
*r = value >> 16 & 0xff;
148160
*g = (value >> 8) & 0xff;
149161
*b = value & 0xff;
@@ -155,9 +167,9 @@ void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t* self, mp_obj_t color, uint8_
155167
mp_raise_ValueError_varg(translate("Expected tuple of length %d, got %d"), byteorder->bpp, len);
156168
}
157169

158-
*r = mp_obj_get_int_truncated(items[PIXEL_R]);
159-
*g = mp_obj_get_int_truncated(items[PIXEL_G]);
160-
*b = mp_obj_get_int_truncated(items[PIXEL_B]);
170+
*r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
171+
*g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
172+
*b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
161173
if (len > 3) {
162174
if (mp_obj_is_float(items[PIXEL_W])) {
163175
*w = 255 * mp_obj_get_float(items[PIXEL_W]);
@@ -218,17 +230,35 @@ void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t* self, size_t index, mp_obj_t v
218230
_pixelbuf_set_pixel_color(self, index, r, g, b, w);
219231
}
220232

221-
void common_hal__pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t* values) {
233+
void common_hal__pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t* values,
234+
mp_obj_tuple_t *flatten_to)
235+
{
222236
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
223-
for (size_t i = 0; i < slice_len; i++) {
224-
_pixelbuf_set_pixel(self, start, values[i]);
225-
start+=step;
237+
mp_obj_iter_buf_t iter_buf;
238+
mp_obj_t iterable = mp_getiter(values, &iter_buf);
239+
mp_obj_t item;
240+
size_t i = 0;
241+
bool flattened = flatten_to != mp_const_none;
242+
if (flattened) flatten_to->len = self->bytes_per_pixel;
243+
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
244+
if (flattened) {
245+
flatten_to->items[i % self->bytes_per_pixel] = item;
246+
if (++i % self->bytes_per_pixel == 0) {
247+
_pixelbuf_set_pixel(self, start, flatten_to);
248+
start+=step;
249+
}
250+
} else {
251+
_pixelbuf_set_pixel(self, start, item);
252+
start+=step;
253+
}
226254
}
227255
if (self->auto_write) {
228256
common_hal__pixelbuf_pixelbuf_show(self_in);
229257
}
230258
}
231259

260+
261+
232262
void common_hal__pixelbuf_pixelbuf_set_pixel(mp_obj_t self_in, size_t index, mp_obj_t value) {
233263
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
234264
_pixelbuf_set_pixel(self, index, value);

0 commit comments

Comments
 (0)
0