Skip to content

Commit 37a7cf9

Browse files
authored
Merge pull request #2941 from dunkmann00/pixelbuf-negative-step-slice
Implement negative step for pixelbuf slices
2 parents c09f0c8 + c592a2b commit 37a7cf9

File tree

3 files changed

+19
-21
lines changed

3 files changed

+19
-21
lines changed

shared-bindings/_pixelbuf/PixelBuf.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -300,17 +300,20 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
300300
size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in);
301301
mp_seq_get_fast_slice_indexes(length, index_in, &slice);
302302

303-
if (slice.step < 0) {
304-
mp_raise_IndexError(translate("Negative step not supported"));
303+
size_t slice_len;
304+
if (slice.step > 0) {
305+
slice_len = slice.stop - slice.start;
306+
} else {
307+
slice_len = 1 + slice.start - slice.stop;
308+
}
309+
if (slice.step > 1 || slice.step < -1) {
310+
size_t step = slice.step > 0 ? slice.step : slice.step * -1;
311+
slice_len = (slice_len / step) + (slice_len % step ? 1 : 0);
305312
}
306313

307314
if (value == MP_OBJ_SENTINEL) { // Get
308-
size_t len = slice.stop - slice.start;
309-
if (slice.step > 1) {
310-
len = (len / slice.step) + (len % slice.step ? 1 : 0);
311-
}
312-
mp_obj_tuple_t* t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
313-
for (uint i = 0; i < len; i++) {
315+
mp_obj_tuple_t* t = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice_len, NULL));
316+
for (uint i = 0; i < slice_len; i++) {
314317
t->items[i] = common_hal__pixelbuf_pixelbuf_get_pixel(self_in, i * slice.step + slice.start);
315318
}
316319
return MP_OBJ_FROM_PTR(t);
@@ -321,10 +324,6 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
321324
mp_raise_ValueError(translate("tuple/list required on RHS"));
322325
}
323326

324-
size_t dst_len = (slice.stop - slice.start);
325-
if (slice.step > 1) {
326-
dst_len = (dst_len / slice.step) + (dst_len % slice.step ? 1 : 0);
327-
}
328327
mp_obj_t *src_objs;
329328
size_t num_items;
330329
if (MP_OBJ_IS_TYPE(value, &mp_type_list)) {
@@ -336,12 +335,12 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
336335
num_items = l->len;
337336
src_objs = l->items;
338337
}
339-
if (num_items != dst_len) {
338+
if (num_items != slice_len) {
340339
mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."),
341-
dst_len, num_items);
340+
slice_len, num_items);
342341
}
343342

344-
common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.stop, slice.step, src_objs);
343+
common_hal__pixelbuf_pixelbuf_set_pixels(self_in, slice.start, slice.step, slice_len, src_objs);
345344
return mp_const_none;
346345
#else
347346
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, size_t stop, size_t step, 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);
5151

5252
#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H

shared-module/_pixelbuf/PixelBuf.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,11 @@ void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t* self, size_t index, mp_obj_t v
216216
_pixelbuf_set_pixel_color(self, index, r, g, b, w);
217217
}
218218

219-
void common_hal__pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, size_t stop, size_t step, mp_obj_t* values) {
219+
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) {
220220
pixelbuf_pixelbuf_obj_t* self = native_pixelbuf(self_in);
221-
size_t source_i = 0;
222-
for (size_t target_i = start; target_i < stop; target_i += step) {
223-
_pixelbuf_set_pixel(self, target_i, values[source_i]);
224-
source_i++;
221+
for (size_t i = 0; i < slice_len; i++) {
222+
_pixelbuf_set_pixel(self, start, values[i]);
223+
start+=step;
225224
}
226225
if (self->auto_write) {
227226
common_hal__pixelbuf_pixelbuf_show(self_in);

0 commit comments

Comments
 (0)