summaryrefslogtreecommitdiff
path: root/shared-bindings/_pixelbuf/PixelBuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-bindings/_pixelbuf/PixelBuf.c')
-rw-r--r--shared-bindings/_pixelbuf/PixelBuf.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c
index d8f1810db..c953951ea 100644
--- a/shared-bindings/_pixelbuf/PixelBuf.c
+++ b/shared-bindings/_pixelbuf/PixelBuf.c
@@ -53,18 +53,13 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t
//| When brightness is less than 1.0, a second buffer will be used to store the color values
//| before they are adjusted for brightness.
//|
-//| When ``P`` (pwm duration) is present as the 4th character of the byteorder
+//| When ``P`` (PWM duration) is present as the 4th character of the byteorder
//| string, the 4th value in the tuple/list for a pixel is the individual pixel
-//| brightness (0.0-1.0) and will enable a Dotstar compatible 1st byte in the
-//| output buffer (``buf``).
-//|
-//| When ``P`` (pwm duration) is present as the first character of the byteorder
-//| string, the 4th value in the tuple/list for a pixel is the individual pixel
-//| brightness (0.0-1.0) and will enable a Dotstar compatible 1st byte in the
-//| output buffer (``buf``).
+//| brightness (0.0-1.0) and will enable a Dotstar compatible 1st byte for each
+//| pixel.
//|
//| :param ~int size: Number of pixels
-//| :param ~str byteorder: Byte order string (such as "BGR" or "PBGR")
+//| :param ~str byteorder: Byte order string (such as "RGB", "RGBW" or "PBGR")
//| :param ~float brightness: Brightness (0 to 1.0, default 1.0)
//| :param ~bool auto_write: Whether to automatically write pixels (Default False)
//| :param bytes header: Sequence of bytes to always send before pixel values.
@@ -276,13 +271,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_f
//| def __getitem__(self, index: Any) -> Any:
//| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values
-//| between 0 and 255."""
+//| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel
+//| intensity from 0-1.0."""
//| ...
//|
//| def __setitem__(self, index: Any, value: Any) -> Any:
-//| """Sets the pixel value at the given index. Value can either be a tuple of (Red, Green, Blue
-//| [, White]) values between 0 and 255 or an integer where the red, green and blue values are
-//| packed into the lower three bytes (0xRRGGBB)."""
+//| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are
+//| The individual (Red, Green, Blue[, White]) values between 0 and 255. If given an integer, the
+//| red, green and blue values are packed into the lower three bytes (0xRRGGBB).
+//| For RGBW byteorders, if given only RGB values either as an int or as a tuple, the white value
+//| is used instead when the red, green, and blue values are the same."""
//| ...
//|
STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
@@ -300,17 +298,20 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in);
mp_seq_get_fast_slice_indexes(length, index_in, &slice);
- if (slice.step < 0) {
- mp_raise_IndexError(translate("Negative step not supported"));
+ size_t slice_len;
+ if (slice.step > 0) {
+ slice_len = slice.stop - slice.start;
+ } else {
+ slice_len = 1 + slice.start - slice.stop;
+ }
+ if (slice.step > 1 || slice.step < -1) {
+ size_t step = slice.step > 0 ? slice.step : slice.step * -1;
+ slice_len = (slice_len / step) + (slice_len % step ? 1 : 0);
}
if (value == MP_OBJ_SENTINEL) { // Get
- size_t len = slice.stop - slice.start;
- if (slice.step > 1) {
- len = (len / slice.step) + (len % slice.step ? 1 : 0);
- }
- mp_obj_tuple_t* t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
- for (uint i = 0; i < len; i++) {
+ mp_obj_tuple_t* t = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice_len, NULL));
+ for (uint i = 0; i < slice_len; i++) {
t->items[i] = common_hal__pixelbuf_pixelbuf_get_pixel(self_in, i * slice.step + slice.start);
}
return MP_OBJ_FROM_PTR(t);
@@ -321,10 +322,6 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
mp_raise_ValueError(translate("tuple/list required on RHS"));
}
- size_t dst_len = (slice.stop - slice.start);
- if (slice.step > 1) {
- dst_len = (dst_len / slice.step) + (dst_len % slice.step ? 1 : 0);
- }
mp_obj_t *src_objs;
size_t num_items;
if (MP_OBJ_IS_TYPE(value, &mp_type_list)) {
@@ -336,12 +333,12 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
num_items = l->len;
src_objs = l->items;
}
- if (num_items != dst_len) {
+ if (num_items != slice_len) {
mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."),
- dst_len, num_items);
+ slice_len, num_items);
}
- common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.stop, slice.step, src_objs);
+ common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.step, slice_len, src_objs);
return mp_const_none;
#else
return MP_OBJ_NULL; // op not supported