CVB++ 14.0
data_type.hpp
1#pragma once
2
3#include <limits>
4#include <type_traits>
5#include <utility>
6
7
8#include <cmath>
9
10
11
12#include "_cexports/c_img.h"
13
14#include "global.hpp"
15#include "exception.hpp"
16
17namespace Cvb
18{
19
20CVB_BEGIN_INLINE_NS
21
22
23
25
27class DataType final
28{
29 public:
30
32
37 static DataType FromNativeDescriptor(int dataTypeDescriptor) noexcept
38 {
39 return DataType(dataTypeDescriptor);
40 }
41
43
47 static DataType Int8BppUnsigned() noexcept
48 {
49 return DataType(8);
50 }
51
53
57 static DataType Int8BppSigned() noexcept
58 {
59 return DataType(8 | CExports::DT_Signed);
60 }
61
63
67 static DataType Int10BppUnsigned() noexcept
68 {
69 return DataType(10);
70 }
71
73
77 static DataType Int12BppUnsigned() noexcept
78 {
79 return DataType(12);
80 }
81
83
87 static DataType Int16BppUnsigned() noexcept
88 {
89 return DataType(16);
90 }
91
93
97 static DataType Int16BppSigned() noexcept
98 {
99 return DataType(16 | CExports::DT_Signed);
100 }
101
103
107 static DataType Int32BppUnsigned() noexcept
108 {
109 return DataType(32);
110 }
111
113
117 static DataType Int32BppSigned() noexcept
118 {
119 return DataType(32 | CExports::DT_Signed);
120 }
121
123
127 static DataType Int64BppUnsigned() noexcept
128 {
129 return DataType(64);
130 }
131
133
137 static DataType Int64BppSigned() noexcept
138 {
139 return DataType(64 | CExports::DT_Signed);
140 }
141
143
147 static DataType Float32Bpp() noexcept
148 {
149 return DataType(32 | CExports::DT_Float | CExports::DT_Signed);
150 }
151
153
157 static DataType Float64Bpp() noexcept
158 {
159 return DataType(64 | CExports::DT_Float | CExports::DT_Signed);
160 }
161
162
163
165
180 template<typename T>
181 static DataType FromNativeType() noexcept
182 {
184 "CVB: Unsupported image plane data type!");
185 static_assert((1 << 8) == CExports::DT_Signed,
186 "CVB: DT_Signed does not match!");
187 static_assert((1 << 9) == CExports::DT_Float,
188 "CVB: DT_Float does not match!");
189
190
191 CExports::cvbdatatype_t nativeDescriptor = sizeof(T) * 8 // bit size
192 | std::is_signed<T>::value << 8 // set signed bit if signed int or float
193 | std::is_floating_point<T>::value << 9; // set float bit if float
194
195 return DataType(nativeDescriptor);
196 }
197
199
209 template <template<class> class T, class ACTION, class... CTORARGS>
210 auto CallWithInstanceOf(ACTION action, CTORARGS... args) const -> decltype(action(T<int>{std::forward<CTORARGS>(args)...}))
211 {
212 if(this->IsUnsignedInteger())
213 {
214 switch(this->BytesPerPixel())
215 {
216 case 1:
217 {
218 T<std::uint8_t> t{std::forward<CTORARGS>(args)...};
219 return action(t);
220 }
221 case 2:
222 {
223 T<std::uint16_t> t{std::forward<CTORARGS>(args)...};
224 return action(t);
225 }
226 case 4:
227 {
228 T<std::uint32_t> t{std::forward<CTORARGS>(args)...};
229 return action(t);
230 }
231 case 8:
232 {
233 T<std::uint64_t> t{std::forward<CTORARGS>(args)...};
234 return action(t);
235 }
236 default:
237 {
238 break;
239 }
240 }
241 }
242 else if(this->IsSignedInteger())
243 {
244 switch (this->BytesPerPixel())
245 {
246 case 1:
247 {
248 T<std::int8_t> t{std::forward<CTORARGS>(args)...};
249 return action(t);
250 }
251 case 2:
252 {
253 T<std::int16_t> t{std::forward<CTORARGS>(args)...};
254 return action(t);
255 }
256 case 4:
257 {
258 T<std::int32_t> t{std::forward<CTORARGS>(args)...};
259 return action(t);
260 }
261 case 8:
262 {
263 T<std::int64_t> t{std::forward<CTORARGS>(args)...};
264 return action(t);
265 }
266 default:
267 {
268 break;
269 }
270 }
271 }
272 else if(this->IsFloat())
273 {
274 switch (this->BytesPerPixel())
275 {
276 case 4:
277 {
278 T<float> t{std::forward<CTORARGS>(args)...};
279 return action(t);
280 }
281 case 8:
282 {
283 T<double> t{std::forward<CTORARGS>(args)...};
284 return action(t);
285 }
286 default:
287 {
288 break;
289 }
290 }
291 }
292
293 throw std::runtime_error("Could not match native data type");
294 }
295
297
305 template <class T>
306 bool Matches() const noexcept
307 {
309 "CVB: T must be integer or floating point");
310
311 // floats use specialization below
312 return this->BytesPerPixel() == sizeof(T)
315 }
316
318
322 int NativeDescriptor() const noexcept
323 {
324 return dataTypeDescriptor_;
325 }
326
328
332 int BitsPerPixel() const noexcept
333 {
334 return dataTypeDescriptor_ & 0xFF;
335 }
336
338
342 int BytesPerPixel() const noexcept
343 {
344 // remember: 0x7 is equivalent to % 8
345 return BitsPerPixel() / 8 + (((BitsPerPixel() & 0x7) != 0) ? 1 : 0);
346 }
347
349
353 bool IsFloat() const noexcept
354 {
355 // as defined in iCVCImg.h...
356 return (dataTypeDescriptor_ & CExports::DT_Float) != 0;
357 }
358
360
364 bool IsSignedInteger() const noexcept
365 {
366 return (dataTypeDescriptor_ & CExports::DT_Signed) != 0 && !IsFloat();
367 }
368
370
374 bool IsUnsignedInteger() const noexcept
375 {
376 return (dataTypeDescriptor_ & 0xB00) == 0;
377 }
378
380
384 bool IsSigned() const noexcept
385 {
386 return (dataTypeDescriptor_ & CExports::DT_Signed) != 0;
387 }
388
390
394 bool HasOverlayBit() const noexcept
395 {
396 return (dataTypeDescriptor_ & CExports::DT_Overlay) != 0;
397 }
398
400
410 bool IsComplexPacked() const noexcept
411 {
412 return (dataTypeDescriptor_ & CExports::DT_ComplexPacked) != 0;
413 }
414
416
420 double MinVal() const noexcept
421 {
422 if (IsFloat())
423 {
424#ifdef min
425#undef min
426#endif
427 if (BytesPerPixel() == 4)
428 return static_cast<double>(std::numeric_limits<float>::lowest());
429 else if (BytesPerPixel() == 8)
431 else
433 }
434 else
435 {
436 CExports::cvbval_t min = 0;
437 CExports::cvbval_t max = 0;
438 CVB_CALL_CAPI(GetDatatypeMinMaxVal(static_cast<CExports::cvbdatatype_t>(dataTypeDescriptor_), min, max));
439 return static_cast<double>(min);
440 }
441 }
442
444
448 double MaxVal() const noexcept
449 {
450#ifdef max
451#undef max
452#endif
453 if (IsFloat())
454 {
455 if (BytesPerPixel() == 4)
456 return static_cast<double>(std::numeric_limits<float>::max());
457 else if (BytesPerPixel() == 8)
459 else
461 }
462 else
463 {
464 CExports::cvbval_t min = 0;
465 CExports::cvbval_t max = 0;
466 CVB_CALL_CAPI(GetDatatypeMinMaxVal(static_cast<CExports::cvbdatatype_t>(dataTypeDescriptor_), min, max));
467 return static_cast<double>(max);
468 }
469
470 }
471
473
477 PixelDataType NumericType() const noexcept
478 {
479
480 if ((IsComplexPacked()) && (IsFloat()))
482 else if (IsFloat())
484 else if (IsSignedInteger())
485 return PixelDataType::Int;
486 else if (IsUnsignedInteger())
487 return PixelDataType::UInt;
488 else
490
491 }
492
493
495
502 double UndefinedVal() const noexcept
503 {
504
506 return round((MaxVal() - MinVal()) / 2.0);
507 else
508 return 0.0;
509
510 }
511
513
518 bool operator==(const DataType& dataType) const noexcept
519 {
520 if (IsFloat() && dataType.IsFloat())
521 return BitsPerPixel() == dataType.BitsPerPixel(); // skip signed bit if float or double
522 return dataTypeDescriptor_ == dataType.dataTypeDescriptor_;
523 }
524
526
531 bool operator!=(const DataType& dataType) const noexcept
532 {
533 return !(*this == dataType);
534 }
535
536
537
538 private:
539
540 DataType(CExports::cvbdatatype_t dataTypeDescriptor) noexcept
541 : dataTypeDescriptor_(dataTypeDescriptor)
542 {
543 }
544
545
546 int dataTypeDescriptor_;
547};
548
549
550CVB_END_INLINE_NS
551
552}
553
Data type description for an image plane.
Definition: data_type.hpp:28
int BytesPerPixel() const noexcept
Number of bytes occupied by each pixel.
Definition: data_type.hpp:342
static DataType Int64BppSigned() noexcept
Represents 64-bit signed integer pixels.
Definition: data_type.hpp:137
static DataType Int12BppUnsigned() noexcept
Represents 12-bit unsigned integer pixels.
Definition: data_type.hpp:77
double MinVal() const noexcept
Gets the minimum pixel value that fits this data type.
Definition: data_type.hpp:420
static DataType Int16BppUnsigned() noexcept
Represents 16-bit unsigned integer pixels.
Definition: data_type.hpp:87
bool HasOverlayBit() const noexcept
Gets whether bit 0 of the pixels of the plane are being used as an overlay indicator bit.
Definition: data_type.hpp:394
int BitsPerPixel() const noexcept
Number of actually valid bits per pixel.
Definition: data_type.hpp:332
bool IsSigned() const noexcept
Gets whether the pixels of the plane have signed values.
Definition: data_type.hpp:384
int NativeDescriptor() const noexcept
Native data type descriptor.
Definition: data_type.hpp:322
bool IsSignedInteger() const noexcept
Gets whether the pixels of the plane have signed integer values.
Definition: data_type.hpp:364
static DataType Int8BppUnsigned() noexcept
Represents 8-bit unsigned integer pixels (bytes).
Definition: data_type.hpp:47
bool operator!=(const DataType &dataType) const noexcept
Compares to an other data type.
Definition: data_type.hpp:531
bool Matches() const noexcept
Gets whether the type T matches this data type.
Definition: data_type.hpp:306
bool IsUnsignedInteger() const noexcept
Gets whether the pixels of the plane have unsigned integer values.
Definition: data_type.hpp:374
static DataType Int32BppUnsigned() noexcept
Represents 32-bit unsigned integer pixels.
Definition: data_type.hpp:107
PixelDataType NumericType() const noexcept
Returns the basic numeric type of the pixels.
Definition: data_type.hpp:477
static DataType Int32BppSigned() noexcept
Represents 32-bit signed integer pixels.
Definition: data_type.hpp:117
bool operator==(const DataType &dataType) const noexcept
Compares to an other data type.
Definition: data_type.hpp:518
static DataType FromNativeType() noexcept
Construct a data type descriptor from one of the native data type value equivalents.
Definition: data_type.hpp:181
static DataType Int16BppSigned() noexcept
Represents 16-bit signed integer pixels.
Definition: data_type.hpp:97
bool IsFloat() const noexcept
Gets whether the pixels of the plane have floating point values.
Definition: data_type.hpp:353
auto CallWithInstanceOf(ACTION action, CTORARGS... args) const -> decltype(action(T< int >{std::forward< CTORARGS >(args)...}))
Calls action with T instance of native data type this value represents.
Definition: data_type.hpp:210
static DataType Int8BppSigned() noexcept
Represents 8-bit signed integer pixels.
Definition: data_type.hpp:57
static DataType FromNativeDescriptor(int dataTypeDescriptor) noexcept
Construct a data type descriptor from one of the native library's descriptor values.
Definition: data_type.hpp:37
static DataType Float32Bpp() noexcept
Represents single precision (32-bit) floating point pixels.
Definition: data_type.hpp:147
static DataType Int10BppUnsigned() noexcept
Represents 10-bit unsigned integer pixels.
Definition: data_type.hpp:67
static DataType Int64BppUnsigned() noexcept
Represents 64-bit unsigned integer pixels.
Definition: data_type.hpp:127
static DataType Float64Bpp() noexcept
Represents double precision (64-bit) floating point pixels.
Definition: data_type.hpp:157
double MaxVal() const noexcept
Gets the maximum pixel value that fits this data type.
Definition: data_type.hpp:448
double UndefinedVal() const noexcept
Get the undefined value for this data type.
Definition: data_type.hpp:502
bool IsComplexPacked() const noexcept
Indicates whether or not the plane contains a complex packed image format.
Definition: data_type.hpp:410
T lowest(T... args)
T max(T... args)
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
PixelDataType
Defines the numeric data type of one pixel.
Definition: global.hpp:124
T quiet_NaN(T... args)