@@ -94,6 +94,7 @@ static void scratch_bitmap16(displayio_bitmap_t *buf, int rows, int cols) {
9494 ((rowptr)[(x)] = __builtin_bswap16((val)))
9595#define COLOR_R5_G6_B5_TO_RGB565 (r , g , b ) \
9696 (((r) << 11) | ((g) << 5) | (b))
97+ #define COLOR_R8_G8_B8_TO_RGB565 (r8 , g8 , b8 ) ((((r8) & 0xF8) << 8) | (((g8) & 0xFC) << 3) | ((b8) >> 3))
9798
9899#define COLOR_RGB565_TO_R5 (pixel ) (((pixel) >> 11) & 0x1F)
99100#define COLOR_RGB565_TO_R8 (pixel ) \
@@ -121,6 +122,12 @@ static void scratch_bitmap16(displayio_bitmap_t *buf, int rows, int cols) {
121122#define COLOR_R5_MAX (0x1F)
122123#define COLOR_G6_MAX (0x3F)
123124#define COLOR_B5_MAX (0x1F)
125+ #define COLOR_R8_MIN 0
126+ #define COLOR_R8_MAX 255
127+ #define COLOR_G8_MIN 0
128+ #define COLOR_G8_MAX 255
129+ #define COLOR_B8_MIN 0
130+ #define COLOR_B8_MAX 255
124131
125132#define COLOR_RGB565_BINARY_MAX (0xffff)
126133#define COLOR_RGB565_BINARY_MIN (0x0000)
@@ -135,6 +142,40 @@ static void scratch_bitmap16(displayio_bitmap_t *buf, int rows, int cols) {
135142 COLOR_RGB888_TO_Y(r, g, b); \
136143 })
137144
145+ #define COLOR_RGB888_TO_U (r8 , g8 , b8 ) ((((r8) * -21) - ((g8) * 43) + ((b8) * 64)) >> 7) // -0.168736R - 0.331264G + 0.5B
146+ #define COLOR_RGB565_TO_U (rgb565 ) \
147+ ({ \
148+ __typeof__ (rgb565) __rgb565 = (rgb565); \
149+ int r = COLOR_RGB565_TO_R8(__rgb565); \
150+ int g = COLOR_RGB565_TO_G8(__rgb565); \
151+ int b = COLOR_RGB565_TO_B8(__rgb565); \
152+ COLOR_RGB888_TO_U(r, g, b); \
153+ })
154+
155+ #define COLOR_RGB888_TO_V (r8 , g8 , b8 ) ((((r8) * 64) - ((g8) * 54) - ((b8) * 10)) >> 7) // 0.5R - 0.418688G - 0.081312B
156+ #define COLOR_RGB565_TO_V (rgb565 ) \
157+ ({ \
158+ __typeof__ (rgb565) __rgb565 = (rgb565); \
159+ int r = COLOR_RGB565_TO_R8(__rgb565); \
160+ int g = COLOR_RGB565_TO_G8(__rgb565); \
161+ int b = COLOR_RGB565_TO_B8(__rgb565); \
162+ COLOR_RGB888_TO_V(r, g, b); \
163+ })
164+
165+ // https://en.wikipedia.org/wiki/YCbCr -> JPEG Conversion
166+ STATIC uint16_t imlib_yuv_to_rgb (uint8_t y , int8_t u , int8_t v ) {
167+ uint32_t r = IM_MAX (IM_MIN (y + ((91881 * v ) >> 16 ), COLOR_R8_MAX ), COLOR_R8_MIN );
168+ uint32_t g = IM_MAX (IM_MIN (y - (((22554 * u ) + (46802 * v )) >> 16 ), COLOR_G8_MAX ), COLOR_G8_MIN );
169+ uint32_t b = IM_MAX (IM_MIN (y + ((116130 * u ) >> 16 ), COLOR_B8_MAX ), COLOR_B8_MIN );
170+
171+ return COLOR_R8_G8_B8_TO_RGB565 (r , g , b );
172+ }
173+
174+ // CIRCUITPY-CHANGE (vs openmv): an offset is removed so that the Y value is the
175+ // same as from COLOR_RGB565_TO_Y.
176+ #define COLOR_YUV_TO_RGB565 (y , u , v ) imlib_yuv_to_rgb((y), u, v)
177+
178+
138179void shared_module_bitmapfilter_morph (
139180 displayio_bitmap_t * bitmap ,
140181 displayio_bitmap_t * mask ,
@@ -333,12 +374,12 @@ void shared_module_bitmapfilter_solarize(
333374 continue ; // Short circuit.
334375 }
335376 int pixel = IMAGE_GET_RGB565_PIXEL_FAST (row_ptr , x );
336- if ( COLOR_RGB565_TO_Y (pixel ) > threshold_i ) {
337- int r = COLOR_R5_MAX - COLOR_RGB565_TO_R5 ( pixel );
338- int g = COLOR_G6_MAX - COLOR_RGB565_TO_G6 ( pixel );
339- int b = COLOR_B5_MAX - COLOR_RGB565_TO_B5 (pixel );
340-
341- pixel = COLOR_R5_G6_B5_TO_RGB565 ( r , g , b );
377+ int y = COLOR_RGB565_TO_Y (pixel );
378+ if ( y > threshold_i ) {
379+ y = MIN ( 255 , MAX ( 0 , 2 * threshold_i - y ) );
380+ int u = COLOR_RGB565_TO_U (pixel );
381+ int v = COLOR_RGB565_TO_V ( pixel );
382+ pixel = COLOR_YUV_TO_RGB565 ( y , u , v );
342383 IMAGE_PUT_RGB565_PIXEL_FAST (row_ptr , x , pixel );
343384 }
344385 }
0 commit comments