Skip to content

Commit e82f16c

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 a4b397a commit e82f16c

File tree

16 files changed

+2258
-0
lines changed

16 files changed

+2258
-0
lines changed

include/zephyr/pixel/bayer.h

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
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+
12+
#include <zephyr/pixel/stream.h>
13+
14+
/**
15+
* Pixel streams definitions.
16+
* @{
17+
*/
18+
19+
void pixel_rggb8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
20+
21+
#define PIXEL_STREAM_RGGB8_TO_RGB24_3X3(name, width, height) \
22+
PIXEL_STREAM_DEFINE(name, pixel_rggb8stream_to_rgb24stream_3x3, \
23+
(width), (height), (width) * 1, 3 * (width) * 1)
24+
25+
void pixel_grbg8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
26+
27+
#define PIXEL_STREAM_GRBG8_TO_RGB24_3X3(name, width, height) \
28+
PIXEL_STREAM_DEFINE(name, pixel_grbg8stream_to_rgb24stream_3x3, \
29+
(width), (height), (width) * 1, 3 * (width) * 1)
30+
31+
void pixel_bggr8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
32+
33+
#define PIXEL_STREAM_BGGR8_TO_RGB24_3X3(name, width, height) \
34+
PIXEL_STREAM_DEFINE(name, pixel_bggr8stream_to_rgb24stream_3x3, \
35+
(width), (height), (width) * 1, 3 * (width) * 1)
36+
37+
void pixel_gbrg8stream_to_rgb24stream_3x3(struct pixel_stream *strm);
38+
39+
#define PIXEL_STREAM_GBRG8_TO_RGB24_3X3(name, width, height) \
40+
PIXEL_STREAM_DEFINE(name, pixel_gbrg8stream_to_rgb24stream_3x3, \
41+
(width), (height), (width) * 1, 3 * (width) * 1)
42+
43+
void pixel_rggb8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
44+
45+
#define PIXEL_STREAM_RGGB8_TO_RGB24_2X2(name, width, height) \
46+
PIXEL_STREAM_DEFINE(name, pixel_rggb8stream_to_rgb24stream_2x2, \
47+
(width), (height), (width) * 1, 2 * (width) * 1)
48+
49+
void pixel_gbrg8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
50+
51+
#define PIXEL_STREAM_GBRG8_TO_RGB24_2X2(name, width, height) \
52+
PIXEL_STREAM_DEFINE(name, pixel_gbrg8stream_to_rgb24stream_2x2, \
53+
(width), (height), (width) * 1, 2 * (width) * 1)
54+
55+
void pixel_bggr8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
56+
57+
#define PIXEL_STREAM_BGGR8_TO_RGB24_2X2(name, width, height) \
58+
PIXEL_STREAM_DEFINE(name, pixel_bggr8stream_to_rgb24stream_2x2, \
59+
(width), (height), (width) * 1, 2 * (width) * 1)
60+
61+
void pixel_grbg8stream_to_rgb24stream_2x2(struct pixel_stream *strm);
62+
63+
#define PIXEL_STREAM_GRBG8_TO_RGB24_2X2(name, width, height) \
64+
PIXEL_STREAM_DEFINE(name, pixel_grbg8stream_to_rgb24stream_2x2, \
65+
(width), (height), (width) * 1, 2 * (width) * 1)
66+
67+
/** @} */
68+
69+
/**
70+
* @brief Bayer to RGB24 conversion, 3x3 variant.
71+
*
72+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
73+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
74+
* @param i2 Buffer of the input row number 2 in bayer format (1 byte per pixel).
75+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
76+
* @param width Width of the lines in number of pixels.
77+
* @{
78+
*/
79+
/** Variant for RGGB8 format */
80+
void pixel_rggb8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
81+
uint8_t *rgb24, size_t width);
82+
/** Variant for GRBG8 format */
83+
void pixel_grbg8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
84+
uint8_t *rgb24, size_t width);
85+
/** Variant for BGGR8 format */
86+
void pixel_bggr8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
87+
uint8_t *rgb24, size_t width);
88+
/** Variant for GBRG8 format */
89+
void pixel_gbrg8line_to_rgb24line_3x3(const uint8_t *i0, const uint8_t *i1, const uint8_t *i2,
90+
uint8_t *rgb24, size_t width);
91+
/** @} */
92+
93+
/**
94+
* @brief Bayer to RGB24 conversion, 2x2 variant.
95+
*
96+
* @param i0 Buffer of the input row number 0 in bayer format (1 byte per pixel).
97+
* @param i1 Buffer of the input row number 1 in bayer format (1 byte per pixel).
98+
* @param rgb24 Buffer of the output row in RGB24 format (3 bytes per pixel).
99+
* @param width Width of the lines in number of pixels.
100+
* @{
101+
*/
102+
/** Variant for RGGB8 bayer format */
103+
void pixel_rggb8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
104+
size_t width);
105+
/** Variant for GBRG8 bayer format */
106+
void pixel_gbrg8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
107+
size_t width);
108+
/** Variant for BGGR8 bayer format */
109+
void pixel_bggr8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
110+
size_t width);
111+
/** Variant for GRBG8 bayer format */
112+
void pixel_grbg8line_to_rgb24line_2x2(const uint8_t *i0, const uint8_t *i1, uint8_t *rgb24,
113+
size_t width);
114+
/** @} */
115+
116+
/**
117+
* @brief Perform a RGGB8 to RGB24 conversion, 3x3 variant.
118+
*
119+
* @param rgr0 Row 0 with 3 bytes of RGGB8 data
120+
* @param gbg1 Row 1 with 3 bytes of RGGB8 data
121+
* @param rgr2 Row 2 with 3 bytes of RGGB8 data
122+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
123+
*/
124+
static inline void pixel_rggb8_to_rgb24_3x3(const uint8_t rgr0[3], const uint8_t gbg1[3],
125+
const uint8_t rgr2[3], uint8_t rgb24[3])
126+
{
127+
rgb24[0] = ((uint16_t)rgr0[0] + rgr0[2] + rgr2[0] + rgr2[2]) / 4;
128+
rgb24[1] = ((uint16_t)rgr0[1] + gbg1[2] + gbg1[0] + rgr2[1]) / 4;
129+
rgb24[2] = gbg1[1];
130+
}
131+
132+
/**
133+
* @brief Perform a BGGR8 to RGB24 conversion, 3x3 variant.
134+
*
135+
* @param bgb0 Row 0 with 3 bytes of BGGR8 data
136+
* @param grg1 Row 1 with 3 bytes of BGGR8 data
137+
* @param bgb2 Row 2 with 3 bytes of BGGR8 data
138+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
139+
*/
140+
static inline void pixel_bggr8_to_rgb24_3x3(const uint8_t bgb0[3], const uint8_t grg1[3],
141+
const uint8_t bgb2[3], uint8_t rgb24[3])
142+
{
143+
rgb24[0] = grg1[1];
144+
rgb24[1] = ((uint16_t)bgb0[1] + grg1[2] + grg1[0] + bgb2[1]) / 4;
145+
rgb24[2] = ((uint16_t)bgb0[0] + bgb0[2] + bgb2[0] + bgb2[2]) / 4;
146+
}
147+
148+
/**
149+
* @brief Perform a GRBG8 to RGB24 conversion, 3x3 variant.
150+
*
151+
* @param grg0 Row 0 with 3 bytes of GRBG8 data
152+
* @param bgb1 Row 1 with 3 bytes of GRBG8 data
153+
* @param grg2 Row 2 with 3 bytes of GRBG8 data
154+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
155+
*/
156+
static inline void pixel_grbg8_to_rgb24_3x3(const uint8_t grg0[3], const uint8_t bgb1[3],
157+
const uint8_t grg2[3], uint8_t rgb24[3])
158+
{
159+
rgb24[0] = ((uint16_t)grg0[1] + grg2[1]) / 2;
160+
rgb24[1] = bgb1[1];
161+
rgb24[2] = ((uint16_t)bgb1[0] + bgb1[2]) / 2;
162+
}
163+
164+
/**
165+
* @brief Perform a GBRG8 to RGB24 conversion, 3x3 variant.
166+
*
167+
* @param gbg0 Row 0 with 3 bytes of GBRG8 data
168+
* @param rgr1 Row 1 with 3 bytes of GBRG8 data
169+
* @param gbg2 Row 2 with 3 bytes of GBRG8 data
170+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
171+
*/
172+
static inline void pixel_gbrg8_to_rgb24_3x3(const uint8_t gbg0[3], const uint8_t rgr1[3],
173+
const uint8_t gbg2[3], uint8_t rgb24[3])
174+
{
175+
rgb24[0] = ((uint16_t)rgr1[0] + rgr1[2]) / 2;
176+
rgb24[1] = rgr1[1];
177+
rgb24[2] = ((uint16_t)gbg0[1] + gbg2[1]) / 2;
178+
}
179+
180+
/**
181+
* @brief Perform a RGGB8 to RGB24 conversion, 2x2 variant.
182+
*
183+
* @param r0 Red value from the bayer pattern.
184+
* @param g0 Green value from the bayer pattern.
185+
* @param g1 Green value from the bayer pattern.
186+
* @param b0 Blue value from the bayer pattern.
187+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
188+
*/
189+
static inline void pixel_rggb8_to_rgb24_2x2(uint8_t r0, uint8_t g0, uint8_t g1, uint8_t b0,
190+
uint8_t rgb24[3])
191+
{
192+
rgb24[0] = r0;
193+
rgb24[1] = ((uint16_t)g0 + g1) / 2;
194+
rgb24[2] = b0;
195+
}
196+
197+
/**
198+
* @brief Perform a GBRG8 to RGB24 conversion, 2x2 variant.
199+
*
200+
* @param g1 Green value from the bayer pattern.
201+
* @param b0 Blue value from the bayer pattern.
202+
* @param r0 Red value from the bayer pattern.
203+
* @param g0 Green value from the bayer pattern.
204+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
205+
*/
206+
static inline void pixel_gbrg8_to_rgb24_2x2(uint8_t g1, uint8_t b0, uint8_t r0, uint8_t g0,
207+
uint8_t rgb24[3])
208+
{
209+
rgb24[0] = r0;
210+
rgb24[1] = ((uint16_t)g0 + g1) / 2;
211+
rgb24[2] = b0;
212+
}
213+
214+
/**
215+
* @brief Perform a BGGR8 to RGB24 conversion, 2x2 variant.
216+
*
217+
* @param b0 Blue value from the bayer pattern.
218+
* @param g0 Green value from the bayer pattern.
219+
* @param g1 Green value from the bayer pattern.
220+
* @param r0 Red value from the bayer pattern.
221+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
222+
*/
223+
static inline void pixel_bggr8_to_rgb24_2x2(uint8_t b0, uint8_t g0, uint8_t g1, uint8_t r0,
224+
uint8_t rgb24[3])
225+
{
226+
rgb24[0] = r0;
227+
rgb24[1] = ((uint16_t)g0 + g1) / 2;
228+
rgb24[2] = b0;
229+
}
230+
231+
/**
232+
* @brief Perform a GRBG8 to RGB24 conversion, 2x2 variant.
233+
*
234+
* @param g1 Green value from the bayer pattern.
235+
* @param b0 Blue value from the bayer pattern.
236+
* @param r0 Red value from the bayer pattern.
237+
* @param g0 Green value from the bayer pattern.
238+
* @param rgb24 The pixel in RGB24 format: {R, G, B}
239+
*/
240+
static inline void pixel_grbg8_to_rgb24_2x2(uint8_t g1, uint8_t r0, uint8_t b0, uint8_t g0,
241+
uint8_t rgb24[3])
242+
{
243+
rgb24[0] = r0;
244+
rgb24[1] = ((uint16_t)g0 + g1) / 2;
245+
rgb24[2] = b0;
246+
}
247+
248+
#endif /* ZEPHYR_INCLUDE_PIXEL_BAYER_H */

0 commit comments

Comments
 (0)