2828
2929#include "py/misc.h"
3030
31- void common_hal_displayio_colorconverter_construct (displayio_colorconverter_t * self ) {
31+ uint32_t displayio_colorconverter_dither_noise_1 (uint32_t n )
32+ {
33+ n = (n >> 13 ) ^ n ;
34+ int nn = (n * (n * n * 60493 + 19990303 ) + 1376312589 ) & 0x7fffffff ;
35+ return (uint32_t ) (((float )nn / (1073741824.0f * 2 )) * 255 );
36+ }
37+
38+ uint32_t displayio_colorconverter_dither_noise_2 (uint32_t x , uint32_t y ) {
39+ return displayio_colorconverter_dither_noise_1 (x + y * 0xFFFF );
40+ }
41+
42+ void common_hal_displayio_colorconverter_construct (displayio_colorconverter_t * self , bool dither ) {
43+ self -> dither = dither ;
3244}
3345
3446uint16_t displayio_colorconverter_compute_rgb565 (uint32_t color_rgb888 ) {
@@ -96,33 +108,80 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* co
96108 }
97109}
98110
99- bool displayio_colorconverter_convert (displayio_colorconverter_t * self , const _displayio_colorspace_t * colorspace , uint32_t input_color , uint32_t * output_color ) {
111+ void common_hal_displayio_colorconverter_convert (displayio_colorconverter_t * self , const _displayio_colorspace_t * colorspace , uint32_t input_color , uint32_t * output_color ) {
112+ displayio_input_pixel_t input_pixel ;
113+ input_pixel .pixel = input_color ;
114+ input_pixel .x = input_pixel .y = input_pixel .tile = input_pixel .tile_x = input_pixel .tile_y = 0 ;
115+
116+ displayio_output_pixel_t output_pixel ;
117+ output_pixel .pixel = 0 ;
118+ output_pixel .opaque = false;
119+
120+ displayio_colorconverter_convert (self , colorspace , & input_pixel , & output_pixel );
121+
122+ (* output_color ) = output_pixel .pixel ;
123+ }
124+
125+ void common_hal_displayio_colorconverter_set_dither (displayio_colorconverter_t * self , bool dither ) {
126+ self -> dither = dither ;
127+ }
128+
129+ bool common_hal_displayio_colorconverter_get_dither (displayio_colorconverter_t * self ) {
130+ return self -> dither ;
131+ }
132+
133+ 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 ) {
134+ uint32_t pixel = input_pixel -> pixel ;
135+
136+ if (self -> dither ){
137+ uint8_t randr = (displayio_colorconverter_dither_noise_2 (input_pixel -> tile_x ,input_pixel -> tile_y ));
138+ uint8_t randg = (displayio_colorconverter_dither_noise_2 (input_pixel -> tile_x + 33 ,input_pixel -> tile_y ));
139+ uint8_t randb = (displayio_colorconverter_dither_noise_2 (input_pixel -> tile_x ,input_pixel -> tile_y + 33 ));
140+
141+ uint32_t r8 = (pixel >> 16 );
142+ uint32_t g8 = (pixel >> 8 ) & 0xff ;
143+ uint32_t b8 = pixel & 0xff ;
144+
145+ if (colorspace -> depth == 16 ) {
146+ b8 = MIN (255 ,b8 + (randb & 0x07 ));
147+ r8 = MIN (255 ,r8 + (randr & 0x07 ));
148+ g8 = MIN (255 ,g8 + (randg & 0x03 ));
149+ } else {
150+ int bitmask = 0xFF >> colorspace -> depth ;
151+ b8 = MIN (255 ,b8 + (randb & bitmask ));
152+ r8 = MIN (255 ,r8 + (randr & bitmask ));
153+ g8 = MIN (255 ,g8 + (randg & bitmask ));
154+ }
155+ pixel = r8 << 16 | g8 << 8 | b8 ;
156+ }
157+
100158 if (colorspace -> depth == 16 ) {
101- * output_color = displayio_colorconverter_compute_rgb565 (input_color );
102- return true;
159+ output_color -> pixel = displayio_colorconverter_compute_rgb565 (pixel );
160+ output_color -> opaque = true;
161+ return ;
103162 } else if (colorspace -> tricolor ) {
104- uint8_t luma = displayio_colorconverter_compute_luma (input_color );
105- * output_color = luma >> (8 - colorspace -> depth );
106- if (displayio_colorconverter_compute_chroma (input_color ) <= 16 ) {
163+ uint8_t luma = displayio_colorconverter_compute_luma (pixel );
164+ output_color -> pixel = luma >> (8 - colorspace -> depth );
165+ if (displayio_colorconverter_compute_chroma (pixel ) <= 16 ) {
107166 if (!colorspace -> grayscale ) {
108- * output_color = 0 ;
167+ output_color -> pixel = 0 ;
109168 }
110- return true;
169+ output_color -> opaque = true;
170+ return ;
111171 }
112- uint8_t pixel_hue = displayio_colorconverter_compute_hue (input_color );
113- displayio_colorconverter_compute_tricolor (colorspace , pixel_hue , luma , output_color );
114- return true;
115- } else if (colorspace -> grayscale && colorspace -> depth <= 8 ) {
116- uint8_t luma = displayio_colorconverter_compute_luma (input_color );
117- * output_color = luma >> (8 - colorspace -> depth );
118- return true;
172+ uint8_t pixel_hue = displayio_colorconverter_compute_hue (pixel );
173+ displayio_colorconverter_compute_tricolor (colorspace , pixel_hue , luma , & output_color -> pixel );
174+ return ;
175+ } else if (colorspace -> grayscale && colorspace -> depth <= 8 ) {
176+ uint8_t luma = displayio_colorconverter_compute_luma (pixel );
177+ output_color -> pixel = luma >> (8 - colorspace -> depth );
178+ output_color -> opaque = true;
179+ return ;
119180 }
120- return false;
181+ output_color -> opaque = false;
121182}
122183
123- void common_hal_displayio_colorconverter_convert (displayio_colorconverter_t * self , const _displayio_colorspace_t * colorspace , uint32_t input_color , uint32_t * output_color ) {
124- displayio_colorconverter_convert (self , colorspace , input_color , output_color );
125- }
184+
126185
127186// Currently no refresh logic is needed for a ColorConverter.
128187bool displayio_colorconverter_needs_refresh (displayio_colorconverter_t * self ) {
@@ -131,3 +190,4 @@ bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self) {
131190
132191void displayio_colorconverter_finish_refresh (displayio_colorconverter_t * self ) {
133192}
193+
0 commit comments