Ocean
Loading...
Searching...
No Matches
FrameConverterY_UV12.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_Y_UV_12_H
9#define META_OCEAN_CV_FRAME_CONVERTER_Y_UV_12_H
10
11#include "ocean/cv/CV.h"
15
16namespace Ocean
17{
18
19namespace CV
20{
21
22/**
23 * This class provides functions to convert frames with Y_UV12 pixel format.
24 * @ingroup cv
25 */
26class OCEAN_CV_EXPORT FrameConverterY_UV12 : public FrameConverter
27{
28 public:
29
30 /**
31 * Converts a Y_UV12_LIMITED_RANGE frame to a Y8_LIMITED_RANGE frame into a second image buffer.
32 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
33 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, can be invalid, as this parameter is not used
34 * @param target The target frame buffer, with (width + targetPaddingElements) * height elements, must be valid
35 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
36 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
37 * @param flag Determining the type of conversion
38 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
39 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity), actually this parameter is not used
40 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
41 * @param worker Optional worker object to distribute the computational to several CPU cores
42 */
43 static inline void convertY_UV12LimitedRangeToY8LimitedRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
44
45 /**
46 * Converts a Y_UV12_LIMITED_RANGE frame to a Y8_FULL_RANGE frame into a second image buffer.
47 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
48 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, can be invalid, as this parameter is not used
49 * @param target The target frame buffer, with (width + targetPaddingElements) * height elements, must be valid
50 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
51 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
52 * @param flag Determining the type of conversion
53 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
54 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity), actually this parameter is not used
55 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
56 * @param worker Optional worker object to distribute the computational to several CPU cores
57 */
58 static inline void convertY_UV12LimitedRangeToY8FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
59
60 /**
61 * Converts a Y_UV12_FULL_RANGE frame to a Y8_FULL_RANGE frame into a second image buffer.
62 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
63 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, can be invalid, as this parameter is not used
64 * @param target The target frame buffer, with (width + targetPaddingElements) * height elements, must be valid
65 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
66 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
67 * @param flag Determining the type of conversion
68 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
69 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity), actually this parameter is not used
70 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
71 * @param worker Optional worker object to distribute the computational to several CPU cores
72 */
73 static inline void convertY_UV12FullRangeToY8FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
74
75 /**
76 * Converts a Y_UV12_FULL_RANGE frame to a Y8_LIMITED_RANGE frame into a second image buffer.
77 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
78 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, can be invalid, as this parameter is not used
79 * @param target The target frame buffer, with (width + targetPaddingElements) * height elements, must be valid
80 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
81 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
82 * @param flag Determining the type of conversion
83 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
84 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity), actually this parameter is not used
85 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
86 * @param worker Optional worker object to distribute the computational to several CPU cores
87 */
88 static inline void convertY_UV12FullRangeToY8LimitedRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
89
90 /**
91 * Converts a Y_UV12_LIMITED_RANGE frame to a BGR24 frame into a second image buffer.
92 * <pre>
93 * YUV input value range: [16, 235]x[16, 240]x[16, 240]
94 * BGR output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
95 * </pre>
96 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
97 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
98 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
99 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
100 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
101 * @param flag Determining the type of conversion
102 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
103 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
104 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
105 * @param worker Optional worker object to distribute the computational to several CPU cores
106 */
107 static inline void convertY_UV12LimitedRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
108
109 /**
110 * Converts a Y_UV12_LIMITED_RANGE frame to a RGB24 frame into a second image buffer.
111 * <pre>
112 * YUV input value range: [16, 235]x[16, 240]x[16, 240]
113 * RGB output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
114 * </pre>
115 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
116 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
117 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
118 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
119 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
120 * @param flag Determining the type of conversion
121 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
122 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
123 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
124 * @param worker Optional worker object to distribute the computational to several CPU cores
125 */
126 static inline void convertY_UV12LimitedRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
127
128 /**
129 * Converts a Y_UV12_FULL_RANGE frame to a BGR24 (full range) frame into a second image buffer.
130 * <pre>
131 * YUV input value range: [0, 255]x[0, 255]x[0, 255]
132 * BGR output value range: [0, 255]x[0, 255]x[0, 255]
133 * </pre>
134 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
135 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
136 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
137 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
138 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
139 * @param flag Determining the type of conversion
140 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
141 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
142 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
143 * @param worker Optional worker object to distribute the computational to several CPU cores
144 */
145 static inline void convertY_UV12FullRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
146
147 /**
148 * Converts a Y_UV12_FULL_RANGE frame to a RGB24 (full range) frame into a second image buffer.
149 * <pre>
150 * YUV input value range: [0, 255]x[0, 255]x[0, 255]
151 * RGB output value range: [0, 255]x[0, 255]x[0, 255]
152 * </pre>
153 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
154 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
155 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
156 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
157 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
158 * @param flag Determining the type of conversion
159 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
160 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
161 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
162 * @param worker Optional worker object to distribute the computational to several CPU cores
163 */
164 static inline void convertY_UV12FullRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
165
166 /**
167 * Converts a Y_UV12 frame to a 24 bit YUV frame into a second image buffer.
168 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
169 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
170 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, 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 ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
175 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
176 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
177 * @param worker Optional worker object to distribute the computational to several CPU cores
178 */
179 static inline void convertY_UV12ToYUV24(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
180
181 /**
182 * Converts a Y_UV12 frame to a 24 bit YVU frame into a second image buffer.
183 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
184 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
185 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
186 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
187 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
188 * @param flag Determining the type of conversion
189 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
190 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
191 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
192 * @param worker Optional worker object to distribute the computational to several CPU cores
193 */
194 static inline void convertY_UV12ToYVU24(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
195
196 /**
197 * Converts a Y_UV12 frame to a Y_U_V12 frame into a second image buffer.
198 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
199 * @param uvSource The uv source frame buffer, with (2 * width/2 + uvPaddingElements) * height/2 elements, must be valid
200 * @param yTarget The target frame buffer, with (width + yTargetPaddingElements) * height elements, must be valid
201 * @param uTarget The target frame buffer, with (width/2 + uTargetPaddingElements) * height/2 elements, must be valid
202 * @param vTarget The target frame buffer, with (width/2 + vTargetPaddingElements) * height/2 elements, must be valid
203 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
204 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
205 * @param flag Determining the type of conversion
206 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
207 * @param uvSourcePaddingElements The number of padding elements at the end of each uv-source row, in (uint8_t) elements, with range [0, infinity)
208 * @param yTargetPaddingElements The number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
209 * @param uTargetPaddingElements The number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
210 * @param vTargetPaddingElements The number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
211 * @param worker Optional worker object to distribute the computational to several CPU cores
212 */
213 static inline void convertY_UV12ToY_U_V12(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker = nullptr);
214};
215
216inline void FrameConverterY_UV12::convertY_UV12LimitedRangeToY8LimitedRange(const uint8_t* ySource, const uint8_t* /* uvSource */, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int /* uvSourcePaddingElements */, const unsigned int targetPaddingElements, Worker* worker)
217{
218 ocean_assert(ySource != nullptr && target != nullptr);
219 ocean_assert(width >= 1u && height >= 1u);
220
221 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, target, width, height, flag, ySourcePaddingElements, targetPaddingElements, worker);
222}
223
224inline void FrameConverterY_UV12::convertY_UV12LimitedRangeToY8FullRange(const uint8_t* ySource, const uint8_t* /* uvSource */, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int /* uvSourcePaddingElements */, const unsigned int targetPaddingElements, Worker* worker)
225{
226 ocean_assert(ySource != nullptr && target != nullptr);
227 ocean_assert(width >= 1u && height >= 1u);
228
229 FrameConverterY8::convertY8LimitedRangeToY8FullRange(ySource, target, width, height, flag, ySourcePaddingElements, targetPaddingElements, worker);
230}
231
232inline void FrameConverterY_UV12::convertY_UV12FullRangeToY8FullRange(const uint8_t* ySource, const uint8_t* /* uvSource */, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int /* uvSourcePaddingElements */, const unsigned int targetPaddingElements, Worker* worker)
233{
234 ocean_assert(ySource != nullptr && target != nullptr);
235 ocean_assert(width >= 1u && height >= 1u);
236
237 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, target, width, height, flag, ySourcePaddingElements, targetPaddingElements, worker);
238}
239
240inline void FrameConverterY_UV12::convertY_UV12FullRangeToY8LimitedRange(const uint8_t* ySource, const uint8_t* /* uvSource */, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int /* uvSourcePaddingElements */, const unsigned int targetPaddingElements, Worker* worker)
241{
242 ocean_assert(ySource != nullptr && target != nullptr);
243 ocean_assert(width >= 1u && height >= 1u);
244
245 FrameConverterY8::convertY8FullRangeToY8LimitedRange(ySource, target, width, height, flag, ySourcePaddingElements, targetPaddingElements, worker);
246}
247
248inline void FrameConverterY_UV12::convertY_UV12LimitedRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
249{
250 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
251
252 ocean_assert(width >= 2u && width % 2u == 0u);
253 ocean_assert(height >= 2u && height % 2u == 0u);
254
255 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
256 {
257 return;
258 }
259
260 // YUV input value range: [16, 235]x[16, 240]x[16, 240]
261 // BGR output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
262
263 // precise color space conversion:
264 // | B | | 1.1639404296875 2.0179443359375 0.0 -276.919921875 | | Y |
265 // | G | = | 1.1639404296875 -0.3909912109375 -0.81298828125 135.486328125 | * | U |
266 // | R | | 1.1639404296875 0.0 1.595947265625 -222.904296875 | | V |
267 // | 1 |
268
269#if 1
270
271 // Approximation with 6 bit precision:
272 // | B | | 75 128 0 | | Y - 16 |
273 // 64 * | G | = | 75 -25 -52 | * | U - 128 |
274 // | R | | 75 0 102 | | V - 128 |
275
276 const int options[3 + 12] =
277 {
278 // padding parameters
279 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
280
281 // multiplication parameters
282 75, 75, 75, 128, -25, 0, 0, -52, 102,
283
284 // bias/translation parameters
285 16, 128, 128
286 };
287
288 const void* sources[2] =
289 {
290 ySource,
291 uvSource
292 };
293
295
296#else
297
298 // Approximation with 10 bit precision:
299 // | B | | 1192 2066 0 -277 | | Y |
300 // | G | = | 1192 -400 -833 135 | * | U |
301 // | R | | 1192 0 1634 -223 | | V |
302 // | 1 |
303
304 const int options[3 + 12] =
305 {
306 // padding parameters
307 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
308
309 // multiplication parameters (with denominator 1024)
310 1192, 1192, 1192, 2066, -400, 0, 0, -833, 1634,
311
312 // bias/translation parameters (with denominator 1)
313 -277, 135, -223
314 };
315
316 const void* sources[2] =
317 {
318 ySource,
319 uvSource
320 };
321
322 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::convertOneRow1PlaneAnd2ChannelsZippedDownsampled2x2ToZipped3Channels8BitPerChannelPrecision10Bit, options, worker);
323
324#endif
325}
326
327inline void FrameConverterY_UV12::convertY_UV12LimitedRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
328{
329 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
330
331 ocean_assert(width >= 2u && width % 2u == 0u);
332 ocean_assert(height >= 2u && height % 2u == 0u);
333
334 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
335 {
336 return;
337 }
338
339 // YUV input value range: [16, 235]x[16, 240]x[16, 240]
340 // RGB output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
341
342 // precise color space conversion:
343 // | R | | 1.1639404296875 0.0 1.595947265625 -222.904296875 | | Y |
344 // | G | = | 1.1639404296875 -0.3909912109375 -0.81298828125 135.486328125 | * | U |
345 // | B | | 1.1639404296875 2.0179443359375 0.0 -276.919921875 | | V |
346 // | 1 |
347
348#if 1
349
350 // Approximation with 6 bit precision:
351 // | R | | 75 0 102 | | Y - 16 |
352 // 64 * | G | = | 75 -25 -52 | * | U - 128 |
353 // | B | | 75 128 0 | | V - 128 |
354
355 const int options[3 + 12] =
356 {
357 // padding parameters
358 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
359
360 // multiplication parameters
361 75, 75, 75, 0, -25, 128, 102, -52, 0,
362
363 // bias/translation parameters
364 16, 128, 128
365 };
366
367 const void* sources[2] =
368 {
369 ySource,
370 uvSource
371 };
372
374
375#else
376
377 // Approximation with 10 bit precision:
378 // | R | | 1192 0 1634 -223 | | Y |
379 // | G | = | 1192 -400 -833 135 | * | U |
380 // | B | | 1192 2066 0 -277 | | V |
381 // | 1 |
382
383 const int options[3 + 12] =
384 {
385 // padding parameters
386 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
387
388 // multiplication parameters (with denominator 1024)
389 1192, 1192, 1192, 0, -400, 2066, 1634, -833, 0,
390
391 // bias/translation parameters (with denominator 1)
392 -223, 135, -277
393 };
394
395 const void* sources[2] =
396 {
397 ySource,
398 uvSource
399 };
400
401 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::convertOneRow1PlaneAnd2ChannelsZippedDownsampled2x2ToZipped3Channels8BitPerChannelPrecision10Bit, options, worker);
402
403#endif
404
405}
406
407inline void FrameConverterY_UV12::convertY_UV12FullRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
408{
409 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
410
411 ocean_assert(width >= 2u && width % 2u == 0u);
412 ocean_assert(height >= 2u && height % 2u == 0u);
413
414 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
415 {
416 return;
417 }
418
419 /*
420 * YUV input value range: [0, 255]x[0, 255]x[0, 255s]
421 * RGB output value range: [0, 255]x[0, 255]x[0, 255]
422 *
423 * | B | | 1.0 1.772 0.0 -226.816 | | Y |
424 * | G | = | 1.0 -0.34414 -0.71414 135.45984 | * | U |
425 * | R | | 1.0 0.0 1.402 -179.456 | | V |
426 * | 1 |
427 *
428 * Approximation with 6 bit precision:
429 * | B | | 64 113 0 | | Y |
430 * 64 * | G | = | 64 -22 -46 | * | U - 128 |
431 * | R | | 64 0 90 | | V - 128 |
432 */
433
434 const int options[3 + 12] =
435 {
436 // padding parameters
437 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
438
439 // multiplication parameters
440 64, 64, 64, 113, -22, 0, 0, -46, 90,
441
442 // bias/translation parameters
443 0, 128, 128
444 };
445
446 const void* sources[2] =
447 {
448 ySource,
449 uvSource
450 };
451
453}
454
455inline void FrameConverterY_UV12::convertY_UV12FullRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
456{
457 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
458
459 ocean_assert(width >= 2u && width % 2u == 0u);
460 ocean_assert(height >= 2u && height % 2u == 0u);
461
462 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
463 {
464 return;
465 }
466
467 /*
468 * YUV input value range: [0, 255]x[0, 255]x[0, 255s]
469 * RGB output value range: [0, 255]x[0, 255]x[0, 255]
470 *
471 * | R | | 1.0 0.0 1.402 -179.456 | | Y |
472 * | G | = | 1.0 -0.34414 -0.71414 135.45984 | * | U |
473 * | B | | 1.0 1.772 0.0 -226.816 | | V |
474 * | 1 |
475 *
476 * Approximation with 6 bit precision:
477 * | R | | 64 0 90 | | Y |
478 * 64 * | G | = | 64 -22 -46 | * | U - 128 |
479 * | B | | 64 113 0 | | V - 128 |
480 */
481
482 const int options[3 + 12] =
483 {
484 // padding parameters
485 int(ySourcePaddingElements), int(uvSourcePaddingElements), int(targetPaddingElements),
486
487 // multiplication parameters
488 64, 64, 64, 0, -22, 113, 90, -46, 0,
489
490 // bias/translation parameters
491 0, 128, 128
492 };
493
494 const void* sources[2] =
495 {
496 ySource,
497 uvSource
498 };
499
501}
502
503inline void FrameConverterY_UV12::convertY_UV12ToYUV24(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
504{
505 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
506
507 ocean_assert(width >= 2u && width % 2u == 0u);
508 ocean_assert(height >= 2u && height % 2u == 0u);
509
510 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
511 {
512 return;
513 }
514
515 const unsigned int options[3] = {ySourcePaddingElements, uvSourcePaddingElements, targetPaddingElements};
516
517 const void* sources[2] =
518 {
519 ySource,
520 uvSource
521 };
522
523 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::mapOneRow_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel<0u, 1u, 2u>, options, worker);
524}
525
526inline void FrameConverterY_UV12::convertY_UV12ToYVU24(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
527{
528 ocean_assert(ySource != nullptr && uvSource != nullptr && target != nullptr);
529
530 ocean_assert(width >= 2u && width % 2u == 0u);
531 ocean_assert(height >= 2u && height % 2u == 0u);
532
533 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
534 {
535 return;
536 }
537
538 const unsigned int options[3] = {ySourcePaddingElements, uvSourcePaddingElements, targetPaddingElements};
539
540 const void* sources[2] =
541 {
542 ySource,
543 uvSource
544 };
545
546 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::mapOneRow_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel<0u, 2u, 1u>, options, worker);
547}
548
549inline void FrameConverterY_UV12::convertY_UV12ToY_U_V12(const uint8_t* ySource, const uint8_t* uvSource, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker)
550{
551 ocean_assert(ySource != nullptr && uvSource != nullptr && yTarget != nullptr && yTarget != nullptr && vTarget != nullptr);
552
553 ocean_assert(width >= 2u && width % 2u == 0u);
554 ocean_assert(height >= 2u && height % 2u == 0u);
555
556 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
557 {
558 return;
559 }
560
561 // first, we handle the y-plane
562 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, yTarget, width, height, flag, ySourcePaddingElements, yTargetPaddingElements, worker);
563
564 // now we handle the uv-plane
565
566 const unsigned int options[3] = {uvSourcePaddingElements, uTargetPaddingElements, vTargetPaddingElements};
567
568 void* targets[2] =
569 {
570 uTarget,
571 vTarget
572 };
573
574 FrameConverter::convertArbitraryPixelFormat((const void**)(&uvSource), targets, width / 2u, height / 2u, flag, 1u, FrameConverter::mapOneRow_1Plane2Channels_To_2Planes1Channel_8BitPerChannel, options, worker);
575}
576
577}
578
579}
580
581#endif // META_OCEAN_CV_FRAME_CONVERTER_Y_UV_12_H
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 convertTwoRows_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel_Precision6Bit(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 Y_UV12 pixel format to two rows of an image with e....
static void mapOneRow_1Plane2Channels_To_2Planes1Channel_8BitPerChannel(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Maps one row of a 1-plane, 2-channel image to two planes with 1 channels.
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:3506
static void convertY8FullRangeToY8LimitedRange(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 Y8 full range frame [0, 255] to a Y8 limited range frame [16, 235].
Definition FrameConverterY8.h:320
static void convertY8LimitedRangeToY8FullRange(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 Y8 limited range frame [16, 235] to a Y8 full range frame [0, 255].
Definition FrameConverterY8.h:288
This class provides functions to convert frames with Y_UV12 pixel format.
Definition FrameConverterY_UV12.h:27
static void convertY_UV12LimitedRangeToRGB24FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_LIMITED_RANGE frame to a RGB24 frame into a second image buffer.
Definition FrameConverterY_UV12.h:327
static void convertY_UV12FullRangeToY8LimitedRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_FULL_RANGE frame to a Y8_LIMITED_RANGE frame into a second image buffer.
Definition FrameConverterY_UV12.h:240
static void convertY_UV12LimitedRangeToY8FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_LIMITED_RANGE frame to a Y8_FULL_RANGE frame into a second image buffer.
Definition FrameConverterY_UV12.h:224
static void convertY_UV12FullRangeToBGR24FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_FULL_RANGE frame to a BGR24 (full range) frame into a second image buffer.
Definition FrameConverterY_UV12.h:407
static void convertY_UV12ToYVU24(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12 frame to a 24 bit YVU frame into a second image buffer.
Definition FrameConverterY_UV12.h:526
static void convertY_UV12LimitedRangeToBGR24FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_LIMITED_RANGE frame to a BGR24 frame into a second image buffer.
Definition FrameConverterY_UV12.h:248
static void convertY_UV12FullRangeToRGB24FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_FULL_RANGE frame to a RGB24 (full range) frame into a second image buffer.
Definition FrameConverterY_UV12.h:455
static void convertY_UV12FullRangeToY8FullRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_FULL_RANGE frame to a Y8_FULL_RANGE frame into a second image buffer.
Definition FrameConverterY_UV12.h:232
static void convertY_UV12ToYUV24(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12 frame to a 24 bit YUV frame into a second image buffer.
Definition FrameConverterY_UV12.h:503
static void convertY_UV12ToY_U_V12(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *yTarget, uint8_t *uTarget, uint8_t *vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12 frame to a Y_U_V12 frame into a second image buffer.
Definition FrameConverterY_UV12.h:549
static void convertY_UV12LimitedRangeToY8LimitedRange(const uint8_t *ySource, const uint8_t *uvSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int uvSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_UV12_LIMITED_RANGE frame to a Y8_LIMITED_RANGE frame into a second image buffer.
Definition FrameConverterY_UV12.h:216
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
The namespace covering the entire Ocean framework.
Definition Accessor.h:15