Page MenuHomePhabricator

Add possibility to accessByItk using ReadAccessor
Closed, ResolvedPublic

Description

In the current implementation of CastToItk and accessByItk the macro always causes an mitk::ImageWriteAccessor to be created even if it is already clear that it is not needed and a ReadAccessor would be sufficient.

As it is not possible to have two writeAccessors at a time, this can cause problems at various points.

Examples:

You hold pointers to both the mitk::Image and the corresponding itk::Image in some class. When the itk::Image was created using the accessByItk macro, you already have created a WriteAccessor.

You add the mitk::Image to a DataNode int the next step. This will internally call SetDefaultNodeProperties() to configure the DataNode. As a part of this, the 'ideal' levelWindow is computed using some statistics. In order to compute the statistics, the image is cast to itk::Image and we got ourselves the second WriteAccessor, although the statistics will definitely NOT modify the data and write something.

Another point where this happened to me was when trying to write the mitk::Image to disk. This is done by itk::ImageIO and thus an itk::Image is needed. CastToItk creates a WriteAccessor although the image should not be modified when writing it to disk.

I'm not sure about how to adress this problem best but an alternative AccessByItkConst might be a solution.

Event Timeline

Current release is finished. Resetting target milestone

I ran into the same issue. I modified the ImageToItk class to create read or write accessors depending on the constness of the output type. See #17931.

I think, the same concept could be done with the AccessByItk macros. Instead of creating an AccessByItkConst version, the macro could check if the type of the first argument of the itk access function (the output image) is const or not. If it's const, it should create the ImageToItk object with const type parameter.

Currently the image type is extracted from the MITK image, not the function type, and in the MITK image this information is not available.

C++11 offers an easy way to access the type of the function arguments. A proof of concept implementation follows:


emplate<class F>
struct itk_access_function_traits;

// function pointer
template<class R, class Arg>
struct itk_access_function_traits<R(*)(Arg)> : public itk_access_function_traits<R(Arg)>
{

typedef Arg output_type;

};

template<class R, class Arg1>
struct itk_access_function_traits<R(Arg1)>
{

typedef Arg1 output_type;

};

template <typename TPixel, unsigned VDimension>
void func(int i) {}

int main()
{

typedef itk_access_function_traits<decltype(func<int, 2>)> AccessFunctionType;

AccessFunctionType::output_type var;

var = 4;

return 0;

}

The problem is that this is C++11 specific because of the decltype keyword. C++03 implementation is possible, but not very straightforward.

See this:
http://stackoverflow.com/questions/15644611/function-argument-type

That is, the boost typeof should be backported.

There is an example here, but I'm not sure if it covers function types:
http://stackoverflow.com/questions/12199280/how-to-implement-boost-typeof

The next question could be how could we set the locking policy. The read accessors can have an IgnoreLock option. I introduced a setter for ImageToItk to set this.

However, we do not have an access to the ImageToItk object when using the AccessByITK macros.

Maybe, a new optional 'option' parameter could be introduced to the macro.

The code snippet above does not work if the access function is overloaded. A full C++11 solution is here:

http://stackoverflow.com/questions/25034811/capture-function-argument-type-from-actual-arguments

C++03 is TBD.

Thanks for all the feedback and research.

The mentioned issues are being worked on in T17931.