removing submodule
Some checks failed
build lightwatch / build (push) Failing after 5m6s

This commit is contained in:
2023-09-03 01:14:34 -04:00
parent d539dc9119
commit ed18dd911a
190 changed files with 1174526 additions and 4 deletions

View File

@@ -0,0 +1,15 @@
# The *.cpp files are included in the distribution; this is only needed when
# working on the pyx files.
#
# Please check in modified *.cpp files with distribution to not require cython
# to be installed on the users' machine.
# for python3: make PYTHON=$(which python3) CYTHON=$(which cython3)
CYTHON ?= cython
all : core.cpp graphics.cpp
%.cpp : %.pyx
$(CYTHON) --cplus -o $@ $^
clean:
rm -rf core.cpp graphics.cpp

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
__version__ = "0.0.1"
__author__ = "Christoph Friedrich <christoph.friedrich@vonaffenfels.de>"
from .core import RGBMatrix, FrameCanvas, RGBMatrixOptions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
cimport cppinc
cdef class Canvas:
cdef cppinc.Canvas *__getCanvas(self) except +
cdef class FrameCanvas(Canvas):
cdef cppinc.FrameCanvas *__canvas
cdef class RGBMatrix(Canvas):
cdef cppinc.RGBMatrix *__matrix
cdef class RGBMatrixOptions:
cdef cppinc.Options __options
cdef cppinc.RuntimeOptions __runtime_options
# Must keep a reference to the encoded bytes for the strings,
# otherwise, when the Options struct is used, it will be garbage collected
cdef bytes __py_encoded_hardware_mapping
cdef bytes __py_encoded_led_rgb_sequence
cdef bytes __py_encoded_pixel_mapper_config
cdef bytes __py_encoded_panel_type
# Local Variables:
# mode: python
# End:

View File

@@ -0,0 +1,272 @@
# distutils: language = c++
from libcpp cimport bool
from libc.stdint cimport uint8_t, uint32_t, uintptr_t
from PIL import Image
import cython
cdef class Canvas:
cdef cppinc.Canvas* __getCanvas(self) except +:
raise Exception("Not implemented")
def SetImage(self, image, int offset_x = 0, int offset_y = 0, unsafe=True):
if (image.mode != "RGB"):
raise Exception("Currently, only RGB mode is supported for SetImage(). Please create images with mode 'RGB' or convert first with image = image.convert('RGB'). Pull requests to support more modes natively are also welcome :)")
if unsafe:
#In unsafe mode we directly access the underlying PIL image array
#in cython, which is considered unsafe pointer accecss,
#however it's super fast and seems to work fine
#https://groups.google.com/forum/#!topic/cython-users/Dc1ft5W6KM4
img_width, img_height = image.size
self.SetPixelsPillow(offset_x, offset_y, img_width, img_height, image)
else:
# First implementation of a SetImage(). OPTIMIZE_ME: A more native
# implementation that directly reads the buffer and calls the underlying
# C functions can certainly be faster.
img_width, img_height = image.size
pixels = image.load()
for x in range(max(0, -offset_x), min(img_width, self.width - offset_x)):
for y in range(max(0, -offset_y), min(img_height, self.height - offset_y)):
(r, g, b) = pixels[x, y]
self.SetPixel(x + offset_x, y + offset_y, r, g, b)
@cython.boundscheck(False)
@cython.wraparound(False)
def SetPixelsPillow(self, int xstart, int ystart, int width, int height, image):
cdef cppinc.FrameCanvas* my_canvas = <cppinc.FrameCanvas*>self.__getCanvas()
cdef int frame_width = my_canvas.width()
cdef int frame_height = my_canvas.height()
cdef int row, col
cdef uint8_t r, g, b
cdef uint32_t **image_ptr
cdef uint32_t pixel
image.load()
ptr_tmp = dict(image.im.unsafe_ptrs)['image32']
image_ptr = (<uint32_t **>(<uintptr_t>ptr_tmp))
for col in range(max(0, -xstart), min(width, frame_width - xstart)):
for row in range(max(0, -ystart), min(height, frame_height - ystart)):
pixel = image_ptr[row][col]
r = (pixel ) & 0xFF
g = (pixel >> 8) & 0xFF
b = (pixel >> 16) & 0xFF
my_canvas.SetPixel(xstart+col, ystart+row, r, g, b)
cdef class FrameCanvas(Canvas):
def __dealloc__(self):
if <void*>self.__canvas != NULL:
self.__canvas = NULL
cdef cppinc.Canvas* __getCanvas(self) except *:
if <void*>self.__canvas != NULL:
return self.__canvas
raise Exception("Canvas was destroyed or not initialized, you cannot use this object anymore")
def Fill(self, uint8_t red, uint8_t green, uint8_t blue):
(<cppinc.FrameCanvas*>self.__getCanvas()).Fill(red, green, blue)
def Clear(self):
(<cppinc.FrameCanvas*>self.__getCanvas()).Clear()
def SetPixel(self, int x, int y, uint8_t red, uint8_t green, uint8_t blue):
(<cppinc.FrameCanvas*>self.__getCanvas()).SetPixel(x, y, red, green, blue)
property width:
def __get__(self): return (<cppinc.FrameCanvas*>self.__getCanvas()).width()
property height:
def __get__(self): return (<cppinc.FrameCanvas*>self.__getCanvas()).height()
property pwmBits:
def __get__(self): return (<cppinc.FrameCanvas*>self.__getCanvas()).pwmbits()
def __set__(self, pwmBits): (<cppinc.FrameCanvas*>self.__getCanvas()).SetPWMBits(pwmBits)
property brightness:
def __get__(self): return (<cppinc.FrameCanvas*>self.__getCanvas()).brightness()
def __set__(self, val): (<cppinc.FrameCanvas*>self.__getCanvas()).SetBrightness(val)
cdef class RGBMatrixOptions:
def __cinit__(self):
self.__options = cppinc.Options()
self.__runtime_options = cppinc.RuntimeOptions()
# RGBMatrix::Options properties
property hardware_mapping:
def __get__(self): return self.__options.hardware_mapping
def __set__(self, value):
self.__py_encoded_hardware_mapping = value.encode('utf-8')
self.__options.hardware_mapping = self.__py_encoded_hardware_mapping
property rows:
def __get__(self): return self.__options.rows
def __set__(self, uint8_t value): self.__options.rows = value
property cols:
def __get__(self): return self.__options.cols
def __set__(self, uint32_t value): self.__options.cols = value
property chain_length:
def __get__(self): return self.__options.chain_length
def __set__(self, uint8_t value): self.__options.chain_length = value
property parallel:
def __get__(self): return self.__options.parallel
def __set__(self, uint8_t value): self.__options.parallel = value
property pwm_bits:
def __get__(self): return self.__options.pwm_bits
def __set__(self, uint8_t value): self.__options.pwm_bits = value
property pwm_lsb_nanoseconds:
def __get__(self): return self.__options.pwm_lsb_nanoseconds
def __set__(self, uint32_t value): self.__options.pwm_lsb_nanoseconds = value
property brightness:
def __get__(self): return self.__options.brightness
def __set__(self, uint8_t value): self.__options.brightness = value
property scan_mode:
def __get__(self): return self.__options.scan_mode
def __set__(self, uint8_t value): self.__options.scan_mode = value
property multiplexing:
def __get__(self): return self.__options.multiplexing
def __set__(self, uint8_t value): self.__options.multiplexing = value
property row_address_type:
def __get__(self): return self.__options.row_address_type
def __set__(self, uint8_t value): self.__options.row_address_type = value
property disable_hardware_pulsing:
def __get__(self): return self.__options.disable_hardware_pulsing
def __set__(self, value): self.__options.disable_hardware_pulsing = value
property show_refresh_rate:
def __get__(self): return self.__options.show_refresh_rate
def __set__(self, value): self.__options.show_refresh_rate = value
property inverse_colors:
def __get__(self): return self.__options.inverse_colors
def __set__(self, value): self.__options.inverse_colors = value
property led_rgb_sequence:
def __get__(self): return self.__options.led_rgb_sequence
def __set__(self, value):
self.__py_encoded_led_rgb_sequence = value.encode('utf-8')
self.__options.led_rgb_sequence = self.__py_encoded_led_rgb_sequence
property pixel_mapper_config:
def __get__(self): return self.__options.pixel_mapper_config
def __set__(self, value):
self.__py_encoded_pixel_mapper_config = value.encode('utf-8')
self.__options.pixel_mapper_config = self.__py_encoded_pixel_mapper_config
property panel_type:
def __get__(self): return self.__options.panel_type
def __set__(self, value):
self.__py_encoded_panel_type = value.encode('utf-8')
self.__options.panel_type = self.__py_encoded_panel_type
property pwm_dither_bits:
def __get__(self): return self.__options.pwm_dither_bits
def __set__(self, uint8_t value): self.__options.pwm_dither_bits = value
property limit_refresh_rate_hz:
def __get__(self): return self.__options.limit_refresh_rate_hz
def __set__(self, value): self.__options.limit_refresh_rate_hz = value
# RuntimeOptions properties
property gpio_slowdown:
def __get__(self): return self.__runtime_options.gpio_slowdown
def __set__(self, uint8_t value): self.__runtime_options.gpio_slowdown = value
property daemon:
def __get__(self): return self.__runtime_options.daemon
def __set__(self, uint8_t value): self.__runtime_options.daemon = value
property drop_privileges:
def __get__(self): return self.__runtime_options.drop_privileges
def __set__(self, uint8_t value): self.__runtime_options.drop_privileges = value
cdef class RGBMatrix(Canvas):
def __cinit__(self, int rows = 0, int chains = 0, int parallel = 0,
RGBMatrixOptions options = None):
# If RGBMatrixOptions not provided, create defaults and set any optional
# parameters supplied
if options == None:
options = RGBMatrixOptions()
if rows > 0:
options.rows = rows
if chains > 0:
options.chain_length = chains
if parallel > 0:
options.parallel = parallel
self.__matrix = cppinc.CreateMatrixFromOptions(options.__options,
options.__runtime_options)
def __dealloc__(self):
self.__matrix.Clear()
del self.__matrix
cdef cppinc.Canvas* __getCanvas(self) except *:
if <void*>self.__matrix != NULL:
return self.__matrix
raise Exception("Canvas was destroyed or not initialized, you cannot use this object anymore")
def Fill(self, uint8_t red, uint8_t green, uint8_t blue):
self.__matrix.Fill(red, green, blue)
def SetPixel(self, int x, int y, uint8_t red, uint8_t green, uint8_t blue):
self.__matrix.SetPixel(x, y, red, green, blue)
def Clear(self):
self.__matrix.Clear()
def CreateFrameCanvas(self):
return __createFrameCanvas(self.__matrix.CreateFrameCanvas())
# The optional "framerate_fraction" parameter allows to choose which
# multiple of the global frame-count to use. So it slows down your animation
# to an exact integer fraction of the refresh rate.
# Default is 1, so immediately next available frame.
# (Say you have 140Hz refresh rate, then a value of 5 would give you an
# 28Hz animation, nicely locked to the refresh-rate).
# If you combine this with RGBMatrixOptions.limit_refresh_rate_hz you can create
# time-correct animations.
def SwapOnVSync(self, FrameCanvas newFrame, uint8_t framerate_fraction = 1):
return __createFrameCanvas(self.__matrix.SwapOnVSync(newFrame.__canvas, framerate_fraction))
property luminanceCorrect:
def __get__(self): return self.__matrix.luminance_correct()
def __set__(self, luminanceCorrect): self.__matrix.set_luminance_correct(luminanceCorrect)
property pwmBits:
def __get__(self): return self.__matrix.pwmbits()
def __set__(self, pwmBits): self.__matrix.SetPWMBits(pwmBits)
property brightness:
def __get__(self): return self.__matrix.brightness()
def __set__(self, brightness): self.__matrix.SetBrightness(brightness)
property height:
def __get__(self): return self.__matrix.height()
property width:
def __get__(self): return self.__matrix.width()
cdef __createFrameCanvas(cppinc.FrameCanvas* newCanvas):
canvas = FrameCanvas()
canvas.__canvas = newCanvas
return canvas
# Local Variables:
# mode: python
# End:

View File

@@ -0,0 +1,88 @@
from libcpp cimport bool
from libc.stdint cimport uint8_t, uint32_t
########################
### External classes ###
########################
cdef extern from "canvas.h" namespace "rgb_matrix":
cdef cppclass Canvas:
int width()
int height()
void SetPixel(int, int, uint8_t, uint8_t, uint8_t) nogil
void Clear() nogil
void Fill(uint8_t, uint8_t, uint8_t) nogil
cdef extern from "led-matrix.h" namespace "rgb_matrix":
cdef cppclass RGBMatrix(Canvas):
bool SetPWMBits(uint8_t)
uint8_t pwmbits()
void set_luminance_correct(bool)
bool luminance_correct()
void SetBrightness(uint8_t)
uint8_t brightness()
FrameCanvas *CreateFrameCanvas()
FrameCanvas *SwapOnVSync(FrameCanvas*, uint8_t)
cdef cppclass FrameCanvas(Canvas):
bool SetPWMBits(uint8_t)
uint8_t pwmbits()
void SetBrightness(uint8_t)
uint8_t brightness()
struct RuntimeOptions:
RuntimeOptions() except +
int gpio_slowdown
int daemon
int drop_privileges
RGBMatrix *CreateMatrixFromOptions(Options &options, RuntimeOptions runtime_options)
cdef extern from "led-matrix.h" namespace "rgb_matrix::RGBMatrix":
cdef struct Options:
Options() except +
const char *hardware_mapping
int rows
int cols
int chain_length
int parallel
int pwm_bits
int pwm_lsb_nanoseconds
int brightness
int scan_mode
int row_address_type
int multiplexing
int pwm_dither_bits
int limit_refresh_rate_hz
bool disable_hardware_pulsing
bool show_refresh_rate
bool inverse_colors
const char *led_rgb_sequence
const char *pixel_mapper_config
const char *panel_type
cdef extern from "graphics.h" namespace "rgb_matrix":
cdef struct Color:
Color(uint8_t, uint8_t, uint8_t) except +
uint8_t r
uint8_t g
uint8_t b
cdef cppclass Font:
Font() except +
bool LoadFont(const char*)
int height()
int baseline()
int CharacterWidth(uint32_t)
int DrawGlyph(Canvas*, int, int, const Color, uint32_t);
cdef int DrawText(Canvas*, const Font, int, int, const Color, const char*)
cdef void DrawCircle(Canvas*, int, int, int, const Color)
cdef void DrawLine(Canvas*, int, int, int, int, const Color)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
cimport cppinc
cdef class Color:
cdef cppinc.Color __color
cdef class Font:
cdef cppinc.Font __font
# Local Variables:
# mode: python
# End:

View File

@@ -0,0 +1,54 @@
# distutils: language = c++
from libcpp cimport bool
from libc.stdint cimport uint8_t, uint32_t
cimport core
cdef class Color:
def __init__(self, uint8_t red = 0, uint8_t green = 0, uint8_t blue = 0):
self.__color.r = red
self.__color.g = green
self.__color.b = blue
property red:
def __get__(self): return self.__color.r
def __set__(self, uint8_t value): self.__color.r = value
property green:
def __get__(self): return self.__color.g
def __set__(self, uint8_t value): self.__color.g = value
property blue:
def __get__(self): return self.__color.b
def __set__(self, uint8_t value): self.__color.b = value
cdef class Font:
def CharacterWidth(self, uint32_t char):
return self.__font.CharacterWidth(char)
def LoadFont(self, file):
if (not self.__font.LoadFont(file.encode('utf-8'))):
raise Exception("Couldn't load font " + file)
def DrawGlyph(self, core.Canvas c, int x, int y, Color color, uint32_t char):
return self.__font.DrawGlyph(c.__getCanvas(), x, y, color.__color, char)
property height:
def __get__(self): return self.__font.height()
property baseline:
def __get__(self): return self.__font.baseline()
def DrawText(core.Canvas c, Font f, int x, int y, Color color, text):
return cppinc.DrawText(c.__getCanvas(), f.__font, x, y, color.__color, text.encode('utf-8'))
def DrawCircle(core.Canvas c, int x, int y, int r, Color color):
cppinc.DrawCircle(c.__getCanvas(), x, y, r, color.__color)
def DrawLine(core.Canvas c, int x1, int y1, int x2, int y2, Color color):
cppinc.DrawLine(c.__getCanvas(), x1, y1, x2, y2, color.__color)
# Local Variables:
# mode: python
# End: