|
|
|
@ -28,7 +28,19 @@
|
|
|
|
|
|
|
|
|
|
#include "py/misc.h"
|
|
|
|
|
|
|
|
|
|
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) {
|
|
|
|
|
uint32_t displayio_colorconverter_dither_noise_1 (uint32_t n)
|
|
|
|
|
{
|
|
|
|
|
n = (n >> 13) ^ n;
|
|
|
|
|
int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
|
|
|
|
|
return (uint32_t) (((float)nn / (1073741824.0f*2)) * 255);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y) {
|
|
|
|
|
return displayio_colorconverter_dither_noise_1(x + y * 0xFFFF);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self, bool dither) {
|
|
|
|
|
self->dither = dither;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) {
|
|
|
|
@ -96,33 +108,80 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* co
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
|
|
|
|
|
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
|
|
|
|
|
displayio_input_pixel_t input_pixel;
|
|
|
|
|
input_pixel.pixel = input_color;
|
|
|
|
|
input_pixel.x = input_pixel.y = input_pixel.tile = input_pixel.tile_x = input_pixel.tile_y = 0;
|
|
|
|
|
|
|
|
|
|
displayio_output_pixel_t output_pixel;
|
|
|
|
|
output_pixel.pixel = 0;
|
|
|
|
|
output_pixel.opaque = false;
|
|
|
|
|
|
|
|
|
|
displayio_colorconverter_convert(self, colorspace, &input_pixel, &output_pixel);
|
|
|
|
|
|
|
|
|
|
(*output_color) = output_pixel.pixel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void common_hal_displayio_colorconverter_set_dither(displayio_colorconverter_t* self, bool dither) {
|
|
|
|
|
self->dither = dither;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool common_hal_displayio_colorconverter_get_dither(displayio_colorconverter_t* self) {
|
|
|
|
|
return self->dither;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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->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));
|
|
|
|
|
uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y+33));
|
|
|
|
|
|
|
|
|
|
uint32_t r8 = (pixel >> 16);
|
|
|
|
|
uint32_t g8 = (pixel >> 8) & 0xff;
|
|
|
|
|
uint32_t b8 = pixel & 0xff;
|
|
|
|
|
|
|
|
|
|
if (colorspace->depth == 16) {
|
|
|
|
|
b8 = MIN(255,b8 + (randb&0x07));
|
|
|
|
|
r8 = MIN(255,r8 + (randr&0x07));
|
|
|
|
|
g8 = MIN(255,g8 + (randg&0x03));
|
|
|
|
|
} else {
|
|
|
|
|
int bitmask = 0xFF >> colorspace->depth;
|
|
|
|
|
b8 = MIN(255,b8 + (randb&bitmask));
|
|
|
|
|
r8 = MIN(255,r8 + (randr&bitmask));
|
|
|
|
|
g8 = MIN(255,g8 + (randg&bitmask));
|
|
|
|
|
}
|
|
|
|
|
pixel = r8 << 16 | g8 << 8 | b8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (colorspace->depth == 16) {
|
|
|
|
|
*output_color = displayio_colorconverter_compute_rgb565(input_color);
|
|
|
|
|
return true;
|
|
|
|
|
output_color->pixel = displayio_colorconverter_compute_rgb565(pixel);
|
|
|
|
|
output_color->opaque = true;
|
|
|
|
|
return;
|
|
|
|
|
} else if (colorspace->tricolor) {
|
|
|
|
|
uint8_t luma = displayio_colorconverter_compute_luma(input_color);
|
|
|
|
|
*output_color = luma >> (8 - colorspace->depth);
|
|
|
|
|
if (displayio_colorconverter_compute_chroma(input_color) <= 16) {
|
|
|
|
|
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
|
|
|
|
output_color->pixel = luma >> (8 - colorspace->depth);
|
|
|
|
|
if (displayio_colorconverter_compute_chroma(pixel) <= 16) {
|
|
|
|
|
if (!colorspace->grayscale) {
|
|
|
|
|
*output_color = 0;
|
|
|
|
|
output_color->pixel = 0;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
output_color->opaque = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
uint8_t pixel_hue = displayio_colorconverter_compute_hue(input_color);
|
|
|
|
|
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, output_color);
|
|
|
|
|
return true;
|
|
|
|
|
} else if (colorspace->grayscale && colorspace->depth <= 8) {
|
|
|
|
|
uint8_t luma = displayio_colorconverter_compute_luma(input_color);
|
|
|
|
|
*output_color = luma >> (8 - colorspace->depth);
|
|
|
|
|
return true;
|
|
|
|
|
uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel);
|
|
|
|
|
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, &output_color->pixel);
|
|
|
|
|
return;
|
|
|
|
|
} else if (colorspace->grayscale && colorspace->depth <= 8) {
|
|
|
|
|
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
|
|
|
|
|
output_color->pixel = luma >> (8 - colorspace->depth);
|
|
|
|
|
output_color->opaque = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
output_color->opaque = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
|
|
|
|
|
displayio_colorconverter_convert(self, colorspace, input_color, output_color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Currently no refresh logic is needed for a ColorConverter.
|
|
|
|
|
bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) {
|
|
|
|
@ -131,3 +190,4 @@ bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) {
|
|
|
|
|
|
|
|
|
|
void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|