I would like to create an ImageIO class, which permits to load images from an image “cache” through the image file reader, and storing it back in the cache via the image file writer.
Currently I am stumbling over the problem that the ImageFileReader is allocating the memory used by the ImageIOBase derived class to read into. Is there a mechanism, by which the ImageIOBase class could provide the buffer?
The reason I am investigating this problem, is because it might allow to integrate (command-) tools from the ANTs library in our application.
Thanks for any suggestions,
This is an interesting idea that you explaining here. Would you plan to delegate to loading to a “real” IO if your cache does not know your image? Is your cache suppose to be an interface between the Reader and the current IOs, or is it suppose to be independent?
Concerning your question, I don’t think there is a mechanism now in ITK to not allocate the memory in the reader (more specifically in the ImageSource which the Reader derives from). Maybe it is something we can consider if there is a good reason to do so.
Have you looked at the ImportImageFilter?
That is typically used in this situation. Any reason it does not meet your needs?
The reason why I don’t want to use the ImportImageFilter or similar approach, is that I want to integrate command line-like tools from ANTs (Advanced Normalization Tools). These are written with as functions with an api like int Foo(int argc, char**argv). Typically, they load data using the ImageFileReader.
I would like to easily integrate the tools without modification, so if there is a new release in 10 months, I don’t need to redo the same work again.
The fact that buffer is allocated for the image to be read does not prevent you from writing a custom IO type. The only effect that might arise is increased memory usage.
Once the buffer is allocated, your custom IO could simply copy the memory from your cache into that buffer.
3D Slicer has an itk ImageIO which the command line modules utilize to get an image from either in memory (MRML scene) or from a file. It sounds like you want to do a similar thing. Here is the class:
The link @blowekamp shared is great. I was talking with some Slicer developers to know where this mechanism was implemented in Slicer. In their case, they copy the memory (see their
Read() function), which might be better anyway to avoid overwriting your input image, depending on how the function you are calling is implemented.
To allow the IO to manage the memory, one would need to modify
itkImageFileReader. A way of doing so would be to add a method to
ImageIOBase to interrogate the IO if it manages the memory or not. If it does (default/current), then
itkImageFileReader would manage and allocate the memory. Otherwise, the IO would be responsible. I haven’t thought about all the implications this may have and if that would integrate nicely with the current mechanism. As I said earlier, it may be better to always copy the buffer anyway, to avoid problems.
Historically, Slicer had an option for the ImageIO to reuse the buffer, but that was dropped some where between 3.20 and 4.0. There were some problems with the feature because an ITK filters could always run “InPlace” and “steal” the buffer and then free it, unbeknownst to the owner of the buffer.
The performance of a coping memory on modern system is very high. As long as the system has the memory available then its not work the problems that sharing memory can create.
thanks for all the good answers. its true that for my application the only worry I might have is increased memory consumption.
Look at the FileFreeImageIO test in IO/ImageBase.