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