Skip to content

Commit 715a8b0

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 715a8b0

File tree

18 files changed

+2971
-0
lines changed

18 files changed

+2971
-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: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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+
/**
71+
* @brief Convert a stream of pixel data from RGB332 to RGB24.
72+
*
73+
* @param name The symbol of the @ref pixel_stream that will be defined.
74+
* @param width The total width of the input frame in number of pixels.
75+
* @param height The total height of the input frame in number of pixels.
76+
*/
77+
#define PIXEL_RGB332STREAM_TO_RGB24STREAM(name, width, height) \
78+
PIXEL_FORMAT_DEFINE(name, pixel_rgb332stream_to_rgb24stream, (width), (height), 1)
79+
/**
80+
* @brief Convert a stream of pixel data from RGB24 to RGB332
81+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
82+
*/
83+
#define PIXEL_RGB24STREAM_TO_RGB332STREAM(name, width, height) \
84+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb332stream, (width), (height), 3)
85+
/**
86+
* @brief Convert a stream of pixel data from RGB565 little-endian to RGB24
87+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
88+
*/
89+
#define PIXEL_RGB565LESTREAM_TO_RGB24STREAM(name, width, height) \
90+
PIXEL_FORMAT_DEFINE(name, pixel_rgb565lestream_to_rgb24stream, (width), (height), 2)
91+
/**
92+
* @brief Convert a stream of pixel data from RGB24 to RGB565 little-endian
93+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
94+
*/
95+
#define PIXEL_RGB24STREAM_TO_RGB565LESTREAM(name, width, height) \
96+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb565lestream, (width), (height), 3)
97+
/**
98+
* @brief Convert a stream of pixel data from RGB565 big-endian to RGB24
99+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
100+
*/
101+
#define PIXEL_RGB565BESTREAM_TO_RGB24STREAM(name, width, height) \
102+
PIXEL_FORMAT_DEFINE(name, pixel_rgb565bestream_to_rgb24stream, (width), (height), 2)
103+
/**
104+
* @brief Convert a stream of pixel data from RGB24 to RGB565 big-endian
105+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
106+
*/
107+
#define PIXEL_RGB24STREAM_TO_RGB565BESTREAM(name, width, height) \
108+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_rgb565bestream, (width), (height), 3)
109+
/**
110+
* @brief Convert a stream of pixel data from YUYV to RGB24 (BT.709 coefficients)
111+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
112+
*/
113+
#define PIXEL_YUYVSTREAM_TO_RGB24STREAM_BT709(name, width, height) \
114+
PIXEL_FORMAT_DEFINE(name, pixel_yuyvstream_to_rgb24stream_bt709, (width), (height), 2)
115+
/**
116+
* @brief Convert a stream of pixel data from RGB24 to YUYV (BT.709 coefficients)
117+
* @copydetails PIXEL_RGB332STREAM_TO_RGB24STREAM()
118+
*/
119+
#define PIXEL_RGB24STREAM_TO_YUYVSTREAM_BT709(name, width, height) \
120+
PIXEL_FORMAT_DEFINE(name, pixel_rgb24stream_to_yuyvstream_bt709, (width), (height), 3)
121+
122+
/** @cond INTERNAL_HIDDEN */
123+
#define PIXEL_FORMAT_DEFINE(name, fn, width, height, bytes_per_pixel) \
124+
PIXEL_STREAM_DEFINE(name, (fn), (width), (height), \
125+
(width) * (bytes_per_pixel), 1 * (width) * (bytes_per_pixel))
126+
void pixel_rgb24stream_to_rgb332stream(struct pixel_stream *strm);
127+
void pixel_rgb332stream_to_rgb24stream(struct pixel_stream *strm);
128+
void pixel_rgb565lestream_to_rgb24stream(struct pixel_stream *strm);
129+
void pixel_rgb24stream_to_rgb565lestream(struct pixel_stream *strm);
130+
void pixel_rgb565bestream_to_rgb24stream(struct pixel_stream *strm);
131+
void pixel_rgb24stream_to_rgb565bestream(struct pixel_stream *strm);
132+
void pixel_yuyvstream_to_rgb24stream_bt709(struct pixel_stream *strm);
133+
void pixel_rgb24stream_to_yuyvstream_bt709(struct pixel_stream *strm);
134+
/** @endcond */
135+
136+
#endif /* ZEPHYR_INCLUDE_PIXEL_FORMATS_H_ */

0 commit comments

Comments
 (0)