8000 Merge pull request #7191 from jepler/fastpixelmap · adafruit/circuitpython@082b0d1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 082b0d1

Browse files
authored
Merge pull request #7191 from jepler/fastpixelmap
Add a fast PixelMap-like class
2 parents 9c6c25a + ae8fb27 commit 082b0d1

File tree

18 files changed

+698
-52
lines changed

18 files changed

+698
-52
lines changed

locale/circuitpython.pot

Lines changed: 9 additions & 0 deletions
< 9E88 tr class="diff-line-row">
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,7 @@ msgid "Unkown error code %d"
22552255
msgstr ""
22562256

22572257
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
2258+
#: shared-module/adafruit_pixelbuf/PixelMap.c
22582259
#, c-format
22592260
msgid "Unmatched number of items on RHS (expected %d, got %d)."
22602261
msgstr ""
@@ -3123,6 +3124,10 @@ msgstr ""
31233124
msgid "index is out of bounds"
31243125
msgstr ""
31253126

3127+
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
3128+
msgid "index must be tuple or int"
3129+
msgstr ""
3130+
31263131
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c
31273132
#: ports/espressif/common-hal/pulseio/PulseIn.c
31283133
#: shared-bindings/bitmaptools/__init__.c
@@ -3498,6 +3503,10 @@ msgstr ""
34983503
msgid "negative shift count"
34993504
msgstr ""
35003505

3506+
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
3507+
msgid "nested index must be int"
3508+
msgstr ""
3509+
35013510
#: shared-module/sdcardio/SDCard.c
35023511
msgid "no SD card"
35033512
msgstr ""

ports/atmel-samd/mpconfigport.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ CIRCUITPY_I2CTARGET ?= 0
4242
CIRCUITPY_JSON ?= 0
4343
CIRCUITPY_KEYPAD ?= 0
4444
CIRCUITPY_MSGPACK ?= 0
45+
CIRCUITPY_PIXELMAP ?= 0
4546
CIRCUITPY_RE ?= 0
4647
CIRCUITPY_SDCARDIO ?= 0
4748
CIRCUITPY_SYNTHIO ?= 0

ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ QSPI_FLASH_FILESYSTEM = 1
99
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
1010

1111
CIRCUITPY_DISPLAYIO = 1
12+
CIRCUITPY_PIXELMAP = 0
1213

1314
CIRCUITPY_REQUIRE_I2C_PULLUPS = 0

ports/nrf/boards/bluemicro833/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ CIRCUITPY_KEYPAD = 1
1313
CIRCUITPY_NVM = 0
1414
CIRCUITPY_ONEWIREIO = 0
1515
CIRCUITPY_PIXELBUF = 1
16+
CIRCUITPY_PIXELMAP = 0
1617
CIRCUITPY_TOUCHIO = 0

py/circuitpy_defns.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ endif
266266
ifeq ($(CIRCUITPY_PIXELBUF),1)
267267
SRC_PATTERNS += adafruit_pixelbuf/%
268268
endif
269+
ifeq ($(CIRCUITPY_PIXELMAP),1)
270+
SRC_PATTERNS += _pixelmap/%
271+
endif
269272
ifeq ($(CIRCUITPY_QRIO),1)
270273
SRC_PATTERNS += qrio/%
271274
endif
@@ -543,6 +546,8 @@ SRC_SHARED_MODULE_ALL = \
543546
_eve/__init__.c \
544547
adafruit_pixelbuf/PixelBuf.c \
545548
adafruit_pixelbuf/__init__.c \
549+
_pixelmap/PixelMap.c \
550+
_pixelmap/__init__.c \
546551
_stage/Layer.c \
547552
_stage/Text.c \
548553
_stage/__init__.c \

py/circuitpy_mpconfig.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
319319
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
320320
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
321321

322+
CIRCUITPY_PIXELMAP ?= $(CIRCUITPY_PIXELBUF)
323+
CFLAGS += -DCIRCUITPY_PIXELMAP=$(CIRCUITPY_PIXELMAP)
324+
322325
# Only for SAMD boards for the moment
323326
CIRCUITPY_PS2IO ?= 0
324327
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)

shared-bindings/_pixelmap/PixelMap.c

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/*
2+
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Rose Hooper
7+
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "py/objproperty.h"
29+
#include "py/objtype.h"
30+
#include "py/runtime.h"
31+
32+
#include "shared-bindings/_pixelmap/PixelMap.h"
33+
#include "shared-bindings/adafruit_pixelbuf/PixelBuf.h"
34+
#include "shared-module/_pixelmap/PixelMap.h"
35+
36+
//| from adafruit_pixelbuf import PixelBuf, PixelReturnType, PixelSequence, PixelType
37+
//|
38+
//| class PixelMap:
39+
//| def __init__(self, pixelbuf: PixelBuf, indices: Tuple[Union[int, Tuple[int]]]) -> None:
40+
//| """Construct a PixelMap object that uses the given indices of the underlying pixelbuf"""
41+
42+
STATIC mp_obj_t pixelmap_pixelmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
43+
enum { ARG_pixelbuf, ARG_indices };
44+
static const mp_arg_t allowed_args[] = {
45+
{ MP_QSTR_pixelbuf, MP_ARG_REQUIRED },
46+
{ MP_QSTR_indices, MP_ARG_REQUIRED },
47+
};
48+
49+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
50+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
51+
52+
mp_obj_t pixelbuf = args[ARG_pixelbuf].u_obj;
53+
54+
mp_obj_t native_pixelbuf = mp_obj_cast_to_native_base(pixelbuf, &pixelbuf_pixelbuf_type);
55+
if (!native_pixelbuf) {
56+
(void)mp_arg_validate_type(args[ARG_pixelbuf].u_obj, &pixelbuf_pixelbuf_type, MP_QSTR_pixelbuf);
57+
}
58+
mp_obj_assert_native_inited(native_pixelbuf);
59+
60+
size_t buflen = common_hal_adafruit_pixelbuf_pixelbuf_get_len(pixelbuf);
61+
62+
mp_obj_t indices = mp_arg_validate_type(args[ARG_indices].u_obj, &mp_type_tuple, MP_QSTR_indices);
63+
64+
// validate indices
65+
size_t len;
66+
mp_obj_t *items;
67+
mp_obj_tuple_get(indices, &len, &items);
68+
mp_arg_validate_length_min(len, 1, MP_QSTR_items);
69+
70+
for (size_t i = 0; i < len; i++) {
71+
mp_obj_t item = items[i];
72+
if (mp_obj_is_small_int(item)) {
73+
mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item), 0, buflen - 1, MP_QSTR_index);
74+
} else if (mp_obj_is_tuple_compatible(item)) {
75+
size_t len1;
76+
mp_obj_t *items1;
77+
mp_obj_tuple_get(item, &len1, &items1);
78+
for (size_t j = 0; j < len1; j++) {
79+
mp_obj_t item1 = items1[j];
80+
if (!mp_obj_is_small_int(item1)) {
81+
mp_raise_TypeError(translate("nested index must be int"));
82+
}
83+
mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item1), 0, buflen - 1, MP_QSTR_index);
84+
}
85+
} else {
86+
mp_raise_TypeError(translate("index must be tuple or int"));
87+
}
88+
}
89+
90+
pixelmap_pixelmap_obj_t *self = m_new_obj(pixelmap_pixelmap_obj_t);
91+
self->base.type = &pixelmap_pixelmap_type;
92+
shared_module_pixelmap_pixelmap_construct(self, pixelbuf, indices);
93+
94+
return MP_OBJ_FROM_PTR(self);
95+
}
96+
97+
//| auto_write: bool
98+
//| """True if updates should be automatically written"""
99+
STATIC mp_obj_t pixelmap_pixelmap_auto_write_get(const mp_obj_t self_in) {
100+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
101+
return mp_obj_new_bool(shared_module_pixelmap_pixelmap_auto_write_get(self));
102+
}
103+
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_auto_write_get_obj, pixelmap_pixelmap_auto_write_get);
104+
105+
STATIC mp_obj_t pixelmap_pixelmap_auto_write_set(const mp_obj_t self_in, const mp_obj_t arg) {
106+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
107+
shared_module_pixelmap_pixelmap_auto_write_set(self, mp_obj_is_true(arg));
108+
return mp_const_none;
109+
}
110+
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_auto_write_set_obj, pixelmap_pixelmap_auto_write_set);
111+
112+
MP_PROPERTY_GETSET(pixelmap_pixelmap_auto_write_obj,
113+
(mp_obj_t)&pixelmap_pixelmap_auto_write_get_obj,
114+
(mp_obj_t)&pixelmap_pixelmap_auto_write_set_obj);
115+
116+
//| bpp: int
117+
//| """The number of bytes per pixel in the buffer (read-only)"""
118+
STATIC mp_obj_t pixelmap_pixelmap_obj_get_bpp(mp_obj_t self_in) {
119+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
120+
return MP_OBJ_NEW_SMALL_INT(common_hal_adafruit_pixelbuf_pixelbuf_get_bpp(self->pixelbuf));
121+
}
122+
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_bpp_obj, pixelmap_pixelmap_obj_get_bpp);
123+
124+
MP_PROPERTY_GETTER(pixelmap_pixelmap_bpp_obj,
125+
(mp_obj_t)&pixelmap_pixelmap_get_bpp_obj);
126+
127+
//| byteorder: str
128+
//| """byteorder string for the buffer (read-only)"""
129+
STATIC mp_obj_t pixelmap_pixelmap_obj_get_byteorder(mp_obj_t self_in) {
130+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
131+
return common_hal_adafruit_pixelbuf_pixelbuf_get_byteorder_string(self->pixelbuf);
132+
}
133+
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_byteorder, pixelmap_pixelmap_obj_get_byteorder);
134+
MP_PROPERTY_GETTER(pixelmap_pixelmap_byteorder_obj,
135+
(mp_obj_t)&pixelmap_pixelmap_get_byteorder);
136+
137+
//|
138+
//| def fill(self, color: PixelType) -> None:
139+
//| """Fill all the pixels in the map with the given color"""
140+
STATIC mp_obj_t pixelmap_pixelmap_fill(const mp_obj_t self_in, const mp_obj_t color) {
141+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
142+
143+
shared_module_pixelmap_pixelmap_fill(self, color);
144+
return mp_const_none;
145+
}
146+
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_fill_obj, pixelmap_pixelmap_fill);
147+
148+
//|
149+
//| def indices(self, index: int) -> Tuple[int]:
150+
//| """Return the PixelBuf indices for a PixelMap index"""
151+
STATIC mp_obj_t pixelmap_pixelmap_indices(const mp_obj_t self_in, const mp_obj_t index) {
152+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
153+
154+
return shared_module_pixelmap_pixelmap_indices(self, mp_obj_get_int(index));
155+
return mp_const_none;
156+
}
157+
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_indices_obj, pixelmap_pixelmap_indices);
158+
159+
160+
//| @overload
161+
//| def __getitem__(self, index: slice) -> PixelReturnSequence:
162+
//| """Retrieve the value of the underlying pixels."""
163+
//| ...
164+
//| @overload
165+
//| def __getitem__(self, index: int) -> PixelReturnType:
166+
//| """Retrieve the value of one of the underlying pixels at 'index'."""
167+
//| ...
168+
//| @overload
169+
//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ...
170+
//| @overload
171+
//| def __setitem__(self, index: int, value: PixelType) -> None:
172+
//| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are
173+
//| The individual (Red, Green, Blue[, White]) values between 0 and 255. If given an integer, the
174+
//| red, green and blue values are packed into the lower three bytes (0xRRGGBB).
175+
//| For RGBW byteorders, if given only RGB values either as an int or as a tuple, the white value
176+
//| is used instead when the red, green, and blue values are the same."""
177+
//| ...
178+
STATIC mp_obj_t pixelmap_pixelmap_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
179+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
180+
if (value == MP_OBJ_NULL) {
181+
// delete
182+
return MP_OBJ_NULL; // op not supported
183+
}
184+
185+
if (0) {
186+
#if MICROPY_PY_BUILTINS_SLICE
187+
} else if (mp_obj_is_type(index_in, &mp_type_slice)) {
188+
mp_bound_slice_t slice;
189+
mp_seq_get_fast_slice_indexes(self->len, index_in, &slice);
190+
size_t slice_len;
191+
if (slice.step > 0) {
192+
slice_len = slice.stop - slice.start;
193+
} else {
194+
slice_len = 1 + slice.start - slice.stop;
195+
}
196+
if (slice.step > 1 || slice.step < -1) {
197+
size_t step = slice.step > 0 ? slice.step : slice.step * -1;
198+
slice_len = (slice_len / step) + (slice_len % step ? 1 : 0);
199+
}
200+
201+
if (value == MP_OBJ_SENTINEL) { // Get
202+
return shared_module_pixelmap_pixelmap_getslice(self, slice, slice_len);
203+
} else { // Set
204+
shared_module_pixelmap_pixelmap_setslice(self, value, slice, slice_len);
205+
return mp_const_none;
206+
}
207+
#endif
208+
} else { // single index
209+
int index = mp_obj_get_int(index_in);
210+
211+
if (value == MP_OBJ_SENTINEL) { // Get
212+
return shared_module_pixelmap_pixelmap_getitem(self, index);
213+
} else {
214+
shared_module_pixelmap_pixelmap_setitem(self, mp_obj_get_int(index_in), value);
215+
return mp_const_none;
216+
}
217+
}
218+
}
219+
220+
//| def __len__(self) -> int:
221+
//| """Length of the map"""
222+
STATIC mp_obj_t pixelmap_pixelmap_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
223+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
224+
switch (op) {
225+
case MP_UNARY_OP_BOOL:
226+
return mp_const_true;
227+
case MP_UNARY_OP_LEN:
228+
return MP_OBJ_NEW_SMALL_INT(self->len);
229+
default:
230+
return MP_OBJ_NULL; // op not supported
231+
}
232+
}
233+
234+
//| def show(self) -> None:
235+
//| """Transmits the color data to the pixels so that they are shown. This is done automatically
236+
//| when `auto_write` is True."""
237+
//| ...
238+
//|
239+
240+
STATIC mp_obj_t pixelmap_pixelmap_show(mp_obj_t self_in) {
241+
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
242+
common_hal_adafruit_pixelbuf_pixelbuf_show(self->pixelbuf);
243+
return mp_const_none;
244+
}
245+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_show_obj, pixelmap_pixelmap_show);
246+
247+
STATIC const mp_rom_map_elem_t pixelmap_pixelmap_locals_dict_table[] = {
248+
{ MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelmap_pixelmap_auto_write_obj) },
249+
{ MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelmap_pixelmap_bpp_obj) },
250+
{ MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelmap_pixelmap_byteorder_obj) },
251+
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&pixelmap_pixelmap_fill_obj) },
252+
{ MP_ROM_QSTR(MP_QSTR_indices), MP_ROM_PTR(&pixelmap_pixelmap_indices_obj) },
253+
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelmap_pixelmap_show_obj) },
254+
};
255+
256+
STATIC MP_DEFINE_CONST_DICT(pixelmap_pixelmap_locals_dict, pixelmap_pixelmap_locals_dict_table);
257+
258+
259+
const mp_obj_type_t pixelmap_pixelmap_type = {
260+
{ &mp_type_type },
261+
.name = MP_QSTR_PixelMap,
262+
.flags = MP_TYPE_FLAG_EXTENDED,
263+
.locals_dict = (mp_obj_t)&pixelmap_pixelmap_locals_dict,
264+
.make_new = pixelmap_pixelmap_make_new,
265+
MP_TYPE_EXTENDED_FIELDS(
266+
.subscr = pixelmap_pixelmap_subscr,
267+
.unary_op = pixelmap_pixelmap_unary_op,
268+
),
269+
};

shared-bindings/_pixelmap/PixelMap.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Rose Hooper
7+
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#pragma once
29+
#include "py/obj.h"
30+
31+
extern const mp_obj_type_t pixelmap_pixelmap_type;
32+
33+
typedef struct _pixelmap_pixelmap_obj pixelmap_pixelmap_obj_t;
34+
35+
void shared_module_pixelmap_pixelmap_construct(pixelmap_pixelmap_obj_t *self, mp_obj_t pixelbuf, mp_obj_t indices);
36+
bool shared_module_pixelmap_pixelmap_auto_write_get(pixelmap_pixelmap_obj_t *self);
37+
void shared_module_pixelmap_pixelmap_auto_write_set(pixelmap_pixelmap_obj_t *self, bool auto_write);
38+
void shared_module_pixelmap_pixelmap_fill(pixelmap_pixelmap_obj_t *self, const mp_obj_t color);
39+
mp_obj_t shared_module_pixelmap_pixelmap_indices(pixelmap_pixelmap_obj_t *self, int index);
40+
void shared_module_pixelmap_pixelmap_setslice(pixelmap_pixelmap_obj_t *self, const mp_obj_t value, mp_bound_slice_t slice, size_t slice_len);
41+
mp_obj_t shared_module_pixelmap_pixelmap_getslice(pixelmap_pixelmap_obj_t *self, mp_bound_slice_t slice, size_t slice_len);
42+
mp_obj_t shared_module_pixelmap_pixelmap_getitem(pixelmap_pixelmap_obj_t *self, mp_int_t index);
43+
void shared_module_pixelmap_pixelmap_setitem(pixelmap_pixelmap_obj_t *self, mp_int_t index, const mp_obj_t value);

0 commit comments

Comments
 (0)
0