#ifndef __MICROPY_INCLUDED_MICROBIT_IMAGE_H__ #define __MICROPY_INCLUDED_MICROBIT_IMAGE_H__ #include "py/runtime.h" #define MAX_BRIGHTNESS 9 /** Monochrome images are immutable, which means that * we only need one bit per pixel which saves quite a lot * of memory */ /* we reserve a couple of bits, so we won't need to modify the * layout if we need to add more functionality or subtypes. */ #define TYPE_AND_FLAGS \ mp_obj_base_t base; \ uint8_t five:1; \ uint8_t reserved1:1; \ uint8_t reserved2:1 typedef struct _image_base_t { TYPE_AND_FLAGS; } image_base_t; typedef struct _monochrome_5by5_t { TYPE_AND_FLAGS; uint8_t pixel44: 1; uint8_t bits24[3]; } monochrome_5by5_t; /* This is an internal method it is up to the caller to validate the inputs */ uint8_t monochromeGetPixelValue(monochrome_5by5_t * p_mono, mp_int_t x, mp_int_t y); typedef struct _greyscale_t { TYPE_AND_FLAGS; uint8_t height; uint8_t width; uint8_t byte_data[]; /* Static initializer for this will have to be C, not C++ */ } greyscale_t; #if 1 void clear(greyscale_t * p_greyscale); /* Thiese are internal methods and it is up to the caller to validate the inputs */ uint8_t greyscaleGetPixelValue(greyscale_t * p_greyscale, mp_int_t x, mp_int_t y); void greyscaleSetPixelValue(greyscale_t * p_greyscale, mp_int_t x, mp_int_t y, mp_int_t val); void greyscaleFill(greyscale_t * p_greyscale, mp_int_t val); #endif typedef union _microbit_image_obj_t { image_base_t base; monochrome_5by5_t monochrome_5by5; greyscale_t greyscale; } microbit_image_obj_t; #if 1 mp_int_t imageHeight(microbit_image_obj_t * p_image_obj); mp_int_t imageWidth(microbit_image_obj_t * p_image_obj); greyscale_t * imageCopy(microbit_image_obj_t * p_image_obj); greyscale_t * imageInvert(microbit_image_obj_t * p_image_obj); /* This is an internal method it is up to the caller to validate the inputs */ uint8_t imageGetPixelValue(microbit_image_obj_t * p_image_obj, mp_int_t x, mp_int_t y); #endif /** Return a facade object that presents the string as a sequence of images */ mp_obj_t microbit_string_facade(mp_obj_t string); void microbit_image_set_from_char(greyscale_t *img, char c); microbit_image_obj_t *microbit_image_for_char(char c); mp_obj_t microbit_image_slice(microbit_image_obj_t *img, mp_int_t start, mp_int_t width, mp_int_t stride); /* ref exists so that we can pull a string out of an object and not have it GC'ed while oterating over it */ mp_obj_t scrolling_string_image_iterable(const char* str, mp_uint_t len, mp_obj_t ref, bool monospace, bool repeat); #define SMALL_IMAGE(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p44) \ { \ { µbit_image_type }, \ 1, 0, 0, (p44), \ { \ (p0)|((p1)<<1)|((p2)<<2)|((p3)<<3)|((p4)<<4)|((p5)<<5)|((p6)<<6)|((p7)<<7), \ (p8)|((p9)<<1)|((p10)<<2)|((p11)<<3)|((p12)<<4)|((p13)<<5)|((p14)<<6)|((p15)<<7), \ (p16)|((p17)<<1)|((p18)<<2)|((p19)<<3)|((p20)<<4)|((p21)<<5)|((p22)<<6)|((p23)<<7) \ } \ } extern const monochrome_5by5_t microbit_blank_image; extern const monochrome_5by5_t microbit_const_image_heart_obj; extern const mp_obj_type_t microbit_image_type; #define BLANK_IMAGE (microbit_image_obj_t *)(µbit_blank_image) #define HEART_IMAGE (microbit_image_obj_t *)(µbit_const_image_heart_obj) #define HAPPY_IMAGE (microbit_image_obj_t *)(µbit_const_image_happy_obj) #if MICROPY_PY_BUILTINS_FLOAT microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_float_t fval); #else microbit_image_obj_t *microbit_image_dim(microbit_image_obj_t *lhs, mp_int_t val); #endif microbit_image_obj_t *microbit_image_sum(microbit_image_obj_t *lhs, microbit_image_obj_t *rhs, bool add); #endif // __MICROPY_INCLUDED_MICROBIT_IMAGE_H__