Ocean
Loading...
Searching...
No Matches
Frame.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_BASE_FRAME_H
9#define META_OCEAN_BASE_FRAME_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/DataType.h"
16
17#include <type_traits>
18
19namespace Ocean
20{
21
22/**
23 * Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
24 * The frame dimension of a frame specifies the number of pixels in horizontal (width) and vertical (height) direction.<br>
25 * The pixel format specifies which kind of image information is stored.<br>
26 * The pixel origin defines whether the image data starts at the top left corner or at the bottom left corner.<br>
27 * @ingroup base
28 */
29class OCEAN_BASE_EXPORT FrameType
30{
31 public:
32
33 /**
34 * Definition of individual channel data type.
35 */
36 enum DataType : uint8_t
37 {
38 /// Undefined data type.
39 DT_UNDEFINED = 0u,
40 /// Unsigned 8 bit integer data type (uint8_t).
42 /// Signed 8 bit integer data type (int8_t).
44 /// Unsigned 16 bit integer data type (uint16_t).
46 /// Signed 16 bit integer data type (int16_t).
48 /// Unsigned 32 bit integer data type (uint32_t).
50 /// Signed 232 bit integer data type (int32_t).
52 /// Unsigned 64 bit integer data type (uint64_t).
54 /// Signed 64 bit integer data type (int64_t).
56 /// Signed 16 bit float data type.
58 /// Signed 32 bit float data type (float).
60 /// Signed 64 bit float data type (double).
62 /// The helper data type which can be used to identify the last defined data type, DT_END is exclusive.
63 DT_END
64 };
65
66 /**
67 * Definition of a vector holding data types.
68 */
69 using DataTypes = std::vector<DataType>;
70
71 protected:
72
73 /// The number of bits the channel value is shifted within the PixelFormat value.
74 static constexpr uint32_t pixelFormatBitOffsetChannels = 16u;
75
76 /// The number of bits the data type value is shifted within the PixelFormat value.
77 static constexpr uint32_t pixelFormatBitOffsetDatatype = pixelFormatBitOffsetChannels + 8u;
78
79 /// The number of bits the planes value is shifted within the PixelFormat value.
80 static constexpr uint32_t pixelFormatBitOffsetPlanes = pixelFormatBitOffsetDatatype + 8u;
81
82 /// The number of bits the width-multiple value is shifted within the PixelFormat value.
83 static constexpr uint32_t pixelFormatBitOffsetWidthMultiple = pixelFormatBitOffsetPlanes + 8u;
84
85 /// The number of bits the height-multiple value is shifted within the PixelFormat value.
86 static constexpr uint32_t pixelFormatBitOffsetHeightMultiple = pixelFormatBitOffsetWidthMultiple + 8u;
87
88 /**
89 * This class implements a helper class allowing to create generic pixel formats.
90 * @tparam tDataType The data type of the generic pixel format
91 * @tparam tChannels The number of channels of the pixel format
92 * @tparam tPlanes The number of planes of the pixel format, a plane is a joined memory block
93 * @tparam tWidthMultiple The number of pixels the width of a frame must be a multiple of
94 * @tparam tHeightMultiple The number of pixels the height of a frame must be a multiple of
95 */
96 template <DataType tDataType, uint32_t tChannels, uint32_t tPlanes, uint32_t tWidthMultiple, uint32_t tHeightMultiple>
98 {
99 public:
100
101 /// The value of the generic pixel format.
102 static constexpr uint64_t value = (uint64_t(tHeightMultiple) << pixelFormatBitOffsetHeightMultiple) | (uint64_t(tWidthMultiple) << pixelFormatBitOffsetWidthMultiple) | (uint64_t(tPlanes) << pixelFormatBitOffsetPlanes) |(uint64_t(tDataType) << pixelFormatBitOffsetDatatype) | (uint64_t(tChannels) << pixelFormatBitOffsetChannels);
103 };
104
105 /**
106 * Definition of a protected helper enum that simplifies to read the definition of a predefined pixel format.
107 */
108 enum ChannelsValue : uint32_t
109 {
110 /// An invalid channel number, used for non-generic pixel formats.
111 CV_CHANNELS_UNDEFINED = 0u,
112 /// One channel.
113 CV_CHANNELS_1 = 1u,
114 /// Two channels.
115 CV_CHANNELS_2 = 2u,
116 /// Three channels.
117 CV_CHANNELS_3 = 3u,
118 /// Four channels.
119 CV_CHANNELS_4 = 4u
120 };
121
122 /**
123 * Definition of a protected helper enum that simplifies to read the definition of a predefined pixel format.
124 */
125 enum PlanesValue : uint32_t
126 {
127 /// One plane.
128 PV_PLANES_1 = 1u,
129 /// Two planes.
130 PV_PLANES_2 = 2u,
131 /// Three planes.
132 PV_PLANES_3 = 3u,
133 /// Four planes.
134 PV_PLANES_4 = 4u
135 };
136
137 /**
138 * Definition of a protected helper enum that simplifies to read the definition of a predefined pixel format.
139 */
140 enum MultipleValue : uint32_t
141 {
142 /// The size can have any value (as the value must be a multiple of 1).
143 MV_MULTIPLE_1 = 1u,
144 /// The size must have a multiple of 2.
145 MV_MULTIPLE_2 = 2u,
146 /// The size must have a multiple of 3.
147 MV_MULTIPLE_3 = 3u,
148 /// The size must have a multiple of 4.
149 MV_MULTIPLE_4 = 4u
150 };
151
152 public:
153
154 /**
155 * Definition of all pixel formats available in the Ocean framework.
156 * Several common pixel formats are predefined specifying a unique representation of the image information of a frame.<br>
157 * Further, generic pixel formats can be defined. Generic formats can have up to 31 zipped data channels and can be composed of any kind of data type.<br>
158 * The value of a pixel format can be separated into individual parts.<br>
159 * The lower two bytes can be used for predefined pixel formats.<br>
160 * The third byte define the number of data channels of all generic zipped pixel formats.<br>
161 * The fourth byte define the data type.<br>
162 * The fifth byte holds the number of planes.<br>
163 * The sixth byte holds the number of pixels the width of a frame must be a multiple of.<br>
164 * The seventh byte holds the number of pixels the height of a frame must be a multiple of:<br>
165 * <pre>
166 * Byte: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
167 * | unused | height-multiple | width-multiple | planes | data type | channel number | predefined pixel format |
168 * </pre>
169 * A generic zipped pixel format may have the same data layout compared to a predefined pixel format while the actual value of the pixel format may be different.
170 *
171 * The naming convention of predefined pixel formats is:<br>
172 * Left to right is equivalent from first to last bytes in memory.<br>
173 * For example RGB24 stored the red color value in the first byte and the blue color value in the last byte.<br>
174 * BGRA32 stores the blue color value in the first byte, green in the second bytes, red in the third byte and the alpha value in the last byte.
175 *
176 * The following code can be used to define a generic pixel format, in case the predefined pixel formats in 'PixelFormat' do not have the desired format:
177 * @code
178 * // define a used-defined pixel format with three double values per channel
179 * const FrameType::PixelFormat newPixelFormat = FrameType::genericPixelFormat<double, 3u>();
180 * @endcode
181 */
182 enum PixelFormat : uint64_t
183 {
184 /**
185 * Undefined pixel format.
186 */
187 FORMAT_UNDEFINED = 0ull,
188
189 /**
190 * Pixel format with byte order ABGR and 32 bits per pixel.
191 * Here is the memory layout:
192 * <pre>
193 * Pixel: 0 1
194 * Byte: 0 1 2 3 4
195 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
196 * Channel: 0 1 2 3 0
197 * Color: AAAAAAAABBBBBBBBGGGGGGGGRRRRRRRR AAAAAAAA ........
198 * </pre>
199 */
201
202 /**
203 * Pixel format with byte order ARGB and 32 bits per pixel.
204 * Here is the memory layout:
205 * <pre>
206 * Pixel: 0 1
207 * Byte: 0 1 2 3 4
208 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
209 * Channel: 0 1 2 3 0
210 * Color: AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB AAAAAAAA ........
211 * </pre>
212 */
214
215 /**
216 * Pixel format with byte order BGR and 24 bits per pixel.
217 * Here is the memory layout:
218 * <pre>
219 * Pixel: 0 1 2
220 * Byte: 0 1 2 3 4 5 6
221 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
222 * Channel: 0 1 2 0 1 2 0
223 * Color: BBBBBBBBGGGGGGGGRRRRRRRR BBBBBBBBGGGGGGGGRRRRRRRR BBBBBBBB ........
224 * </pre>
225 */
227
228 /**
229 * Pixel format with byte order BGR and 24 bits per pixel and 8 unused bits.
230 * Here is the memory layout:
231 * <pre>
232 * Pixel: 0 1
233 * Byte: 0 1 2 3 4
234 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
235 * Channel: 0 1 2 0
236 * Color: BBBBBBBBGGGGGGGGRRRRRRRR BBBBBBBB ........
237 * </pre>
238 */
240
241 /**
242 * Pixel format with entirely 16 bits per pixel, 12 bits for BGR and 4 unused bits.
243 */
244 FORMAT_BGR4444 = 5ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
245
246 /**
247 * Pixel format with entirely 16 bits per pixel, 15 bits for BGR and 1 unused bit.
248 */
249 FORMAT_BGR5551 = 6ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
250
251 /**
252 * Pixel format with 16 bits per pixel, 5 bits for blue, 6 bits for green and 5 bits for red.
253 * Here is the memory layout:
254 * <pre>
255 * Pixel: 0 1 2
256 * Byte: 0 1 2 3 4
257 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01234
258 * Channel: 0 1 2 0 1 2 0
259 * Color: BBBBBGGGGGGRRRRR BBBBBGGGGGGRRRRR BBBBB ........
260 * </pre>
261 * This pixel format is equivalent to the following pixel formats on Android (note the inverse order or RGB):<br>
262 * Native code: ANDROID_BITMAP_FORMAT_RGB_565, Java: Bitmap.Config.RGB_565.
263 */
264 FORMAT_BGR565 = 7ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
265
266 /**
267 * Pixel format with byte order BGRA and 32 bits per pixel.
268 * Here is the memory layout:
269 * <pre>
270 * Pixel: 0 1
271 * Byte: 0 1 2 3 4
272 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
273 * Channel: 0 1 2 3 0
274 * Color: BBBBBBBBGGGGGGGGRRRRRRRRAAAAAAAA BBBBBBBB ........
275 * </pre>
276 */
278
279 /**
280 * Pixel format with entirely 16 bits per pixel, 4 bits for each channel.
281 */
282 FORMAT_BGRA4444 = 9ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
283
284 /**
285 * The packed pixel format representing a Bayer mosaic pattern for images with blue, green, and red channels with order BGGR for a 2x2 pixel block.
286 * The format has the byte order B G for the upper two pixels, and G R for the lower two pixels in a 2x2 pixel block.<br>
287 * Images with this pixel format have a resolution which is a multiple of 4x2 pixels.<br>
288 * The Pixel format stores 10 bits per pixel (and channel), packed so that four consecutive pixels fit into five bytes.<br>
289 * The higher 8 bits of each pixel are stored in the first four bytes, the lower 2 bits of all four pixels are stored in the fifth byte.<br>
290 * Here is the memory layout:
291 * <pre>
292 * Pixel: 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7
293 * Byte: 0 1 2 3 4 5 6 7 8 9
294 * Bit: 01234567 89ABCDEF 01234567 89ABCDEF 01234567 01234567 89ABCDEF 01234567 89ABCDEF 01234567
295 * Channel: row 0: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
296 * Channel: row 1: 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
297 * Color: row 1: BBBBBBBB GGGGGGGG BBBBBBBB GGGGGGGG BBGGBBGG BBBBBBBB GGGGGGGG BBBBBBBB GGGGGGGG BBGGBBGG ........
298 * Color: row 0: GGGGGGGG RRRRRRRR GGGGGGGG RRRRRRRR GGRRGGRR GGGGGGGG RRRRRRRR GGGGGGGG RRRRRRRR GGRRGGRR ........
299 * Color: row 2: BBBBBBBB GGGGGGGG ........
300 * </pre>
301 */
302 FORMAT_BGGR10_PACKED = 10ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_4, MV_MULTIPLE_2>::value,
303
304 /**
305 * Pixel format with byte order RGB and 24 bits per pixel.
306 * Here is the memory layout:
307 * <pre>
308 * Pixel: 0 1 2
309 * Byte: 0 1 2 3 4 5 6
310 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
311 * Channel: 0 1 2 0 1 2 0
312 * Color: RRRRRRRRGGGGGGGGBBBBBBBB RRRRRRRRGGGGGGGGBBBBBBBB RRRRRRRR ........
313 * </pre>
314 */
316
317 /**
318 * Pixel format with byte order RGB and 24 bits per pixel and 8 unused bits.
319 * Here is the memory layout:
320 * <pre>
321 * Pixel: 0 1
322 * Byte: 0 1 2 3 4
323 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
324 * Channel: 0 1 2 0
325 * Color: RRRRRRRRGGGGGGGGBBBBBBBB RRRRRRRR ........
326 * </pre>
327 */
329
330 /**
331 * Pixel format with entirely 16 bits per pixel, 12 bits for RGB and 4 unused bits.
332 * Here is the memory layout:
333 * <pre>
334 * Pixel: 0 1 2
335 * Byte: 0 1 2 3 4
336 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01234
337 * Channel: 0 1 2 0 1 2 0
338 * Color: RRRRGGGGBBBB RRRRGGGGBBBB RRRRR ........
339 * </pre>
340 */
341 FORMAT_RGB4444 = 13ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
342
343 /**
344 * Pixel format with entirely 16 bits per pixel, 15 bits for RGB and 1 unused bit.
345 * Here is the memory layout:
346 * <pre>
347 * Pixel: 0 1 2
348 * Byte: 0 1 2 3 4
349 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01234
350 * Channel: 0 1 2 0 1 2 0
351 * Color: RRRRRGGGGGBBBBB RRRRRGGGGGBBBBB RRRRR ........
352 * </pre>
353 */
354 FORMAT_RGB5551 = 14ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
355
356 /**
357 * Pixel format with entirely 16 bits per pixel, 5 bits for red, 6 bits for green and 5 bits for blue.
358 * Here is the memory layout:
359 * <pre>
360 * Pixel: 0 1 2
361 * Byte: 0 1 2 3 4
362 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01234
363 * Channel: 0 1 2 0 1 2 0
364 * Color: RRRRRGGGGGGBBBBB RRRRRGGGGGGBBBBB RRRRR ........
365 * </pre>
366 */
367 FORMAT_RGB565 = 15ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
368
369 /**
370 * Pixel format with byte order RGBA and 32 bits per pixel.
371 * Here is the memory layout:
372 * <pre>
373 * Pixel: 0 1
374 * Byte: 0 1 2 3 4
375 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
376 * Channel: 0 1 2 3 0
377 * Color: RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA RRRRRRRR ........
378 * </pre>
379 * This pixel format is equivalent to the following pixel formats on Android (note the inverse order of ARGB):<br>
380 * Native code: ANDROID_BITMAP_FORMAT_RGBA_8888, Java: Bitmap.Config.ARGB_8888.
381 */
383
384 /**
385 * Pixel format with entirely 16 bits per pixel, 4 bits for each channel.
386 * Here is the memory layout:
387 * <pre>
388 * Pixel: 0 1 2
389 * Byte: 0 1 2 3 4
390 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01234
391 * Channel: 0 1 2 0 1 2 0
392 * Color: RRRRGGGGBBBBAAAA RRRRGGGGBBBBAAAA RRRRR ........
393 * </pre>
394 */
395 FORMAT_RGBA4444 = 17ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_16, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
396
397 /**
398 * Pixel format with byte order RGBT and 24 bits for the RGB channels and 8 bits for an arbitrary texture channel.
399 * Here is the memory layout:
400 * <pre>
401 * Pixel: 0 1
402 * Byte: 0 1 2 3 4
403 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
404 * Channel: 0 1 2 3 0
405 * Color: RRRRRRRRGGGGGGGGBBBBBBBBTTTTTTTT RRRRRRRR ........
406 * </pre>
407 */
409
410 /**
411 * The packed pixel format representing a Bayer mosaic pattern for images with red, green, and blue channels with order RGGB for a 2x2 pixel block.
412 * The format has the byte order R G for the upper two pixels, and G B for the lower two pixels in a 2x2 pixel block.<br>
413 * Images with this pixel format have a resolution which is a multiple of 4x2 pixels.<br>
414 * The Pixel format stores 10 bits per pixel (and channel), packed so that four consecutive pixels fit into five bytes.<br>
415 * The higher 8 bits of each pixel are stored in the first four bytes, the lower 2 bits of all four pixels are stored in the fifth byte.<br>
416 * Here is the memory layout:
417 * <pre>
418 * Pixel: 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7
419 * Byte: 0 1 2 3 4 5 6 7 8 9
420 * Bit: 01234567 89ABCDEF 01234567 89ABCDEF 01234567 01234567 89ABCDEF 01234567 89ABCDEF 01234567
421 * Channel: row 0: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
422 * Channel: row 1: 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
423 * Color: row 0: RRRRRRRR GGGGGGGG RRRRRRRR GGGGGGGG RRGGRRGG RRRRRRRR GGGGGGGG RRRRRRRR GGGGGGGG RRGGRRGG ........
424 * Color: row 1: GGGGGGGG BBBBBBBB GGGGGGGG BBBBBBBB GGBBGGBB GGGGGGGG BBBBBBBB GGGGGGGG BBBBBBBB GGBBGGBB ........
425 * Color: row 2: RRRRRRRR GGGGGGGG ........
426 * </pre>
427 */
428 FORMAT_RGGB10_PACKED = 19ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_4, MV_MULTIPLE_2>::value,
429
430 /**
431 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled U frame and 8 bits 2x2 sub-sampled V frame, both as individual blocks, resulting in 12 bits per pixel.
432 * Sometimes also denoted as 'I420'.
433 *
434 * The memory layout of a Y_U_V12 image looks like this:
435 * <pre>
436 * y-plane: u-plane: v-plane:
437 * --------- ----- -----
438 * | Y Y Y Y | | U U | | V V |
439 * | Y Y Y Y | | U U | | V V |
440 * | Y Y Y Y | ----- -----
441 * | Y Y Y Y |
442 * ---------
443 * </pre>
444 * Width and height must be even (multiple of two).
445 */
446 FORMAT_Y_U_V12 = 20ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
447
448 /**
449 * This pixel format is deprecated and is currently an alias for FORMAT_YUV24_LIMITED_RANGE.
450 * Pixel format with byte order YUV and 24 bits per pixel.
451 * Here is the memory layout:
452 * <pre>
453 * Pixel: 0 1 2
454 * Byte: 0 1 2 3 4 5 6
455 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
456 * Channel: 0 1 2 0 1 2 0
457 * Color: YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYY ........
458 * </pre>
459 */
461
462 /**
463 * Pixel format with byte order YUVA and 32 bits per pixel.
464 * Here is the memory layout:
465 * <pre>
466 * Pixel: 0 1
467 * Byte: 0 1 2 3 4
468 * Bit: 0123456789ABCDEF0123456789ABCDEF 01234567
469 * Channel: 0 1 2 3 0
470 * Color: YYYYYYYYUUUUUUUUVVVVVVVVAAAAAAAA YYYYYYYY ........
471 * </pre>
472 */
474
475 /**
476 * Pixel format with byte order YUVA and 24 bits for the YUV channels and 8 bit for an arbitrary texture channel.
477 */
479
480 /**
481 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled V frame and 8 bits 2x2 sub-sampled U frame, both as individual blocks, resulting in 12 bits per pixel.
482 * Sometimes also denoted as 'YV12'.
483 *
484 * The memory layout of a Y_V_U12 image looks like this:
485 * <pre>
486 * y-plane: v-plane: u-plane:
487 * --------- ----- -----
488 * | Y Y Y Y | | V V | | U U |
489 * | Y Y Y Y | | V V | | U U |
490 * | Y Y Y Y | ----- -----
491 * | Y Y Y Y |
492 * ---------
493 * </pre>
494 * Width and height must be even (multiple of two).
495 */
496 FORMAT_Y_V_U12 = 24ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
497
498 /**
499 * This pixel format is deprecated and is currently an alias for FORMAT_YVU24_LIMITED_RANGE.
500 * Pixel format with byte order YVU and 24-bits per pixel.
501 * Here is the memory layout:
502 * <pre>
503 * Pixel: 0 1 2
504 * Byte: 0 1 2 3 4 5 6
505 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
506 * Channel: 0 1 2 0 1 2 0
507 * Color: YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYY ........
508 * </pre>
509 */
511
512 /**
513 * This pixel format is deprecated and is currently an alias for FORMAT_Y_UV12_LIMITED_RANGE.
514 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled U and V zipped (interleaved) pixels, resulting in 12 bits per pixel.
515 * Sometimes also denoted as 'NV12'.
516 *
517 * The memory layout of a Y_UV12 image looks like this:
518 * <pre>
519 * y-plane: u/v-plane:
520 * --------- ---------
521 * | Y Y Y Y | | U V U V |
522 * | Y Y Y Y | | U V U V |
523 * | Y Y Y Y | ---------
524 * | Y Y Y Y |
525 * ---------
526 * </pre>
527 * Width and height must be even (multiple of two).
528 */
529 FORMAT_Y_UV12 = 26ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_2, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
530
531 /**
532 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled V and U zipped (interleaved) pixels, resulting in 12 bits per pixel.
533 * Sometimes also denoted as 'NV21'.
534 *
535 * The memory layout of a Y_VU12 image looks like this:
536 * <pre>
537 * y-plane: v/u-plane:
538 * --------- ---------
539 * | Y Y Y Y | | V U V U |
540 * | Y Y Y Y | | V U V U |
541 * | Y Y Y Y | ---------
542 * | Y Y Y Y |
543 * ---------
544 * </pre>
545 * Width and height must be even (multiple of two).
546 */
547 FORMAT_Y_VU12 = 27ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_2, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
548
549 /**
550 * Pixel format with 8 bit Y pixel values zipped (interleaved) with 8 bits 2x1 (horizontal) sub-sampled U and V pixel values respectively, resulting in 16 bits per pixel.
551 * Sometimes also denoted as 'YUY2'.
552 *
553 * The memory layout of a YUYV16 image looks like this:
554 * <pre>
555 * y/u/v-plane:
556 * -----------------
557 * | Y U Y V Y U Y V |
558 * | Y U Y V Y U Y V |
559 * | Y U Y V Y U Y V |
560 * | Y U Y V Y U Y V |
561 * -----------------
562 * </pre>
563 * The width must be even (multiple of two).
564 */
565 FORMAT_YUYV16 = 28ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_2, MV_MULTIPLE_1>::value,
566
567 /**
568 * Pixel format with 8 bit Y pixel values zipped (interleaved) with 8 bits 2x1 (horizontal) sub-sampled U and V pixel values respectively, resulting in 16 bits per pixel.
569 * Sometimes also denoted as 'UYVY'.
570 *
571 * The memory layout of a UYVY16 image looks like this:
572 * <pre>
573 * y/u/v-plane:
574 * -----------------
575 * | U Y V Y U Y V Y |
576 * | U Y V Y U Y V Y |
577 * | U Y V Y U Y V Y |
578 * | U Y V Y U Y V Y |
579 * -----------------
580 * </pre>
581 * The width must be even (multiple of two).
582 */
583 FORMAT_UYVY16 = 29ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_2, MV_MULTIPLE_1>::value,
584
585 /**
586 * Pixel format for grayscale images with byte order Y and 8 bits per pixel.
587 * Here is the memory layout:
588 * <pre>
589 * Pixel: 0 1
590 * Byte: 0 1
591 * Bit: 01234567 89ABCDEF
592 * Channel: 0 0
593 * Color: YYYYYYYY YYYYYYYY ........
594 * </pre>
595 */
597
598 /**
599 * Pixel format with byte order Y and 10 bits per pixel, the upper 6 bits are unused.
600 * Here is the memory layout:
601 * <pre>
602 * Pixel: 0 1
603 * Byte: 0 1 2 3
604 * Bit: 01234567 89ABCDEF 01234567 89ABCDEF
605 * Channel: 0 0
606 * Color: YYYYYYYY YY YYYYYYYY YY ........
607 * </pre>
608 */
610
611 /**
612 * Pixel format with byte order Y and 10 bits per pixel, packed so that four consecutive pixels fit into five bytes.
613 * The higher 8 bits of each pixel are stored in the first four bytes, the lower 2 bits of all four pixels are stored in the fifth byte.
614 * Here is the memory layout:
615 * <pre>
616 * Pixel: 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7
617 * Byte: 0 1 2 3 4 5 6 7 8 9
618 * Bit: 01234567 89ABCDEF 01234567 89ABCDEF 01234567 01234567 89ABCDEF 01234567 89ABCDEF 01234567
619 * Channel: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
620 * Color: YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY ........
621 * </pre>
622 */
623 FORMAT_Y10_PACKED = 32ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_1, MV_MULTIPLE_4, MV_MULTIPLE_1>::value,
624
625 /**
626 * Pixel format with 16 bits Y frame.
627 * Here is the memory layout:
628 * <pre>
629 * Pixel: 0 1 2
630 * Byte: 0 1 2 3 4
631 * Bit: 0123456789ABCDEF 0123456789ABCDEF 01
632 * Channel: 0 0
633 * Color: YYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYY YY ........
634 * </pre>
635 */
637
638 /**
639 * Pixel format with 32 bits Y frame.
640 */
642
643 /**
644 * Pixel format with 64 bits Y frame.
645 */
647
648 /**
649 * Pixel format with byte order YA and 16 bits per pixel.
650 */
652
653 /**
654 * Pixel format with byte order RGB and 48 bits per pixel, with 16 bit per component.
655 * Here is the memory layout:
656 * <pre>
657 * Pixel: 0 1
658 * Byte: 0 1 2 3 4 5 6 7
659 * Bit: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF 0123456789ABCDEF
660 * Channel: 0 1 2 0
661 * Color: RRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGBBBBBBBBBBBBBBBB RRRRRRRRRRRRRRRR ........
662 * </pre>
663 */
665
666 /**
667 * Pixel format with byte order RGBA and 64 bits per pixel, with 16 bit per component.
668 * Here is the memory layout:
669 * <pre>
670 * Pixel: 0 1
671 * Byte: 0 1 2 3 4 5 6 7 8 9
672 * Bit: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF 0123456789ABCDEF
673 * Channel: 0 1 2 3 0
674 * Color: RRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAA RRRRRRRRRRRRRRRR ........
675 * </pre>
676 */
678
679 /**
680 * This pixel format is deprecated and is currently an alias for FORMAT_Y_U_V24_LIMITED_RANGE.
681 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
682 * Sometimes also denoted as 'I444'.
683 *
684 * The memory layout of a Y_U_V24 image looks like this:
685 * <pre>
686 * y-plane: u-plane: v-plane:
687 * --------- --------- ---------
688 * | Y Y Y Y | | U U U U | | V V V V |
689 * | Y Y Y Y | | U U U U | | V V V V |
690 * | Y Y Y Y | | U U U U | | V V V V |
691 * | Y Y Y Y | | U U U U | | V V V V |
692 * --------- --------- ---------
693 * </pre>
694 */
695 FORMAT_Y_U_V24 = 39ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
696
697 /**
698 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
699 * Sometimes also denoted as 'I444'.
700 *
701 * The pixel format is using a limited value range for the individual channels:
702 * <pre>
703 * Y channel: [16, 235]
704 * U channel: [16, 240]
705 * V channel: [16, 240]
706 * </pre>
707 *
708 * The memory layout of a Y_U_V24 image looks like this:
709 * <pre>
710 * y-plane: u-plane: v-plane:
711 * --------- --------- ---------
712 * | Y Y Y Y | | U U U U | | V V V V |
713 * | Y Y Y Y | | U U U U | | V V V V |
714 * | Y Y Y Y | | U U U U | | V V V V |
715 * | Y Y Y Y | | U U U U | | V V V V |
716 * --------- --------- ---------
717 * </pre>
718 * @see FORMAT_Y_U_V24_FULL_RANGE.
719 */
720 FORMAT_Y_U_V24_LIMITED_RANGE = FORMAT_Y_U_V24,
721
722 /**
723 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits U frame as individual block, followed by a V frame as individual block, resulting in 24 bits per pixel.
724 * Sometimes also denoted as 'I444'.
725 *
726 * The pixel format is using a full value range for all three channels:
727 * <pre>
728 * Y channel: [0, 255]
729 * U channel: [0, 255]
730 * V channel: [0, 255]
731 * </pre>
732 *
733 * The memory layout of a Y_U_V24 image looks like this:
734 * <pre>
735 * y-plane: u-plane: v-plane:
736 * --------- --------- ---------
737 * | Y Y Y Y | | U U U U | | V V V V |
738 * | Y Y Y Y | | U U U U | | V V V V |
739 * | Y Y Y Y | | U U U U | | V V V V |
740 * | Y Y Y Y | | U U U U | | V V V V |
741 * --------- --------- ---------
742 * </pre>
743 * @see FORMAT_Y_U_V24_LIMITED_RANGE.
744 */
745 FORMAT_Y_U_V24_FULL_RANGE = 40ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
746
747 /**
748 * Pixel format for grayscale images with byte order Y and 8 bits per pixel (with limited range).
749 *
750 * The pixel format is using a limited value range:
751 * <pre>
752 * Y channel: [16, 235]
753 * </pre>
754 *
755 * Here is the memory layout:
756 * <pre>
757 * Pixel: 0 1
758 * Byte: 0 1
759 * Bit: 01234567 89ABCDEF
760 * Channel: 0 0
761 * Color: YYYYYYYY YYYYYYYY ........
762 * </pre>
763 * @see FORMAT_Y8_FULL_RANGE.
764 */
766
767 /**
768 * Pixel format for grayscale images with byte order Y and 8 bits per pixel (with full range).
769 *
770 * The pixel format is using a full value range:
771 * <pre>
772 * Y channel: [0, 255]
773 * </pre>
774 *
775 * Here is the memory layout:
776 * <pre>
777 * Pixel: 0 1
778 * Byte: 0 1
779 * Bit: 01234567 89ABCDEF
780 * Channel: 0 0
781 * Color: YYYYYYYY YYYYYYYY ........
782 * </pre>
783 * @see FORMAT_Y8_LIMITED_RANGE.
784 */
785 FORMAT_Y8_FULL_RANGE = FORMAT_Y8,
786
787 /**
788 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled U and V zipped (interleaved) pixels, resulting in 12 bits per pixel.
789 * Sometimes also denoted as 'NV12'.
790 *
791 * The pixel format is using a limited value range for all three channels:
792 * <pre>
793 * Y channel: [16, 235]
794 * U channel: [16, 240]
795 * V channel: [16, 240]
796 * </pre>
797 *
798 * The memory layout of a Y_UV12 image looks like this:
799 * <pre>
800 * y-plane: u/v-plane:
801 * --------- ---------
802 * | Y Y Y Y | | U V U V |
803 * | Y Y Y Y | | U V U V |
804 * | Y Y Y Y | ---------
805 * | Y Y Y Y |
806 * ---------
807 * </pre>
808 * @see FORMAT_Y_UV12_FULL_RANGE.
809 */
810 FORMAT_Y_UV12_LIMITED_RANGE = FORMAT_Y_UV12,
811
812 /**
813 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled U and V zipped (interleaved) pixels, resulting in 12 bits per pixel.
814 * Sometimes also denoted as 'NV12'.
815 *
816 * The pixel format is using a full value range for all three channels:
817 * <pre>
818 * Y channel: [0, 255]
819 * U channel: [0, 255]
820 * V channel: [0, 255]
821 * </pre>
822 *
823 * The memory layout of a Y_UV12 image looks like this:
824 * <pre>
825 * y-plane: u/v-plane:
826 * --------- ---------
827 * | Y Y Y Y | | U V U V |
828 * | Y Y Y Y | | U V U V |
829 * | Y Y Y Y | ---------
830 * | Y Y Y Y |
831 * ---------
832 * </pre>
833 * @see FORMAT_Y_UV12_LIMITED_RANGE.
834 * Width and height must be even (multiple of two).
835 */
836 FORMAT_Y_UV12_FULL_RANGE = 42ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_2, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
837
838 /**
839 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled V and U zipped (interleaved) pixels, resulting in 12 bits per pixel.
840 * Sometimes also denoted as 'NV21'.
841 *
842 * The pixel format is using a limited value range for all three channels:
843 * <pre>
844 * Y channel: [16, 235]
845 * V channel: [16, 240]
846 * U channel: [16, 240]
847 * </pre>
848 *
849 * The memory layout of a Y_VU12 image looks like this:
850 * <pre>
851 * y-plane: u/v-plane:
852 * --------- ---------
853 * | Y Y Y Y | | V U V U |
854 * | Y Y Y Y | | V U V U |
855 * | Y Y Y Y | ---------
856 * | Y Y Y Y |
857 * ---------
858 * </pre>
859 * @see FORMAT_Y_VU12_FULL_RANGE.
860 */
861 FORMAT_Y_VU12_LIMITED_RANGE = FORMAT_Y_VU12,
862
863 /**
864 * Pixel format with 8 bits Y frame as entire block, followed by 8 bits 2x2 sub-sampled V and U zipped (interleaved) pixels, resulting in 12 bits per pixel.
865 * Sometimes also denoted as 'NV21'.
866 *
867 * The pixel format is using a full value range for all three channels:
868 * <pre>
869 * Y channel: [0, 255]
870 * V channel: [0, 255]
871 * U channel: [0, 255]
872 * </pre>
873 *
874 * The memory layout of a Y_VU12 image looks like this:
875 * <pre>
876 * y-plane: u/v-plane:
877 * --------- ---------
878 * | Y Y Y Y | | V U V U |
879 * | Y Y Y Y | | V U V U |
880 * | Y Y Y Y | ---------
881 * | Y Y Y Y |
882 * ---------
883 * </pre>
884 * @see FORMAT_Y_VU12_LIMITED_RANGE.
885 * Width and height must be even (multiple of two).
886 */
887 FORMAT_Y_VU12_FULL_RANGE = 43ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_2, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
888
889 /**
890 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled U frame and 8 bits 2x2 sub-sampled V frame, both as individual blocks, resulting in 12 bits per pixel.
891 * Sometimes also denoted as 'I420'.
892 *
893 * The pixel format is using a limited value range for all three channels:
894 * <pre>
895 * Y channel: [16, 235]
896 * V channel: [16, 240]
897 * U channel: [16, 240]
898 * </pre>
899 *
900 * The memory layout of a Y_U_V12 image looks like this:
901 * <pre>
902 * y-plane: u-plane: v-plane:
903 * --------- ----- -----
904 * | Y Y Y Y | | U U | | V V |
905 * | Y Y Y Y | | U U | | V V |
906 * | Y Y Y Y | ----- -----
907 * | Y Y Y Y |
908 * ---------
909 * </pre>
910 * @see FORMAT_Y_U_V12_FULL_RANGE.
911 */
912 FORMAT_Y_U_V12_LIMITED_RANGE = FORMAT_Y_U_V12,
913
914 /**
915 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled U frame and 8 bits 2x2 sub-sampled V frame, both as individual blocks, resulting in 12 bits per pixel.
916 * Sometimes also denoted as 'I420'.
917 *
918 * The pixel format is using a full value range for all three channels:
919 * <pre>
920 * Y channel: [0, 255]
921 * V channel: [0, 255]
922 * U channel: [0, 255]
923 * </pre>
924 *
925 * The memory layout of a Y_U_V12 image looks like this:
926 * <pre>
927 * y-plane: u-plane: v-plane:
928 * --------- ----- -----
929 * | Y Y Y Y | | U U | | V V |
930 * | Y Y Y Y | | U U | | V V |
931 * | Y Y Y Y | ----- -----
932 * | Y Y Y Y |
933 * ---------
934 * </pre>
935 * @see FORMAT_Y_U_V12_LIMITED_RANGE.
936 * Width and height must be even (multiple of two).
937 */
938 FORMAT_Y_U_V12_FULL_RANGE = 44ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
939
940 /**
941 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled V frame and 8 bits 2x2 sub-sampled U frame, both as individual blocks, resulting in 12 bits per pixel.
942 * Sometimes also denoted as 'YV12'.
943 *
944 * The pixel format is using a limited value range for all three channels:
945 * <pre>
946 * Y channel: [16, 235]
947 * V channel: [16, 240]
948 * U channel: [16, 240]
949 * </pre>
950 *
951 * The memory layout of a Y_V_U12 image looks like this:
952 * <pre>
953 * y-plane: v-plane: u-plane:
954 * --------- ----- -----
955 * | Y Y Y Y | | V V | | U U |
956 * | Y Y Y Y | | V V | | U U |
957 * | Y Y Y Y | ----- -----
958 * | Y Y Y Y |
959 * ---------
960 * </pre>
961 * @see FORMAT_Y_V_U12_FULL_RANGE.
962 */
963 FORMAT_Y_V_U12_LIMITED_RANGE = FORMAT_Y_V_U12,
964
965 /**
966 * Pixel format with 8 bits Y frame as individual block, followed by 8 bits 2x2 sub-sampled V frame and 8 bits 2x2 sub-sampled U frame, both as individual blocks, resulting in 12 bits per pixel.
967 * Sometimes also denoted as 'YV12'.
968 *
969 * The pixel format is using a full value range for all three channels:
970 * <pre>
971 * Y channel: [0, 255]
972 * V channel: [0, 255]
973 * U channel: [0, 255]
974 * </pre>
975 *
976 * The memory layout of a Y_V_U12 image looks like this:
977 * <pre>
978 * y-plane: v-plane: u-plane:
979 * --------- ----- -----
980 * | Y Y Y Y | | V V | | U U |
981 * | Y Y Y Y | | V V | | U U |
982 * | Y Y Y Y | ----- -----
983 * | Y Y Y Y |
984 * ---------
985 * </pre>
986 * @see FORMAT_Y_V_U12_LIMITED_RANGE.
987 * Width and height must be even (multiple of two).
988 */
989 FORMAT_Y_V_U12_FULL_RANGE = 45ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_2, MV_MULTIPLE_2>::value,
990
991 /**
992 * Pixel format for a frame with one channel and 32 bit floating point precision per element.
993 */
995
996 /**
997 * Pixel format for a frame with one channel and 64 bit floating point precision per element.
998 */
1000
1001 /**
1002 * Pixel format with 8 bits R frame as individual block, followed by 8 bits G frame as individual block, followed by a B frame as individual block, resulting in 24 bits per pixel.
1003 *
1004 * The memory layout of a R_G_B24 image looks like this:
1005 * <pre>
1006 * r-plane: g-plane: b-plane:
1007 * --------- --------- ---------
1008 * | R R R R | | G G G G | | B B B B |
1009 * | R R R R | | G G G G | | B B B B |
1010 * | R R R R | | G G G G | | B B B B |
1011 * | R R R R | | G G G G | | B B B B |
1012 * --------- --------- ---------
1013 * </pre>
1014 */
1015 FORMAT_R_G_B24 = 48ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
1016
1017 /**
1018 * Pixel format with 8 bits B frame as individual block, followed by 8 bits G frame as individual block, followed by a R frame as individual block, resulting in 24 bits per pixel.
1019 *
1020 * The memory layout of a B_G_R24 image looks like this:
1021 * <pre>
1022 * b-plane: g-plane: r-plane:
1023 * --------- --------- ---------
1024 * | B B B B | | G G G G | | R R R R |
1025 * | B B B B | | G G G G | | R R R R |
1026 * | B B B B | | G G G G | | R R R R |
1027 * | B B B B | | G G G G | | R R R R |
1028 * --------- --------- ---------
1029 * </pre>
1030 */
1031 FORMAT_B_G_R24 = 49ull | GenericPixelFormat<DT_UNSIGNED_INTEGER_8, CV_CHANNELS_UNDEFINED /* as non-generic */, PV_PLANES_3, MV_MULTIPLE_1, MV_MULTIPLE_1>::value,
1032
1033 /**
1034 * Pixel format with byte order YUV and 24 bits per pixel.
1035 *
1036 * The pixel format is using a limited value range for all three channels:
1037 * <pre>
1038 * Y channel: [16, 235]
1039 * U channel: [16, 240]
1040 * V channel: [16, 240]
1041 * </pre>
1042 *
1043 * Here is the memory layout:
1044 * <pre>
1045 * Pixel: 0 1 2
1046 * Byte: 0 1 2 3 4 5 6
1047 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
1048 * Channel: 0 1 2 0 1 2 0
1049 * Color: YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYY ........
1050 * </pre>
1051 * @see FORMAT_YUV24_FULL_RANGE.
1052 */
1053 FORMAT_YUV24_LIMITED_RANGE = FORMAT_YUV24,
1054
1055 /**
1056 * Pixel format with byte order YUV and 24 bits per pixel.
1057 *
1058 * The pixel format is using a full value range for all three channels:
1059 * <pre>
1060 * Y channel: [0, 255]
1061 * U channel: [0, 255]
1062 * V channel: [0, 255]
1063 * </pre>
1064 *
1065 * Here is the memory layout:
1066 * <pre>
1067 * Pixel: 0 1 2
1068 * Byte: 0 1 2 3 4 5 6
1069 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
1070 * Channel: 0 1 2 0 1 2 0
1071 * Color: YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYYUUUUUUUUVVVVVVVV YYYYYYYY ........
1072 * </pre>
1073 * @see FORMAT_YUV24_LIMITED_RANGE.
1074 */
1076
1077 /**
1078 * Pixel format with byte order YVU and 24 bits per pixel.
1079 *
1080 * The pixel format is using a limited value range for all three channels:
1081 * <pre>
1082 * Y channel: [16, 235]
1083 * V channel: [16, 240]
1084 * U channel: [16, 240]
1085 * </pre>
1086 *
1087 * Here is the memory layout:
1088 * <pre>
1089 * Pixel: 0 1 2
1090 * Byte: 0 1 2 3 4 5 6
1091 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
1092 * Channel: 0 1 2 0 1 2 0
1093 * Color: YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYY ........
1094 * </pre>
1095 * @see FORMAT_YVU24_FULL_RANGE.
1096 */
1097 FORMAT_YVU24_LIMITED_RANGE = FORMAT_YVU24,
1098
1099 /**
1100 * Pixel format with byte order YVU and 24 bits per pixel.
1101 *
1102 * The pixel format is using a full value range for all three channels:
1103 * <pre>
1104 * Y channel: [0, 255]
1105 * V channel: [0, 255]
1106 * U channel: [0, 255]
1107 * </pre>
1108 *
1109 * Here is the memory layout:
1110 * <pre>
1111 * Pixel: 0 1 2
1112 * Byte: 0 1 2 3 4 5 6
1113 * Bit: 0123456789ABCDEF01234567 89ABCDEF0123456789ABCDEF 01234567
1114 * Channel: 0 1 2 0 1 2 0
1115 * Color: YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYYVVVVVVVVUUUUUUUU YYYYYYYY ........
1116 * </pre>
1117 * @see FORMAT_YVU24_LIMITED_RANGE.
1118 */
1120
1121 /**
1122 * The helper pixel format which can be used to identify the last defined pixel format, FORMAT_END is exclusive.
1123 */
1124 FORMAT_END = 52ull
1126
1127 /**
1128 * Definition of a vector holding pixel formats.
1129 */
1130 using PixelFormats = std::vector<PixelFormat>;
1131
1132 /**
1133 * Defines different types of frame origin positions.
1134 */
1135 enum PixelOrigin : uint32_t
1136 {
1137 /// Invalid origin type.
1138 ORIGIN_INVALID = 0u,
1139 /// The first pixel lies in the upper left corner, the last pixel in the lower right corner.
1141 /// The first pixel lies in the lower left corner, the last pixel in the upper right corner.
1142 ORIGIN_LOWER_LEFT
1144
1145 private:
1146
1147 /**
1148 * Helper struct allowing to get access to the properties of a pixel format with a debugger.
1149 */
1151 {
1152 /// The value of the pixel format if predefined (if the pixel format is e.g., FORMAT_RGB24, FORMAT_Y8, FORMAT_Y_UV12, ...), 0 if the pixel format is pure generic.
1154
1155 /// The number of channels, the pixel format has.
1156 uint8_t channels_;
1157
1158 /// The data type of each elements of the pixel format.
1160
1161 /// The number of individual planes of the pixel format.
1162 uint8_t planes_;
1163
1164 /// The number of pixels the width of a frame must be a multiple of
1166
1167 /// The number of pixels the height of a frame must be a multiple of
1169
1170 /// Currently unused.
1171 uint8_t unused_;
1172 };
1173
1174 static_assert(sizeof(PixelFormatProperties) == sizeof(std::underlying_type<PixelFormat>::type), "Invalid helper struct!");
1175
1176 /**
1177 * This union mainly contains the pixel format as value.
1178 * In addition, this union allows to access a struct (genericPixelFormatStruct_) to investigate the individual components of a pixel format during a debugging session.<br>
1179 * However, overall this union is nothing else but a wrapper around 'PixelFormat'.
1180 */
1182 {
1183 public:
1184
1185 /**
1186 * Creates a new union object based on a given pixel format.
1187 * @param pixelFormat The pixel format to be stored in the new union
1188 */
1189 explicit inline PixelFormatUnion(const PixelFormat& pixelFormat);
1190
1191 public:
1192
1193 /**
1194 * The actual pixel format defining the layout of the color space, the number of channels and the data type.
1195 * In case, the pixel format is pure generic, use 'genericPixelFormatStruct_' during a debugging session to lookup the data type and channel number.
1196 */
1198
1199 private:
1200
1201 /// The properties of the pixel format.
1203 };
1204
1205 public:
1206
1207 /**
1208 * Creates a new frame type with invalid parameters.
1209 */
1210 FrameType() = default;
1211
1212 /**
1213 * Creates a new frame type.
1214 * @param width The width of the frame in pixel, must match with the pixel format condition, widthMultiple()
1215 * @param height The height of the frame in pixel, must match with the pixel format condition, heightMultiple()
1216 * @param pixelFormat Pixel format of the frame
1217 * @param pixelOrigin Pixel origin of the frame
1218 */
1219 inline FrameType(const unsigned int width, const unsigned int height, const PixelFormat pixelFormat, const PixelOrigin pixelOrigin);
1220
1221 /**
1222 * Creates a new frame type.
1223 * @param type Frame type to copy most properties from
1224 * @param width The width of the frame in pixel to be used instead of the width defined in the given frame type, must match with the pixel format condition, widthMultiple()
1225 * @param height The height of the frame in pixel to be used instead of the height defined in the given frame type, must match with the pixel format condition, heightMultiple()
1226 */
1227 inline FrameType(const FrameType& type, const unsigned int width, const unsigned int height);
1228
1229 /**
1230 * Creates a new frame type.
1231 * @param type Frame type to copy most properties from
1232 * @param pixelFormat Pixel format to be used instead of the pixel format defined in the given frame type
1233 */
1234 inline FrameType(const FrameType& type, const PixelFormat pixelFormat);
1235
1236 /**
1237 * Creates a new frame type.
1238 * @param type Frame type to copy most properties from
1239 * @param pixelOrigin Pixel origin to be used instead of the pixel origin defined in the given frame type
1240 */
1241 inline FrameType(const FrameType& type, const PixelOrigin pixelOrigin);
1242
1243 /**
1244 * Creates a new frame type.
1245 * @param type Frame type to copy most properties from
1246 * @param pixelFormat Pixel format of the frame
1247 * @param pixelOrigin Pixel origin to be used instead of the pixel origin defined in the given frame type
1248 */
1249 inline FrameType(const FrameType& type, const PixelFormat pixelFormat, const PixelOrigin pixelOrigin);
1250
1251 /**
1252 * Returns the width of the frame format in pixel.
1253 * @return Width in pixel
1254 */
1255 inline unsigned int width() const;
1256
1257 /**
1258 * Returns the height of the frame in pixel.
1259 * @return Height in pixel
1260 */
1261 inline unsigned int height() const;
1262
1263 /**
1264 * Returns the pixel format of the frame.
1265 * @return Pixel format
1266 */
1267 inline PixelFormat pixelFormat() const;
1268
1269 /**
1270 * Explicitly changes the pixel format of this frame.
1271 * Beware: Commonly there is no need to change the pixel format explicitly.
1272 * @param pixelFormat The new pixel format to be set, can be invalid
1273 */
1274 inline void setPixelFormat(const PixelFormat pixelFormat);
1275
1276 /**
1277 * Returns the data type of the pixel format of this frame.
1278 * @return The frame's data type
1279 */
1280 inline DataType dataType() const;
1281
1282 /**
1283 * Returns the number of bytes which are necessary to store the data type of this frame.
1284 * @return The number of bytes of the frame's data type, with range [1, infinity)
1285 */
1286 inline unsigned int bytesPerDataType() const;
1287
1288 /**
1289 * Returns the number of individual channels the frame has.
1290 * An invalid frame or a frame with undefined pixel format has 0 channels.
1291 * @return Number of channels, with range [0, infinity)
1292 */
1293 inline unsigned int channels() const;
1294
1295 /**
1296 * Returns the number of planes of the pixel format of this frame.
1297 * @return The number of planes, with range [0, infinity)
1298 */
1299 inline uint32_t numberPlanes() const;
1300
1301 /**
1302 * Returns the pixel origin of the frame.
1303 * @return Pixel origin
1304 */
1305 inline PixelOrigin pixelOrigin() const;
1306
1307 /**
1308 * Returns the number of pixels for the frame.
1309 * @return Number of frame pixels
1310 */
1311 inline unsigned int pixels() const;
1312
1313 /**
1314 * Returns the number of bytes necessary for the frame type, without padding at the end of frame rows.
1315 * In case the pixel format holds more than one plane, the resulting number of bytes is the sum of all planes.
1316 * Beware: An actual frame may have a larger size if the frame comes with padding at end of rows.
1317 * @return The size of the memory necessary for this frame type in bytes, with range [0, infinity)
1318 * @see Frame::size().
1319 */
1320 unsigned int frameTypeSize() const;
1321
1322 /**
1323 * Returns whether the pixel format of this frame type is compatible with a given pixel format.
1324 * Two pixel formats are compatible if:
1325 * - Both pixel formats are identical, or
1326 * - Both pixel formats are pure generic pixel formats with identical data type and channel number, or
1327 * - One pixel format is not pure generic (e.g., FORMAT_RGB24), while the other pixel format is pure generic but has the same data type and channel number
1328 * @param pixelFormat The pixel format to be checked, must be valid
1329 * @return True, if the given pixel format is compatible
1330 * @see isFrameTypeCompatible(), isPixelFormatDataLayoutCompatible().
1331 */
1332 inline bool isPixelFormatCompatible(const PixelFormat pixelFormat) const;
1333
1334 /**
1335 * Returns whether this pixel format has a compatible data layout with a given pixel format.
1336 * Two pixel formats have compatible data layouts if they have the same memory structure (data type, channels, planes, width/height multiples, packed status).<br>
1337 * This means both pixel formats can be forwarded to the same Computer Vision function without crashing, although they may produce different results.
1338 * @param pixelFormat The pixel format to be checked, must be valid
1339 * @return True, if the given pixel format has a compatible data layout
1340 * @see isPixelFormatCompatible(), isFrameTypeCompatible().
1341 */
1342 inline bool isPixelFormatDataLayoutCompatible(const PixelFormat pixelFormat) const;
1343
1344 /**
1345 * Returns whether this frame type is compatible with a given frame type.
1346 * Two frame types are compatible if:
1347 * - Both types are identical, or
1348 * - Both types have the same dimension and compatible pixel formats
1349 * @param frameType The first frame type to be checked, must be valid
1350 * @param allowDifferentPixelOrigins True, to allow different pixel origins; False, so that both frame types must have the same pixel origin
1351 * @return True, if the given frame type is compatible
1352 * @see isPixelFormatCompatible().
1353 */
1354 inline bool isFrameTypeCompatible(const FrameType& frameType, const bool allowDifferentPixelOrigins) const;
1355
1356 /**
1357 * Returns whether this frame type has a compatible data layout with a given frame type.
1358 * Two frame types have compatible data layouts if they have the same dimensions and their pixel formats have compatible data layouts.
1359 * This means both frame types can be forwarded to the same Computer Vision function without crashing, although they may produce different results.
1360 * @param frameType The frame type to be checked, must be valid
1361 * @param allowDifferentPixelOrigins True, to allow different pixel origins; False, so that both frame types must have the same pixel origin
1362 * @return True, if the given frame type has a compatible data layout
1363 * @see isFrameTypeCompatible(), isPixelFormatDataLayoutCompatible().
1364 */
1365 inline bool isFrameTypeDataLayoutCompatible(const FrameType& frameType, const bool allowDifferentPixelOrigins) const;
1366
1367 /**
1368 * Returns whether two frame types are equal.
1369 * @param right The right frame type
1370 * @return True, if so
1371 */
1372 bool operator==(const FrameType& right) const;
1373
1374 /**
1375 * Returns whether two frame types are not equal.
1376 * @param right The right frame type
1377 * @return True, if so
1378 */
1379 inline bool operator!=(const FrameType& right) const;
1380
1381 /**
1382 * Returns whether the left frame type is 'smaller' than the right one.
1383 * The operator does not compare the area of both frames but considers 'width', 'height', pixel format, and pixel origin to create a unique order between frame types.
1384 * @param right The right frame type
1385 * @return True, if so
1386 */
1387 bool operator<(const FrameType& right) const;
1388
1389 /**
1390 * Returns whether this frame type is valid.
1391 * @return True, if so
1392 */
1393 inline bool isValid() const;
1394
1395 /**
1396 * Returns the number of individual channels of a given pixel format.
1397 * @param pixelFormat Pixel format to be check
1398 * @return Number of channels
1399 */
1400 static unsigned int channels(const PixelFormat pixelFormat);
1401
1402 /**
1403 * Returns the number of planes of a pixel format.
1404 * @param pixelFormat The pixel format for which the number of planes will be returned
1405 * @return The number of planes, with range [0, infinity)
1406 */
1407 static inline uint32_t numberPlanes(const PixelFormat pixelFormat);
1408
1409 /**
1410 * Returns the (pixel format) data type of a given C++ data type.
1411 * @return The data type of the given template parameter, DT_UNDEFINED if the C++ data type is not supported
1412 * @tparam T The C++ data type for which the (pixel format) data type is returned
1413 */
1414 template <typename T>
1415 static constexpr DataType dataType();
1416
1417 /**
1418 * Returns the data type of a pixel format.
1419 * @param pixelFormat Pixel format to be check
1420 * @return The data type of the given pixel format, DT_UNDEFINED if the pixel format is not supported
1421 */
1422 static inline DataType dataType(const PixelFormat pixelFormat);
1423
1424 /**
1425 * Returns the number of bytes which are necessary to store a specified data type.
1426 * @param dataType The data type for which the number of bytes is requested
1427 * @return The number of bytes per data type, with range [1, infinity)
1428 */
1429 static unsigned int bytesPerDataType(const DataType dataType);
1430
1431 /**
1432 * Returns a specific generic pixel format with a specified data type, channel number, and plane number.
1433 * @param dataType The data type of the generic format
1434 * @param channels The number of channels of the generic format, with range [1, 31]
1435 * @param planes The number of planes of the generic pixel format, with range [1, 255]
1436 * @param widthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1437 * @param heightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1438 * @return Pixel format the resulting pixel format
1439 */
1440 static constexpr inline PixelFormat genericPixelFormat(const DataType dataType, const uint32_t channels, const uint32_t planes = 1u, const uint32_t widthMultiple = 1u, const uint32_t heightMultiple = 1u);
1441
1442 /**
1443 * Returns a specific generic pixel format with specified bit per pixel per channel, channel number, and plane number.
1444 * The overall number of bits per pixel will be bitsPerPixelChannel * channels
1445 * @param bitsPerPixelChannel The number of bits each pixel and channel of the pixel format will have, with values (4, 8, 16, 32, 64)
1446 * @param channels The number of channels of the generic format, with range [1, 31]
1447 * @param planes The number of planes of the generic pixel format, with range [1, 255]
1448 * @param widthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1449 * @param heightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1450 * @return Pixel format the resulting pixel format
1451 */
1452 static PixelFormat genericPixelFormat(const unsigned int bitsPerPixelChannel, const uint32_t channels, const uint32_t planes = 1u, const uint32_t widthMultiple = 1u, const uint32_t heightMultiple = 1u);
1453
1454 /**
1455 * Returns a specific generic pixel format with a specified data type and channel number.
1456 * @return Pixel format the resulting pixel format
1457 * @tparam tDataType The data type of the generic format
1458 * @tparam tChannels The number of channels of the generic format, with range [1, 31]
1459 * @tparam tPlanes The number of planes of the generic pixel format, with range [1, 255]
1460 * @tparam tWidthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1461 * @tparam tHeightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1462 *
1463 * @code
1464 * // a pixel format with 3 channels storing 'unsigned char' values for each channel
1465 * const FrameType::PixelFormat pixelFormat3Channels = FrameType::genericPixelFormat<FrameType::DT_UNSIGNED_INTEGER_8, 3u>();
1466 *
1467 * // a pixel format with 1 channel composed of 'float' values
1468 * const FrameType::PixelFormat pixelFormat1Channel = FrameType::genericPixelFormat<FrameType::DT_SIGNED_FLOAT_32, 1u>();
1469 * @endcode
1470 * @see genericPixelFormat<TDataType, tChannels>();
1471 */
1472 template <DataType tDataType, uint32_t tChannels, uint32_t tPlanes = 1u, uint32_t tWidthMultiple = 1u, uint32_t tHeightMultiple = 1u>
1473 constexpr static PixelFormat genericPixelFormat();
1474
1475 /**
1476 * Returns a specific generic pixel format with a specified data type and channel number.
1477 * @return Pixel format the resulting pixel format
1478 * @param channels The number of channels of the generic format, with range [1, 31]
1479 * @param planes The number of planes of the generic pixel format, with range [1, 255]
1480 * @param widthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1481 * @param heightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1482 * @tparam tDataType The data type of the generic format
1483 *
1484 * @code
1485 * // a pixel format with 3 channels storing 'unsigned char' values for each channel
1486 * const FrameType::PixelFormat pixelFormat3Channels = FrameType::genericPixelFormat<FrameType::DT_UNSIGNED_INTEGER_8>(3u);
1487 *
1488 * // a pixel format with 1 channel composed of 'float' values
1489 * const FrameType::PixelFormat pixelFormat1Channel = FrameType::genericPixelFormat<FrameType::DT_SIGNED_FLOAT_32>(1u);
1490 * @endcode
1491 */
1492 template <DataType tDataType>
1493 constexpr static PixelFormat genericPixelFormat(const uint32_t channels, const uint32_t planes = 1u, const uint32_t widthMultiple = 1u, const uint32_t heightMultiple = 1u);
1494
1495 /**
1496 * Returns a specific generic pixel format with a specified data type and channel number.
1497 * @return Pixel format the resulting pixel format
1498 * @tparam TDataType The C++ data type for which the (pixel format) data type is returned
1499 * @tparam tChannels The number of channels of the generic format, with range [1, 31]
1500 * @tparam tPlanes The number of planes of the generic pixel format, with range [1, 255]
1501 * @tparam tWidthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1502 * @tparam tHeightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1503 *
1504 * The following code snippet shows how to use this function:
1505 * @code
1506 * // a pixel format with 3 channels storing 'unsigned char' values for each channel
1507 * const FrameType::PixelFormat pixelFormat3Channels = FrameType::genericPixelFormat<unsigned char, 3u>();
1508 *
1509 * // a pixel format with 1 channel composed of 'float' values
1510 * const FrameType::PixelFormat pixelFormat1Channel = FrameType::genericPixelFormat<float, 1u>();
1511 * @endcode
1512 * @see genericPixelFormat<tDataType, tChannels>();
1513 */
1514 template <typename TDataType, uint32_t tChannels, uint32_t tPlanes = 1u, uint32_t tWidthMultiple = 1u, uint32_t tHeightMultiple = 1u>
1516
1517 /**
1518 * Returns a specific generic pixel format with a specified data type and channel number.
1519 * @return Pixel format the resulting pixel format
1520 * @param channels The number of channels of the generic format, with range [1, 31]
1521 * @param planes The number of planes of the generic pixel format, with range [1, 255]
1522 * @param widthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1523 * @param heightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1524 * @tparam TDataType The C++ data type for which the (pixel format) data type is returned
1525 *
1526 * The following code snippet shows how to use this function:
1527 * @code
1528 * // a pixel format with 3 channels storing 'unsigned char' values for each channel
1529 * const FrameType::PixelFormat pixelFormat3Channels = FrameType::genericPixelFormat<unsigned char>(3u);
1530 *
1531 * // a pixel format with 1 channel composed of 'float' values
1532 * const FrameType::PixelFormat pixelFormat1Channel = FrameType::genericPixelFormat<float>(1u);
1533 * @endcode
1534 */
1535 template <typename TDataType>
1536 constexpr static PixelFormat genericPixelFormat(uint32_t channels, const uint32_t planes = 1u, const uint32_t widthMultiple = 1u, const uint32_t heightMultiple = 1u);
1537
1538 /**
1539 * Converts a any pixel format into a generic one
1540 * This function has no effect for input pixel formats which are already generic
1541 * @param pixelFormat A pixel format
1542 * @return The generic pixel format; for generic pixel formats output will be identical to input
1543 */
1544 static inline PixelFormat makeGenericPixelFormat(const PixelFormat pixelFormat);
1545
1546 /**
1547 * Checks whether a given pixel format is a specific layout regarding data channels and data type.
1548 * @param pixelFormat The pixel format to be checked
1549 * @param dataType The expected data type of the given pixel format
1550 * @param channels The expected number of channels of the given pixel format, with range [0, 31]
1551 * @param planes The number of planes of the generic pixel format, with range [0, 255]
1552 * @param widthMultiple The number of pixels the width of a frame must be a multiple of, with range [1, 255]
1553 * @param heightMultiple The number of pixels the height of a frame must be a multiple of, with range [1, 255]
1554 * @return True, if succeeded
1555 */
1556 static inline bool formatIsGeneric(const PixelFormat pixelFormat, const DataType dataType, const uint32_t channels, const uint32_t planes = 1u, const uint32_t widthMultiple = 1u, const uint32_t heightMultiple = 1u);
1557
1558 /**
1559 * Checks whether a given pixel format is a generic pixel format.
1560 * @param pixelFormat The pixel format to be checked
1561 * @return True, if succeeded
1562 */
1563 static inline bool formatIsGeneric(const PixelFormat pixelFormat);
1564
1565 /**
1566 * Checks whether a given pixel format is a pure generic pixel format.
1567 * @param pixelFormat The pixel format to be checked
1568 * @return True, if succeeded
1569 */
1570 static inline bool formatIsPureGeneric(const PixelFormat pixelFormat);
1571
1572 /**
1573 * Returns the number of individual channels of a given generic pixel format.
1574 * @param pixelFormat Generic pixel format to be checked
1575 * @return The number of channels, 0 if the pixel format is not generic (e.g., FORMAT_Y_UV12)
1576 */
1577 static unsigned int formatGenericNumberChannels(const PixelFormat pixelFormat);
1578
1579 /**
1580 * Returns the number of bits of one pixel for a given generic pixel format.
1581 * @param pixelFormat Pixel format to check
1582 * @return Number of bits per pixel
1583 */
1584 static inline unsigned int formatGenericBitsPerPixel(const PixelFormat pixelFormat);
1585
1586 /**
1587 * Returns the number of bits of one pixel for the red channel.
1588 * @param pixelFormat Pixel format to check
1589 * @return Number of bits per pixel
1590 */
1591 static unsigned int formatBitsPerPixelRedChannel(const PixelFormat pixelFormat);
1592
1593 /**
1594 * Returns the number of bits of one pixel for the green channel.
1595 * @param pixelFormat Pixel format to check
1596 * @return Number of bits per pixel
1597 */
1598 static unsigned int formatBitsPerPixelGreenChannel(const PixelFormat pixelFormat);
1599
1600 /**
1601 * Returns the number of bits of one pixel for the blue channel.
1602 * @param pixelFormat Pixel format to check
1603 * @return Number of bits per pixel
1604 */
1605 static unsigned int formatBitsPerPixelBlueChannel(const PixelFormat pixelFormat);
1606
1607 /**
1608 * Returns the number of bits of one pixel for the alpha channel.
1609 * @param pixelFormat Pixel format to check
1610 * @return Number of bits per pixel
1611 */
1612 static unsigned int formatBitsPerPixelAlphaChannel(const PixelFormat pixelFormat);
1613
1614 /**
1615 * Returns whether a given pixel format holds an alpha channel.
1616 * @param pixelFormat Pixel format to check
1617 * @param isLastChannel Optional returning whether the alpha channel is the last channel (true) or whether it is the first channel (false)
1618 * @return True, if so
1619 */
1620 static bool formatHasAlphaChannel(const PixelFormat pixelFormat, bool* isLastChannel = nullptr);
1621
1622 /**
1623 * Returns whether a given pixel format is a packed pixel format.
1624 * Packed pixel formats like FORMAT_BGGR10_PACKED or FORMAT_Y10_PACKED contain bytes providing color information for several individual pixels.
1625 * @return True, if so
1626 */
1627 static bool formatIsPacked(const PixelFormat pixelFormat);
1628
1629 /**
1630 * Returns whether a given pixel format is using a limited value range (e.g., like Y_UV12_LIMITED_RANGE) or a full value range (e.g., like Y_UV12_FULL_RANGE).
1631 * @param pixelFormat The pixel format to be checked
1632 * @return True, if the pixel format is using a limited value range; False, if the pixel format is using a full value range
1633 */
1634 static bool formatIsLimitedRange(const PixelFormat pixelFormat);
1635
1636 /**
1637 * Returns the most suitable 1-plane pixel format for a given pixel format which may be composed of several planes.
1638 * If the given pixel format is a generic 1-plane pixel format already, the same pixel format will be returned.
1639 * Here is a table with some examples:
1640 * <pre>
1641 * Output pixel format: Input pixel format:
1642 * <generic pixel format> <generic pixel format> (e.g., FORMAT_RGB24)
1643 * FORMAT_BGR24 FORMAT_BGR4444, FORMAT_BGR5551, FORMAT_BGR565
1644 * FORMAT_BGRA32 FORMAT_BGRA4444
1645 * FORMAT_RGB24 FORMAT_RGB4444, FORMAT_RGB5551, FORMAT_RGB565
1646 * FORMAT_RGBA32 FORMAT_RGBA4444
1647 * FORMAT_YUV24, FORMAT_Y_UV12, FORMAT_UYVY16, FORMAT_Y_U_V12, FORMAT_YUYV16, FORMAT_Y_U_V24
1648 * FORMAT_YVU24 FORMAT_Y_VU12, FORMAT_Y_V_U12
1649 * </pre>
1650 * @param pixelFormat Pixel format for which the 1-plane pixel format will be returned
1651 * @return The resulting 1-plane pixel format, FORMAT_UNDEFINED if no matching pixel format could be found
1652 */
1654
1655 /**
1656 * Adds an alpha channel to a given pixel format.
1657 * @param pixelFormat Pixel format without alpha channel
1658 * @param lastChannel True, to add the alpha channel at the end of the data channels, otherwise the alpha channel will be added in front of the data channels
1659 * @return Pixel format with alpha channel, if existing
1660 */
1661 static PixelFormat formatAddAlphaChannel(const PixelFormat pixelFormat, const bool lastChannel = true);
1662
1663 /**
1664 * Removes an alpha channel from a given pixel format.
1665 * @param pixelFormat Pixel format with alpha channel
1666 * @return Pixel format without alpha channel, if existing
1667 */
1669
1670 /**
1671 * Returns the best matching grayscale pixel format for a given pixel format.
1672 * The resulting pixel format will either be FORMAT_Y8_LIMITED_RANGE or FORMAT_Y8_FULL_RANGE, depending on the whether the input pixel format is a limited range or a full range pixel format.<br>
1673 * The function can be used to quickly determine the grayscale pixel format for an input image to avoid making a copy of the image during conversion:
1674 * <pre>
1675 * Frame inputFrame = ... // e.g., FORMAT_RGB24, or FORMAT_Y_UV12_LIMITED_RANGE, or FORMAT_Y_UV12_FULL_RANGE
1676 * Frame yFrame; // a frame with either FORMAT_Y8_LIMITED_RANGE or FORMAT_Y8_FULL_RANGE
1677 * CV::FrameConverter::Comfort::convert(inputFrame, FrameType::formatGrayscalePixelFormat(inputFrame.pixelFormat()), yFrame, CV::FrameConverter::CP_AVOID_COPY_IF_POSSIBLE);
1678 * </pre>
1679 * @param pixelFormat The pixel format for which the best matching grayscale pixel format will be returned, must be valid
1680 * @return The best matching grayscale pixel format, either FORMAT_Y8_LIMITED_RANGE or FORMAT_Y8_FULL_RANGE
1681 */
1683
1684 /**
1685 * Returns the number of pixels the width of a frame must be a multiple of.
1686 * @param pixelFormat Pixel format to return the number of pixels for
1687 * @return Number of pixels
1688 */
1689 static inline unsigned int widthMultiple(const PixelFormat pixelFormat);
1690
1691 /**
1692 * Returns the number of pixels the height of a frame must be a multiple of.
1693 * @param pixelFormat Pixel format to return the number of pixels for
1694 * @return Number of pixels
1695 */
1696 static inline unsigned int heightMultiple(const PixelFormat pixelFormat);
1697
1698 /**
1699 * Returns the channels of a plane for a pixel format.
1700 * @param imagePixelFormat The pixel format of the entire frame, must be valid
1701 * @param planeIndex The index of the plane for which the channels will be returned, with range [0, numberPlanes(imagePixelFormat))
1702 * @return The plane's channels, with range [0, infinity)
1703 */
1704 static unsigned int planeChannels(const PixelFormat& imagePixelFormat, const unsigned int planeIndex);
1705
1706 /**
1707 * Returns the number of bytes of one pixel of a plane for a pixel format.
1708 * Beware: This function will return 0 if the pixel format is a special packed format (e.g., FORMAT_Y10_PACKED) which does not allow to calculate the number of bytes per pixel.
1709 * @param imagePixelFormat The pixel format of the entire frame, must be valid
1710 * @param planeIndex The index of the plane for which the bytes per pixel will be returned, with range [0, numberPlanes(imagePixelFormat))
1711 * @return The plane's number of bytes per pixel, will be 0 for special packed pixel formats like FORMAT_Y10_PACKED
1712 */
1713 static inline unsigned int planeBytesPerPixel(const PixelFormat& imagePixelFormat, const unsigned int planeIndex);
1714
1715 /**
1716 * Returns the plane layout of a given pixel format.
1717 * @param imagePixelFormat The pixel format of the image for which the plane layout will be returned, must be valid
1718 * @param imageWidth The width of the image, in (image) pixel, with range [1, infinity)
1719 * @param imageHeight The height of the image, in (image) pixel, with range [1, infinity)
1720 * @param planeIndex The index of the plane for which the layout will be returned, with range [0, numberPlanes(imagePixelFormat) - 1]
1721 * @param planeWidth The resulting width of the specified plane, in (plane) pixel, with range [1, infinity)
1722 * @param planeHeight The resulting height of the specified plane, in (plane) pixel, with range [1, infinity)
1723 * @param planeChannels The resulting number of channels the plane has, with range [1, infinity)
1724 * @param planeWidthElementsMultiple Optional the resulting number of (plane) elements the width of the plane must be a multiple of, in elements, with range [1, infinity)
1725 * @param planeHeightElementsMultiple Optional the resulting number of (plane) elements the height of the plane must be a multiple of, in elements, with range [1, infinity)
1726 * @return True, if succeeded
1727 */
1728 static bool planeLayout(const PixelFormat imagePixelFormat, const unsigned int imageWidth, const unsigned int imageHeight, const unsigned int planeIndex, unsigned int& planeWidth, unsigned int& planeHeight, unsigned int& planeChannels, unsigned int* planeWidthElementsMultiple = nullptr, unsigned int* planeHeightElementsMultiple = nullptr);
1729
1730 /**
1731 * Returns the plane layout of a given frame type.
1732 * @param frameType The frame type for which the plane layout will be returned, must be valid
1733 * @param planeIndex The index of the plane for which the layout will be returned, with range [0, numberPlanes(imagePixelFormat) - 1]
1734 * @param planeWidth The resulting width of the specified plane, in (plane) pixel, with range [1, infinity)
1735 * @param planeHeight The resulting height of the specified plane, in (plane) pixel, with range [1, infinity)
1736 * @param planeChannels The resulting number of channels the plane has, with range [1, infinity)
1737 * @param planeWidthElementsMultiple Optional the resulting number of (plane) elements the width of the plane must be a multiple of, in elements, with range [1, infinity)
1738 * @param planeHeightElementsMultiple Optional the resulting number of (plane) elements the height of the plane must be a multiple of, in elements, with range [1, infinity)
1739 * @return True, if succeeded
1740 */
1741 static inline bool planeLayout(const FrameType& frameType, const unsigned int planeIndex, unsigned int& planeWidth, unsigned int& planeHeight, unsigned int& planeChannels, unsigned int* planeWidthElementsMultiple = nullptr, unsigned int* planeHeightElementsMultiple = nullptr);
1742
1743 /**
1744 * Translates a string containing a data type into the data type.<br>
1745 * For example 'UNSIGNED_INTEGER_8' will be translated into DT_UNSIGNED_INTEGER_8.
1746 * @param dataType Data type as string
1747 * @return Data type as value
1748 */
1749 static DataType translateDataType(const std::string& dataType);
1750
1751 /**
1752 * Translates a string containing a pixel format into the pixel format.<br>
1753 * For example 'BGR24' will be translated into FORMAT_BGR24.
1754 * @param pixelFormat Pixel format as string
1755 * @return Pixel format as value
1756 */
1757 static PixelFormat translatePixelFormat(const std::string& pixelFormat);
1758
1759 /**
1760 * Translates a string containing the pixel origin into the pixel origin value.<br>
1761 * For example 'UPPER_LEFT' will be translated into ORIGIN_UPPER_LEFT.
1762 * @param pixelOrigin Pixel origin as string
1763 * @return Pixel origin as value
1764 */
1765 static PixelOrigin translatePixelOrigin(const std::string& pixelOrigin);
1766
1767 /**
1768 * Translates a data type value into a string containing the data type.<br>
1769 * For example the DT_UNSIGNED_INTEGER_8 will be translated into 'UNSIGNED_INTEGER_8'.
1770 * @param dataType the data type as value
1771 * @return The data type as string, 'UNDEFINED' if the data type is invalid or cannot be translated
1772 */
1773 static std::string translateDataType(const DataType dataType);
1774
1775 /**
1776 * Translates a pixel format value into a string containing the pixel format.<br>
1777 * For example the FORMAT_BGR24 will be translated into 'BGR24'.
1778 * @param pixelFormat Pixel format as value
1779 * @return Pixel format as string, 'UNDEFINED' if the pixel format is invalid or cannot be translated
1780 */
1781 static std::string translatePixelFormat(const PixelFormat pixelFormat);
1782
1783 /**
1784 * Translates a pixel origin value into a string containing the pixel origin.<br>
1785 * For example the ORIGIN_UPPER_LEFT will be translated into 'UPPER_LEFT'.
1786 * @param pixelOrigin Pixel origin as value
1787 * @return Pixel origin as string, 'INVALID' if the pixel origin is invalid or cannot be translated
1788 */
1789 static std::string translatePixelOrigin(const PixelOrigin pixelOrigin);
1790
1791 /**
1792 * Returns a best fitting pixel format having the given number of bits per pixels.
1793 * @param bitsPerPixel Number of bits per pixel the resulting pixel format will have, with range [1, infinity)
1794 * @return Resulting pixel format, FORMAT_UNDEFINED if no pixel format can be found
1795 */
1796 static PixelFormat findPixelFormat(const unsigned int bitsPerPixel);
1797
1798 /**
1799 * Returns a best fitting pixel format having the given number of bits per pixels.
1800 * The following mappings are defined:
1801 * <pre>
1802 * DataType: Channels: PixelFormat:
1803 * DT_UNSIGNED_INTEGER_8 1 FORMAT_Y8
1804 * DT_UNSIGNED_INTEGER_8 2 FORMAT_YA16
1805 * DT_UNSIGNED_INTEGER_8 3 FORMAT_RGB24
1806 * DT_UNSIGNED_INTEGER_8 4 FORMAT_RGBA32
1807 *
1808 * DT_UNSIGNED_INTEGER_16 3 FORMAT_RGB48
1809 * DT_UNSIGNED_INTEGER_16 4 FORMAT_RGBA64
1810 * </pre>
1811 * @param dataType The data type of each pixel element for which a pixel type is determined, must be valid
1812 * @param channels The number of channels for which a pixel format will be determined, with range [1, infinity)
1813 * @return Resulting pixel format, FORMAT_UNDEFINED if no pixel format can be found
1814 */
1815 static PixelFormat findPixelFormat(const DataType dataType, const unsigned int channels);
1816
1817 /**
1818 * Returns whether two given pixel formats are compatible.
1819 * Two pixel formats are compatible if:
1820 * - Both pixel formats are identical, or
1821 * - Both pixel formats are pure generic pixel formats with identical data type and channel number, or
1822 * - One pixel format is not pure generic (e.g., FORMAT_RGB24), while the other pixel format is pure generic but has the same data type and channel number
1823 * @param pixelFormatA The first pixel format to be checked, must be valid
1824 * @param pixelFormatB The second pixel format to be checked, must be valid
1825 * @return True, if both pixel formats are compatible
1826 * @see areFrameTypesCompatible().
1827 */
1828 static bool arePixelFormatsCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB);
1829
1830 /**
1831 * Returns whether two given frame types are compatible.
1832 * Two frame types are compatible if:
1833 * - Both types are identical, or
1834 * - Both types have the same dimension and compatible pixel formats
1835 * @param frameTypeA The first frame type to be checked, must be valid
1836 * @param frameTypeB The second frame type to be checked, must be valid
1837 * @param allowDifferentPixelOrigins True, to allow different pixel origins; False, so that both frame types must have the same pixel origin
1838 * @return True, if both frame types are compatible
1839 * @see arePixelFormatsCompatible().
1840 */
1841 static bool areFrameTypesCompatible(const FrameType& frameTypeA, const FrameType& frameTypeB, const bool allowDifferentPixelOrigins);
1842
1843 /**
1844 * Returns whether two given frame types have compatible data layouts.
1845 * Two frame types have compatible data layouts if they have the same dimensions and their pixel formats have compatible data layouts.
1846 * This means both frame types can be forwarded to the same Computer Vision function without crashing, although they may produce different results.
1847 * @param frameTypeA The first frame type to be checked, must be valid
1848 * @param frameTypeB The second frame type to be checked, must be valid
1849 * @param allowDifferentPixelOrigins True, to allow different pixel origins; False, so that both frame types must have the same pixel origin
1850 * @return True, if both frame types have compatible data layouts
1851 * @see isDataLayoutCompatible(), areFrameTypesCompatible().
1852 */
1853 static bool areFrameTypesDataLayoutCompatible(const FrameType& frameTypeA, const FrameType& frameTypeB, const bool allowDifferentPixelOrigins);
1854
1855 /**
1856 * Returns whether two given pixel formats have compatible data layouts.
1857 * Two pixel formats have compatible data layouts if they have the same memory structure (data type, channels, planes, width/height multiples, packed status).
1858 * This means both pixel formats can be forwarded to the same Computer Vision function without crashing, although they may produce different results.
1859 * For example:
1860 * - FORMAT_RGB24 and FORMAT_BGR24 have compatible layouts (both are 3-channel uint8, non-packed, 1 plane)
1861 * - FORMAT_Y_UV12 and FORMAT_Y_VU12 have compatible layouts (both are 3-channel uint8, 2 planes, with specific width/height multiples)
1862 * @param pixelFormatA The first pixel format to be checked, must be valid
1863 * @param pixelFormatB The second pixel format to be checked, must be valid
1864 * @return True, if both pixel formats have compatible data layouts
1865 * @see arePixelFormatsCompatible(), areFrameTypesCompatible().
1866 */
1867 static bool isDataLayoutCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB);
1868
1869 /**
1870 * Returns whether a given pointer has the same byte alignment as the size of the data type the pointer is pointing to.
1871 * Actually, this function returns whether the following condition is true:
1872 * <pre>
1873 * size_t(data) % sizeof(T) == 0
1874 * </pre>
1875 * @param data The pointer to the memory to be checked, must be valid
1876 * @return True, if so
1877 */
1878 template <typename T>
1879 static inline bool dataIsAligned(const void* data);
1880
1881 /**
1882 * Returns all defined data types.
1883 * @return Ocean's defined data types
1884 */
1886
1887 /**
1888 * Returns all defined pixel formats.
1889 * @return Ocean's defined pixel formats
1890 */
1892
1893 /**
1894 * Returns whether two values can be added with each other without producing an overflow.
1895 * @param valueA The first value to add
1896 * @param valueB The second value to add
1897 * @return True, if the sum is within a valid value range
1898 */
1899 static constexpr bool isSumInsideValueRange(const unsigned int valueA, const unsigned int valueB);
1900
1901 /**
1902 * Returns whether two values can be multiplied with each other without producing an overflow.
1903 * @param valueA The first value to multiply
1904 * @param valueB The second value to multiply
1905 * @return True, if the product is within a valid value range
1906 */
1907 static constexpr bool isProductInsideValueRange(const unsigned int valueA, const unsigned int valueB);
1908
1909 private:
1910
1911 /// Frame width in pixel, with range [0, infinity)
1912 unsigned int width_ = 0u;
1913
1914 /// Frame height in pixel, with range [0, infinity)
1915 unsigned int height_ = 0u;
1916
1917 /// The pixel format of the frame encapsulated in a union (mainly holding PixelFormat).
1918 PixelFormatUnion pixelFormat_ = PixelFormatUnion(FORMAT_UNDEFINED);
1919
1920 /// The origin of the pixel data, either the upper left corner or the bottom left corner (if valid).
1921 PixelOrigin pixelOrigin_ = ORIGIN_INVALID;
1922};
1923
1924// Forward declaration.
1925class Frame;
1926
1927/**
1928 * Definition of a vector holding padding frames.
1929 * @see Frame.
1930 * @ingroup base
1931 */
1932using Frames = std::vector<Frame>;
1933
1934/**
1935 * Definition of an object reference for frame objects.
1936 * @ingroup base
1937 */
1939
1940/**
1941 * Definition of a vector holding frame references.
1942 * @ingroup base
1943 */
1944using FrameRefs = std::vector<FrameRef>;
1945
1946/**
1947 * This class implements Ocean's image class.
1948 * An image is composed of several planes, each plane can store image content with interleaved color channels.
1949 * <pre>
1950 * Plane 0:
1951 * ---------------------------------- ----------------------------
1952 * | | |
1953 * | | |
1954 * | |<--- paddingElements(0) --->| plane height (0)
1955 * | | |
1956 * | | |
1957 * ---------------------------------- ----------------------------
1958 *
1959 * Plane 1:
1960 * -------------- ------------------------
1961 * | | |
1962 * | |<- paddingElements(1) ->| plane height (1)
1963 * | | |
1964 * -------------- ------------------------
1965 * </pre>
1966 * @ingroup base
1967 */
1968class OCEAN_BASE_EXPORT Frame : public FrameType
1969{
1970 public:
1971
1972 /**
1973 * Definition of individual copy modes.
1974 */
1975 enum CopyMode : uint32_t
1976 {
1977 /// The source memory is used only, no copy is created, the padding layout is preserved.
1978 CM_USE_KEEP_LAYOUT = 1u << 0u,
1979 /// Makes a copy of the source memory, but the new plane will not contain padding elements.
1980 CM_COPY_REMOVE_PADDING_LAYOUT = 1u << 1u,
1981 /// Makes a copy of the source memory, the padding layout is preserved, but the padding data is not copied.
1982 CM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA = 1u << 2u,
1983 /// Makes a copy of the source memory, the padding layout is preserved, the padding data is copied as well.
1984 CM_COPY_KEEP_LAYOUT_COPY_PADDING_DATA = 1u << 3u,
1985 };
1986
1987 /**
1988 * Definition of advanced copy modes containing all copy modes from `CopyMode` but also some additional.
1989 */
1990 enum AdvancedCopyMode : std::underlying_type<CopyMode>::type
1991 {
1992 /// Same as CM_USE_KEEP_LAYOUT.
1993 ACM_USE_KEEP_LAYOUT = CM_USE_KEEP_LAYOUT,
1994 /// Same as CM_COPY_REMOVE_PADDING_LAYOUT.
1995 ACM_COPY_REMOVE_PADDING_LAYOUT = CM_COPY_REMOVE_PADDING_LAYOUT,
1996 /// Same as CM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA.
1997 ACM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA = CM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA,
1998 /// Same as CM_COPY_KEEP_LAYOUT_COPY_PADDING_DATA.
1999 ACM_COPY_KEEP_LAYOUT_COPY_PADDING_DATA = CM_COPY_KEEP_LAYOUT_COPY_PADDING_DATA,
2000
2001 /// The source memory is used if the source is not owner of the memory; The source memory is copied if the source is owner of the memory, padding layout will be removed.
2002 ACM_USE_OR_COPY = ACM_USE_KEEP_LAYOUT | ACM_COPY_REMOVE_PADDING_LAYOUT,
2003 /// The source memory is used if the source is not owner of the memory; The source memory is copied if the source is owner of the memory, padding layout is preserved, but padding data is not copied.
2004 ACM_USE_OR_COPY_KEEP_LAYOUT = ACM_USE_KEEP_LAYOUT | ACM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA,
2005 };
2006
2007 /**
2008 * Definition of an image plane, a block of memory storing pixel data with interleaved channels (or just one channel).
2009 * The plane does not store the specific pixel format or the width of the plane, as this information is part of the frame which owns the plane.
2010 * A plane has the following memory layout:
2011 * <pre>
2012 * |<-------- plane width ----------->|<-- paddingElements -->|
2013 *
2014 * ---------------------------------- ----------------------- ---
2015 * |A0 A1 An-1 B0 B1 Bn-1 ... | | ^
2016 * |... | | |
2017 * | | | plane height
2018 * | | | |
2019 * | | | V
2020 * ---------------------------------- ----------------------- ---
2021 *
2022 * |<------------------- stride bytes ----------------------->|
2023 *
2024 * With A0 first channel (or element) of first pixel, A1 second channel of first pixel, ...
2025 * And B0 first channel of second pixel, ...
2026 * </pre>
2027 * Note that: strideBytes == (planeWidth * channels + paddingElements) * bytesPerElement.<br>
2028 * A plane can have a different number of channels than a frame's pixel format which is owning the plane.<br>
2029 * The plane's channels are defined in relation to the data type of each pixel:<br>
2030 * A frame with pixel format FORMAT_RGB24 has three channels, one plane, and the plane has three channels (as the data type of each pixel element is uint8_t).<br>
2031 * However, a frame with pixel format FORMAT_RGB565 has three channels, one plane, but the plane has one channel only (as the data type of each pixel is uint16_t).
2032 */
2033 class OCEAN_BASE_EXPORT Plane
2034 {
2035 friend class Frame;
2036
2037 public:
2038
2039 /**
2040 * Creates a new invalid plane.
2041 */
2042 Plane() = default;
2043
2044 /**
2045 * Move constructor.
2046 * @param plane The plane to be moved
2047 */
2048 inline Plane(Plane&& plane) noexcept;
2049
2050 /**
2051 * Copy constructor.
2052 * @param plane The plane to be copied, can be invalid
2053 * @param advancedCopyMode The copy mode specifying whether the source memory is used or copied
2054 */
2055 Plane(const Plane& plane, const AdvancedCopyMode advancedCopyMode = ACM_USE_OR_COPY_KEEP_LAYOUT) noexcept;
2056
2057 /**
2058 * Creates a new plane object with own allocated memory.
2059 * @param width The width of the plane in pixel, with range [1, infinity)
2060 * @param height The height of the plane in pixel, with range [1, infinity)
2061 * @param channels The number of channels the plane has, with respect to the specified data type `T`, with range [1, infinity)
2062 * @param elementTypeSize The size of each element of the new plane, in bytes, with range [1, infinity)
2063 * @param paddingElements The optional number of padding elements at the end of each row, in elements, with range [0, infinity)
2064 */
2065 Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const unsigned int paddingElements) noexcept;
2066
2067 /**
2068 * Creates a new plane object which is not creating a copy of the given memory. Instead, the memory pointer is just used.
2069 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2070 * @param height The height of the plane in pixel, with range [1, infinity)
2071 * @param channels The number of channels the plane has, with respect to the specified data type `T`, with range [1, infinity)
2072 * @param dataToUse Memory pointer of the read-only memory which will not be copied, must be valid
2073 * @param paddingElements The optional number of padding elements at the end of each row, in elements, with range [0, infinity)
2074 * @tparam T The data type of each element
2075 */
2076 template <typename T>
2077 inline Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const T* dataToUse, const unsigned int paddingElements) noexcept;
2078
2079 /**
2080 * Creates a new plane object which is not creating a copy of the given memory. Instead, the memory pointer is just used.
2081 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2082 * @param height The height of the plane in pixel, with range [1, infinity)
2083 * @param channels The number of channels the plane has, with respect to the specified data type `T`, with range [1, infinity)
2084 * @param dataToUse Memory pointer of the writable memory which will not be copied, must be valid
2085 * @param paddingElements The optional number of padding elements at the end of each row, in elements, with range [0, infinity)
2086 * @tparam T The data type of each element
2087 */
2088 template <typename T>
2089 inline Plane(const unsigned int width, const unsigned int height, const unsigned int channels, T* dataToUse, const unsigned int paddingElements) noexcept;
2090
2091 /**
2092 * Creates a new plane object by making a copy of the given memory.
2093 * @param sourceDataToCopy The source data to be copied, must be valid
2094 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2095 * @param height The height of the plane in pixels, with range [1, infinity)
2096 * @param channels The number of channels the plane has, with respect to the specified data type `T`, with range [1, infinity)
2097 * @param targetPaddingElements The optional number of padding elements at the end of each row this new plane will have, in elements, with range [0, infinity)
2098 * @param sourcePaddingElements The number of padding elements at the end of each row the given source memory has, in elements, with range [0, infinity)
2099 * @param makeCopyOfPaddingData True, to copy the entire padding data of the source plane (both planes must have the same padding layout: `targetPaddingElements == sourcePaddingElements`); False, to skip the padding data when copying the plane
2100 * @tparam T The data type of each element
2101 */
2102 template <typename T>
2103 inline Plane(const T* sourceDataToCopy, const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int targetPaddingElements, const unsigned int sourcePaddingElements, const bool makeCopyOfPaddingData = false) noexcept;
2104
2105 /**
2106 * Creates a new plane object by making a copy of the given memory.
2107 * @param sourceDataToCopy The source data to be copied, must be valid
2108 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2109 * @param height The height of the plane in pixels, with range [1, infinity)
2110 * @param channels The number of channels the plane has, with respect to the specified data type `T`, with range [1, infinity)
2111 * @param sourcePaddingElements The number of padding elements at the end of each row the given source memory has, in elements, with range [0, infinity)
2112 * @param copyMode The copy mode to be applied
2113 * @tparam T The data type of each element
2114 */
2115 template <typename T>
2116 inline Plane(const T* sourceDataToCopy, const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int sourcePaddingElements, const CopyMode copyMode) noexcept;
2117
2118 /**
2119 * Destructs a Plane object.
2120 */
2121 inline ~Plane();
2122
2123 /**
2124 * Returns the width of the plane in pixel.
2125 * @return The plane's width, in pixel, with range [0, infinity)
2126 */
2127 inline unsigned int width() const;
2128
2129 /**
2130 * Returns the height of the plane in pixel.
2131 * @return The plane's height, in pixel, with range [0, infinity)
2132 */
2133 inline unsigned int height() const;
2134
2135 /**
2136 * Returns the channels of the plane.
2137 * @return The plane's channels, with range [0, infinity)
2138 */
2139 inline unsigned int channels() const;
2140
2141 /**
2142 * Returns the read-only memory pointer to this plane with a specific data type compatible with elementTypeSize().
2143 * @return The plane's read-only memory pointer, nullptr if this plane is invalid
2144 * @tparam T the data type of the resulting memory pointer, with `sizeof(T) == elementTypeSize()`
2145 */
2146 template <typename T>
2147 inline const T* constdata() const;
2148
2149 /**
2150 * Returns the writable memory pointer to this plane with a specific data type compatible with elementTypeSize().
2151 * @return The plane's writable memory pointer, nullptr if this plane is not writable or invalid
2152 * @tparam T the data type of the resulting memory pointer, with `sizeof(T) == elementTypeSize()`
2153 */
2154 template <typename T>
2155 inline T* data();
2156
2157 /**
2158 * Returns the number of padding elements at the end of each plane row, in elements.
2159 * @return The number of padding elements, with range [0, infinity)
2160 * @see paddingBytes().
2161 */
2162 inline unsigned int paddingElements() const;
2163
2164 /**
2165 * Returns the number of padding bytes at the end of each plane row, in bytes.
2166 * This function actually returns `paddingElements() * elementTypeSize()`.
2167 * @return The number of padding bytes, with range [0, infinity)
2168 * @see paddingElements().
2169 */
2170 inline unsigned int paddingBytes() const;
2171
2172 /**
2173 * Returns the size of each element of this plane.
2174 * @return The element size, in bytes
2175 */
2176 inline unsigned int elementTypeSize() const;
2177
2178 /**
2179 * Returns the width of the plane in elements, the width does not contain optional padding elements.
2180 * This is the number of elements in which image data is stored (the number of elements between start of a row and start of the padding elements):
2181 * <pre>
2182 * widthElements == width * channels == strideElements() - paddingElements()
2183 * </pre>
2184 * @return The number of elements, with range [0, infinity)
2185 */
2186 inline unsigned int widthElements() const;
2187
2188 /**
2189 * Returns the width of the plane in bytes, the width does not contain optional padding elements.
2190 * This is the number of bytes in which image data is stored (the number of bytes between start of a row and start of the padding elements):
2191 * <pre>
2192 * widthBytes == width * channels * elementTypeSize() == strideBytes - elementTypeSize() * paddingElements()
2193 * </pre>
2194 * @return The number of bytes, with range [0, infinity)
2195 */
2196 inline unsigned int widthBytes() const;
2197
2198 /**
2199 * Returns the number of elements between the start positions of two consecutive rows, in elements.
2200 * This function actually returns `width * channels + paddingElements`.
2201 * @return The number of elements, with range [width * elementsPerPixel, infinity)
2202 */
2203 inline unsigned int strideElements() const;
2204
2205 /**
2206 * Returns the number of bytes between the start positions of two consecutive rows, in bytes.
2207 * @return The number of bytes, with range [width * bytesPerPlanePixel, infinity)
2208 */
2209 inline unsigned int strideBytes() const;
2210
2211 /**
2212 * Returns the number of bytes which is used for each pixel.
2213 * @return The number of bytes, with range [1, infinity), 0 if unknown
2214 */
2215 inline unsigned int bytesPerPixel() const;
2216
2217 /**
2218 * Releases this plane and all resources of this plane.
2219 */
2220 void release();
2221
2222 /**
2223 * Returns whether this plane is compatible with a given element data type.
2224 * @tparam T The data type to be checked
2225 * @return True, if so
2226 */
2227 template <typename T>
2228 inline bool isCompatibleWithDataType() const;
2229
2230 /**
2231 * Returns the number of bytes necessary for the entire plane data including optional padding elements at the end of each row.
2232 * This function actually returns `strideBytes() * height()`.
2233 * @return Plane size in bytes, with range [0, infinity)
2234 */
2235 inline unsigned int size() const;
2236
2237 /**
2238 * Returns whether this plane is based on continuous memory and thus does not have any padding at the end of rows.
2239 * @return True, if so
2240 */
2241 inline bool isContinuous() const;
2242
2243 /**
2244 * Returns whether this plane is the owner of the memory.
2245 * @return True, if the plane is the owner; False, if someone else is the owner
2246 */
2247 inline bool isOwner() const;
2248
2249 /**
2250 * Returns whether this plane holds read-only memory.
2251 * @return True, if the memory of the plane is not writable
2252 */
2253 inline bool isReadOnly() const;
2254
2255 /**
2256 * Returns whether this plane holds valid data.
2257 * @return True, if so; False, if the plane is empty
2258 */
2259 inline bool isValid() const;
2260
2261 /**
2262 * Copies data from another plane into this plane.
2263 * If this plane does not have a compatible memory, or if this plane's memory is not writable, reallocation will be done if `reallocateIfNecessary == true`.
2264 * @param sourcePlane The source plane from which the memory will be copied, an invalid plane to release this plane
2265 * @param advancedCopyMode The copy mode specifying whether the source memory is used or copied
2266 * @param reallocateIfNecessary True, to reallocate new memory if this plane is not compatible with the source plane; False, to prevent a reallocation and to skip to copy the source plane
2267 * @return True, if succeeded
2268 */
2269 bool copy(const Plane& sourcePlane, const AdvancedCopyMode advancedCopyMode = ACM_COPY_KEEP_LAYOUT_DO_NOT_COPY_PADDING_DATA, const bool reallocateIfNecessary = true);
2270
2271 /**
2272 * Move operator.
2273 * @param plane The plane to be moved
2274 * @return The reference to this object
2275 */
2276 Plane& operator=(Plane&& plane) noexcept;
2277
2278 /**
2279 * Copy operator.
2280 * This plane will have the same stride/padding layout. However, the padding memory will not be copied.
2281 * If the source plane is owner of the memory, this plane will be owner of an own copy of the memory.
2282 * If the source plane is not the owner of the memory, this plane will also not be the owner but will use the memory of the source plane as well.
2283 * @param plane The plane to be copied
2284 * @return Reference to this object
2285 */
2286 Plane& operator=(const Plane& plane) noexcept;
2287
2288 /**
2289 * Allocates memory with specific byte alignment.
2290 * @param size The size of the resulting buffer in bytes, with range [0, infinity)
2291 * @param alignment The requested byte alignment, with range [1, infinity)
2292 * @param alignedData the resulting pointer to the aligned memory
2293 * @return The allocated memory with arbitrary alignment
2294 */
2295 static void* alignedMemory(const size_t size, const size_t alignment, void*& alignedData);
2296
2297 /**
2298 * Returns whether the memory layout of a plane is valid (and fits into the memory).
2299 * @param planeWidth The width of the plane, in pixel, with range [0, infinity)
2300 * @param planeHeight The height of the plane, in pixel, with range [0, infinity)
2301 * @param planeChannels The channels of the plane, with range [0, infinity)
2302 * @param bytesPerElement The number of bytes each element has, with range [1, infinity)
2303 * @param paddingElements The optional number of padding elements at the end of each plane row, in elements, with range [0, infinity)
2304 * @return True, if so; False, if the memory usage is out of bounds
2305 */
2306 static constexpr bool validateMemoryLayout(const unsigned int planeWidth, const unsigned int planeHeight, const unsigned int planeChannels, const unsigned int bytesPerElement, const unsigned int paddingElements);
2307
2308 protected:
2309
2310 /**
2311 * Creates a new plane object which is not creating a copy of the given memory. Instead, the memory pointer is just used.
2312 * @param width The width of the plane, in pixel, with range [0, infinity)
2313 * @param height The height of the plane, in pixel, with range [0, infinity)
2314 * @param channels The channels of the plane, with range [0, infinity)
2315 * @param elementTypeSize The size of each element in bytes, which is `sizeof(T)`, with range [1, infinity)
2316 * @param constData The value for `constData` to be set
2317 * @param data The value for `data` to be set
2318 * @param paddingElements The optional number of padding elements at the end of each row, in elements, with range [0, infinity)
2319 */
2320 inline Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const void* constData, void* data, const unsigned int paddingElements) noexcept;
2321
2322 /**
2323 * Creates a new plane object which is not creating a copy of the given memory. Instead, the memory pointer is just used.
2324 * @param width The width of the plane, in pixel, with range [0, infinity)
2325 * @param height The height of the plane, in pixel, with range [0, infinity)
2326 * @param channels The channels of the plane, with range [0, infinity)
2327 * @param elementTypeSize The size of each element in bytes, which is `sizeof(T)`, with range [1, infinity)
2328 * @param dataToUse Memory pointer of the read-only memory which will not be copied, must be valid
2329 * @param paddingElements The number of padding elements at the end of each row, in elements, with range [0, infinity)
2330 */
2331 Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const void* dataToUse, const unsigned int paddingElements) noexcept;
2332
2333 /**
2334 * Creates a new plane object which is not creating a copy of the given memory. Instead, the memory pointer is just used.
2335 * @param width The width of the plane, in pixel, with range [0, infinity)
2336 * @param height The height of the plane, in pixel, with range [0, infinity)
2337 * @param channels The channels of the plane, with range [0, infinity)
2338 * @param elementTypeSize The size of each element in bytes, which is `sizeof(T)`, with range [1, infinity)
2339 * @param dataToUse Memory pointer of the read-only memory which will not be copied, must be valid
2340 * @param paddingElements The number of padding elements at the end of each row, in elements, with range [0, infinity)
2341 */
2342 Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, void* dataToUse, const unsigned int paddingElements) noexcept;
2343
2344 /**
2345 * Creates a new plane object by making a copy of the given memory.
2346 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2347 * @param height The height of the plane in pixels, with range [1, infinity)
2348 * @param channels The number of channels the plane has, with respect to the specified data type, with range [1, infinity)
2349 * @param elementTypeSize The size of each element in bytes, which is `sizeof(T)`, with range [1, infinity)
2350 * @param sourceDataToCopy The source data to be copied, must be valid
2351 * @param targetPaddingElements The number of padding elements at the end of each row this new plane will have, in elements, with range [0, infinity)
2352 * @param sourcePaddingElements The number of padding elements at the end of each row the given source memory has, in elements, with range [0, infinity)
2353 * @param makeCopyOfPaddingData True, to copy the entire padding data of the source plane (both planes must have the same padding layout: `targetPaddingElements == sourcePaddingElements`); False, to skip the padding data when copying the plane
2354 */
2355 Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const void* sourceDataToCopy, const unsigned int targetPaddingElements, const unsigned int sourcePaddingElements, const bool makeCopyOfPaddingData = false) noexcept;
2356
2357 /**
2358 * Creates a new plane object by making a copy of the given memory.
2359 * @param width The width of the plane in pixels, one pixel has size `sizeof(T) * channels`, with range [1, infinity)
2360 * @param height The height of the plane in pixels, with range [1, infinity)
2361 * @param channels The number of channels the plane has, with respect to the specified data type, with range [1, infinity)
2362 * @param elementTypeSize The size of each element in bytes, which is `sizeof(T)`, with range [1, infinity)
2363 * @param sourceDataToCopy The source data to be copied, must be valid
2364 * @param sourcePaddingElements The number of padding elements at the end of each row the given source memory has, in elements, with range [0, infinity)
2365 * @param copyMode The copy mode to be applied
2366 */
2367 Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const void* sourceDataToCopy, const unsigned int sourcePaddingElements, const CopyMode copyMode) noexcept;
2368
2369 /**
2370 * Copies memory into this plane which has compatible memory already.
2371 * @param sourceData The source data from a compatible plane, must be valid
2372 * @param sourceStrideBytes The number of bytes between the start positions of two consecutive rows in the source plane, in bytes, with range [strideBytes(), infinity)
2373 * @param sourcePaddingElements The number of padding elements at the end of each row, in elements, with range [0, infinity)
2374 * @param makeCopyOfPaddingData True, to copy the entire padding data of the source plane (this plane mast have the same padding layout); False, to skip the padding data when copying the plane
2375 */
2376 void copy(const void* sourceData, const unsigned int sourceStrideBytes, const unsigned int sourcePaddingElements, const bool makeCopyOfPaddingData = false);
2377
2378 /**
2379 * Calculates the number of bytes between the start positions of two consecutive rows, in bytes.
2380 * @return The number of bytes, with range [width * bytesPerPlanePixel, infinity).
2381 */
2382 inline unsigned int calculateStrideBytes() const;
2383
2384 /**
2385 * Calculates the number of bytes per pixel.
2386 * @return The number of bytes, with range [1, infinity), 0 if unknown
2387 */
2388 unsigned int calculateBytesPerPixel() const;
2389
2390 protected:
2391
2392 /// The pointer to the memory which this plane has allocated, this pointer is pointing to the memory which needs to be freed when disposing the plane object, nullptr if the plane is not owner of the memory.
2393 void* allocatedData_ = nullptr;
2394
2395 /// The usable capacity of the allocated buffer in bytes, used for buffer reuse when sizes differ but the existing buffer is large enough.
2396 unsigned int allocatedCapacity_ = 0u;
2397
2398 /// The pointer to the read-only memory of the plane (not the pointer to the allocated memory), nullptr, if the plane is not read-only, or invalid.
2399 const void* constData_ = nullptr;
2400
2401 /// The pointer to the writable memory of the plane (not the pointer to the allocated memory), nullptr if the plane is not writable.
2402 void* data_ = nullptr;
2403
2404 /// The width of the plane in pixel, with range [0, infinity).
2405 unsigned int width_ = 0u;
2406
2407 /// The height of the plane in pixel, with range [0, infinity).
2408 unsigned int height_ = 0u;
2409
2410 /// The number of channels the plane has, with range [0, infinity).
2411 unsigned int channels_ = 0u;
2412
2413 /// The size of each element of this plane, in bytes, with range [0, infinity).
2414 unsigned int elementTypeSize_ = 0u;
2415
2416 /// The number of padding elements at the end of each plane row, in elements, with range [0, infinity).
2417 unsigned int paddingElements_ = 0u;
2418
2419 /// The number of bytes between the start positions of two consecutive rows, in bytes, identical to '(width_ * channels_ + paddingElements_) * elementTypeSize_`
2420 unsigned int strideBytes_ = 0u;
2421
2422 /// The number of bytes per pixel, with range [1, infinity), 0 if unknown.
2423 unsigned int bytesPerPixel_ = 0u;
2424 };
2425
2426 /**
2427 * Definition of a vector storing planes.
2428 */
2430
2431 /**
2432 * This class implements a helper class which can be used to initialize a multi-plane frame in the constructor.
2433 * The class is mainly a temporary storage for memory pointers, copy modes, and number of padding elements.
2434 * @tparam T The data type of the frame's element type, can be `void` if unknown
2435 */
2436 template <typename T>
2438 {
2439 friend class Frame;
2440
2441 public:
2442
2443 /**
2444 * Creates a new initializer object for a read-only memory pointer.
2445 * @param constdata The read-only memory pointer to the plane data, must be valid
2446 * @param copyMode The copy mode to be applied when initializing the plane
2447 * @param dataPaddingElements The number of padding elements at the end of each row of the given memory pointer, in elements, with range [0, infinity)
2448 */
2449 inline PlaneInitializer(const T* constdata, const CopyMode copyMode, const unsigned int dataPaddingElements = 0u);
2450
2451 /**
2452 * Creates a new initializer object for a writable memory pointer.
2453 * @param data The writable memory pointer to the plane data, must be valid
2454 * @param copyMode The copy mode to be applied when initializing the plane
2455 * @param dataPaddingElements The number of padding elements at the end of each row of the given memory pointer, in elements, with range [0, infinity)
2456 */
2457 inline PlaneInitializer(T* data, const CopyMode copyMode, const unsigned int dataPaddingElements = 0u);
2458
2459 /**
2460 * Creates a new initializer object for a new plane for which the number of padding elements is known.
2461 * @param planePaddingElements The number of padding elements at the end of each row of the resulting plane, in elements, with range [0, infinity)
2462 */
2463 explicit inline PlaneInitializer(const unsigned int planePaddingElements = 0u);
2464
2465 protected:
2466
2467 /**
2468 * Creates plane initializer objects with padding elements only.
2469 * @param paddingElementsPerPlane The padding elements one value for each plane
2470 * @return The resulting plane initializer objects
2471 */
2472 static std::vector<PlaneInitializer<T>> createPlaneInitializersWithPaddingElements(const Indices32& paddingElementsPerPlane);
2473
2474 protected:
2475
2476 /// The pointer to the read-only source memory, can be nullptr.
2477 const T* constdata_ = nullptr;
2478
2479 /// The pointer to the writable source memory, can be nullptr.
2480 T* data_ = nullptr;
2481
2482 /// The copy mode to be applied, unused if `constdata_ == nullptr` and `data_ == nullptr`.
2483 CopyMode copyMode_ = CopyMode(0u);
2484
2485 /// If a valid memory pointer is provided, the number of padding elements at the end of each source memory row; Otherwise, the number of padding elements at the end row of the new plane, with range [0, infinity)
2486 unsigned int paddingElements_ = 0u;
2487 };
2488
2489 /**
2490 * Definition of a vector holding plane initializer objects.
2491 * @tparam T The data type of the frame's element type.
2492 */
2493 template <typename T>
2494 using PlaneInitializers = std::vector<PlaneInitializer<T>>;
2495
2496 /**
2497 * Definition of a data type storing all channel values of one pixel in an array.
2498 * @tparam T The data type of each pixel channel
2499 * @tparam tChannels The number of channels the pixel has, with range [1, infinity)
2500 */
2501 template <typename T, unsigned int tChannels>
2503
2504 public:
2505
2506 /**
2507 * Creates an empty frame.
2508 */
2509 inline Frame();
2510
2511 /**
2512 * Creates a second version of a given frame.
2513 * If the given source frame is not owner of the frame data, this new frame will also not be owner of the frame data.<br>
2514 * But, if the given source frame is the owner of the frame data, this new frame will also be the owner of new copy of the frame data.<br>
2515 * Thus, the following two lines of code produce the same result:
2516 * @code
2517 * Frame newFrameA(frame);
2518 * Frame newFrameB(frame, ACM_USE_OR_COPY);
2519 * ocean_assert(newFrameB.isOwner() == false || newFrameB.isContinuous());
2520 * @endcode
2521 * This function behaves similar like the normal assign operator.
2522 * Whenever a copy is created, the memory layout of the resulting frame will be continuous.
2523 * @param frame The frame to copy
2524 */
2525 Frame(const Frame& frame);
2526
2527 /**
2528 * Move constructor.
2529 * @param frame The frame to be moved
2530 */
2531 inline Frame(Frame&& frame) noexcept;
2532
2533 /**
2534 * Creates a second version of a given frame.
2535 * Beware: The pixel memory will either be copied or used only, this depends on 'advancedCopyMode'.<br>
2536 * @param frame The frame to copy, can be invalid
2537 * @param advancedCopyMode The copy mode to be applied
2538 */
2539 Frame(const Frame& frame, const AdvancedCopyMode advancedCopyMode) noexcept;
2540
2541 /**
2542 * Creates a frame with specified width, height, pixel format and frame origin and an optional padding.
2543 * The necessary buffer is allocated but not initialized.
2544 * @param frameType Type of the frame, must be valid
2545 * @param paddingElementsPerPlane The padding elements at the end of each individual plane row, in elements of the pixel format, one for each plane, an empty vector to define a frame without padding
2546 * @param timestamp The timestamp of the frame
2547 */
2548 explicit inline Frame(const FrameType& frameType, const Indices32& paddingElementsPerPlane = Indices32(), const Timestamp& timestamp = Timestamp(false));
2549
2550 /**
2551 * Deprecated: Use Frame(const FrameType& frameType, const Indices32& paddingElements, const Timestamp& timestamp) instead.
2552 *
2553 * Creates a new one-plane frame by given width, height, pixel format and frame origin and an optional padding.
2554 * The necessary buffer is allocated but not initialized.
2555 * @param frameType Type of the frame, must be valid
2556 * @param paddingElements Optional number of elements at the end of each row, one pixel has (1 * channels) elements, must be 0 for non-generic pixel formats (e.g., Y_UV12), with range [0, infinity)
2557 * @param timestamp The timestamp of the frame
2558 */
2559 explicit inline Frame(const FrameType& frameType, const unsigned int paddingElements, const Timestamp& timestamp = Timestamp(false));
2560
2561 /**
2562 * Creates a new one-plane frame with known frame type with read-only source memory.
2563 * Beware: If this frame uses the pixel data only, the provided buffer must be valid as long as this new frame exists!
2564 * @param frameType Type of the frame, must be valid
2565 * @param data Frame data to copy or to use, depending on the data copy flag
2566 * @param copyMode The copy mode to be applied
2567 * @param paddingElements Optional number of elements at the end of each row, one pixel has (1 * channels) elements, must be 0 for non-generic pixel formats (e.g., Y_UV12), with range [0, infinity)
2568 * @param timestamp The timestamp of the frame
2569 * @tparam T The data type of each pixel element, e.g., 'uint8_t', 'uint16_t', or 'float', can be `void` to force the usage of the pixel element type as defined in `frameType.pixelFormat()`
2570 */
2571 template <typename T>
2572 inline Frame(const FrameType& frameType, const T* data, const CopyMode copyMode, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false));
2573
2574 /**
2575 * Creates a new one-plane frame with known frame type with writable source memory.
2576 * Beware: If this frame uses the pixel data only, the provided buffer must be valid as long as this new frame exists!
2577 * @param frameType Type of the frame
2578 * @param data Frame data to copy or to use, depending on the data copy flag
2579 * @param copyMode The copy mode to be applied
2580 * @param paddingElements Optional number of elements at the end of each row, one pixel has (1 * channels) elements, must be 0 for non-generic pixel formats (e.g., Y_UV12), with range [0, infinity)
2581 * @param timestamp The timestamp of the frame
2582 * @tparam T The data type of each pixel element, e.g., 'uint8_t', 'uint16_t', or 'float', can be `void` to force the usage of the pixel element type as defined in `frameType.pixelFormat()`
2583 */
2584 template <typename T>
2585 inline Frame(const FrameType& frameType, T* data, const CopyMode copyMode, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false));
2586
2587 /**
2588 * Creates a new multi-plane frame with known frame type and given source memory for each individual plane.
2589 * @param frameType The data type of the new frame, must be valid
2590 * @param planeInitializers The initializers for the individual planes, one for each plane of the pixel format
2591 * @param timestamp The timestamp of the frame
2592 * @tparam T The data type of each pixel element, e.g., 'uint8_t', 'uint16_t', or 'float', can be `void` to force the usage of the pixel element type as defined in `frameType.pixelFormat()`
2593 */
2594 template <typename T>
2595 inline Frame(const FrameType& frameType, const PlaneInitializers<T>& planeInitializers, const Timestamp& timestamp = Timestamp(false));
2596
2597 /**
2598 * Destructs a frame.
2599 */
2601
2602 /**
2603 * Returns the frame type of this frame.
2604 * This return value is actually the cast of the base class of this frame.
2605 * @return Frame type
2606 */
2607 inline const FrameType& frameType() const;
2608
2609 /**
2610 * Returns the individual planes of this frame.
2611 * @return The frame's plane
2612 */
2613 inline const Planes& planes() const;
2614
2615 /**
2616 * Deprecated.
2617 *
2618 * Copies frame data from a source frame.
2619 * When both frame types are not identical, the frame type of this frame is changed to the source frame type.<br>
2620 * This frame will own the new frame data, thus a new frame buffer is allocated if necessary.<br>
2621 * In case a new frame buffer needed to be allocated, the memory layout of the new frame buffer will be continuous.
2622 * @param source The source frame to copy, must be valid and must not be this frame
2623 * @param copyTimestamp True, to copy the frame's timestamp; False, to copy the image data only
2624 * @return True, if the copy operation was successful; otherwise, the frame is not modified and false is returned.
2625 */
2626 bool copy(const Frame& source, const bool copyTimestamp = true);
2627
2628 /**
2629 * Copies the entire image content of a source frame into this frame.
2630 * Both frames must have a compatible pixel format and must have the same pixel origin.<br>
2631 * Only the intersecting image content will be copied, padding data is not copied:
2632 * <pre>
2633 * Source frame
2634 * -------------------------------
2635 * This |(targetLeft, targetTop) |
2636 * target frame | |
2637 * -----------------|--------- |
2638 * |(0, 0) |XXXXXXXXX| |
2639 * | |XXXXXXXXX| |
2640 * | -------------------------------
2641 * | |
2642 * ---------------------------
2643 * </pre>
2644 * The intersecting image content is marked with an 'X'.
2645 * @param targetLeft The horizontal position within this image to which the top-left corner of the source image will be copied, with range (-infinity, infinity)
2646 * @param targetTop The vertical position within this image to which the top-left corner of the source image will be copied, with range (-infinity, infinity)
2647 * @param source The source frame to be copied, must be valid
2648 * @param copyTimestamp True, to copy the frame's timestamp; False, to copy the image data only
2649 * @return False, if both frames are not compatible; True, if the input was valid, even if both images do not intersect
2650 */
2651 bool copy(const int targetLeft, const int targetTop, const Frame& source, const bool copyTimestamp = true);
2652
2653 /**
2654 * Sets a new frame type for this frame.
2655 * The frame data will be reallocated (re-initialized) if the specified frame types, or one of the property flags (forceOwner, forceWritable) do not fit with the current frame.
2656 * @param frameType New frame type to set, can be invalid
2657 * @param forceOwner If specified and the frame is not yet owner, then the frame will allocate its own frame buffer
2658 * @param forceWritable If specified and the frame is read-only, then the frame will allocate its own frame buffer
2659 * @param planePaddingElements The padding elements at the end of each individual plane row, in elements, one for each plane, an empty vector to use the existing padding layout or no padding if reallocation
2660 * @param timestamp The timestamp to be set
2661 * @param reallocated Optional resulting state whether the frame has been reallocated; nullptr otherwise
2662 * @return True, if succeeded
2663 */
2664 bool set(const FrameType& frameType, const bool forceOwner, const bool forceWritable = false, const Indices32& planePaddingElements = Indices32(), const Timestamp& timestamp = Timestamp(false), bool* reallocated = nullptr);
2665
2666 /**
2667 * Updates the memory pointer for a specific plane of the frame to a new read-only memory location.
2668 * This function should only be used if the specified plane does not own its memory to ensure that the frame's ownership behavior remains consistent.
2669 * @param data The new read-only memory pointer to be set, must be valid
2670 * @param planeIndex The index of the frame's plane for which the memory will be updated, with range [0, numberPlanes())
2671 * @return True, if succeeded; False, if e.g., the plane to update owned the memory
2672 * @see isPlaneOwner().
2673 */
2674 template <typename T>
2675 bool updateMemory(const T* data, const unsigned int planeIndex = 0u);
2676
2677 /**
2678 * Updates the memory pointer for a specific plane of the frame to a new read-only or writable memory location.
2679 * This function should only be used if the specified plane currently does not own its memory to ensure that the frame's ownership behavior remains consistent.
2680 * For read-only memory, provide a const memory pointer; For writable memory, provide a non-const pointer.
2681 * @param data The new writable memory pointer to be set, must be valid
2682 * @param planeIndex The index of the frame's plane for which the memory will be updated, with range [0, numberPlanes())
2683 * @return True, if succeeded; False, if e.g., the plane to update owned the memory
2684 * @see isPlaneOwner().
2685 */
2686 template <typename T>
2687 bool updateMemory(T* data, const unsigned int planeIndex = 0u);
2688
2689 /**
2690 * Updates the memory pointers for all or some of the planes of the frame to new writable memory locations.
2691 * This function should be used only when the planes do not own their memory, to maintain consistent ownership behavior across the frame.
2692 * @param planeDatas The new writable memory pointers to be set, the number of pointers provided should be at least one and at most equal to numberPlanes().
2693 * @return True, if succeeded; False, if e.g., the plane to update owned the memory
2694 * @see isPlaneOwner().
2695 */
2696 template <typename T>
2697 bool updateMemory(const std::initializer_list<T*>& planeDatas);
2698
2699 /**
2700 * Makes the memory of this frame continuous.
2701 * If the memory is already continuous, nothing happens.<br>
2702 * If the memory is not continuous, a new continuous memory block will be allocated and the memory is copied into the new memory block (for each plane individually), the frame will be owner of the memory.
2703 */
2705
2706 /**
2707 * Makes this frame the owner of the memory.
2708 * In case this frame does not own the memory, new memory will be allocated.
2709 */
2711
2712 /**
2713 * Returns a sub-frame of this frame.
2714 * The copy mode defines whether the resulting sub-frame owns the memory or uses the memory.
2715 * @param subFrameLeft Left start location of the resulting sub-frame, in pixels, defined within this frame, with range [0, width - 1], must be 0 if the pixel format is packed
2716 * @param subFrameTop Top start location of the resulting sub-frame, in pixels, defined within this frame, with range [0, height - 1]
2717 * @param subFrameWidth Width of the resulting sub-frame in pixels, with range [1, width() - subFrameLeft]
2718 * @param subFrameHeight Height of the resulting sub-frame in pixels, with range [1, height() - subFrameTop]
2719 * @param copyMode The copy mode to be applied, must not be CM_COPY_KEEP_LAYOUT_COPY_PADDING_DATA
2720 * @return The requested sub-frame not owning the image data, an invalid frame if the defined sub-region does not fit into this frame
2721 * @see FrameType::formatIsPacked().
2722 */
2723 Frame subFrame(const unsigned int subFrameLeft, const unsigned int subFrameTop, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const CopyMode copyMode = CM_USE_KEEP_LAYOUT) const;
2724
2725 /**
2726 * Sets the memory of the frame to a specified byte value (the memory of one plane).
2727 * Each byte of the frame's memory will be set to the same value.
2728 *
2729 * The following code snippet shows how this function may be used:
2730 * @code
2731 * Frame rgbFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
2732 * rgbFrame.setValue(0x00u);
2733 * @endcode
2734 * @param value The 8 bit value to be set to each byte of the frame, with range [0, 255]
2735 * @param planeIndex The index of the plane for which the memory will be set, with range [0, numberPlanes())
2736 * @param skipPaddingData True, to do not set the memory value of the padding data; False, to write the memory value of the padding data as well
2737 * @return True, if the image data was writable; False, if the image holds read-only memory
2738 * @see isReadOnly().
2739 */
2740 bool setValue(const uint8_t value, const unsigned int planeIndex = 0u, const bool skipPaddingData = true);
2741
2742 /**
2743 * Sets the memory of the frame to a specified pixel value (the memory of one plane).
2744 * Each pixel will be set to the same values (each channel will be set to an own value).
2745 *
2746 * The following code snippet shows how this function may be used:
2747 * @code
2748 * Frame rgbFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
2749 * const Frame::PixelType<uint8_t, 3u> yellow({0xFFu, 0xFFu, 0x00u});
2750 * rgbFrame.setValue<uint8_t, 3u>(yellow);
2751 *
2752 * Frame tensorFrame(FrameType(1920u, 1080u, FrameType::genericPixelFormat<float, 3u>(), FrameType::ORIGIN_UPPER_LEFT));
2753 * const Frame::PixelType<float, 3u> value({0.0f, 1.0f, 2.0f});
2754 * tensorFrame.setValue<float, 3u>(value);
2755 * @endcode
2756 * @param planePixelValue The pixel value to be set to each pixel
2757 * @param planeIndex The index of the plane for which the memory will be set, with range [0, numberPlanes())
2758 * @tparam T The data type of the given pixel value, must be identical to the data type of the frame
2759 * @tparam tPlaneChannels The number of channels the plane has (not the number of channels the frame has), with range [1, channels()]
2760 * @return True, if the image data was writable; False, if the image holds read-only memory
2761 */
2762 template <typename T, const unsigned int tPlaneChannels>
2763 bool setValue(const PixelType<T, tPlaneChannels>& planePixelValue, const unsigned int planeIndex = 0u);
2764
2765 /**
2766 * Sets the memory of the frame to a specified pixel value (the memory of one plane).
2767 * Each pixel will be set to the same values (each channel will be set to an own value).
2768 *
2769 * The following code snippet shows how this function may be used:
2770 * @code
2771 * Frame rgbFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
2772 * rgbFrame.setValue<uint8_t>(CV::Canvas::yellow(), 3u);
2773 * @endcode
2774 * @param planePixelValue The pixel value to be set to each pixel, one value for each plane channel, must be valid
2775 * @param planePixelValueSize The number of provided pixel values, with range [1, 4], must be `planes().channels()`
2776 * @param planeIndex The index of the plane for which the memory will be set, with range [0, numberPlanes())
2777 * @tparam T The data type of the given pixel value, must be identical to the data type of the frame
2778 * @return True, if the image data was writable; False, if the image holds read-only memory
2779 */
2780 template <typename T>
2781 bool setValue(const T* planePixelValue, const size_t planePixelValueSize, const unsigned int planeIndex = 0u);
2782
2783 /**
2784 * Sets the memory of the frame to a specified pixel value (the memory of one plane).
2785 * Each pixel will be set to the same values (each channel will be set to an own value).
2786 *
2787 * The following code snippet shows how this function may be used:
2788 * @code
2789 * Frame rgbFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
2790 * rgbFrame.setValue<uint8_t>({0xFFu, 0xFFu, 0x00u});
2791 *
2792 * Frame tensorFrame(FrameType(1920u, 1080u, FrameType::genericPixelFormat<float, 3u>(), FrameType::ORIGIN_UPPER_LEFT));
2793 * tensorFrame.setValue<float>({0.0f, 1.0f, 2.0f});
2794 * @endcode
2795 * @param planePixelValues The pixel values to be set to each pixel, one value for each plane channel
2796 * @param planeIndex The index of the plane for which the memory will be set, with range [0, numberPlanes())
2797 * @tparam T The data type of the given pixel value, must be identical to the data type of the frame
2798 * @return True, if the image data was writable; False, if the image holds read-only memory
2799 */
2800 template <typename T>
2801 bool setValue(const std::initializer_list<typename Identity<T>::Type>& planePixelValues, const unsigned int planeIndex = 0u);
2802
2803 /**
2804 * Returns whether the frame (one plane) contains a specified pixel value.
2805 * @param planePixelValue The pixel value to be checked
2806 * @param planeIndex The index of the plane for which the memory will be set, with range [0, numberPlanes())
2807 * @tparam T The data type of the given pixel value, must be identical to the data type of the frame
2808 * @tparam tPlaneChannels The number of channels the plane has (not the number of channels the frame has), with range [1, channels()]
2809 * @return True, if at least one pixel has the specified value
2810 */
2811 template <typename T, const unsigned int tPlaneChannels>
2812 bool containsValue(const PixelType<T, tPlaneChannels>& planePixelValue, const unsigned int planeIndex = 0u) const;
2813
2814 /**
2815 * Returns the number of bytes necessary for a specific plane including optional padding at the end of plane rows.
2816 * @param planeIndex The index of the plane for which the check is done, with range [0, planes().size())
2817 * @return Frame buffer size in bytes, with range [0, infinity)
2818 */
2819 inline unsigned int size(const unsigned int planeIndex = 0u) const;
2820
2821 /**
2822 * Returns the optional number of padding elements at the end of each row for a specific plane.
2823 * @param planeIndex The index of the plane for which the number of padding elements will be returned, with range [0, planes().size())
2824 * @return The frame's number of padding elements, in elements, with range [0, infinity)
2825 */
2826 inline unsigned int paddingElements(const unsigned int planeIndex = 0u) const;
2827
2828 /**
2829 * Returns the optional number of padding bytes at the end of each row for a specific plane.
2830 * @param planeIndex The index of the plane for which the number of padding bytes will be returned, with range [0, planes().size())
2831 * @return The frame's number of padding bytes, in bytes, with range [0, infinity)
2832 */
2833 inline unsigned int paddingBytes(const unsigned int planeIndex = 0u) const;
2834
2835 /**
2836 * Returns the number of elements within one row, including optional padding at the end of a row for a specific plane.
2837 * The number of elements per row is be determined by the plane's values: pixels * elementsPerPixel + paddingElements().
2838 * @param planeIndex The index of the plane for which the number of stride elements will be returned, with range [0, planes().size())
2839 * @return The frame's stride defined in elements, with range [width * elementsPerPixel, infinity)
2840 */
2841 inline unsigned int strideElements(const unsigned int planeIndex = 0u) const;
2842
2843 /**
2844 * Returns the number of bytes within one row, including optional padding at the end of a row for a specific plane.
2845 * @param planeIndex The index of the plane for which the number of stride bytes will be returned, with range [0, planes().size())
2846 * @return The frame's stride defined in bytes, with range [pixels * elementsPerPixel * bitsPerDatatype() / 8, infinity)
2847 */
2848 inline unsigned int strideBytes(const unsigned int planeIndex = 0u) const;
2849
2850 /**
2851 * Returns the width of a plane of this frame.
2852 * @param planeIndex The index of the plane for which the width will be returned, with range [0, planes().size())
2853 * @return The plane's width, in pixel, with range [0, infinity)
2854 */
2855 inline unsigned int planeWidth(const unsigned int planeIndex) const;
2856
2857 /**
2858 * Returns the height of a plane of this frame.
2859 * @param planeIndex The index of the plane for which the height will be returned, with range [0, planes().size())
2860 * @return The plane's height, in pixel, with range [0, infinity)
2861 */
2862 inline unsigned int planeHeight(const unsigned int planeIndex) const;
2863
2864 /**
2865 * Returns the channels of a plane of this frame.
2866 * @param planeIndex The index of the plane for which the channels will be returned, with range [0, planes().size())
2867 * @return The plane's channels, with range [0, infinity)
2868 */
2869 inline unsigned int planeChannels(const unsigned int planeIndex) const;
2870
2871 /**
2872 * Returns the width of a plane of this frame, not in pixel, but in elements, not including padding at the end of each plane row.
2873 * @param planeIndex The index of the plane for which the width will be returned, with range [0, planes().size())
2874 * @return The plane's width, in elements, with is `planeWidth(planeIndex) * planeChannels(planeIndex)`, with range [0, infinity)
2875 */
2876 inline unsigned int planeWidthElements(const unsigned int planeIndex) const;
2877
2878 /**
2879 * Returns the width of a plane of this frame, not in pixel, but in bytes, not including padding at the end of each plane row.
2880 * @param planeIndex The index of the plane for which the width will be returned, with range [0, planes().size())
2881 * @return The plane's width, in bytes, with range [0, infinity)
2882 */
2883 inline unsigned int planeWidthBytes(const unsigned int planeIndex) const;
2884
2885 /**
2886 * Returns the number of bytes of one pixel of a plane for a pixel format.
2887 * Beware: This function will return 0 if the pixel format is a special packed format (e.g., FORMAT_Y10_PACKED) which does not allow to calculate the number of bytes per pixel.
2888 * @param planeIndex The index of the plane for which the bytes per pixel will be returned, with range [0, numberPlanes(imagePixelFormat))
2889 * @return The plane's number of bytes per pixel, will be 0 for special packed pixel formats like FORMAT_Y10_PACKED
2890 */
2891 inline unsigned int planeBytesPerPixel(const unsigned int planeIndex) const;
2892
2893 /**
2894 * Returns whether a specific plane of this frame is based on continuous memory and thus does not have any padding at the end of rows.
2895 * @param planeIndex The index of the plane for which the check is done, with range [0, planes().size())
2896 * @return True, if so
2897 */
2898 inline bool isPlaneContinuous(const unsigned int planeIndex = 0u) const;
2899
2900 /**
2901 * Returns whether a specific plane of this frame is the owner of the memory.
2902 * @param planeIndex The index of the plane for which the check is done, with range [0, planes().size())
2903 * @return True, if so
2904 */
2905 inline bool isPlaneOwner(const unsigned int planeIndex = 0u) const;
2906
2907 /**
2908 * Returns the timestamp of this frame.
2909 * @return Timestamp
2910 */
2911 inline const Timestamp& timestamp() const;
2912
2913 /**
2914 * Returns the relative timestamp of this frame.
2915 * @return Timestamp
2916 */
2917 inline const Timestamp& relativeTimestamp() const;
2918
2919 /**
2920 * Sets the timestamp of this frame.
2921 * @param timestamp Timestamp to be set
2922 * @see setRelativeTimestamp().
2923 */
2924 inline void setTimestamp(const Timestamp& timestamp);
2925
2926 /**
2927 * Sets the relative timestamp of this frame.
2928 * In contrast to the standard timestamp of this frame, the relative timestamp provides the frame time in relation to a reference time.<br>
2929 * @param relative The relative timestamp to be set
2930 * @see setTimestamp().
2931 */
2932 inline void setRelativeTimestamp(const Timestamp& relative);
2933
2934 /**
2935 * Releases this frame and the frame data if this frame is the owner.
2936 */
2937 void release();
2938
2939 /**
2940 * Returns a pointer to the pixel data of a specific plane.
2941 * Ensure that the frame holds writable pixel data before calling this function.
2942 * @param planeIndex The index of the plane for which the data will be returned, with range [0, planes().size())
2943 * @return The plane's writable pixel data
2944 * @tparam T The explicit data type of the value of each pixel channel
2945 * @see isValid(), isReadOnly().
2946 */
2947 template <typename T>
2948 inline T* data(const unsigned int planeIndex = 0u);
2949
2950 /**
2951 * Returns a pointer to the read-only pixel data of a specific plane.
2952 * @param planeIndex The index of the plane for which the data will be returned, with range [0, planes().size())
2953 * @return The plane's read-only pixel data
2954 * @tparam T The explicit data type of the value of each pixel channel
2955 * @see isValid().
2956 */
2957 template <typename T>
2958 inline const T* constdata(const unsigned int planeIndex = 0u) const;
2959
2960 /**
2961 * Returns the pointer to the pixel data of a specific row.
2962 * Ensure that the frame is valid and that the frame holds a valid frame buffer before this function is called.
2963 *
2964 * The index of the row is defined with respect to the origin of the frame's data.<br>
2965 * Therefore, row<T>(0) will return the top row of an image if pixelOrigin() == ORIGIN_UPPER_LEFT,<br>
2966 * and will return the bottom row of an image if pixelOrigin() == ORIGIN_LOWER_LEFT.<br>
2967 * In any case, row<T>(0) is equivalent to data<T>().
2968 *
2969 * @param y The index of the row (the vertical location) to which the resulting pointer will point, with range [0, planeHeight(planeIndex) - 1]
2970 * @param planeIndex The index of the plane for which the pixel will be returned, with range [0, planes().size())
2971 * @return The pointer to the memory at which the row starts
2972 * @tparam T The explicit data type of the value of each pixel channel
2973 * @see data(), pixel(), constrow(), constdata(), constpixel().
2974 */
2975 template <typename T>
2976 inline T* row(const unsigned int y, const unsigned int planeIndex = 0u);
2977
2978 /**
2979 * Returns the pointer to the constant data of a specific row.
2980 * Ensure that the frame is valid and that the frame holds a valid frame buffer before this function is called.
2981 *
2982 * The index of the row is defined with respect to the origin of the frame's data.<br>
2983 * Therefore, constrow<T>(0) will return the top row of an image if pixelOrigin() == ORIGIN_UPPER_LEFT,<br>
2984 * and will return the bottom row of an image if pixelOrigin() == ORIGIN_LOWER_LEFT.<br>
2985 * In any case, constrow<T>(0) is equivalent to constdata<T>().
2986 *
2987 * @param y The index of the row (the vertical location) to which the resulting pointer will point, with range [0, planeHeight(planeIndex) - 1]
2988 * @param planeIndex The index of the plane for which the pixel will be returned, with range [0, planes().size())
2989 * @return The pointer to the memory at which the row starts
2990 * @tparam T The explicit data type of the value of each pixel channel
2991 * @see data(), pixel(), constrow(), constdata(), constpixel().
2992 */
2993 template <typename T>
2994 inline const T* constrow(const unsigned int y, const unsigned int planeIndex = 0u) const;
2995
2996 /**
2997 * Returns the pointer to the data of a specific pixel.
2998 * Ensure that the frame is valid and that the frame holds a valid frame buffer before this function is called.
2999 *
3000 * In general, the usage of this function is recommended for prototyping only.<br>
3001 * As the location of each pixel has to be calculated every time, this function is quite slow.<br>
3002 * Production code should use the constdata(), data(), constrow(), and row() functions instead.
3003 *
3004 * The vertical location (the y coordinate) of the pixel is defined with respect to the origin of the frame's data.<br>
3005 * Therefore, pixel(0, 0) will return the top left pixel of an image if pixelOrigin() == ORIGIN_UPPER_LEFT,<br>
3006 * and will return the bottom left pixel of an image if pixelOrigin() == ORIGIN_LOWER_LEFT.<br>
3007 * In any case, pixel(0, 0) is equivalent to data().
3008 *
3009 * This function most not be called for packed pixel formats.
3010 *
3011 * @param x The horizontal position of the requested pixel, with range [0, planeWidth(planeIndex) - 1]
3012 * @param y The vertical position of the requested pixel, with range [0, planeHeight(planeIndex) - 1]
3013 * @param planeIndex The index of the plane for which the pixel will be returned, with range [0, planes().size())
3014 * @return The pointer to the memory at which the pixel starts
3015 * @tparam T The explicit data type of the value of each pixel channel
3016 * @see data(), row(), constpixel(), constdata(), constrow(). formatIsPacked().
3017 *
3018 *
3019 * The following code snippet shows how this function may be used:
3020 * @code
3021 * // we create a RGB image with 24 bit per pixel (8 bit per channel)
3022 * Frame rgbImage(FrameType(1280u, 720u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
3023 *
3024 * const uint8_t redChannelValue = 0xFF; // 255
3025 * const uint8_t greenChannelValue = 0x80; // 128
3026 * const uint8_t blueChannelValue = 0x00; // 0
3027 *
3028 * // we iterate overall every pixel
3029 * for (unsigned int y = 0u; y < rgbImage.height(); ++y)
3030 * {
3031 * for (unsigned int x = 0u; x < rgbImage.width(); ++x)
3032 * {
3033 * // we store the pointer to the pixel
3034 * uint8_t* rgbPixel = rgbImage.pixel<uint8_t>(x, y);
3035 *
3036 * // we set the color value of each red channel and green channel
3037 * rgbPixel[0] = redChannelValue;
3038 * rgbPixel[1] = greenChannelValue;
3039 *
3040 * // we also can set the value of each channel directly
3041 * rgbImage.pixel<uint8_t>(x, y)[2] = blueChannelValue;
3042 * }
3043 * }
3044 *
3045 * // now we have set the color of every pixel of the image
3046 * @endcode
3047 */
3048 template <typename T>
3049 inline T* pixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex = 0u);
3050
3051 /**
3052 * Returns the pointer to the constant data of a specific pixel.
3053 * Ensure that the frame is valid and that the frame holds a valid frame buffer before this function is called.
3054 *
3055 * In general, the usage of this function is recommended for prototyping only.<br>
3056 * As the location of each pixel has to be calculated every time, this function is quite slow.<br>
3057 * Production code should use the constdata(), data(), constrow(), and row() functions instead.
3058 *
3059 * The vertical location (the y coordinate) of the pixel is defined with respect to the origin of the frame's data.<br>
3060 * Therefore, pixel<T>(0, 0) will return the top left pixel of an image if pixelOrigin() == ORIGIN_UPPER_LEFT,<br>
3061 * and will return the bottom left pixel of an image if pixelOrigin() == ORIGIN_LOWER_LEFT.<br>
3062 * In any case, pixel<T>(0, 0) is equivalent to data<T>().
3063 *
3064 * This function most not be called for packed pixel formats.
3065 *
3066 * @param x The horizontal position of the requested pixel, with range [0, planeWidth(planeIndex) - 1]
3067 * @param y The vertical position of the requested pixel, with range [0, planeHeight(planeIndex) - 1]
3068 * @param planeIndex The index of the plane for which the pixel will be returned, with range [0, planes().size())
3069 * @return The pointer to the memory at which the pixel starts
3070 * @tparam T The explicit data type of the value of each pixel channel
3071 * @see data(), row(), pixel(), constdata(), constrow(), formatIsPacked().
3072 */
3073 template <typename T>
3074 inline const T* constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex = 0u) const;
3075
3076 /**
3077 * Returns whether all planes of this frame have continuous memory and thus do not contain any padding at the end of their rows.
3078 * @return True, if so
3079 */
3080 inline bool isContinuous() const;
3081
3082 /**
3083 * Returns whether the frame is the owner of the internal frame data.
3084 * Otherwise the frame data is stored by e.g., a 3rd party and this frame holds a reference only.<br>
3085 * The frame is not owner of the memory if at least one plane is not owner of the memory.
3086 * @return True, if so
3087 * @see Plane::isOwner().
3088 */
3089 inline bool isOwner() const;
3090
3091 /**
3092 * Returns true, if the frame allows only read access (using constdata()). Otherwise, data() may be used to modify the frame data.
3093 * Beware: Call this method only if the frame is valid.
3094 * The frame is read-only if at least one plane is read-only.
3095 * @return True, if the frame object allows read access only
3096 * @see data(), constdata(), Plane::isReadOnly().
3097 */
3098 inline bool isReadOnly() const;
3099
3100 /**
3101 * Returns whether the frame's pixel format contains an alpha channel.
3102 * @return True, if so
3103 */
3104 inline bool hasAlphaChannel() const;
3105
3106 /**
3107 * Returns whether the frame holds at least one pixel with an non opaque alpha value.
3108 * The pixel format must be composed of one plane only.
3109 * @return True, if so
3110 * @tparam T The type of the frame's data type, either `uint8_t`, or `uint16_t`
3111 */
3112 template <typename T>
3113 bool hasTransparentPixel(const T opaque) const;
3114
3115 /**
3116 * Returns whether this frame is valid.
3117 * This function is mainly calling `FrameType::isValid()`, while in debug builds, additional checks are performed.
3118 * @return True, if so
3119 */
3120 inline bool isValid() const;
3121
3122 /**
3123 * Returns whether two frame objects have any amount of intersecting memory.
3124 * This frame and the given frame must both be valid.<br>
3125 * Use this function to ensure that e.g., a source buffer and target buffer is completely independent.<br>
3126 * This functions also considers memory intersections in the padding area as regular intersection.
3127 * @param frame The second frame of which its memory will be compared to the memory of this frame, must be valid
3128 * @return True, if so
3129 */
3130 bool haveIntersectingMemory(const Frame& frame) const;
3131
3132 /**
3133 * Returns whether this frame object is valid and holds a frame.
3134 * @return True, if so
3135 */
3136 explicit inline operator bool() const;
3137
3138 /**
3139 * Assign operator.
3140 * Releases the current frame (and frees the memory if the frame is the owner) and creates a second version of a given frame.
3141 * If the given source frame is not owner of the frame data, this frame will also not be owner of the frame data.<br>
3142 * But, if the given source frame is the owner of the frame data, this frame will also be the owner of new copy of the frame data.<br>
3143 * If the memory is actually copied, the memory layout of this new frame will be continuous.
3144 * This function behaves similar like the normal copy constructor.
3145 * @param right The right frame to assign
3146 * @return Reference to this frame
3147 */
3148 Frame& operator=(const Frame& right) noexcept;
3149
3150 /**
3151 * Move operator.
3152 * @param right The right frame to moved
3153 * @return Reference to this frame
3154 */
3155 Frame& operator=(Frame&& right) noexcept;
3156
3157 /**
3158 * Determines the number of padding elements at the end of a row of a plane for which the pixel format, the image width and the plane's stride (in bytes) are known.
3159 * @param pixelFormat The pixel format of the image, must be valid
3160 * @param imageWidth The width of the image in pixels, with range [0, infinity)
3161 * @param planeStrideBytes The number of bytes between to start points of successive rows (the stride of the row in bytes) for the specified image plane, with range [planeWidthBytes(planeIndex), infinity)
3162 * @param planePaddingElements The resulting number of padding elements at the end of each row (at the actual end of the row's pixel data) for the specified image plane, in elements (not bytes), with range [0, infinity)
3163 * @param planeIndex The index of the image plane for which the number of padding elements will be calculated, with range [0, numberPlanes() - 1]
3164 * @return True, if succeeded; False, if the given plane configuration is invalid
3165 */
3166 static bool strideBytes2paddingElements(const PixelFormat& pixelFormat, const unsigned int imageWidth, const unsigned int planeStrideBytes, unsigned int& planePaddingElements, const unsigned int planeIndex = 0u);
3167
3168 protected:
3169
3170 /**
3171 * Creates a new multi-plane frame with known frame type and given source memory for each individual plane.
3172 * @param frameType The data type of the new frame, must be valid
3173 * @param planeInitializers The initializers for the individual planes, one for each plane of the pixel format, must be valid
3174 * @param sizePlaneInitializers The number of specified initializers for the individual planes, must be frameType.numberPlanes()
3175 * @param timestamp The timestamp of the frame
3176 */
3177 Frame(const FrameType& frameType, const PlaneInitializer<void>* planeInitializers, size_t sizePlaneInitializers, const Timestamp& timestamp = Timestamp(false));
3178
3179 /**
3180 * Deleted constructor to prevent misuse.
3181 * @param frame The frame to copy
3182 * @param copyData Determines whether this new frame will make an own copy of the given frame data or whether the pixel data is used only
3183 */
3184 Frame(const Frame& frame, const bool copyData) = delete;
3185
3186 /**
3187 * Deleted constructor to prevent misuse.
3188 * @param frameType The frame type which would be used to create the object
3189 * @param copyMode The copy mode which would be used to create the object
3190 */
3191 Frame(const FrameType& frameType, const CopyMode copyMode) = delete;
3192
3193 /**
3194 * Deleted constructor to prevent misuse.
3195 * @param frameType The frame type which would be used to create the object
3196 * @param advancedCopyMode The advanced copy mode which would be used to create the object
3197 */
3198 Frame(const FrameType& frameType, const AdvancedCopyMode advancedCopyMode) = delete;
3199
3200 /**
3201 * Deleted constructor to prevent misuse, use `AdvancedCopyMode` instead.
3202 * @param frame The frame to be copied
3203 * @param copyMode The copy mode which would be used to create the object
3204 */
3205 Frame(const Frame& frame, const CopyMode copyMode) = delete;
3206
3207 /**
3208 * Deleted constructor to prevent misuse.
3209 * @param frameType The frame type which would be used
3210 * @param timestamp The timestamp which would be used to create the object
3211 */
3212 Frame(const FrameType& frameType, const Timestamp& timestamp) = delete;
3213
3214 /**
3215 * Deleted constructor to prevent misuse.
3216 * @param frame The frame to be copied
3217 * @param timestamp The timestamp which would be used to create the object
3218 */
3219 Frame(const Frame& frame, const Timestamp& timestamp) = delete;
3220
3221 /**
3222 * Deleted constructor to prevent misuse, use `Frame(const FrameType& frameType, const T* data, const CopyMode copyMode, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false));` instead.
3223 * @param frameType Type of the frame, must be valid
3224 * @param data Frame data to copy or to use, depending on the data copy flag
3225 * @param copyData Determines whether the frame will make an own copy of the given frame data or whether the pixel data are used only
3226 * @param paddingElements Optional number of elements at the end of each row, one pixel has (1 * channels) elements, must be 0 for non-generic pixel formats (e.g., Y_UV12), with range [0, infinity)
3227 * @param timestamp The timestamp of the frame
3228 * @tparam T The data type of each pixel element, e.g., 'uint8_t', 'uint16_t', or 'float', can be `void` to force the usage of the pixel element type as defined in `frameType.pixelFormat()`
3229 */
3230 template <typename T>
3231 Frame(const FrameType& frameType, const T* data, const bool copyData, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false)) = delete;
3232
3233 /**
3234 * Deleted constructor to prevent misuse, use `Frame(const FrameType& frameType, T* data, const CopyMode copyMode, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false));` instead.
3235 * @param frameType Type of the frame
3236 * @param data Frame data to copy or to use, depending on the data copy flag
3237 * @param copyData Determines whether the frame will make an own copy of the given frame data or whether the pixel data are used only
3238 * @param paddingElements Optional number of elements at the end of each row, one pixel has (1 * channels) elements, must be 0 for non-generic pixel formats (e.g., Y_UV12), with range [0, infinity)
3239 * @param timestamp The timestamp of the frame
3240 * @tparam T The data type of each pixel element, e.g., 'uint8_t', 'uint16_t', or 'float', can be `void` to force the usage of the pixel element type as defined in `frameType.pixelFormat()`
3241 */
3242 template <typename T>
3243 Frame(const FrameType& frameType, T* data, const bool copyData, const unsigned int paddingElements = 0u, const Timestamp& timestamp = Timestamp(false)) = delete;
3244
3245 protected:
3246
3247 /// The individual memory planes of this frame.
3249
3250 /// Timestamp of the frame.
3252
3253 /// Relative timestamp of this frame.
3255};
3256
3257inline FrameType::PixelFormatUnion::PixelFormatUnion(const PixelFormat& pixelFormat) :
3258 pixelFormat_(pixelFormat)
3259{
3260 // nothing to do here
3261}
3262
3263inline FrameType::FrameType(const unsigned int width, const unsigned int height, const PixelFormat pixelFormat, const PixelOrigin pixelOrigin) :
3264 width_(width),
3265 height_(height),
3268{
3269 if (isValid())
3270 {
3272 {
3273 ocean_assert(false && "The configuration of this frame type is invalid - this should never happen!");
3274
3275 width_ = 0u;
3276 height_ = 0u;
3279
3280 ocean_assert(!isValid());
3281 }
3282 }
3283}
3284
3285inline FrameType::FrameType(const FrameType& type, const unsigned int width, const unsigned int height) :
3286 width_(width),
3287 height_(height),
3288 pixelFormat_(type.pixelFormat_),
3289 pixelOrigin_(type.pixelOrigin_)
3290{
3291 if (isValid())
3292 {
3294 {
3295 ocean_assert(false && "The configuration of this frame type is invalid - this should never happen!");
3296
3297 width_ = 0u;
3298 height_ = 0u;
3301
3302 ocean_assert(!isValid());
3303 }
3304 }
3305}
3306
3307inline FrameType::FrameType(const FrameType& type, const PixelFormat pixelFormat) :
3308 width_(type.width_),
3309 height_(type.height_),
3310 pixelFormat_(pixelFormat),
3311 pixelOrigin_(type.pixelOrigin_)
3312{
3313 // nothing to do here
3314}
3315
3316inline FrameType::FrameType(const FrameType& type, const PixelOrigin pixelOrigin) :
3317 width_(type.width_),
3318 height_(type.height_),
3319 pixelFormat_(type.pixelFormat_),
3320 pixelOrigin_(pixelOrigin)
3321{
3322 // nothing to do here
3323}
3324
3325inline FrameType::FrameType(const FrameType& type, const PixelFormat pixelFormat, const PixelOrigin pixelOrigin) :
3326 width_(type.width_),
3327 height_(type.height_),
3328 pixelFormat_(pixelFormat),
3329 pixelOrigin_(pixelOrigin)
3330{
3331 // nothing to do here
3332}
3333
3334inline unsigned int FrameType::width() const
3335{
3336 return width_;
3337}
3338
3339inline unsigned int FrameType::height() const
3340{
3341 return height_;
3342}
3343
3348
3349inline void FrameType::setPixelFormat(const PixelFormat pixelFormat)
3350{
3352}
3353
3358
3359inline unsigned int FrameType::bytesPerDataType() const
3360{
3361 return bytesPerDataType(dataType());
3362}
3363
3364inline unsigned int FrameType::channels() const
3365{
3367 {
3368 return 0u;
3369 }
3370
3372}
3373
3374inline uint32_t FrameType::numberPlanes() const
3375{
3377}
3378
3380{
3381 return pixelOrigin_;
3382}
3383
3384inline unsigned int FrameType::pixels() const
3385{
3387
3388 return width_ * height_;
3389}
3390
3391inline bool FrameType::isPixelFormatCompatible(const PixelFormat pixelFormat) const
3392{
3393 return arePixelFormatsCompatible(this->pixelFormat(), pixelFormat);
3394}
3395
3397{
3398 return isDataLayoutCompatible(this->pixelFormat(), pixelFormat);
3399}
3400
3401inline bool FrameType::isFrameTypeCompatible(const FrameType& frameType, const bool allowDifferentPixelOrigins) const
3402{
3403 return areFrameTypesCompatible(*this, frameType, allowDifferentPixelOrigins);
3404}
3405
3406inline bool FrameType::isFrameTypeDataLayoutCompatible(const FrameType& frameType, const bool allowDifferentPixelOrigins) const
3407{
3408 return areFrameTypesDataLayoutCompatible(*this, frameType, allowDifferentPixelOrigins);
3409}
3410
3411inline bool FrameType::operator!=(const FrameType& right) const
3412{
3413 return !(*this == right);
3414}
3415
3416inline bool FrameType::isValid() const
3417{
3419}
3420
3421inline uint32_t FrameType::numberPlanes(const PixelFormat pixelFormat)
3422{
3423 return uint32_t((pixelFormat >> pixelFormatBitOffsetPlanes) & 0xFFull);
3424}
3425
3426inline uint32_t FrameType::formatGenericNumberChannels(const PixelFormat pixelFormat)
3427{
3428 return uint32_t((pixelFormat >> pixelFormatBitOffsetChannels) & 0xFFull);
3429}
3430
3431template <>
3432constexpr FrameType::DataType FrameType::dataType<char>()
3433{
3434 static_assert(sizeof(char) == 1, "Invalid data type!");
3435
3436 return (std::is_signed<char>::value) ? DT_SIGNED_INTEGER_8 : DT_UNSIGNED_INTEGER_8;
3437}
3438
3439template <>
3440constexpr FrameType::DataType FrameType::dataType<signed char>()
3441{
3442 static_assert(sizeof(signed char) == 1, "Invalid data type!");
3443 return DT_SIGNED_INTEGER_8;
3444}
3445
3446template <>
3447constexpr FrameType::DataType FrameType::dataType<unsigned char>()
3448{
3449 static_assert(sizeof(unsigned char) == 1, "Invalid data type!");
3450 return DT_UNSIGNED_INTEGER_8;
3451}
3452
3453template <>
3454constexpr FrameType::DataType FrameType::dataType<unsigned short>()
3455{
3456 static_assert(sizeof(unsigned short) == 2, "Invalid data type!");
3458}
3459
3460template <>
3461constexpr FrameType::DataType FrameType::dataType<short>()
3462{
3463 static_assert(sizeof(short) == 2, "Invalid data type!");
3464 return DT_SIGNED_INTEGER_16;
3465}
3466
3467template <>
3468constexpr FrameType::DataType FrameType::dataType<unsigned int>()
3469{
3470 static_assert(sizeof(unsigned int) == 4, "Invalid data type!");
3472}
3473
3474template <>
3475constexpr FrameType::DataType FrameType::dataType<int>()
3476{
3477 static_assert(sizeof(int) == 4, "Invalid data type!");
3478 return DT_SIGNED_INTEGER_32;
3479}
3480
3481template <>
3482constexpr FrameType::DataType FrameType::dataType<unsigned long>()
3483{
3484 static_assert(sizeof(unsigned long) == 4 || sizeof(unsigned long) == 8, "Invalid data type!");
3485
3486 return (sizeof(unsigned long) == 4) ? DT_UNSIGNED_INTEGER_32 : DT_UNSIGNED_INTEGER_64;
3487}
3488
3489template <>
3490constexpr FrameType::DataType FrameType::dataType<long>()
3491{
3492 static_assert(sizeof(unsigned long) == 4 || sizeof(unsigned long) == 8, "Invalid data type!");
3493
3494 return (sizeof(long) == 4) ? DT_SIGNED_INTEGER_32 : DT_SIGNED_INTEGER_64;
3495}
3496
3497template <>
3498constexpr FrameType::DataType FrameType::dataType<unsigned long long>()
3499{
3500 static_assert(sizeof(unsigned long long) == 8, "Invalid data type!");
3502}
3503
3504template <>
3505constexpr FrameType::DataType FrameType::dataType<long long>()
3506{
3507 static_assert(sizeof(long long) == 8, "Invalid data type!");
3508 return DT_SIGNED_INTEGER_64;
3509}
3510
3511template <>
3512constexpr FrameType::DataType FrameType::dataType<float>()
3513{
3514 static_assert(sizeof(float) == 4, "Invalid data type!");
3515 return DT_SIGNED_FLOAT_32;
3516}
3517
3518template <>
3519constexpr FrameType::DataType FrameType::dataType<double>()
3520{
3521 static_assert(sizeof(double) == 8, "Invalid data type!");
3522 return DT_SIGNED_FLOAT_64;
3523}
3524
3525template <typename T>
3527{
3528 return DT_UNDEFINED;
3529}
3530
3532{
3533 ocean_assert(((pixelFormat >> pixelFormatBitOffsetDatatype) & 0xFFull) <= DT_SIGNED_FLOAT_64);
3534
3535 return DataType((pixelFormat >> pixelFormatBitOffsetDatatype) & 0xFFull);
3536}
3537
3542
3543constexpr inline FrameType::PixelFormat FrameType::genericPixelFormat(const DataType dataType, const uint32_t channels, const uint32_t planes, const uint32_t widthMultiple, const uint32_t heightMultiple)
3544{
3545 ocean_assert(uint8_t(dataType) > uint8_t(DT_UNDEFINED) && uint8_t(dataType) < DT_END);
3546 ocean_assert(channels >= 1u && channels <= 31u);
3547 ocean_assert(planes >= 1u && planes <= 255u);
3548 ocean_assert(widthMultiple >= 1u && widthMultiple <= 255u);
3549 ocean_assert(heightMultiple >= 1u && heightMultiple <= 255u);
3550
3552}
3553
3554template <FrameType::DataType tDataType, uint32_t tChannels, uint32_t tPlanes, uint32_t tWidthMultiple, uint32_t tHeightMultiple>
3556{
3557 static_assert(uint8_t(tDataType) > uint8_t(DT_UNDEFINED) && uint8_t(tDataType) < DT_END, "Invalid data type!");
3558 static_assert(tChannels >= 1u && tChannels < 31u, "Invalid channel number!");
3559 static_assert(tPlanes >= 1u && tPlanes <= 255u, "Invalid plane number!");
3560 static_assert(tWidthMultiple >= 1u && tWidthMultiple <= 255u, "Invalid width-multiple!");
3561 static_assert(tHeightMultiple >= 1u && tHeightMultiple <= 255u, "Invalid height-multiple!");
3562
3563 return genericPixelFormat(tDataType, tChannels, tPlanes, tWidthMultiple, tHeightMultiple);
3564}
3565
3566template <FrameType::DataType tDataType>
3567constexpr FrameType::PixelFormat FrameType::genericPixelFormat(const uint32_t channels, const uint32_t planes, const uint32_t widthMultiple, const uint32_t heightMultiple)
3568{
3569 static_assert(uint8_t(tDataType) > uint8_t(DT_UNDEFINED) && uint8_t(tDataType) < DT_END, "Invalid data type!");
3570
3571 return genericPixelFormat(tDataType, channels, planes, widthMultiple, heightMultiple);
3572}
3573
3574template <typename TDataType, uint32_t tChannels, uint32_t tPlanes, uint32_t tWidthMultiple, uint32_t tHeightMultiple>
3576{
3577 static_assert(tChannels >= 1u && tChannels < 31u, "Invalid channel number!");
3578 static_assert(tPlanes >= 1u && tPlanes <= 255u, "Invalid plane number!");
3579 static_assert(tWidthMultiple >= 1u && tWidthMultiple <= 255u, "Invalid width-multiple!");
3580 static_assert(tHeightMultiple >= 1u && tHeightMultiple <= 255u, "Invalid height-multiple!");
3581
3582 constexpr DataType pixelFormatDataType = dataType<TDataType>();
3583 static_assert(uint8_t(pixelFormatDataType) > uint8_t(DT_UNDEFINED) && uint8_t(pixelFormatDataType) < DT_END, "Invalid data type!");
3584
3585 return genericPixelFormat(pixelFormatDataType, tChannels, tPlanes, tWidthMultiple, tHeightMultiple);
3586}
3587
3588template <typename TDataType>
3589constexpr FrameType::PixelFormat FrameType::genericPixelFormat(const uint32_t channels, const uint32_t planes, const uint32_t widthMultiple, const uint32_t heightMultiple)
3590{
3591 constexpr DataType pixelFormatDataType = dataType<TDataType>();
3592 static_assert(uint8_t(pixelFormatDataType) > uint8_t(DT_UNDEFINED) && uint8_t(pixelFormatDataType) < DT_END, "Invalid data type!");
3593
3594 ocean_assert(channels >= 1u && channels <= 31u);
3595 ocean_assert(planes >= 1u && planes <= 255u);
3596 ocean_assert(widthMultiple >= 1u && widthMultiple <= 255u);
3597 ocean_assert(heightMultiple >= 1u && heightMultiple <= 255u);
3598
3599 return genericPixelFormat(pixelFormatDataType, channels, planes, widthMultiple, heightMultiple);
3600}
3601
3603{
3604 static_assert(std::is_same<std::underlying_type<PixelFormat>::type, uint64_t>::value, "Invalid pixel format data type!");
3605
3606 return PixelFormat(pixelFormat & 0xFFFFFFFFFFFF0000ull); // Cf. documentation of enum PixelFormat
3607}
3608
3609inline bool FrameType::formatIsGeneric(const PixelFormat pixelFormat, const DataType pixelFormatDataType, const uint32_t channels, const uint32_t planes, const uint32_t widthMultiple, const uint32_t heightMultiple)
3610{
3612}
3613
3618
3619inline bool FrameType::formatIsPureGeneric(const PixelFormat pixelFormat)
3620{
3621 static_assert(std::is_same<std::underlying_type<PixelFormat>::type, uint64_t>::value, "Invalid pixel format data type!");
3622
3623 return (pixelFormat & 0x000000000000FFFFull) == 0u && formatIsGeneric(pixelFormat);
3624}
3625
3626inline uint32_t FrameType::widthMultiple(const PixelFormat pixelFormat)
3627{
3628 return uint32_t((pixelFormat >> pixelFormatBitOffsetWidthMultiple) & 0xFFull);
3629}
3630
3631inline uint32_t FrameType::heightMultiple(const PixelFormat pixelFormat)
3632{
3633 return uint32_t((pixelFormat >> pixelFormatBitOffsetHeightMultiple) & 0xFFull);
3634}
3635
3636inline unsigned int FrameType::planeBytesPerPixel(const PixelFormat& imagePixelFormat, const unsigned int planeIndex)
3637{
3638 unsigned int planeWidthDummy;
3639 unsigned int planeHeightDummy;
3640
3641 unsigned int planeChannels;
3642
3643 unsigned int planeWidthElementsMultiple;
3644 unsigned int planeHeightElementsMultiple;
3645
3646 if (planeLayout(imagePixelFormat, widthMultiple(imagePixelFormat), heightMultiple(imagePixelFormat), planeIndex, planeWidthDummy, planeHeightDummy, planeChannels, &planeWidthElementsMultiple, &planeHeightElementsMultiple))
3647 {
3648 ocean_assert(planeChannels >= 1u && planeWidthElementsMultiple >= 1u && planeHeightElementsMultiple >= 1u);
3649
3650 if (planeWidthElementsMultiple != 1u || planeHeightElementsMultiple != 1u)
3651 {
3652 // we have a packed pixel format for which we cannot calculate the number of bytes per pixel
3653 return 0u;
3654 }
3655
3656 return planeChannels * bytesPerDataType(dataType(imagePixelFormat));
3657 }
3658 else
3659 {
3660 ocean_assert(false && "Invalid input!");
3661 return 0u;
3662 }
3663}
3664
3665inline bool FrameType::planeLayout(const FrameType& frameType, const unsigned int planeIndex, unsigned int& planeWidth, unsigned int& planeHeight, unsigned int& planeChannels, unsigned int* planeWidthElementsMultiple, unsigned int* planeHeightElementsMultiple)
3666{
3667 ocean_assert(frameType.isValid());
3668
3669 return planeLayout(frameType.pixelFormat(), frameType.width(), frameType.height(), planeIndex, planeWidth, planeHeight, planeChannels, planeWidthElementsMultiple, planeHeightElementsMultiple);
3670}
3671
3672template <typename T>
3673inline bool FrameType::dataIsAligned(const void* data)
3674{
3675 ocean_assert(data != nullptr);
3676 return size_t(data) % sizeof(T) == size_t(0);
3677}
3678
3679constexpr bool FrameType::isSumInsideValueRange(const unsigned int valueA, const unsigned int valueB)
3680{
3681 return valueA <= (unsigned int)(-1) - valueB;
3682}
3683
3684constexpr bool FrameType::isProductInsideValueRange(const unsigned int valueA, const unsigned int valueB)
3685{
3686 return valueB == 0u || valueA <= (unsigned int)(-1) / valueB;
3687}
3688
3689inline Frame::Plane::Plane(Plane&& plane) noexcept
3690{
3691 *this = std::move(plane);
3692}
3693
3694template <typename T>
3695inline Frame::Plane::Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const T* dataToUse, const unsigned int paddingElements) noexcept :
3696 Plane(width, height, channels, sizeof(T), (const void*)(dataToUse), paddingElements)
3697{
3698 // nothing to do here
3699}
3700
3701template <typename T>
3702inline Frame::Plane::Plane(const unsigned int width, const unsigned int height, const unsigned int channels, T* dataToUse, const unsigned int paddingElements) noexcept :
3703 Plane(width, height, channels, sizeof(T), (void*)(dataToUse), paddingElements)
3704{
3705 // nothing to do here
3706}
3707
3708template <typename T>
3709inline Frame::Plane::Plane(const T* sourceDataToCopy, const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int targetPaddingElements, const unsigned int sourcePaddingElements, const bool makeCopyOfPaddingData) noexcept :
3710 Plane(width, height, channels, sizeof(T), (const void*)(sourceDataToCopy), targetPaddingElements, sourcePaddingElements, makeCopyOfPaddingData)
3711{
3712 // nothing to do here
3713}
3714
3715template <typename T>
3716inline Frame::Plane::Plane(const T* sourceDataToCopy, const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int sourcePaddingElements, const CopyMode copyMode) noexcept :
3717 Plane(width, height, channels, sizeof(T), (const void*)(sourceDataToCopy), sourcePaddingElements, copyMode)
3718{
3719 // nothing to do here
3720}
3721
3722inline Frame::Plane::Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const void* constData, void* data, const unsigned int paddingElements) noexcept :
3723 allocatedData_(nullptr),
3724 constData_(constData),
3725 data_(data),
3726 width_(width),
3727 height_(height),
3728 channels_(channels),
3729 elementTypeSize_(elementTypeSize),
3730 paddingElements_(paddingElements)
3731{
3732 strideBytes_ = calculateStrideBytes();
3733 bytesPerPixel_ = calculateBytesPerPixel();
3734}
3735
3737{
3738 release();
3739}
3740
3741inline unsigned int Frame::Plane::width() const
3742{
3743 return width_;
3744}
3745
3746inline unsigned int Frame::Plane::height() const
3747{
3748 return height_;
3749}
3750
3751inline unsigned int Frame::Plane::channels() const
3752{
3753 return channels_;
3754}
3755
3756template <typename T>
3757inline const T* Frame::Plane::constdata() const
3758{
3759 return reinterpret_cast<const T*>(constData_);
3760}
3761
3762template <typename T>
3764{
3765 return reinterpret_cast<T*>(data_);
3766}
3767
3768inline unsigned int Frame::Plane::paddingElements() const
3769{
3770 return paddingElements_;
3771}
3772
3773inline unsigned int Frame::Plane::paddingBytes() const
3774{
3775 return paddingElements_ * elementTypeSize_;
3776}
3777
3778inline unsigned int Frame::Plane::elementTypeSize() const
3779{
3780 return elementTypeSize_;
3781}
3782
3783inline unsigned int Frame::Plane::widthElements() const
3784{
3785 ocean_assert(isProductInsideValueRange(width_, channels_));
3786
3787 return width_ * channels_;
3788}
3789
3790inline unsigned int Frame::Plane::widthBytes() const
3791{
3792 ocean_assert(isProductInsideValueRange(widthElements(), elementTypeSize_));
3793
3794 return widthElements() * elementTypeSize_;
3795}
3796
3797inline unsigned int Frame::Plane::strideElements() const
3798{
3799 ocean_assert(isSumInsideValueRange(widthElements(), paddingElements_));
3800
3801 return widthElements() + paddingElements_;
3802}
3803
3804inline unsigned int Frame::Plane::strideBytes() const
3805{
3806 ocean_assert(width_ == 0u || strideBytes_ != 0u);
3807 ocean_assert(strideBytes_ == calculateStrideBytes()); // ensuring that stride bytes is actually correct
3808
3809 return strideBytes_;
3810}
3811
3812inline unsigned int Frame::Plane::bytesPerPixel() const
3813{
3814 ocean_assert(bytesPerPixel_ == calculateBytesPerPixel());
3815
3816 return bytesPerPixel_;
3817}
3818
3819template <typename T>
3821{
3822 return elementTypeSize_ == sizeof(T);
3823}
3824
3825inline unsigned int Frame::Plane::size() const
3826{
3828
3829 return strideBytes() * height_;
3830}
3831
3833{
3834 return paddingElements_ == 0u;
3835}
3836
3837inline bool Frame::Plane::isOwner() const
3838{
3839 return allocatedData_ != nullptr;
3840}
3841
3842inline bool Frame::Plane::isReadOnly() const
3843{
3844 return data_ == nullptr;
3845}
3846
3847inline bool Frame::Plane::isValid() const
3848{
3849 return width_ != 0u && height_ != 0u && channels_ != 0u;
3850}
3851
3852constexpr bool Frame::Plane::validateMemoryLayout(const unsigned int planeWidth, const unsigned int planeHeight, const unsigned int planeChannels, const unsigned int bytesPerElement, const unsigned int paddingElements)
3853{
3855 {
3856 return false;
3857 }
3858
3859 const unsigned int planeWidthElements = planeWidth * planeChannels;
3860
3862 {
3863 return false;
3864 }
3865
3866 const unsigned int planeStrideElements = planeWidthElements + paddingElements;
3867
3868 if (!isProductInsideValueRange(planeStrideElements, bytesPerElement))
3869 {
3870 return false;
3871 }
3872
3873 const unsigned int planeStrideBytes = planeStrideElements * bytesPerElement;
3874
3875 if (!isProductInsideValueRange(planeStrideBytes, planeHeight))
3876 {
3877 return false;
3878 }
3879
3880 return true;
3881}
3882
3883inline unsigned int Frame::Plane::calculateStrideBytes() const
3884{
3885 ocean_assert(isProductInsideValueRange(strideElements(), elementTypeSize_));
3886
3887 return strideElements() * elementTypeSize_;
3888}
3889
3890template <typename T>
3891inline Frame::PlaneInitializer<T>::PlaneInitializer(const T* constdata, const CopyMode copyMode, const unsigned int dataPaddingElements) :
3892 constdata_(constdata),
3893 data_(nullptr),
3894 copyMode_(copyMode),
3895 paddingElements_(dataPaddingElements)
3896{
3897 // nothing to do here
3898}
3899
3900template <typename T>
3901inline Frame::PlaneInitializer<T>::PlaneInitializer(T* data, const CopyMode copyMode, const unsigned int dataPaddingElements) :
3902 constdata_(nullptr),
3903 data_(data),
3904 copyMode_(copyMode),
3905 paddingElements_(dataPaddingElements)
3906{
3907 // nothing to do here
3908}
3909
3910template <typename T>
3911inline Frame::PlaneInitializer<T>::PlaneInitializer(const unsigned int planePaddingElements) :
3912 constdata_(nullptr),
3913 data_(nullptr),
3914 copyMode_(CM_USE_KEEP_LAYOUT),
3915 paddingElements_(planePaddingElements)
3916{
3917 // nothing to do here
3918}
3919
3920template <typename T>
3921std::vector<Frame::PlaneInitializer<T>> Frame::PlaneInitializer<T>::createPlaneInitializersWithPaddingElements(const Indices32& paddingElementsPerPlane)
3922{
3923 PlaneInitializers<T> planeInitializers;
3924 planeInitializers.reserve(paddingElementsPerPlane.size());
3925
3926 for (const Index32& paddingElements : paddingElementsPerPlane)
3927 {
3928 planeInitializers.emplace_back(paddingElements);
3929 }
3930
3931 return planeInitializers;
3932}
3933
3935 FrameType(),
3936 planes_(1, Plane())
3937{
3938 // nothing to do here
3939}
3940
3941inline Frame::Frame(Frame&& frame) noexcept :
3942 FrameType()
3943{
3944 *this = std::move(frame);
3945
3946 ocean_assert(planes_.size() >= 1);
3947 ocean_assert(frame.planes_.size() == 1);
3948}
3949
3950inline Frame::Frame(const FrameType& frameType, const Indices32& planePaddingElements, const Timestamp& timestamp) :
3951 Frame(frameType, PlaneInitializer<void>::createPlaneInitializersWithPaddingElements(planePaddingElements), timestamp)
3952{
3953 ocean_assert(frameType.numberPlanes() == planePaddingElements.size() || planePaddingElements.empty());
3954 ocean_assert(planes_.size() == frameType.numberPlanes());
3955}
3956
3957inline Frame::Frame(const FrameType& frameType, const unsigned int paddingElements, const Timestamp& timestamp) :
3958 Frame(frameType, PlaneInitializers<void>(1, PlaneInitializer<void>(paddingElements)), timestamp)
3959{
3960 ocean_assert(frameType.numberPlanes() == 1u);
3961 ocean_assert(planes_.size() == 1);
3962}
3963
3964template <>
3965inline Frame::Frame(const FrameType& frameType, const void* data, const CopyMode copyMode, const unsigned int paddingElements, const Timestamp& timestamp) :
3966 Frame(frameType, PlaneInitializers<void>(1, PlaneInitializer<void>(data, copyMode, paddingElements)), timestamp)
3967{
3968 // this constructor is for 1-plane frames only
3969
3970 ocean_assert(frameType.numberPlanes() == 1u);
3971 ocean_assert(planes_.size() == 1);
3972}
3973
3974template <typename T>
3975inline Frame::Frame(const FrameType& frameType, const T* data, const CopyMode copyMode, const unsigned int paddingElements, const Timestamp& timestamp) :
3976 Frame(frameType, (const void*)(data), copyMode, paddingElements, timestamp)
3977{
3978#ifdef OCEAN_DEBUG
3979 const FrameType::DataType debugTemplateDataType = FrameType::dataType<T>();
3980 const FrameType::DataType debugFrameTypeDataType = frameType.dataType();
3981
3982 // we ensure that the template data type matches with the data type of the pixel format (as padding is defined in elements)
3983 ocean_assert(debugTemplateDataType == FrameType::DT_UNDEFINED || debugTemplateDataType == debugFrameTypeDataType);
3984#endif
3985
3986 ocean_assert(planes_.size() == 1);
3987}
3988
3989template <>
3990inline Frame::Frame(const FrameType& frameType, void* data, const CopyMode copyMode, const unsigned int paddingElements, const Timestamp& timestamp) :
3991 Frame(frameType, PlaneInitializers<void>(1, PlaneInitializer<void>(data, copyMode, paddingElements)), timestamp)
3992{
3993 // this constructor is for 1-plane frames only
3994
3995 ocean_assert(frameType.numberPlanes() == 1u);
3996 ocean_assert(planes_.size() == 1);
3997}
3998
3999template <typename T>
4000inline Frame::Frame(const FrameType& frameType, T* data, const CopyMode copyMode, const unsigned int paddingElements, const Timestamp& timestamp) :
4001 Frame(frameType, (void*)(data), copyMode, paddingElements, timestamp)
4002{
4003#ifdef OCEAN_DEBUG
4004 const FrameType::DataType debugTemplateDataType = FrameType::dataType<T>();
4005 const FrameType::DataType debugFrameTypeDataType = frameType.dataType();
4006
4007 // we ensure that the template data type matches with the data type of the pixel format (as padding is defined in elements)
4008 ocean_assert(debugTemplateDataType == FrameType::DT_UNDEFINED || debugTemplateDataType == debugFrameTypeDataType);
4009#endif
4010
4011 ocean_assert(planes_.size() == 1);
4012}
4013
4014template <typename T>
4015inline Frame::Frame(const FrameType& frameType, const PlaneInitializers<T>& planeInitializers, const Timestamp& timestamp) :
4016 Frame(frameType, (const PlaneInitializer<void>*)planeInitializers.data(), planeInitializers.size(), timestamp)
4017{
4018#ifdef OCEAN_DEBUG
4019 const FrameType::DataType debugTemplateDataType = FrameType::dataType<T>();
4020 const FrameType::DataType debugFrameTypeDataType = frameType.dataType();
4021
4022 // we ensure that the template data type matches with the data type of the pixel format (as padding is defined in elements)
4023 ocean_assert(debugTemplateDataType == FrameType::DT_UNDEFINED || debugTemplateDataType == debugFrameTypeDataType);
4024#endif
4025
4026 ocean_assert(planes_.size() == frameType.numberPlanes());
4027}
4028
4029inline const FrameType& Frame::frameType() const
4030{
4031 return (const FrameType&)(*this);
4032}
4033
4034inline const Frame::Planes& Frame::planes() const
4035{
4036 return planes_;
4037}
4038
4039template <typename T>
4040bool Frame::updateMemory(const T* data, const unsigned int planeIndex)
4041{
4042 ocean_assert(data != nullptr);
4043 if (data != nullptr)
4044 {
4045 ocean_assert(planeIndex < planes_.size());
4046 if (planeIndex < planes_.size())
4047 {
4048 Plane& plane = planes_[planeIndex];
4049
4050 if constexpr (!std::is_void_v<T>)
4051 {
4052 ocean_assert(sizeof(T) == plane.elementTypeSize());
4053 }
4054
4055 ocean_assert(plane.allocatedData_ == nullptr);
4056 if (plane.allocatedData_ == nullptr)
4057 {
4058 plane.constData_ = data;
4059 plane.data_ = nullptr;
4060
4061 return true;
4062 }
4063 }
4064 }
4065
4066 return false;
4067}
4068
4069template <typename T>
4070bool Frame::updateMemory(T* data, const unsigned int planeIndex)
4071{
4072 ocean_assert(data != nullptr);
4073 if (data != nullptr)
4074 {
4075 ocean_assert(planeIndex < planes_.size());
4076 if (planeIndex < planes_.size())
4077 {
4078 Plane& plane = planes_[planeIndex];
4079
4080 if constexpr (!std::is_void_v<T>)
4081 {
4082 ocean_assert(sizeof(T) == plane.elementTypeSize());
4083 }
4084
4085 ocean_assert(plane.allocatedData_ == nullptr);
4086 if (plane.allocatedData_ == nullptr)
4087 {
4088 plane.data_ = data;
4089 plane.constData_ = (const T*)(data);
4090
4091 return true;
4092 }
4093 }
4094 }
4095
4096 return false;
4097}
4098
4099template <typename T>
4100bool Frame::updateMemory(const std::initializer_list<T*>& planeDatas)
4101{
4102 ocean_assert(planeDatas.size() != 0);
4103 ocean_assert(planeDatas.size() <= planes_.size());
4104
4105 if (planeDatas.size() == 0 || planeDatas.size() > planes_.size())
4106 {
4107 return false;
4108 }
4109
4110 for (unsigned int planeIndex = 0u; planeIndex < planeDatas.size(); ++planeIndex)
4111 {
4112 if (!updateMemory(planeDatas.begin()[planeIndex], planeIndex))
4113 {
4114 return false;
4115 }
4116 }
4117
4118 return true;
4119}
4120
4121template <typename T, const unsigned int tPlaneChannels>
4122bool Frame::setValue(const PixelType<T, tPlaneChannels>& planePixelValue, const unsigned int planeIndex)
4123{
4124 static_assert(!std::is_void_v<T>, "Value access/assignment cannot be performed with void types.");
4125
4126 ocean_assert(planes_.size() >= 1);
4127 ocean_assert(planeIndex < planes_.size());
4128
4129 Plane& plane = planes_[planeIndex];
4130
4131 ocean_assert(plane.isValid());
4132
4133 if (sizeof(T) != plane.elementTypeSize())
4134 {
4135 ocean_assert(false && "The specified data type must fit to the frame's data type!");
4136 return false;
4137 }
4138
4139 if (plane.channels() != tPlaneChannels)
4140 {
4141 ocean_assert(false && "The specified number of channels does not fit with the plane's actual channels!");
4142 return false;
4143 }
4144
4145 if (plane.isReadOnly())
4146 {
4147 return false;
4148 }
4149
4150 if (plane.paddingElements_ == 0u)
4151 {
4153
4154 for (unsigned int n = 0u; n < plane.width() * plane.height(); ++n)
4155 {
4156 data[n] = planePixelValue;
4157 }
4158 }
4159 else
4160 {
4161 const unsigned int planeStrideBytes = plane.strideBytes();
4162
4163 for (unsigned int y = 0u; y < plane.height(); ++y)
4164 {
4165 PixelType<T, tPlaneChannels>* const data = (PixelType<T, tPlaneChannels>*)(plane.data<uint8_t>() + y * planeStrideBytes);
4166
4167 for (unsigned int x = 0u; x < plane.width(); ++x)
4168 {
4169 data[x] = planePixelValue;
4170 }
4171 }
4172 }
4173
4174 return true;
4175}
4176
4177template <typename T, const unsigned int tPlaneChannels>
4178bool Frame::containsValue(const PixelType<T, tPlaneChannels>& planePixelValue, const unsigned int planeIndex) const
4179{
4180 static_assert(!std::is_void_v<T>, "Value access/comparison cannot be performed with void types.");
4181
4182 ocean_assert(planes_.size() >= 1);
4183 ocean_assert(planeIndex < planes_.size());
4184
4185 const Plane& plane = planes_[planeIndex];
4186
4187 ocean_assert(plane.isValid());
4188
4189 if (sizeof(T) != plane.elementTypeSize())
4190 {
4191 ocean_assert(false && "The specified data type must fit to the frame's data type!");
4192 return false;
4193 }
4194
4195 if (plane.channels() != tPlaneChannels)
4196 {
4197 ocean_assert(false && "The specified number of channels does not fit with the plane's actual channels!");
4198 return false;
4199 }
4200
4201 const unsigned int planeStrideBytes = plane.strideBytes();
4202
4203 for (unsigned int y = 0u; y < plane.height(); ++y)
4204 {
4205 PixelType<T, tPlaneChannels>* const data = (PixelType<T, tPlaneChannels>*)(plane.constdata<uint8_t>() + y * planeStrideBytes);
4206
4207 for (unsigned int x = 0u; x < plane.width(); ++x)
4208 {
4209 if (data[x] == planePixelValue)
4210 {
4211 return true;
4212 }
4213 }
4214 }
4215
4216 return false;
4217}
4218
4219template <typename T>
4220bool Frame::setValue(const T* planePixelValue, const size_t planePixelValueSize, const unsigned int planeIndex)
4221{
4222 static_assert(!std::is_void_v<T>, "Value access/assignment cannot be performed with void types.");
4223
4224 ocean_assert(planePixelValue != nullptr);
4225
4226 ocean_assert(planes_[planeIndex].elementTypeSize() == sizeof(T));
4227 ocean_assert(planes_[planeIndex].channels() == planePixelValueSize);
4228
4229 switch (planePixelValueSize)
4230 {
4231 case 1:
4232 {
4233 const PixelType<T, 1u> value =
4234 {{
4235 planePixelValue[0]
4236 }};
4237
4238 return setValue<T, 1u>(value, planeIndex);
4239 }
4240
4241 case 2:
4242 {
4243 const PixelType<T, 2u> value =
4244 {{
4245 planePixelValue[0],
4246 planePixelValue[1]
4247 }};
4248
4249 return setValue<T, 2u>(value, planeIndex);
4250 }
4251
4252 case 3:
4253 {
4254 const PixelType<T, 3u> value =
4255 {{
4256 planePixelValue[0],
4257 planePixelValue[1],
4258 planePixelValue[2]
4259 }};
4260
4261 return setValue<T, 3u>(value, planeIndex);
4262 }
4263
4264 case 4:
4265 {
4266 const PixelType<T, 4u> value =
4267 {{
4268 planePixelValue[0],
4269 planePixelValue[1],
4270 planePixelValue[2],
4271 planePixelValue[3]
4272 }};
4273
4274 return setValue<T, 4u>(value, planeIndex);
4275 }
4276
4277 default:
4278 break;
4279 }
4280
4281 ocean_assert(false && "The number of channels is not supported");
4282 return false;
4283}
4284
4285template <typename T>
4286bool Frame::setValue(const std::initializer_list<typename Identity<T>::Type>& planePixelValues, const unsigned int planeIndex)
4287{
4288 return setValue<T>(planePixelValues.begin(), planePixelValues.size(), planeIndex);
4289}
4290
4291inline unsigned int Frame::size(const unsigned int planeIndex) const
4292{
4293 ocean_assert(planes_.size() >= 1);
4294 ocean_assert(planeIndex < planes_.size());
4295
4296 return planes_[planeIndex].size();
4297}
4298
4299inline unsigned int Frame::paddingElements(const unsigned int planeIndex) const
4300{
4301 ocean_assert(planes_.size() >= 1);
4302 ocean_assert(planeIndex < planes_.size());
4303
4304 return planes_[planeIndex].paddingElements();
4305}
4306
4307inline unsigned int Frame::paddingBytes(const unsigned int planeIndex) const
4308{
4309 ocean_assert(planes_.size() >= 1);
4310 ocean_assert(planeIndex < planes_.size());
4311
4312 return planes_[planeIndex].paddingBytes();
4313}
4314
4315inline unsigned int Frame::strideElements(const unsigned int planeIndex) const
4316{
4317 ocean_assert(planes_.size() >= 1);
4318 ocean_assert(planeIndex < planes_.size());
4319
4320 return planes_[planeIndex].strideElements();
4321}
4322
4323inline unsigned int Frame::strideBytes(const unsigned int planeIndex) const
4324{
4325 ocean_assert(planes_.size() >= 1);
4326 ocean_assert(planeIndex < planes_.size());
4327
4328 return planes_[planeIndex].strideBytes();
4329}
4330
4331inline unsigned int Frame::planeWidth(const unsigned int planeIndex) const
4332{
4333 ocean_assert(planes_.size() >= 1);
4334 ocean_assert(planeIndex < planes_.size());
4335
4336 return planes_[planeIndex].width();
4337}
4338
4339inline unsigned int Frame::planeHeight(const unsigned int planeIndex) const
4340{
4341 ocean_assert(planes_.size() >= 1);
4342 ocean_assert(planeIndex < planes_.size());
4343
4344 return planes_[planeIndex].height();
4345}
4346
4347inline unsigned int Frame::planeChannels(const unsigned int planeIndex) const
4348{
4349 ocean_assert(planes_.size() >= 1);
4350 ocean_assert(planeIndex < planes_.size());
4351
4352 return planes_[planeIndex].channels();
4353}
4354
4355inline unsigned int Frame::planeWidthElements(const unsigned int planeIndex) const
4356{
4357 ocean_assert(planes_.size() >= 1);
4358 ocean_assert(planeIndex < planes_.size());
4359
4360 return planes_[planeIndex].widthElements();
4361}
4362
4363inline unsigned int Frame::planeWidthBytes(const unsigned int planeIndex) const
4364{
4365 ocean_assert(planes_.size() >= 1);
4366 ocean_assert(planeIndex < planes_.size());
4367
4368 return planes_[planeIndex].widthBytes();
4369}
4370
4371inline unsigned int Frame::planeBytesPerPixel(const unsigned int planeIndex) const
4372{
4373 ocean_assert(planes_.size() >= 1);
4374 ocean_assert(planeIndex < planes_.size());
4375
4376 return FrameType::planeBytesPerPixel(pixelFormat(), planeIndex);
4377}
4378
4379inline bool Frame::isPlaneContinuous(const unsigned int planeIndex) const
4380{
4381 ocean_assert(planes_.size() >= 1);
4382 ocean_assert(planeIndex < planes_.size());
4383
4384 return planes_[planeIndex].isContinuous();
4385}
4386
4387inline bool Frame::isPlaneOwner(const unsigned int planeIndex) const
4388{
4389 ocean_assert(planes_.size() >= 1);
4390 ocean_assert(planeIndex < planes_.size());
4391
4392 return planes_[planeIndex].isOwner();
4393}
4394
4395inline const Timestamp& Frame::timestamp() const
4396{
4397 return timestamp_;
4398}
4399
4401{
4402 return relativeTimestamp_;
4403}
4404
4405inline void Frame::setTimestamp(const Timestamp& timestamp)
4406{
4408}
4409
4410inline void Frame::setRelativeTimestamp(const Timestamp& relativeTimestamp)
4411{
4413}
4414
4415template <typename T>
4416inline T* Frame::data(const unsigned int planeIndex)
4417{
4418 ocean_assert(planes_.size() >= 1);
4419 ocean_assert(planeIndex < planes_.size());
4420
4421 return planes_[planeIndex].data<T>();
4422}
4423
4424template <typename T>
4425inline const T* Frame::constdata(const unsigned int planeIndex) const
4426{
4427 ocean_assert(planes_.size() >= 1);
4428 ocean_assert(planeIndex < planes_.size());
4429
4430 return planes_[planeIndex].constdata<T>();
4431}
4432
4433template <typename T>
4434inline T* Frame::row(const unsigned int y, const unsigned int planeIndex)
4435{
4436 ocean_assert(isValid());
4437 ocean_assert(y < height());
4438
4439 ocean_assert(planes_.size() >= 1);
4440 ocean_assert(planeIndex < planes_.size());
4441 Plane& plane = planes_[planeIndex];
4442
4443 ocean_assert(plane.isValid());
4444
4445 ocean_assert(y < plane.height());
4446 return reinterpret_cast<T*>(plane.data<uint8_t>() + y * plane.strideBytes());
4447}
4448
4449template <typename T>
4450inline const T* Frame::constrow(const unsigned int y, const unsigned int planeIndex) const
4451{
4452 ocean_assert(isValid());
4453 ocean_assert(y < height());
4454
4455 ocean_assert(planes_.size() >= 1);
4456 ocean_assert(planeIndex < planes_.size());
4457 const Plane& plane = planes_[planeIndex];
4458
4459 ocean_assert(plane.isValid());
4460
4461 ocean_assert(y < plane.height());
4462 return reinterpret_cast<const T*>(plane.constdata<uint8_t>() + y * plane.strideBytes());
4463}
4464
4465template <typename T>
4466inline T* Frame::pixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex)
4467{
4468 ocean_assert(isValid());
4469 ocean_assert(x < planeWidth(planeIndex));
4470 ocean_assert(y < planeHeight(planeIndex));
4471
4472 ocean_assert(planes_.size() >= 1);
4473 ocean_assert(planeIndex < planes_.size());
4474 Plane& plane = planes_[planeIndex];
4475
4476 ocean_assert(plane.isValid());
4477
4478 if constexpr (!std::is_void_v<T>)
4479 {
4480 ocean_assert(sizeof(T) == plane.elementTypeSize());
4481 }
4482
4483 /*
4484 * how to determine pixel offsets within row:
4485 *
4486 * the pixel format RGB24 has data type`uint8_t` and 3 channels
4487 * so the n-th pixel is reach by row<uint8_t>() + n * sizeof(uint8_t) * channels()
4488 *
4489 * RGB5551 has data type `uint16_t` and 3 channels
4490 * so the n-th pixel is reach by row<uint8_t>() + n * sizeof(uint16_t) * channels() / 3 == row<uint8_t>() + n * sizeof(uint16_t)
4491 * or row<uint16_t>() + n * channels() / 3 == row<uint16_t>() + n
4492 *
4493 * Therefore, the pixel offset cannot be determined via x * channels(),
4494 * Instead, we determine the offset via bytes per pixel == planeWidthBytes() / planeWidth()
4495 */
4496
4497 ocean_assert(x == 0u || !formatIsPacked(pixelFormat()));
4498
4499 ocean_assert(plane.bytesPerPixel() != 0u);
4500 const unsigned int xBytes = x * plane.bytesPerPixel();
4501
4502 ocean_assert(y < plane.height());
4503 return reinterpret_cast<T*>(plane.data<uint8_t>() + y * plane.strideBytes() + xBytes);
4504}
4505
4506template <typename T>
4507inline const T* Frame::constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex) const
4508{
4509 ocean_assert(isValid());
4510 ocean_assert(x < planeWidth(planeIndex));
4511 ocean_assert(y < planeHeight(planeIndex));
4512
4513 ocean_assert(planes_.size() >= 1);
4514 ocean_assert(planeIndex < planes_.size());
4515 const Plane& plane = planes_[planeIndex];
4516
4517 ocean_assert(plane.isValid());
4518
4519 if constexpr (!std::is_void_v<T>)
4520 {
4521 ocean_assert(sizeof(T) == plane.elementTypeSize());
4522 }
4523
4524 ocean_assert(x == 0u || !formatIsPacked(pixelFormat()));
4525
4526 ocean_assert(plane.bytesPerPixel() != 0u);
4527 const unsigned int xBytes = x * plane.bytesPerPixel();
4528
4529 ocean_assert(y < plane.height());
4530 return reinterpret_cast<const T*>(plane.constdata<uint8_t>() + y * plane.strideBytes() + xBytes);
4531}
4532
4533inline bool Frame::isContinuous() const
4534{
4535 ocean_assert(planes_.size() >= 1);
4536
4537 for (const Plane& plane : planes_)
4538 {
4539 if (!plane.isContinuous())
4540 {
4541 return false;
4542 }
4543 }
4544
4545 return true;
4546}
4547
4548inline bool Frame::isOwner() const
4549{
4550 ocean_assert(planes_.size() >= 1);
4551
4552 for (const Plane& plane : planes_)
4553 {
4554 if (!plane.isOwner())
4555 {
4556 return false;
4557 }
4558 }
4559
4560 return true;
4561}
4562
4563inline bool Frame::isReadOnly() const
4564{
4565 ocean_assert(planes_.size() >= 1);
4566
4567 for (const Plane& plane : planes_)
4568 {
4569 if (plane.isReadOnly())
4570 {
4571 return true;
4572 }
4573 }
4574
4575 return false;
4576}
4577
4578inline bool Frame::hasAlphaChannel() const
4579{
4580 ocean_assert(isValid());
4581
4583}
4584
4585template <>
4586inline bool Frame::hasTransparentPixel(const uint8_t opaque) const
4587{
4588 if (!hasAlphaChannel())
4589 {
4590 return false;
4591 }
4592
4593 ocean_assert(numberPlanes() == 1u);
4594
4595 if (dataType() != dataType<uint8_t>())
4596 {
4597 ocean_assert(false && "Data type does not fit with the frame's data type!");
4598 return false;
4599 }
4600
4601 if (pixelFormat() == FORMAT_YA16)
4602 {
4603 for (unsigned int y = 0u; y < height(); ++y)
4604 {
4605 const uint8_t* row = constrow<uint8_t>(y) + 1;
4606
4607 for (unsigned int x = 0u; x < width(); ++x)
4608 {
4609 if (*row != opaque)
4610 {
4611 return true;
4612 }
4613
4614 row += 2;
4615 }
4616 }
4617 }
4618 else
4619 {
4621
4622 const unsigned int offset = (pixelFormat() == FORMAT_ABGR32 || pixelFormat() == FORMAT_ARGB32) ? 0u : 3u;
4623
4624 for (unsigned int y = 0u; y < height(); ++y)
4625 {
4626 const uint8_t* row = constrow<uint8_t>(y) + offset;
4627
4628 for (unsigned int x = 0u; x < width(); ++x)
4629 {
4630 if (*row != opaque)
4631 {
4632 return true;
4633 }
4634
4635 row += 4;
4636 }
4637 }
4638 }
4639
4640 return false;
4641}
4642
4643template <>
4644inline bool Frame::hasTransparentPixel(const uint16_t opaque) const
4645{
4646 if (!hasAlphaChannel())
4647 {
4648 return false;
4649 }
4650
4651 ocean_assert(numberPlanes() == 1u);
4652
4653 if (dataType() != dataType<uint16_t>())
4654 {
4655 ocean_assert(false && "Data type does not fit with the frame's data type!");
4656 return false;
4657 }
4658
4659 if (pixelFormat() == FORMAT_RGBA64)
4660 {
4661 for (unsigned int y = 0u; y < height(); ++y)
4662 {
4663 const uint16_t* row = constrow<uint16_t>(y) + 3;
4664
4665 for (unsigned int x = 0u; x < width(); ++x)
4666 {
4667 if (*row != opaque)
4668 {
4669 return true;
4670 }
4671
4672 row += 4;
4673 }
4674 }
4675 }
4676 else
4677 {
4678 ocean_assert(pixelFormat() == FORMAT_RGBA4444 || pixelFormat() == FORMAT_BGRA4444);
4679
4680 for (unsigned int y = 0u; y < height(); ++y)
4681 {
4682 const uint16_t* row = constrow<uint16_t>(y);
4683
4684 for (unsigned int x = 0u; x < width(); ++x)
4685 {
4686 if ((*row & opaque) != opaque)
4687 {
4688 return true;
4689 }
4690
4691 ++row;
4692 }
4693 }
4694 }
4695
4696 return false;
4697}
4698
4699template <typename T>
4700bool Frame::hasTransparentPixel(const T /*opaque*/) const
4701{
4702 return false;
4703}
4704
4705inline bool Frame::isValid() const
4706{
4707 ocean_assert(planes_.size() >= 1);
4708
4709 const bool frameTypeIsValid = FrameType::isValid();
4710
4711#ifdef OCEAN_DEBUG
4712 {
4713 // we ensure that the state of `planes_` is consistent with the state of `FrameType::isValid()`
4714
4715 size_t debugValidPlanes = 0;
4716
4717 for (const Plane& plane : planes_)
4718 {
4719 if (plane.isValid())
4720 {
4721 ++debugValidPlanes;
4722 }
4723 }
4724
4725 const bool debugIsValid = !planes_.isEmpty() && debugValidPlanes == planes_.size();
4726
4727 ocean_assert(debugIsValid == frameTypeIsValid);
4728 }
4729#endif // OCEAN_DEBUG
4730
4731 return frameTypeIsValid;
4732}
4733
4734inline Frame::operator bool() const
4735{
4736 return isValid();
4737}
4738
4739}
4740
4741#endif // META_OCEAN_BASE_FRAME_H
Template class allowing to define an array of data types.
Definition DataType.h:27
Definition of an image plane, a block of memory storing pixel data with interleaved channels (or just...
Definition Frame.h:2034
unsigned int width() const
Returns the width of the plane in pixel.
Definition Frame.h:3741
bool isCompatibleWithDataType() const
Returns whether this plane is compatible with a given element data type.
Definition Frame.h:3820
unsigned int paddingElements() const
Returns the number of padding elements at the end of each plane row, in elements.
Definition Frame.h:3768
void * allocatedData_
The pointer to the memory which this plane has allocated, this pointer is pointing to the memory whic...
Definition Frame.h:2393
unsigned int paddingBytes() const
Returns the number of padding bytes at the end of each plane row, in bytes.
Definition Frame.h:3773
unsigned int elementTypeSize() const
Returns the size of each element of this plane.
Definition Frame.h:3778
bool isOwner() const
Returns whether this plane is the owner of the memory.
Definition Frame.h:3837
unsigned int calculateStrideBytes() const
Calculates the number of bytes between the start positions of two consecutive rows,...
Definition Frame.h:3883
void * data_
The pointer to the writable memory of the plane (not the pointer to the allocated memory),...
Definition Frame.h:2402
unsigned int strideBytes() const
Returns the number of bytes between the start positions of two consecutive rows, in bytes.
Definition Frame.h:3804
bool isContinuous() const
Returns whether this plane is based on continuous memory and thus does not have any padding at the en...
Definition Frame.h:3832
Plane(const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int elementTypeSize, const unsigned int paddingElements) noexcept
Creates a new plane object with own allocated memory.
const T * constdata() const
Returns the read-only memory pointer to this plane with a specific data type compatible with elementT...
Definition Frame.h:3757
bool isValid() const
Returns whether this plane holds valid data.
Definition Frame.h:3847
T * data()
Returns the writable memory pointer to this plane with a specific data type compatible with elementTy...
Definition Frame.h:3763
bool isReadOnly() const
Returns whether this plane holds read-only memory.
Definition Frame.h:3842
unsigned int size() const
Returns the number of bytes necessary for the entire plane data including optional padding elements a...
Definition Frame.h:3825
static constexpr bool validateMemoryLayout(const unsigned int planeWidth, const unsigned int planeHeight, const unsigned int planeChannels, const unsigned int bytesPerElement, const unsigned int paddingElements)
Returns whether the memory layout of a plane is valid (and fits into the memory).
Definition Frame.h:3852
unsigned int widthBytes() const
Returns the width of the plane in bytes, the width does not contain optional padding elements.
Definition Frame.h:3790
~Plane()
Destructs a Plane object.
Definition Frame.h:3736
Plane()=default
Creates a new invalid plane.
unsigned int channels() const
Returns the channels of the plane.
Definition Frame.h:3751
const void * constData_
The pointer to the read-only memory of the plane (not the pointer to the allocated memory),...
Definition Frame.h:2399
unsigned int bytesPerPixel() const
Returns the number of bytes which is used for each pixel.
Definition Frame.h:3812
void release()
Releases this plane and all resources of this plane.
unsigned int strideElements() const
Returns the number of elements between the start positions of two consecutive rows,...
Definition Frame.h:3797
Plane(const Plane &plane, const AdvancedCopyMode advancedCopyMode=ACM_USE_OR_COPY_KEEP_LAYOUT) noexcept
Copy constructor.
unsigned int height() const
Returns the height of the plane in pixel.
Definition Frame.h:3746
unsigned int paddingElements_
The number of padding elements at the end of each plane row, in elements, with range [0,...
Definition Frame.h:2417
unsigned int widthElements() const
Returns the width of the plane in elements, the width does not contain optional padding elements.
Definition Frame.h:3783
This class implements a helper class which can be used to initialize a multi-plane frame in the const...
Definition Frame.h:2438
PlaneInitializer(const T *constdata, const CopyMode copyMode, const unsigned int dataPaddingElements=0u)
Creates a new initializer object for a read-only memory pointer.
Definition Frame.h:3891
static std::vector< PlaneInitializer< T > > createPlaneInitializersWithPaddingElements(const Indices32 &paddingElementsPerPlane)
Creates plane initializer objects with padding elements only.
Definition Frame.h:3921
This class implements Ocean's image class.
Definition Frame.h:1969
bool copy(const int targetLeft, const int targetTop, const Frame &source, const bool copyTimestamp=true)
Copies the entire image content of a source frame into this frame.
static bool strideBytes2paddingElements(const PixelFormat &pixelFormat, const unsigned int imageWidth, const unsigned int planeStrideBytes, unsigned int &planePaddingElements, const unsigned int planeIndex=0u)
Determines the number of padding elements at the end of a row of a plane for which the pixel format,...
Frame(const FrameType &frameType, const CopyMode copyMode)=delete
Deleted constructor to prevent misuse.
typename Ocean::DataType< T, tChannels >::Type PixelType
Definition of a data type storing all channel values of one pixel in an array.
Definition Frame.h:2502
Timestamp relativeTimestamp_
Relative timestamp of this frame.
Definition Frame.h:3254
bool isContinuous() const
Returns whether all planes of this frame have continuous memory and thus do not contain any padding a...
Definition Frame.h:4533
bool hasAlphaChannel() const
Returns whether the frame's pixel format contains an alpha channel.
Definition Frame.h:4578
Frame(const FrameType &frameType, const AdvancedCopyMode advancedCopyMode)=delete
Deleted constructor to prevent misuse.
Frame(const FrameType &frameType, const PlaneInitializer< void > *planeInitializers, size_t sizePlaneInitializers, const Timestamp &timestamp=Timestamp(false))
Creates a new multi-plane frame with known frame type and given source memory for each individual pla...
unsigned int strideBytes(const unsigned int planeIndex=0u) const
Returns the number of bytes within one row, including optional padding at the end of a row for a spec...
Definition Frame.h:4323
bool haveIntersectingMemory(const Frame &frame) const
Returns whether two frame objects have any amount of intersecting memory.
Timestamp timestamp_
Timestamp of the frame.
Definition Frame.h:3251
unsigned int strideElements(const unsigned int planeIndex=0u) const
Returns the number of elements within one row, including optional padding at the end of a row for a s...
Definition Frame.h:4315
T * row(const unsigned int y, const unsigned int planeIndex=0u)
Returns the pointer to the pixel data of a specific row.
Definition Frame.h:4434
bool updateMemory(const T *data, const unsigned int planeIndex=0u)
Updates the memory pointer for a specific plane of the frame to a new read-only memory location.
Definition Frame.h:4040
Frame subFrame(const unsigned int subFrameLeft, const unsigned int subFrameTop, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const CopyMode copyMode=CM_USE_KEEP_LAYOUT) const
Returns a sub-frame of this frame.
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition Frame.h:4425
void setRelativeTimestamp(const Timestamp &relative)
Sets the relative timestamp of this frame.
Definition Frame.h:4410
const FrameType & frameType() const
Returns the frame type of this frame.
Definition Frame.h:4029
Frame(const Frame &frame)
Creates a second version of a given frame.
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4416
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4705
Frame(const FrameType &frameType, const T *data, const bool copyData, const unsigned int paddingElements=0u, const Timestamp &timestamp=Timestamp(false))=delete
Deleted constructor to prevent misuse, use Frame(const FrameType& frameType, const T* data,...
T * pixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u)
Returns the pointer to the data of a specific pixel.
Definition Frame.h:4466
void setTimestamp(const Timestamp &timestamp)
Sets the timestamp of this frame.
Definition Frame.h:4405
bool isReadOnly() const
Returns true, if the frame allows only read access (using constdata()).
Definition Frame.h:4563
Frame(const Frame &frame, const Timestamp &timestamp)=delete
Deleted constructor to prevent misuse.
bool copy(const Frame &source, const bool copyTimestamp=true)
Deprecated.
Frame(const Frame &frame, const bool copyData)=delete
Deleted constructor to prevent misuse.
bool set(const FrameType &frameType, const bool forceOwner, const bool forceWritable=false, const Indices32 &planePaddingElements=Indices32(), const Timestamp &timestamp=Timestamp(false), bool *reallocated=nullptr)
Sets a new frame type for this frame.
Frame & operator=(Frame &&right) noexcept
Move operator.
const Timestamp & timestamp() const
Returns the timestamp of this frame.
Definition Frame.h:4395
unsigned int planeBytesPerPixel(const unsigned int planeIndex) const
Returns the number of bytes of one pixel of a plane for a pixel format.
Definition Frame.h:4371
unsigned int planeWidthElements(const unsigned int planeIndex) const
Returns the width of a plane of this frame, not in pixel, but in elements, not including padding at t...
Definition Frame.h:4355
std::vector< PlaneInitializer< T > > PlaneInitializers
Definition of a vector holding plane initializer objects.
Definition Frame.h:2494
const Timestamp & relativeTimestamp() const
Returns the relative timestamp of this frame.
Definition Frame.h:4400
const Planes & planes() const
Returns the individual planes of this frame.
Definition Frame.h:4034
bool isOwner() const
Returns whether the frame is the owner of the internal frame data.
Definition Frame.h:4548
CopyMode
Definition of individual copy modes.
Definition Frame.h:1976
@ CM_USE_KEEP_LAYOUT
The source memory is used only, no copy is created, the padding layout is preserved.
Definition Frame.h:1978
unsigned int planeChannels(const unsigned int planeIndex) const
Returns the channels of a plane of this frame.
Definition Frame.h:4347
unsigned int planeWidth(const unsigned int planeIndex) const
Returns the width of a plane of this frame.
Definition Frame.h:4331
void release()
Releases this frame and the frame data if this frame is the owner.
Frame(const Frame &frame, const AdvancedCopyMode advancedCopyMode) noexcept
Creates a second version of a given frame.
Frame()
Creates an empty frame.
Definition Frame.h:3934
const T * constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific pixel.
Definition Frame.h:4507
Frame(const FrameType &frameType, T *data, const bool copyData, const unsigned int paddingElements=0u, const Timestamp &timestamp=Timestamp(false))=delete
Deleted constructor to prevent misuse, use Frame(const FrameType& frameType, T* data,...
~Frame()
Destructs a frame.
void makeOwner()
Makes this frame the owner of the memory.
Frame(const FrameType &frameType, const Timestamp &timestamp)=delete
Deleted constructor to prevent misuse.
AdvancedCopyMode
Definition of advanced copy modes containing all copy modes from CopyMode but also some additional.
Definition Frame.h:1991
Frame(const Frame &frame, const CopyMode copyMode)=delete
Deleted constructor to prevent misuse, use AdvancedCopyMode instead.
bool isPlaneContinuous(const unsigned int planeIndex=0u) const
Returns whether a specific plane of this frame is based on continuous memory and thus does not have a...
Definition Frame.h:4379
bool containsValue(const PixelType< T, tPlaneChannels > &planePixelValue, const unsigned int planeIndex=0u) const
Returns whether the frame (one plane) contains a specified pixel value.
Definition Frame.h:4178
bool setValue(const uint8_t value, const unsigned int planeIndex=0u, const bool skipPaddingData=true)
Sets the memory of the frame to a specified byte value (the memory of one plane).
bool isPlaneOwner(const unsigned int planeIndex=0u) const
Returns whether a specific plane of this frame is the owner of the memory.
Definition Frame.h:4387
unsigned int paddingBytes(const unsigned int planeIndex=0u) const
Returns the optional number of padding bytes at the end of each row for a specific plane.
Definition Frame.h:4307
const T * constrow(const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific row.
Definition Frame.h:4450
void makeContinuous()
Makes the memory of this frame continuous.
unsigned int planeWidthBytes(const unsigned int planeIndex) const
Returns the width of a plane of this frame, not in pixel, but in bytes, not including padding at the ...
Definition Frame.h:4363
bool hasTransparentPixel(const T opaque) const
Returns whether the frame holds at least one pixel with an non opaque alpha value.
Definition Frame.h:4700
Frame & operator=(const Frame &right) noexcept
Assign operator.
unsigned int planeHeight(const unsigned int planeIndex) const
Returns the height of a plane of this frame.
Definition Frame.h:4339
unsigned int size(const unsigned int planeIndex=0u) const
Returns the number of bytes necessary for a specific plane including optional padding at the end of p...
Definition Frame.h:4291
Planes planes_
The individual memory planes of this frame.
Definition Frame.h:3248
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition Frame.h:4299
This class implements a helper class allowing to create generic pixel formats.
Definition Frame.h:98
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition Frame.h:30
static unsigned int widthMultiple(const PixelFormat pixelFormat)
Returns the number of pixels the width of a frame must be a multiple of.
Definition Frame.h:3626
static PixelFormat translatePixelFormat(const std::string &pixelFormat)
Translates a string containing a pixel format into the pixel format.
static PixelFormat genericPixelFormat(const unsigned int bitsPerPixelChannel, const uint32_t channels, const uint32_t planes=1u, const uint32_t widthMultiple=1u, const uint32_t heightMultiple=1u)
Returns a specific generic pixel format with specified bit per pixel per channel, channel number,...
static unsigned int bytesPerDataType(const DataType dataType)
Returns the number of bytes which are necessary to store a specified data type.
bool operator==(const FrameType &right) const
Returns whether two frame types are equal.
unsigned int pixels() const
Returns the number of pixels for the frame.
Definition Frame.h:3384
FrameType()=default
Creates a new frame type with invalid parameters.
static unsigned int formatBitsPerPixelGreenChannel(const PixelFormat pixelFormat)
Returns the number of bits of one pixel for the green channel.
static constexpr uint32_t pixelFormatBitOffsetChannels
The number of bits the channel value is shifted within the PixelFormat value.
Definition Frame.h:74
static PixelFormat findPixelFormat(const DataType dataType, const unsigned int channels)
Returns a best fitting pixel format having the given number of bits per pixels.
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition Frame.h:183
@ FORMAT_YA16
Pixel format with byte order YA and 16 bits per pixel.
Definition Frame.h:651
@ FORMAT_BGRA4444
Pixel format with entirely 16 bits per pixel, 4 bits for each channel.
Definition Frame.h:282
@ FORMAT_UNDEFINED
Undefined pixel format.
Definition Frame.h:187
@ FORMAT_RGBA64
Pixel format with byte order RGBA and 64 bits per pixel, with 16 bit per component.
Definition Frame.h:677
@ FORMAT_RGBA4444
Pixel format with entirely 16 bits per pixel, 4 bits for each channel.
Definition Frame.h:395
@ FORMAT_ARGB32
Pixel format with byte order ARGB and 32 bits per pixel.
Definition Frame.h:213
@ FORMAT_ABGR32
Pixel format with byte order ABGR and 32 bits per pixel.
Definition Frame.h:200
@ FORMAT_RGBA32
Pixel format with byte order RGBA and 32 bits per pixel.
Definition Frame.h:382
@ FORMAT_YUVA32
Pixel format with byte order YUVA and 32 bits per pixel.
Definition Frame.h:473
@ FORMAT_BGRA32
Pixel format with byte order BGRA and 32 bits per pixel.
Definition Frame.h:277
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3334
static PixelFormat genericSinglePlanePixelFormat(const PixelFormat pixelFormat)
Returns the most suitable 1-plane pixel format for a given pixel format which may be composed of seve...
PlanesValue
Definition of a protected helper enum that simplifies to read the definition of a predefined pixel fo...
Definition Frame.h:126
bool isPixelFormatDataLayoutCompatible(const PixelFormat pixelFormat) const
Returns whether this pixel format has a compatible data layout with a given pixel format.
Definition Frame.h:3396
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition Frame.h:3379
std::vector< PixelFormat > PixelFormats
Definition of a vector holding pixel formats.
Definition Frame.h:1130
static bool areFrameTypesDataLayoutCompatible(const FrameType &frameTypeA, const FrameType &frameTypeB, const bool allowDifferentPixelOrigins)
Returns whether two given frame types have compatible data layouts.
static DataType translateDataType(const std::string &dataType)
Translates a string containing a data type into the data type.
unsigned int frameTypeSize() const
Returns the number of bytes necessary for the frame type, without padding at the end of frame rows.
static unsigned int formatGenericBitsPerPixel(const PixelFormat pixelFormat)
Returns the number of bits of one pixel for a given generic pixel format.
Definition Frame.h:3538
static constexpr bool isProductInsideValueRange(const unsigned int valueA, const unsigned int valueB)
Returns whether two values can be multiplied with each other without producing an overflow.
Definition Frame.h:3684
unsigned int height_
Frame height in pixel, with range [0, infinity)
Definition Frame.h:1915
static bool dataIsAligned(const void *data)
Returns whether a given pointer has the same byte alignment as the size of the data type the pointer ...
Definition Frame.h:3673
static PixelOrigin translatePixelOrigin(const std::string &pixelOrigin)
Translates a string containing the pixel origin into the pixel origin value.
bool operator!=(const FrameType &right) const
Returns whether two frame types are not equal.
Definition Frame.h:3411
static constexpr bool isSumInsideValueRange(const unsigned int valueA, const unsigned int valueB)
Returns whether two values can be added with each other without producing an overflow.
Definition Frame.h:3679
static bool planeLayout(const PixelFormat imagePixelFormat, const unsigned int imageWidth, const unsigned int imageHeight, const unsigned int planeIndex, unsigned int &planeWidth, unsigned int &planeHeight, unsigned int &planeChannels, unsigned int *planeWidthElementsMultiple=nullptr, unsigned int *planeHeightElementsMultiple=nullptr)
Returns the plane layout of a given pixel format.
static PixelFormat formatGrayscalePixelFormat(const PixelFormat pixelFormat)
Returns the best matching grayscale pixel format for a given pixel format.
static constexpr PixelFormat genericPixelFormat()
Returns a specific generic pixel format with a specified data type and channel number.
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition Frame.h:3374
PixelOrigin pixelOrigin_
The origin of the pixel data, either the upper left corner or the bottom left corner (if valid).
Definition Frame.h:1921
static std::string translatePixelFormat(const PixelFormat pixelFormat)
Translates a pixel format value into a string containing the pixel format.
static bool formatIsLimitedRange(const PixelFormat pixelFormat)
Returns whether a given pixel format is using a limited value range (e.g., like Y_UV12_LIMITED_RANGE)...
static PixelFormat formatRemoveAlphaChannel(const PixelFormat pixelFormat)
Removes an alpha channel from a given pixel format.
static bool arePixelFormatsCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB)
Returns whether two given pixel formats are compatible.
static unsigned int formatBitsPerPixelAlphaChannel(const PixelFormat pixelFormat)
Returns the number of bits of one pixel for the alpha channel.
MultipleValue
Definition of a protected helper enum that simplifies to read the definition of a predefined pixel fo...
Definition Frame.h:141
static bool areFrameTypesCompatible(const FrameType &frameTypeA, const FrameType &frameTypeB, const bool allowDifferentPixelOrigins)
Returns whether two given frame types are compatible.
static bool formatHasAlphaChannel(const PixelFormat pixelFormat, bool *isLastChannel=nullptr)
Returns whether a given pixel format holds an alpha channel.
static unsigned int heightMultiple(const PixelFormat pixelFormat)
Returns the number of pixels the height of a frame must be a multiple of.
Definition Frame.h:3631
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition Frame.h:3344
unsigned int bytesPerDataType() const
Returns the number of bytes which are necessary to store the data type of this frame.
Definition Frame.h:3359
static constexpr PixelFormat genericPixelFormat(uint32_t channels, const uint32_t planes=1u, const uint32_t widthMultiple=1u, const uint32_t heightMultiple=1u)
Returns a specific generic pixel format with a specified data type and channel number.
PixelOrigin
Defines different types of frame origin positions.
Definition Frame.h:1136
@ ORIGIN_INVALID
Invalid origin type.
Definition Frame.h:1138
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition Frame.h:1140
static const FrameType::DataTypes & definedDataTypes()
Returns all defined data types.
ChannelsValue
Definition of a protected helper enum that simplifies to read the definition of a predefined pixel fo...
Definition Frame.h:109
DataType
Definition of individual channel data type.
Definition Frame.h:37
@ DT_UNSIGNED_INTEGER_64
Unsigned 64 bit integer data type (uint64_t).
Definition Frame.h:53
@ DT_UNSIGNED_INTEGER_16
Unsigned 16 bit integer data type (uint16_t).
Definition Frame.h:45
@ DT_SIGNED_INTEGER_16
Signed 16 bit integer data type (int16_t).
Definition Frame.h:47
@ DT_SIGNED_INTEGER_32
Signed 232 bit integer data type (int32_t).
Definition Frame.h:51
@ DT_END
The helper data type which can be used to identify the last defined data type, DT_END is exclusive.
Definition Frame.h:63
@ DT_SIGNED_INTEGER_64
Signed 64 bit integer data type (int64_t).
Definition Frame.h:55
@ DT_UNDEFINED
Undefined data type.
Definition Frame.h:39
@ DT_SIGNED_FLOAT_64
Signed 64 bit float data type (double).
Definition Frame.h:61
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition Frame.h:41
@ DT_UNSIGNED_INTEGER_32
Unsigned 32 bit integer data type (uint32_t).
Definition Frame.h:49
@ DT_SIGNED_FLOAT_16
Signed 16 bit float data type.
Definition Frame.h:57
@ DT_SIGNED_FLOAT_32
Signed 32 bit float data type (float).
Definition Frame.h:59
@ DT_SIGNED_INTEGER_8
Signed 8 bit integer data type (int8_t).
Definition Frame.h:43
static unsigned int planeBytesPerPixel(const PixelFormat &imagePixelFormat, const unsigned int planeIndex)
Returns the number of bytes of one pixel of a plane for a pixel format.
Definition Frame.h:3636
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3339
static unsigned int formatBitsPerPixelRedChannel(const PixelFormat pixelFormat)
Returns the number of bits of one pixel for the red channel.
static constexpr uint32_t pixelFormatBitOffsetDatatype
The number of bits the data type value is shifted within the PixelFormat value.
Definition Frame.h:77
static bool formatIsPacked(const PixelFormat pixelFormat)
Returns whether a given pixel format is a packed pixel format.
unsigned int width_
Frame width in pixel, with range [0, infinity)
Definition Frame.h:1912
static constexpr uint32_t pixelFormatBitOffsetWidthMultiple
The number of bits the width-multiple value is shifted within the PixelFormat value.
Definition Frame.h:83
bool operator<(const FrameType &right) const
Returns whether the left frame type is 'smaller' than the right one.
static bool formatIsPureGeneric(const PixelFormat pixelFormat)
Checks whether a given pixel format is a pure generic pixel format.
Definition Frame.h:3619
static bool isDataLayoutCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB)
Returns whether two given pixel formats have compatible data layouts.
bool isValid() const
Returns whether this frame type is valid.
Definition Frame.h:3416
static const FrameType::PixelFormats & definedPixelFormats()
Returns all defined pixel formats.
bool isPixelFormatCompatible(const PixelFormat pixelFormat) const
Returns whether the pixel format of this frame type is compatible with a given pixel format.
Definition Frame.h:3391
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3364
static unsigned int channels(const PixelFormat pixelFormat)
Returns the number of individual channels of a given pixel format.
PixelFormatUnion pixelFormat_
The pixel format of the frame encapsulated in a union (mainly holding PixelFormat).
Definition Frame.h:1918
static std::string translateDataType(const DataType dataType)
Translates a data type value into a string containing the data type.
std::vector< DataType > DataTypes
Definition of a vector holding data types.
Definition Frame.h:69
static unsigned int formatBitsPerPixelBlueChannel(const PixelFormat pixelFormat)
Returns the number of bits of one pixel for the blue channel.
static PixelFormat findPixelFormat(const unsigned int bitsPerPixel)
Returns a best fitting pixel format having the given number of bits per pixels.
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition Frame.h:3354
static PixelFormat makeGenericPixelFormat(const PixelFormat pixelFormat)
Converts a any pixel format into a generic one This function has no effect for input pixel formats wh...
Definition Frame.h:3602
static unsigned int planeChannels(const PixelFormat &imagePixelFormat, const unsigned int planeIndex)
Returns the channels of a plane for a pixel format.
static constexpr PixelFormat genericPixelFormat()
Returns a specific generic pixel format with a specified data type and channel number.
Definition Frame.h:3555
bool isFrameTypeCompatible(const FrameType &frameType, const bool allowDifferentPixelOrigins) const
Returns whether this frame type is compatible with a given frame type.
Definition Frame.h:3401
static constexpr uint32_t pixelFormatBitOffsetHeightMultiple
The number of bits the height-multiple value is shifted within the PixelFormat value.
Definition Frame.h:86
static unsigned int formatGenericNumberChannels(const PixelFormat pixelFormat)
Returns the number of individual channels of a given generic pixel format.
Definition Frame.h:3426
static std::string translatePixelOrigin(const PixelOrigin pixelOrigin)
Translates a pixel origin value into a string containing the pixel origin.
static bool formatIsGeneric(const PixelFormat pixelFormat, const DataType dataType, const uint32_t channels, const uint32_t planes=1u, const uint32_t widthMultiple=1u, const uint32_t heightMultiple=1u)
Checks whether a given pixel format is a specific layout regarding data channels and data type.
Definition Frame.h:3609
static constexpr uint32_t pixelFormatBitOffsetPlanes
The number of bits the planes value is shifted within the PixelFormat value.
Definition Frame.h:80
void setPixelFormat(const PixelFormat pixelFormat)
Explicitly changes the pixel format of this frame.
Definition Frame.h:3349
bool isFrameTypeDataLayoutCompatible(const FrameType &frameType, const bool allowDifferentPixelOrigins) const
Returns whether this frame type has a compatible data layout with a given frame type.
Definition Frame.h:3406
static PixelFormat formatAddAlphaChannel(const PixelFormat pixelFormat, const bool lastChannel=true)
Adds an alpha channel to a given pixel format.
T Type
The data type of 'T'.
Definition DataType.h:90
This template class implements a object reference with an internal reference counter.
Definition base/ObjectRef.h:58
bool isEmpty() const
Returns whether this vector is empty.
Definition StackHeapVector.h:695
size_t size() const
Returns the number of elements of this vector.
Definition StackHeapVector.h:681
This class implements a timestamp.
Definition Timestamp.h:64
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
std::vector< Frame > Frames
Definition of a vector holding padding frames.
Definition Frame.h:1932
std::vector< FrameRef > FrameRefs
Definition of a vector holding frame references.
Definition Frame.h:1944
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32
Helper struct allowing to get access to the properties of a pixel format with a debugger.
Definition Frame.h:1151
DataType dataType_
The data type of each elements of the pixel format.
Definition Frame.h:1159
uint16_t predefinedPixelFormat_
The value of the pixel format if predefined (if the pixel format is e.g., FORMAT_RGB24,...
Definition Frame.h:1153
uint8_t planes_
The number of individual planes of the pixel format.
Definition Frame.h:1162
uint8_t heightMultiple_
The number of pixels the height of a frame must be a multiple of.
Definition Frame.h:1168
uint8_t widthMultiple_
The number of pixels the width of a frame must be a multiple of.
Definition Frame.h:1165
uint8_t unused_
Currently unused.
Definition Frame.h:1171
uint8_t channels_
The number of channels, the pixel format has.
Definition Frame.h:1156
This union mainly contains the pixel format as value.
Definition Frame.h:1182
PixelFormat pixelFormat_
The actual pixel format defining the layout of the color space, the number of channels and the data t...
Definition Frame.h:1197
PixelFormatProperties properties_
The properties of the pixel format.
Definition Frame.h:1202