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 ""
|
||||
|
||||
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
||||
#: shared-module/adafruit_pixelbuf/PixelMap.c
|
||||
#, c-format
|
||||
msgid "Unmatched number of items on RHS (expected %d, got %d)."
|
||||
msgstr ""
|
||||
|
@ -3123,6 +3124,10 @@ msgstr ""
|
|||
msgid "index is out of bounds"
|
||||
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
|
||||
#: ports/espressif/common-hal/pulseio/PulseIn.c
|
||||
#: shared-bindings/bitmaptools/__init__.c
|
||||
|
@ -3498,6 +3503,10 @@ msgstr ""
|
|||
msgid "negative shift count"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
|
||||
msgid "nested index must be int"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/sdcardio/SDCard.c
|
||||
msgid "no SD card"
|
||||
msgstr ""
|
||||
|
|
|
@ -42,6 +42,7 @@ CIRCUITPY_I2CTARGET ?= 0
|
|||
CIRCUITPY_JSON ?= 0
|
||||
CIRCUITPY_KEYPAD ?= 0
|
||||
CIRCUITPY_MSGPACK ?= 0
|
||||
CIRCUITPY_PIXELMAP ?= 0
|
||||
CIRCUITPY_RE ?= 0
|
||||
CIRCUITPY_SDCARDIO ?= 0
|
||||
CIRCUITPY_SYNTHIO ?= 0
|
||||
|
|
|
@ -9,5 +9,6 @@ QSPI_FLASH_FILESYSTEM = 1
|
|||
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
|
||||
|
||||
CIRCUITPY_DISPLAYIO = 1
|
||||
CIRCUITPY_PIXELMAP = 0
|
||||
|
||||
CIRCUITPY_REQUIRE_I2C_PULLUPS = 0
|
||||
|
|
|
@ -13,4 +13,5 @@ CIRCUITPY_KEYPAD = 1
|
|||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_PIXELBUF = 1
|
||||
CIRCUITPY_PIXELMAP = 0
|
||||
CIRCUITPY_TOUCHIO = 0
|
||||
|
|
|
@ -266,6 +266,9 @@ endif
|
|||
ifeq ($(CIRCUITPY_PIXELBUF),1)
|
||||
SRC_PATTERNS += adafruit_pixelbuf/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PIXELMAP),1)
|
||||
SRC_PATTERNS += _pixelmap/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_QRIO),1)
|
||||
SRC_PATTERNS += qrio/%
|
||||
endif
|
||||
|
@ -543,6 +546,8 @@ SRC_SHARED_MODULE_ALL = \
|
|||
_eve/__init__.c \
|
||||
adafruit_pixelbuf/PixelBuf.c \
|
||||
adafruit_pixelbuf/__init__.c \
|
||||
_pixelmap/PixelMap.c \
|
||||
_pixelmap/__init__.c \
|
||||
_stage/Layer.c \
|
||||
_stage/Text.c \
|
||||
_stage/__init__.c \
|
||||
|
|
|
@ -319,6 +319,9 @@ CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
|
|||
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
|
||||
|
||||
CIRCUITPY_PIXELMAP ?= $(CIRCUITPY_PIXELBUF)
|
||||
CFLAGS += -DCIRCUITPY_PIXELMAP=$(CIRCUITPY_PIXELMAP)
|
||||
|
||||
# Only for SAMD boards for the moment
|
||||
CIRCUITPY_PS2IO ?= 0
|
||||
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
};
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
||||
|
||||
//| def fill(
|
||||
//| self, color: Union[int, Tuple[int, int, int], Tuple[int, int, int, float]]
|
||||
//| ) -> None:
|
||||
//| def fill(self, color: PixelType) -> None:
|
||||
//| """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);
|
||||
|
||||
//| @overload
|
||||
//| def __getitem__(
|
||||
//| 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]]:
|
||||
//| def __getitem__(self, index: slice) -> PixelReturnSequence:
|
||||
//| """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
|
||||
//| intensity from 0-1.0."""
|
||||
//| ...
|
||||
//| @overload
|
||||
//| def __setitem__(
|
||||
//| self, index: slice, value: Tuple[Union[int, Tuple[float, ...], List[float]], ...]
|
||||
//| ) -> None: ...
|
||||
//| def __getitem__(self, index: int) -> PixelReturnType:
|
||||
//| """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
|
||||
//| intensity from 0-1.0."""
|
||||
//| ...
|
||||
//| @overload
|
||||
//| def __setitem__(
|
||||
//| self, index: slice, value: List[Union[int, Tuple[float, ...], List[float]]]
|
||||
//| ) -> None: ...
|
||||
//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ...
|
||||
//| @overload
|
||||
//| def __setitem__(
|
||||
//| self, index: int, value: Union[int, Tuple[float, ...], List[float]]
|
||||
//| ) -> None:
|
||||
//| 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).
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
||||
#define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H
|
||||
|
||||
#include "py/objtuple.h"
|
||||
#include "shared-module/adafruit_pixelbuf/PixelBuf.h"
|
||||
|
||||
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);
|
||||
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_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
|
||||
|
|
|
@ -39,6 +39,15 @@
|
|||
//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel.
|
||||
//|
|
||||
//| 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.
|
||||
|
||||
STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = {
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
||||
|
||||
STATIC color_u _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color) {
|
||||
color_u result;
|
||||
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) {
|
||||
pixelbuf_byteorder_details_t *byteorder = &self->byteorder;
|
||||
// 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.
|
||||
if (byteorder->is_dotstar) {
|
||||
result.w = 255;
|
||||
*w = 255;
|
||||
} else {
|
||||
result.w = 0;
|
||||
*w = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
result.r = value >> 16 & 0xff;
|
||||
result.g = (value >> 8) & 0xff;
|
||||
result.b = value & 0xff;
|
||||
*r = value >> 16 & 0xff;
|
||||
*g = (value >> 8) & 0xff;
|
||||
*b = value & 0xff;
|
||||
} else {
|
||||
mp_obj_t *items;
|
||||
size_t len;
|
||||
mp_obj_get_array(color, &len, &items);
|
||||
mp_arg_validate_length_range(len, 3, 4, MP_QSTR_color);
|
||||
|
||||
result.r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
|
||||
result.g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
|
||||
result.b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
|
||||
*r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
|
||||
*g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
|
||||
*b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
|
||||
if (len > 3) {
|
||||
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 {
|
||||
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.
|
||||
// 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) {
|
||||
result.w = result.r;
|
||||
result.r = 0;
|
||||
result.g = 0;
|
||||
result.b = 0;
|
||||
if (!byteorder->is_dotstar && byteorder->bpp == 4 && byteorder->has_white && *r == *g && *r == *b) {
|
||||
*w = *r;
|
||||
*r = 0;
|
||||
*g = 0;
|
||||
*b = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, color_u rgbw) {
|
||||
uint8_t r = rgbw.r;
|
||||
uint8_t g = rgbw.g;
|
||||
uint8_t b = rgbw.b;
|
||||
uint8_t w = rgbw.w;
|
||||
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) {
|
||||
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
|
||||
pixelbuf_parse_color(self, color, r, g, b, 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
|
||||
// by three to leave the top five bits.
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
color_u rgbw = _pixelbuf_parse_color(self, value);
|
||||
_pixelbuf_set_pixel_color(self, index, rgbw);
|
||||
uint8_t r;
|
||||
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,
|
||||
|
@ -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) {
|
||||
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++) {
|
||||
_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) {
|
||||
common_hal_adafruit_pixelbuf_pixelbuf_show(self_in);
|
||||
|
|
|
@ -24,13 +24,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#ifndef PIXELBUF_SHARED_MODULE_H
|
||||
#define PIXELBUF_SHARED_MODULE_H
|
||||
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
|
@ -68,5 +66,3 @@ typedef struct {
|
|||
|
||||
#define DOTSTAR_LED_START 0b11100000
|
||||
#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue