template<dip::uint N, typename T = dip::dfloat>
dip::GenericJointImageIterator class

A data-type–agnostic version of dip::JointImageIterator. Use this iterator only to write code that does not know at compile-time what the data type of the image is.

This iterator works similarly to dip::JointImageIterator. The Pointer<N> method returns a void pointer to the first sample in the pixel for image N. This is the more efficient way of using the iterator.

The Sample<N> method returns a dip::Image::Sample object. This object references the sample, so that assigning to it changes the samples’s value in the image. It is convenient in use, but not very efficient. The optional template argument to GenericJointImageIterator sets the template argument to the dip::Image::CastSample object that is actually returned by the method. Choose a type in which you wish to work, but know that this choice will not affect the results of reading from and assigning to the samples. The only difference is the type to which the output can implicitly be cast to.

Example usage slightly modified from dip::Image::Copy:

dip::uint processingDim = Framework::OptimalProcessingDim( src );
auto it = dip::GenericJointImageIterator< 2 >( { src, dest }, processingDim );
do {
   detail::CopyBuffer(
         it.InPointer(),
         src.DataType(),
         src.Stride( processingDim ),
         src.TensorStride(),
         it.OutPointer(),
         dest.DataType(),
         dest.Stride( processingDim ),
         dest.TensorStride(),
         dest.Size( processingDim ),
         dest.TensorElements()
   );
} while( ++it );

Note that when an image is stripped or reforged, all its iterators are invalidated.

Constructors, destructors, assignment and conversion operators

GenericJointImageIterator()
Default constructor yields an invalid iterator that cannot be dereferenced, and is equivalent to an end iterator
GenericJointImageIterator(dip::ImageConstRefArray const& images, dip::uint procDim = std::numeric_limits::max()) explicit
To construct a useful iterator, provide two images, and optionally a processing dimension

Aliases

using iterator_category = std::forward_iterator_tag
Iterator category
using pointer = dip::GenericJointImageIterator::value_type*
The type of a pointer to a pixel
using reference = dip::GenericJointImageIterator::value_type
The type of a reference to a pixel (note dip::Image::CastPixel references a value in the image)
using value_type = dip::Image::CastPixel
The type of the pixel, obtained when dereferencing the iterator

Functions

template<dip::uint I>
auto begin() const -> typename value_type::Iterator
Get an iterator over the tensor for the current pixel of image I
auto Coordinates() const -> dip::UnsignedArray const&
Return the current coordinates
template<dip::uint I>
auto end() const -> typename value_type::Iterator
Get an end iterator over the tensor for the current pixel of image I
template<dip::uint I, typename S = T>
auto GetConstLineIterator() const -> dip::ConstLineIterator
Get a const iterator over the current line of image I
template<dip::uint I, typename S = T>
auto GetLineIterator() const -> dip::LineIterator
Get an iterator over the current line of image I
auto HasProcessingDimension() const -> bool
True if the processing dimension is set
auto In() const -> dip::GenericJointImageIterator::value_type
Get pixel for image 0.
auto Index() const -> dip::uint
Return the current index, which is computed: this function is not trivial
auto InOffset() const -> dip::sint
Index into image tensor for image 0.
auto InPointer(dip::uint index) const -> void*
Index into image tensor for image 0.
auto InPointer() const -> void*
Return the current pointer for image 0.
auto InSample(dip::uint index) const -> dip::Image::CastSample
Index into image tensor for image 0.
auto IsAtEnd() const -> bool
Test to see if the iterator reached past the last pixel
auto IsOnEdge() const -> bool
Return true if the iterator points at a pixel on the edge of the image. more...
template<dip::uint I>
auto Offset() const -> dip::sint
Return the current offset for image I
auto Optimize(dip::uint n = 0) -> dip::GenericJointImageIterator&
Optimizes the order in which the iterator visits the image pixels. more...
auto OptimizeAndFlatten(dip::uint n = 0) -> dip::GenericJointImageIterator&
Like Optimize, but additionally folds dimensions together where possible (flattens the image, so that the iterator has fewer dimensions to work with). The processing dimension is not affected.
auto Out() const -> dip::GenericJointImageIterator::value_type
Get pixel for image 1.
auto OutOffset() const -> dip::sint
Index into image tensor for image 1.
auto OutPointer(dip::uint index) const -> void*
Index into image tensor for image 1.
auto OutPointer() const -> void*
Return the current pointer for image 1.
auto OutSample(dip::uint index) const -> dip::Image::CastSample
Index into image tensor for image 1.
template<dip::uint I>
auto Pixel() const -> dip::GenericJointImageIterator::value_type
Get pixel for image I.
template<dip::uint I>
auto Pointer(dip::uint index) const -> void*
Index into image tensor for image I
template<dip::uint I>
auto Pointer() const -> void*
Return the current pointer for image I
auto ProcessingDimension() const -> dip::uint
Return the processing dimension, the direction of the lines over which the iterator iterates. more...
auto ProcessingDimensionSize() const -> dip::uint
Return the size along the processing dimension.
template<dip::uint I>
auto ProcessingDimensionStride() const -> dip::sint
Return the stride along the processing dimension.
auto Reset() -> dip::GenericJointImageIterator&
Reset the iterator to the first pixel in the image (as it was when first created)
template<dip::uint I>
auto Sample(dip::uint index) const -> dip::Image::CastSample
Index into image tensor for image I
template<dip::uint I>
auto Sample() const -> dip::Image::CastSample
Get first tensor element for image I.
auto SetCoordinates(dip::UnsignedArray coords) -> dip::GenericJointImageIterator&
Set the iterator to point at a different location in the image
auto Sizes() const -> dip::UnsignedArray const&
Return the sizes of the images we’re iterating over.
template<dip::uint I>
auto Strides() const -> dip::IntegerArray const&
Return the strides used to iterate over the image I.
template<typename S>
void swap(dip::GenericJointImageIterator& other)
Swap

Operators

auto operator bool() const -> bool explicit
Test to see if the iterator is still pointing at a pixel
template<typename S>
auto operator!=(dip::GenericJointImageIterator const& other) const -> bool
Inequality comparison
auto operator++() -> dip::GenericJointImageIterator&
Pre-increment
auto operator++(int ) -> dip::GenericJointImageIterator
Post-increment
template<typename S>
auto operator==(dip::GenericJointImageIterator const& other) const -> bool
Equality comparison, is equal if the two iterators have the same coordinates.

Alias documentation

template<dip::uint N, typename T>
using iterator_category = std::forward_iterator_tag

Iterator category

template<dip::uint N, typename T>
using value_type = dip::Image::CastPixel

The type of the pixel, obtained when dereferencing the iterator

template<dip::uint N, typename T>
using reference = dip::GenericJointImageIterator::value_type

The type of a reference to a pixel (note dip::Image::CastPixel references a value in the image)

template<dip::uint N, typename T>
using pointer = dip::GenericJointImageIterator::value_type*

The type of a pointer to a pixel

Function documentation

template<dip::uint N, typename T>
GenericJointImageIterator( )

Default constructor yields an invalid iterator that cannot be dereferenced, and is equivalent to an end iterator

template<dip::uint N, typename T>
GenericJointImageIterator( dip::ImageConstRefArray const& images, dip::uint procDim = std::numeric_limits::max()) explicit

To construct a useful iterator, provide two images, and optionally a processing dimension

template<dip::uint N, typename T>
template<typename S>
void swap( dip::GenericJointImageIterator& other)

Swap

template<dip::uint N, typename T>
template<dip::uint I>
dip::Image::CastSample Sample( dip::uint index) const

Index into image tensor for image I

template<dip::uint N, typename T>
dip::Image::CastSample InSample( dip::uint index) const

Index into image tensor for image 0.

template<dip::uint N, typename T>
dip::Image::CastSample OutSample( dip::uint index) const

Index into image tensor for image 1.

template<dip::uint N, typename T>
template<dip::uint I>
dip::Image::CastSample Sample( ) const

Get first tensor element for image I.

template<dip::uint N, typename T>
dip::GenericJointImageIterator::value_type In( ) const

Get pixel for image 0.

template<dip::uint N, typename T>
dip::GenericJointImageIterator::value_type Out( ) const

Get pixel for image 1.

template<dip::uint N, typename T>
template<dip::uint I>
dip::GenericJointImageIterator::value_type Pixel( ) const

Get pixel for image I.

template<dip::uint N, typename T>
template<dip::uint I>
typename value_type::Iterator begin( ) const

Get an iterator over the tensor for the current pixel of image I

template<dip::uint N, typename T>
template<dip::uint I>
typename value_type::Iterator end( ) const

Get an end iterator over the tensor for the current pixel of image I

template<dip::uint N, typename T>
template<dip::uint I, typename S = T>
dip::LineIterator GetLineIterator( ) const

Get an iterator over the current line of image I

template<dip::uint N, typename T>
template<dip::uint I, typename S = T>
dip::ConstLineIterator GetConstLineIterator( ) const

Get a const iterator over the current line of image I

template<dip::uint N, typename T>
bool IsAtEnd( ) const

Test to see if the iterator reached past the last pixel

template<dip::uint N, typename T>
dip::UnsignedArray const& Coordinates( ) const

Return the current coordinates

template<dip::uint N, typename T>
dip::GenericJointImageIterator& SetCoordinates( dip::UnsignedArray coords)

Set the iterator to point at a different location in the image

template<dip::uint N, typename T>
dip::UnsignedArray const& Sizes( ) const

Return the sizes of the images we’re iterating over.

template<dip::uint N, typename T>
dip::uint ProcessingDimensionSize( ) const

Return the size along the processing dimension.

template<dip::uint N, typename T>
template<dip::uint I>
dip::IntegerArray const& Strides( ) const

Return the strides used to iterate over the image I.

template<dip::uint N, typename T>
template<dip::uint I>
dip::sint ProcessingDimensionStride( ) const

Return the stride along the processing dimension.

template<dip::uint N, typename T>
bool IsOnEdge( ) const

Return true if the iterator points at a pixel on the edge of the image.

If there is a processing dimension, then the iterator always points at an edge pixel; in this case only returns true if all pixels on the line are edge pixels (i.e. the first and last pixel of the line are not counted).

template<dip::uint N, typename T>
template<dip::uint I>
void* Pointer( dip::uint index) const

Index into image tensor for image I

template<dip::uint N, typename T>
void* InPointer( dip::uint index) const

Index into image tensor for image 0.

template<dip::uint N, typename T>
void* OutPointer( dip::uint index) const

Index into image tensor for image 1.

template<dip::uint N, typename T>
template<dip::uint I>
void* Pointer( ) const

Return the current pointer for image I

template<dip::uint N, typename T>
void* InPointer( ) const

Return the current pointer for image 0.

template<dip::uint N, typename T>
void* OutPointer( ) const

Return the current pointer for image 1.

template<dip::uint N, typename T>
template<dip::uint I>
dip::sint Offset( ) const

Return the current offset for image I

template<dip::uint N, typename T>
dip::sint InOffset( ) const

Index into image tensor for image 0.

template<dip::uint N, typename T>
dip::sint OutOffset( ) const

Index into image tensor for image 1.

template<dip::uint N, typename T>
dip::uint Index( ) const

Return the current index, which is computed: this function is not trivial

template<dip::uint N, typename T>
bool HasProcessingDimension( ) const

True if the processing dimension is set

template<dip::uint N, typename T>
dip::uint ProcessingDimension( ) const

Return the processing dimension, the direction of the lines over which the iterator iterates.

If the return value is larger or equal to the dimensionality (i.e. not one of the image dimensions), then there is no processing dimension.

template<dip::uint N, typename T>
dip::GenericJointImageIterator& Reset( )

Reset the iterator to the first pixel in the image (as it was when first created)

template<dip::uint N, typename T>
dip::GenericJointImageIterator& Optimize( dip::uint n = 0)

Optimizes the order in which the iterator visits the image pixels.

The iterator internally reorders and flips image dimensions to change the linear index to match the storage order of the first image (see dip::Image::StandardizeStrides), or image n if a parameter is given. If the image’s strides were not normal, this will significantly increase the speed of reading or writing to the image. Expanded singleton dimensions are eliminated only if the dimension is expanded in all images. Additionally, singleton dimensions are ignored.

After calling this function, Coordinates and Index no longer match the input images. Do not use this method if the order of accessing pixels is relevant, or if Coordinates are needed.

Note that the processing dimension stride could change sign. Use ProcessingDimensionStride. If the processing dimension was a singleton dimension, or singleton-expanded, the iterator will no longer have a singleton dimension. In this case, HasProcessingDimension will return false.

The iterator is reset to the first pixel.

template<dip::uint N, typename T>
dip::GenericJointImageIterator& OptimizeAndFlatten( dip::uint n = 0)

Like Optimize, but additionally folds dimensions together where possible (flattens the image, so that the iterator has fewer dimensions to work with). The processing dimension is not affected.

template<dip::uint N, typename T>
dip::GenericJointImageIterator& operator++( )

Pre-increment

template<dip::uint N, typename T>
dip::GenericJointImageIterator operator++( int )

Post-increment

template<dip::uint N, typename T>
template<typename S>
bool operator==( dip::GenericJointImageIterator const& other) const

Equality comparison, is equal if the two iterators have the same coordinates.

template<dip::uint N, typename T>
template<typename S>
bool operator!=( dip::GenericJointImageIterator const& other) const

Inequality comparison

template<dip::uint N, typename T>
bool operator bool( ) const explicit

Test to see if the iterator is still pointing at a pixel