Skip to content

Commit c2db7c4

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 <[email protected]>
1 parent a1f7efc commit c2db7c4

File tree

22 files changed

+3248
-0
lines changed

22 files changed

+3248
-0
lines changed

cmake/linker_script/common/common-ram.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ if(CONFIG_PCIE)
138138
zephyr_iterable_section(NAME pcie_dev GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
139139
endif()
140140

141+
if(CONFIG_PIXEL)
142+
zephyr_iterable_section(NAME pixel_convert GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
143+
zephyr_iterable_section(NAME pixel_resize GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
144+
zephyr_iterable_section(NAME pixel_kernel GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
145+
endif()
146+
141147
if(CONFIG_USB_DEVICE_STACK OR CONFIG_USB_DEVICE_STACK_NEXT)
142148
zephyr_iterable_section(NAME usbd_context GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
143149
zephyr_iterable_section(NAME usbd_class_fs GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})

include/zephyr/pixel/bayer.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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/operation.h>
14+
15+
/**
16+
* @brief Define a new bayer format conversion operation.
17+
*
18+
* @param _fn Function performing the operation.
19+
* @param _fourcc_in The input format for that operation.
20+
* @param _window_size The number of line of context needed for that debayer operation.
21+
*/
22+
#define PIXEL_DEFINE_BAYER_OPERATION(_fn, _fourcc_in, _window_size) \
23+
static const STRUCT_SECTION_ITERABLE_ALTERNATE(pixel_convert, pixel_operation, \
24+
_fn##_op) = { \
25+
.name = #_fn, \
26+
.fourcc_in = _fourcc_in, \
27+
.fourcc_out = VIDEO_PIX_FMT_RGB24, \
28+
.window_size = _window_size, \
29+
.run = _fn, \
30+
}
31+
32+
/**
33+
* @brief Convert a line from RGGB8 to RGB24 with 3x3 method
34+
*
35+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
36+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
37+
* @param i2 Buffer of the input row number 2 in bayer format (1 byte per pixel).
38+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
39+
* @param width Width of the lines in number of pixels.
40+
*/
41+
void pixel_line_rggb8_to_rgb24_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
42+
uint8_t *rgb24, uint16_t width);
43+
/**
44+
* @brief Convert a line from GRBG8 to RGB24 with 3x3 method
45+
* @copydetails pixel_line_rggb8_to_rgb24_3x3()
46+
*/
47+
void pixel_line_grbg8_to_rgb24_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
48+
uint8_t *rgb24, uint16_t width);
49+
/**
50+
* @brief Convert a line from BGGR8 to RGB24 with 3x3 method
51+
* @copydetails pixel_line_rggb8_to_rgb24_3x3()
52+
*/
53+
void pixel_line_bggr8_to_rgb24_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
54+
uint8_t *rgb24, uint16_t width);
55+
/**
56+
* @brief Convert a line from GBRG8 to RGB24 with 3x3 method
57+
* @copydetails pixel_line_rggb8_to_rgb24_3x3()
58+
*/
59+
void pixel_line_gbrg8_to_rgb24_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
60+
uint8_t *rgb24, uint16_t width);
61+
62+
/**
63+
* @brief Convert a line from RGGB8 to RGB24 with 2x2 method
64+
*
65+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
66+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
67+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
68+
* @param width Width of the lines in number of pixels.
69+
*/
70+
void pixel_line_rggb8_to_rgb24_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
71+
uint16_t width);
72+
/**
73+
* @brief Convert a line from GBRG8 to RGB24 with 2x2 method
74+
* @copydetails pixel_line_rggb8_to_rgb24_2x2()
75+
*/
76+
void pixel_line_gbrg8_to_rgb24_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
77+
uint16_t width);
78+
/**
79+
* @brief Convert a line from BGGR8 to RGB24 with 2x2 method
80+
* @copydetails pixel_line_rggb8_to_rgb24_2x2()
81+
*/
82+
void pixel_line_bggr8_to_rgb24_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
83+
uint16_t width);
84+
/**
85+
* @brief Convert a line from GRBG8 to RGB24 with 2x2 method
86+
* @copydetails pixel_line_rggb8_to_rgb24_2x2()
87+
*/
88+
void pixel_line_grbg8_to_rgb24_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
89+
uint16_t width);
90+
91+
#endif /* ZEPHYR_INCLUDE_PIXEL_BAYER_H_ */

include/zephyr/pixel/convert.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright (c) 2025 tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_PIXEL_CONVERT_H_
8+
#define ZEPHYR_INCLUDE_PIXEL_CONVERT_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/image.h>
16+
17+
/**
18+
* @brief Define a new format conversion operation.
19+
*
20+
* @param _fn Function converting one input line.
21+
* @param _fourcc_in The input format for that operation.
22+
* @param _fourcc_out The Output format for that operation.
23+
*/
24+
#define PIXEL_DEFINE_CONVERT_OPERATION(_fn, _fourcc_in, _fourcc_out) \
25+
static const STRUCT_SECTION_ITERABLE_ALTERNATE(pixel_convert, pixel_operation, \
26+
_fn##_op) = { \
27+
.name = #_fn, \
28+
.fourcc_in = _fourcc_in, \
29+
.fourcc_out = _fourcc_out, \
30+
.window_size = 1, \
31+
.run = pixel_convert_op, \
32+
.arg = _fn, \
33+
}
34+
/**
35+
* @brief Helper to turn a format conversion function into an operation.
36+
*
37+
* The line conversion function is free to perform any processing on the input line.
38+
* The @c w argument is the width of both the source and destination buffers.
39+
*
40+
* The line conversion function is to be provided in @c op->arg
41+
*
42+
* @param op Current operation in progress.
43+
*/
44+
void pixel_convert_op(struct pixel_operation *op);
45+
46+
/**
47+
* @brief Get the luminance (luma channel) of an RGB24 pixel.
48+
*
49+
* @param rgb24 Pointer to an RGB24 pixel: red, green, blue channels.
50+
*/
51+
uint8_t pixel_rgb24_get_luma_bt709(const uint8_t rgb24[3]);
52+
53+
/**
54+
* @brief Convert a line of pixel data from RGB24 to RGB24 (null conversion).
55+
*
56+
* See @ref video_pixel_formats for the definition of the input and output formats.
57+
*
58+
* You only need to call this function to work directly on raw buffers.
59+
* See @ref pixel_image_convert for converting between formats.
60+
*
61+
* @param src Buffer of the input line in the format, @c XXX in @c pixel_line_XXX_to_YYY().
62+
* @param dst Buffer of the output line in the format, @c YYY in @c pixel_line_XXX_to_YYY().
63+
* @param width Width of the lines in number of pixels.
64+
*/
65+
void pixel_line_rgb24_to_rgb24(const uint8_t *src, uint8_t *dst, uint16_t width);
66+
/**
67+
* @brief Convert a line of pixel data from RGB332 to RGB24.
68+
* @copydetails pixel_line_rgb24_to_rgb24()
69+
*/
70+
void pixel_line_rgb332_to_rgb24(const uint8_t *src, uint8_t *dst, uint16_t width);
71+
/**
72+
* @brief Convert a line of pixel data from RGB24 to RGB332 little-endian.
73+
* @copydetails pixel_line_rgb24_to_rgb24()
74+
*/
75+
void pixel_line_rgb24_to_rgb332(const uint8_t *src, uint8_t *dst, uint16_t width);
76+
/**
77+
* @brief Convert a line of pixel data from RGB565 little-endian to RGB24.
78+
* @copydetails pixel_line_rgb24_to_rgb24()
79+
*/
80+
void pixel_line_rgb565le_to_rgb24(const uint8_t *src, uint8_t *dst, uint16_t width);
81+
/**
82+
* @brief Convert a line of pixel data from RGB565 big-endian to RGB24.
83+
* @copydetails pixel_line_rgb24_to_rgb24()
84+
*/
85+
void pixel_line_rgb565be_to_rgb24(const uint8_t *src, uint8_t *dst, uint16_t width);
86+
/**
87+
* @brief Convert a line of pixel data from RGB24 to RGB565 little-endian.
88+
* @copydetails pixel_line_rgb24_to_rgb24()
89+
*/
90+
void pixel_line_rgb24_to_rgb565le(const uint8_t *src, uint8_t *dst, uint16_t width);
91+
/**
92+
* @brief Convert a line of pixel data from RGB24 to RGB565 big-endian.
93+
* @copydetails pixel_line_rgb24_to_rgb24()
94+
*/
95+
void pixel_line_rgb24_to_rgb565be(const uint8_t *src, uint8_t *dst, uint16_t width);
96+
/**
97+
* @brief Convert a line of pixel data from YUYV to RGB24 (BT.709 coefficients).
98+
* @copydetails pixel_line_rgb24_to_rgb24()
99+
*/
100+
void pixel_line_yuyv_to_rgb24_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
101+
/**
102+
* @brief Convert a line of pixel data from RGB24 to YUYV (BT.709 coefficients).
103+
* @copydetails pixel_line_rgb24_to_rgb24()
104+
*/
105+
void pixel_line_rgb24_to_yuyv_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
106+
/**
107+
* @brief Convert a line of pixel data from RGB24 to YUV24 (BT.709 coefficients).
108+
* @copydetails pixel_line_rgb24_to_rgb24()
109+
*/
110+
void pixel_line_rgb24_to_yuv24_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
111+
/**
112+
* @brief Convert a line of pixel data from YUV24 to RGB24 (BT.709 coefficients).
113+
* @copydetails pixel_line_rgb24_to_rgb24()
114+
*/
115+
void pixel_line_yuv24_to_rgb24_bt709(const uint8_t *src, uint8_t *dst, uint16_t width);
116+
/**
117+
* @brief Convert a line of pixel data from YUYV to YUV24
118+
* @copydetails pixel_line_rgb24_to_rgb24()
119+
*/
120+
void pixel_line_yuyv_to_yuv24(const uint8_t *src, uint8_t *dst, uint16_t width);
121+
/**
122+
* @brief Convert a line of pixel data from YUV24 to YUYV
123+
* @copydetails pixel_line_rgb24_to_rgb24()
124+
*/
125+
void pixel_line_yuv24_to_yuyv(const uint8_t *src, uint8_t *dst, uint16_t width);
126+
127+
#endif /* ZEPHYR_INCLUDE_PIXEL_CONVERT_H_ */

0 commit comments

Comments
 (0)