[Insight-developers] std::vector inide ImportImageContainer
Miller, James V (GE, Research)
millerjv at crd.ge.com
Wed Sep 13 15:52:41 EDT 2006
Henning,
In the first draft of the STL standard, there was nothing that dictated
that std::vector's had to be continguous memory. Std::valarray, on the
other hand, had to be contiguous memory. It turned out that all the
implementations of std::vector chose to make the memory contiguous.
I don't recall whether std::vector allows one to pass in the memory
block to use for the vector. Perhaps it can be done with a special
allocator type.
What are your thoughts for providing alternative pixel container types
without requiring an API change to ITK?
There doesn't seem to be much of a motivation to have
ImportImageContainer use an std::vector (and modifying the rest of the
system) unless these changes facilitate using pixel containers with
alternative memory layouts (without modifying the API or imposing a
performance penalty).
Jim
-----Original Message-----
From: Henning Meyer [mailto:tutmann at gmail.com]
Sent: Wednesday, September 13, 2006 3:39 AM
To: Miller, James V (GE, Research)
Cc: insight-developers at itk.org
Subject: Re: [Insight-developers] std::vector inide ImportImageContainer
Hello Jim,
Thank you for your explanations. That makes things more clear.
But...I think ITK should not stick to the old mistakes.
As far as I understood the API of ITK would not change, when we would
rewrite ImportImageContainer to use a generic random accessible
container. All we had to do is to rewrite the depending code ( Iterators
and IO).
I'm not really sure about it, but it seems, that when using std::vector<
Pixeltype, SpecialAllocator> this could even be used to wrap ITK around
images generated outside ITK.
We could also use some more advanced containers like
boost::multi_array....
I also think, that the iterators should be subclassed, but this could
wait until a major version change ( ITK 3.0?).
Another question: Why did you use valarray instead of vector?
Henning
2006/9/12, Miller, James V (GE, Research) <millerjv at crd.ge.com>:
> Henning,
>
> Originally, we had two ImageContainer classes. One that used
> std::valarray and one that used raw pointers. The version using
> std::valarray was used for images that ITK created itself. The
> version using raw pointers was used for images created outside of ITK
> and "wrapped" to look at an ITK image. The latter is frequently used
> when integrating ITK into an existing imaging applications. This is a
> very important capability of ITK.
>
> When we had both ImageContainer classes, Image was templated over the
> type of container. We decided to reduce the number of template
> parameters to Image, and disposed of the std::valarray version since
> the version using raw pointers can be used for both cases (ITK created
> images as well as images created outside of ITK and wrapped to be ITK
> images).
>
> That is the legacy.
>
> The design flaw in the ImageContainer class and the Image class is
> that we (I) exposed the pointer to the underlying buffer. At the time,
> it seemed benign but this mistake has hindered ITK from natively
> supporting images with different memory layouts. An ITK image
> (implicitly) has to be contiguous in memory. A lot ITK machinery (IO,
> Iterators, etc.) implicitly rely on this fact.
>
> From a design standpoint, we would have been better off keeping the
> API to the ImageContainer abstract. We should have used methods like
> Get(index)/Set(index, value) to modify pixels, presenting an abstract
> row-major order memory layout. Under the hood, an ImageContainer
> could have the data organized any manner of ways: sparse images, slice
> contiguous images (the pixels for each slice contiguous in memory but
> slice to slice would not have to be contiguous), disk based images,
> compressed/run length encoded images, etc.
>
> By the time we (I) realized the magnitude of this mistake, it was too
> late to fix. I still dream about returning to the ImageContainer,
> removing the GetBufferPointer() method, and modifying all the
> iterators to use the abstract API to index into the ImageContainer.
> The RegionIterators would be easy to modify since they always operate
> on an offset from a base address. The RegionIteratorsWithIndex
> iterators would require a bit of rework. The NeighborhoodIterators and
> the ShapedNeighborhoodIterators would require a lot of work. Then a
> few things in IO would need to be fixed up as well.
>
> The downside to these changes (aside from the effort) is that in order
> to keep the rest of ITK backward compatible, we'd probably have to use
> virtual functions, which will slow down pixel access in an image.
>
> Another design that I have thought about is to use traits to select an
> appropriate iterator type for a given image. So instead of using
> ImageRegionIterator<TInputImage> to define a region iterator inside of
> an algorithm, the code would read TInputImage::RegionIterator. This
> would allow for iterators specific to the type image (dense, sparse,
> disk, etc.). This would completely break people's code. Bad. But it
> would make ITK look more like STL.
>
> (On a side note, we did not make the iterators inner classes of the
> image class because we could not get the compilers to compile an image
> class with the breadth of iterators ITK uses to compile when the
> iterators are defined as inner classes.)
>
> So, there you have it. A design decision made in the year 2000 and the
> desire to maintain backward compatibility is tying our hands.
>
> Jim
>
>
>
>
>
>
> -----Original Message-----
> From: insight-developers-bounces+millerjv=crd.ge.com at itk.org
> [mailto:insight-developers-bounces+millerjv=crd.ge.com at itk.org] On
> Behalf Of Henning Meyer
> Sent: Monday, September 11, 2006 6:09 AM
> To: insight-developers at itk.org
> Subject: [Insight-developers] std::vector inide ImportImageContainer
>
> Hello,
>
> I'm wondering why ImportImageContainer does not use std::vector and
> its iterator.
> Instead everywhere I see raw pointers and allocations via new.
> What was the reason for this decision?
> Is it feasable to modify everything to support std::vector (or even a
> generic random accessable container)?
> Where would be the difficult points? What would the drawbacks be?
>
> I would really like to do this, because then I could have an
> itk::Image< bool, 3 > why simply uses just one bit per pixel instead
> of 8 bits (due to partial specialization inside STL for std::vector<
bool >).
> Also I think it could be quite easy then to create sparse image
> support ( with std::map< OffsetType, PixelType > inside the container
).
>
> What do you think about this?
> When using std::vector there shouldn't be any performance drawbacks...
>
> Henning
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at itk.org
> http://www.itk.org/mailman/listinfo/insight-developers
>
More information about the Insight-developers
mailing list