Merge remote-tracking branch 'origin/main' into alphablend
This commit is contained in:
commit
8e8c44afea
|
@ -104,11 +104,11 @@ msgid "%q length must be >= 1"
|
|||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
msgid "%q must <= %d"
|
||||
msgid "%q must be %d-%d"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
msgid "%q must be %d-%d"
|
||||
#: py/argcheck.c shared-bindings/gifio/GifWriter.c
|
||||
msgid "%q must be <= %d"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
|
@ -3103,6 +3103,7 @@ msgstr ""
|
|||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c
|
||||
#: shared-module/gifio/GifWriter.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4361,6 +4362,10 @@ msgstr ""
|
|||
msgid "unsupported Xtensa instruction '%s' with %d arguments"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/gifio/GifWriter.c
|
||||
msgid "unsupported colorspace for GifWriter"
|
||||
msgstr ""
|
||||
|
||||
#: py/objstr.c
|
||||
#, c-format
|
||||
msgid "unsupported format character '%c' (0x%x) at index %d"
|
||||
|
|
|
@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ
|
|||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_GAMEPADSHIFT = 1
|
||||
CIRCUITPY_GIFIO = 0
|
||||
CIRCUITPY_STAGE = 1
|
||||
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge
|
||||
|
|
|
@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ
|
|||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_GAMEPADSHIFT = 1
|
||||
CIRCUITPY_GIFIO = 0
|
||||
CIRCUITPY_STAGE = 1
|
||||
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer
|
||||
|
|
|
@ -49,6 +49,7 @@ CIRCUITPY_COUNTIO ?= 0
|
|||
# Not enough RAM for framebuffers
|
||||
CIRCUITPY_FRAMEBUFFERIO ?= 0
|
||||
CIRCUITPY_FREQUENCYIO ?= 0
|
||||
CIRCUITPY_GIFIO ?= 0
|
||||
CIRCUITPY_I2CPERIPHERAL ?= 0
|
||||
CIRCUITPY_JSON ?= 0
|
||||
CIRCUITPY_KEYPAD ?= 0
|
||||
|
|
|
@ -23,6 +23,7 @@ CIRCUITPY_AUDIOPWMIO = 0
|
|||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_GIFIO = 0
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_MIDI = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
|
|
|
@ -22,6 +22,7 @@ LD_FILE = boards/STM32F401xe_boot.ld
|
|||
|
||||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_BLEIO_HCI = 0
|
||||
CIRCUITPY_GIFIO = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_STAGE = 1
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ LD_FILE = boards/STM32F411_fs.ld
|
|||
CIRCUITPY_AUDIOCORE = 0
|
||||
CIRCUITPY_AUDIOPWMIO = 0
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_GIFIO = 0
|
||||
CIRCUITPY_MIDI = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/enum.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/displayio/__init__.h"
|
||||
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB888, DISPLAYIO_COLORSPACE_RGB888);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565, DISPLAYIO_COLORSPACE_RGB565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565_SWAPPED, DISPLAYIO_COLORSPACE_RGB565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555, DISPLAYIO_COLORSPACE_RGB555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555_SWAPPED, DISPLAYIO_COLORSPACE_RGB555_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565, DISPLAYIO_COLORSPACE_BGR565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565_SWAPPED, DISPLAYIO_COLORSPACE_BGR565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555, DISPLAYIO_COLORSPACE_BGR555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555_SWAPPED, DISPLAYIO_COLORSPACE_BGR555_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, L8, DISPLAYIO_COLORSPACE_L8);
|
||||
|
||||
//| class Colorspace:
|
||||
//| """The colorspace for a `ColorConverter` to operate in"""
|
||||
//|
|
||||
//| RGB888: Colorspace
|
||||
//| """The standard 24-bit colorspace. Bits 0-7 are blue, 8-15 are green, and 16-24 are red. (0xRRGGBB)"""
|
||||
//|
|
||||
//| RGB565: Colorspace
|
||||
//| """The standard 16-bit colorspace. Bits 0-4 are blue, bits 5-10 are green, and 11-15 are red (0bRRRRRGGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB565_SWAPPED: Colorspace
|
||||
//| """The swapped 16-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB565"""
|
||||
//|
|
||||
//| RGB555: Colorspace
|
||||
//| """The standard 15-bit colorspace. Bits 0-4 are blue, bits 5-9 are green, and 11-14 are red. The top bit is ignored. (0bxRRRRRGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB555_SWAPPED: Colorspace
|
||||
//| """The swapped 15-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB555"""
|
||||
//|
|
||||
MAKE_ENUM_MAP(displayio_colorspace) {
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB888),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, L8),
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_colorspace_locals_dict, displayio_colorspace_locals_table);
|
||||
|
||||
MAKE_PRINTER(displayio, displayio_colorspace);
|
||||
MAKE_ENUM_TYPE(displayio, ColorSpace, displayio_colorspace);
|
||||
|
||||
STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Colorspace), MP_ROM_PTR(&displayio_colorspace_type) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table);
|
||||
|
||||
const mp_obj_module_t displayio_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&displayio_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module, CIRCUITPY_DISPLAYIO_COLORSPACE_ONLY);
|
|
@ -27,5 +27,10 @@ SRC_C += $(SRC_QRIO)
|
|||
CFLAGS += -DCIRCUITPY_QRIO=1
|
||||
$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h
|
||||
|
||||
SRC_GIFIO := $(patsubst ../../%,%,$(wildcard ../../shared-bindings/gifio/*.c ../../shared-module/gifio/*.c)) shared/runtime/context_manager_helpers.c displayio_colorspace_only.c shared-module/displayio/ColorConverter.c shared-bindings/util.c
|
||||
SRC_C += $(SRC_GIFIO)
|
||||
|
||||
CFLAGS += -DCIRCUITPY_GIFIO=1 -DCIRCUITPY_DISPLAYIO_COLORSPACE_ONLY=1
|
||||
|
||||
SRC_C += coverage.c
|
||||
SRC_CXX += coveragecpp.cpp
|
||||
|
|
|
@ -165,7 +165,7 @@ mp_int_t mp_arg_validate_int_min(mp_int_t i, mp_int_t min, qstr arg_name) {
|
|||
|
||||
mp_int_t mp_arg_validate_int_max(mp_int_t i, mp_int_t max, qstr arg_name) {
|
||||
if (i > max) {
|
||||
mp_raise_ValueError_varg(translate("%q must <= %d"), arg_name, max);
|
||||
mp_raise_ValueError_varg(translate("%q must be <= %d"), arg_name, max);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -197,6 +197,9 @@ endif
|
|||
ifeq ($(CIRCUITPY_GETPASS),1)
|
||||
SRC_PATTERNS += getpass/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_GIFIO),1)
|
||||
SRC_PATTERNS += gifio/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_GNSS),1)
|
||||
SRC_PATTERNS += gnss/%
|
||||
endif
|
||||
|
@ -465,6 +468,7 @@ $(filter $(SRC_PATTERNS), \
|
|||
digitalio/Direction.c \
|
||||
digitalio/DriveMode.c \
|
||||
digitalio/Pull.c \
|
||||
displayio/Colorspace.c \
|
||||
fontio/Glyph.c \
|
||||
imagecapture/ParallelImageCapture.c \
|
||||
math/__init__.c \
|
||||
|
@ -536,6 +540,8 @@ SRC_SHARED_MODULE_ALL = \
|
|||
gamepadshift/GamePadShift.c \
|
||||
gamepadshift/__init__.c \
|
||||
getpass/__init__.c \
|
||||
gifio/__init__.c \
|
||||
gifio/GifWriter.c \
|
||||
imagecapture/ParallelImageCapture.c \
|
||||
ipaddress/IPv4Address.c \
|
||||
ipaddress/__init__.c \
|
||||
|
|
|
@ -214,6 +214,13 @@ CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT)
|
|||
CIRCUITPY_GETPASS ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_GETPASS=$(CIRCUITPY_GETPASS)
|
||||
|
||||
ifeq ($(CIRCUITPY_DISPLAYIO),1)
|
||||
CIRCUITPY_GIFIO ?= $(CIRCUITPY_FULL_BUILD)
|
||||
else
|
||||
CIRCUITPY_GIFIO ?= 0
|
||||
endif
|
||||
CFLAGS += -DCIRCUITPY_GIFIO=$(CIRCUITPY_GIFIO)
|
||||
|
||||
CIRCUITPY_GNSS ?= 0
|
||||
CFLAGS += -DCIRCUITPY_GNSS=$(CIRCUITPY_GNSS)
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "py/enum.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/util.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ extern const mp_obj_type_t displayio_colorconverter_type;
|
|||
|
||||
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *self, bool dither, displayio_colorspace_t input_colorspace);
|
||||
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color);
|
||||
uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspace, uint32_t pixel);
|
||||
|
||||
void common_hal_displayio_colorconverter_set_dither(displayio_colorconverter_t *self, bool dither);
|
||||
bool common_hal_displayio_colorconverter_get_dither(displayio_colorconverter_t *self);
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/enum.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/displayio/__init__.h"
|
||||
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB888, DISPLAYIO_COLORSPACE_RGB888);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565, DISPLAYIO_COLORSPACE_RGB565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565_SWAPPED, DISPLAYIO_COLORSPACE_RGB565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555, DISPLAYIO_COLORSPACE_RGB555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555_SWAPPED, DISPLAYIO_COLORSPACE_RGB555_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565, DISPLAYIO_COLORSPACE_BGR565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565_SWAPPED, DISPLAYIO_COLORSPACE_BGR565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555, DISPLAYIO_COLORSPACE_BGR555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555_SWAPPED, DISPLAYIO_COLORSPACE_BGR555_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, L8, DISPLAYIO_COLORSPACE_L8);
|
||||
|
||||
//| class Colorspace:
|
||||
//| """The colorspace for a `ColorConverter` to operate in"""
|
||||
//|
|
||||
//| RGB888: Colorspace
|
||||
//| """The standard 24-bit colorspace. Bits 0-7 are blue, 8-15 are green, and 16-24 are red. (0xRRGGBB)"""
|
||||
//|
|
||||
//| RGB565: Colorspace
|
||||
//| """The standard 16-bit colorspace. Bits 0-4 are blue, bits 5-10 are green, and 11-15 are red (0bRRRRRGGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB565_SWAPPED: Colorspace
|
||||
//| """The swapped 16-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB565"""
|
||||
//|
|
||||
//| RGB555: Colorspace
|
||||
//| """The standard 15-bit colorspace. Bits 0-4 are blue, bits 5-9 are green, and 11-14 are red. The top bit is ignored. (0bxRRRRRGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB555_SWAPPED: Colorspace
|
||||
//| """The swapped 15-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB555"""
|
||||
//|
|
||||
MAKE_ENUM_MAP(displayio_colorspace) {
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB888),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, L8),
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_colorspace_locals_dict, displayio_colorspace_locals_table);
|
||||
|
||||
MAKE_PRINTER(displayio, displayio_colorspace);
|
||||
MAKE_ENUM_TYPE(displayio, ColorSpace, displayio_colorspace);
|
|
@ -69,50 +69,6 @@ STATIC mp_obj_t displayio_release_displays(void) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays);
|
||||
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB888, DISPLAYIO_COLORSPACE_RGB888);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565, DISPLAYIO_COLORSPACE_RGB565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565_SWAPPED, DISPLAYIO_COLORSPACE_RGB565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555, DISPLAYIO_COLORSPACE_RGB555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB555_SWAPPED, DISPLAYIO_COLORSPACE_RGB555_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565, DISPLAYIO_COLORSPACE_BGR565);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR565_SWAPPED, DISPLAYIO_COLORSPACE_BGR565_SWAPPED);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555, DISPLAYIO_COLORSPACE_BGR555);
|
||||
MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, BGR555_SWAPPED, DISPLAYIO_COLORSPACE_BGR555_SWAPPED);
|
||||
|
||||
//| class Colorspace:
|
||||
//| """The colorspace for a `ColorConverter` to operate in"""
|
||||
//|
|
||||
//| RGB888: Colorspace
|
||||
//| """The standard 24-bit colorspace. Bits 0-7 are blue, 8-15 are green, and 16-24 are red. (0xRRGGBB)"""
|
||||
//|
|
||||
//| RGB565: Colorspace
|
||||
//| """The standard 16-bit colorspace. Bits 0-4 are blue, bits 5-10 are green, and 11-15 are red (0bRRRRRGGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB565_SWAPPED: Colorspace
|
||||
//| """The swapped 16-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB565"""
|
||||
//|
|
||||
//| RGB555: Colorspace
|
||||
//| """The standard 15-bit colorspace. Bits 0-4 are blue, bits 5-9 are green, and 11-14 are red. The top bit is ignored. (0bxRRRRRGGGGGBBBBB)"""
|
||||
//|
|
||||
//| RGB555_SWAPPED: Colorspace
|
||||
//| """The swapped 15-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB555"""
|
||||
//|
|
||||
MAKE_ENUM_MAP(displayio_colorspace) {
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB888),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB555_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR565_SWAPPED),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555),
|
||||
MAKE_ENUM_MAP_ENTRY(displayio_colorspace, BGR555_SWAPPED),
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_colorspace_locals_dict, displayio_colorspace_locals_table);
|
||||
|
||||
MAKE_PRINTER(displayio, displayio_colorspace);
|
||||
MAKE_ENUM_TYPE(displayio, ColorSpace, displayio_colorspace);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) },
|
||||
|
@ -135,7 +91,6 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
|
|||
|
||||
{ MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table);
|
||||
|
||||
const mp_obj_module_t displayio_module = {
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef enum {
|
|||
CHIP_SELECT_TOGGLE_EVERY_BYTE
|
||||
} display_chip_select_behavior_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum displayio_colorspace {
|
||||
DISPLAYIO_COLORSPACE_RGB888,
|
||||
DISPLAYIO_COLORSPACE_RGB565,
|
||||
DISPLAYIO_COLORSPACE_RGB555,
|
||||
|
@ -50,6 +50,7 @@ typedef enum {
|
|||
DISPLAYIO_COLORSPACE_BGR555,
|
||||
DISPLAYIO_COLORSPACE_BGR565_SWAPPED,
|
||||
DISPLAYIO_COLORSPACE_BGR555_SWAPPED,
|
||||
DISPLAYIO_COLORSPACE_L8,
|
||||
} displayio_colorspace_t;
|
||||
|
||||
typedef bool (*display_bus_bus_reset)(mp_obj_t bus);
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/obj.h"
|
||||
#if MICROPY_VFS
|
||||
#include "extmod/vfs.h"
|
||||
#endif
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/gifio/GifWriter.h"
|
||||
#include "shared-module/gifio/GifWriter.h"
|
||||
#include "shared/runtime/context_manager_helpers.h"
|
||||
|
||||
//| class GifWriter:
|
||||
//| def __init__(self, file: Union[typing.BinaryIO, str], width:int, height:int, colorspace: displayio.Colorspace, loop:bool=True, dither:bool=False) -> None:
|
||||
//| """Construct a GifWriter object
|
||||
//|
|
||||
//| :param file: Either a file open in bytes mode, or the name of a file to open in bytes mode.
|
||||
//| :param width: The width of the image. All frames must have the same width.
|
||||
//| :param height: The height of the image. All frames must have the same height.
|
||||
//| :param colorspace: The colorspace of the image. All frames must have the same colorspace. The supported colorspaces are ``RGB565``, ``BGR565``, ``RGB565_SWAPPED``, ``BGR565_SWAPPED``, and ``L8`` (greyscale)
|
||||
//| :param loop: If True, the GIF is marked for looping playback
|
||||
//| :param dither: If True, and the image is in color, a simple ordered dither is applied.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_file, ARG_width, ARG_height, ARG_colorspace, ARG_loop, ARG_dither };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL} },
|
||||
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
|
||||
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
|
||||
{ MP_QSTR_colorspace, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL} },
|
||||
{ MP_QSTR_loop, MP_ARG_BOOL, { .u_bool = true } },
|
||||
{ MP_QSTR_dither, MP_ARG_BOOL, { .u_bool = false } },
|
||||
};
|
||||
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 file = args[ARG_file].u_obj;
|
||||
bool own_file = false;
|
||||
if (mp_obj_is_str(file)) {
|
||||
file = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), file, MP_OBJ_NEW_QSTR(MP_QSTR_wb));
|
||||
own_file = true;
|
||||
}
|
||||
|
||||
gifio_gifwriter_t *self = m_new_obj(gifio_gifwriter_t);
|
||||
self->base.type = &gifio_gifwriter_type;
|
||||
shared_module_gifio_gifwriter_construct(
|
||||
self,
|
||||
file,
|
||||
args[ARG_width].u_int,
|
||||
args[ARG_height].u_int,
|
||||
(displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_colorspace].u_obj),
|
||||
args[ARG_loop].u_bool,
|
||||
args[ARG_dither].u_bool,
|
||||
own_file);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
//| def __enter__(self) -> GifWriter:
|
||||
//| """No-op used by Context Managers."""
|
||||
//| ...
|
||||
// Provided by context manager helper.
|
||||
|
||||
//| def __exit__(self) -> None:
|
||||
//| """Automatically deinitializes the hardware when exiting a context. See
|
||||
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||
//| ...
|
||||
//|
|
||||
static mp_obj_t gifio_gifwriter___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
gifio_gifwriter_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
shared_module_gifio_gifwriter_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gifio_gifwriter___exit___obj, 4, 4, gifio_gifwriter___exit__);
|
||||
|
||||
//| def deinit(self) -> None:
|
||||
//| """Close the underlying file."""
|
||||
//| ...
|
||||
//|
|
||||
static mp_obj_t gifio_gifwriter_deinit(mp_obj_t self_in) {
|
||||
gifio_gifwriter_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
shared_module_gifio_gifwriter_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(gifio_gifwriter_deinit_obj, gifio_gifwriter_deinit);
|
||||
|
||||
//| def add_frame(self, bitmap: ReadableBuffer, delay: float = 0.1) -> None:
|
||||
//| """Add a frame to the GIF.
|
||||
//|
|
||||
//| :param bitmap: The frame data
|
||||
//| :param delay: The frame delay in seconds. The GIF format rounds this to the nearest 1/100 second, and the largest permitted value is 655 seconds.
|
||||
//| """
|
||||
//| ...
|
||||
static mp_obj_t gifio_gifwriter_add_frame(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_bitmap, ARG_delay };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_bitmap, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL} },
|
||||
{ MP_QSTR_delay, MP_ARG_OBJ, {.u_obj = NULL} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
gifio_gifwriter_t *self = MP_OBJ_TO_PTR(pos_args[0]);
|
||||
shared_module_gifio_gifwriter_check_for_deinit(self);
|
||||
|
||||
|
||||
mp_float_t delay = mp_arg_validate_obj_float_non_negative(args[ARG_delay].u_obj, MICROPY_FLOAT_CONST(0.1), MP_QSTR_delay);
|
||||
if (delay > MICROPY_FLOAT_CONST(655.)) {
|
||||
mp_raise_ValueError_varg(translate("%q must be <= %d"), MP_QSTR_delay, 655);
|
||||
}
|
||||
|
||||
int delay_centiseconds = (int)(delay * 100);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[ARG_bitmap].u_obj, &bufinfo, MP_BUFFER_READ);
|
||||
shared_module_gifio_gifwriter_add_frame(self, &bufinfo, delay_centiseconds);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(gifio_gifwriter_add_frame_obj, 1, gifio_gifwriter_add_frame);
|
||||
|
||||
STATIC const mp_rom_map_elem_t gifio_gifwriter_locals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_GifWriter) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&gifio_gifwriter___exit___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gifio_gifwriter_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_add_frame), MP_ROM_PTR(&gifio_gifwriter_add_frame_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(gifio_gifwriter_locals, gifio_gifwriter_locals_table);
|
||||
|
||||
const mp_obj_type_t gifio_gifwriter_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_GifWriter,
|
||||
.make_new = gifio_gifwriter_make_new,
|
||||
.locals_dict = (mp_obj_dict_t *)&gifio_gifwriter_locals,
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/obj.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct gifio_gifwriter gifio_gifwriter_t;
|
||||
typedef enum displayio_colorspace displayio_colorspace_t;
|
||||
|
||||
extern const mp_obj_type_t gifio_gifwriter_type;
|
||||
|
||||
void shared_module_gifio_gifwriter_construct(gifio_gifwriter_t *self, mp_obj_t *file, int width, int height, displayio_colorspace_t colorspace, bool loop, bool dither, bool own_file);
|
||||
void shared_module_gifio_gifwriter_check_for_deinit(gifio_gifwriter_t *self);
|
||||
bool shared_module_gifio_gifwriter_deinited(gifio_gifwriter_t *self);
|
||||
void shared_module_gifio_gifwriter_deinit(gifio_gifwriter_t *self);
|
||||
void shared_module_gifio_gifwriter_add_frame(gifio_gifwriter_t *self, const mp_buffer_info_t *buf, int16_t delay);
|
||||
void shared_module_gifio_gifwriter_close(gifio_gifwriter_t *self);
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "shared-bindings/gifio/GifWriter.h"
|
||||
#include "shared-bindings/util.h"
|
||||
|
||||
//| """Access GIF-format images
|
||||
//| """
|
||||
//|
|
||||
STATIC const mp_rom_map_elem_t gifio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gifio) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_GifWriter), MP_ROM_PTR(&gifio_gifwriter_type)},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(gifio_module_globals, gifio_module_globals_table);
|
||||
|
||||
const mp_obj_module_t gifio_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&gifio_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_gifio, gifio_module, CIRCUITPY_GIFIO);
|
|
@ -145,15 +145,10 @@ void common_hal_displayio_colorconverter_make_opaque(displayio_colorconverter_t
|
|||
self->transparent_color = NO_TRANSPARENT_COLOR;
|
||||
}
|
||||
|
||||
void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
uint32_t pixel = input_pixel->pixel;
|
||||
|
||||
if (self->transparent_color == pixel) {
|
||||
output_color->opaque = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (self->input_colorspace) {
|
||||
// Convert a single input pixel to RGB888
|
||||
uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspace, uint32_t pixel) {
|
||||
switch (colorspace) {
|
||||
case DISPLAYIO_COLORSPACE_RGB565_SWAPPED:
|
||||
pixel = __builtin_bswap16(pixel);
|
||||
MP_FALLTHROUGH;
|
||||
|
@ -198,10 +193,31 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
|
|||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case DISPLAYIO_COLORSPACE_RGB888:
|
||||
break;
|
||||
|
||||
case DISPLAYIO_COLORSPACE_L8: {
|
||||
uint32_t l8 = pixel & 0xff;
|
||||
pixel = l8 * 0x010101;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return pixel;
|
||||
}
|
||||
|
||||
void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
uint32_t pixel = input_pixel->pixel;
|
||||
|
||||
if (self->transparent_color == pixel) {
|
||||
output_color->opaque = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pixel = displayio_colorconverter_convert_pixel(self->input_colorspace, pixel);
|
||||
|
||||
|
||||
if (self->dither) {
|
||||
uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y));
|
||||
uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33,input_pixel->tile_y));
|
||||
|
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Jeff Epler for Adafruit Industries
|
||||
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-module/gifio/GifWriter.h"
|
||||
#include "shared-bindings/gifio/GifWriter.h"
|
||||
#include "shared-bindings/displayio/ColorConverter.h"
|
||||
#include "shared-bindings/util.h"
|
||||
|
||||
#define BLOCK_SIZE (126) // (2^7) - 2 // (DO NOT CHANGE!)
|
||||
|
||||
static void handle_error(gifio_gifwriter_t *self) {
|
||||
if (self->error != 0) {
|
||||
mp_raise_OSError(self->error);
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_data(gifio_gifwriter_t *self) {
|
||||
if (self->cur == 0) {
|
||||
return;
|
||||
}
|
||||
int error = 0;
|
||||
self->file_proto->write(self->file, self->data, self->cur, &error);
|
||||
self->cur = 0;
|
||||
if (error != 0) {
|
||||
self->error = error;
|
||||
}
|
||||
}
|
||||
|
||||
// These "write" calls _MUST_ have enough buffer space available! This is
|
||||
// ensured by allocating the proper buffer size in construct.
|
||||
static void write_data(gifio_gifwriter_t *self, const void *data, size_t size) {
|
||||
assert(self->cur + size <= self->size);
|
||||
memcpy(self->data + self->cur, data, size);
|
||||
self->cur += size;
|
||||
}
|
||||
|
||||
static void write_byte(gifio_gifwriter_t *self, uint8_t value) {
|
||||
write_data(self, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static void write_long(gifio_gifwriter_t *self, uint32_t value) {
|
||||
write_data(self, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static void write_word(gifio_gifwriter_t *self, uint16_t value) {
|
||||
write_data(self, &value, sizeof(value));
|
||||
}
|
||||
|
||||
void shared_module_gifio_gifwriter_construct(gifio_gifwriter_t *self, mp_obj_t *file, int width, int height, displayio_colorspace_t colorspace, bool loop, bool dither, bool own_file) {
|
||||
self->file = file;
|
||||
self->file_proto = mp_proto_get_or_throw(MP_QSTR_protocol_stream, file);
|
||||
if (self->file_proto->is_text) {
|
||||
mp_raise_TypeError(translate("file must be a file opened in byte mode"));
|
||||
}
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
self->colorspace = colorspace;
|
||||
self->dither = dither;
|
||||
self->own_file = own_file;
|
||||
|
||||
size_t nblocks = (width * height + 125) / 126;
|
||||
self->size = nblocks * 128 + 4;
|
||||
self->data = gc_alloc(self->size, 0, false);
|
||||
self->cur = 0;
|
||||
self->error = 0;
|
||||
|
||||
write_data(self, "GIF89a", 6);
|
||||
write_word(self, width);
|
||||
write_word(self, height);
|
||||
write_data(self, (uint8_t []) {0xF6, 0x00, 0x00}, 3);
|
||||
|
||||
switch (colorspace) {
|
||||
case DISPLAYIO_COLORSPACE_RGB565:
|
||||
case DISPLAYIO_COLORSPACE_RGB565_SWAPPED:
|
||||
case DISPLAYIO_COLORSPACE_BGR565:
|
||||
case DISPLAYIO_COLORSPACE_BGR565_SWAPPED:
|
||||
case DISPLAYIO_COLORSPACE_L8:
|
||||
break;
|
||||
|
||||
default:
|
||||
mp_raise_TypeError(translate("unsupported colorspace for GifWriter"));
|
||||
}
|
||||
|
||||
bool color = (colorspace != DISPLAYIO_COLORSPACE_L8);
|
||||
|
||||
bool bgr = (colorspace == DISPLAYIO_COLORSPACE_BGR565 || colorspace == DISPLAYIO_COLORSPACE_BGR565_SWAPPED);
|
||||
self->byteswap = (colorspace == DISPLAYIO_COLORSPACE_RGB565_SWAPPED || colorspace == DISPLAYIO_COLORSPACE_BGR565_SWAPPED);
|
||||
|
||||
if (color) {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int red = (int)(((((i & 0x60) >> 5) * 255) + 1.5) / 3);
|
||||
int green = (int)(((((i & 0x1C) >> 2) * 255) + 3.5) / 7);
|
||||
int blue = (int)((((i & 0x3) * 255) + 1.5) / 3);
|
||||
if (bgr) {
|
||||
write_data(self, (uint8_t []) {blue, red, green}, 3);
|
||||
} else {
|
||||
write_data(self, (uint8_t []) {red, green, blue}, 3);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int gray = (int)(((i * 255) + 63.5) / 127);
|
||||
write_data(self, (uint8_t []) {gray, gray, gray}, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
write_data(self, (uint8_t []) {'!', 0xFF, 0x0B}, 3);
|
||||
write_data(self, "NETSCAPE2.0", 11);
|
||||
write_data(self, (uint8_t []) {0x03, 0x01, 0x00, 0x00, 0x00}, 5);
|
||||
}
|
||||
|
||||
flush_data(self);
|
||||
handle_error(self);
|
||||
}
|
||||
|
||||
bool shared_module_gifio_gifwriter_deinited(gifio_gifwriter_t *self) {
|
||||
return !self->file;
|
||||
}
|
||||
|
||||
void shared_module_gifio_gifwriter_check_for_deinit(gifio_gifwriter_t *self) {
|
||||
if (shared_module_gifio_gifwriter_deinited(self)) {
|
||||
raise_deinited_error();
|
||||
}
|
||||
}
|
||||
|
||||
void shared_module_gifio_gifwriter_deinit(gifio_gifwriter_t *self) {
|
||||
if (!shared_module_gifio_gifwriter_deinited(self)) {
|
||||
shared_module_gifio_gifwriter_close(self);
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t rb_bayer[4][4] = {
|
||||
{ 0, 33, 8, 42},
|
||||
{50, 16, 58, 25},
|
||||
{12, 46, 4, 37},
|
||||
{63, 29, 54, 21}
|
||||
};
|
||||
|
||||
static const uint8_t g_bayer[4][4] = {
|
||||
{ 0, 16, 4, 20},
|
||||
{24, 8, 28, 12},
|
||||
{ 6, 22, 2, 18},
|
||||
{31, 14, 26, 10}
|
||||
};
|
||||
|
||||
void shared_module_gifio_gifwriter_add_frame(gifio_gifwriter_t *self, const mp_buffer_info_t *bufinfo, int16_t delay) {
|
||||
if (delay) {
|
||||
write_data(self, (uint8_t []) {'!', 0xF9, 0x04, 0x04}, 4);
|
||||
write_word(self, delay);
|
||||
write_word(self, 0); // end
|
||||
}
|
||||
|
||||
write_byte(self, 0x2C);
|
||||
write_long(self, 0);
|
||||
write_word(self, self->width);
|
||||
write_word(self, self->height);
|
||||
write_data(self, (uint8_t []) {0x00, 0x07}, 2); // 7-bits
|
||||
|
||||
int pixel_count = self->width * self->height;
|
||||
int blocks = (pixel_count + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||
|
||||
uint8_t *data = self->data + self->cur;
|
||||
|
||||
if (self->colorspace == DISPLAYIO_COLORSPACE_L8) {
|
||||
mp_get_index(&mp_type_memoryview, bufinfo->len, MP_OBJ_NEW_SMALL_INT(pixel_count - 1), false);
|
||||
|
||||
uint8_t *pixels = bufinfo->buf;
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
assert(pixel_count >= 0);
|
||||
int block_size = MIN(BLOCK_SIZE, pixel_count);
|
||||
pixel_count -= block_size;
|
||||
*data++ = 1 + block_size;
|
||||
*data++ = 0x80;
|
||||
for (int j = 0; j < block_size; j++) {
|
||||
*data++ = (*pixels++) >> 1;
|
||||
}
|
||||
}
|
||||
} else if (!self->dither) {
|
||||
mp_get_index(&mp_type_memoryview, bufinfo->len, MP_OBJ_NEW_SMALL_INT(2 * pixel_count - 1), false);
|
||||
|
||||
uint16_t *pixels = bufinfo->buf;
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
int block_size = MIN(BLOCK_SIZE, pixel_count);
|
||||
pixel_count -= block_size;
|
||||
|
||||
*data++ = 1 + block_size;
|
||||
*data++ = 0x80;
|
||||
for (int j = 0; j < block_size; j++) {
|
||||
int pixel = *pixels++;
|
||||
if (self->byteswap) {
|
||||
pixel = __builtin_bswap16(pixel);
|
||||
}
|
||||
int red = (pixel >> (11 + (5 - 2))) & 0x3;
|
||||
int green = (pixel >> (5 + (6 - 3))) & 0x7;
|
||||
int blue = (pixel >> (0 + (5 - 2))) & 0x3;
|
||||
*data++ = (red << 5) | (green << 2) | blue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mp_get_index(&mp_type_memoryview, bufinfo->len, MP_OBJ_NEW_SMALL_INT(2 * pixel_count - 1), false);
|
||||
|
||||
uint16_t *pixels = bufinfo->buf;
|
||||
int x = 0, y = 0;
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
int block_size = MIN(BLOCK_SIZE, pixel_count);
|
||||
pixel_count -= block_size;
|
||||
|
||||
*data++ = 1 + block_size;
|
||||
*data++ = 0x80;
|
||||
for (int j = 0; j < block_size; j++) {
|
||||
int pixel = *pixels++;
|
||||
if (self->byteswap) {
|
||||
pixel = __builtin_bswap16(pixel);
|
||||
}
|
||||
int red = (pixel >> 8) & 0xf8;
|
||||
int green = (pixel >> 3) & 0xfc;
|
||||
int blue = (pixel << 3) & 0xf8;
|
||||
|
||||
red = MAX(0, red - rb_bayer[x % 4][y % 4]);
|
||||
green = MAX(0, green - g_bayer[x % 4][(y + 2) % 4]);
|
||||
blue = MAX(0, blue - rb_bayer[(x + 2) % 4][y % 4]);
|
||||
x++;
|
||||
if (x == self->width) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
|
||||
*data++ = ((red >> 1) & 0x60) | ((green >> 3) & 0x1c) | (blue >> 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->cur = data - self->data;
|
||||
|
||||
write_data(self, (uint8_t []) {0x01, 0x81, 0x00}, 3); // end code
|
||||
flush_data(self);
|
||||
handle_error(self);
|
||||
}
|
||||
|
||||
void shared_module_gifio_gifwriter_close(gifio_gifwriter_t *self) {
|
||||
write_byte(self, ';');
|
||||
flush_data(self);
|
||||
|
||||
int error = 0;
|
||||
self->file_proto->ioctl(self->file, self->own_file ? MP_STREAM_CLOSE : MP_STREAM_FLUSH, 0, &error);
|
||||
self->file = NULL;
|
||||
|
||||
if (error != 0) {
|
||||
self->error = error;
|
||||
}
|
||||
handle_error(self);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 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"
|
||||
#include "py/stream.h"
|
||||
#include "shared-bindings/displayio/__init__.h"
|
||||
|
||||
typedef struct gifio_gifwriter {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t *file;
|
||||
const mp_stream_p_t *file_proto;
|
||||
displayio_colorspace_t colorspace;
|
||||
int width, height;
|
||||
int error;
|
||||
uint8_t *data;
|
||||
size_t cur, size;
|
||||
bool own_file;
|
||||
bool byteswap;
|
||||
bool dither;
|
||||
} gifio_gifwriter_t;
|
|
@ -31,13 +31,14 @@ mport
|
|||
|
||||
builtins micropython _thread array
|
||||
binascii btree cexample cmath
|
||||
collections cppexample errno ffi
|
||||
framebuf gc hashlib json
|
||||
math qrio re sys
|
||||
termios ubinascii uctypes uerrno
|
||||
uheapq uio ujson ulab
|
||||
uos urandom ure uselect
|
||||
ustruct utime utimeq uzlib
|
||||
collections cppexample displayio errno
|
||||
ffi framebuf gc gifio
|
||||
hashlib json math qrio
|
||||
re sys termios ubinascii
|
||||
uctypes uerrno uheapq uio
|
||||
ujson ulab uos urandom
|
||||
ure uselect ustruct utime
|
||||
utimeq uzlib
|
||||
ime
|
||||
|
||||
utime utimeq
|
||||
|
|
Loading…
Reference in New Issue