Ocean
Loading...
Searching...
No Matches
FrameConverterRGB24.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_CV_FRAME_CONVERTER_RGB_24_H
9#define META_OCEAN_CV_FRAME_CONVERTER_RGB_24_H
10
11#include "ocean/cv/CV.h"
14
15#include "ocean/base/Worker.h"
16
17namespace Ocean
18{
19
20namespace CV
21{
22
23/**
24 * This class provides functions to convert or to change frames with RGB pixel format.
25 * @ingroup cv
26 */
27class OCEAN_CV_EXPORT FrameConverterRGB24 : public FrameConverter
28{
29 public:
30
31 /**
32 * Converts a RGB 24 bit frame to a ARGB 32 bit frame.
33 * @param source The source frame buffer, must be valid
34 * @param target The target frame buffer, must be valid
35 * @param width The width of the frame in pixel, with range (0, infinity)
36 * @param height The height of the frame in pixel, with range (0, infinity)
37 * @param flag Determining the type of conversion
38 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
39 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
40 * @param alphaValue The value of the alpha channel to be set, with range [0, 255]
41 * @param worker Optional worker object to distribute the computational load
42 */
43 static inline void convertRGB24ToARGB32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue = 0xFF, Worker* worker = nullptr);
44
45 /**
46 * Converts a RGB 24 bit frame to a BGR 24 bit frame.
47 * @param source The source frame buffer, must be valid
48 * @param target The target frame buffer, must be valid
49 * @param width The width of the frame in pixel, with range (0, infinity)
50 * @param height The height of the frame in pixel, with range (0, infinity)
51 * @param flag Determining the type of conversion
52 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
53 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
54 * @param worker Optional worker object to distribute the computational load
55 */
56 static inline void convertRGB24ToBGR24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
57
58 /**
59 * Converts a RGB 24 bit frame to a BGR 32 bit frame.
60 * @param source The source frame buffer, must be valid
61 * @param target The target frame buffer, must be valid
62 * @param width The width of the frame in pixel, with range (0, infinity)
63 * @param height The height of the frame in pixel, with range (0, infinity)
64 * @param flag Determining the type of conversion
65 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
66 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
67 * @param worker Optional worker object to distribute the computational load
68 * @remarks The unused last channel of each pixel in target frame is set to zero.
69 */
70 static inline void convertRGB24ToBGR32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker);
71 /**
72 * Converts a RGB 24 bit frame to a BGRA 32 bit frame.
73 * @param source The source frame buffer, must be valid
74 * @param target The target frame buffer, must be valid
75 * @param width The width of the frame in pixel, with range (0, infinity)
76 * @param height The height of the frame in pixel, with range (0, infinity)
77 * @param flag Determining the type of conversion
78 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
79 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
80 * @param alphaValue The value of the alpha channel to be set, with range [0, 255]
81 * @param worker Optional worker object to distribute the computational load
82 */
83 static inline void convertRGB24ToBGRA32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue = 0xFF, Worker* worker = nullptr);
84
85 /**
86 * Changes a RGB 24 bit frame to a BGR 24 bit frame in place.
87 * @param frame The frame buffer to be changed, must be valid
88 * @param width The width of the frame in pixel, with range (0, infinity)
89 * @param height The height of the frame in pixel, with range (0, infinity)
90 * @param worker Optional worker object to distribute the computational load
91 */
92 static inline void changeRGB24ToBGR24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker = nullptr);
93
94 /**
95 * Converts a RGB 24 bit frame to a RGB 24 bit frame.
96 * @param source The source frame buffer, must be valid
97 * @param target The target frame buffer, must be valid
98 * @param width The width of the frame in pixel, with range (0, infinity)
99 * @param height The height of the frame in pixel, with range (0, infinity)
100 * @param flag Determining the type of conversion
101 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
102 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
103 * @param worker Optional worker object to distribute the computational load
104 */
105 static inline void convertRGB24ToRGB24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
106
107 /**
108 * Converts a RGB 24 bit frame to a RGB 32 bit frame.
109 * @param source The source frame buffer, must be valid
110 * @param target The target frame buffer, must be valid
111 * @param width The width of the frame in pixel, with range (0, infinity)
112 * @param height The height of the frame in pixel, with range (0, infinity)
113 * @param flag Determining the type of conversion
114 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
115 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
116 * @param worker Optional worker object to distribute the computational load
117 * @remarks The unused last channel of each pixel in target frame is set to zero.
118 */
119 static inline void convertRGB24ToRGB32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
120
121 /**
122 * Converts a RGB 24 bit frame to a RGBA 32 bit frame.
123 * @param source The source frame buffer, must be valid
124 * @param target The target frame buffer, must be valid
125 * @param width The width of the frame in pixel, with range (0, infinity)
126 * @param height The height of the frame in pixel, with range (0, infinity)
127 * @param flag Determining the type of conversion
128 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
129 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
130 * @param alphaValue The value of the alpha channel to be set, with range [0, 255]
131 * @param worker Optional worker object to distribute the computational load
132 */
133 static inline void convertRGB24ToRGBA32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue = 0xFF, Worker* worker = nullptr);
134
135 /**
136 * Converts a RGB frame to a gray scale frame.
137 * Gray = Red * 0.299 + Green * 0.587 + Blue * 0.114
138 * @param source The source frame buffer, must be valid
139 * @param target The target frame buffer, must be valid
140 * @param width The width of the frame in pixel, with range (0, infinity)
141 * @param height The height of the frame in pixel, with range (0, infinity)
142 * @param flag Determining the type of conversion
143 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
144 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
145 * @param worker Optional worker object to distribute the computational load
146 */
147 static inline void convertRGB24ToY8(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
148
149 /**
150 * Converts a RGB 24 bit frame to a YUV 24 bit frame by the exact conversion.
151 * @param source The source frame buffer, must be valid
152 * @param target The target frame buffer, must be valid
153 * @param width The width of the frame in pixel, with range (0, infinity)
154 * @param height The height of the frame in pixel, with range (0, infinity)
155 * @param flag Determining the type of conversion
156 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
157 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
158 * @param worker Optional worker object to distribute the computational load
159 */
160 static inline void convertRGB24ToYUV24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
161
162 /**
163 * Converts a full range RGB24 frame to a limited range Y_UV12 frame with 7-bit precision using BT.601.
164 * <pre>
165 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
166 * YUV input value range: [16, 235]x[16, 240]x[16, 240]
167 * </pre>
168 * @param source The source frame plane, must be valid
169 * @param yTarget The y-target frame plane, must be valid
170 * @param uvTarget The uv-target frame plane, must be valid
171 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
172 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
173 * @param flag Determining the type of conversion
174 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
175 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
176 * @param uvTargetPaddingElements Optional number of padding elements at the end of each uv-target row, in (uint8_t) elements, with range [0, infinity)
177 * @param worker Optional worker object to distribute the computational load
178 */
179 static inline void convertRGB24FullRangeToY_UV12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker = nullptr);
180
181 /**
182 * Converts a full range RGB24 frame to a limited range Y_VU12 frame with 7-bit precision using BT.601.
183 * <pre>
184 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
185 * YVU input value range: [16, 235]x[16, 240]x[16, 240]
186 * </pre>
187 * @param source The source frame plane, must be valid
188 * @param yTarget The y-target frame plane, must be valid
189 * @param vuTarget The vu-target frame plane, must be valid
190 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
191 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
192 * @param flag Determining the type of conversion
193 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
194 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
195 * @param vuTargetPaddingElements Optional number of padding elements at the end of each vu-target row, in (uint8_t) elements, with range [0, infinity)
196 * @param worker Optional worker object to distribute the computational load
197 */
198 static inline void convertRGB24FullRangeToY_VU12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker* worker = nullptr);
199
200 /**
201 * Converts a full range RGB24 frame to a full range Y_UV12 frame with 7-bit precision using BT.601.
202 * <pre>
203 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
204 * YUV output value range: [0, 255]x[0, 255]x[0, 255]
205 * </pre>
206 * @param source The source frame plane, must be valid
207 * @param yTarget The y-target frame plane, must be valid
208 * @param uvTarget The uv-target frame plane, must be valid
209 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
210 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
211 * @param flag Determining the type of conversion
212 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
213 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
214 * @param uvTargetPaddingElements Optional number of padding elements at the end of each uv-target row, in (uint8_t) elements, with range [0, infinity)
215 * @param worker Optional worker object to distribute the computational load
216 */
217 static inline void convertRGB24FullRangeToY_UV12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker = nullptr);
218
219 /**
220 * Converts a full range RGB24 frame to a full range Y_VU12 frame with 7-bit precision using BT.601.
221 * <pre>
222 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
223 * YVU output value range: [0, 255]x[0, 255]x[0, 255]
224 * </pre>
225 * @param source The source frame plane, must be valid
226 * @param yTarget The y-target frame plane, must be valid
227 * @param vuTarget The vu-target frame plane, must be valid
228 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
229 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
230 * @param flag Determining the type of conversion
231 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
232 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
233 * @param vuTargetPaddingElements Optional number of padding elements at the end of each vu-target row, in (uint8_t) elements, with range [0, infinity)
234 * @param worker Optional worker object to distribute the computational load
235 */
236 static inline void convertRGB24FullRangeToY_VU12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker* worker = nullptr);
237
238 /**
239 * Converts a full range RGB24 frame to a limited range Y_U_V12 frame with 7-bit precision using BT.601.
240 * <pre>
241 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
242 * YUV input value range: [16, 235]x[16, 240]x[16, 240]
243 * </pre>
244 * @param source The source frame plane, must be valid
245 * @param yTarget The y-target frame plane, must be valid
246 * @param uTarget The u-target frame plane, must be valid
247 * @param vTarget The v-target frame plane, must be valid
248 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
249 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
250 * @param flag Determining the type of conversion
251 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
252 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
253 * @param uTargetPaddingElements Optional number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
254 * @param vTargetPaddingElements Optional number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
255 * @param worker Optional worker object to distribute the computational load
256 */
257 static inline void convertRGB24FullRangeToY_U_V12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker = nullptr);
258
259 /**
260 * Converts a full range RGB24 frame to a limited range Y_V_U12 frame with 7-bit precision using BT.601.
261 * <pre>
262 * RGB input value range: [ 0, 255]x[ 0, 255]x[0 , 255]
263 * YVU input value range: [16, 235]x[16, 240]x[16, 240]
264 * </pre>
265 * @param source The source frame plane, must be valid
266 * @param yTarget The y-target frame plane, must be valid
267 * @param vTarget The v-target frame plane, must be valid
268 * @param uTarget The u-target frame plane, must be valid
269 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
270 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
271 * @param flag Determining the type of conversion
272 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
273 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
274 * @param vTargetPaddingElements Optional number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
275 * @param uTargetPaddingElements Optional number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
276 * @param worker Optional worker object to distribute the computational load
277 */
278 static inline void convertRGB24FullRangeToY_V_U12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker = nullptr);
279
280 /**
281 * Converts a full range RGB24 frame to a full range Y_U_V12 frame with 7-bit precision using BT.601.
282 * <pre>
283 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
284 * YUV output value range: [0, 255]x[0, 255]x[0, 255]
285 * </pre>
286 * @param source The source frame plane, must be valid
287 * @param yTarget The y-target frame plane, must be valid
288 * @param uTarget The u-target frame plane, must be valid
289 * @param vTarget The v-target frame plane, must be valid
290 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
291 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
292 * @param flag Determining the type of conversion
293 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
294 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
295 * @param uTargetPaddingElements Optional number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
296 * @param vTargetPaddingElements Optional number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
297 * @param worker Optional worker object to distribute the computational load
298 */
299 static inline void convertRGB24FullRangeToY_U_V12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker = nullptr);
300
301 /**
302 * Converts a full range RGB24 frame to a full range Y_V_U12 frame with 7-bit precision using BT.601.
303 * <pre>
304 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
305 * YVU output value range: [0, 255]x[0, 255]x[0, 255]
306 * </pre>
307 * @param source The source frame plane, must be valid
308 * @param yTarget The y-target frame plane, must be valid
309 * @param vTarget The v-target frame plane, must be valid
310 * @param uTarget The u-target frame plane, must be valid
311 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
312 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
313 * @param flag Determining the type of conversion
314 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
315 * @param yTargetPaddingElements Optional number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
316 * @param vTargetPaddingElements Optional number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
317 * @param uTargetPaddingElements Optional number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
318 * @param worker Optional worker object to distribute the computational load
319 */
320 static inline void convertRGB24FullRangeToY_V_U12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker = nullptr);
321
322 /**
323 * Changes a RGB 24 bit frame to a YUV 24 bit frame by the exact conversion in place.
324 * @param frame The frame buffer to be changed, must be valid
325 * @param width The width of the frame in pixel, with range (0, infinity)
326 * @param height The height of the frame in pixel, with range (0, infinity)
327 * @param worker Optional worker object to distribute the computational load
328 */
329 static inline void changeRGB24ToYUV24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker = nullptr);
330
331 /**
332 * Converts one RGB 24 bit pixel to one YUV 24 bit pixel.
333 * As this implementation uses a right shift the result may differ from the correct value by 1.
334 * @param rgb The source pixel value to convert, must be valid and must provided the three channel values
335 * @param yuv The target pixel value, must be valid and must be large enough for three channel values
336 */
337 static inline void convertRGB24ToYUV24Pixel(const uint8_t* rgb, uint8_t* yuv);
338
339 /**
340 * Converts a RGB 24 bit frame to a R_G_B 24 bit frame.
341 * @param source The source frame buffer, with (width * 3 + targetPaddingElements) * height elements, must be valid
342 * @param rTarget The r target frame buffer, with (width + rPaddingElements) * height elements, must be valid
343 * @param gTarget The g target frame buffer, with (width + gPaddingElements) * height elements, must be valid
344 * @param bTarget The b target frame buffer, with (width + bPaddingElements) * height elements, must be valid
345 * @param width The width of the frame in pixel, with range [2, infinity)
346 * @param height The height of the frame in pixel, with range [2, infinity)
347 * @param flag Determining the type of conversion
348 * @param sourcePaddingElements The number of padding elements at the end of each source row, in (uint8_t) elements, with range [0, infinity)
349 * @param rTargetPaddingElements The number of padding elements at the end of each r-target row, in (uint8_t) elements, with range [0, infinity)
350 * @param gTargetPaddingElements The number of padding elements at the end of each g-target row, in (uint8_t) elements, with range [0, infinity)
351 * @param bTargetPaddingElements The number of padding elements at the end of each b-target row, in (uint8_t) elements, with range [0, infinity)
352 * @param worker Optional worker object to distribute the computation
353 */
354 static inline void convertRGB24ToR_G_B24(const uint8_t* source, uint8_t* rTarget, uint8_t* gTarget, uint8_t* bTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int rTargetPaddingElements, const unsigned int gTargetPaddingElements, const unsigned int bTargetPaddingElements, Worker* worker = nullptr);
355
356 protected:
357
358 /**
359 * Changes a subset of RGB 24 bit frame to a BGR 24 bit frame.
360 * @param frame The frame buffer to be changed, must be valid
361 * @param width The width of the frame in pixel, with range (0, infinity)
362 * @param firstRow First (including) row to convert, with range [0, height)
363 * @param numberRows Number of rows to convert, with range [1, height]
364 */
365 static void changeRGB24ToBGR24Subset(uint8_t* frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows);
366
367 /**
368 * Changes a subset of a RGB 24 bit frame to a YUV 24 bit frame by exact conversion.
369 * @param frame The frame buffer to be changed, must be valid
370 * @param width The width of the frame in pixel, with range (0, infinity)
371 * @param firstRow First (including) row to convert, with range [0, height)
372 * @param numberRows Number of rows to convert, with range [1, height]
373 */
374 static void changeRGB24ToYUV24Subset(uint8_t* frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows);
375
376#if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
377
378 /**
379 * Converts a RGB 24 bit row to a YUV 24 bit row by using NEON instructions.
380 * Beware: This function uses hard-coded conversion parameters which improves execution performance while also increases binary size when used.
381 * @param source The pointer to the source pixels, must be valid
382 * @param target The pointer to the target pixels receiving the converted pixel data, must be valid
383 * @param size The number of source (and target pixels) to convert, with range [1, infinity)
384 * @param parameters Unused parameters, must be nullptr
385 */
386 static void convertRGB24ToYUV24RowPrecision7BitNEON(const uint8_t* source, uint8_t* target, const size_t size, const void* parameters);
387
388 /**
389 * Converts 16 RGB24 pixels to 16 YUV24 pixels by using NEON instructions.
390 * Beware: This function uses hard-coded conversion parameters which improves execution performance while also increases binary size when used.
391 * @param source The pointer to the 16 source pixels (with 3 channels = 48 bytes) to convert, must be valid
392 * @param target The pointer to the 16 target pixels (with 3 channels = 48 bytes) receiving the converted pixel data, must be valid
393 */
394 static OCEAN_FORCE_INLINE void convert16PixelsRGB24ToYUV24Precision7BitNEON(const uint8_t* const source, uint8_t* const target);
395
396#endif // OCEAN_HARDWARE_NEON_VERSION >= 10
397};
398
399inline void FrameConverterRGB24::convertRGB24ToARGB32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue, Worker* worker)
400{
401 ocean_assert(source != nullptr && target != nullptr);
402 ocean_assert(width >= 1u && height >= 1u);
403
404 FrameChannels::addFirstChannelValue<uint8_t, 3u>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
405}
406
407inline void FrameConverterRGB24::convertRGB24ToBGR24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
408{
409 ocean_assert(source != nullptr && target != nullptr);
410 ocean_assert(width >= 1u && height >= 1u);
411
412 FrameChannels::reverseChannelOrder<uint8_t, 3u>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
413}
414
415inline void FrameConverterRGB24::changeRGB24ToBGR24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker)
416{
417 ocean_assert(frame);
418 ocean_assert(width != 0u && height != 0u);
419
420 if (worker)
421 {
422 worker->executeFunction(Worker::Function::createStatic(&FrameConverterRGB24::changeRGB24ToBGR24Subset, frame, width, 0u, 0u), 0u, height, 2u, 3u, 100u);
423 }
424 else
425 {
426 changeRGB24ToBGR24Subset(frame, width, 0u, height);
427 }
428}
429
430inline void FrameConverterRGB24::convertRGB24ToBGR32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
431{
432 ocean_assert(source != nullptr && target != nullptr);
433 ocean_assert(width >= 1u && height >= 1u);
434
435 // source frame R G B
436 // 0 1 2
437 // target frame B G R -
438 // pattern 2 1 0
439 constexpr unsigned int shufflePattern = 0x012u;
440
441 FrameChannels::shuffleChannelsAndSetLastChannelValue<uint8_t, 3u, 4u, shufflePattern>(source, 0u, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
442}
443
444inline void FrameConverterRGB24::convertRGB24ToBGRA32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue, Worker* worker)
445{
446 ocean_assert(source != nullptr && target != nullptr);
447 ocean_assert(width >= 1u && height >= 1u);
448
449 // source frame R G B
450 // 0 1 2
451 // target frame B G R A
452 // pattern 2 1 0
453 constexpr unsigned int shufflePattern = 0x012u;
454
455 FrameChannels::shuffleChannelsAndSetLastChannelValue<uint8_t, 3u, 4u, shufflePattern>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
456}
457
458inline void FrameConverterRGB24::convertRGB24ToRGB24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
459{
460 ocean_assert(source != nullptr && target != nullptr);
461 ocean_assert(width >= 1u && height >= 1u);
462
463 FrameChannels::transformGeneric<uint8_t, 3u>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
464}
465
466inline void FrameConverterRGB24::convertRGB24ToRGB32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
467{
468 ocean_assert(source != nullptr && target != nullptr);
469 ocean_assert(width >= 1u && height >= 1u);
470
471 FrameChannels::addLastChannelValue<uint8_t, 3u>(source, 0u, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
472}
473
474inline void FrameConverterRGB24::convertRGB24ToRGBA32(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue, Worker* worker)
475{
476 ocean_assert(source != nullptr && target != nullptr);
477 ocean_assert(width >= 1u && height >= 1u);
478
479 FrameChannels::addLastChannelValue<uint8_t, 3u>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
480}
481
482inline void FrameConverterRGB24::convertRGB24ToY8(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
483{
484 ocean_assert(source != nullptr && target != nullptr);
485 ocean_assert(width >= 1u && height >= 1u);
486
487 const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
488 const unsigned int targetStrideElements = width + targetPaddingElements;
489
490 constexpr unsigned int channelFactors[3] = {38u, 75u, 15u}; // 38/128 ~ 0.299, 75/128 ~ 0.587, 15/128 ~ 0.114
491
492 static_assert(channelFactors[0] + channelFactors[1] + channelFactors[2] == 128u, "Invalid factors!");
493
494 constexpr bool useFactorChannel0 = channelFactors[0] != 0u;
495 constexpr bool useFactorChannel1 = channelFactors[1] != 0u;
496 constexpr bool useFactorChannel2 = channelFactors[2] != 0u;
497
498 const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
499
500 FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo1Channel8BitPerChannel7BitPrecision<useFactorChannel0, useFactorChannel1, useFactorChannel2>, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 1u>, areContinuous, channelFactors, worker);
501}
502
503inline void FrameConverterRGB24::convertRGB24ToYUV24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
504{
505 ocean_assert(source != nullptr && target != nullptr);
506 ocean_assert(width >= 1u && height >= 1u);
507
508 const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
509 const unsigned int targetStrideElements = width * 3u + targetPaddingElements;
510
511#if defined(OCEAN_USE_HARDCODED_RGB24_TO_YUV24_CONVERTER) && OCEAN_HARDWARE_NEON_VERSION >= 10
512
513 // we keep this function mainly to show the performance difference between the hard-coded implementation and a variable implementation
514
515 FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, FrameConverterRGB24::convertRGB24ToYUV24RowPrecision7BitNEON, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, nullptr, worker);
516
517#else
518
519 // approximation:
520 // Y = ( 33 * R + 64 * G + 13 * B) / 128 + 16
521 // U = (-19 * R - 37 * G + 56 * B) / 128 + 128
522 // V = ( 56 * R - 47 * G - 9 * B) / 128 + 128
523
524 const int parameters[12] = {33, -19, 56, 64, -37, -47, 13, 56, -9, 16, 128, 128};
525
526 const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
527
528 FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo3Channels8BitPerChannel7BitPrecision, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, areContinuous, parameters, worker);
529
530#endif
531}
532
533inline void FrameConverterRGB24::convertRGB24FullRangeToY_UV12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker)
534{
535 ocean_assert(source != nullptr && yTarget != nullptr && uvTarget != nullptr);
536
537 ocean_assert(width >= 2u && width % 2u == 0u);
538 ocean_assert(height >= 2u && height % 2u == 0u);
539
540 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
541 {
542 return;
543 }
544
545 /*
546 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
547 * YUV output value range: [16, 235]x[16, 240]x[16, 240]
548 *
549 * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
550 * | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
551 * | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
552 * | 1 |
553 * Approximation with 7 bit precision:
554 * | Y | | 33 64 13 16 * 128 | | R |
555 * 128 * | U | = | -19 -37 56 128 * 128 | * | G |
556 * | V | | 56 -47 -9 128 * 128 | | B |
557 * | 1 |
558 */
559
560 const int options[3 + 9 + 3] =
561 {
562 // padding parameters
563 int(sourcePaddingElements), int(yTargetPaddingElements), int(uvTargetPaddingElements),
564
565 // multiplication parameters
566 33, -19, 56, 64, -37, -47, 13, 56, -9,
567
568 // bias/translation parameters
569 16, 128, 128
570 };
571
572 void* target[2] =
573 {
574 yTarget,
575 uvTarget,
576 };
577
579}
580
581inline void FrameConverterRGB24::convertRGB24FullRangeToY_VU12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker* worker)
582{
583 ocean_assert(source != nullptr && yTarget != nullptr && vuTarget != nullptr);
584
585 ocean_assert(width >= 2u && width % 2u == 0u);
586 ocean_assert(height >= 2u && height % 2u == 0u);
587
588 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
589 {
590 return;
591 }
592
593 /*
594 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
595 * YVU output value range: [16, 235]x[16, 240]x[16, 240]
596 *
597 * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
598 * | V | = | 0.4375 -0.3671875 -0.0703125 128.0 | * | G |
599 * | U | | -0.1484375 -0.2890625 0.4375 128.0 | | B |
600 * | 1 |
601 * Approximation with 7 bit precision:
602 * | Y | | 33 64 13 16 * 128 | | R |
603 * 128 * | V | = | 56 -47 -9 128 * 128 | * | G |
604 * | U | | -19 -37 56 128 * 128 | | B |
605 * | 1 |
606 */
607
608 const int options[3 + 9 + 3] =
609 {
610 // padding parameters
611 int(sourcePaddingElements), int(yTargetPaddingElements), int(vuTargetPaddingElements),
612
613 // multiplication parameters
614 33, 56, -19, 64, -47, -37, 13, -9, 56,
615
616 // bias/translation parameters
617 16, 128, 128
618 };
619
620 void* target[2] =
621 {
622 yTarget,
623 vuTarget
624 };
625
627}
628
629inline void FrameConverterRGB24::convertRGB24FullRangeToY_UV12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker)
630{
631 ocean_assert(source != nullptr && yTarget != nullptr && uvTarget != nullptr);
632
633 ocean_assert(width >= 2u && width % 2u == 0u);
634 ocean_assert(height >= 2u && height % 2u == 0u);
635
636 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
637 {
638 return;
639 }
640
641 /*
642 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
643 * YUV output value range: [0, 255]x[0, 255]x[0, 255]
644 *
645 * | Y | | 0.299 0.587 0.114 0 | | R |
646 * | U | = | -0.168736 -0.331264 0.5 128 | * | G |
647 * | V | | 0.5 -0.418688 -0.081312 128 | | B |
648 * | 1 |
649 * Approximation with 7 bit precision:
650 * | Y | | 38 75 15 0 * 128 | | R |
651 * 128 * | U | = | -22 -42 64 128 * 128 | * | G |
652 * | V | | 64 -54 -10 128 * 128 | | B |
653 * | 1 |
654 */
655
656 const int options[3 + 9 + 3] =
657 {
658 // padding parameters
659 int(sourcePaddingElements), int(yTargetPaddingElements), int(uvTargetPaddingElements),
660
661 // multiplication parameters
662 38, -22, 64, 75, -42, -54, 15, 64, -10,
663
664 // bias/translation parameters
665 0, 128, 128
666 };
667
668 void* target[2] =
669 {
670 yTarget,
671 uvTarget
672 };
673
675}
676
677inline void FrameConverterRGB24::convertRGB24FullRangeToY_VU12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker* worker)
678{
679 ocean_assert(source != nullptr && yTarget != nullptr && vuTarget != nullptr);
680
681 ocean_assert(width >= 2u && width % 2u == 0u);
682 ocean_assert(height >= 2u && height % 2u == 0u);
683
684 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
685 {
686 return;
687 }
688
689 /*
690 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
691 * YVU output value range: [0, 255]x[0, 255]x[0, 255]
692 *
693 * | Y | | 0.299 0.587 0.114 0 | | R |
694 * | V | = | 0.5 -0.418688 -0.081312 128 | * | G |
695 * | U | | -0.168736 -0.331264 0.5 128 | | B |
696 * | 1 |
697 * Approximation with 7 bit precision:
698 * | Y | | 38 75 15 0 * 128 | | R |
699 * 128 * | V | = | 64 -54 -10 128 * 128 | * | G |
700 * | U | | -22 -42 64 128 * 128 | | B |
701 * | 1 |
702 */
703
704 const int options[3 + 9 + 3] =
705 {
706 // padding parameters
707 int(sourcePaddingElements), int(yTargetPaddingElements), int(vuTargetPaddingElements),
708
709 // multiplication parameters
710 38, 64, -22, 75, -54, -42, 15, -10, 64,
711
712 // bias/translation parameters
713 0, 128, 128
714 };
715
716 void* target[2] =
717 {
718 yTarget,
719 vuTarget
720 };
721
723}
724
725inline void FrameConverterRGB24::convertRGB24FullRangeToY_U_V12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker)
726{
727 ocean_assert(source != nullptr && yTarget != nullptr && uTarget != nullptr && vTarget != nullptr);
728
729 ocean_assert(width >= 2u && width % 2u == 0u);
730 ocean_assert(height >= 2u && height % 2u == 0u);
731
732 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
733 {
734 return;
735 }
736
737 /*
738 * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
739 * YUV output value range: [16, 235]x[16, 240]x[16, 240]
740 *
741 * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
742 * | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
743 * | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
744 * | 1 |
745 * Approximation with 7 bit precision:
746 * | Y | | 33 64 13 16 * 128 | | R |
747 * 128 * | U | = | -19 -37 56 128 * 128 | * | G |
748 * | V | | 56 -47 -9 128 * 128 | | B |
749 * | 1 |
750 */
751
752 const int options[4 + 9 + 3] =
753 {
754 // padding parameters
755 int(sourcePaddingElements), int(yTargetPaddingElements), int(uTargetPaddingElements), int(vTargetPaddingElements),
756
757 // multiplication parameters
758 33, -19, 56, 64, -37, -47, 13, 56, -9,
759
760 // bias/translation parameters
761 16, 128, 128
762 };
763
764 void* target[3] =
765 {
766 yTarget,
767 uTarget,
768 vTarget
769 };
770
772}
773
774inline void FrameConverterRGB24::convertRGB24FullRangeToY_V_U12LimitedRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker)
775{
776 // just swapping u- and v-plane, and calling converter to Y_U_V12
777
778 convertRGB24FullRangeToY_U_V12LimitedRange(source, yTarget, uTarget, vTarget, width, height, flag, sourcePaddingElements, yTargetPaddingElements, uTargetPaddingElements, vTargetPaddingElements, worker);
779}
780
781inline void FrameConverterRGB24::convertRGB24FullRangeToY_U_V12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker)
782{
783 ocean_assert(source != nullptr && yTarget != nullptr && uTarget != nullptr && vTarget != nullptr);
784
785 ocean_assert(width >= 2u && width % 2u == 0u);
786 ocean_assert(height >= 2u && height % 2u == 0u);
787
788 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
789 {
790 return;
791 }
792
793 /*
794 * RGB input value range: [0, 255]x[0, 255]x[0, 255]
795 * YUV output value range: [0, 255]x[0, 255]x[0, 255]
796 *
797 * | Y | | 0.299 0.587 0.114 0 | | R |
798 * | U | = | -0.168736 -0.331264 0.5 128 | * | G |
799 * | V | | 0.5 -0.418688 -0.081312 128 | | B |
800 * | 1 |
801 * Approximation with 7 bit precision:
802 * | Y | | 38 75 15 0 * 128 | | R |
803 * 128 * | U | = | -22 -42 64 128 * 128 | * | G |
804 * | V | | 64 -54 -10 128 * 128 | | B |
805 * | 1 |
806 */
807
808 const int options[4 + 9 + 3] =
809 {
810 // padding parameters
811 int(sourcePaddingElements), int(yTargetPaddingElements), int(uTargetPaddingElements), int(vTargetPaddingElements),
812
813 // multiplication parameters
814 38, -22, 64, 75, -42, -54, 15, 64, -10,
815
816 // bias/translation parameters
817 0, 128, 128
818 };
819
820 void* target[3] =
821 {
822 yTarget,
823 uTarget,
824 vTarget
825 };
826
828}
829
830inline void FrameConverterRGB24::convertRGB24FullRangeToY_V_U12FullRange(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker)
831{
832 // just swapping u- and v-plane, and calling converter to Y_U_V12
833
834 convertRGB24FullRangeToY_U_V12FullRange(source, yTarget, uTarget, vTarget, width, height, flag, sourcePaddingElements, yTargetPaddingElements, uTargetPaddingElements, vTargetPaddingElements, worker);
835}
836
837inline void FrameConverterRGB24::changeRGB24ToYUV24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker)
838{
839 ocean_assert(frame);
840
841 if (worker)
842 {
843 worker->executeFunction(Worker::Function::createStatic(&FrameConverterRGB24::changeRGB24ToYUV24Subset, frame, width, 0u, 0u), 0u, height, 2u, 3u, 100u);
844 }
845 else
846 {
847 changeRGB24ToYUV24Subset(frame, width, 0u, height);
848 }
849}
850
851inline void FrameConverterRGB24::convertRGB24ToYUV24Pixel(const uint8_t* rgb, uint8_t* yuv)
852{
853 ocean_assert(rgb && yuv);
854
855 yuv[0] = uint8_t(((rgb[0] * 66 + rgb[1] * 129 + rgb[2] * 25 + 128) >> 8) + 16);
856 yuv[1] = uint8_t(((rgb[0] * -38 - rgb[1] * 74 + rgb[2] * 112 + 128) >> 8) + 128);
857 yuv[2] = uint8_t(((rgb[0] * 112 - rgb[1] * 94 - rgb[2] * 18 + 128) >> 8) + 128);
858
859 ocean_assert(abs(int(yuv[0]) - int(((rgb[0] * 66 + rgb[1] * 129 + rgb[2] * 25 + 128) / 256) + 16)) <= 1);
860 ocean_assert(abs(int(yuv[1]) - int(((rgb[0] * -38 - rgb[1] * 74 + rgb[2] * 112 + 128) / 256) + 128)) <= 1);
861 ocean_assert(abs(int(yuv[2]) - int(((rgb[0] * 112 - rgb[1] * 94 - rgb[2] * 18 + 128) / 256) + 128)) <= 1);
862}
863
864inline void FrameConverterRGB24::convertRGB24ToR_G_B24(const uint8_t* source, uint8_t* rTarget, uint8_t* gTarget, uint8_t* bTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int rTargetPaddingElements, const unsigned int gTargetPaddingElements, const unsigned int bTargetPaddingElements, Worker* worker)
865{
866 ocean_assert(source != nullptr && rTarget != nullptr && gTarget != nullptr && bTarget != nullptr);
867
868 if (width < 1u || height < 1u)
869 {
870 return;
871 }
872
873 const unsigned int options[4] = {sourcePaddingElements, rTargetPaddingElements, gTargetPaddingElements, bTargetPaddingElements};
874
875 void* targets[3] =
876 {
877 rTarget,
878 gTarget,
879 bTarget
880 };
881
882 FrameConverter::convertArbitraryPixelFormat((const void**)(&source), targets, width, height, flag, 1u, FrameConverter::mapOneRow_1Plane3Channels_To_3Plane1Channel_8BitPerChannel<0u, 1u, 2u>, options, worker);
883}
884
885#if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
886
887OCEAN_FORCE_INLINE void FrameConverterRGB24::convert16PixelsRGB24ToYUV24Precision7BitNEON(const uint8_t* const source, uint8_t* const target)
888{
889 ocean_assert(source != nullptr && target != nullptr);
890
891 // the documentation of this function designed for RGB24 to YUV24 conversion
892
893 // precise color space conversion:
894 // | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
895 // | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
896 // | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
897 // | 1 |
898
899 // approximation:
900 // Y = ( 33 * R + 64 * G + 13 * B) / 128 + 16
901 // U = (-19 * R - 37 * G + 56 * B) / 128 + 128
902 // V = ( 56 * R - 47 * G - 9 * B) / 128 + 128
903
904 // we load 8 pixels (= 3 * 8 values) and directly deinterleave the 3 channels so that we receive the following patterns:
905 // source_u_8x8x3.val[0]: R R R R R R R R
906 // source_u_8x8x3.val[1]: G G G G G G G G
907 // source_u_8x8x3.val[2]: B B B B B B B B
908
909 const uint8x16x3_t source_u_8x16x3 = vld3q_u8(source);
910
911 const uint8x8_t source0_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[0]);
912 const uint8x8_t source0_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[0]);
913
914 const uint8x8_t source1_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[1]);
915 const uint8x8_t source1_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[1]);
916
917 const uint8x8_t source2_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[2]);
918 const uint8x8_t source2_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[2]);
919
920
921 const uint8x8_t constant33_u_8x8 = vdup_n_u8(33);
922 uint16x8_t intermediateResults0_low_u_16x8 = vmull_u8(source0_low_u_8x8, constant33_u_8x8);
923 uint16x8_t intermediateResults0_high_u_16x8 = vmull_u8(source0_high_u_8x8, constant33_u_8x8);
924
925 const uint8x8_t constant64_u_8x8 = vdup_n_u8(64);
926 intermediateResults0_low_u_16x8 = vmlal_u8(intermediateResults0_low_u_16x8, source1_low_u_8x8, constant64_u_8x8);
927 intermediateResults0_high_u_16x8 = vmlal_u8(intermediateResults0_high_u_16x8, source1_high_u_8x8, constant64_u_8x8);
928
929 const uint8x8_t constant13_u_8x8 = vdup_n_u8(13);
930 intermediateResults0_low_u_16x8 = vmlal_u8(intermediateResults0_low_u_16x8, source2_low_u_8x8, constant13_u_8x8);
931 intermediateResults0_high_u_16x8 = vmlal_u8(intermediateResults0_high_u_16x8, source2_high_u_8x8, constant13_u_8x8);
932
933
934 const uint8x8_t constant56_u_8x8 = vdup_n_u8(56);
935 uint16x8_t intermediateResults1_low_u_16x8 = vmull_u8(source2_low_u_8x8, constant56_u_8x8);
936 uint16x8_t intermediateResults1_high_u_16x8 = vmull_u8(source2_high_u_8x8, constant56_u_8x8);
937
938 uint16x8_t intermediateResults2_low_u_16x8 = vmull_u8(source0_low_u_8x8, constant56_u_8x8);
939 uint16x8_t intermediateResults2_high_u_16x8 = vmull_u8(source0_high_u_8x8, constant56_u_8x8);
940
941
942 const uint8x8_t constant19_u_8x8 = vdup_n_u8(19);
943 intermediateResults1_low_u_16x8 = vmlsl_u8(intermediateResults1_low_u_16x8, source0_low_u_8x8, constant19_u_8x8);
944 intermediateResults1_high_u_16x8 = vmlsl_u8(intermediateResults1_high_u_16x8, source0_high_u_8x8, constant19_u_8x8);
945
946 const uint8x8_t constant37_u_8x8 = vdup_n_u8(37);
947 intermediateResults1_low_u_16x8 = vmlsl_u8(intermediateResults1_low_u_16x8, source1_low_u_8x8, constant37_u_8x8);
948 intermediateResults1_high_u_16x8 = vmlsl_u8(intermediateResults1_high_u_16x8, source1_high_u_8x8, constant37_u_8x8);
949
950
951 const uint8x8_t constant47_u_8x8 = vdup_n_u8(47);
952 intermediateResults2_low_u_16x8 = vmlsl_u8(intermediateResults2_low_u_16x8, source1_low_u_8x8, constant47_u_8x8);
953 intermediateResults2_high_u_16x8 = vmlsl_u8(intermediateResults2_high_u_16x8, source1_high_u_8x8, constant47_u_8x8);
954
955 const uint8x8_t constant9_u_8x8 = vdup_n_u8(9);
956 intermediateResults2_low_u_16x8 = vmlsl_u8(intermediateResults2_low_u_16x8, source2_low_u_8x8, constant9_u_8x8);
957 intermediateResults2_high_u_16x8 = vmlsl_u8(intermediateResults2_high_u_16x8, source2_high_u_8x8, constant9_u_8x8);
958
959
960 const int16x8_t constant16_s_16x8 = vdupq_n_s16(16 * 128);
961 const int16x8_t constant128_s_16x8 = vdupq_n_s16(128 * 128);
962
963 const int16x8_t intermediateResults0_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults0_low_u_16x8), constant16_s_16x8);
964 const int16x8_t intermediateResults0_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults0_high_u_16x8), constant16_s_16x8);
965
966 const int16x8_t intermediateResults1_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults1_low_u_16x8), constant128_s_16x8);
967 const int16x8_t intermediateResults1_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults1_high_u_16x8), constant128_s_16x8);
968
969 const int16x8_t intermediateResults2_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults2_low_u_16x8), constant128_s_16x8);
970 const int16x8_t intermediateResults2_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults2_high_u_16x8), constant128_s_16x8);
971
972 // saturated narrow signed to unsigned
973
974 uint8x16x3_t results_u_8x16x3;
975 results_u_8x16x3.val[0] = vcombine_u8(vqrshrun_n_s16(intermediateResults0_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults0_high_s_16x8, 7));
976 results_u_8x16x3.val[1] = vcombine_u8(vqrshrun_n_s16(intermediateResults1_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults1_high_s_16x8, 7));
977 results_u_8x16x3.val[2] = vcombine_u8(vqrshrun_n_s16(intermediateResults2_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults2_high_s_16x8, 7));
978
979 // and we can store the result
980 vst3q_u8(target, results_u_8x16x3);
981}
982
983#endif // OCEAN_HARDWARE_NEON_VERSION >= 10
984
985}
986
987}
988
989#endif // META_OCEAN_CV_FRAME_CONVERTER_RGB_24_H
static void convertRow3ChannelsTo3Channels8BitPerChannel7BitPrecision(const uint8_t *source, uint8_t *target, const size_t size, const void *parameters)
Converts a row of pixels with 3 channels to pixels with 3 channels by a linear combination of the thr...
This is the base class for all frame converter classes.
Definition FrameConverter.h:32
ConversionFlag
Definition of individual conversion flags.
Definition FrameConverter.h:39
static void convertGenericPixelFormat(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourceStrideElements, const unsigned int targetStrideElements, const ConversionFlag flag, const RowConversionFunction< TSource, TTarget > rowConversionFunction, const RowReversePixelOrderInPlaceFunction< TTarget > targetReversePixelOrderInPlaceFunction, const bool areContinuous, const void *options, Worker *worker)
Converts a frame with generic pixel format (e.g., RGBA32, BGR24, YUV24, ...) to a frame with generic ...
Definition FrameConverter.h:3211
static void convertTwoRows_1Plane3Channels_To_1Plane1ChannelAnd2Planes1ChannelsDownsampled2x2_8BitPerChannel_Precision7Bit(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Converts two rows of an image with e.g., a RGB pixel format to two rows of an image with e....
static void convertTwoRows_1Plane3Channels_To_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_8BitPerChannel_Precision7Bit(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Converts two rows of an image with e.g., a RGB pixel format to two rows of an image with e....
static void convertArbitraryPixelFormat(const void **sources, void **targets, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int multipleRowsPerIteration, const MultipleRowsConversionFunction multipleRowsConversionFunction, const void *options, Worker *worker)
Converts a frame with arbitrary pixel format (e.g., Y_UV12, Y_VU12, YUYV16, ...) to a frame with arbi...
Definition FrameConverter.h:3234
This class provides functions to convert or to change frames with RGB pixel format.
Definition FrameConverterRGB24.h:28
static void convertRGB24FullRangeToY_VU12FullRange(const uint8_t *source, uint8_t *yTarget, uint8_t *vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a full range Y_VU12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:677
static void changeRGB24ToBGR24(uint8_t *frame, const unsigned int width, const unsigned int height, Worker *worker=nullptr)
Changes a RGB 24 bit frame to a BGR 24 bit frame in place.
Definition FrameConverterRGB24.h:415
static void convertRGB24ToRGB24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a RGB 24 bit frame.
Definition FrameConverterRGB24.h:458
static void convertRGB24FullRangeToY_VU12LimitedRange(const uint8_t *source, uint8_t *yTarget, uint8_t *vuTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vuTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a limited range Y_VU12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:581
static void convertRGB24FullRangeToY_UV12FullRange(const uint8_t *source, uint8_t *yTarget, uint8_t *uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a full range Y_UV12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:629
static OCEAN_FORCE_INLINE void convert16PixelsRGB24ToYUV24Precision7BitNEON(const uint8_t *const source, uint8_t *const target)
Converts 16 RGB24 pixels to 16 YUV24 pixels by using NEON instructions.
Definition FrameConverterRGB24.h:887
static void convertRGB24FullRangeToY_V_U12LimitedRange(const uint8_t *source, uint8_t *yTarget, uint8_t *vTarget, uint8_t *uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a limited range Y_V_U12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:774
static void convertRGB24ToARGB32(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue=0xFF, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a ARGB 32 bit frame.
Definition FrameConverterRGB24.h:399
static void convertRGB24ToR_G_B24(const uint8_t *source, uint8_t *rTarget, uint8_t *gTarget, uint8_t *bTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int rTargetPaddingElements, const unsigned int gTargetPaddingElements, const unsigned int bTargetPaddingElements, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a R_G_B 24 bit frame.
Definition FrameConverterRGB24.h:864
static void convertRGB24FullRangeToY_U_V12FullRange(const uint8_t *source, uint8_t *yTarget, uint8_t *uTarget, uint8_t *vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a full range Y_U_V12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:781
static void convertRGB24ToBGR24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a BGR 24 bit frame.
Definition FrameConverterRGB24.h:407
static void convertRGB24FullRangeToY_UV12LimitedRange(const uint8_t *source, uint8_t *yTarget, uint8_t *uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a limited range Y_UV12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:533
static void convertRGB24FullRangeToY_U_V12LimitedRange(const uint8_t *source, uint8_t *yTarget, uint8_t *uTarget, uint8_t *vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a limited range Y_U_V12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:725
static void changeRGB24ToBGR24Subset(uint8_t *frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows)
Changes a subset of RGB 24 bit frame to a BGR 24 bit frame.
static void convertRGB24ToBGR32(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker)
Converts a RGB 24 bit frame to a BGR 32 bit frame.
Definition FrameConverterRGB24.h:430
static void convertRGB24ToYUV24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a YUV 24 bit frame by the exact conversion.
Definition FrameConverterRGB24.h:503
static void convertRGB24FullRangeToY_V_U12FullRange(const uint8_t *source, uint8_t *yTarget, uint8_t *vTarget, uint8_t *uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker *worker=nullptr)
Converts a full range RGB24 frame to a full range Y_V_U12 frame with 7-bit precision using BT....
Definition FrameConverterRGB24.h:830
static void convertRGB24ToRGBA32(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue=0xFF, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a RGBA 32 bit frame.
Definition FrameConverterRGB24.h:474
static void convertRGB24ToYUV24RowPrecision7BitNEON(const uint8_t *source, uint8_t *target, const size_t size, const void *parameters)
Converts a RGB 24 bit row to a YUV 24 bit row by using NEON instructions.
static void convertRGB24ToY8(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a RGB frame to a gray scale frame.
Definition FrameConverterRGB24.h:482
static void convertRGB24ToRGB32(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a RGB 32 bit frame.
Definition FrameConverterRGB24.h:466
static void changeRGB24ToYUV24(uint8_t *frame, const unsigned int width, const unsigned int height, Worker *worker=nullptr)
Changes a RGB 24 bit frame to a YUV 24 bit frame by the exact conversion in place.
Definition FrameConverterRGB24.h:837
static void convertRGB24ToBGRA32(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue=0xFF, Worker *worker=nullptr)
Converts a RGB 24 bit frame to a BGRA 32 bit frame.
Definition FrameConverterRGB24.h:444
static void changeRGB24ToYUV24Subset(uint8_t *frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows)
Changes a subset of a RGB 24 bit frame to a YUV 24 bit frame by exact conversion.
static void convertRGB24ToYUV24Pixel(const uint8_t *rgb, uint8_t *yuv)
Converts one RGB 24 bit pixel to one YUV 24 bit pixel.
Definition FrameConverterRGB24.h:851
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2876
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
The namespace covering the entire Ocean framework.
Definition Accessor.h:15