Merge pull request #7191 from jepler/fastpixelmap
Add a fast PixelMap-like class
This commit is contained in:
commit
082b0d1aed
@ -2255,6 +2255,7 @@ msgid "Unkown error code %d"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
||||||
|
#: shared-module/adafruit_pixelbuf/PixelMap.c
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unmatched number of items on RHS (expected %d, got %d)."
|
msgid "Unmatched number of items on RHS (expected %d, got %d)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -3123,6 +3124,10 @@ msgstr ""
|
|||||||
msgid "index is out of bounds"
|
msgid "index is out of bounds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
|
||||||
|
msgid "index must be tuple or int"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c
|
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c
|
||||||
#: ports/espressif/common-hal/pulseio/PulseIn.c
|
#: ports/espressif/common-hal/pulseio/PulseIn.c
|
||||||
#: shared-bindings/bitmaptools/__init__.c
|
#: shared-bindings/bitmaptools/__init__.c
|
||||||
@ -3498,6 +3503,10 @@ msgstr ""
|
|||||||
msgid "negative shift count"
|
msgid "negative shift count"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
|
||||||
|
msgid "nested index must be int"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: shared-module/sdcardio/SDCard.c
|
#: shared-module/sdcardio/SDCard.c
|
||||||
msgid "no SD card"
|
msgid "no SD card"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -42,6 +42,7 @@ CIRCUITPY_I2CTARGET ?= 0
|
|||||||
CIRCUITPY_JSON ?= 0
|
CIRCUITPY_JSON ?= 0
|
||||||
CIRCUITPY_KEYPAD ?= 0
|
CIRCUITPY_KEYPAD ?= 0
|
||||||
CIRCUITPY_MSGPACK ?= 0
|
CIRCUITPY_MSGPACK ?= 0
|
||||||
|
CIRCUITPY_PIXELMAP ?= 0
|
||||||
CIRCUITPY_RE ?= 0
|
CIRCUITPY_RE ?= 0
|
||||||
CIRCUITPY_SDCARDIO ?= 0
|
CIRCUITPY_SDCARDIO ?= 0
|
||||||
CIRCUITPY_SYNTHIO ?= 0
|
CIRCUITPY_SYNTHIO ?= 0
|
||||||
|
@ -9,5 +9,6 @@ QSPI_FLASH_FILESYSTEM = 1
|
|||||||
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
|
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
|
||||||
|
|
||||||
CIRCUITPY_DISPLAYIO = 1
|
CIRCUITPY_DISPLAYIO = 1
|
||||||
|
CIRCUITPY_PIXELMAP = 0
|
||||||
|
|
||||||
CIRCUITPY_REQUIRE_I2C_PULLUPS = 0
|
CIRCUITPY_REQUIRE_I2C_PULLUPS = 0
|
||||||
|
@ -13,4 +13,5 @@ CIRCUITPY_KEYPAD = 1
|
|||||||
CIRCUITPY_NVM = 0
|
CIRCUITPY_NVM = 0
|
||||||
CIRCUITPY_ONEWIREIO = 0
|
CIRCUITPY_ONEWIREIO = 0
|
||||||
CIRCUITPY_PIXELBUF = 1
|
CIRCUITPY_PIXELBUF = 1
|
||||||
|
CIRCUITPY_PIXELMAP = 0
|
||||||
CIRCUITPY_TOUCHIO = 0
|
CIRCUITPY_TOUCHIO = 0
|
||||||
|
@ -266,6 +266,9 @@ endif
|
|||||||
ifeq ($(CIRCUITPY_PIXELBUF),1)
|
ifeq ($(CIRCUITPY_PIXELBUF),1)
|
||||||
SRC_PATTERNS += adafruit_pixelbuf/%
|
SRC_PATTERNS += adafruit_pixelbuf/%
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CIRCUITPY_PIXELMAP),1)
|
||||||
|
SRC_PATTERNS += _pixelmap/%
|
||||||
|
endif
|
||||||
ifeq ($(CIRCUITPY_QRIO),1)
|
ifeq ($(CIRCUITPY_QRIO),1)
|
||||||
SRC_PATTERNS += qrio/%
|
SRC_PATTERNS += qrio/%
|
||||||
endif
|
endif
|
||||||
@ -543,6 +546,8 @@ SRC_SHARED_MODULE_ALL = \
|
|||||||
_eve/__init__.c \
|
_eve/__init__.c \
|
||||||
adafruit_pixelbuf/PixelBuf.c \
|
adafruit_pixelbuf/PixelBuf.c \
|
||||||
adafruit_pixelbuf/__init__.c \
|
adafruit_pixelbuf/__init__.c \
|
||||||
|
_pixelmap/PixelMap.c \
|
||||||
|
_pixelmap/__init__.c \
|
||||||
_stage/Layer.c \
|
_stage/Layer.c \
|
||||||
_stage/Text.c \
|
_stage/Text.c \
|
||||||
_stage/__init__.c \
|
_stage/__init__.c \
|
||||||
|
@ -319,6 +319,9 @@ CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
|
|||||||
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
|
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
|
||||||
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
|
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
|
||||||
|
|
||||||
|
CIRCUITPY_PIXELMAP ?= $(CIRCUITPY_PIXELBUF)
|
||||||
|
CFLAGS += -DCIRCUITPY_PIXELMAP=$(CIRCUITPY_PIXELMAP)
|
||||||
|
|
||||||
# Only for SAMD boards for the moment
|
# Only for SAMD boards for the moment
|
||||||
CIRCUITPY_PS2IO ?= 0
|
CIRCUITPY_PS2IO ?= 0
|
||||||
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
|
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
|
||||||
|
269
shared-bindings/_pixelmap/PixelMap.c
Normal file
269
shared-bindings/_pixelmap/PixelMap.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/objtype.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/_pixelmap/PixelMap.h"
|
||||||
|
#include "shared-bindings/adafruit_pixelbuf/PixelBuf.h"
|
||||||
|
#include "shared-module/_pixelmap/PixelMap.h"
|
||||||
|
|
||||||
|
//| from adafruit_pixelbuf import PixelBuf, PixelReturnType, PixelSequence, PixelType
|
||||||
|
//|
|
||||||
|
//| class PixelMap:
|
||||||
|
//| def __init__(self, pixelbuf: PixelBuf, indices: Tuple[Union[int, Tuple[int]]]) -> None:
|
||||||
|
//| """Construct a PixelMap object that uses the given indices of the underlying pixelbuf"""
|
||||||
|
|
||||||
|
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) {
|
||||||
|
enum { ARG_pixelbuf, ARG_indices };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_pixelbuf, MP_ARG_REQUIRED },
|
||||||
|
{ MP_QSTR_indices, MP_ARG_REQUIRED },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_obj_t pixelbuf = args[ARG_pixelbuf].u_obj;
|
||||||
|
|
||||||
|
mp_obj_t native_pixelbuf = mp_obj_cast_to_native_base(pixelbuf, &pixelbuf_pixelbuf_type);
|
||||||
|
if (!native_pixelbuf) {
|
||||||
|
(void)mp_arg_validate_type(args[ARG_pixelbuf].u_obj, &pixelbuf_pixelbuf_type, MP_QSTR_pixelbuf);
|
||||||
|
}
|
||||||
|
mp_obj_assert_native_inited(native_pixelbuf);
|
||||||
|
|
||||||
|
size_t buflen = common_hal_adafruit_pixelbuf_pixelbuf_get_len(pixelbuf);
|
||||||
|
|
||||||
|
mp_obj_t indices = mp_arg_validate_type(args[ARG_indices].u_obj, &mp_type_tuple, MP_QSTR_indices);
|
||||||
|
|
||||||
|
// validate indices
|
||||||
|
size_t len;
|
||||||
|
mp_obj_t *items;
|
||||||
|
mp_obj_tuple_get(indices, &len, &items);
|
||||||
|
mp_arg_validate_length_min(len, 1, MP_QSTR_items);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
mp_obj_t item = items[i];
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item), 0, buflen - 1, MP_QSTR_index);
|
||||||
|
} else if (mp_obj_is_tuple_compatible(item)) {
|
||||||
|
size_t len1;
|
||||||
|
mp_obj_t *items1;
|
||||||
|
mp_obj_tuple_get(item, &len1, &items1);
|
||||||
|
for (size_t j = 0; j < len1; j++) {
|
||||||
|
mp_obj_t item1 = items1[j];
|
||||||
|
if (!mp_obj_is_small_int(item1)) {
|
||||||
|
mp_raise_TypeError(translate("nested index must be int"));
|
||||||
|
}
|
||||||
|
mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item1), 0, buflen - 1, MP_QSTR_index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mp_raise_TypeError(translate("index must be tuple or int"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixelmap_pixelmap_obj_t *self = m_new_obj(pixelmap_pixelmap_obj_t);
|
||||||
|
self->base.type = &pixelmap_pixelmap_type;
|
||||||
|
shared_module_pixelmap_pixelmap_construct(self, pixelbuf, indices);
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
//| auto_write: bool
|
||||||
|
//| """True if updates should be automatically written"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_auto_write_get(const mp_obj_t self_in) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return mp_obj_new_bool(shared_module_pixelmap_pixelmap_auto_write_get(self));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_auto_write_get_obj, pixelmap_pixelmap_auto_write_get);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_auto_write_set(const mp_obj_t self_in, const mp_obj_t arg) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
shared_module_pixelmap_pixelmap_auto_write_set(self, mp_obj_is_true(arg));
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_auto_write_set_obj, pixelmap_pixelmap_auto_write_set);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETSET(pixelmap_pixelmap_auto_write_obj,
|
||||||
|
(mp_obj_t)&pixelmap_pixelmap_auto_write_get_obj,
|
||||||
|
(mp_obj_t)&pixelmap_pixelmap_auto_write_set_obj);
|
||||||
|
|
||||||
|
//| bpp: int
|
||||||
|
//| """The number of bytes per pixel in the buffer (read-only)"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_obj_get_bpp(mp_obj_t self_in) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(common_hal_adafruit_pixelbuf_pixelbuf_get_bpp(self->pixelbuf));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_bpp_obj, pixelmap_pixelmap_obj_get_bpp);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETTER(pixelmap_pixelmap_bpp_obj,
|
||||||
|
(mp_obj_t)&pixelmap_pixelmap_get_bpp_obj);
|
||||||
|
|
||||||
|
//| byteorder: str
|
||||||
|
//| """byteorder string for the buffer (read-only)"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_obj_get_byteorder(mp_obj_t self_in) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return common_hal_adafruit_pixelbuf_pixelbuf_get_byteorder_string(self->pixelbuf);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_byteorder, pixelmap_pixelmap_obj_get_byteorder);
|
||||||
|
MP_PROPERTY_GETTER(pixelmap_pixelmap_byteorder_obj,
|
||||||
|
(mp_obj_t)&pixelmap_pixelmap_get_byteorder);
|
||||||
|
|
||||||
|
//|
|
||||||
|
//| def fill(self, color: PixelType) -> None:
|
||||||
|
//| """Fill all the pixels in the map with the given color"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_fill(const mp_obj_t self_in, const mp_obj_t color) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
shared_module_pixelmap_pixelmap_fill(self, color);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_fill_obj, pixelmap_pixelmap_fill);
|
||||||
|
|
||||||
|
//|
|
||||||
|
//| def indices(self, index: int) -> Tuple[int]:
|
||||||
|
//| """Return the PixelBuf indices for a PixelMap index"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_indices(const mp_obj_t self_in, const mp_obj_t index) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
return shared_module_pixelmap_pixelmap_indices(self, mp_obj_get_int(index));
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_indices_obj, pixelmap_pixelmap_indices);
|
||||||
|
|
||||||
|
|
||||||
|
//| @overload
|
||||||
|
//| def __getitem__(self, index: slice) -> PixelReturnSequence:
|
||||||
|
//| """Retrieve the value of the underlying pixels."""
|
||||||
|
//| ...
|
||||||
|
//| @overload
|
||||||
|
//| def __getitem__(self, index: int) -> PixelReturnType:
|
||||||
|
//| """Retrieve the value of one of the underlying pixels at 'index'."""
|
||||||
|
//| ...
|
||||||
|
//| @overload
|
||||||
|
//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ...
|
||||||
|
//| @overload
|
||||||
|
//| def __setitem__(self, index: int, value: PixelType) -> None:
|
||||||
|
//| """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 pixelmap_pixelmap_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
if (value == MP_OBJ_NULL) {
|
||||||
|
// delete
|
||||||
|
return MP_OBJ_NULL; // op not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
|
} else if (mp_obj_is_type(index_in, &mp_type_slice)) {
|
||||||
|
mp_bound_slice_t slice;
|
||||||
|
mp_seq_get_fast_slice_indexes(self->len, index_in, &slice);
|
||||||
|
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
|
||||||
|
return shared_module_pixelmap_pixelmap_getslice(self, slice, slice_len);
|
||||||
|
} else { // Set
|
||||||
|
shared_module_pixelmap_pixelmap_setslice(self, value, slice, slice_len);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else { // single index
|
||||||
|
int index = mp_obj_get_int(index_in);
|
||||||
|
|
||||||
|
if (value == MP_OBJ_SENTINEL) { // Get
|
||||||
|
return shared_module_pixelmap_pixelmap_getitem(self, index);
|
||||||
|
} else {
|
||||||
|
shared_module_pixelmap_pixelmap_setitem(self, mp_obj_get_int(index_in), value);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def __len__(self) -> int:
|
||||||
|
//| """Length of the map"""
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
switch (op) {
|
||||||
|
case MP_UNARY_OP_BOOL:
|
||||||
|
return mp_const_true;
|
||||||
|
case MP_UNARY_OP_LEN:
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(self->len);
|
||||||
|
default:
|
||||||
|
return MP_OBJ_NULL; // op not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def show(self) -> None:
|
||||||
|
//| """Transmits the color data to the pixels so that they are shown. This is done automatically
|
||||||
|
//| when `auto_write` is True."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
|
||||||
|
STATIC mp_obj_t pixelmap_pixelmap_show(mp_obj_t self_in) {
|
||||||
|
pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_show(self->pixelbuf);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_show_obj, pixelmap_pixelmap_show);
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t pixelmap_pixelmap_locals_dict_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelmap_pixelmap_auto_write_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelmap_pixelmap_bpp_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelmap_pixelmap_byteorder_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&pixelmap_pixelmap_fill_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_indices), MP_ROM_PTR(&pixelmap_pixelmap_indices_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelmap_pixelmap_show_obj) },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(pixelmap_pixelmap_locals_dict, pixelmap_pixelmap_locals_dict_table);
|
||||||
|
|
||||||
|
|
||||||
|
const mp_obj_type_t pixelmap_pixelmap_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_PixelMap,
|
||||||
|
.flags = MP_TYPE_FLAG_EXTENDED,
|
||||||
|
.locals_dict = (mp_obj_t)&pixelmap_pixelmap_locals_dict,
|
||||||
|
.make_new = pixelmap_pixelmap_make_new,
|
||||||
|
MP_TYPE_EXTENDED_FIELDS(
|
||||||
|
.subscr = pixelmap_pixelmap_subscr,
|
||||||
|
.unary_op = pixelmap_pixelmap_unary_op,
|
||||||
|
),
|
||||||
|
};
|
43
shared-bindings/_pixelmap/PixelMap.h
Normal file
43
shared-bindings/_pixelmap/PixelMap.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t pixelmap_pixelmap_type;
|
||||||
|
|
||||||
|
typedef struct _pixelmap_pixelmap_obj pixelmap_pixelmap_obj_t;
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_construct(pixelmap_pixelmap_obj_t *self, mp_obj_t pixelbuf, mp_obj_t indices);
|
||||||
|
bool shared_module_pixelmap_pixelmap_auto_write_get(pixelmap_pixelmap_obj_t *self);
|
||||||
|
void shared_module_pixelmap_pixelmap_auto_write_set(pixelmap_pixelmap_obj_t *self, bool auto_write);
|
||||||
|
void shared_module_pixelmap_pixelmap_fill(pixelmap_pixelmap_obj_t *self, const mp_obj_t color);
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_indices(pixelmap_pixelmap_obj_t *self, int index);
|
||||||
|
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);
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_getslice(pixelmap_pixelmap_obj_t *self, mp_bound_slice_t slice, size_t slice_len);
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_getitem(pixelmap_pixelmap_obj_t *self, mp_int_t index);
|
||||||
|
void shared_module_pixelmap_pixelmap_setitem(pixelmap_pixelmap_obj_t *self, mp_int_t index, const mp_obj_t value);
|
62
shared-bindings/_pixelmap/__init__.c
Normal file
62
shared-bindings/_pixelmap/__init__.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/_pixelmap/__init__.h"
|
||||||
|
#include "shared-bindings/_pixelmap/PixelMap.h"
|
||||||
|
|
||||||
|
|
||||||
|
//| """A fast pixel mapping library
|
||||||
|
//|
|
||||||
|
//| The `_pixelmap` module provides the :py:class:`PixelMap` class to accelerate
|
||||||
|
//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel."""
|
||||||
|
//|
|
||||||
|
//| # The types accepted when getting a pixel value
|
||||||
|
//| PixelReturnType = Union[
|
||||||
|
//| Tuple[int, int, int], Tuple[int, int, int, int], Tuple[int, int, int, float]
|
||||||
|
//| ]
|
||||||
|
//| PixelReturnSequence = Tuple[PixelReturnType]
|
||||||
|
//| # The types returned when getting a pixel value
|
||||||
|
//| PixelType = Union[int, PixelReturnType]
|
||||||
|
//| PixelSequence = Union[Tuple[PixelType], List[PixelType]]
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t pixelmap_module_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pixelmap) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_PixelMap), MP_ROM_PTR(&pixelmap_pixelmap_type) },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(pixelmap_module_globals, pixelmap_module_globals_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t pixelmap_module = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t *)&pixelmap_module_globals,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR__pixelmap, pixelmap_module, CIRCUITPY_PIXELMAP);
|
30
shared-bindings/_pixelmap/__init__.h
Normal file
30
shared-bindings/_pixelmap/__init__.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CP_SHARED_BINDINGS_PIXELBUF_INIT_H
|
||||||
|
#define CP_SHARED_BINDINGS_PIXELBUF_INIT_H
|
||||||
|
|
||||||
|
#endif // CP_SHARED_BINDINGS_PIXELBUF_INIT_H
|
@ -251,9 +251,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show);
|
||||||
|
|
||||||
//| def fill(
|
//| def fill(self, color: PixelType) -> None:
|
||||||
//| self, color: Union[int, Tuple[int, int, int], Tuple[int, int, int, float]]
|
|
||||||
//| ) -> None:
|
|
||||||
//| """Fills the given pixelbuf with the given color."""
|
//| """Fills the given pixelbuf with the given color."""
|
||||||
//| ...
|
//| ...
|
||||||
|
|
||||||
@ -265,29 +263,21 @@ STATIC mp_obj_t pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t value) {
|
|||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_fill);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_fill);
|
||||||
|
|
||||||
//| @overload
|
//| @overload
|
||||||
//| def __getitem__(
|
//| def __getitem__(self, index: slice) -> PixelReturnSequence:
|
||||||
//| self, index: slice
|
|
||||||
//| ) -> Union[Tuple[Tuple[int, int, int], ...], Tuple[Tuple[int, int, int, float], ...]]: ...
|
|
||||||
//| @overload
|
|
||||||
//| def __getitem__(
|
|
||||||
//| self, index: int
|
|
||||||
//| ) -> Union[Tuple[int, int, int], Tuple[int, int, int, float]]:
|
|
||||||
//| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values
|
//| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values
|
||||||
//| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel
|
//| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel
|
||||||
//| intensity from 0-1.0."""
|
//| intensity from 0-1.0."""
|
||||||
//| ...
|
//| ...
|
||||||
//| @overload
|
//| @overload
|
||||||
//| def __setitem__(
|
//| def __getitem__(self, index: int) -> PixelReturnType:
|
||||||
//| self, index: slice, value: Tuple[Union[int, Tuple[float, ...], List[float]], ...]
|
//| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values
|
||||||
//| ) -> None: ...
|
//| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel
|
||||||
|
//| intensity from 0-1.0."""
|
||||||
|
//| ...
|
||||||
//| @overload
|
//| @overload
|
||||||
//| def __setitem__(
|
//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ...
|
||||||
//| self, index: slice, value: List[Union[int, Tuple[float, ...], List[float]]]
|
|
||||||
//| ) -> None: ...
|
|
||||||
//| @overload
|
//| @overload
|
||||||
//| def __setitem__(
|
//| def __setitem__(self, index: int, value: PixelType) -> None:
|
||||||
//| self, index: int, value: Union[int, Tuple[float, ...], List[float]]
|
|
||||||
//| ) -> None:
|
|
||||||
//| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are
|
//| """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
|
//| 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).
|
//| red, green and blue values are packed into the lower three bytes (0xRRGGBB).
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#ifndef CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
#ifndef CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
||||||
#define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
#define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
||||||
|
|
||||||
|
#include "py/objtuple.h"
|
||||||
#include "shared-module/adafruit_pixelbuf/PixelBuf.h"
|
#include "shared-module/adafruit_pixelbuf/PixelBuf.h"
|
||||||
|
|
||||||
extern const mp_obj_type_t pixelbuf_pixelbuf_type;
|
extern const mp_obj_type_t pixelbuf_pixelbuf_type;
|
||||||
@ -55,5 +56,7 @@ void common_hal_adafruit_pixelbuf_pixelbuf_show(mp_obj_t self);
|
|||||||
mp_obj_t common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(mp_obj_t self, size_t index);
|
mp_obj_t common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(mp_obj_t self, size_t index);
|
||||||
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel(mp_obj_t self, size_t index, mp_obj_t item);
|
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel(mp_obj_t self, size_t index, mp_obj_t item);
|
||||||
void common_hal_adafruit_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);
|
void common_hal_adafruit_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);
|
||||||
|
void common_hal_adafruit_pixelbuf_pixelbuf_parse_color(mp_obj_t self, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w);
|
||||||
|
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(mp_obj_t self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
|
||||||
|
|
||||||
#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
#endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
||||||
|
@ -39,6 +39,15 @@
|
|||||||
//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel.
|
//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel.
|
||||||
//|
|
//|
|
||||||
//| Byteorders are configured with strings, such as "RGB" or "RGBD"."""
|
//| Byteorders are configured with strings, such as "RGB" or "RGBD"."""
|
||||||
|
//|
|
||||||
|
//| # The types accepted when getting a pixel value
|
||||||
|
//| PixelReturnType = Union[
|
||||||
|
//| Tuple[int, int, int], Tuple[int, int, int, int], Tuple[int, int, int, float]
|
||||||
|
//| ]
|
||||||
|
//| PixelReturnSequence = Tuple[PixelReturnType]
|
||||||
|
//| # The types returned when getting a pixel value
|
||||||
|
//| PixelType = Union[int, PixelReturnType]
|
||||||
|
//| PixelSequence = Union[Tuple[PixelType], List[PixelType]]
|
||||||
// TODO: Pull in docs from adafruit_pixelbuf.
|
// TODO: Pull in docs from adafruit_pixelbuf.
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = {
|
STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = {
|
||||||
|
174
shared-module/_pixelmap/PixelMap.c
Normal file
174
shared-module/_pixelmap/PixelMap.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/smallint.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/_pixelmap/PixelMap.h"
|
||||||
|
#include "shared-bindings/adafruit_pixelbuf/PixelBuf.h"
|
||||||
|
#include "shared-module/_pixelmap/PixelMap.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void pixelmap_set_pixel_rgbw(pixelmap_pixelmap_obj_t *self, size_t i, color_u rgbw) {
|
||||||
|
mp_arg_validate_index_range(i, 0, self->len - 1, MP_QSTR_index);
|
||||||
|
|
||||||
|
mp_obj_t item = self->items[i];
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(item), rgbw.r, rgbw.g, rgbw.b, rgbw.w);
|
||||||
|
} else {
|
||||||
|
size_t len;
|
||||||
|
mp_obj_t *items;
|
||||||
|
mp_obj_tuple_get(item, &len, &items);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < len; j++) {
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(items[j]), rgbw.r, rgbw.g, rgbw.b, rgbw.w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pixelmap_set_pixel(pixelmap_pixelmap_obj_t *self, size_t i, mp_obj_t color) {
|
||||||
|
color_u rgbw;
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w);
|
||||||
|
pixelmap_set_pixel_rgbw(self, i, rgbw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_construct(pixelmap_pixelmap_obj_t *self, mp_obj_t pixelbuf, mp_obj_t indices) {
|
||||||
|
self->pixelbuf = pixelbuf;
|
||||||
|
self->indices = indices;
|
||||||
|
mp_obj_tuple_get(indices, &self->len, &self->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool auto_write_get_and_clear(pixelmap_pixelmap_obj_t *self) {
|
||||||
|
bool auto_write = self->auto_write && common_hal_adafruit_pixelbuf_pixelbuf_get_auto_write(self->pixelbuf);
|
||||||
|
if (auto_write) {
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_set_auto_write(self->pixelbuf, false);
|
||||||
|
}
|
||||||
|
return auto_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void auto_write_reapply(pixelmap_pixelmap_obj_t *self, bool auto_write) {
|
||||||
|
if (auto_write) {
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_set_auto_write(self->pixelbuf, true);
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_show(self->pixelbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shared_module_pixelmap_pixelmap_auto_write_get(pixelmap_pixelmap_obj_t *self) {
|
||||||
|
return self->auto_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_auto_write_set(pixelmap_pixelmap_obj_t *self, bool auto_write) {
|
||||||
|
self->auto_write = auto_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_fill(pixelmap_pixelmap_obj_t *self, const mp_obj_t color) {
|
||||||
|
color_u rgbw;
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w);
|
||||||
|
bool auto_write = auto_write_get_and_clear(self);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < self->len; i++) {
|
||||||
|
pixelmap_set_pixel_rgbw(self, i, rgbw);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_write_reapply(self, auto_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_indices(pixelmap_pixelmap_obj_t *self, int index) {
|
||||||
|
mp_arg_validate_index_range(index, 0, self->len - 1, MP_QSTR_index);
|
||||||
|
|
||||||
|
mp_obj_t item = self->items[index];
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
return mp_obj_new_tuple(1, &item);
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
|
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_getslice(pixelmap_pixelmap_obj_t *self, mp_bound_slice_t slice, size_t slice_len) {
|
||||||
|
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] = shared_module_pixelmap_pixelmap_getitem(self, i * slice.step + slice.start);
|
||||||
|
}
|
||||||
|
return MP_OBJ_FROM_PTR(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_setslice(pixelmap_pixelmap_obj_t *self, const mp_obj_t values, mp_bound_slice_t slice, size_t slice_len) {
|
||||||
|
size_t num_items = mp_obj_get_int(mp_obj_len(values));
|
||||||
|
if (num_items != slice_len) {
|
||||||
|
mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."), slice_len, num_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool auto_write = auto_write_get_and_clear(self);
|
||||||
|
|
||||||
|
// because we didn't preflight the pixel values, an exception could occur.
|
||||||
|
// In that case we need to do the auto-write of any pixels that were set
|
||||||
|
// before re-raising the exception
|
||||||
|
nlr_buf_t nlr;
|
||||||
|
|
||||||
|
size_t start = slice.start;
|
||||||
|
mp_int_t step = slice.step;
|
||||||
|
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
mp_obj_iter_buf_t iter_buf;
|
||||||
|
mp_obj_t iterable = mp_getiter(values, &iter_buf);
|
||||||
|
mp_obj_t item;
|
||||||
|
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||||
|
pixelmap_set_pixel(self, start, item);
|
||||||
|
start += step;
|
||||||
|
}
|
||||||
|
nlr_pop();
|
||||||
|
auto_write_reapply(self, auto_write);
|
||||||
|
} else {
|
||||||
|
auto_write_reapply(self, auto_write);
|
||||||
|
// exception converting color value, re-raise
|
||||||
|
nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void shared_module_pixelmap_pixelmap_setitem(pixelmap_pixelmap_obj_t *self, mp_int_t i, mp_obj_t color) {
|
||||||
|
color_u rgbw;
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w);
|
||||||
|
bool auto_write = auto_write_get_and_clear(self);
|
||||||
|
pixelmap_set_pixel_rgbw(self, i, rgbw);
|
||||||
|
auto_write_reapply(self, auto_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t shared_module_pixelmap_pixelmap_getitem(pixelmap_pixelmap_obj_t *self, mp_int_t i) {
|
||||||
|
mp_arg_validate_index_range(i, 0, self->len - 1, MP_QSTR_index);
|
||||||
|
mp_obj_t item = self->items[i];
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
return common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(item));
|
||||||
|
} else {
|
||||||
|
size_t len;
|
||||||
|
mp_obj_t *items;
|
||||||
|
mp_obj_tuple_get(item, &len, &items);
|
||||||
|
return common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(items[0]));
|
||||||
|
}
|
||||||
|
}
|
39
shared-module/_pixelmap/PixelMap.h
Normal file
39
shared-module/_pixelmap/PixelMap.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Rose Hooper
|
||||||
|
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared-module/adafruit_pixelbuf/PixelBuf.h"
|
||||||
|
|
||||||
|
typedef struct _pixelmap_pixelmap_obj {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
mp_obj_t pixelbuf;
|
||||||
|
mp_obj_t indices;
|
||||||
|
size_t len;
|
||||||
|
mp_obj_t *items;
|
||||||
|
bool auto_write;
|
||||||
|
} pixelmap_pixelmap_obj_t;
|
0
shared-module/_pixelmap/__init__.c
Normal file
0
shared-module/_pixelmap/__init__.c
Normal file
@ -154,56 +154,55 @@ STATIC uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) {
|
|||||||
translate("can't convert %q to %q"), mp_obj_get_type_qstr(obj), MP_QSTR_int);
|
translate("can't convert %q to %q"), mp_obj_get_type_qstr(obj), MP_QSTR_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC color_u _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color) {
|
static 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) {
|
||||||
color_u result;
|
|
||||||
pixelbuf_byteorder_details_t *byteorder = &self->byteorder;
|
pixelbuf_byteorder_details_t *byteorder = &self->byteorder;
|
||||||
// w is shared between white in NeoPixels and brightness in dotstars (so that DotStars can have
|
// w is shared between white in NeoPixels and brightness in dotstars (so that DotStars can have
|
||||||
// per-pixel brightness). Set the defaults here in case it isn't set below.
|
// per-pixel brightness). Set the defaults here in case it isn't set below.
|
||||||
if (byteorder->is_dotstar) {
|
if (byteorder->is_dotstar) {
|
||||||
result.w = 255;
|
*w = 255;
|
||||||
} else {
|
} else {
|
||||||
result.w = 0;
|
*w = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_obj_is_int(color) || mp_obj_is_float(color)) {
|
if (mp_obj_is_int(color) || mp_obj_is_float(color)) {
|
||||||
mp_int_t value = mp_obj_is_int(color) ? mp_obj_get_int_truncated(color) : (mp_int_t)mp_obj_get_float(color);
|
mp_int_t value = mp_obj_is_int(color) ? mp_obj_get_int_truncated(color) : (mp_int_t)mp_obj_get_float(color);
|
||||||
result.r = value >> 16 & 0xff;
|
*r = value >> 16 & 0xff;
|
||||||
result.g = (value >> 8) & 0xff;
|
*g = (value >> 8) & 0xff;
|
||||||
result.b = value & 0xff;
|
*b = value & 0xff;
|
||||||
} else {
|
} else {
|
||||||
mp_obj_t *items;
|
mp_obj_t *items;
|
||||||
size_t len;
|
size_t len;
|
||||||
mp_obj_get_array(color, &len, &items);
|
mp_obj_get_array(color, &len, &items);
|
||||||
mp_arg_validate_length_range(len, 3, 4, MP_QSTR_color);
|
mp_arg_validate_length_range(len, 3, 4, MP_QSTR_color);
|
||||||
|
|
||||||
result.r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
|
*r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
|
||||||
result.g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
|
*g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
|
||||||
result.b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
|
*b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
|
||||||
if (len > 3) {
|
if (len > 3) {
|
||||||
if (mp_obj_is_float(items[PIXEL_W])) {
|
if (mp_obj_is_float(items[PIXEL_W])) {
|
||||||
result.w = 255 * mp_obj_get_float(items[PIXEL_W]);
|
*w = 255 * mp_obj_get_float(items[PIXEL_W]);
|
||||||
} else {
|
} else {
|
||||||
result.w = mp_obj_get_int_truncated(items[PIXEL_W]);
|
*w = mp_obj_get_int_truncated(items[PIXEL_W]);
|
||||||
}
|
}
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Int colors can't set white directly so convert to white when all components are equal.
|
// Int colors can't set white directly so convert to white when all components are equal.
|
||||||
// Also handles RGBW values assigned an RGB tuple.
|
// Also handles RGBW values assigned an RGB tuple.
|
||||||
if (!byteorder->is_dotstar && byteorder->bpp == 4 && byteorder->has_white && result.r == result.g && result.r == result.b) {
|
if (!byteorder->is_dotstar && byteorder->bpp == 4 && byteorder->has_white && *r == *g && *r == *b) {
|
||||||
result.w = result.r;
|
*w = *r;
|
||||||
result.r = 0;
|
*r = 0;
|
||||||
result.g = 0;
|
*g = 0;
|
||||||
result.b = 0;
|
*b = 0;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, color_u rgbw) {
|
void common_hal_adafruit_pixelbuf_pixelbuf_parse_color(mp_obj_t self_in, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w) {
|
||||||
uint8_t r = rgbw.r;
|
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
|
||||||
uint8_t g = rgbw.g;
|
pixelbuf_parse_color(self, color, r, g, b, w);
|
||||||
uint8_t b = rgbw.b;
|
}
|
||||||
uint8_t w = rgbw.w;
|
|
||||||
|
static void pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||||
// DotStars don't have white, instead they have 5 bit brightness so pack it into w. Shift right
|
// DotStars don't have white, instead they have 5 bit brightness so pack it into w. Shift right
|
||||||
// by three to leave the top five bits.
|
// by three to leave the top five bits.
|
||||||
if (self->bytes_per_pixel == 4 && self->byteorder.is_dotstar) {
|
if (self->bytes_per_pixel == 4 && self->byteorder.is_dotstar) {
|
||||||
@ -240,10 +239,18 @@ STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t inde
|
|||||||
scaled_buffer[rgbw_order->b] = (b * self->scaled_brightness) / 256;
|
scaled_buffer[rgbw_order->b] = (b * self->scaled_brightness) / 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(mp_obj_t self_in, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||||
|
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
|
||||||
|
pixelbuf_set_pixel_color(self, index, r, g, b, w);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t *self, size_t index, mp_obj_t value) {
|
STATIC void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t *self, size_t index, mp_obj_t value) {
|
||||||
color_u rgbw = _pixelbuf_parse_color(self, value);
|
uint8_t r;
|
||||||
_pixelbuf_set_pixel_color(self, index, rgbw);
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t w;
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self, value, &r, &g, &b, &w);
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self, index, r, g, b, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t *values,
|
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t *values,
|
||||||
@ -322,10 +329,14 @@ void common_hal_adafruit_pixelbuf_pixelbuf_show(mp_obj_t self_in) {
|
|||||||
void common_hal_adafruit_pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t fill_color) {
|
void common_hal_adafruit_pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t fill_color) {
|
||||||
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
|
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
|
||||||
|
|
||||||
color_u rgbw = _pixelbuf_parse_color(self, fill_color);
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t w;
|
||||||
|
common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self, fill_color, &r, &g, &b, &w);
|
||||||
|
|
||||||
for (size_t i = 0; i < self->pixel_count; i++) {
|
for (size_t i = 0; i < self->pixel_count; i++) {
|
||||||
_pixelbuf_set_pixel_color(self, i, rgbw);
|
common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self, i, r, g, b, w);
|
||||||
}
|
}
|
||||||
if (self->auto_write) {
|
if (self->auto_write) {
|
||||||
common_hal_adafruit_pixelbuf_pixelbuf_show(self_in);
|
common_hal_adafruit_pixelbuf_pixelbuf_show(self_in);
|
||||||
|
@ -24,13 +24,11 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/objarray.h"
|
#include "py/objarray.h"
|
||||||
|
|
||||||
#ifndef PIXELBUF_SHARED_MODULE_H
|
|
||||||
#define PIXELBUF_SHARED_MODULE_H
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
uint8_t g;
|
uint8_t g;
|
||||||
@ -68,5 +66,3 @@ typedef struct {
|
|||||||
|
|
||||||
#define DOTSTAR_LED_START 0b11100000
|
#define DOTSTAR_LED_START 0b11100000
|
||||||
#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF
|
#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user