Package org.apache.sis.image

## Class PixelIterator

- Object
- - PixelIterator

- Direct Known Subclasses:
    `WritablePixelIterator`

      public abstract class PixelIterator
      extends Object

  An iterator over sample values in a raster or an image. This iterator makes easier to read and write efficiently pixel or sample values. The iterator acquires tiles and releases them automatically. Unless otherwise specified, iterators are free to use an iteration order that minimize the "acquire / release tile" operations (in other words, iterations are not necessarily from left to right). Iteration can be performed on a complete image or only a sub-region of it. Some optimized iterator implementations exist for a few commonly used sample models.
  Example:

  >     PixelIterator it = PixelIterator.create(image);
  >     double[] samples = null;
  >     while (it.next()) {
  >         samples = it.getPixel(samples);      // Get values in all bands.
  >         // Perform computation here...
  >     }

  Since:
    1.0

  Defined in the `sis-feature` module

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class | Description
    --- | --- | ---
    `static class` | `PixelIterator.Builder` | Builds pixel iterators for specified region of interest, window size or iteration order.
    `static class` | `PixelIterator.Window<T extends Buffer>` | Contains the sample values in a moving window over the image.

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static PixelIterator` | `create​(RenderedImage data)` | Creates an iterator for all pixels in the given image.
    `abstract <T extends Buffer> PixelIterator.Window<T>` | `createWindow​(TransferType<T> type)` | Returns a moving window over the sample values in a rectangular region starting at iterator position.
    `Rectangle` | `getDomain()` | Returns the pixel coordinates of the region where this iterator is doing the iteration.
    `int` | `getNumBands()` | Returns the number of bands (samples per pixel) in the image or raster.
    `abstract double[]` | `getPixel​(double[] dest)` | Returns the sample values of current pixel for all bands.
    `abstract float[]` | `getPixel​(float[] dest)` | Returns the sample values of current pixel for all bands.
    `abstract int[]` | `getPixel​(int[] dest)` | Returns the sample values of current pixel for all bands.
    `abstract Point` | `getPosition()` | Returns the column (x) and row (y) indices of the current pixel.
    `abstract int` | `getSample​(int band)` | Returns the sample value in the specified band of current pixel, rounded toward zero.
    `abstract double` | `getSampleDouble​(int band)` | Returns the sample value in the specified band of current pixel, without precision lost.
    `abstract float` | `getSampleFloat​(int band)` | Returns the sample value in the specified band of current pixel as a single-precision floating point number.
    `NumberRange<?>[]` | `getSampleRanges()` | Returns the range of sample values that can be stored in each band of the rendered image or raster.
    `TransferType<?>` | `getTransferType()` | Returns the most efficient type (`int`, `float` or `double`) for transferring data between the underlying rasters and this iterator.
    `boolean` | `isWritable()` | Returns `true` if this iterator can write pixel values (after cast to `WritablePixelIterator`).
    `abstract void` | `moveTo​(int x, int y)` | Moves the pixel iterator to the given column (x) and row (y) indices.
    `abstract boolean` | `next()` | Moves the iterator to the next pixel.
    `abstract void` | `rewind()` | Restores the iterator to the start position.

    - ### Methods inherited from class Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Method Detail

    - #### create

          public static PixelIterator create​(RenderedImage data)

      Creates an iterator for all pixels in the given image. This is a convenience method for `new Builder()​.create(data)`.
      Parameters:
        `data` - the image which contains the sample values on which to iterate.
      Returns:
        a new iterator traversing all pixels in the given image, in arbitrary order.

    - #### isWritable

          public boolean isWritable()

      Returns `true` if this iterator can write pixel values (after cast to `WritablePixelIterator`). This method should be used instead than `instanceof` check because, for some implementations, being an instance of `WritablePixelIterator` is not a sufficient condition.
      Returns:
        `true` if this iterator can safely be casted to `WritablePixelIterator` and used for writing pixel values.

    - #### getTransferType

          public TransferType<?> getTransferType()

      Returns the most efficient type (`int`, `float` or `double`) for transferring data between the underlying rasters and this iterator. The transfer type is not necessarily the storage type used by the rasters. For example `int` values will be used for transferring data even if the underlying rasters store all sample values as `byte`s.

      The transfer type is only a hint since all iterator methods work for any type (conversions are applied as needed). However if this method returns `TransferType​.INT`, then `getSample(int)` and `getPixel(int[])` will be slightly more efficient than equivalent methods for other types. Conversely if this method returns `TransferType​.DOUBLE`, then `getSampleDouble(int)` will be both more efficient and avoid accuracy lost.

      Returns:
        the most efficient data type for transferring data.

    - #### getSampleRanges

          public NumberRange<?>[] getSampleRanges()

      Returns the range of sample values that can be stored in each band of the rendered image or raster. The ranges depend on the data type (byte, integer, etc.) and the number of bits per sample. If the samples are stored as floating point values, then the ranges are infinite (unbounded).

      Usually, the range is the same for all bands. A situation where the ranges may differ is when an image uses `SinglePixelPackedSampleModel`, in which case the number of bits per pixel may vary for different bands.

      Returns:
        the ranges of valid sample values for each band. Ranges may be unbounded.

    - #### getNumBands

          public int getNumBands()

      Returns the number of bands (samples per pixel) in the image or raster.
      Returns:
        number of bands.

    - #### getDomain

          public Rectangle getDomain()

      Returns the pixel coordinates of the region where this iterator is doing the iteration. If no region was specified at construction time, then this method returns the image or raster bounds.
      Returns:
        pixel coordinates of the iteration region.

    - #### getPosition

          public abstract Point getPosition()

      Returns the column (x) and row (y) indices of the current pixel. The `next()` or `moveTo(int,int)` method must have been invoked before this method. Indices of the first pixel are not necessarily zero; they can even be negative.
      Returns:
        column and row indices of current iterator position.
      Throws:
        `IllegalStateException` - if this method is invoked before the first call to `next()` or `moveTo(int,int)`, or after `next()` returned `false`.

    - #### moveTo

          public abstract void moveTo​(int x,
                                      int y)

      Moves the pixel iterator to the given column (x) and row (y) indices. After this method invocation, the iterator state is as if the `next()` method has been invoked just before to reach the specified position.
      Usage example:

      >     iterator.moveTo(x, y);
      >     do {
      >         int sample = iterator.getSample(band);
      >         // Use sample value here...
      >     } while (iterator.next());

      Parameters:
        `x` - the column index of the pixel to make current.
        `y` - the row index of the pixel to make current.
      Throws:
        `IndexOutOfBoundsException` - if the given indices are outside the iteration domain.

    - #### next

          public abstract boolean next()

      Moves the iterator to the next pixel. A pixel iterator is initially positioned before the first pixel. The first call to `next()` makes the first pixel the current one; the second call makes the second pixel the current one, etc. The second pixel is not necessarily on the same row than the first one; iteration order is implementation dependent.

      When a call to `next()` returns `false`, the iterator is positioned after the last pixel. Any invocation of a `getSample(int)` method will result in a `NoSuchElementException` to be thrown.

      Returns:
        `true` if the current pixel is valid, or `false` if there is no more pixels.
      Throws:
        `IllegalStateException` - if this iterator already reached end of iteration in a previous call to `next()`, and `rewind()` or `moveTo(int,int)` have not been invoked.

    - #### getSample

          public abstract int getSample​(int band)

      Returns the sample value in the specified band of current pixel, rounded toward zero. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getSample(int)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `band` - the band for which to get the sample value.
      Returns:
        sample value in specified band of current pixel.
      See Also:
        `Raster​.getSample(int, int, int)`

    - #### getSampleFloat

          public abstract float getSampleFloat​(int band)

      Returns the sample value in the specified band of current pixel as a single-precision floating point number. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getSampleFloat(int)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `band` - the band for which to get the sample value.
      Returns:
        sample value in specified band of current pixel.
      See Also:
        `Raster​.getSampleFloat(int, int, int)`

    - #### getSampleDouble

          public abstract double getSampleDouble​(int band)

      Returns the sample value in the specified band of current pixel, without precision lost. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getSampleDouble(int)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `band` - the band for which to get the sample value.
      Returns:
        sample value in specified band of current pixel.
      See Also:
        `Raster​.getSampleDouble(int, int, int)`

    - #### getPixel

          public abstract int[] getPixel​(int[] dest)

      Returns the sample values of current pixel for all bands. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getPixel(…)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `dest` - a pre-allocated array where to store the sample values, or `null` if none.
      Returns:
        the sample values for current pixel.
      See Also:
        `Raster​.getPixel(int, int, int[])`

    - #### getPixel

          public abstract float[] getPixel​(float[] dest)

      Returns the sample values of current pixel for all bands. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getPixel(…)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `dest` - a pre-allocated array where to store the sample values, or `null` if none.
      Returns:
        the sample values for current pixel.
      See Also:
        `Raster​.getPixel(int, int, float[])`

    - #### getPixel

          public abstract double[] getPixel​(double[] dest)

      Returns the sample values of current pixel for all bands. The `next()` method must have returned `true`, or the `moveTo(int,int)` method must have been invoked successfully, before this `getPixel(…)` method is invoked. If above condition is not met, then this method behavior is undefined: it may throw any runtime exception or return a meaningless value (there is no explicit bounds check for performance reasons).
      Parameters:
        `dest` - a pre-allocated array where to store the sample values, or `null` if none.
      Returns:
        the sample values for current pixel.
      See Also:
        `Raster​.getPixel(int, int, double[])`

    - #### createWindow

          public abstract <T extends Buffer> PixelIterator.Window<T> createWindow​(TransferType<T> type)

      Returns a moving window over the sample values in a rectangular region starting at iterator position. The window size must have been specified at `PixelIterator` construction time. The current iterator position is the window corner having the smallest x and y coordinates. This is typically, but not necessarily (depending on axis orientations) the window upper-left corner. Sample values are stored in a sequence of length (number of bands) × (window width) × (window height). Values are always stored with band index varying fastest, then column index, then row index. Columns are traversed from left to right and rows are traversed from top to bottom (linear iteration order). That order is the same regardless the iteration order of this iterator.
      Example: for an RGB image, the 3 first values are the red, green and blue components of the pixel at current iterator position. The 3 next values are the red, green and blue components of the pixel at the right of current iterator position (not necessarily the position where a call to `next()` would have go), etc.
      Calls to `next()` or `moveTo(int,int)` followed by `PixelIterator​.Window​.update()` replaces the window content with values starting at the new iterator position. Before the first `PixelIterator​.Window​.update()` invocation, the window is filled with zero values.

      If this iterator is used for writing pixel values at current position, those write operations may change the content of windows at next positions unless the iteration order of this iterator is `SequenceType​.LINEAR`.

      Usage example: following code creates an iterator over the full area of given image, then a window of 5×5 pixels. The window is moved over all the image area in iteration order. Inside the window, data are copied in linear order regardless the iteration order.

      >     PixelIterator it = create(image, null, new Dimension(5, 5), null);     // Windows size will be 5×5 pixels.
      >     PixelIterator<FloatBuffer> window = it.createWindow(TransferType.FLOAT);
      >     FloatBuffer values = window.values;
      >     while (it.next()) {
      >         window.update();
      >         while (buffer.hasRemaining()) {
      >             float sample = buffer.get();
      >             // use the sample value here.
      >         }
      >     }

      Type Parameters:
        `T` - the type of the data buffer to use for transferring data.
      Parameters:
        `type` - the desired type of values (`int`, `float` or `double`). Use `getTransferType()` if the most efficient type is desired.
      Returns:
        a window over the sample values in the underlying image or raster.
      See Also:
        `Raster​.getPixels(int, int, int, int, double[])`

    - #### rewind

          public abstract void rewind()

      Restores the iterator to the start position. After this method has been invoked, the iterator is in the same state than after construction.