Skip to content

Commit 87a8af8

Browse files
committed
lib: pixel: Introduce a pixel and image processing library
The "pixel" library aims facilitating the implementation of all image processing tasks, such as pixel conversion, with a focus on low-resource environments. The processing functions scale down to per-pixel "kernels" to line-based conversion to full streams of several frames. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 0387bf8 commit 87a8af8

File tree

18 files changed

+3087
-0
lines changed

18 files changed

+3087
-0
lines changed

include/zephyr/pixel/bayer.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (c) 2025 tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_PIXEL_BAYER_H_
8+
#define ZEPHYR_INCLUDE_PIXEL_BAYER_H_
9+
10+
#include <stdint.h>
11+
#include <stdlib.h>
12+
13+
#include <zephyr/pixel/stream.h>
14+
15+
/**
16+
* @brief Convert a line from RGGB8 to RGB24 with 3x3 method
17+
*
18+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
19+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
20+
* @param i2 Buffer of the input row number 2 in bayer format (1 byte per pixel).
21+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
22+
* @param width Width of the lines in number of pixels.
23+
*/
24+
void pixel_rggb8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
25+
uint8_t *rgb24, uint16_t width);
26+
/**
27+
* @brief Convert a line from GRBG8 to RGB24 with 3x3 method
28+
* @copydetails pixel_rggb8line_to_rgb24line_3x3()
29+
*/
30+
void pixel_grbg8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
31+
uint8_t *rgb24, uint16_t width);
32+
/**
33+
* @brief Convert a line from BGGR8 to RGB24 with 3x3 method
34+
* @copydetails pixel_rggb8line_to_rgb24line_3x3()
35+
*/
36+
void pixel_bggr8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
37+
uint8_t *rgb24, uint16_t width);
38+
/**
39+
* @brief Convert a line from GBRG8 to RGB24 with 3x3 method
40+
* @copydetails pixel_rggb8line_to_rgb24line_3x3()
41+
*/
42+
void pixel_gbrg8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
43+
uint8_t *rgb24, uint16_t width);
44+
45+
/**
46+
* @brief Convert a line from RGGB8 to RGB24 with 2x2 method
47+
*
48+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
49+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
50+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
51+
* @param width Width of the lines in number of pixels.
52+
*/
53+
void pixel_rggb8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
54+
uint16_t width);
55+
/**
56+
* @brief Convert a line from GBRG8 to RGB24 with 2x2 method
57+
* @copydetails pixel_rggb8line_to_rgb24line_2x2()
58+
*/
59+
void pixel_gbrg8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
60+
uint16_t width);
61+
/**
62+
* @brief Convert a line from BGGR8 to RGB24 with 2x2 method
63+
* @copydetails pixel_rggb8line_to_rgb24line_2x2()
64+
*/
65+
void pixel_bggr8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
66+
uint16_t width);
67+
/**
68+
* @brief Convert a line from GRBG8 to RGB24 with 2x2 method
69+
* @copydetails pixel_rggb8line_to_rgb24line_2x2()
70+
*/
71+
void pixel_grbg8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
72+
uint16_t width);
73+
74+
/**
75+
* @brief Define a stream converter from RGGB8 to RGB24 with the 3x3 method
76+
*
77+
* @param name The symbol of the @ref pixel_stream that will be defined.
78+
* @param width The total width of the input frame in number of pixels.
79+
* @param height The total height of the input frame in number of pixels.
80+
*/
81+
#define PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3(name, width, height) \
82+
PIXEL_BAYER_DEFINE(name, pixel_rggb8stream_to_rgb24stream_3x3, (width), (height), 3)
83+
/**
84+
* @brief Define a stream converter from GRBG8 to RGB24 with the 3x3 method
85+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
86+
*/
87+
#define PIXEL_GRBG8STREAM_TO_RGB24STREAM_3X3(name, width, height) \
88+
PIXEL_BAYER_DEFINE(name, pixel_grbg8stream_to_rgb24stream_3x3, (width), (height), 3)
89+
/**
90+
* @brief Define a stream converter from BGGR8 to RGB24 with the 3x3 method
91+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
92+
*/
93+
#define PIXEL_BGGR8STREAM_TO_RGB24STREAM_3X3(name, width, height) \
94+
PIXEL_BAYER_DEFINE(name, pixel_bggr8stream_to_rgb24stream_3x3, (width), (height), 3)
95+
/**
96+
* @brief Define a stream converter from GBRG8 to RGB24 with the 3x3 method
97+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
98+
*/
99+
#define PIXEL_GBRG8STREAM_TO_RGB24STREAM_3X3(name, width, height) \
100+
PIXEL_BAYER_DEFINE(name, pixel_gbrg8stream_to_rgb24stream_3x3, (width), (height), 3)
101+
/**
102+
* @brief Define a stream converter from RGGB8 to RGB24 with the 2x2 method
103+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
104+
*/
105+
#define PIXEL_RGGB8STREAM_TO_RGB24STREAM_2X2(name, width, height) \
106+
PIXEL_BAYER_DEFINE(name, pixel_rggb8stream_to_rgb24stream_2x2, (width), (height), 2)
107+
/**
108+
* @brief Define a stream converter from GBRG8 to RGB24 with the 2x2 method
109+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
110+
*/
111+
#define PIXEL_GBRG8STREAM_TO_RGB24STREAM_2X2(name, width, height) \
112+
PIXEL_BAYER_DEFINE(name, pixel_gbrg8stream_to_rgb24stream_2x2, (width), (height), 2)
113+
/**
114+
* @brief Define a stream converter from BGGR8 to RGB24 with the 2x2 method
115+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
116+
*/
117+
#define PIXEL_BGGR8STREAM_TO_RGB24STREAM_2X2(name, width, height) \
118+
PIXEL_BAYER_DEFINE(name, pixel_bggr8stream_to_rgb24stream_2x2, (width), (height), 2)
119+
/**
120+
* @brief Define a stream converter from GRBG8 to RGB24 with the 2x2 method
121+
* @copydetails PIXEL_RGGB8STREAM_TO_RGB24STREAM_3X3()
122+
*/
123+
#define PIXEL_GRBG8STREAM_TO_RGB24STREAM_2X2(name, width, height) \
124+
PIXEL_BAYER_DEFINE(name, pixel_grbg8stream_to_rgb24stream_2x2, (width), (height), 2)
125+
126+
/** @cond INTERNAL_HIDDEN */
127+
#define PIXEL_BAYER_DEFINE(name, fn, width, height, window_height) \
128+
PIXEL_STREAM_DEFINE((name), (fn), (width), (height), (width), (window_height) * (width))
129+
void pixel_rggb8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
130+
void pixel_grbg8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
131+
void pixel_bggr8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
132+
void pixel_gbrg8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
133+
void pixel_rggb8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
134+
void pixel_gbrg8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
135+
void pixel_bggr8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
136+
void pixel_grbg8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
137+
/** @endcond */
138+
139+
#endif /* ZEPHYR_INCLUDE_PIXEL_BAYER_H_ */

include/zephyr/pixel/formats.h

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (c) 2025 tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_PIXEL_FORMATS_H_
8+
#define ZEPHYR_INCLUDE_PIXEL_FORMATS_H_
9+
10+
#include <stdlib.h>
11+
#include <stdint.h>
12+
13+
#include <zephyr/sys/util.h>
14+
#include <zephyr/sys/byteorder.h>
15+
#include <zephyr/pixel/stream.h>
16+
17+
/**
18+
* @brief Get the luminance (luma channel) of an RGB24 pixel.
19+
*
20+
* @param rgb24 Pointer to an RGB24 pixel: red, green, blue channels.
21+
*/
22+
uint8_t pixel_rgb24_get_luma_bt709(const uint8_t rgb24[3]);
23+
24+
/**
25+
* @brief Convert a line of pixel data from RGB332 to RGB24.
26+
*
27+
* See @ref video_pixel_formats for the definition of the input and output formats.
28+
*
29+
* @param src Buffer of the input line in the format, @c XXX in @c pixel_XXXline_to_YYYline().
30+
* @param dst Buffer of the output line in the format, @c YYY in @c pixel_XXXline_to_YYYline().
31+
* @param width Width of the lines in number of pixels.
32+
*/
33+
void pixel_rgb332line_to_rgb24line(const uint8_t *src, uint8_t *dst, uint16_t width);
34+
/**
35+
* @brief Convert a line of pixel data from RGB24 to RGB332 little-endian.
36+
* @copydetails pixel_rgb332line_to_rgb24line()
37+
*/
38+
void pixel_rgb24line_to_rgb332line(const uint8_t *src, uint8_t *dst, uint16_t width);
39+
/**
40+
* @brief Convert a line of pixel data from RGB565 little-endian to RGB24.
41+
* @copydetails pixel_rgb332line_to_rgb24line()
42+
*/
43+
void pixel_rgb565leline_to_rgb24line(const uint8_t *src, uint8_t *dst, uint16_t width);
44+
/**
45+
* @brief Convert a line of pixel data from RGB565 big-endian to RGB24.
46+
* @copydetails pixel_rgb332line_to_rgb24line()
47+
*/
48+
void pixel_rgb565beline_to_rgb24line(const uint8_t *src, uint8_t *dst, uint16_t width);
49+
/**
50+
* @brief Convert a line of pixel data from RGB24 to RGB565 little-endian.
51+
* @copydetails pixel_rgb332line_to_rgb24line()
52+
*/
53+
void pixel_rgb24line_to_rgb565leline(const uint8_t *src, uint8_t *dst, uint16_t width);
54+
/**
55+
* @brief Convert a line of pixel data from RGB24 to RGB565 big-endian.
56+
* @copydetails pixel_rgb332line_to_rgb24line()
57+
*/
58+
void pixel_rgb24line_to_rgb565beline(const uint8_t *src, uint8_t *dst, uint16_t width);
59+
/**
60+
* @brief Convert a line of pixel data from YUYV to RGB24 (BT.709 coefficients).
61+
* @copydetails pixel_rgb332line_to_rgb24line()
62+
*/
63+
void pixel_yuyvline_to_rgb24line_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
64+
/**
65+
* @brief Convert a line of pixel data from RGB24 to YUYV (BT.709 coefficients).
66+
* @copydetails pixel_rgb332line_to_rgb24line()
67+
*/
68+
void pixel_rgb24line_to_yuyvline_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
69+
/**
70+
* @brief Convert a line of pixel data from RGB24 to YUV24 (BT.709 coefficients).
71+
* @copydetails pixel_rgb332line_to_rgb24line()
72+
*/
73+
void pixel_rgb24line_to_yuv24line_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
74+
/**
75+
* @brief Convert a line of pixel data from YUV24 to RGB24 (BT.709 coefficients).
76+
* @copydetails pixel_rgb332line_to_rgb24line()
77+
*/
78+
void pixel_yuv24line_to_rgb24line_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
79+
/**
80+
* @brief Convert a line of pixel data from YUYV to YUV24
81+
* @copydetails pixel_rgb332line_to_rgb24line()
82+
*/
83+
void pixel_yuyvline_to_yuv24line(const uint8_t *src, uint8_t *dst, uint16_t width);
84+
/**
85+
* @brief Convert a line of pixel data from YUV24 to YUYV
86+
* @copydetails pixel_rgb332line_to_rgb24line()
87+
*/
88+
void pixel_yuv24line_to_yuyvline(const uint8_t *src, uint8_t *dst, uint16_t width);
89+
90+
/**
91+
* @brief Convert a stream of pixel data from RGB332 to RGB24.
92+
*
93+
* @param name The symbol of the @ref pixel_stream that will be defined.
94+
* @param width The total width of the input frame in number of pixels.
95+
* @param height The total height of the input frame in number of pixels.
96+
*/
97+
#define PIXEL_RGB332STREAM_TO_RGB24STREAM(name, width, height) \
98+
PIXEL_FORMAT_DEFINE(name, pixel_rgb332stream_to_rgb24stream, (width), (height), 1)
99+
/**
100+
* @brief Convert a stream of pixel data from RGB24 to RGB332
101+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
102+
*/
103+
#define PIXEL_RGB24STREAM_TO_RGB332STREAM(name, width, height) \
104+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb332stream, (width), (height), 3)
105+
/**
106+
* @brief Convert a stream of pixel data from RGB565 little-endian to RGB24
107+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
108+
*/
109+
#define PIXEL_RGB565LESTREAM_TO_RGB24STREAM(name, width, height) \
110+
PIXEL_FORMAT_DEFINE(name, pixel_rgb565lestream_to_rgb24stream, (width), (height), 2)
111+
/**
112+
* @brief Convert a stream of pixel data from RGB24 to RGB565 little-endian
113+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
114+
*/
115+
#define PIXEL_RGB24STREAM_TO_RGB565LESTREAM(name, width, height) \
116+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb565lestream, (width), (height), 3)
117+
/**
118+
* @brief Convert a stream of pixel data from RGB565 big-endian to RGB24
119+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
120+
*/
121+
#define PIXEL_RGB565BESTREAM_TO_RGB24STREAM(name, width, height) \
122+
PIXEL_FORMAT_DEFINE(name, pixel_rgb565bestream_to_rgb24stream, (width), (height), 2)
123+
/**
124+
* @brief Convert a stream of pixel data from RGB24 to RGB565 big-endian
125+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
126+
*/
127+
#define PIXEL_RGB24STREAM_TO_RGB565BESTREAM(name, width, height) \
128+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb565bestream, (width), (height), 3)
129+
/**
130+
* @brief Convert a stream of pixel data from YUYV to RGB24 (BT.709 coefficients)
131+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
132+
*/
133+
#define PIXEL_YUYVSTREAM_TO_RGB24STREAM_BT709(name, width, height) \
134+
PIXEL_FORMAT_DEFINE(name, pixel_yuyvstream_to_rgb24stream_bt709, (width), (height), 2)
135+
/**
136+
* @brief Convert a stream of pixel data from RGB24 to YUYV (BT.709 coefficients)
137+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
138+
*/
139+
#define PIXEL_RGB24STREAM_TO_YUYVSTREAM_BT709(name, width, height) \
140+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_yuyvstream_bt709, (width), (height), 3)
141+
/**
142+
* @brief Convert a stream of pixel data from YUV24 to RGB24 (BT.709 coefficients)
143+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
144+
*/
145+
#define PIXEL_YUV24STREAM_TO_RGB24STREAM_BT709(name, width, height) \
146+
PIXEL_FORMAT_DEFINE(name, pixel_yuv24stream_to_rgb24stream_bt709, (width), (height), 3)
147+
/**
148+
* @brief Convert a stream of pixel data from RGB24 to YUV24 (BT.709 coefficients)
149+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
150+
*/
151+
#define PIXEL_RGB24STREAM_TO_YUV24STREAM_BT709(name, width, height) \
152+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_yuv24stream_bt709, (width), (height), 3)
153+
/**
154+
* @brief Convert a stream of pixel data from YUYV to YUV24
155+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
156+
*/
157+
#define PIXEL_YUYVSTREAM_TO_YUV24STREAM(name, width, height) \
158+
PIXEL_FORMAT_DEFINE(name, pixel_yuyvstream_to_yuv24stream, (width), (height), 2)
159+
/**
160+
* @brief Convert a stream of pixel data from YUV24 to YUYV
161+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
162+
*/
163+
#define PIXEL_YUV24STREAM_TO_YUYVSTREAM(name, width, height) \
164+
PIXEL_FORMAT_DEFINE(name, pixel_yuv24stream_to_yuyvstream, (width), (height), 3)
165+
166+
/** @cond INTERNAL_HIDDEN */
167+
#define PIXEL_FORMAT_DEFINE(name, fn, width, height, bytes_per_pixel) \
168+
PIXEL_STREAM_DEFINE(name, (fn), (width), (height), \
169+
(width) * (bytes_per_pixel), 1 * (width) * (bytes_per_pixel))
170+
void pixel_rgb24stream_to_rgb332stream(struct pixel_stream *strm);
171+
void pixel_rgb332stream_to_rgb24stream(struct pixel_stream *strm);
172+
void pixel_rgb565lestream_to_rgb24stream(struct pixel_stream *strm);
173+
void pixel_rgb24stream_to_rgb565lestream(struct pixel_stream *strm);
174+
void pixel_rgb565bestream_to_rgb24stream(struct pixel_stream *strm);
175+
void pixel_rgb24stream_to_rgb565bestream(struct pixel_stream *strm);
176+
void pixel_yuyvstream_to_rgb24stream_bt709(struct pixel_stream *strm);
177+
void pixel_rgb24stream_to_yuyvstream_bt709(struct pixel_stream *strm);
178+
void pixel_yuv24stream_to_rgb24stream_bt709(struct pixel_stream *strm);
179+
void pixel_rgb24stream_to_yuv24stream_bt709(struct pixel_stream *strm);
180+
void pixel_yuyvstream_to_yuv24stream(struct pixel_stream *strm);
181+
void pixel_yuv24stream_to_yuyvstream(struct pixel_stream *strm);
182+
/** @endcond */
183+
184+
#endif /* ZEPHYR_INCLUDE_PIXEL_FORMATS_H_ */

0 commit comments

Comments
 (0)