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