sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmarec...@apache.org
Subject svn commit: r1803291 [1/3] - in /sis/branches/JDK8: core/ core/sis-raster/ core/sis-raster/src/ core/sis-raster/src/main/ core/sis-raster/src/main/java/ core/sis-raster/src/main/java/org/ core/sis-raster/src/main/java/org/apache/ core/sis-raster/src/ma...
Date Fri, 28 Jul 2017 16:08:38 GMT
Author: rmarechal
Date: Fri Jul 28 16:08:28 2017
New Revision: 1803291

URL: http://svn.apache.org/viewvc?rev=1803291&view=rev
Log:
(sis-raster): add first work of PixelIterator

Added:
    sis/branches/JDK8/core/sis-raster/
    sis/branches/JDK8/core/sis-raster/pom.xml
    sis/branches/JDK8/core/sis-raster/src/
    sis/branches/JDK8/core/sis-raster/src/main/
    sis/branches/JDK8/core/sis-raster/src/main/java/
    sis/branches/JDK8/core/sis-raster/src/main/java/org/
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/DefaultIterator.java
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIterator.java
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIteratorFactory.java
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/RectIter.java
    sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/WritablePixelIterator.java
    sis/branches/JDK8/core/sis-raster/src/test/
    sis/branches/JDK8/core/sis-raster/src/test/java/
    sis/branches/JDK8/core/sis-raster/src/test/java/org/
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/DefaultReadOnlyTest.java
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/IteratorTest.java
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/IteratorTestImage.java
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/IteratorTestUtilities.java
    sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/ReadOnlyTest.java
Modified:
    sis/branches/JDK8/core/pom.xml
    sis/branches/JDK8/ide-project/NetBeans/nbproject/build-impl.xml
    sis/branches/JDK8/ide-project/NetBeans/nbproject/genfiles.properties
    sis/branches/JDK8/ide-project/NetBeans/nbproject/project.properties
    sis/branches/JDK8/ide-project/NetBeans/nbproject/project.xml

Modified: sis/branches/JDK8/core/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/pom.xml?rev=1803291&r1=1803290&r2=1803291&view=diff
==============================================================================
--- sis/branches/JDK8/core/pom.xml (original)
+++ sis/branches/JDK8/core/pom.xml Fri Jul 28 16:08:28 2017
@@ -192,6 +192,7 @@
     <module>sis-referencing</module>
     <module>sis-referencing-by-identifiers</module>
     <module>sis-feature</module>
+    <module>sis-raster</module>
   </modules>
 
 </project>

Added: sis/branches/JDK8/core/sis-raster/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/pom.xml?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/pom.xml (added)
+++ sis/branches/JDK8/core/sis-raster/pom.xml Fri Jul 28 16:08:28 2017
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns              = "http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi          = "http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
+                               http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.sis</groupId>
+    <artifactId>core</artifactId>
+    <version>0.8-jdk8-SNAPSHOT</version>
+  </parent>
+
+
+  <!-- ===========================================================
+           Module Description
+       =========================================================== -->
+  <groupId>org.apache.sis.core</groupId>
+  <artifactId>sis-raster</artifactId>
+  <packaging>bundle</packaging>
+  <name>Apache SIS rasters</name>
+  <description>
+  <!-- Left alignment because this description will be copied in META-INF/MANIFEST.MF
+       The leading space after the first line is necessary for proper formatting. -->
+Representations of geographic features.
+  </description>
+
+
+  <!-- ===========================================================
+           Developers and Contributors
+       =========================================================== -->
+  <developers>
+    <developer>
+      <name>Martin Desruisseaux</name>
+      <id>desruisseaux</id>
+      <email>desruisseaux@apache.org</email>
+      <organization>Geomatys</organization>
+      <organizationUrl>http://www.geomatys.com</organizationUrl>
+      <timezone>+1</timezone>
+      <roles>
+        <role>developer</role>
+      </roles>
+    </developer>
+    <developer>
+      <name>Remi Marechal</name>
+      <id>rmarechal</id>
+      <email>rmarechal@apache.org</email>
+      <organization>Geomatys</organization>
+      <organizationUrl>http://www.geomatys.com</organizationUrl>
+      <timezone>+1</timezone>
+      <roles>
+        <role>developer</role>
+      </roles>
+   </developer>
+  </developers>
+
+
+  <!-- ===========================================================
+           Build configuration
+       =========================================================== -->
+  <build>
+    <plugins>
+
+      <!-- Package as OSGi bundle -->
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>org.apache.sis.raster</Bundle-SymbolicName>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+
+  <!-- ===========================================================
+           Dependencies
+       =========================================================== -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.sis.core</groupId>
+      <artifactId>sis-utility</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.apache.sis.core</groupId>
+      <artifactId>sis-utility</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

Added: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/DefaultIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/DefaultIterator.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/DefaultIterator.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/DefaultIterator.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.Rectangle;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import org.opengis.coverage.grid.SequenceType;
+
+/**
+ * An Iterator for traversing anyone rendered Image.
+ * <p>
+ * Iteration transverse each tiles(raster) from rendered image or raster source one by one in order.
+ * Iteration to follow tiles(raster) begin by raster bands, next, raster x coordinates,
+ * and to finish raster y coordinates.
+ * <p>
+ * Iteration follow this scheme :
+ * tiles band --&gt; tiles x coordinates --&gt; tiles y coordinates --&gt; next rendered image tiles.
+ *
+ * Moreover iterator traversing a read-only each rendered image tiles(raster) in top-to-bottom, left-to-right order.
+ *
+ *
+ * /// TODO !!!!!!!!!
+ * Code example :
+ * {@code
+ *                  final PixelIterator dRII = PixelIteratorFactory.create(Iterator(renderedImage, rectangleAreaIterate));
+ *                  while (dRII.next()) {
+ *                      dRii.getSample();
+ *                  }
+ * }
+ *
+ * @author Rémi Marechal       (Geomatys).
+ * @author Martin Desruisseaux (Geomatys).
+ */
+class DefaultIterator extends PixelIterator {
+
+    /**
+     * Current X pixel coordinate in this current raster.
+     */
+    protected int x;
+
+    /**
+     * Current Y pixel coordinate in this current raster.
+     */
+    protected int y;
+
+    /**
+     * The X coordinate of the upper-left pixel of this current raster.
+     */
+    private int minX;
+
+    /**
+     * Create raster iterator to follow from minX, minY raster and rectangle intersection coordinate.
+     *
+     * @param raster will be followed by this iterator.
+     * @param subArea {@code Rectangle} which define read iterator area.
+     * @throws IllegalArgumentException if subArea don't intersect raster boundary.
+     */
+    DefaultIterator(final Raster raster, final Rectangle subArea) {
+        super(raster, subArea);
+        this.minX              = areaIterate.minx;
+        this.currentRasterMaxX = areaIterate.maxX;
+        this.currentRasterMaxY = areaIterate.maxY;
+        x                      = this.minX;
+        y                      = areaIterate.miny;
+    }
+
+    /**
+     * Create default rendered image iterator.
+     *
+     * @param renderedImage image which will be follow by iterator.
+     * @param subArea {@code Rectangle} which represent image sub area iteration.
+     * @throws IllegalArgumentException if subArea don't intersect image boundary.
+     */
+    DefaultIterator(final RenderedImage renderedImage, final Rectangle subArea) {
+        super(renderedImage, subArea);
+        tX = tileIndexArea.minx - 1;
+        tY = tileIndexArea.miny;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public boolean next() {
+        if (++band == rasterNumBand) {
+            band = 0;
+            if (++x == currentRasterMaxX) {
+                if (++y == currentRasterMaxY) {
+                    if (++tX == tileIndexArea.maxX) {
+                        tX = tileIndexArea.minx;
+                        if (++tY >= tileIndexArea.maxY) {
+                            {
+                                //-- initialize attribut with expected values to throw exception if another next() is  called.
+                                band = rasterNumBand - 1;
+                                x    = currentRasterMaxX - 1;
+                                y    = currentRasterMaxY - 1;
+                                tX   = tileIndexArea.maxY - 1;
+                            }
+
+                            if ((tY - 1) >= tileIndexArea.maxY)//-- at first out tY == tMaxY and with another next() tY = tMaxY + 1.
+                                throw new IllegalStateException("Out of raster boundary. Illegal next call, you should rewind iterator first.");
+                            return false;
+                        }
+                    }
+                    //initialize from new tile(raster).
+                    updateCurrentRaster(tX, tY);
+                }
+                x = minX;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Update current raster from tiles array coordinates.
+     *
+     * @param tileX current X coordinate from rendered image tiles array.
+     * @param tileY current Y coordinate from rendered image tiles array.
+     */
+    protected void updateCurrentRaster(int tileX, int tileY) {
+        //-- update traveled raster
+        this.currentRaster = this.renderedImage.getTile(tileX, tileY);
+
+        //-- update needed attibut to iter
+        final int cRMinX       = this.currentRaster.getMinX();
+        final int cRMinY       = this.currentRaster.getMinY();
+        this.minX = this.x     = Math.max(areaIterate.minx, cRMinX);
+        this.y                 = Math.max(areaIterate.miny, cRMinY);
+        this.currentRasterMaxX = Math.min(areaIterate.maxX, cRMinX + tileSize.width);
+        this.currentRasterMaxY = Math.min(areaIterate.maxY, cRMinY + tileSize.height);
+        this.rasterNumBand     = this.currentRaster.getNumBands(); //-- ??? what is this attributs
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public int getX() {
+        return x;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public int getY() {
+        return y;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public int getSample() {
+        return currentRaster.getSample(x, y, band);
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public float getSampleFloat() {
+        return currentRaster.getSampleFloat(x, y, band);
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public double getSampleDouble() {
+        return currentRaster.getSampleDouble(x, y, band);
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public void rewind() {
+        if (renderedImage == null) {
+            band = -1; x = minX; y = areaIterate.miny;
+            tX = tY = 0;
+//            tMaxX = tMaxY = 1;
+        } else {
+            this.x    = this.y    = this.band    = 0;
+            this.currentRasterMaxX = this.currentRasterMaxY = this.rasterNumBand = 1;
+            this.tX   = tileIndexArea.minx - 1;
+            this.tY   = tileIndexArea.miny;
+        }
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public void close() {}
+
+    @Override
+    public void moveTo(final int x, final int y, final int b) {
+        super.moveTo(x, y, b);
+        if (renderedImage != null) {
+            final int riMinX = renderedImage.getMinX();
+            final int riMinY = renderedImage.getMinY();
+            final int tmpTX = (x - riMinX) / tileSize.width  + renderedImage.getMinTileX();
+            final int tmpTY = (y - riMinY) / tileSize.height + renderedImage.getMinTileY();
+            if (tmpTX != tX || tmpTY != tY) {
+                tX = tmpTX;
+                tY = tmpTY;
+                updateCurrentRaster(tX, tY);
+            }
+        }
+        this.x = x;
+        this.y = y;
+        this.band = b;// - 1;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    public SequenceType getIterationDirection() {
+        if (renderedImage == null) return SequenceType.LINEAR;//1 raster seul
+        if (renderedImage.getNumXTiles() <=1 && renderedImage.getNumYTiles() <= 1)
+            return SequenceType.LINEAR;
+        return null;
+    }
+}

Added: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIterator.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIterator.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIterator.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,912 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.WritableRenderedImage;
+import java.io.Closeable;
+import org.apache.sis.util.ArgumentChecks;
+import org.opengis.coverage.grid.SequenceType;
+
+/**
+ * Define standard iterator for image pixel.
+ *
+ * Iteration order is define in sub-classes implementation.
+ * However iteration begging by Bands.
+ *
+ * Moreover comportment not specify if iterator exceed image limits.
+ *
+ * @author Rémi Marechal       (Geomatys).
+ * @author Martin Desruisseaux (Geomatys).
+ */
+abstract class PixelIterator implements Closeable {
+
+    /**
+     * Define boundary, in pixel coordinates, of area traveled by this PixeIterator.
+     * @see #getBoundary(boolean)
+     */
+    protected final RectIter areaIterate;
+
+    /**
+     * Define boundary, in pixel coordinates, of iterated object.
+     * @see #getBoundary(boolean)
+     */
+    private final Rectangle objectBoundary;
+
+    /**
+     * Tile index of iterated object.
+     * note : raster is considered as image of one tile.
+     */
+    protected final RectIter tileIndexArea;
+
+    /**
+     * Size of tiles from iterated object.
+     */
+    protected final Dimension tileSize;
+
+    /**
+     * Current raster which is followed by Iterator.
+     */
+    protected Raster currentRaster;
+
+    /**
+     * RenderedImage which is followed by Iterator.
+     */
+    protected final RenderedImage renderedImage;
+//
+    /**
+     * Number of band.
+     */
+    protected final int fixedNumBand;
+
+    /**
+     * Number of raster band.
+     * WARNING ! this is used a bit everywhere in iterator as a 'updateTileRaster' flag.
+     */
+    protected int rasterNumBand;
+
+    /**
+     * Current band position in this current raster.
+     */
+    protected int band;
+
+    /**
+     * {@link SampleModel} from the iterate object.
+     */
+    protected final SampleModel currentSampleModel;
+
+    //-- Iteration attributs
+    /**
+     * Stored position of upper right corner of current traveled raster.
+     * Generaly when this values are reach an update of the current
+     * traveled raster is effectuate.
+     */
+    protected int currentRasterMaxX;
+    protected int currentRasterMaxY;
+
+    /**
+     * Current Tile index of current traveled raster.
+     */
+    protected int tX;
+    protected int tY;
+
+    /**
+     * Create raster iterator to follow from minX, minY raster and rectangle intersection coordinate.
+     *
+     * @param raster will be followed by this iterator.
+     * @param subArea {@code Rectangle} which define read iterator area.
+     * @throws IllegalArgumentException if subArea don't intersect raster boundary.
+     */
+    PixelIterator(final Raster raster, final Rectangle subArea) {
+        ArgumentChecks.ensureNonNull("raster", raster);
+        objectBoundary     = new Rectangle(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight());
+        this.currentRaster = raster;
+        this.renderedImage = null;
+        tileSize           = new Dimension(objectBoundary.width, objectBoundary.height);
+        currentSampleModel = raster.getSampleModel();
+        areaIterate        = new RectIter((subArea != null)
+                             ? subArea.intersection(objectBoundary)
+                             : objectBoundary);
+
+        if (areaIterate.isEmpty())
+            throw new IllegalArgumentException("No intersection between subArea and raster.\n "
+                    + "Raster boundary  = " + objectBoundary + "\n "
+                    + "subArea boundary = " + subArea);
+
+        //-- in our case only one raster -> tile index 0 -> 1
+        tileIndexArea      = new RectIter(0, 0, 1, 1);
+
+        this.rasterNumBand = raster.getNumBands();
+        this.fixedNumBand  = this.rasterNumBand; //-- je pense que c uniquement utilisé pour les direct iterators
+        this.band = -1;
+    }
+
+    /**
+     * Create default rendered image iterator.
+     *
+     * @param renderedImage image which will be follow by iterator.
+     * @param subArea {@code Rectangle} which represent image sub area iteration.
+     * @throws IllegalArgumentException if subArea don't intersect image boundary.
+     */
+    PixelIterator(final RenderedImage renderedImage, final Rectangle subArea) {
+        ArgumentChecks.ensureNonNull("renderedImage", renderedImage);
+        this.renderedImage = renderedImage;
+        objectBoundary     = new Rectangle(renderedImage.getMinX(), renderedImage.getMinY(), renderedImage.getWidth(), renderedImage.getHeight());
+        tileSize           = new Dimension(renderedImage.getTileWidth(), renderedImage.getTileHeight());
+        currentSampleModel = renderedImage.getSampleModel();
+        areaIterate        = new RectIter((subArea != null)
+                                         ? subArea.intersection(objectBoundary)
+                                         : objectBoundary);
+        if (areaIterate.isEmpty())
+            throw new IllegalArgumentException("No intersection between subArea and raster.\n "
+                    + "RenderedImage boundary  = " + objectBoundary + "\n "
+                    + "subArea boundary = " + subArea);
+
+        //--tiles index attributs computing
+        {
+            final int offTX = renderedImage.getTileGridXOffset();
+            final int offTY = renderedImage.getTileGridYOffset();
+            final int tMinX = (areaIterate.minx - objectBoundary.x) / tileSize.width  + offTX;
+            final int tMinY = (areaIterate.miny - objectBoundary.y) / tileSize.height + offTY;
+            final int tMaxX = (areaIterate.maxX - objectBoundary.x + tileSize.width - 1)  / tileSize.width  + offTX;
+            final int tMaxY = (areaIterate.maxY - objectBoundary.y + tileSize.height - 1) / tileSize.height + offTY;
+            tileIndexArea = new RectIter(tMinX, tMinY, tMaxX - tMinX, tMaxY - tMinY);
+        }
+
+        //initialize attributs to first iteration
+        this.band = -1;
+        this.rasterNumBand = 1;
+        this.fixedNumBand  = currentSampleModel.getNumBands();
+    }
+
+    /**
+     * Returns true if the iteration has more pixel(in other words if {@linkplain #next()} is possible)
+     * and move forward iterator.
+     *
+     * @return true if next value exist else false.
+     * @throws IllegalStateException if you call again this method when you have
+     *         already reach the end of the iteration.
+     */
+    public abstract boolean next();
+
+    /**
+     * Returns next X iterator coordinate without move forward it.
+     * User must call next() method before getX() method.
+     *
+     * @return X iterator position.
+     */
+    public abstract int getX();
+
+    /**
+     * Returns next Y iterator coordinate without move forward it.
+     * User must call next() method before getY() method.
+     *
+     * @return Y iterator position.
+     */
+    public abstract int getY();
+
+    /**
+     * Returns the next integer value from iteration.
+     *
+     * @return the next integer value.
+     */
+    public abstract int getSample();
+
+    /**
+     * Returns the next float value from iteration.
+     *
+     * @return the next float value.
+     */
+    public abstract float getSampleFloat();
+
+    /**
+     * Returns the next double value from iteration.
+     *
+     * @return the next double value.
+     */
+    public abstract double getSampleDouble();
+
+    /**
+     * Initializes iterator.
+     * Carry back iterator at its initial position like iterator is just build.
+     */
+    public abstract void rewind();
+
+    /**
+     * To release last tiles iteration from writable rendered image tiles array.
+     * if this method is invoked in read-only iterator, method is idempotent (has no effect).
+     */
+    public abstract void close();
+
+    /**
+     * Return type of sequence iteration direction.
+     *
+     * @return type of sequence.
+     */
+    public abstract SequenceType getIterationDirection();
+
+    /**
+     * <p>Move forward iterator cursor at x, y coordinates. Cursor is automatically
+     * positioned at band index.<br>
+     *
+     * Code example :<br>
+     * {@code PixelIterator.moveTo(x, y, b);}<br>
+     *
+     * {@code       do} {<br>
+     * {@code           PixelIterator.getSample();//for example}<br>
+     *        } {@code while (PixelIterator.next());}<br>
+     *
+     * MoveTo method is configure to use do...while() loop after moveTo call.</p>
+     *
+     * @param x the x coordinate cursor position.
+     * @param y the y coordinate cursor position.
+     * @param b the band index cursor position.
+     * @throws IllegalArgumentException if coordinates are out of iteration area boundary.
+     */
+    public void moveTo(int x, int y, int b){
+        if (x < areaIterate.minx || x >= areaIterate.maxX
+            ||  y < areaIterate.miny || y >= areaIterate.maxY)
+                throw new IllegalArgumentException("coordinate out of iteration area define by : ("+areaIterate+") \n "
+                        + "given coordinates are : "+x+" "+y);
+        if (b<0 || b>=fixedNumBand)
+            throw new IllegalArgumentException("band index out of numband border define by: [0;"+fixedNumBand+"]");
+    }
+
+    /**
+     * Returns the number of bands (samples per pixel) from Image or Raster within this Iterator.
+     *
+     * @return the number of bands (samples per pixel) from current raster or Image.
+     */
+    public int getNumBands() {
+        return fixedNumBand;
+    }
+
+    /**
+     * Returns {@code Rectangle} which is Image or Raster boundary within this Iterator.
+     *
+     * @param areaIterate true to get area iterate boundary, false to get boundary of object that iterate.
+     * @return {@code Rectangle} which is Image or Raster boundary within this Iterator.
+     */
+    public Rectangle getBoundary(final boolean areaIterate) {
+        return (Rectangle) ((areaIterate) ? this.areaIterate.toRectangle() : objectBoundary.clone());
+    }
+
+    /**
+     * Return {@link RenderedImage} that this iterator travel.
+     *
+     * @return {@link RenderedImage} that this iterator travel or {@code null} if iterator was built to travel {@link Raster}.
+     */
+    public RenderedImage getRenderedImage() {
+        return renderedImage;
+    }
+
+    //-- TODO : methodes suivantes a refactorer (code duplication) + mettre ailleur + static + package private
+    /**
+     * Check that the two input rasters are compatible for coupling in a {@link WritablePixelIterator}
+     */
+    public static void checkRasters(final Raster readableRaster, final WritableRaster writableRaster){
+        //raster dimension
+        if (readableRaster.getMinX()     != writableRaster.getMinX()
+         || readableRaster.getMinY()     != writableRaster.getMinY()
+         || readableRaster.getWidth()    != writableRaster.getWidth()
+         || readableRaster.getHeight()   != writableRaster.getHeight()
+         || readableRaster.getNumBands() != writableRaster.getNumBands())
+         throw new IllegalArgumentException("raster and writable raster are not in same dimension"+readableRaster+writableRaster);
+        //raster data type
+        if (readableRaster.getDataBuffer().getDataType() != writableRaster.getDataBuffer().getDataType())
+            throw new IllegalArgumentException("raster and writable raster haven't got same datas type");
+    }
+
+    /**
+     * Verify Rendered image conformity.
+     */
+    public static void checkRenderedImage(final RenderedImage renderedImage, final WritableRenderedImage writableRI) {
+        //image dimensions
+        if (renderedImage.getMinX()   != writableRI.getMinX()
+         || renderedImage.getMinY()   != writableRI.getMinY()
+         || renderedImage.getWidth()  != writableRI.getWidth()
+         || renderedImage.getHeight() != writableRI.getHeight()
+         || renderedImage.getSampleModel().getNumBands() != writableRI.getSampleModel().getNumBands())
+         throw new IllegalArgumentException("rendered image and writable rendered image dimensions are not conform.\n" +
+                 "First : "+renderedImage+"\nSecond : "+writableRI);
+        final int wrimtx = writableRI.getMinTileX();
+        final int wrimty = writableRI.getMinTileY();
+        final int rimtx  = writableRI.getMinTileX();
+        final int rimty  = writableRI.getMinTileY();
+        //tiles dimensions
+        if (rimtx != wrimtx
+         || rimty != wrimty
+         || renderedImage.getNumXTiles() != writableRI.getNumXTiles()
+         || renderedImage.getNumYTiles() != writableRI.getNumYTiles()
+         || renderedImage.getTileGridXOffset() != writableRI.getTileGridXOffset()
+         || renderedImage.getTileGridYOffset() != writableRI.getTileGridYOffset()
+         || renderedImage.getTileHeight() != writableRI.getTileHeight()
+         || renderedImage.getTileWidth()  != writableRI.getTileWidth())
+            throw new IllegalArgumentException("rendered image and writable rendered image tiles configuration are not conform.\n" +
+                    "First : "+renderedImage+"\nSecond : "+writableRI);
+        //data type
+        // TODO : Should be required only for Direct iterators (working directly with data buffers)
+        if (renderedImage.getTile(rimtx, rimty).getDataBuffer().getDataType() != writableRI.getTile(wrimtx, wrimty).getDataBuffer().getDataType())
+            throw new IllegalArgumentException("rendered image and writable rendered image haven't got same datas type");
+
+    }
+
+    /**
+     * Verify raster conformity.
+     */
+    protected void checkRasters(final Raster readableRaster, final WritableRaster writableRaster, final Rectangle subArea) {
+        final int wRmx = writableRaster.getMinX();
+        final int wRmy = writableRaster.getMinY();
+        final int wRw  = writableRaster.getWidth();
+        final int wRh  = writableRaster.getHeight();
+        if ((wRmx != areaIterate.minx)
+          || wRmy != areaIterate.miny
+          || wRw  != areaIterate.width
+          || wRh  != areaIterate.height)
+
+        //raster dimension
+        if ((readableRaster.getMinX()   != wRmx)
+          || readableRaster.getMinY()   != wRmy
+          || readableRaster.getWidth()  != wRw
+          || readableRaster.getHeight() != wRh)
+         throw new IllegalArgumentException("raster and writable raster are not in same dimension"+readableRaster+writableRaster);
+
+        if (readableRaster.getNumBands() != writableRaster.getNumBands())
+            throw new IllegalArgumentException("raster and writable raster haven't got same band number");
+        //raster data type
+        if (readableRaster.getDataBuffer().getDataType() != writableRaster.getDataBuffer().getDataType())
+            throw new IllegalArgumentException("raster and writable raster haven't got same datas type");
+    }
+
+    /**
+     * Verify Rendered image conformity.
+     */
+    protected void checkRenderedImage(final RenderedImage renderedImage, final WritableRenderedImage writableRI, final Rectangle subArea) {
+        if (renderedImage.getSampleModel().getNumBands() != writableRI.getSampleModel().getNumBands())
+            throw new IllegalArgumentException("renderedImage and writableRenderedImage haven't got same band number");
+        final int riMinX   = renderedImage.getMinX();
+        final int riMinY   = renderedImage.getMinY();
+        final int riTileWidth = renderedImage.getTileWidth();
+        final int riTileHeight = renderedImage.getTileHeight();
+        final int rimtx  = renderedImage.getMinTileX();
+        final int rimty  = renderedImage.getMinTileY();
+
+        final int wrimtx = writableRI.getMinTileX();
+        final int wrimty = writableRI.getMinTileY();
+
+        //data type
+        if (renderedImage.getTile(rimtx, rimty).getDataBuffer().getDataType() != writableRI.getTile(wrimtx, wrimty).getDataBuffer().getDataType())
+            throw new IllegalArgumentException("rendered image and writable rendered image haven't got same datas type");
+
+        //tiles dimensions
+        if (renderedImage.getTileHeight() != writableRI.getTileHeight()
+         || renderedImage.getTileWidth()  != writableRI.getTileWidth()
+         || renderedImage.getTileGridXOffset() != writableRI.getTileGridXOffset()
+         || renderedImage.getTileGridYOffset() != writableRI.getTileGridYOffset())
+            throw new IllegalArgumentException("rendered image and writable rendered image tiles configuration are not conform"+renderedImage+writableRI);
+
+        //verifier les index de tuiles au depart
+        final boolean minTileX = (wrimtx == (areaIterate.minx - riMinX)/ riTileWidth  + rimtx);
+        final boolean minTileY = (wrimty == (areaIterate.miny - riMinY)/ riTileHeight + rimty);
+
+        //writable image correspond with iteration area
+        if (writableRI.getMinX()  != areaIterate.minx    //areaiteration
+         || writableRI.getMinY()  != areaIterate.miny    //areaiteration
+         || writableRI.getWidth() != areaIterate.width//longueuriteration
+         || writableRI.getHeight()!= areaIterate.height//largeuriteration
+         || !minTileX || !minTileY )
+
+        //image dimensions
+        if (renderedImage.getMinX()   != writableRI.getMinX()
+         || renderedImage.getMinY()   != writableRI.getMinY()
+         || renderedImage.getWidth()  != writableRI.getWidth()
+         || renderedImage.getHeight() != writableRI.getHeight()
+         || rimtx != wrimtx || rimty != wrimty
+         || renderedImage.getNumXTiles() != writableRI.getNumXTiles()
+         || renderedImage.getNumYTiles() != writableRI.getNumYTiles())
+         throw new IllegalArgumentException("rendered image and writable rendered image dimensions are not conform"+renderedImage+writableRI);
+    }
+
+    /**
+     * Fill given buffer with samples within the given area at the specified image band.
+     * Adapted for a {@link PixelInterleavedSampleModel} {@link SampleModel} type.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     * @param band the interest band.
+     */
+    private void getAreaByInterleaved(final Rectangle area, final Object buffer, final int band) {
+        rewind();
+        final Rectangle generalArea = getBoundary(false);//-- compute one time
+        final int sourceDataType = getSourceDatatype();
+
+        final int minTX, minTY, maxTX, maxTY;
+
+        if (renderedImage != null) {
+            minTX = tileIndexArea.minx + (area.x - generalArea.x) / tileSize.width;
+            minTY = tileIndexArea.miny + (area.y - generalArea.y) / tileSize.height;
+            maxTX = tileIndexArea.minx + (area.x + area.width + tileSize.width - 1) / tileSize.width;
+            maxTY = tileIndexArea.miny + (area.y + area.height + tileSize.height - 1) / tileSize.height;
+        } else {
+            minTX = minTY = 0;
+            maxTX = maxTY = 1;
+        }
+
+        for (int ty = minTY; ty < maxTY; ty++) {
+            for (int tx = minTX; tx < maxTX; tx++) {
+
+                //-- intersection sur
+                final Raster rast = (renderedImage != null) ? renderedImage.getTile(tx, ty) : currentRaster;
+                final int minX = Math.max(rast.getMinX(), area.x);
+                final int minY = Math.max(rast.getMinY(), area.y);
+                final int maxX = Math.min(rast.getMinX() + tileSize.width, area.x + area.width);
+                final int maxY = Math.min(rast.getMinY() + tileSize.height, area.y + area.height);
+                if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
+
+                final int readLength = (maxX - minX);
+                int destId = 0;
+                for (int y = minY; y < maxY; y++) {
+                    moveTo(minX, y, band);
+                    int s = 0;
+                    int id = destId;
+                    while (s < readLength) {
+
+                        switch (sourceDataType) {
+                            case DataBuffer.TYPE_BYTE : {
+                                ((byte[]) buffer)[id++] = (byte) getSample();
+                                break;
+                            }
+                            case DataBuffer.TYPE_USHORT :
+                            case DataBuffer.TYPE_SHORT  : {
+                                ((short[]) buffer)[id++] = (short) getSample();
+                                break;
+                            }
+                            case DataBuffer.TYPE_INT : {
+                                ((int[]) buffer)[id++] = getSample();
+                                break;
+                            }
+                            case DataBuffer.TYPE_FLOAT : {
+                                ((float[]) buffer)[id++] = getSampleFloat();
+                                break;
+                            }
+                            case DataBuffer.TYPE_DOUBLE : {
+                                ((double[]) buffer)[id++] = getSampleDouble();
+                                break;
+                            }
+                            default : {
+                                throw new IllegalStateException("Unknow datatype.");
+                            }
+                        }
+                        int b = 0;
+                        while (next()) {
+                            if (++b == getNumBands()) break;
+                        }
+                        s++;
+                    }
+                    destId    += area.width;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Fill given buffer with samples within the given area and from all image band.
+     * Adapted for a {@link PixelInterleavedSampleModel} {@link SampleModel} type.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     */
+    private void getAreaByInterleaved(final Rectangle area, final Object[] buffer) {
+        rewind();
+        final Rectangle generalArea = getBoundary(false);//-- compute one time
+        final int sourceDataType = getSourceDatatype();
+
+        final int minTX, minTY, maxTX, maxTY;
+
+        if (renderedImage != null) {
+            minTX = tileIndexArea.minx + (area.x - generalArea.x) / tileSize.width;
+            minTY = tileIndexArea.miny + (area.y - generalArea.y) / tileSize.height;
+            maxTX = tileIndexArea.minx + (area.x + area.width + tileSize.width - 1) / tileSize.width;
+            maxTY = tileIndexArea.miny + (area.y + area.height + tileSize.height - 1) / tileSize.height;
+        } else {
+            minTX = minTY = 0;
+            maxTX = maxTY = 1;
+        }
+
+        for (int ty = minTY; ty < maxTY; ty++) {
+            for (int tx = minTX; tx < maxTX; tx++) {
+
+                //-- intersection sur
+                final Raster rast = (renderedImage != null) ? renderedImage.getTile(tx, ty) : currentRaster;
+                final int minX = Math.max(rast.getMinX(), area.x);
+                final int minY = Math.max(rast.getMinY(), area.y);
+                final int maxX = Math.min(rast.getMinX() + tileSize.width, area.x + area.width);
+                final int maxY = Math.min(rast.getMinY() + tileSize.height, area.y + area.height);
+                if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
+
+                final int readLength = (maxX - minX);
+                int destId = 0;
+                for (int y = minY; y < maxY; y++) {
+                    moveTo(minX, y, 0);
+                    int s = 0;
+                    int id = destId;
+                    while (s < readLength) {
+                        int b = 0;
+                        while (b < getNumBands()) {
+                            switch (sourceDataType) {
+                                case DataBuffer.TYPE_BYTE : {
+                                    ((byte[]) buffer[b])[id++] = (byte) getSample();
+                                    break;
+                                }
+                                case DataBuffer.TYPE_USHORT :
+                                case DataBuffer.TYPE_SHORT  : {
+                                    ((short[]) buffer[b])[id++] = (short) getSample();
+                                    break;
+                                }
+                                case DataBuffer.TYPE_INT : {
+                                    ((int[]) buffer[b])[id++] = getSample();
+                                    break;
+                                }
+                                case DataBuffer.TYPE_FLOAT : {
+                                    ((float[]) buffer[b])[id++] = getSampleFloat();
+                                    break;
+                                }
+                                case DataBuffer.TYPE_DOUBLE : {
+                                    ((double[]) buffer[b])[id++] = getSampleDouble();
+                                    break;
+                                }
+                                default : {
+                                    throw new IllegalStateException("Unknow datatype.");
+                                }
+                            }
+                            b++;
+                            next();
+                        }
+                        s++;
+                    }
+                    destId    += area.width;
+                }
+            }
+        }
+    }
+
+    /**
+     * Fill given buffer with samples within the given area and from all image band.
+     * Adapted for a {@link BandedSampleModel} {@link SampleModel} type.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     */
+    private void getAreaByBanded (final Rectangle area, final Object[] buffer) {
+
+        final ComponentSampleModel compSM = (ComponentSampleModel) currentSampleModel;
+        final int[] bankIndices = compSM.getBankIndices();
+        assert bankIndices.length == getNumBands();
+        final int[] bandOffsets = compSM.getBandOffsets();
+        assert bandOffsets.length == getNumBands();
+
+        final Rectangle generalArea = getBoundary(false);//-- compute one time
+        final int sourceDataType = getSourceDatatype();
+
+        final int minTX, minTY, maxTX, maxTY;
+
+        if (renderedImage != null) {
+            minTX = tileIndexArea.minx + (area.x - generalArea.x) / tileSize.width;
+            minTY = tileIndexArea.miny + (area.y - generalArea.y) / tileSize.height;
+            maxTX = tileIndexArea.minx + (area.x + area.width + tileSize.width - 1) / tileSize.width;
+            maxTY = tileIndexArea.miny + (area.y + area.height + tileSize.height - 1) / tileSize.height;
+        } else {
+            minTX = minTY = 0;
+            maxTX = maxTY = 1;
+        }
+        for (int b = 0; b < getNumBands(); b++) {
+            for (int ty = minTY; ty < maxTY; ty++) {
+                for (int tx = minTX; tx < maxTX; tx++) {
+
+                    //-- intersection sur
+                    final Raster rast = (renderedImage != null) ? renderedImage.getTile(tx, ty) : currentRaster;
+                    final int minX = Math.max(rast.getMinX(), area.x);
+                    final int minY = Math.max(rast.getMinY(), area.y);
+                    final int maxX = Math.min(rast.getMinX() + tileSize.width, area.x + area.width);
+                    final int maxY = Math.min(rast.getMinY() + tileSize.height, area.y + area.height);
+                    if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
+
+                    final DataBuffer databuff = rast.getDataBuffer();
+                    int srcRastId = bandOffsets[b] + ((minY - rast.getMinY()) * tileSize.width + minX - rast.getMinX());
+                    final int readLength = (maxX - minX);
+                    int destId = 0;
+                    for (int y = minY; y < maxY; y++) {
+
+                        switch (sourceDataType) {
+                            case DataBuffer.TYPE_BYTE : {
+                                final byte[] src  = ((DataBufferByte) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (byte[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            case DataBuffer.TYPE_USHORT : {
+                                final short[] src  = ((DataBufferUShort) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (short[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            case DataBuffer.TYPE_SHORT  : {
+                                final short[] src  = ((DataBufferShort) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (short[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            case DataBuffer.TYPE_INT : {
+                                final int[] src  = ((DataBufferInt) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (int[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            case DataBuffer.TYPE_FLOAT : {
+                                final float[] src  = ((DataBufferFloat) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (float[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            case DataBuffer.TYPE_DOUBLE : {
+                                final double[] src  = ((DataBufferDouble) databuff).getData(bankIndices[b]);
+                                System.arraycopy(src, srcRastId, (double[]) buffer[b], destId, readLength);
+                                break;
+                            }
+                            default : {
+                                throw new IllegalStateException("Unknow datatype.");
+                            }
+                        }
+                        srcRastId += tileSize.width;
+                        destId    += area.width;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Fill given buffer with samples within the given area at the specified image band.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     * @param band the interest band.
+     */
+    public void getArea(final Rectangle area, final Object buffer, int band) {
+        ArgumentChecks.ensureNonNull("area", area);
+        ArgumentChecks.ensureNonNull("buffer", buffer);
+
+        final int sourceDataType = getSourceDatatype();
+        final int areaLength = area.width * area.height;
+
+        switch (sourceDataType) {
+            case DataBuffer.TYPE_BYTE : {
+                if (!(buffer instanceof byte[])) throw new IllegalArgumentException("Buffer argument must be instance of byte[][] array");
+                if (((byte[]) buffer).length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_USHORT :
+            case DataBuffer.TYPE_SHORT  : {
+                if (!(buffer instanceof short[])) throw new IllegalArgumentException("Buffer argument must be instance of short[][] array");
+                if (((short[]) buffer).length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_INT : {
+                if (!(buffer instanceof int[])) throw new IllegalArgumentException("Buffer argument must be instance of int[][] array");
+                if (((int[]) buffer).length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_FLOAT : {
+                if (!(buffer instanceof float[])) throw new IllegalArgumentException("Buffer argument must be instance of float[][] array");
+                if (((float[]) buffer).length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_DOUBLE : {
+                if (!(buffer instanceof double[])) throw new IllegalArgumentException("Buffer argument must be instance of double[][] array");
+                if (((double[]) buffer).length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            default : {
+                throw new IllegalStateException("Unknow datatype.");
+            }
+        }
+
+        if (currentSampleModel instanceof ComponentSampleModel) {
+            if (((ComponentSampleModel) currentSampleModel).getPixelStride() == 1) {
+                getAreaByBanded(area, buffer, band);
+                return;
+            }
+        }
+        getAreaByInterleaved(area, buffer, band);
+    }
+
+    /**
+     * Fill given buffer with samples within the given area at the specified image band.
+     * Adapted for a {@link BandedSampleModel} {@link SampleModel} type.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     * @param band the interest band.
+     */
+    public void getAreaByBanded(final Rectangle area, final Object buffer, final int band) {
+        final ComponentSampleModel compSM = (ComponentSampleModel) currentSampleModel;
+        final int bankIndices = compSM.getBankIndices()[band];
+        final int bandOffsets = compSM.getBandOffsets()[band];
+
+        final Rectangle generalArea = getBoundary(false);//-- compute one time
+        final int sourceDataType = getSourceDatatype();
+
+        final int minTX, minTY, maxTX, maxTY;
+
+        if (renderedImage != null) {
+            minTX = tileIndexArea.minx + (area.x - generalArea.x) / tileSize.width;
+            minTY = tileIndexArea.miny + (area.y - generalArea.y) / tileSize.height;
+            maxTX = tileIndexArea.minx + (area.x + area.width + tileSize.width - 1) / tileSize.width;
+            maxTY = tileIndexArea.miny + (area.y + area.height + tileSize.height - 1) / tileSize.height;
+        } else {
+            minTX = minTY = 0;
+            maxTX = maxTY = 1;
+        }
+        for (int ty = minTY; ty < maxTY; ty++) {
+            for (int tx = minTX; tx < maxTX; tx++) {
+
+                //-- intersection sur
+                final Raster rast = (renderedImage != null) ? renderedImage.getTile(tx, ty) : currentRaster;
+                final int minX = Math.max(rast.getMinX(), area.x);
+                final int minY = Math.max(rast.getMinY(), area.y);
+                final int maxX = Math.min(rast.getMinX() + tileSize.width, area.x + area.width);
+                final int maxY = Math.min(rast.getMinY() + tileSize.height, area.y + area.height);
+                if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
+
+                final DataBuffer databuff = rast.getDataBuffer();
+                int srcRastId = bandOffsets + ((minY - rast.getMinY()) * tileSize.width + minX - rast.getMinX());
+                final int readLength = (maxX - minX);
+                int destId = 0;
+                for (int y = minY; y < maxY; y++) {
+
+                    switch (sourceDataType) {
+                        case DataBuffer.TYPE_BYTE : {
+                            final byte[] src  = ((DataBufferByte) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (byte[]) buffer, destId, readLength);
+                            break;
+                        }
+                        case DataBuffer.TYPE_USHORT : {
+                            final short[] src  = ((DataBufferUShort) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (short[]) buffer, destId, readLength);
+                            break;
+                        }
+                        case DataBuffer.TYPE_SHORT  : {
+                            final short[] src  = ((DataBufferShort) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (short[]) buffer, destId, readLength);
+                            break;
+                        }
+                        case DataBuffer.TYPE_INT : {
+                            final int[] src  = ((DataBufferInt) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (int[]) buffer, destId, readLength);
+                            break;
+                        }
+                        case DataBuffer.TYPE_FLOAT : {
+                            final float[] src  = ((DataBufferFloat) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (float[]) buffer, destId, readLength);
+                            break;
+                        }
+                        case DataBuffer.TYPE_DOUBLE : {
+                            final double[] src  = ((DataBufferDouble) databuff).getData(bankIndices);
+                            System.arraycopy(src, srcRastId, (double[]) buffer, destId, readLength);
+                            break;
+                        }
+                        default : {
+                            throw new IllegalStateException("Unknow datatype.");
+                        }
+                    }
+                    srcRastId += tileSize.width;
+                    destId    += area.width;
+                }
+            }
+        }
+    }
+
+    /**
+     * Fill given buffer with samples within the given area and from all the source image band.
+     *
+     * @param area define needed samples area.
+     * @param buffer array which will be filled by samples.
+     */
+    public void getArea(final Rectangle area, final Object[] buffer) {
+        ArgumentChecks.ensureNonNull("area", area);
+        ArgumentChecks.ensureNonNull("buffer", buffer);
+        if (buffer.length < getNumBands()) throw new IllegalArgumentException("buffer must have length equals to numbands. Found : "+buffer.length+". Expected : "+getNumBands());
+
+        final int sourceDataType = getSourceDatatype();
+        final int areaLength = area.width * area.height * getNumBands();
+
+        switch (sourceDataType) {
+            case DataBuffer.TYPE_BYTE : {
+                if (!(buffer instanceof byte[][])) throw new IllegalArgumentException("Buffer argument must be instance of byte[][] array");
+                if (((byte[][]) buffer)[0].length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_USHORT :
+            case DataBuffer.TYPE_SHORT  : {
+                if (!(buffer instanceof short[][])) throw new IllegalArgumentException("Buffer argument must be instance of short[][] array");
+                if (((short[][]) buffer)[0].length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_INT : {
+                if (!(buffer instanceof int[][])) throw new IllegalArgumentException("Buffer argument must be instance of int[][] array");
+                if (((int[][]) buffer)[0].length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_FLOAT : {
+                if (!(buffer instanceof float[][])) throw new IllegalArgumentException("Buffer argument must be instance of float[][] array");
+                if (((float[][]) buffer)[0].length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            case DataBuffer.TYPE_DOUBLE : {
+                if (!(buffer instanceof double[][])) throw new IllegalArgumentException("Buffer argument must be instance of double[][] array");
+                if (((double[][]) buffer)[0].length < areaLength) throw new IllegalArgumentException("Buffer must have a length equal or upper than area sample number. Expected : "+areaLength);
+                break;
+            }
+            default : {
+                throw new IllegalStateException("Unknow datatype.");
+            }
+        }
+
+        if (currentSampleModel instanceof ComponentSampleModel) {
+            if (((ComponentSampleModel) currentSampleModel).getPixelStride() == 1) {
+                getAreaByBanded(area, buffer);
+                return;
+            }
+        }
+        getAreaByInterleaved(area, buffer);
+    }
+
+    /**
+     * Return type data from iterate source.
+     * @return type data from iterate source.
+     */
+    public int getSourceDatatype() {
+        return (renderedImage == null) ? currentRaster.getSampleModel().getDataType() : renderedImage.getSampleModel().getDataType();
+    }
+
+    /**
+     * Compute an array which give the number of data elements until the next sample in the pixel. Note that the first
+     * element gives number of elements between the last sample of the previous pixel and the first sample of current one.
+     * @param bandOffsets The bandOffsets table given by {@link java.awt.image.ComponentSampleModel#getBandOffsets()}.
+     * @param pixelStride The pixel stride value given by {@link java.awt.image.ComponentSampleModel#getPixelStride()}
+     * @return An array whose components are the number of elements to skip until the next sample.
+     */
+     public static int[] getBandSteps(final int[] bandOffsets, final int pixelStride) {
+        final int[] bandSteps = new int[bandOffsets.length];
+        bandSteps[0] = bandOffsets[0] + pixelStride - bandOffsets[bandOffsets.length-1];
+        for (int i = 1 ; i < bandSteps.length ; i++) {
+            bandSteps[i] = bandOffsets[i] - bandOffsets[i-1];
+        }
+        return bandSteps;
+    }
+}

Added: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIteratorFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIteratorFactory.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIteratorFactory.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/PixelIteratorFactory.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.Rectangle;
+import java.awt.image.*;
+import java.util.Arrays;
+
+/**
+ * Create an appropriate iterator.
+ *
+ * @author Rémi Marechal (Geomatys).
+ */
+public final class PixelIteratorFactory {
+
+    private PixelIteratorFactory() {
+    }
+
+    /**
+     * Create and return an adapted default {@link Raster} iterator.
+     *
+     * @param raster   {@link Raster} will be traveled by iterator.
+     * @return adapted {@link PixelIterator}.
+     */
+    public static PixelIterator createReadOnlyIterator(final Raster raster) {
+        return PixelIteratorFactory.createReadOnlyIterator(raster, null);
+    }
+
+    /**
+     * Create and return an adapted default read-only {@link Raster} iterator to read on raster sub-area.
+     *
+     * @param raster      {@link Raster} will be traveled by iterator from it's sub-area.
+     * @param subReadArea {@link Rectangle} which define raster read area.
+     * @return adapted    {@link PixelIterator}.
+     */
+    public static PixelIterator createReadOnlyIterator(final Raster raster, final Rectangle subReadArea) {
+//        final SampleModel sampleM = raster.getSampleModel();
+//
+//        if (sampleM instanceof ComponentSampleModel) {
+//            if (checkBankIndices(((ComponentSampleModel)sampleM).getBankIndices())) {
+//                switch (sampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new DefaultDirectByteIterator(raster, subReadArea);
+//                    case DataBuffer.TYPE_FLOAT : return new DefaultDirectFloatIterator(raster, subReadArea);
+//                    default : return new DefaultIterator(raster, subReadArea);
+//                }
+//            }
+//        }
+        return new DefaultIterator(raster, subReadArea);
+    }
+
+    /**
+     * Create and return an adapted default read-only {@link RenderedImage} iterator.
+     *
+     * @param renderedImage {@link RenderedImage} will be traveled by iterator.
+     * @return adapted      {@link PixelIterator}.
+     */
+    public static PixelIterator createReadOnlyIterator(final RenderedImage renderedImage) {
+       return createReadOnlyIterator(renderedImage, null);
+    }
+
+    /**
+     * Create and return an adapted default read-only {@link RenderedImage} iterator to read on raster sub-area.
+     *
+     * @param renderedImage {@link RenderedImage} will be traveled by iterator from it's sub-area.
+     * @param subReadArea   {@link Rectangle} which define rendered image read area.
+     * @return adapted      {@link PixelIterator}.
+     */
+    public static PixelIterator createReadOnlyIterator(final RenderedImage renderedImage, final Rectangle subReadArea) {
+        if (isSingleRaster(renderedImage)){
+            return PixelIteratorFactory.createReadOnlyIterator(renderedImage.getTile(renderedImage.getMinTileX(), renderedImage.getMinTileY()), subReadArea);
+        }
+
+//        final SampleModel sampleM = renderedImage.getSampleModel();
+//        if (sampleM instanceof ComponentSampleModel ) {
+//            if (checkBankIndices(((ComponentSampleModel)sampleM).getBankIndices())) {
+//                switch (sampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new DefaultDirectByteIterator(renderedImage, subReadArea);
+//                    case DataBuffer.TYPE_FLOAT : return new DefaultDirectFloatIterator(renderedImage, subReadArea);
+//                    default : return new DefaultIterator(renderedImage, subReadArea);
+//                }
+//            }
+//        }
+        return new DefaultIterator(renderedImage, subReadArea);
+    }
+
+    //-- NOT IMPLEMENTED YET
+//
+//    /**
+//     * Create and return an adapted default read and write raster iterator.
+//     *
+//     * @param raster          {@link Raster} will be traveled by read-only iterator.
+//     * @param writeableRaster {@link WritableRaster} raster wherein value is set (write).
+//     * @return adapted        {@link PixelIterator} .
+//     */
+//    public static PixelIterator createDefaultWriteableIterator(final Raster raster, final WritableRaster writeableRaster) {
+//        return createDefaultWriteableIterator(raster, writeableRaster, null);
+//    }
+//
+//    /**
+//     * Create and return an adapted default read and write raster iterator.
+//     * Iterator move in a raster sub-area.
+//     *
+//     * @param raster          {@link Raster} will be traveled by read-only iterator.
+//     * @param writeableRaster {@link WritableRaster} raster wherein value is set (write).
+//     * @param subArea     {@link Rectangle} which define raster read and write area.
+//     * @return adapted        {@link PixelIterator}.
+//     */
+//    public static PixelIterator createDefaultWriteableIterator(final Raster raster, final WritableRaster writeableRaster, final Rectangle subArea) {
+//        final SampleModel srcSampleM = raster.getSampleModel();
+//        final SampleModel destSampleM = raster.getSampleModel();
+//        PixelIterator.checkRasters(raster, writeableRaster);
+//
+//        if (srcSampleM instanceof ComponentSampleModel && destSampleM instanceof ComponentSampleModel) {
+//            ComponentSampleModel srcCSModel = (ComponentSampleModel) srcSampleM;
+//            ComponentSampleModel destCSModel = (ComponentSampleModel) destSampleM;
+//
+//            // Source and destination image must have identical structure in order to allow a single iterator to move through them.
+//            if (checkBankIndices(srcCSModel.getBankIndices()) && checkBankIndices(destCSModel.getBankIndices())
+//             && Arrays.equals(srcCSModel.getBandOffsets(), destCSModel.getBandOffsets())
+//             && srcCSModel.getPixelStride() == destCSModel.getPixelStride()
+//             && srcCSModel.getScanlineStride() == destCSModel.getScanlineStride()) {
+//
+//                switch (srcSampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new DefaultWritableDirectByteIterator(raster, writeableRaster, subArea);
+//                    case DataBuffer.TYPE_FLOAT : return new DefaultWritableDirectFloatIterator(raster, writeableRaster, subArea);
+//                    default : return new DefaultWritableIterator(raster, writeableRaster, subArea);
+//                }
+//            }
+//        }
+//        return new DefaultWritableIterator(raster, writeableRaster, subArea);
+//    }
+//
+//    /**
+//     * Create and return an adapted default read and write rendered image iterator.
+//     *
+//     * @param renderedImage         {@link RenderedImage} will be traveled by iterator.
+//     * @param writableRenderedImage {@link WritableRenderedImage} rendered image wherein value is set (write).
+//     * @return adapted              {@link PixelIterator}.
+//     */
+//    public static PixelIterator createDefaultWriteableIterator(final RenderedImage renderedImage, final WritableRenderedImage writableRenderedImage) {
+//        return createDefaultWriteableIterator(renderedImage, writableRenderedImage, null);
+//    }
+//
+//    /**
+//     * Create and return an adapted default read and write rendered image iterator from it's sub-area.
+//     *
+//     * @param renderedImage         {@link RenderedImage} will be traveled by iterator from it's sub-area.
+//     * @param writableRenderedImage {@link WritableRenderedImage} rendered image wherein value is set (write).
+//     * @param subArea               {@link Rectangle} which define rendered image read and write area.
+//     * @return adapted              {@link PixelIterator}.
+//     */
+//    public static PixelIterator createDefaultWriteableIterator(final RenderedImage renderedImage, final WritableRenderedImage writableRenderedImage, final Rectangle subArea) {
+//        final SampleModel srcSampleM = renderedImage.getSampleModel();
+//        final SampleModel destSampleM = renderedImage.getSampleModel();
+//
+//        if (srcSampleM instanceof ComponentSampleModel && destSampleM instanceof ComponentSampleModel) {
+//            ComponentSampleModel srcCSModel = (ComponentSampleModel) srcSampleM;
+//            ComponentSampleModel destCSModel = (ComponentSampleModel) destSampleM;
+//
+//            // Source and destination image must have identical structure in order to allow a single iterator to move through them.
+//            if (checkBankIndices(srcCSModel.getBankIndices()) && checkBankIndices(destCSModel.getBankIndices())
+//                    && Arrays.equals(srcCSModel.getBandOffsets(), destCSModel.getBandOffsets())
+//                    && srcCSModel.getPixelStride() == destCSModel.getPixelStride()
+//                    && srcCSModel.getScanlineStride() == destCSModel.getScanlineStride()) {
+//
+//                switch (srcSampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new DefaultWritableDirectByteIterator(renderedImage, writableRenderedImage, subArea);
+//                    case DataBuffer.TYPE_FLOAT : return new DefaultWritableDirectFloatIterator(renderedImage, writableRenderedImage, subArea);
+//                    default : return new DefaultWritableIterator(renderedImage, writableRenderedImage, subArea);
+//                }
+//            }
+//        }
+//        return new DefaultWritableIterator(renderedImage, writableRenderedImage, subArea);
+//    }
+
+    ////////////////////////////// Row Major Iterator ////////////////////////////
+
+//    /**
+//     * Create and return an adapted Row Major read-only rendered image iterator.
+//     * RowMajor : iterator move forward line per line one by one in downward order.
+//     *
+//     * @param renderedImage {@link RenderedImage} will be traveled by iterator.
+//     * @return adapted      {@link PixelIterator}.
+//     */
+//    public static PixelIterator createRowMajorIterator(final RenderedImage renderedImage) {
+//        return createRowMajorIterator(renderedImage, null);
+//    }
+//
+//    /**
+//     * Create and return an adapted Row Major read-only rendered image iterator from it's sub-area.
+//     * RowMajor : iterator move forward line per line one by one in downward order.
+//     *
+//     * @param renderedImage {@link RenderedImage} will be traveled by iterator from it's sub-area.
+//     * @param subReadArea   {@link Rectangle} which define rendered image read-only area.
+//     * @return adapted      {@link PixelIterator}.
+//     */
+//    public static PixelIterator createRowMajorIterator(final RenderedImage renderedImage, final Rectangle subReadArea) {
+//        final SampleModel sampleM = renderedImage.getSampleModel();
+//        if (sampleM instanceof ComponentSampleModel) {
+//            if (checkBankIndices(((ComponentSampleModel)sampleM).getBankIndices())) {
+//                switch (sampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new RowMajorDirectByteIterator(renderedImage, subReadArea);
+//                    case DataBuffer.TYPE_FLOAT : return new RowMajorDirectFloatIterator(renderedImage, subReadArea);
+//                    default : return new RowMajorIterator(renderedImage, subReadArea);
+//                }
+//            }
+//        }
+//        return new RowMajorIterator(renderedImage, subReadArea);
+//    }
+//
+//    /**
+//     * Create and return an adapted Row Major read and write rendered image iterator.
+//     * RowMajor : iterator move forward line per line one by one in downward order.
+//     *
+//     * No build is allowed for single {@link java.awt.image.Raster} browsing, because {@link org.geotoolkit.image.iterator.DefaultDirectIterator}
+//     * will do the job as fast as it, and with the same behavior.
+//     *
+//     * @param renderedImage         {@link RenderedImage} will be traveled by iterator.
+//     * @param writableRenderedImage {@link WritableRenderedImage}  rendered image wherein value is set (write).
+//     * @return adapted              {@link PixelIterator}.
+//     */
+//    public static PixelIterator createRowMajorWriteableIterator(final RenderedImage renderedImage, final WritableRenderedImage writableRenderedImage) {
+//        return createRowMajorWriteableIterator(renderedImage, writableRenderedImage, null);
+//    }
+//
+//    /**
+//     * Create and return an adapted Row Major read and write rendered image iterator from it's sub-area.
+//     * RowMajor : iterator move forward line per line one by one in downward order.
+//     *
+//     * No build is allowed for single {@link java.awt.image.Raster} browsing, because {@link org.geotoolkit.image.iterator.DefaultDirectIterator}
+//     * will do the job as fast as it, and with the same behavior.
+//     *
+//     * @param renderedImage         {@link RenderedImage} will be traveled by iterator from it's sub-area.
+//     * @param writableRenderedImage {@link WritableRenderedImage}  rendered image wherein value is set (write).
+//     * @param subArea               {@link Rectangle} which define rendered image read and write area.
+//     * @return adapted              {@link PixelIterator}.
+//     */
+//    public static PixelIterator createRowMajorWriteableIterator(final RenderedImage renderedImage, final WritableRenderedImage writableRenderedImage, final Rectangle subArea) {
+//        final SampleModel srcSampleM = renderedImage.getSampleModel();
+//        final SampleModel destSampleM = renderedImage.getSampleModel();
+//
+//        if (srcSampleM instanceof ComponentSampleModel && destSampleM instanceof ComponentSampleModel) {
+//            ComponentSampleModel srcCSModel = (ComponentSampleModel) srcSampleM;
+//            ComponentSampleModel destCSModel = (ComponentSampleModel) destSampleM;
+//
+//            // Source and destination image must have identical structure in order to allow a single iterator to move through them.
+//            if (checkBankIndices(srcCSModel.getBankIndices()) && checkBankIndices(destCSModel.getBankIndices())
+//                    && Arrays.equals(srcCSModel.getBandOffsets(), destCSModel.getBandOffsets())
+//                    && srcCSModel.getPixelStride() == destCSModel.getPixelStride()
+//                    && srcCSModel.getScanlineStride() == destCSModel.getScanlineStride()) {
+//
+//                switch (srcSampleM.getDataType()) {
+//                    case DataBuffer.TYPE_BYTE  : return new RowMajorWritableDirectByteIterator(renderedImage, writableRenderedImage, subArea);
+//                    case DataBuffer.TYPE_FLOAT : return new RowMajorWritableDirectFloatIterator(renderedImage, writableRenderedImage, subArea);
+//                    default : return new RowMajorWritableIterator(renderedImage, writableRenderedImage, subArea);
+//                }
+//            }
+//        }
+//        return new RowMajorWritableIterator(renderedImage, writableRenderedImage, subArea);
+//    }
+
+    /**
+     * Verify bandOffset table conformity.
+     *
+     * @param bandOffset band offset table.
+     * @return true if bandOffset table is conform else false.
+     */
+    private static boolean checkBandOffset(int[] bandOffset) {
+        for (int i = 0, l = bandOffset.length; i<l; i++) if (bandOffset[i] != i) return false;
+        return true;
+    }
+
+    /**
+     * Check image samples are stored in a single bank.
+     *
+     * @param bankIndices bank indice table retrieved from input image (see {@link java.awt.image.ComponentSampleModel#getBankIndices()}.
+     * @return true if input image use a single bank. false otherwise.
+     */
+    private static boolean checkBankIndices(int[] bankIndices) {
+        if (bankIndices.length == 1) return true;
+        for (int i = 1, l = bankIndices.length; i<l; i++) if (bankIndices[i] != bankIndices[i-1]) return false;
+        return true;
+    }
+
+    private static boolean isSingleRaster(final RenderedImage renderedImage){
+        return renderedImage.getNumXTiles()==1 && renderedImage.getNumYTiles()==1;
+    }
+
+}

Added: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/RectIter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/RectIter.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/RectIter.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/RectIter.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.Rectangle;
+
+/**
+ * To avoid unneccessary recomputing of method {@link Rectangle#getMaxX() }
+ * or {@link Rectangle#getMaxY() } do a new integer Rectangle implementation only used by {@link PixelIterator}
+ *
+ * @author Remi Marechal (Geomatys).
+ */
+class RectIter {
+
+    final int minx;
+    final int miny;
+    final int maxX;
+    final int maxY;
+    final int width;
+    final int height;
+
+    /**
+     * Create integer Rectangle with no boundary coordinate recomputing.
+     *
+     * @param rect origin coordinates references.
+     */
+    RectIter(final Rectangle rect) {
+        this.minx   = rect.x;
+        this.miny   = rect.y;
+        this.width  = rect.width;
+        this.height = rect.height;
+        this.maxX   = minx + width;
+        this.maxY   = miny + height;
+    }
+
+    /**
+     * Create integer Rectangle with no boundary coordinate recomputing.
+     *
+     * @param minx minimum lower left corner in X direction.
+     * @param miny minimum lower left corner in Y direction.
+     * @param width width in X direction.
+     * @param height height in Y direction.
+     */
+    RectIter(final int minx, final int miny, final int width, final int height) {
+        this.minx   = minx;
+        this.miny   = miny;
+        this.width  = width;
+        this.height = height;
+        this.maxX   = this.minx + width;
+        this.maxY   = this.miny + height;
+    }
+
+    boolean isEmpty() {
+        return (maxX <= minx || maxY <= miny);
+    }
+
+    Rectangle toRectangle() {
+        return new Rectangle(minx, miny, width, height);
+    }
+}

Added: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/WritablePixelIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/WritablePixelIterator.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/WritablePixelIterator.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/iterator/WritablePixelIterator.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.Rectangle;
+import java.awt.image.WritableRaster;
+import java.awt.image.WritableRenderedImage;
+
+/**
+ *
+ * @author Remi Marechal (Geomatys).
+ */
+abstract class WritablePixelIterator extends PixelIterator {
+
+    private final WritableRaster wRaster;
+
+    private final WritableRenderedImage wRenderedImage;
+
+    public WritablePixelIterator(WritableRaster raster, Rectangle subArea) {
+        super(raster, subArea);
+        wRaster        = raster;
+        wRenderedImage = null;
+    }
+
+    public WritablePixelIterator(WritableRenderedImage renderedImage, Rectangle subArea) {
+        super(renderedImage, subArea);
+        wRaster        = null;
+        wRenderedImage = renderedImage;
+    }
+
+    /**
+     * Write integer value at current iterator position.
+     *
+     * @param value integer to write.
+     */
+    public abstract void setSample(final int value);
+
+    /**
+     * Write float value at current iterator position.
+     *
+     * @param value float to write.
+     */
+    public abstract void setSampleFloat(final float value);
+
+    /**
+     * Write double value at current iterator position.
+     *
+     * @param value double to write.
+     */
+    public abstract void setSampleDouble(final double value);
+
+}

Added: sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/DefaultReadOnlyTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/DefaultReadOnlyTest.java?rev=1803291&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/DefaultReadOnlyTest.java (added)
+++ sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/iterator/DefaultReadOnlyTest.java Fri Jul 28 16:08:28 2017
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.iterator;
+
+import java.awt.image.DataBuffer;
+
+/**
+ * Some Basic core tests about Iterator.
+ *
+ * @author Rémi Marechal (Geomatys).
+ */
+public class DefaultReadOnlyTest extends ReadOnlyTest {
+
+    /**
+     * Table which contains expected tests results values.
+     */
+    private int[] tabRef;
+
+    /**
+     * Table which contains tests results values.
+     */
+    private int[] tabTest;
+
+    public DefaultReadOnlyTest() {
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected void setTabTestValue(int index, double value) {
+        tabTest[index] = (int)value;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected void setTabRefValue(int index, double value) {
+        tabRef[index] = (int) value;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected boolean compareTab() {
+        return compareTab(tabRef, tabTest);
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected void setMoveToRITabs(int indexCut, int length) {
+        tabTest = new int[length];
+        int[] tabTemp = new int[length];
+        System.arraycopy(tabRef.clone(), indexCut, tabTemp, 0, length);
+        tabRef = tabTemp.clone();
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected int getDataBufferType() {
+        return DataBuffer.TYPE_INT;
+    }
+
+    /**
+     * {@inheritDoc }.
+     */
+    @Override
+    protected void createTable(int length) {
+        tabRef = new int[length];
+        tabTest = new int[length];
+    }
+}



Mime
View raw message