ML Reference
ml::TypedCalculateOutputImageHandler< Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, VariableType3 > Class Template Reference

TypedCalculateOutputImageHandler can be used as a base class for an own CalculateOutputImageHandler and supports up to 4 variable types. More...

#include <mlTypedHandlers.h>

Inheritance diagram for ml::TypedCalculateOutputImageHandler< Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, VariableType3 >:
ml::internal::TypedHandlerBase< CalculateOutputImageHandler, Derived, NumberOfInputImages > ml::CalculateOutputImageHandler

List of all members.


Detailed Description

template<typename Derived, int NumberOfInputImages, template< typename, int, typename >class VariableType0 = internal::NoTypes, template< typename, int, typename >class VariableType1 = internal::NoTypes, template< typename, int, typename >class VariableType2 = internal::NoTypes, template< typename, int, typename >class VariableType3 = internal::NoTypes>
class ml::TypedCalculateOutputImageHandler< Derived, NumberOfInputImages, VariableType0, VariableType1, VariableType2, VariableType3 >

TypedCalculateOutputImageHandler can be used as a base class for an own CalculateOutputImageHandler and supports up to 4 variable types.

Its main feature is that it provides a mapping of the untyped SubImage instances of CalculateOutputImageHandler::calculateOutputSubImage to a call to a method called typedCalculateOutputSubImage() with typed sub images (TSubImage).

A derived class can pass up to 4 VariableType classes as template parameters and assign assigning either variable types or fixed types to the each output and input sub images. This configuration is given by an anonymous enum, that you need to provide in your derived handler class (this is due to the template magic that is done underneath, since all this needs to be known at compile time).

In addition to that, the class has two static methods:

which can be called from Module::calculateOutputImageProperties() to setup the datatypes and readonly flags that are known via the static information and to verify if the given datatypes are valid and will work with the VariableTypes that are used (this allows auto-invalidation of the output image, if the current datatype is not supported by the typedCalculateOutputSubImage instantiations).

Below follows a simple handler which supports an output and 1 input sub image of the same type:

// Create handler with 1 input image and MLVariableType0 = StandardTypes.
class ExampleHandler : public TypedCalculateOutputImageHandler<ExampleHandler, 1, StandardTypes>
{

public:
  enum {
    OutputSubImage_Type = MLVariableType0, // Output sub image uses MLVariableType0, thus it supports StandardTypes.
    InputSubImage0_Type = MLVariableType0, // Input sub image 0 uses MLVariableType0 as well, so it will have the same datatype as the OutputImage.
    InputSubImage0_ReadOnly = true         // Input sub image 0 is accessed read-only.
  };

  ExampleHandler(const PagedImage& outputImage, const Example& module)
  {
    // store some state here
  }

  template <typename OUTTYPE>
  void typedCalculateOutputSubImage(TSubImage<OUTTYPE>& outSubImage,
    const TSubImage<OUTTYPE>& inSubImage0,
    UserThreadData* userThreadData)
  {
    // Compute outSubImage from inSubImage0, both having the same type (one of StandardTypes).
  }
};

If the above handler should support all datatypes, use AllTypes instead of StandardTypes as template argument.

Now to a more complex example, having different output/input types (only showing the configuration parts):

// Example handler that supports a different output and input sub image type.
class ExampleHandler : public TypedCalculateOutputImageHandler<ExampleHandler, 1, StandardTypes, FloatTypes>
{
public:
  enum {
    OutputSubImage_Type = MLVariableType0, // Output sub image uses MLVariableType0, thus it supports StandardTypes.
    InputSubImage0_Type = MLVariableType1, // Input sub image uses MLVariableType1, thus it supports having a different type than the output image and needs to be of type FloatTypes.
    InputSubImage0_ReadOnly = true
  };
  ...
  template <typename OUTTYPE, typename INTYPE0>
  void typedCalculateOutputSubImage(TSubImage<OUTTYPE>& outSubImage,
                              const TSubImage<INTYPE0>& inSubImage0,
                                    UserThreadData* userThreadData)
  {
    // Compute outSubImage from inSubImage0, input and output types can be different, INTYPE0 can be one of FloatTypes and OUTTYPE can be one of StandardTypes.
  }
};

If the above input sub image should support all standard types, you could pass StandardTypes as second argument. Note that it is important that each template argument specifies on MLVariantType[0-3] and if each output/input sub image should support a different datatype on its own (compared to having the same datatype for all sub images), you need to pass the same VariableType multiple times (instead of, e.g., passing StandardTypes once, you need to pass it two times if input and output datatype shall/may be different).

Another useful configuration is to have a fixed datatype on the output image (e.g., because it always generates a MLint16 mask), but to support a variable datatype on the input images. The example below illustrates this:

// Handler with fixed output datatype and variable input datatype on all three input sub images.
class ExampleHandler : public TypedCalculateOutputImageHandler<ExampleHandler,3,StandardTypes>
{
public:
  enum {
    OutputSubImage_Type = MLint16Type,     // Output sub image always is of type MLint16Type.
    InputSubImage0_Type = MLVariableType0, // All three sub images have the same variable type (one of StandardTypes).
    InputSubImage1_Type = MLVariableType0,
    InputSubImage2_Type = MLVariableType0
  };

  template <typename INTYPE0>
  void typedCalculateOutputSubImage(TSubImage<MLint16>& outSubImage,
    const TSubImage<INTYPE0>& inSubImage0,
    const TSubImage<INTYPE0>& inSubImage1,
    const TSubImage<INTYPE0>& inSubImage2,
    UserThreadData* userThreadData)
  {
    // Compute outSubImage from inSubImage[0-2], output sub image is always of type MLint16.
  }

And now finally a more complex example, using all features of the typed handler:

class ExampleHandler : public TypedCalculateOutputImageHandler<ExampleHandler, 3, StandardTypes, StandardTypes>
{

public:
  enum {
    OutputSubImage_Type = MLVariableType0, // Output sub image types is one of StandardTypes.
    InputSubImage0_Type = MLVariableType1,
    InputSubImage1_Type = MLVariableType1, // Both input sub image 0 and 1 have the same variable type, which is different from output sub image type
    InputSubImage2_Type = MLdoubleType,    // Input sub image 2 is always of type MLdouble.
    InputSubImage0_ReadOnly = true,
    InputSubImage1_ReadOnly = true,
    InputSubImage2_ReadOnly = false // Input sub image 2 will be passed non-const and can be written to for temporary calculations.
  };

  template <typename OUTTYPE, typename INTYPE0>
  void typedCalculateOutputSubImage(TSubImage<OUTTYPE>& outSubImage,
    const TSubImage<INTYPE0>& inSubImage0,
    const TSubImage<INTYPE0>& inSubImage1,
          TSubImage<MLdouble>& inSubImage2,
          UserThreadData* userThreadData)
  {
    // Compute outSubImage from inSubImage[0-2].
  }
};

Definition at line 932 of file mlTypedHandlers.h.


The documentation for this class was generated from the following file: