Skip to content

Commit ccc85f8

Browse files
committed
bitmapfilter: factor out macros
.. they will be used in uvc to do rgb->yuyv conversion
1 parent 3615745 commit ccc85f8

File tree

2 files changed

+106
-90
lines changed

2 files changed

+106
-90
lines changed

shared-module/bitmapfilter/__init__.c

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "shared-bindings/displayio/Palette.h"
1717
#include "shared-bindings/bitmapfilter/__init__.h"
1818
#include "shared-module/bitmapfilter/__init__.h"
19+
#include "shared-module/bitmapfilter/macros.h"
1920

2021
#if defined(UNIX)
2122
#include <stdlib.h>
@@ -79,104 +80,15 @@ static void scratch_bitmap16(displayio_bitmap_t *buf, int rows, int cols) {
7980
buf->data = data;
8081
}
8182

82-
#define IM_MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
83-
#define IM_MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
84-
#define IM_DIV(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; })
85-
#define IM_MOD(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; })
86-
87-
#define IMAGE_RGB565_LINE_LEN_BYTES(bitmap) \
88-
((bitmap)->width * 2)
89-
90-
#define IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(bitmap, y) \
91-
(uint16_t *)(&(bitmap)->data[(bitmap)->stride * (y)])
92-
#define IMAGE_GET_RGB565_PIXEL_FAST(rowptr, x) \
93-
__builtin_bswap16((rowptr)[(x)])
94-
#define IMAGE_PUT_RGB565_PIXEL_FAST(rowptr, x, val) \
95-
((rowptr)[(x)] = __builtin_bswap16((val)))
96-
#define COLOR_R5_G6_B5_TO_RGB565(r, g, b) \
97-
(((r) << 11) | ((g) << 5) | (b))
98-
#define COLOR_R8_G8_B8_TO_RGB565(r8, g8, b8) ((((r8) & 0xF8) << 8) | (((g8) & 0xFC) << 3) | ((b8) >> 3))
99-
100-
#define COLOR_RGB565_TO_R5(pixel) (((pixel) >> 11) & 0x1F)
101-
#define COLOR_RGB565_TO_R8(pixel) \
102-
({ \
103-
__typeof__ (pixel) __pixel = (pixel); \
104-
__pixel = (__pixel >> 8) & 0xF8; \
105-
__pixel | (__pixel >> 5); \
106-
})
107-
108-
#define COLOR_RGB565_TO_G6(pixel) (((pixel) >> 5) & 0x3F)
109-
#define COLOR_RGB565_TO_G8(pixel) \
110-
({ \
111-
__typeof__ (pixel) __pixel = (pixel); \
112-
__pixel = (__pixel >> 3) & 0xFC; \
113-
__pixel | (__pixel >> 6); \
114-
})
115-
116-
#define COLOR_RGB565_TO_B5(pixel) ((pixel) & 0x1F)
117-
#define COLOR_RGB565_TO_B8(pixel) \
118-
({ \
119-
__typeof__ (pixel) __pixel = (pixel); \
120-
__pixel = (__pixel << 3) & 0xF8; \
121-
__pixel | (__pixel >> 5); \
122-
})
123-
#define COLOR_R5_MAX (0x1F)
124-
#define COLOR_G6_MAX (0x3F)
125-
#define COLOR_B5_MAX (0x1F)
126-
#define COLOR_R8_MIN 0
127-
#define COLOR_R8_MAX 255
128-
#define COLOR_G8_MIN 0
129-
#define COLOR_G8_MAX 255
130-
#define COLOR_B8_MIN 0
131-
#define COLOR_B8_MAX 255
132-
133-
#define COLOR_RGB565_BINARY_MAX (0xffff)
134-
#define COLOR_RGB565_BINARY_MIN (0x0000)
135-
136-
#define COLOR_RGB888_TO_Y(r8, g8, b8) ((((r8) * 38) + ((g8) * 75) + ((b8) * 15)) >> 7) // 0.299R + 0.587G + 0.114B
137-
#define COLOR_RGB565_TO_Y(rgb565) \
138-
({ \
139-
__typeof__ (rgb565) __rgb565 = (rgb565); \
140-
int r = COLOR_RGB565_TO_R8(__rgb565); \
141-
int g = COLOR_RGB565_TO_G8(__rgb565); \
142-
int b = COLOR_RGB565_TO_B8(__rgb565); \
143-
COLOR_RGB888_TO_Y(r, g, b); \
144-
})
145-
146-
#define COLOR_RGB888_TO_U(r8, g8, b8) ((((r8) * -21) - ((g8) * 43) + ((b8) * 64)) >> 7) // -0.168736R - 0.331264G + 0.5B
147-
#define COLOR_RGB565_TO_U(rgb565) \
148-
({ \
149-
__typeof__ (rgb565) __rgb565 = (rgb565); \
150-
int r = COLOR_RGB565_TO_R8(__rgb565); \
151-
int g = COLOR_RGB565_TO_G8(__rgb565); \
152-
int b = COLOR_RGB565_TO_B8(__rgb565); \
153-
COLOR_RGB888_TO_U(r, g, b); \
154-
})
155-
156-
#define COLOR_RGB888_TO_V(r8, g8, b8) ((((r8) * 64) - ((g8) * 54) - ((b8) * 10)) >> 7) // 0.5R - 0.418688G - 0.081312B
157-
#define COLOR_RGB565_TO_V(rgb565) \
158-
({ \
159-
__typeof__ (rgb565) __rgb565 = (rgb565); \
160-
int r = COLOR_RGB565_TO_R8(__rgb565); \
161-
int g = COLOR_RGB565_TO_G8(__rgb565); \
162-
int b = COLOR_RGB565_TO_B8(__rgb565); \
163-
COLOR_RGB888_TO_V(r, g, b); \
164-
})
165-
16683
// https://en.wikipedia.org/wiki/YCbCr -> JPEG Conversion
167-
STATIC uint16_t imlib_yuv_to_rgb(uint8_t y, int8_t u, int8_t v) {
84+
uint16_t imlib_yuv_to_rgb(uint8_t y, int8_t u, int8_t v) {
16885
uint32_t r = IM_MAX(IM_MIN(y + ((91881 * v) >> 16), COLOR_R8_MAX), COLOR_R8_MIN);
16986
uint32_t g = IM_MAX(IM_MIN(y - (((22554 * u) + (46802 * v)) >> 16), COLOR_G8_MAX), COLOR_G8_MIN);
17087
uint32_t b = IM_MAX(IM_MIN(y + ((116130 * u) >> 16), COLOR_B8_MAX), COLOR_B8_MIN);
17188

17289
return COLOR_R8_G8_B8_TO_RGB565(r, g, b);
17390
}
17491

175-
// CIRCUITPY-CHANGE (vs openmv): an offset is removed so that the Y value is the
176-
// same as from COLOR_RGB565_TO_Y.
177-
#define COLOR_YUV_TO_RGB565(y, u, v) imlib_yuv_to_rgb((y), u, v)
178-
179-
18092
void shared_module_bitmapfilter_morph(
18193
displayio_bitmap_t *bitmap,
18294
displayio_bitmap_t *mask,
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
3+
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
4+
* Copyright (c) 2024 Jeff Epler for Adafruit Industries
5+
*
6+
* This work is licensed under the MIT license, see the file LICENSE for details.
7+
* Adapted from https://github.com/openmv/openmv/blob/master/bitmap/omv/imlib/filter.c#L2083
8+
*/
9+
10+
11+
#pragma once
12+
13+
// Triggered by use of IM_MIN(IM_MAX(...)); this is a spurious diagnostic.
14+
#pragma GCC diagnostic ignored "-Wshadow"
15+
16+
#define IM_MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
17+
#define IM_MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
18+
#define IM_DIV(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; })
19+
#define IM_MOD(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; })
20+
21+
#define IMAGE_RGB565_LINE_LEN_BYTES(bitmap) \
22+
((bitmap)->width * 2)
23+
24+
#define IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(bitmap, y) \
25+
(uint16_t *)(&(bitmap)->data[(bitmap)->stride * (y)])
26+
#define IMAGE_GET_RGB565_PIXEL_FAST(rowptr, x) \
27+
__builtin_bswap16((rowptr)[(x)])
28+
#define IMAGE_PUT_RGB565_PIXEL_FAST(rowptr, x, val) \
29+
((rowptr)[(x)] = __builtin_bswap16((val)))
30+
#define COLOR_R5_G6_B5_TO_RGB565(r, g, b) \
31+
(((r) << 11) | ((g) << 5) | (b))
32+
#define COLOR_R8_G8_B8_TO_RGB565(r8, g8, b8) ((((r8) & 0xF8) << 8) | (((g8) & 0xFC) << 3) | ((b8) >> 3))
33+
34+
#define COLOR_RGB565_TO_R5(pixel) (((pixel) >> 11) & 0x1F)
35+
#define COLOR_RGB565_TO_R8(pixel) \
36+
({ \
37+
__typeof__ (pixel) __pixel = (pixel); \
38+
__pixel = (__pixel >> 8) & 0xF8; \
39+
__pixel | (__pixel >> 5); \
40+
})
41+
42+
#define COLOR_RGB565_TO_G6(pixel) (((pixel) >> 5) & 0x3F)
43+
#define COLOR_RGB565_TO_G8(pixel) \
44+
({ \
45+
__typeof__ (pixel) __pixel = (pixel); \
46+
__pixel = (__pixel >> 3) & 0xFC; \
47+
__pixel | (__pixel >> 6); \
48+
})
49+
50+
#define COLOR_RGB565_TO_B5(pixel) ((pixel) & 0x1F)
51+
#define COLOR_RGB565_TO_B8(pixel) \
52+
({ \
53+
__typeof__ (pixel) __pixel = (pixel); \
54+
__pixel = (__pixel << 3) & 0xF8; \
55+
__pixel | (__pixel >> 5); \
56+
})
57+
#define COLOR_R5_MAX (0x1F)
58+
#define COLOR_G6_MAX (0x3F)
59+
#define COLOR_B5_MAX (0x1F)
60+
#define COLOR_R8_MIN 0
61+
#define COLOR_R8_MAX 255
62+
#define COLOR_G8_MIN 0
63+
#define COLOR_G8_MAX 255
64+
#define COLOR_B8_MIN 0
65+
#define COLOR_B8_MAX 255
66+
67+
#define COLOR_RGB565_BINARY_MAX (0xffff)
68+
#define COLOR_RGB565_BINARY_MIN (0x0000)
69+
70+
#define COLOR_RGB888_TO_Y(r8, g8, b8) ((((r8) * 38) + ((g8) * 75) + ((b8) * 15)) >> 7) // 0.299R + 0.587G + 0.114B
71+
#define COLOR_RGB565_TO_Y(rgb565) \
72+
({ \
73+
__typeof__ (rgb565) __rgb565 = (rgb565); \
74+
int r = COLOR_RGB565_TO_R8(__rgb565); \
75+
int g = COLOR_RGB565_TO_G8(__rgb565); \
76+
int b = COLOR_RGB565_TO_B8(__rgb565); \
77+
COLOR_RGB888_TO_Y(r, g, b); \
78+
})
79+
80+
#define COLOR_RGB888_TO_U(r8, g8, b8) ((((r8) * -21) - ((g8) * 43) + ((b8) * 64)) >> 7) // -0.168736R - 0.331264G + 0.5B
81+
#define COLOR_RGB565_TO_U(rgb565) \
82+
({ \
83+
__typeof__ (rgb565) __rgb565 = (rgb565); \
84+
int r = COLOR_RGB565_TO_R8(__rgb565); \
85+
int g = COLOR_RGB565_TO_G8(__rgb565); \
86+
int b = COLOR_RGB565_TO_B8(__rgb565); \
87+
COLOR_RGB888_TO_U(r, g, b); \
88+
})
89+
90+
#define COLOR_RGB888_TO_V(r8, g8, b8) ((((r8) * 64) - ((g8) * 54) - ((b8) * 10)) >> 7) // 0.5R - 0.418688G - 0.081312B
91+
#define COLOR_RGB565_TO_V(rgb565) \
92+
({ \
93+
__typeof__ (rgb565) __rgb565 = (rgb565); \
94+
int r = COLOR_RGB565_TO_R8(__rgb565); \
95+
int g = COLOR_RGB565_TO_G8(__rgb565); \
96+
int b = COLOR_RGB565_TO_B8(__rgb565); \
97+
COLOR_RGB888_TO_V(r, g, b); \
98+
})
99+
100+
uint16_t imlib_yuv_to_rgb(uint8_t y, int8_t u, int8_t v);
101+
102+
// CIRCUITPY-CHANGE (vs openmv): an offset is removed so that the Y value is the
103+
// same as from COLOR_RGB565_TO_Y.
104+
#define COLOR_YUV_TO_RGB565(y, u, v) imlib_yuv_to_rgb((y), u, v)

0 commit comments

Comments
 (0)