-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathFrameConverter.h
More file actions
3586 lines (3247 loc) · 196 KB
/
Copy pathFrameConverter.h
File metadata and controls
3586 lines (3247 loc) · 196 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifndef META_OCEAN_CV_FRAME_CONVERTER_H
#define META_OCEAN_CV_FRAME_CONVERTER_H
#include "ocean/cv/CV.h"
#include "ocean/cv/CVUtilities.h"
#include "ocean/cv/NEON.h"
#include "ocean/base/Frame.h"
#include "ocean/base/Worker.h"
#include "ocean/math/Matrix.h"
namespace Ocean
{
namespace CV
{
OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC // Clang has a bug and need to be disabled for FrameConverter
/**
* This is the base class for all frame converter classes.
* @ingroup cv
*/
class OCEAN_CV_EXPORT FrameConverter
{
public:
/**
* Definition of individual conversion flags.
*/
enum ConversionFlag : uint32_t
{
/**
* Normal conversion, neither flips nor mirrors the image.
* The following pattern shows the conversion for an image with resolution 2x2:
* <pre>
* Input: Output:
* | A B | | A B |
* | C D | | C D |
* </pre>
*/
CONVERT_NORMAL,
/**
* Flipped conversion, exchanges top and bottom of the image (flipping around the x-axis).
* The following pattern shows the conversion for an image with resolution 2x2:
* <pre>
* Input: Output:
* | A B | | C D |
* | C D | | A B |
* </pre>
*/
CONVERT_FLIPPED,
/**
* Mirrored conversion, exchanges left and right of the image (like in a mirror, mirroring around the y-axis).
* The following pattern shows the conversion for an image with resolution 2x2:
* <pre>
* Input: Output:
* | A B | | B A |
* | C D | | D C |
* </pre>
*/
CONVERT_MIRRORED,
/**
* Rotated conversion, rotates the image by 180.0 degrees with anchor in the center of the image.
* The following pattern shows the conversion for an image with resolution 2x2:
* <pre>
* Input: Output:
* | A B | | D C |
* | C D | | B A |
* </pre>
*/
CONVERT_FLIPPED_AND_MIRRORED
};
/**
* Definition of a vector holding conversion flags.
*/
using ConversionFlags = std::vector<ConversionFlag>;
/**
* Definition of a boolean enum for copy preferences (to improve code readability).
*/
enum CopyPreference : bool
{
/// Tries to avoid copying the frame data whenever possible.
CP_AVOID_COPY_IF_POSSIBLE = false,
/// Forces a copy of the frame data in any case.
CP_ALWAYS_COPY = true
};
/**
* Definition of a class storing options for frame conversions.
*/
class Options
{
public:
/**
* Definition of individual types of options.
*/
enum OptionsType : uint32_t
{
/// Default conversion.
OT_DEFAULT = 0u,
/// Conversion with explicit alpha channel target value.
OT_ALPHA_CHANNEL_TARGET_VALUE = 1u << 0u,
/// Conversion with gamma correction.
OT_GAMMA_CORRECTION = 1u << 1u,
/// Conversion with black level, white balance, and gamma encoding
OT_BLACKLEVEL_WHITEBALANCE_GAMMA = 1u << 2u,
/// Approximated conversion.
OT_APPROXIMATED = 1u << 2u,
};
public:
/**
* Default constructor.
* @param allowApproximation True, to allow an approximated conversion if available
*/
explicit inline Options(const bool allowApproximation = false);
/**
* Creates options for source image without alpha channel but a target image with alpha channel.
* @param alphaChannelTargetValue The uint8_t alpha channel value for the target image if the source image does not contain an alpha channel; ignored if the source image contains an alpha channel, with range [0, 255]
* @param allowApproximation True, to allow an approximated conversion if available
*/
explicit inline Options(const uint8_t alphaChannelTargetValue, const bool allowApproximation = false);
/**
* Creates options for a conversion applying gamma correction.
* @param gamma The gamma value to be applied, with range (0, 2)
* @param allowApproximation True, to allow an approximated conversion if available
*/
explicit inline Options(const float gamma, const bool allowApproximation = false);
/**
* Creates options for a conversion applying black level subtraction, white balance, and gamma encoding.
* @param blackLevel The black level value that is subtracted from each element of the raw image before any other operation, with range [0, 1024)
* @param whiteBalanceRed The white balancing scalar of the red channel, with range [0, infinity)
* @param whiteBalanceGreen The white balancing scalar of the green channel, with range [0, infinity)
* @param whiteBalanceBlue The white balancing scalar of the blue channel, with range [0, infinity)
* @param gamma The gamma value to be applied, with range (0, infinity)
* @param allowApproximation True, to allow an allowApproximation conversion if available
* @sa FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24BlacklevelWhiteBalanceGammaLUT()
*/
explicit inline Options(const uint16_t blackLevel, const float whiteBalanceRed, const float whiteBalanceGreen, const float whiteBalanceBlue, const float gamma, const bool allowApproximation = false);
/**
* Returns the options type.
* @return The options' type
*/
inline OptionsType optionsType() const;
/**
* Returns the uint8_t alpha channel value for the target image if the source image does not contain an alpha channel; ignored if the source image contains an alpha channel.
* @return The alpha value for the target channel, with range [0, 255]
*/
inline uint8_t alphaChannelTargetValue() const;
/**
* Returns the gamma value for a conversion with gamma correction/encoding.
* @return The gamma value, with range (0, 2) (OT_GAMMA_CORRECTION) or [0, infinity) (OT_BLACKLEVEL_WHITEBALANCE_GAMMA)
*/
inline float gamma() const;
/**
* Returns the black level value for a conversion with black level correction.
* @return The black level value, with range [0, 1024)
*/
inline uint16_t blackLevel() const;
/**
* Returns the white balance values for a conversion with white balance correction.
* @return The white balance values for the red, green, and blue channels, with range [0, infinity)
*/
inline const float* whiteBalance() const;
/**
* Returns whether the conversion can be approximated.
* @return True, if so
*/
inline bool allowApproximation() const;
protected:
/// The options type.
OptionsType optionsType_ = OT_DEFAULT;
/// The alpha channel value for the target image if the source image does not contain an alpha channel, with range [0, 255]
uint8_t alphaChannelTargetValue_ = 0xFFu;
/// The gamma value for a conversion with gamma correction/encoding, with range (0, 2) (OT_GAMMA_CORRECTION) or [0, infinity) (OT_BLACKLEVEL_WHITEBALANCE_GAMMA)
float gamma_ = 1.0f;
/// The black level value that is subtracted from each element of the raw image before any other operation, with range [0, 1024)
uint16_t blackLevel_ = 0u;
/// The white balancing scalars of the red, green, and blue channels (in that order), with range [0, infinity)
float whiteBalance_[3] = { 1.0f, 1.0f, 1.0f };
};
protected:
/**
* This class implements a singleton-based map for function pointers of conversion functions.
*/
class OCEAN_CV_EXPORT ConversionFunctionMap : public Singleton<ConversionFunctionMap>
{
friend class Singleton<ConversionFunctionMap>;
public:
/**
* Definition of individual types of conversion functions.
*/
enum FunctionType : uint32_t
{
/// And invalid function type.
FT_INVALID = 0u,
/// 1-plane uint8 to 1-plane uint8 conversion function.
FT_1_UINT8_TO_1_UINT8,
/// 1-plane uint8 with constant gamma correction to 1-plane uint8 conversion function.
FT_1_UINT8_GAMMA_TO_1_UINT8,
/// 1-plane uint8 to 1-plane uint8 with constant alpha channel conversion function.
FT_1_UINT8_TO_1_UINT8_ALPHA,
/// 1-plane uint8 to 1-plane uint8 conversion function with constant black level, white balance, and gamma values.
FT_1_UINT8_TO_1_UINT8_BLACKLEVEL_WHITEBALANCE_GAMMA,
/// 1-plane uint8 to 1-plane uint16 conversion function.
FT_1_UINT8_TO_1_UINT16,
/// 1-plane uint16 to 1-plane uint8 conversion function.
FT_1_UINT16_TO_1_UINT8,
/// 1-plane uint16 to 1-plane uint16 conversion function.
FT_1_UINT16_TO_1_UINT16,
/// 1-plane uint32 to 1-plane uint8 conversion function.
FT_1_UINT32_TO_1_UINT8,
/// 1-plane uint32 to 1-plane uint16 conversion function.
FT_1_UINT32_TO_1_UINT16,
/// 1-plane uint8 to 2-plane uint8 conversion function.
FT_1_UINT8_TO_2_UINT8,
/// 1-plane uint8 to 3-plane uint8 conversion function.
FT_1_UINT8_TO_3_UINT8,
/// 2-plane uint8 to 1-plane uint8 conversion function.
FT_2_UINT8_TO_1_UINT8,
/// 2-plane uint8 to 1-plane uint8 with constant alpha channel conversion function.
FT_2_UINT8_TO_1_UINT8_ALPHA,
/// 2-plane uint8 to 2-plane uint8 conversion function.
FT_2_UINT8_TO_2_UINT8,
/// 2-plane uint8 to 3-plane uint8 conversion function.
FT_2_UINT8_TO_3_UINT8,
/// 3-plane uint8 to 1-plane uint8 conversion function.
FT_3_UINT8_TO_1_UINT8,
/// 3-plane uint8 to 1-plane uint8 with constant alpha channel conversion function.
FT_3_UINT8_TO_1_UINT8_ALPHA,
/// 3-plane uint8 to 3-plane uint8 conversion function.
FT_3_UINT8_TO_3_UINT8
};
/**
* Definition of a function pointer to a conversion function with one source plane and one target plane.
*/
template <typename TSource, typename TTarget>
using OneSourceOneTargetConversionFunction = void(*)(const TSource* source, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t sourcePaddingElements, const uint32_t targetPaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with one source plane with gamma correction and one target plane.
*/
template <typename TSource, typename TTarget>
using OneSourceGammaOneTargetConversionFunction = void(*)(const TSource* source, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const float gamma, const uint32_t sourcePaddingElements, const uint32_t targetPaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with one source plane and one target plane with constant alpha value.
*/
template <typename TSource, typename TTarget>
using OneSourceOneTargetAlphaConversionFunction = void(*)(const TSource* source, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t sourcePaddingElements, const uint32_t targetPaddingElements, const uint8_t alphaValue, Worker* worker);
/**
* Definition of a function pointer to a conversion function with one source plane and one target plane with constant values for black level, white balance (red, green, blue), and gamma.
*/
template <typename TSource, typename TTarget>
using OneSourceOneTargetBlackLevelWhiteBalanceGammaConversionFunction = void(*)(const TSource* source, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint16_t blackLevelValue, const float* whiteBalanceValues, const float gamma, const uint32_t sourcePaddingElements, const uint32_t targetPaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with one source plane and two target planes.
*/
template <typename TSource, typename TTarget>
using OneSourceTwoTargetsConversionFunction = void(*)(const TSource* source, TTarget* target0, TTarget* target1, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t sourcePaddingElements, const uint32_t target0PaddingElements, const uint32_t target1PaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with one source plane and three target planes.
*/
template <typename TSource, typename TTarget>
using OneSourceThreeTargetsConversionFunction = void(*)(const TSource* source, TTarget* target0, TTarget* target1, TTarget* target2, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t sourcePaddingElements, const uint32_t target0PaddingElements, const uint32_t target1PaddingElements, const uint32_t target2PaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with two source planes and one target plane.
*/
template <typename TSource, typename TTarget>
using TwoSourcesOneTargetConversionFunction = void(*)(const TSource* source0, const TSource* source1, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t targetPaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with two source planes and one target plane with constant alpha.
*/
template <typename TSource, typename TTarget>
using TwoSourcesOneTargetAlphaConversionFunction = void(*)(const TSource* source0, const TSource* source1, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t targetPaddingElements, const uint8_t alphaValue, Worker* worker);
/**
* Definition of a function pointer to a conversion function with two source planes and two target plane.
*/
template <typename TSource, typename TTarget>
using TwoSourcesTwoTargetConversionFunction = void(*)(const TSource* source0, const TSource* source1, TTarget* target0, TTarget* target1, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t target0PaddingElements, const uint32_t target1PaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with two source planes and three target planes.
*/
template <typename TSource, typename TTarget>
using TwoSourcesThreeTargetConversionFunction = void(*)(const TSource* source0, const TSource* source1, TTarget* target0, TTarget* target1, TTarget* target2, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t targetPaddingElements0, const uint32_t targetPaddingElements1, const uint32_t targetPaddingElements2, Worker* worker);
/**
* Definition of a function pointer to a conversion function with three source planes and one target plane.
*/
template <typename TSource, typename TTarget>
using ThreeSourcesOneTargetConversionFunction = void(*)(const TSource* source0, const TSource* source1, const TSource* source2, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t source2PaddingElements, const uint32_t targetPaddingElements, Worker* worker);
/**
* Definition of a function pointer to a conversion function with three source planes and one target plane with constant alpha value.
*/
template <typename TSource, typename TTarget>
using ThreeSourcesOneTargetAlphaConversionFunction = void(*)(const TSource* source0, const TSource* source1, const TSource* source2, TTarget* target, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t source2PaddingElements, const uint32_t targetPaddingElements, const uint8_t alphaValue, Worker* worker);
/**
* Definition of a function pointer to a conversion function with three source planes and three target planes.
*/
template <typename TSource, typename TTarget>
using ThreeSourcesThreeTargetConversionFunction = void(*)(const TSource* source0, const TSource* source1, const TSource* source2, TTarget* target0, TTarget* target1, TTarget* target2, const uint32_t width, const uint32_t height, const ConversionFlag conversionFlag, const uint32_t source0PaddingElements, const uint32_t source1PaddingElements, const uint32_t source2PaddingElements, const uint32_t targetPaddingElements0, const uint32_t targetPaddingElements1, const uint32_t targetPaddingElements2, Worker* worker);
protected:
/**
* This class combines source pixel format, target pixel format, and options types.
*/
class ConversionTriple
{
public:
/**
* Helper class for a hash function.
* The separate struct is necessary for compilers like GCC.
*/
struct Hash
{
/**
* Hash function.
* @param conversionTriple The conversion triple for which the hash will be determined
* @return The hash value
*/
inline size_t operator()(const ConversionTriple& conversionTriple) const;
};
public:
/**
* Default constructor.
*/
ConversionTriple() = default;
/**
* Creates a new object.
* @param sourcePixelFormat The pixel format of the source frame, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param optionsType The type of the options for which the conversion is defined
*/
inline ConversionTriple(const FrameType::PixelFormat& sourcePixelFormat, const FrameType::PixelFormat& targetPixelFormat, const Options::OptionsType optionsType = Options::OT_DEFAULT);
/**
* Returns whether two objects are identical.
* @param conversionTriple The second object
* @return True, if so
*/
inline bool operator==(const ConversionTriple& conversionTriple) const;
public:
/// The pixel format of the source frame, must be valid
FrameType::PixelFormat sourcePixelFormat_ = FrameType::FORMAT_UNDEFINED;
/// The pixel format of the target frame, must be valid
FrameType::PixelFormat targetPixelFormat_ = FrameType::FORMAT_UNDEFINED;
/// The type of the options for which the conversion is defined
Options::OptionsType optionsType_ = Options::OT_DEFAULT;
};
/**
* This class is a wrapper for function pointers.
*/
class FunctionWrapper
{
friend class ConversionFunctionMap;
public:
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_GAMMA_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceGammaOneTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_1_UINT8_ALPHA function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetAlphaConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_1_UINT8_BLACKLEVEL_WHITEBALANCE_GAMMA function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetBlackLevelWhiteBalanceGammaConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_1_UINT16 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint8_t, uint16_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT16_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint16_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT16_TO_1_UINT16 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint16_t, uint16_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT32_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint32_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT32_TO_1_UINT16 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceOneTargetConversionFunction<uint32_t, uint16_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_2_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceTwoTargetsConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_1_UINT8_TO_3_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const OneSourceThreeTargetsConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_2_UINT8_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const TwoSourcesOneTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_2_UINT8_TO_1_UINT8_ALPHA function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const TwoSourcesOneTargetAlphaConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_2_UINT8_TO_2_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const TwoSourcesTwoTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_2_UINT8_TO_3_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const TwoSourcesThreeTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_3_UINT8_TO_1_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const ThreeSourcesOneTargetConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_3_UINT8_TO_1_UINT8_ALPHA function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const ThreeSourcesOneTargetAlphaConversionFunction<uint8_t, uint8_t> function);
/**
* Creates a new wrapper object and stores a function pointer to a FT_3_UINT8_TO_3_UINT8 function.
* @param function The pointer to the conversion function, must be valid
*/
FunctionWrapper(const ThreeSourcesThreeTargetConversionFunction<uint8_t, uint8_t> function);
protected:
/// The function pointer of the conversion function.
const void* function_;
/// The type of the conversion function.
const FunctionType functionType_;
};
/**
* Definition of a map mapping pairs or pixel formats to function pointers.
*/
using FormatPair2FunctionWrapperMap = std::unordered_map<ConversionTriple, FunctionWrapper, ConversionTriple::Hash>;
public:
/**
* Returns the function pointer for a source and target pixel format.
* @param sourcePixelFormat The pixel format of the source frame, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param functionType The resulting type of the conversion function
* @param options The options for the conversion
* @return The function pointer, nullptr if the combination of source and target pixel format is not supported
*/
const void* function(const FrameType::PixelFormat& sourcePixelFormat, const FrameType::PixelFormat& targetPixelFormat, FunctionType& functionType, const Options& options) const;
protected:
/**
* Creates a new map object and initializes all function pointers.
*/
ConversionFunctionMap();
protected:
/// The map mapping pairs or pixel formats to function pointers.
FormatPair2FunctionWrapperMap formatPair2FunctionWrapperMap_;
};
protected:
/**
* Definition of a function pointer to a function able to convert one image row from one generic pixel format to another generic pixel format.
* @param sourceRow The row in the source frame, must be valid
* @param targetRow The row in the target frame, must be valid
* @param width The number of pixels to convert, with range [1, infinity)
* @param options Optional options which are necessary for the conversion, otherwise nullptr
* @tparam TSource The data type of each source pixel channel, e.g., 'uint8_t' or 'float'
* @tparam TTarget The data type of each target pixel channel, e.g., 'uint8_t' or 'float'
*/
template <typename TSource, typename TTarget>
using RowConversionFunction = void (*)(const TSource* sourceRow, TTarget* targetRow, const size_t width, const void* options);
/**
* Definition of a function pointer to a function able to convert multiple image row from an arbitrary pixel format to another arbitrary pixel format.
* @param sources The memory pointers defining the source rows, must be valid
* @param targets The memory pointers defining the target rows, must be valid
* @param multipleRowIndex The index of the rows to be converted, with range [0, height / multipleRowsPerIteration - 1]
* @param width The width of the frame in pixel, with range [1, infinity)
* @param height The height of the frame in pixel, with range [1, infinity)
* @param conversionFlag The conversion to be applied
* @param options Optional options which are necessary for the conversion, otherwise nullptr
*/
using MultipleRowsConversionFunction = void (*)(const void** sources, void** targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void* options);
/**
* Definition of a function pointer to a function able to reverse the order of pixels in an image row with a generic pixel format.
* @param inputRow The row to reverse, must be valid
* @param targetRow The row receiving the reversed pixels, must be different from 'inputRow', must be valid
* @param width The number of pixels to reverse, with range [1, infinity)
* @tparam T The data type of each pixel channel, e.g., 'uint8_t' or 'float'
*/
template <typename T>
using RowReversePixelOrderFunction = void (*)(const T* inputRow, T* targetRow, const size_t width);
/**
* Definition of a function pointer to a function able to reverse the order of pixels in an image row with a generic pixel format in-place.
* @param row The row to reverse, must be valid
* @param width The number of pixels to reverse, with range [1, infinity)
* @tparam T The data type of each pixel channel, e.g., 'uint8_t' or 'float'
*/
template <typename T>
using RowReversePixelOrderInPlaceFunction = void (*)(T* row, const size_t width);
/**
* Definition of the parameters used by the function for row-wise conversion of RGGB14_PACKED to RGB24/BGR24
*/
struct RGGB10ToRGB24AdvancedOptions
{
/// The black level that needs to be subtracted from the unpacked pixel values, with range [0, 1024)
uint16_t blackLevel = 0u;
/// The white balance factors for the red, green, and blue channel as 7 bit fixed-point numbers; the order of the channels is the same as in the target frame
unsigned int whiteBalance7[3] = { 128u, 128u, 128u };
/// Pointer to the gamma lookup-table, cf. `FrameConverterY10_Packed::LookupTableManager`
const uint8_t* gammaLookupValues = nullptr;
/// The number of padding elements of the source frame
unsigned int sourcePaddingElements = 0u;
/// The number of padding elements of the target frame
unsigned int targetPaddingElements = 0u;
};
public:
/**
* The following comfort class provides comfortable functions simplifying prototyping applications but also increasing binary size of the resulting applications.
* Best practice is to avoid using these functions if binary size matters,<br>
* as for every comfort function a corresponding function exists with specialized functionality not increasing binary size significantly.<br>
*/
class OCEAN_CV_EXPORT Comfort
{
public:
/**
* Returns whether the convert function of this class supports the conversion of a frame with one pixel format to a new frame with other pixel format.
* @param sourceType The frame type of the source frame, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param targetPixelOrigin The pixel origin of the target frame, ORIGIN_INVALID to use the pixel origin of the source frame
* @param options The options to be used for conversion
* @return True, if so
* @see convert().
*/
static bool isSupported(const FrameType& sourceType, const FrameType::PixelFormat targetPixelFormat, const FrameType::PixelOrigin targetPixelOrigin = FrameType::ORIGIN_INVALID, const Options& options = Options());
/**
* Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension, but different pixel format or pixel origin.
* @param source The source frame to convert, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param targetPixelOrigin The pixel origin of the target frame, must be valid
* @param target The resulting target frame, the frame will be modified if the frame type is not compatible, or if the target frame is not owner of the frame data, or if the target frame is a read-only frame, can be invalid
* @param forceCopy True, if the resulting target image is expected to be the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*
* Here is an example showing how to use this function:
* @code
* bool function(const Frame& anyFrame)
* {
* // we do not know which pixel format (and pixel origin) the given frame has
* // however, we know that we need e.g., a grayscale frame with 8 bit and pixel origin in the upper left corner of the target frame
*
* Frame yFrame;
* if (!FrameConverter::Comfort::convert(anyFrame, FrameType::FORMAT_Y8, FrameType::ORIGIN_UPPER_LEFT, yFrame, FrameConverter::CP_AVOID_COPY_IF_POSSIBLE)) // we try to avoid a copy if possible
* {
* // the given frame could not be converted into a Y8 frame, so we stop here
* return false;
* }
*
* // from now on we have access to a Y8 frame, it may be
* // - a frame not owning the frame data but referencing the memory only (in case 'anyFrame' provided a plain Y8 block)
* // - a frame owning the frame data if the given image was converted to a Y8 frame
*
* // we can use the memory as long as anyFrame exists
* const uint8_t* data = yFrame.constdata<uint8_t>();
*
* // do something here
*
* return true;
* }
* @endcode
* @see isSupported(), convertAndCopy().
*/
static bool convert(const Frame& source, const FrameType::PixelFormat targetPixelFormat, const FrameType::PixelOrigin targetPixelOrigin, Frame& target, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension and pixel origin, but different pixel format.
* @param source The source frame to convert, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param target The resulting target frame, the frame will be modified if the frame type is not compatible, or if the target frame is not owner of the frame data, or if the target frame is a read-only frame, can be invalid
* @param forceCopy True, if the resulting target image is expected to be the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*
* Here is an example showing how to use this function:
* @code
* bool function(const Frame& anyFrame)
* {
* // we do not know which pixel format (and pixel origin) the given frame has
* // however, we know that we need e.g., a grayscale frame with 8 bit with any pixel origin
*
* Frame yFrame;
* if (!FrameConverter::Comfort::convert(anyFrame, FrameType::FORMAT_Y8, yFrame, FrameConverter::CP_AVOID_COPY_IF_POSSIBLE)) // we try to avoid a copy if possible
* {
* // the given frame could not be converted into a Y8 frame, so we stop here
* return false;
* }
*
* // from now on we have access to a Y8 frame, it may be
* // - a frame not owning the frame data but referencing the memory only (in case 'anyFrame' provided a plain Y8 block)
* // - a frame owning the frame data if the given image was converted to a Y8 frame
*
* // we can use the memory as long as anyFrame exists
* const uint8_t* data = yFrame.constdata<uint8_t>();
*
* // do something here
*
* return true;
* }
* @endcode
* @see isSupported(), convertAndCopy().
*/
static inline bool convert(const Frame& source, const FrameType::PixelFormat targetPixelFormat, Frame& target, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension and pixel format, but different pixel origin.
* @param source The source frame to convert, must be valid
* @param targetPixelOrigin The pixel origin of the target frame, must be valid
* @param target The resulting target frame, the frame will be modified if the frame type is not compatible, or if the target frame is not owner of the frame data, or if the target frame is a read-only frame, can be invalid
* @param forceCopy True, if the resulting target image is expected to be the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
* @see isSupported(), convertAndCopy().
*/
static inline bool convert(const Frame& source, const FrameType::PixelOrigin targetPixelOrigin, Frame& target, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension but different pixel format or pixel origin.
* This function does always copy the memory to the already existing memory of the target frame.
* @param source The source frame to convert, must be valid
* @param target The target frame which will receive the converted source image information, must contain writable memory, must be valid
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*
* Here is an example showing how to use this function:
* @code
* bool function(const Frame& anySourceFrame)
* {
* uint8_t* targetMemoryRGB24 = ...;
* const unsigned int targetMemoryPaddingElements = ...;
*
* const FrameType targetFrameType(anySourceFrame.width(), anySourceFrame.height(), FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT);
*
* Frame targetFrame(targetFrameType, targetMemoryRGB24, Frame::CM_USE_KEEP_LAYOUT, targetMemoryPaddingElements);
*
* if (!FrameConverter::Comfort::convertAndCopy(anySourceFrame, targetFrame))
* {
* // there is no converter from the source pixel format to the target pixel format, so we stop here
* return false;
* }
*
* // do something here with the RGB memory in `targetMemoryRGB24`
*
* return true;
* }
* @endcode
* @see isSupported(), convert().
*/
static bool convertAndCopy(const Frame& source, Frame& target, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts / changes a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension but different pixel format or pixel origin.
* @param frame The frame to convert, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param targetPixelOrigin The pixel origin of the target frame, must be valid
* @param forceCopy True, if the resulting target image is expected to are the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*/
static inline bool change(Frame& frame, const FrameType::PixelFormat targetPixelFormat, const FrameType::PixelOrigin targetPixelOrigin, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts / changes a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension and same pixel origin but different pixel format.
* @param frame The frame to convert, must be valid
* @param targetPixelFormat The pixel format of the target frame, must be valid
* @param forceCopy True, if the resulting target image is expected to are the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*/
static inline bool change(Frame& frame, const FrameType::PixelFormat targetPixelFormat, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
/**
* Converts / changes a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same dimension and same pixel format but different pixel origin.
* @param frame The frame to convert, must be valid
* @param targetPixelOrigin The pixel origin of the target frame, must be valid
* @param forceCopy True, if the resulting target image is expected to are the owner of the image data, otherwise the source frame will be the owner of the image data if possible
* @param worker Optional worker object to distribute the conversion computation to different CPU cores
* @param options The options to be used for conversion
* @return True, if the frame type conversion is supported and succeeded
*/
static inline bool change(Frame& frame, const FrameType::PixelOrigin targetPixelOrigin, const bool forceCopy = true, Worker* worker = nullptr, const Options& options = Options());
protected:
/**
* Converts frames with compatible formats that do not require an actual conversion, either memory is copied or used.
* @param source The source frame to convert, must be valid
* @param targetType The target frame type, must be valid
* @param target The resulting target frame, will be modified if conversion is supported
* @param forceCopy True, to force copying of frame data; False, to allow referencing source data when possible
* @return True, if the conversion was handled by this function; False, if a different conversion method is needed
*/
static bool convertCompatibleFormats(const Frame& source, const FrameType& targetType, Frame& target, const bool forceCopy);
/**
* Converts frames using a registered conversion function from the ConversionFunctionMap.
* This function looks up and applies optimized, format-specific conversion functions
* that have been registered in the conversion function map (e.g., YUV to RGB, format-specific conversions).
* @param source The source frame to convert, must be valid
* @param targetType The target frame type, must be valid
* @param target The resulting target frame, will be modified if conversion is supported
* @param options The conversion options (e.g., alpha channel value, gamma correction)
* @param worker Optional worker object to distribute computation across multiple CPU cores
* @return True, if a registered conversion function exists and was applied successfully; False, otherwise
*/
static bool convertWithConversionFunction(const Frame& source, const FrameType& targetType, Frame& target, const Options& options, Worker* worker);
/**
* Converts frames with generic pixel formats.
* @param source The source frame to convert, must be valid
* @param targetType The target frame type, must be valid
* @param target The resulting target frame, will be modified if conversion is supported
* @param worker Optional worker object to distribute computation across multiple CPU cores
* @return True, if the conversion was successful; False, otherwise
*/
static bool convertGenericFormats(const Frame& source, const FrameType& targetType, Frame& target, Worker* worker);
};
/**
* Casts the pixel values from one frame type to another frame type.
* The source frame must be a zipped frame e.g., FrameType::FORMAT_Y8, FrameType::FORMAT_RGB24, ...<br>
* Beware: This function does not handle any out of range issues and does not apply rounding.<br>
* This function mainly does the following:
* @code
* for each pixel and channel:
* targetValue = TTarget(sourceValue)
* @endcode
* @param source The source frame to be casted, must be valid
* @param target The target frame receiving the casted pixel values, must be valid (and not overlap the source frame)
* @param width The width of the source (and target frame) in pixel, with range [1, infinity)
* @param height The height of the source (and target frame) in pixel, with range [1, infinity)
* @param channels The number of channels the source frame (and target frame) has, with range [1, infinity)
* @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
* @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
* @tparam TSource The data type of each pixel channel of the source frame, e.g., 'uint8_t', 'int', 'float', ...
* @tparam TTarget The data type of each pixel channel of the target frame, e.g., 'uint8_t', 'int', 'float', ...
*
* Here is an example how to use this function:
* @code
* void function()
* {
* // we have a source frame e.g., with pixel format RGB 24 bit, 'uint8_t' for each pixel channel
* Frame sourceFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
*
* // set the pixel values of sourceFrame here ...
*
* // we want to cast this frame to a frame with 32 bit floating point values
* // we use the frame type of the source as pattern and change the pixel format only
* Frame targetFrame(FrameType(sourceFrame, FrameType::genericPixelFormat(FrameType::DT_SIGNED_FLOAT_32, 3u)));
*
* // now we simply cast the values from the source frame to the target frame
* FrameConverter::cast<uint8_t, float>(sourceFrame.constdata<uint8_t>(), targetFrame.data<float>(), sourceFrame.width(), sourceFrame.height(), sourceFrame.channels());
*
* // now we can access the floating point pixel values of target
* const float* floatRGBValues = targetFrame.constdata<float>();
* }
* @endcode
* @see normalizedCast().
*/
template <typename TSource, typename TTarget>
static void cast(const TSource* __restrict source, TTarget* __restrict target, const unsigned int width, const unsigned int height, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements);
/**
* Casts the pixel values from one frame type to another frame type but also normalizes the casted source values before assigning them (by scaling and offsetting).
* The source frame must be a zipped frame e.g., FrameType::FORMAT_Y8, FrameType::FORMAT_RGB24, ...<br>
* Beware: This function does not handle any out of range issues and does not apply rounding.<br>
* This function mainly does the following:
* @code
* for each pixel and channel:
* targetValue = TTarget(sourceValue) * multiplicationFactor + offset
* @endcode
* @param source The source frame to be casted, must be valid
* @param target The target frame receiving the casted pixel values, must be valid (and not overlap the source frame)
* @param width The width of the source (and target frame) in pixel, with range [1, infinity)
* @param height The height of the source (and target frame) in pixel, with range [1, infinity)
* @param channels The number of channels the source frame (and target frame) has, with range [1, infinity)
* @param multiplicationFactor The multiplication factor (with data type TTarget) which will be multiplied with each source values before the value is assigned, should not be zero
* @param offset The offset (with data type TTarget) that is added to each value after the conversion
* @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
* @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
* @tparam TSource The data type of each pixel channel of the source frame, e.g., 'uint8_t', 'int', 'float', ...
* @tparam TTarget The data type of each pixel channel of the target frame, e.g., 'uint8_t', 'int', 'float', ...
*
* Here is an example how to use this function:
* @code
* void function()
* {
* // we have a source frame e.g., with pixel format RGB 24 bit, 'uint8_t' for each pixel channel
* Frame sourceFrame(FrameType(1920u, 1080u, FrameType::FORMAT_RGB24, FrameType::ORIGIN_UPPER_LEFT));
*
* // set the pixel values of sourceFrame here ...
*
* // we want to cast this frame to a frame with 32 bit floating point values
* // we use the frame type of the source as pattern and change the pixel format only
* Frame targetFrame(FrameType(sourceFrame, FrameType::genericPixelFormat(FrameType::DT_SIGNED_FLOAT_32, 3u)));
*
* // now we normalize the source values by 1/255 and assign the values - so that we get floating point values with range [0, 1]
* FrameConverter::normalizedCast<uint8_t, float>(sourceFrame.constdata<uint8_t>(), targetFrame.data<float>(), sourceFrame.width(), sourceFrame.height(), sourceFrame.channels(), 1.0f / 255.0f, 0);
*
* // now we can access the normalized floating point pixel values of target
* const float* floatRGBValues = targetFrame.constdata<float>();
* }
* @endcode
* @see cast().
*/
template <typename TSource, typename TTarget>
static void normalizedCast(const TSource* __restrict source, TTarget* __restrict target, const unsigned int width, const unsigned int height, const unsigned int channels, const TTarget multiplicationFactor, const TTarget offset, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements);
/**
* Copies a sub-frame of a given frame into a second frame while both frames might have an individual number of padding elements at the end of each row.
* The dimension of the sub-frame must fit into the source and target frame.
* @param source The source frame from which the sub-frame will be copied, must be valid
* @param target The target frame to which the sub-frame will be copied, must be valid
* @param sourceWidth Width of the entire source frame in pixels, with range [1, infinity)
* @param sourceHeight Height of the entire source frame in pixels, with range [1, infinity)
* @param targetWidth Width of the entire target frame in pixels, with range [1, infinity)
* @param targetHeight Height of the entire target frame in pixels, with range [1, infinity)
* @param channels Number of data channels of the given source (and target) frame, with range [1, infinity)
* @param sourceLeft Horizontal start position of the sub-frame inside the source frame in pixels, with range [0, sourceWidth - 1]
* @param sourceTop Vertical start position of the sub-frame inside the source frame in pixels, with range [0, sourceHeight - 1]
* @param targetLeft Horizontal start position of the sub-frame inside the target frame in pixels, with range [0, targetWidth -1]
* @param targetTop Vertical start position of the sub-frame inside the target frame in pixels, with range [0, targetHeight - 1]
* @param width The width of the sub-frame in pixel, with range [1, min(sourceWidth - sourceLeft, targetWidth - targetLeft)]
* @param height The height of the sub-frame in pixel, with range [1, min(sourceHeight - sourceTop, targetHeight - targetTop)]
* @param sourcePaddingElements Optional number of padding elements at the end of each source row, with range [0, infinity)
* @param targetPaddingElements Optional number of padding elements at the end of each target row, with range [0, infinity)
* @return True, if succeeded
* @tparam T The data type of each element
*/
template <typename T>
static bool subFrame(const T* source, T* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int channels, const unsigned int sourceLeft, const unsigned int sourceTop, const unsigned int targetLeft, const unsigned int targetTop, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements);
/**
* Copies pixels from one sub-frame to another if the pixels are part of a mask; input may use padding.
* The behavior of this function can be described as:
* <pre>
* target[i] = mask[i] == maskValue ? source[i] : target[i]
* </pre>
* The dimension of the sub-frame must fit into the source and target frame. The mask must have the same size as the sub-frame.
* @param sourceFrame The source frame from which the sub-frame will be copied, must be valid
* @param targetFrame The target frame to which the sub-frame will be copied, must be valid
* @param maskFrame The binary mask that is used to indicate which source pixels to copy to the target frame, must be valid, have one channel, and have the same size of the region that is copied (`subFrameWidth` x `subFrameHeight`)
* @param sourceLeft Horizontal start position of the sub-frame inside the source frame in pixels, with range [0, sourceWidth - 1]
* @param sourceTop Vertical start position of the sub-frame inside the source frame in pixels, with range [0, sourceHeight - 1]
* @param targetLeft Horizontal start position of the sub-frame inside the target frame in pixels, with range [0, targetWidth -1]
* @param targetTop Vertical start position of the sub-frame inside the target frame in pixels, with range [0, targetHeight - 1]
* @param subFrameWidth Width of the sub-frame in pixel, with range [0, min(sourceWidth - sourceLeft, targetWidth - targetLeft)]
* @param subFrameHeight Height of the sub-frame in pixel, with range [1, min(sourceHeight - sourceTop, targetHeight - targetTop)]
* @param maskValue Optional value which indicates which pixel value should be interpreted as the foreground (and copied)
* @return True, if succeeded
* @tparam T The data type of the elements of the source and target frames
*/
template <typename T>
static bool subFrameMask(const Frame& sourceFrame, Frame& targetFrame, const Frame& maskFrame, const uint32_t sourceLeft, const uint32_t sourceTop, const uint32_t targetLeft, const uint32_t targetTop, const uint32_t subFrameWidth, const uint32_t subFrameHeight, const uint8_t maskValue = 0u);
/**
* Copies pixels from one sub-frame to another if the pixels are part of a mask; input may use padding.
* The behavior of this function can be described as:
* <pre>
* target[i] = mask[i] == maskValue ? source[i] : target[i]
* </pre>
* The dimension of the sub-frame must fit into the source and target frame. The mask must have the same size as the sub-frame.
* @param source The source frame from which the sub-frame will be copied, must be valid
* @param target The target frame to which the sub-frame will be copied, must be valid
* @param mask The binary mask that is used to indicate which source pixels to copy to the target frame, must be valid, have one channel, and have the same size of the region that is copied (`subFrameWidth` x `subFrameHeight`)
* @param sourceWidth Width of the entire source frame in pixels, with range [1, infinity)
* @param sourceHeight Height of the entire source frame in pixels, with range [1, infinity)
* @param targetWidth Width of the entire target frame in pixels, with range [1, infinity)
* @param targetHeight Height of the entire target frame in pixels, with range [1, infinity)
* @param channels Number of data channels of the given source (and target) frame, with range [1, infinity)
* @param sourceLeft Horizontal start position of the sub-frame inside the source frame in pixels, with range [0, sourceWidth - 1]