MeVisLab Toolbox Reference
mlTypedHandlers.h
Go to the documentation of this file.
1/*************************************************************************************
2**
3** Copyright 2009, MeVis Medical Solutions AG
4**
5** The user may use this file in accordance with the license agreement provided with
6** the Software or, alternatively, in accordance with the terms contained in a
7** written agreement between the user and MeVis Medical Solutions AG.
8**
9** For further information use the contact form at https://www.mevislab.de/contact
10**
11**************************************************************************************/
12
13#ifndef ML_TYPED_HANDLERS_H
14#define ML_TYPED_HANDLERS_H
15
16#include "mlInitSystemML.h"
17
18#include "mlTSubImage.h"
19#include "mlModuleInterfaces.h"
20#include "mlTypeTraits.h"
22#include "mlPagedImage.h"
23
24// Deprecated macros that do nothing, should be removed in a future version:
25#define MLCarrierForType(TYPE) TYPE
26#define MLCarrierInForType(TYPE) TYPE
27
28// Warn users about the above macros:
29#if defined(WIN32)
30#pragma deprecated("MLCarrierForType")
31#pragma deprecated("MLCarrierInForType")
32#endif
33
34ML_START_NAMESPACE
35
36//---------------------------------------------------------------------------
39//---------------------------------------------------------------------------
40
44#define ML_N_INPUTS 0x4000
45
47#define _ML_SWITCH_SELECT_OFFSET 32768
48
50#define _ML_OUTPUTINDEX -1
51
62
64
92};
93
94namespace internal {
95
96#ifndef DOXYGEN_SHOULD_SKIP_THIS
97
98//-------------------------------------------------------------------------------------------------
99
101template <int select, typename Types>
102struct SwitchOrFixedTypeSelector {
103 typedef typename DataTypeSelector<select>::Type Type;
104 typedef TSubImage<Type> SubImageType;
105};
106
107// Specializations for SwitchOrFixedTypeSelector
108template <typename Types>
109struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+0, Types> {
110 typedef typename Types::T0 Type;
111 typedef TSubImage<Type> SubImageType;
112};
113template <typename Types>
114struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+1, Types> {
115 typedef typename Types::T1 Type;
116 typedef TSubImage<Type> SubImageType;
117};
118template <typename Types>
119struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+2, Types> {
120 typedef typename Types::T2 Type;
121 typedef TSubImage<Type> SubImageType;
122};
123template <typename Types>
124struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+3, Types> {
125 typedef typename Types::T3 Type;
126 typedef TSubImage<Type> SubImageType;
127};
128template <typename Types>
129struct SwitchOrFixedTypeSelector<_ML_SWITCH_SELECT_OFFSET+10, Types> {
130 typedef void Type;
131 typedef SubImage SubImageType;
132};
133
134//-------------------------------------------------------------------------------------------------
135
137template <int shouldBeConst, typename InType>
138struct ConstTypeSelector {};
139
140// Specializations for ConstTypeSelector,
141template <typename InType>
142struct ConstTypeSelector<0, InType> { typedef InType Type; };
143template <typename InType>
144struct ConstTypeSelector<1, InType> { typedef const InType Type; };
145
146//-------------------------------------------------------------------------------------------------
147
149template <int v>
150class InputImagesCount {
151public:
152 enum {
153 count = v
154 };
155};
156
157//------------------------------------------------------------------------------------------
158
160struct CalculateOutputSubImageArguments {
162 CalculateOutputSubImageArguments() {
163 outImg = nullptr;
164 inImgs = nullptr;
165 userThreadData = nullptr;
166 }
167
169 CalculateOutputSubImageArguments(SubImage* outImage, SubImage* inImages, UserThreadData* threadData) {
170 outImg = outImage;
171 inImgs = inImages;
172 userThreadData = threadData;
173 }
174
175 // Members are intentionally public, since this is used as replacement for individual arguments.
176 SubImage* outImg;
177 SubImage* inImgs;
178 UserThreadData* userThreadData;
179 int variableDataType[4];
180};
181
182//------------------------------------------------------------------------------------------
183
185template<typename InT0, typename InT1, typename InT2, typename InT3>
186struct TypeTuple4 {
187 typedef InT0 T0;
188 typedef InT1 T1;
189 typedef InT2 T2;
190 typedef InT3 T3;
191};
192
194struct EmptyType {};
195
197typedef TypeTuple4<EmptyType, EmptyType, EmptyType, EmptyType> EmptyTypeTuple4;
198
201template <int position, typename T, typename Tuple>
202struct TypeTuple4Insert {};
203
204// Specializations of TypeTuple4Insert for four positions.
205template <typename T, typename Tuple>
206struct TypeTuple4Insert<0, T, Tuple> {
207 typedef TypeTuple4<T, T, T, T> Type;
208};
209template <typename T, typename Tuple>
210struct TypeTuple4Insert<1, T, Tuple> {
211 typedef TypeTuple4<typename Tuple::T0, T, T, T> Type;
212};
213template <typename T, typename Tuple>
214struct TypeTuple4Insert<2, T, Tuple> {
215 typedef TypeTuple4<typename Tuple::T0, typename Tuple::T1, T, T> Type;
216};
217template <typename T, typename Tuple>
218struct TypeTuple4Insert<3, T, Tuple> {
219 typedef TypeTuple4<typename Tuple::T0, typename Tuple::T1, typename Tuple::T2, T> Type;
220};
221
222#endif // of DOXYGEN_SHOULD_SKIP_THIS
223
224#ifndef DOXYGEN_SHOULD_SKIP_THIS
225
228MLEXPORT void setupKnownPagedImgProperties(PagedImage* outImg, int templateNumImages, int outputType, const int inputTypes[10], const int inputReadOnly[10], int numVariableTypes, const int variableTypes[4]);
229
232MLEXPORT void verifyPagedImgProperties(PagedImage* outImg, int templateNumImages, int outputType, const int inputTypes[10], const int inputReadOnly[10], int numVariableTypes, const int variableTypes[4], int resultDataTypes[4]);
233
234#endif // of DOXYGEN_SHOULD_SKIP_THIS
235
236//-----------------------------------------------------------------------------------------------------
237
239
243template<class BaseClass, class Derived, int NumberOfInputImages>
244class TypedHandlerBase : public BaseClass {
245
246public:
247 // Defines the preconfigured static selection of types and their properties.
248 enum {
249 // Enums to be overwritten by user
250 OutputSubImage_Type = MLVariableType0,
251 InputSubImage0_Type = MLVariableType1,
252 InputSubImage1_Type = MLVariableType2,
253 InputSubImage2_Type = MLVariableType3,
254 InputSubImage3_Type = MLVariableType3,
255 InputSubImage4_Type = MLVariableType3,
256 InputSubImage5_Type = MLVariableType3,
257 InputSubImage6_Type = MLVariableType3,
258 InputSubImage7_Type = MLVariableType3,
259 InputSubImage8_Type = MLVariableType3,
260 InputSubImage9_Type = MLVariableType3,
261
262 InputSubImage0_ReadOnly = true,
263 InputSubImage1_ReadOnly = true,
264 InputSubImage2_ReadOnly = true,
265 InputSubImage3_ReadOnly = true,
266 InputSubImage4_ReadOnly = true,
267 InputSubImage5_ReadOnly = true,
268 InputSubImage6_ReadOnly = true,
269 InputSubImage7_ReadOnly = true,
270 InputSubImage8_ReadOnly = true,
271 InputSubImage9_ReadOnly = true,
272 };
273
274 TypedHandlerBase() {
275 setupVariableTypes(_variableTypeIndex);
276 }
277
278private:
280 int _variableTypeIndex[4];
281
283 static void setupVariableTypes(int variableTypeIndex[4]) {
284 const int inputTypes[10] = {
285 Derived::InputSubImage0_Type, Derived::InputSubImage1_Type, Derived::InputSubImage2_Type, Derived::InputSubImage3_Type, Derived::InputSubImage4_Type,
286 Derived::InputSubImage5_Type, Derived::InputSubImage6_Type, Derived::InputSubImage7_Type, Derived::InputSubImage8_Type, Derived::InputSubImage9_Type };
287 for (int i=0;i<Derived::getNumVariableTypes();i++) {
288 // use output image as default
289 variableTypeIndex[i] = _ML_OUTPUTINDEX;
290 // find the first image that uses variable type i, either the output or one of the inputs
291 if (Derived::OutputSubImage_Type == MLVariableType0 + i) {
292 variableTypeIndex[i] = _ML_OUTPUTINDEX;
293 } else {
294 // for the purpose of the below loop, treat ML_N_INPUTS as 1
295 const int numInputs = (NumberOfInputImages==ML_N_INPUTS)?1:NumberOfInputImages;
296 for (int j=0;j<numInputs;j++) {
297 if (inputTypes[j] == MLVariableType0 + i) {
298 variableTypeIndex[i] = j;
299 break;
300 }
301 }
302 }
303 }
304 }
305
306public:
307
309 void calculateOutputSubImage(SubImage* outImg, SubImage* inImgs, UserThreadData* userThreadData) override {
310 // Put arguments in struct to facilitate passing them through.
311 CalculateOutputSubImageArguments args(outImg, inImgs, userThreadData);
312
313 // Detect the correct data type for up to 4 variable types (loop length is compile time!)
314 for (int i=0; i<Derived::getNumVariableTypes(); i++) {
315 args.variableDataType[i] = (_variableTypeIndex[i] == _ML_OUTPUTINDEX) ?
316 args.outImg->getDataType() : args.inImgs[_variableTypeIndex[i]].getDataType();
317 }
318
319 // Start the switching, which will call back to helperCalculateOutputSubImage below when all types are switched.
320 static_cast<Derived*>(this)->doSwitching(args);
321 }
322
323#ifndef DOXYGEN_SHOULD_SKIP_THIS
324
325 template<typename Types>
326 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args) {
327 // we collected up to 4 types in Types, now delegate to specific method for NumberOfInputImages
328 helperCalculateOutputSubImage<Types>(args, static_cast<InputImagesCount<NumberOfInputImages>*>(nullptr));
329 }
330
331 template<typename Types>
332 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<ML_N_INPUTS>*) {
333 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::Type OUTTYPE;
334 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::Type INTYPE0;
335 TSubImage<OUTTYPE> outTSubImg(*args.outImg);
336 typedef typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, TSubImage<INTYPE0> >::Type INTSUBIMG0;
337 // Cast inImgs to TSubImage!
338 INTSUBIMG0* inTSubImgs = tsubimage_cast<INTYPE0>(args.inImgs);
339 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImgs, args.userThreadData);
340 }
341
342 template<typename Types>
343 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<0>*) {
344 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
345 OUTIMAGETYPE outTSubImg(*args.outImg);
346 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, args.userThreadData);
347 }
348
349 template<typename Types>
350 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<1>*) {
351 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
352 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
353 OUTIMAGETYPE outTSubImg(*args.outImg);
354 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
355 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, args.userThreadData);
356 }
357
358 template<typename Types>
359 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<2>*) {
360 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
361 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
362 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
363 OUTIMAGETYPE outTSubImg(*args.outImg);
364 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
365 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
366 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, args.userThreadData);
367 }
368
369 template<typename Types>
370 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<3>*) {
371 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
372 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
373 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
374 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
375 OUTIMAGETYPE outTSubImg(*args.outImg);
376 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
377 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
378 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
379 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, args.userThreadData);
380 }
381
382 template<typename Types>
383 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<4>*) {
384 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
385 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
386 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
387 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
388 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
389 OUTIMAGETYPE outTSubImg(*args.outImg);
390 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
391 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
392 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
393 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
394 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, args.userThreadData);
395 }
396
397 template<typename Types>
398 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<5>*) {
399 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
400 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
401 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
402 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
403 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
404 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
405 OUTIMAGETYPE outTSubImg(*args.outImg);
406 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
407 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
408 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
409 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
410 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
411 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, args.userThreadData);
412 }
413
414 template<typename Types>
415 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<6>*) {
416 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
417 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
418 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
419 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
420 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
421 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
422 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
423 OUTIMAGETYPE outTSubImg(*args.outImg);
424 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
425 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
426 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
427 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
428 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
429 typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
430 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, args.userThreadData);
431 }
432
433 template<typename Types>
434 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<7>*) {
435 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
436 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
437 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
438 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
439 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
440 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
441 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
442 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
443 OUTIMAGETYPE outTSubImg(*args.outImg);
444 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
445 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
446 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
447 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
448 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
449 typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
450 typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
451 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, args.userThreadData);
452 }
453
454 template<typename Types>
455 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<8>*) {
456 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
457 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
458 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
459 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
460 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
461 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
462 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
463 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
464 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
465 OUTIMAGETYPE outTSubImg(*args.outImg);
466 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
467 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
468 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
469 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
470 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
471 typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
472 typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
473 typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
474 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, args.userThreadData);
475 }
476
477 template<typename Types>
478 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<9>*) {
479 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
480 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
481 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
482 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
483 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
484 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
485 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
486 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
487 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
488 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage8_Type, Types>::SubImageType INIMAGETYPE8;
489 OUTIMAGETYPE outTSubImg(*args.outImg);
490 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
491 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
492 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
493 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
494 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
495 typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
496 typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
497 typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
498 typename ConstTypeSelector<Derived::InputSubImage8_ReadOnly, INIMAGETYPE8>::Type inTSubImg8(args.inImgs[8]);
499 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, inTSubImg8, args.userThreadData);
500 }
501
502 template<typename Types>
503 void helperCalculateOutputSubImage(const CalculateOutputSubImageArguments& args, InputImagesCount<10>*) {
504 typedef typename SwitchOrFixedTypeSelector<Derived::OutputSubImage_Type, Types>::SubImageType OUTIMAGETYPE;
505 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage0_Type, Types>::SubImageType INIMAGETYPE0;
506 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage1_Type, Types>::SubImageType INIMAGETYPE1;
507 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage2_Type, Types>::SubImageType INIMAGETYPE2;
508 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage3_Type, Types>::SubImageType INIMAGETYPE3;
509 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage4_Type, Types>::SubImageType INIMAGETYPE4;
510 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage5_Type, Types>::SubImageType INIMAGETYPE5;
511 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage6_Type, Types>::SubImageType INIMAGETYPE6;
512 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage7_Type, Types>::SubImageType INIMAGETYPE7;
513 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage8_Type, Types>::SubImageType INIMAGETYPE8;
514 typedef typename SwitchOrFixedTypeSelector<Derived::InputSubImage9_Type, Types>::SubImageType INIMAGETYPE9;
515 OUTIMAGETYPE outTSubImg(*args.outImg);
516 typename ConstTypeSelector<Derived::InputSubImage0_ReadOnly, INIMAGETYPE0>::Type inTSubImg0(args.inImgs[0]);
517 typename ConstTypeSelector<Derived::InputSubImage1_ReadOnly, INIMAGETYPE1>::Type inTSubImg1(args.inImgs[1]);
518 typename ConstTypeSelector<Derived::InputSubImage2_ReadOnly, INIMAGETYPE2>::Type inTSubImg2(args.inImgs[2]);
519 typename ConstTypeSelector<Derived::InputSubImage3_ReadOnly, INIMAGETYPE3>::Type inTSubImg3(args.inImgs[3]);
520 typename ConstTypeSelector<Derived::InputSubImage4_ReadOnly, INIMAGETYPE4>::Type inTSubImg4(args.inImgs[4]);
521 typename ConstTypeSelector<Derived::InputSubImage5_ReadOnly, INIMAGETYPE5>::Type inTSubImg5(args.inImgs[5]);
522 typename ConstTypeSelector<Derived::InputSubImage6_ReadOnly, INIMAGETYPE6>::Type inTSubImg6(args.inImgs[6]);
523 typename ConstTypeSelector<Derived::InputSubImage7_ReadOnly, INIMAGETYPE7>::Type inTSubImg7(args.inImgs[7]);
524 typename ConstTypeSelector<Derived::InputSubImage8_ReadOnly, INIMAGETYPE8>::Type inTSubImg8(args.inImgs[8]);
525 typename ConstTypeSelector<Derived::InputSubImage9_ReadOnly, INIMAGETYPE9>::Type inTSubImg9(args.inImgs[9]);
526 static_cast<Derived*>(this)->typedCalculateOutputSubImage(outTSubImg, inTSubImg0, inTSubImg1, inTSubImg2, inTSubImg3, inTSubImg4, inTSubImg5, inTSubImg6, inTSubImg7, inTSubImg8, inTSubImg9, args.userThreadData);
527 }
528
529#endif // of DOXYGEN_SHOULD_SKIP_THIS
530
531 // Helper macro that collects compile time enum information of 'Derived' class.
532 #define _ML_COLLECT_ENUMS \
533 const int inputTypes[10] = { \
534 Derived::InputSubImage0_Type, Derived::InputSubImage1_Type, Derived::InputSubImage2_Type, Derived::InputSubImage3_Type, Derived::InputSubImage4_Type, \
535 Derived::InputSubImage5_Type, Derived::InputSubImage6_Type, Derived::InputSubImage7_Type, Derived::InputSubImage8_Type, Derived::InputSubImage9_Type }; \
536 const int inputReadOnly[10] = { \
537 Derived::InputSubImage0_ReadOnly, Derived::InputSubImage1_ReadOnly, Derived::InputSubImage2_ReadOnly, Derived::InputSubImage3_ReadOnly, Derived::InputSubImage4_ReadOnly, \
538 Derived::InputSubImage5_ReadOnly, Derived::InputSubImage6_ReadOnly, Derived::InputSubImage7_ReadOnly, Derived::InputSubImage8_ReadOnly, Derived::InputSubImage9_ReadOnly }; \
539 int variableTypes[4] {}; \
540 setupVariableTypes(variableTypes);
541
544 static void setupKnownProperties(PagedImage* outImg) {
545 // collect static information
547 setupKnownPagedImgProperties(outImg, NumberOfInputImages, Derived::OutputSubImage_Type, inputTypes, inputReadOnly, Derived::getNumVariableTypes(), variableTypes);
548 }
549
553 static bool verifyProperties(PagedImage* outImg) {
554 // collect static information
556 int resultDataTypes[4];
557 verifyPagedImgProperties(outImg, NumberOfInputImages, Derived::OutputSubImage_Type, inputTypes, inputReadOnly, Derived::getNumVariableTypes(), variableTypes, resultDataTypes);
558 if (outImg->isValid()) {
559 std::ostringstream errorMessages;
560 for (int i = 0; i < Derived::getNumVariableTypes(); i++) {
561 if (!Derived::doesVariableTypeSupportDataType(i, resultDataTypes[i])) {
562 if (variableTypes[i]!=_ML_OUTPUTINDEX) {
563 errorMessages << "Unsupported data type '" << MLNameFromDataType(resultDataTypes[i]) << "' at input" << variableTypes[i] << " using variable type " << Derived::variableTypeName(i) << std::endl;
564 } else {
565 errorMessages << "Unsupported data type '" << MLNameFromDataType(resultDataTypes[i]) << "' at output using variable type " << Derived::variableTypeName(i) << std::endl;
566 }
567 }
568 }
569 if (errorMessages.str().size()) {
570 outImg->setInvalid();
571 outImg->setStateInfo(errorMessages.str(), ML_BAD_DATA_TYPE);
572 }
573 }
574 return outImg->isValid();
575 }
576
577 #undef _ML_COLLECT_ENUMS
578};
579
580#ifndef DOXYGEN_SHOULD_SKIP_THIS
581
584template<class Derived, int Step, class Args >
585class NoTypes : public VariableType {
586public:
587 enum {
588 IsEmpty = true
589 };
590
591 static const char* name() { return "NoTypes"; }
592
593 // Empty switching code that returns \c true.
594 template<typename PrevTypes, typename TargetLabelType>
595 bool doSwitchingCode(int /*switchCode*/, const Args& /*args*/, bool /*printError*/ = true) { return true; }
596};
597
598//------------------------------------------------------------------------------------------
601struct DispatchVariableType1Label {};
602struct DispatchVariableType2Label {};
603struct DispatchVariableType3Label {};
604struct DispatchDoneLabel {};
605struct DispatchDoNothingLabel {};
606
609typedef TypeTuple4<DispatchDoneLabel, DispatchDoneLabel, DispatchDoneLabel, DispatchDoneLabel> JumpTable1;
612typedef TypeTuple4<DispatchVariableType1Label, DispatchDoneLabel, DispatchDoneLabel, DispatchDoneLabel> JumpTable2;
615typedef TypeTuple4<DispatchVariableType1Label, DispatchVariableType2Label, DispatchDoneLabel, DispatchDoneLabel> JumpTable3;
618typedef TypeTuple4<DispatchVariableType1Label, DispatchVariableType2Label, DispatchVariableType3Label, DispatchDoneLabel> JumpTable4;
619
620
622template<class Derived>
623class EmptyVariableTypeDispatcher
624{
625public:
626 static int getNumVariableTypes() { return 0; }
627 static bool doesVariableTypeSupportDataType(int /*variableType*/, int /*switchCode*/) { return false; }
628 static const char* variableTypeName(int /*variableType*/) { return "NoTypes"; }
629
630 void doSwitching(const CalculateOutputSubImageArguments& args) {
631 // call back directly to caller, we have no variable types
632 static_cast<Derived*>(this)->template helperCalculateOutputSubImage<EmptyTypeTuple4>(args);
633 }
634
635};
636
639template<class Derived, class JumpTable, class VariableType0, class VariableType1, class VariableType2, class VariableType3>
640class VariableTypeDispatcher : public VariableType0, public VariableType1, public VariableType2, public VariableType3 {
641public:
642
644 static int getNumVariableTypes() {
645 return (VariableType0::IsEmpty?0:1) + (VariableType1::IsEmpty?0:1) +
646 (VariableType2::IsEmpty?0:1) + (VariableType3::IsEmpty?0:1);
647 }
648
649 static bool doesVariableTypeSupportDataType(int variableType, int switchCode) {
650 VariableTypeDispatcher<Derived, JumpTable, VariableType0, VariableType1, VariableType2, VariableType3> self;
651 CalculateOutputSubImageArguments args;
652 if (variableType == 0) {
653 return static_cast<VariableType0*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
654 } else if (variableType == 1) {
655 return static_cast<VariableType1*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
656 } else if (variableType == 2) {
657 return static_cast<VariableType2*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
658 } else if (variableType == 3) {
659 return static_cast<VariableType3*>(&self)->template doSwitchingCode<EmptyTypeTuple4, DispatchDoNothingLabel>(switchCode, args, false /* no error printing*/ );
660 }
661 return false;
662 }
663
664 static const char* variableTypeName(int variableType) {
665 if (variableType == 0) {
666 return VariableType0::name();
667 } else if (variableType == 1) {
668 return VariableType1::name();
669 } else if (variableType == 2) {
670 return VariableType2::name();
671 } else if (variableType == 3) {
672 return VariableType3::name();
673 }
674 return "";
675 }
676
677 void doSwitching(const CalculateOutputSubImageArguments& args) {
678 MLDataType dt = args.variableDataType[0];
679 static_cast<VariableType0*>(this)->template doSwitchingCode<EmptyTypeTuple4, typename JumpTable::T0>(dt, args);
680 }
681
682 template<typename Types>
683 void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType1Label*) {
684 MLDataType dt = args.variableDataType[1];
685 static_cast<VariableType1*>(this)->template doSwitchingCode<Types, typename JumpTable::T1>(dt, args);
686 }
687
688 template<typename Types>
689 void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType2Label*) {
690 MLDataType dt = args.variableDataType[2];
691 static_cast<VariableType2*>(this)->template doSwitchingCode<Types, typename JumpTable::T2>(dt, args);
692 }
693
694 template<typename Types>
695 void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchVariableType3Label*) {
696 MLDataType dt = args.variableDataType[3];
697 static_cast<VariableType3*>(this)->template doSwitchingCode<Types, typename JumpTable::T3>(dt, args);
698 }
699
700 template<typename Types>
701 void doSwitchingWithLabel(const CalculateOutputSubImageArguments& args, DispatchDoneLabel*) {
702 static_cast<Derived*>(this)->template helperCalculateOutputSubImage<Types>(args);
703 }
704
705 template<typename Types>
706 void doSwitchingWithLabel(const CalculateOutputSubImageArguments&, DispatchDoNothingLabel*) {
707 }
708};
709
710#endif // of DOXYGEN_SHOULD_SKIP_THIS
711
712} // end namespace internal
713
714
715//----------------------------------------------------------------------------------------------------
716
721template <typename Derived, int NumberOfInputImages,
722 template <typename, int, typename>class VariableType0 = internal::NoTypes,
723 template <typename, int, typename>class VariableType1 = internal::NoTypes,
724 template <typename, int, typename>class VariableType2 = internal::NoTypes,
725 template <typename, int, typename>class VariableType3 = internal::NoTypes >
726class TypedProcessAllPagesHandler : public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
727 public internal::VariableTypeDispatcher<Derived, internal::JumpTable4, VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
728 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
729 VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
730 VariableType3<Derived, 3, internal::CalculateOutputSubImageArguments > >
731{
732};
733
734
735#ifndef DOXYGEN_SHOULD_SKIP_THIS
736
737// Specialization with three variable types.
738template <typename Derived, int NumberOfInputImages,
739template <typename, int, typename>class VariableType0,
740template <typename, int, typename>class VariableType1,
741template <typename, int, typename>class VariableType2>
742class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, internal::NoTypes> :
743 public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
744 public internal::VariableTypeDispatcher<Derived, internal::JumpTable3,
745 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
746 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
747 VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
748 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
749{
750};
751
752// Specialization with two variable types.
753template <typename Derived, int NumberOfInputImages,
754template <typename, int, typename>class VariableType0,
755template <typename, int, typename>class VariableType1>
756class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, internal::NoTypes, internal::NoTypes> :
757 public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
758 public internal::VariableTypeDispatcher<Derived, internal::JumpTable2,
759 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
760 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
761 internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
762 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
763{
764};
765
766// Specialization with one variable type.
767template <typename Derived, int NumberOfInputImages,
768template <typename, int, typename>class VariableType0>
769class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, VariableType0, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
770 public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
771 public internal::VariableTypeDispatcher<Derived, internal::JumpTable1,
772 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
773 internal::NoTypes<Derived, 1, internal::CalculateOutputSubImageArguments >,
774 internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
775 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
776{
777};
778
779// Specialization with zero variable types.
780template <typename Derived, int NumberOfInputImages>
781class TypedProcessAllPagesHandler<Derived, NumberOfInputImages, internal::NoTypes, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
782 public internal::TypedHandlerBase<ProcessAllPagesHandler, Derived, NumberOfInputImages>,
783 public internal::EmptyVariableTypeDispatcher<Derived>
784{
785};
786
787#endif // of DOXYGEN_SHOULD_SKIP_THIS
788
789//----------------------------------------------------------------------------------------------------
790
796
822
834
855
862
887
895
914
925
937template <typename Derived, int NumberOfInputImages,
938template <typename, int, typename>class VariableType0 = internal::NoTypes,
939template <typename, int, typename>class VariableType1 = internal::NoTypes,
940template <typename, int, typename>class VariableType2 = internal::NoTypes,
941template <typename, int, typename>class VariableType3 = internal::NoTypes >
942class TypedCalculateOutputImageHandler : public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
943 public internal::VariableTypeDispatcher<Derived, internal::JumpTable4,
944 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
945 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
946 VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
947 VariableType3<Derived, 3, internal::CalculateOutputSubImageArguments > >
948{
949};
950
951#ifndef DOXYGEN_SHOULD_SKIP_THIS
952
953// Specialization with three variable types
954template <typename Derived, int NumberOfInputImages,
955template <typename, int, typename>class VariableType0,
956template <typename, int, typename>class VariableType1,
957template <typename, int, typename>class VariableType2>
958class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, internal::NoTypes> :
959 public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
960 public internal::VariableTypeDispatcher<Derived, internal::JumpTable3,
961 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
962 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
963 VariableType2<Derived, 2, internal::CalculateOutputSubImageArguments >,
964 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
965{
966};
967
968// Specialization with two variable types
969template <typename Derived, int NumberOfInputImages,
970template <typename, int, typename>class VariableType0,
971template <typename, int, typename>class VariableType1>
972class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, VariableType1, internal::NoTypes, internal::NoTypes> :
973 public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
974 public internal::VariableTypeDispatcher<Derived, internal::JumpTable2,
975 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
976 VariableType1<Derived, 1, internal::CalculateOutputSubImageArguments >,
977 internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
978 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
979{
980};
981
982// Specialization with one variable type
983template <typename Derived, int NumberOfInputImages,
984template <typename, int, typename>class VariableType0>
985class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, VariableType0, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
986 public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
987 public internal::VariableTypeDispatcher<Derived, internal::JumpTable1,
988 VariableType0<Derived, 0, internal::CalculateOutputSubImageArguments >,
989 internal::NoTypes<Derived, 1, internal::CalculateOutputSubImageArguments >,
990 internal::NoTypes<Derived, 2, internal::CalculateOutputSubImageArguments >,
991 internal::NoTypes<Derived, 3, internal::CalculateOutputSubImageArguments > >
992{
993};
994
995// Specialization with zero variable types
996template <typename Derived, int NumberOfInputImages>
997class TypedCalculateOutputImageHandler<Derived, NumberOfInputImages, internal::NoTypes, internal::NoTypes, internal::NoTypes, internal::NoTypes> :
998 public internal::TypedHandlerBase<CalculateOutputImageHandler, Derived, NumberOfInputImages>,
999 public internal::EmptyVariableTypeDispatcher<Derived>
1000{
1001};
1002
1003#endif // of DOXYGEN_SHOULD_SKIP_THIS
1004
1005//----------------------------------------------------------------------------------------------------
1006
1007//---------------------------------------------------------------------------
1010//---------------------------------------------------------------------------
1011
1015
1029#define ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(NAME) \
1030 template<class Derived, int Step, class Args = ML_NAMESPACE::internal::CalculateOutputSubImageArguments> \
1031class NAME : public VariableType { \
1032public: \
1033 enum { IsEmpty = false }; \
1034 \
1035 static const char* name() { return #NAME; } \
1036 \
1037 template<typename PrevTypes, typename TargetLabelType> \
1038 bool doSwitchingCode(int switchCode, const Args& args, bool printError = true) { \
1039 static const char* switcherName = #NAME; \
1040 bool result = true; \
1041 switch (switchCode) {
1042
1045#define ML_IMPLEMENT_VARIABLE_TYPE_END \
1046 default: { \
1047 result = false; \
1048 if (printError) { \
1049 char buf[512]=""; \
1050 sprintf(buf, "No switch case for physical data type %d.", switchCode); \
1051 ML_PRINT_FATAL_ERROR(switcherName, ML_BAD_DATA_TYPE, buf); } \
1052 } \
1053 break; \
1054} \
1055 return result; \
1056} \
1057};
1058
1061#define ML_IMPLEMENT_VARIABLE_TYPE_CASE(TYPE) \
1062 case TypeTraits<TYPE>::dataType: \
1063 static_cast<Derived*>(this)->template doSwitchingWithLabel<typename ML_NAMESPACE::internal::TypeTuple4Insert<Step, TYPE, PrevTypes>::Type>(args, static_cast<TargetLabelType*>(0)); \
1064 break;
1065
1066#define ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(DATATYPE, TYPE) \
1067 case DATATYPE: \
1068 static_cast<Derived*>(this)->template doSwitchingWithLabel<typename ML_NAMESPACE::internal::TypeTuple4Insert<Step, TYPE, PrevTypes>::Type>(args, static_cast<TargetLabelType*>(0)); \
1069 break;
1070
1073#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT \
1074 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLfloat) \
1075 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLdouble)
1076
1079#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER \
1080 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint8) \
1081 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint8) \
1082 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint16) \
1083 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint16) \
1084 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint32) \
1085 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint32) \
1086 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLuint64) \
1087 ML_IMPLEMENT_VARIABLE_TYPE_CASE(MLint64)
1088
1089#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_COMPLEX \
1090 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexfType, std::complex<MLfloat>) \
1091 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexdType, std::complex<MLdouble>)
1092
1093#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED \
1094 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexfType, std::complex<MLfloat>) \
1095 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLComplexdType, std::complex<MLdouble>) \
1096 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector2fType, Vector2f) \
1097 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector2dType, Vector2d) \
1098 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector3fType, Vector3f) \
1099 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector3dType, Vector3d) \
1100 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector6fType, Vector6f) \
1101 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLVector6dType, Vector6d) \
1102 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix2fType, Matrix2f) \
1103 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix2dType, Matrix2d) \
1104 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix3fType, Matrix3f) \
1105 ML_IMPLEMENT_VARIABLE_EXTENDED_TYPE_CASE(MLMatrix3dType, Matrix3d)
1106
1113
1120
1128
1135
1144
1152
1159
1166
1175
1177
1178ML_END_NAMESPACE
1179
1180#endif // of __mlTypedHandlers_H
1181
@ T
Defines a variable type for the complex datatypes (float and double) to be used with a TypedProcessAl...
Defines a variable type for the default extended datatypes to be used with a TypedProcessAllPagesHand...
Defines a variable type for all scalar and the default extended datatypes to be used with a TypedProc...
Defines a variable type for all built-in floating point datatypes to be used with a TypedProcessAllPa...
Defines a variable type for all built-in integer datatypes to be used with a TypedProcessAllPagesHand...
Defines a variable type for the complex datatypes (float and double) to be used with a TypedProcessAl...
Defines a variable type for all built-in datatypes to be used with a TypedProcessAllPagesHandler/Type...
This template class manages/represents a rectangular 6D image region in memory that is organized line...
TypedCalculateOutputImageHandler can be used as a base class for a custom CalculateOutputImageHandler...
TypedProcessAllPagesHandler can be used as a base class for a custom ProcessAllPages handler and supp...
Base class for all variable types, mainly for Doxygen documentation purpose.
#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_INTEGER
Defines a variable type case block for all integer types.
#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_FLOAT
Defines a variable type case block for all float types.
#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_COMPLEX
#define ML_IMPLEMENT_VARIABLE_TYPE_CASES_DEFAULT_EXTENDED
#define ML_IMPLEMENT_VARIABLE_TYPE_BEGIN(NAME)
Macro to declare a variable type, needs to be followed by 0-N ML_IMPLEMENT_VARIABLE_TYPE_CASE macros ...
#define ML_IMPLEMENT_VARIABLE_TYPE_END
Macro to end declaration of a variable type.
MLint32 MLDataType
MLDataType.
Definition mlTypeDefs.h:595
MLEXPORT const char * MLNameFromDataType(MLDataType dataType)
Function that returns the NULL-terminated string name for data type dataType or "" in case of error o...
#define ML_BAD_DATA_TYPE
A wrong or unexpected data type has been passed to an algorithm, which often is a programming error.
Definition mlTypeDefs.h:781
#define MLEXPORT
To export symbols from a DLL/shared object, we need to mark them with the MLEXPORT symbol.
#define _ML_COLLECT_ENUMS
#define _ML_OUTPUTINDEX
Defines a special index that means to use the output image.
#define ML_N_INPUTS
Special value that can be passed as number of inputs to the typed handlers.
#define _ML_SWITCH_SELECT_OFFSET
Defines an offset for switch types (internal).
const int MLGenericType
Defines special index to use a generic type.
const int MLVariableType2
Defines to use the result type of variable type 2.
const int MLVariableType3
Defines to use the result type of variable type 3.
const int MLVariableType0
Defines to use the result type of variable type 0.
const int MLVariableType1
Defines to use the result type of variable type 1.
Helper template so select a data type from its type ID.