Ocean
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"
13 #include "ocean/cv/FrameChannels.h"
14 
15 #include "ocean/base/Worker.h"
16 
17 namespace Ocean
18 {
19 
20 namespace CV
21 {
22 
23 /**
24  * This class provides functions to convert or to change frames with RGB pixel format.
25  * @ingroup cv
26  */
27 class 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 full 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  protected:
340 
341  /**
342  * Changes a subset of RGB 24 bit frame to a BGR 24 bit frame.
343  * @param frame The frame buffer to be changed, must be valid
344  * @param width The width of the frame in pixel, with range (0, infinity)
345  * @param firstRow First (including) row to convert, with range [0, height)
346  * @param numberRows Number of rows to convert, with range [1, height]
347  */
348  static void changeRGB24ToBGR24Subset(uint8_t* frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows);
349 
350  /**
351  * Changes a subset of a RGB 24 bit frame to a YUV 24 bit frame by exact conversion.
352  * @param frame The frame buffer to be changed, must be valid
353  * @param width The width of the frame in pixel, with range (0, infinity)
354  * @param firstRow First (including) row to convert, with range [0, height)
355  * @param numberRows Number of rows to convert, with range [1, height]
356  */
357  static void changeRGB24ToYUV24Subset(uint8_t* frame, const unsigned int width, const unsigned int firstRow, const unsigned int numberRows);
358 
359 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
360 
361  /**
362  * Converts a RGB 24 bit row to a YUV 24 bit row by using NEON instructions.
363  * Beware: This function uses hard-coded conversion parameters which improves execution performance while also increases binary size when used.
364  * @param source The pointer to the source pixels, must be valid
365  * @param target The pointer to the target pixels receiving the converted pixel data, must be valid
366  * @param size The number of source (and target pixels) to convert, with range [1, infinity)
367  * @param parameters Unused parameters, must be nullptr
368  */
369  static void convertRGB24ToYUV24RowPrecision7BitNEON(const uint8_t* source, uint8_t* target, const size_t size, const void* parameters);
370 
371  /**
372  * Converts 16 RGB24 pixels to 16 YUV24 pixels by using NEON instructions.
373  * Beware: This function uses hard-coded conversion parameters which improves execution performance while also increases binary size when used.
374  * @param source The pointer to the 16 source pixels (with 3 channels = 48 bytes) to convert, must be valid
375  * @param target The pointer to the 16 target pixels (with 3 channels = 48 bytes) receiving the converted pixel data, must be valid
376  */
377  static OCEAN_FORCE_INLINE void convert16PixelsRGB24ToYUV24Precision7BitNEON(const uint8_t* const source, uint8_t* const target);
378 
379 #endif // OCEAN_HARDWARE_NEON_VERSION >= 10
380 };
381 
382 inline 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)
383 {
384  ocean_assert(source != nullptr && target != nullptr);
385  ocean_assert(width >= 1u && height >= 1u);
386 
387  FrameChannels::addFirstChannelValue<uint8_t, 3u>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
388 }
389 
390 inline 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)
391 {
392  ocean_assert(source != nullptr && target != nullptr);
393  ocean_assert(width >= 1u && height >= 1u);
394 
395  FrameChannels::reverseChannelOrder<uint8_t, 3u>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
396 }
397 
398 inline void FrameConverterRGB24::changeRGB24ToBGR24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker)
399 {
400  ocean_assert(frame);
401  ocean_assert(width != 0u && height != 0u);
402 
403  if (worker)
404  {
405  worker->executeFunction(Worker::Function::createStatic(&FrameConverterRGB24::changeRGB24ToBGR24Subset, frame, width, 0u, 0u), 0u, height, 2u, 3u, 100u);
406  }
407  else
408  {
409  changeRGB24ToBGR24Subset(frame, width, 0u, height);
410  }
411 }
412 
413 inline 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)
414 {
415  ocean_assert(source != nullptr && target != nullptr);
416  ocean_assert(width >= 1u && height >= 1u);
417 
418  // source frame R G B
419  // 0 1 2
420  // target frame B G R -
421  // pattern 2 1 0
422  constexpr unsigned int shufflePattern = 0x012u;
423 
424  FrameChannels::shuffleChannelsAndSetLastChannelValue<uint8_t, 3u, 4u, shufflePattern>(source, 0u, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
425 }
426 
427 inline 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)
428 {
429  ocean_assert(source != nullptr && target != nullptr);
430  ocean_assert(width >= 1u && height >= 1u);
431 
432  // source frame R G B
433  // 0 1 2
434  // target frame B G R A
435  // pattern 2 1 0
436  constexpr unsigned int shufflePattern = 0x012u;
437 
438  FrameChannels::shuffleChannelsAndSetLastChannelValue<uint8_t, 3u, 4u, shufflePattern>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
439 }
440 
441 inline 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)
442 {
443  ocean_assert(source != nullptr && target != nullptr);
444  ocean_assert(width >= 1u && height >= 1u);
445 
446  FrameChannels::transformGeneric<uint8_t, 3u>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
447 }
448 
449 inline 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)
450 {
451  ocean_assert(source != nullptr && target != nullptr);
452  ocean_assert(width >= 1u && height >= 1u);
453 
454  FrameChannels::addLastChannelValue<uint8_t, 3u>(source, 0u, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
455 }
456 
457 inline 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)
458 {
459  ocean_assert(source != nullptr && target != nullptr);
460  ocean_assert(width >= 1u && height >= 1u);
461 
462  FrameChannels::addLastChannelValue<uint8_t, 3u>(source, alphaValue, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
463 }
464 
465 inline 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)
466 {
467  ocean_assert(source != nullptr && target != nullptr);
468  ocean_assert(width >= 1u && height >= 1u);
469 
470  const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
471  const unsigned int targetStrideElements = width + targetPaddingElements;
472 
473  constexpr unsigned int channelFactors[3] = {38u, 75u, 15u}; // 38/128 ~ 0.299, 75/128 ~ 0.587, 15/128 ~ 0.114
474 
475  static_assert(channelFactors[0] + channelFactors[1] + channelFactors[2] == 128u, "Invalid factors!");
476 
477  constexpr bool useFactorChannel0 = channelFactors[0] != 0u;
478  constexpr bool useFactorChannel1 = channelFactors[1] != 0u;
479  constexpr bool useFactorChannel2 = channelFactors[2] != 0u;
480 
481  const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
482 
483  FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo1Channel8BitPerChannel7BitPrecision<useFactorChannel0, useFactorChannel1, useFactorChannel2>, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 1u>, areContinuous, channelFactors, worker);
484 }
485 
486 inline 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)
487 {
488  ocean_assert(source != nullptr && target != nullptr);
489  ocean_assert(width >= 1u && height >= 1u);
490 
491  const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
492  const unsigned int targetStrideElements = width * 3u + targetPaddingElements;
493 
494 #if defined(OCEAN_USE_HARDCODED_RGB24_TO_YUV24_CONVERTER) && OCEAN_HARDWARE_NEON_VERSION >= 10
495 
496  // we keep this function mainly to show the performance difference between the hard-coded implementation and a variable implementation
497 
498  FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, FrameConverterRGB24::convertRGB24ToYUV24RowPrecision7BitNEON, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, nullptr, worker);
499 
500 #else
501 
502  // approximation:
503  // Y = ( 33 * R + 64 * G + 13 * B) / 128 + 16
504  // U = (-19 * R - 37 * G + 56 * B) / 128 + 128
505  // V = ( 56 * R - 47 * G - 9 * B) / 128 + 128
506 
507  const int parameters[12] = {33, -19, 56, 64, -37, -47, 13, 56, -9, 16, 128, 128};
508 
509  const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
510 
511  FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo3Channels8BitPerChannel7BitPrecision, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, areContinuous, parameters, worker);
512 
513 #endif
514 }
515 
516 inline 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)
517 {
518  ocean_assert(source != nullptr && yTarget != nullptr && uvTarget != nullptr);
519 
520  ocean_assert(width >= 2u && width % 2u == 0u);
521  ocean_assert(height >= 2u && height % 2u == 0u);
522 
523  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
524  {
525  return;
526  }
527 
528  /*
529  * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
530  * YUV output value range: [16, 235]x[16, 240]x[16, 240]
531  *
532  * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
533  * | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
534  * | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
535  * | 1 |
536  * Approximation with 7 bit precision:
537  * | Y | | 33 64 13 16 * 128 | | R |
538  * 128 * | U | = | -19 -37 56 128 * 128 | * | G |
539  * | V | | 56 -47 -9 128 * 128 | | B |
540  * | 1 |
541  */
542 
543  const int options[3 + 9 + 3] =
544  {
545  // padding parameters
546  int(sourcePaddingElements), int(yTargetPaddingElements), int(uvTargetPaddingElements),
547 
548  // multiplication parameters
549  33, -19, 56, 64, -37, -47, 13, 56, -9,
550 
551  // bias/translation parameters
552  16, 128, 128
553  };
554 
555  void* target[2] =
556  {
557  yTarget,
558  uvTarget,
559  };
560 
562 }
563 
564 inline 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)
565 {
566  ocean_assert(source != nullptr && yTarget != nullptr && vuTarget != nullptr);
567 
568  ocean_assert(width >= 2u && width % 2u == 0u);
569  ocean_assert(height >= 2u && height % 2u == 0u);
570 
571  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
572  {
573  return;
574  }
575 
576  /*
577  * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
578  * YVU output value range: [16, 235]x[16, 240]x[16, 240]
579  *
580  * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
581  * | V | = | 0.4375 -0.3671875 -0.0703125 128.0 | * | G |
582  * | U | | -0.1484375 -0.2890625 0.4375 128.0 | | B |
583  * | 1 |
584  * Approximation with 7 bit precision:
585  * | Y | | 33 64 13 16 * 128 | | R |
586  * 128 * | V | = | 56 -47 -9 128 * 128 | * | G |
587  * | U | | -19 -37 56 128 * 128 | | B |
588  * | 1 |
589  */
590 
591  const int options[3 + 9 + 3] =
592  {
593  // padding parameters
594  int(sourcePaddingElements), int(yTargetPaddingElements), int(vuTargetPaddingElements),
595 
596  // multiplication parameters
597  33, 56, -19, 64, -47, -37, 13, -9, 56,
598 
599  // bias/translation parameters
600  16, 128, 128
601  };
602 
603  void* target[2] =
604  {
605  yTarget,
606  vuTarget
607  };
608 
610 }
611 
612 inline 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)
613 {
614  ocean_assert(source != nullptr && yTarget != nullptr && uvTarget != nullptr);
615 
616  ocean_assert(width >= 2u && width % 2u == 0u);
617  ocean_assert(height >= 2u && height % 2u == 0u);
618 
619  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
620  {
621  return;
622  }
623 
624  /*
625  * RGB input value range: [0, 255]x[0, 255]x[0, 255]
626  * YUV output value range: [0, 255]x[0, 255]x[0, 255]
627  *
628  * | Y | | 0.299 0.587 0.114 0 | | R |
629  * | U | = | -0.168736 -0.331264 0.5 128 | * | G |
630  * | V | | 0.5 -0.418688 -0.081312 128 | | B |
631  * | 1 |
632  * Approximation with 7 bit precision:
633  * | Y | | 38 75 15 0 * 128 | | R |
634  * 128 * | U | = | -22 -42 64 128 * 128 | * | G |
635  * | V | | 64 -54 -10 128 * 128 | | B |
636  * | 1 |
637  */
638 
639  const int options[3 + 9 + 3] =
640  {
641  // padding parameters
642  int(sourcePaddingElements), int(yTargetPaddingElements), int(uvTargetPaddingElements),
643 
644  // multiplication parameters
645  38, -22, 64, 75, -42, -54, 15, 64, -10,
646 
647  // bias/translation parameters
648  0, 128, 128
649  };
650 
651  void* target[2] =
652  {
653  yTarget,
654  uvTarget
655  };
656 
658 }
659 
660 inline 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)
661 {
662  ocean_assert(source != nullptr && yTarget != nullptr && vuTarget != nullptr);
663 
664  ocean_assert(width >= 2u && width % 2u == 0u);
665  ocean_assert(height >= 2u && height % 2u == 0u);
666 
667  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
668  {
669  return;
670  }
671 
672  /*
673  * RGB input value range: [0, 255]x[0, 255]x[0, 255]
674  * YVU output value range: [0, 255]x[0, 255]x[0, 255]
675  *
676  * | Y | | 0.299 0.587 0.114 0 | | R |
677  * | V | = | 0.5 -0.418688 -0.081312 128 | * | G |
678  * | U | | -0.168736 -0.331264 0.5 128 | | B |
679  * | 1 |
680  * Approximation with 7 bit precision:
681  * | Y | | 38 75 15 0 * 128 | | R |
682  * 128 * | V | = | 64 -54 -10 128 * 128 | * | G |
683  * | U | | -22 -42 64 128 * 128 | | B |
684  * | 1 |
685  */
686 
687  const int options[3 + 9 + 3] =
688  {
689  // padding parameters
690  int(sourcePaddingElements), int(yTargetPaddingElements), int(vuTargetPaddingElements),
691 
692  // multiplication parameters
693  38, 64, -22, 75, -54, -42, 15, -10, 64,
694 
695  // bias/translation parameters
696  0, 128, 128
697  };
698 
699  void* target[2] =
700  {
701  yTarget,
702  vuTarget
703  };
704 
706 }
707 
708 inline 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)
709 {
710  ocean_assert(source != nullptr && yTarget != nullptr && uTarget != nullptr && vTarget != nullptr);
711 
712  ocean_assert(width >= 2u && width % 2u == 0u);
713  ocean_assert(height >= 2u && height % 2u == 0u);
714 
715  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
716  {
717  return;
718  }
719 
720  /*
721  * RGB input value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
722  * YUV output value range: [16, 235]x[16, 240]x[16, 240]
723  *
724  * | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
725  * | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
726  * | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
727  * | 1 |
728  * Approximation with 7 bit precision:
729  * | Y | | 33 64 13 16 * 128 | | R |
730  * 128 * | U | = | -19 -37 56 128 * 128 | * | G |
731  * | V | | 56 -47 -9 128 * 128 | | B |
732  * | 1 |
733  */
734 
735  const int options[4 + 9 + 3] =
736  {
737  // padding parameters
738  int(sourcePaddingElements), int(yTargetPaddingElements), int(uTargetPaddingElements), int(vTargetPaddingElements),
739 
740  // multiplication parameters
741  33, -19, 56, 64, -37, -47, 13, 56, -9,
742 
743  // bias/translation parameters
744  16, 128, 128
745  };
746 
747  void* target[3] =
748  {
749  yTarget,
750  uTarget,
751  vTarget
752  };
753 
755 }
756 
757 inline 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)
758 {
759  // just swapping u- and v-plane, and calling converter to Y_U_V12
760 
761  convertRGB24FullRangeToY_U_V12LimitedRange(source, yTarget, uTarget, vTarget, width, height, flag, sourcePaddingElements, yTargetPaddingElements, uTargetPaddingElements, vTargetPaddingElements, worker);
762 }
763 
764 inline 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)
765 {
766  ocean_assert(source != nullptr && yTarget != nullptr && uTarget != nullptr && vTarget != nullptr);
767 
768  ocean_assert(width >= 2u && width % 2u == 0u);
769  ocean_assert(height >= 2u && height % 2u == 0u);
770 
771  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
772  {
773  return;
774  }
775 
776  /*
777  * RGB input value range: [0, 255]x[0, 255]x[0, 255]
778  * YUV output value range: [0, 255]x[0, 255]x[0, 255]
779  *
780  * | Y | | 0.299 0.587 0.114 0 | | R |
781  * | U | = | -0.168736 -0.331264 0.5 128 | * | G |
782  * | V | | 0.5 -0.418688 -0.081312 128 | | B |
783  * | 1 |
784  * Approximation with 7 bit precision:
785  * | Y | | 38 75 15 0 * 128 | | R |
786  * 128 * | U | = | -22 -42 64 128 * 128 | * | G |
787  * | V | | 64 -54 -10 128 * 128 | | B |
788  * | 1 |
789  */
790 
791  const int options[4 + 9 + 3] =
792  {
793  // padding parameters
794  int(sourcePaddingElements), int(yTargetPaddingElements), int(uTargetPaddingElements), int(vTargetPaddingElements),
795 
796  // multiplication parameters
797  38, -22, 64, 75, -42, -54, 15, 64, -10,
798 
799  // bias/translation parameters
800  0, 128, 128
801  };
802 
803  void* target[3] =
804  {
805  yTarget,
806  uTarget,
807  vTarget
808  };
809 
811 }
812 
813 inline 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)
814 {
815  // just swapping u- and v-plane, and calling converter to Y_U_V12
816 
817  convertRGB24FullRangeToY_U_V12FullRange(source, yTarget, uTarget, vTarget, width, height, flag, sourcePaddingElements, yTargetPaddingElements, uTargetPaddingElements, vTargetPaddingElements, worker);
818 }
819 
820 inline void FrameConverterRGB24::changeRGB24ToYUV24(uint8_t* frame, const unsigned int width, const unsigned int height, Worker* worker)
821 {
822  ocean_assert(frame);
823 
824  if (worker)
825  {
826  worker->executeFunction(Worker::Function::createStatic(&FrameConverterRGB24::changeRGB24ToYUV24Subset, frame, width, 0u, 0u), 0u, height, 2u, 3u, 100u);
827  }
828  else
829  {
830  changeRGB24ToYUV24Subset(frame, width, 0u, height);
831  }
832 }
833 
834 inline void FrameConverterRGB24::convertRGB24ToYUV24Pixel(const uint8_t* rgb, uint8_t* yuv)
835 {
836  ocean_assert(rgb && yuv);
837 
838  yuv[0] = uint8_t(((rgb[0] * 66 + rgb[1] * 129 + rgb[2] * 25 + 128) >> 8) + 16);
839  yuv[1] = uint8_t(((rgb[0] * -38 - rgb[1] * 74 + rgb[2] * 112 + 128) >> 8) + 128);
840  yuv[2] = uint8_t(((rgb[0] * 112 - rgb[1] * 94 - rgb[2] * 18 + 128) >> 8) + 128);
841 
842  ocean_assert(abs(int(yuv[0]) - int(((rgb[0] * 66 + rgb[1] * 129 + rgb[2] * 25 + 128) / 256) + 16)) <= 1);
843  ocean_assert(abs(int(yuv[1]) - int(((rgb[0] * -38 - rgb[1] * 74 + rgb[2] * 112 + 128) / 256) + 128)) <= 1);
844  ocean_assert(abs(int(yuv[2]) - int(((rgb[0] * 112 - rgb[1] * 94 - rgb[2] * 18 + 128) / 256) + 128)) <= 1);
845 }
846 
847 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
848 
849 OCEAN_FORCE_INLINE void FrameConverterRGB24::convert16PixelsRGB24ToYUV24Precision7BitNEON(const uint8_t* const source, uint8_t* const target)
850 {
851  ocean_assert(source != nullptr && target != nullptr);
852 
853  // the documentation of this function designed for RGB24 to YUV24 conversion
854 
855  // precise color space conversion:
856  // | Y | | 0.2578125 0.5039063 0.09765625 16.0 | | R |
857  // | U | = | -0.1484375 -0.2890625 0.4375 128.0 | * | G |
858  // | V | | 0.4375 -0.3671875 -0.0703125 128.0 | | B |
859  // | 1 |
860 
861  // approximation:
862  // Y = ( 33 * R + 64 * G + 13 * B) / 128 + 16
863  // U = (-19 * R - 37 * G + 56 * B) / 128 + 128
864  // V = ( 56 * R - 47 * G - 9 * B) / 128 + 128
865 
866  // we load 8 pixels (= 3 * 8 values) and directly deinterleave the 3 channels so that we receive the following patterns:
867  // source_u_8x8x3.val[0]: R R R R R R R R
868  // source_u_8x8x3.val[1]: G G G G G G G G
869  // source_u_8x8x3.val[2]: B B B B B B B B
870 
871  const uint8x16x3_t source_u_8x16x3 = vld3q_u8(source);
872 
873  const uint8x8_t source0_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[0]);
874  const uint8x8_t source0_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[0]);
875 
876  const uint8x8_t source1_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[1]);
877  const uint8x8_t source1_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[1]);
878 
879  const uint8x8_t source2_low_u_8x8 = vget_low_u8(source_u_8x16x3.val[2]);
880  const uint8x8_t source2_high_u_8x8 = vget_high_u8(source_u_8x16x3.val[2]);
881 
882 
883  const uint8x8_t constant33_u_8x8 = vdup_n_u8(33);
884  uint16x8_t intermediateResults0_low_u_16x8 = vmull_u8(source0_low_u_8x8, constant33_u_8x8);
885  uint16x8_t intermediateResults0_high_u_16x8 = vmull_u8(source0_high_u_8x8, constant33_u_8x8);
886 
887  const uint8x8_t constant64_u_8x8 = vdup_n_u8(64);
888  intermediateResults0_low_u_16x8 = vmlal_u8(intermediateResults0_low_u_16x8, source1_low_u_8x8, constant64_u_8x8);
889  intermediateResults0_high_u_16x8 = vmlal_u8(intermediateResults0_high_u_16x8, source1_high_u_8x8, constant64_u_8x8);
890 
891  const uint8x8_t constant13_u_8x8 = vdup_n_u8(13);
892  intermediateResults0_low_u_16x8 = vmlal_u8(intermediateResults0_low_u_16x8, source2_low_u_8x8, constant13_u_8x8);
893  intermediateResults0_high_u_16x8 = vmlal_u8(intermediateResults0_high_u_16x8, source2_high_u_8x8, constant13_u_8x8);
894 
895 
896  const uint8x8_t constant56_u_8x8 = vdup_n_u8(56);
897  uint16x8_t intermediateResults1_low_u_16x8 = vmull_u8(source2_low_u_8x8, constant56_u_8x8);
898  uint16x8_t intermediateResults1_high_u_16x8 = vmull_u8(source2_high_u_8x8, constant56_u_8x8);
899 
900  uint16x8_t intermediateResults2_low_u_16x8 = vmull_u8(source0_low_u_8x8, constant56_u_8x8);
901  uint16x8_t intermediateResults2_high_u_16x8 = vmull_u8(source0_high_u_8x8, constant56_u_8x8);
902 
903 
904  const uint8x8_t constant19_u_8x8 = vdup_n_u8(19);
905  intermediateResults1_low_u_16x8 = vmlsl_u8(intermediateResults1_low_u_16x8, source0_low_u_8x8, constant19_u_8x8);
906  intermediateResults1_high_u_16x8 = vmlsl_u8(intermediateResults1_high_u_16x8, source0_high_u_8x8, constant19_u_8x8);
907 
908  const uint8x8_t constant37_u_8x8 = vdup_n_u8(37);
909  intermediateResults1_low_u_16x8 = vmlsl_u8(intermediateResults1_low_u_16x8, source1_low_u_8x8, constant37_u_8x8);
910  intermediateResults1_high_u_16x8 = vmlsl_u8(intermediateResults1_high_u_16x8, source1_high_u_8x8, constant37_u_8x8);
911 
912 
913  const uint8x8_t constant47_u_8x8 = vdup_n_u8(47);
914  intermediateResults2_low_u_16x8 = vmlsl_u8(intermediateResults2_low_u_16x8, source1_low_u_8x8, constant47_u_8x8);
915  intermediateResults2_high_u_16x8 = vmlsl_u8(intermediateResults2_high_u_16x8, source1_high_u_8x8, constant47_u_8x8);
916 
917  const uint8x8_t constant9_u_8x8 = vdup_n_u8(9);
918  intermediateResults2_low_u_16x8 = vmlsl_u8(intermediateResults2_low_u_16x8, source2_low_u_8x8, constant9_u_8x8);
919  intermediateResults2_high_u_16x8 = vmlsl_u8(intermediateResults2_high_u_16x8, source2_high_u_8x8, constant9_u_8x8);
920 
921 
922  const int16x8_t constant16_s_16x8 = vdupq_n_s16(16 * 128);
923  const int16x8_t constant128_s_16x8 = vdupq_n_s16(128 * 128);
924 
925  const int16x8_t intermediateResults0_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults0_low_u_16x8), constant16_s_16x8);
926  const int16x8_t intermediateResults0_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults0_high_u_16x8), constant16_s_16x8);
927 
928  const int16x8_t intermediateResults1_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults1_low_u_16x8), constant128_s_16x8);
929  const int16x8_t intermediateResults1_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults1_high_u_16x8), constant128_s_16x8);
930 
931  const int16x8_t intermediateResults2_low_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults2_low_u_16x8), constant128_s_16x8);
932  const int16x8_t intermediateResults2_high_s_16x8 = vqaddq_s16(vreinterpretq_s16_u16(intermediateResults2_high_u_16x8), constant128_s_16x8);
933 
934  // saturated narrow signed to unsigned
935 
936  uint8x16x3_t results_u_8x16x3;
937  results_u_8x16x3.val[0] = vcombine_u8(vqrshrun_n_s16(intermediateResults0_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults0_high_s_16x8, 7));
938  results_u_8x16x3.val[1] = vcombine_u8(vqrshrun_n_s16(intermediateResults1_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults1_high_s_16x8, 7));
939  results_u_8x16x3.val[2] = vcombine_u8(vqrshrun_n_s16(intermediateResults2_low_s_16x8, 7), vqrshrun_n_s16(intermediateResults2_high_s_16x8, 7));
940 
941  // and we can store the result
942  vst3q_u8(target, results_u_8x16x3);
943 }
944 
945 #endif // OCEAN_HARDWARE_NEON_VERSION >= 10
946 
947 }
948 
949 }
950 
951 #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:3160
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:3183
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:660
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:398
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:441
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:564
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:612
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:849
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 full range Y_V_U12 frame with 7-bit precision using BT....
Definition: FrameConverterRGB24.h:757
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:382
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:764
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:390
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:516
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:708
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:413
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:486
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:813
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:457
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:465
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:449
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:820
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:427
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:834
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