You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/07/29 17:13:10 UTC
svn commit: r1803381 - in /sis/branches/JDK8/core/sis-raster/src:
main/java/org/apache/sis/image/ test/java/org/apache/sis/image/
Author: desruisseaux
Date: Sat Jul 29 17:13:10 2017
New Revision: 1803381
URL: http://svn.apache.org/viewvc?rev=1803381&view=rev
Log:
Review of TiledImage, and begining review of PixelIterator.
Added:
sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/TiledImage.java
- copied, changed from r1803380, sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/IteratorTestImage.java
Removed:
sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/IteratorTestImage.java
Modified:
sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java
sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java
sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/package-info.java
sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/PixelIteratorTest.java
Modified: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java?rev=1803381&r1=1803380&r2=1803381&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java [UTF-8] Sat Jul 29 17:13:10 2017
@@ -141,8 +141,8 @@ class DefaultIterator extends PixelItera
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.currentRasterMaxX = Math.min(areaIterate.maxX, cRMinX + tileWidth);
+ this.currentRasterMaxY = Math.min(areaIterate.maxY, cRMinY + tileHeight);
this.rasterNumBand = this.currentRaster.getNumBands(); //-- ??? what is this attributs
}
@@ -215,8 +215,8 @@ class DefaultIterator extends PixelItera
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();
+ final int tmpTX = (x - riMinX) / tileWidth + renderedImage.getMinTileX();
+ final int tmpTY = (y - riMinY) / tileHeight + renderedImage.getMinTileY();
if (tmpTX != tX || tmpTY != tY) {
tX = tmpTX;
tY = tmpTY;
Modified: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java?rev=1803381&r1=1803380&r2=1803381&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/PixelIterator.java [UTF-8] Sat Jul 29 17:13:10 2017
@@ -16,7 +16,6 @@
*/
package org.apache.sis.image;
-import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
@@ -34,14 +33,14 @@ 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;
+import org.apache.sis.util.ArgumentChecks;
+
/**
- * An iterator over sample values in an image. This iterator make easier to get the values
- * without managing the complexity of various {@linkplain SampleModel sample model} and tiling.
- * Iteration may be done on a full image or only a sub-area of it.
- * Iteration order is implementation specific.
+ * An iterator over sample values in a raster or an image. This iterator simplifies accesses to sample values
+ * by hiding the {@linkplain SampleModel sample model} and tiling complexity. Iteration may be done on a full
+ * image or on only a sub-area of it. Iteration order is implementation specific.
*
* @author Rémi Marechal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
@@ -50,16 +49,15 @@ import org.opengis.coverage.grid.Sequenc
* @module
*/
public abstract class PixelIterator implements Closeable {
-
/**
* Define boundary, in pixel coordinates, of area traveled by this PixeIterator.
- * @see #getBoundary(boolean)
+ *
+ * @see #getDomain()
*/
final RectIter areaIterate;
/**
* Define boundary, in pixel coordinates, of iterated object.
- * @see #getBoundary(boolean)
*/
private final Rectangle objectBoundary;
@@ -72,7 +70,7 @@ public abstract class PixelIterator impl
/**
* Size of tiles from iterated object.
*/
- final Dimension tileSize;
+ final int tileWidth, tileHeight;
/**
* Current raster which is followed by Iterator.
@@ -83,11 +81,11 @@ public abstract class PixelIterator impl
* RenderedImage which is followed by Iterator.
*/
final RenderedImage renderedImage;
-//
+
/**
* Number of band.
*/
- final int fixedNumBand;
+ private final int fixedNumBand;
/**
* Number of raster band.
@@ -103,7 +101,7 @@ public abstract class PixelIterator impl
/**
* {@link SampleModel} from the iterate object.
*/
- final SampleModel currentSampleModel;
+ private final SampleModel currentSampleModel;
//-- Iteration attributs
/**
@@ -130,9 +128,10 @@ public abstract class PixelIterator impl
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);
+ currentRaster = raster;
+ renderedImage = null;
+ tileWidth = objectBoundary.width;
+ tileHeight = objectBoundary.height;
currentSampleModel = raster.getSampleModel();
areaIterate = new RectIter((subArea != null)
? subArea.intersection(objectBoundary)
@@ -162,7 +161,8 @@ public abstract class PixelIterator impl
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());
+ tileWidth = renderedImage.getTileWidth();
+ tileHeight = renderedImage.getTileHeight();
currentSampleModel = renderedImage.getSampleModel();
areaIterate = new RectIter((subArea != null)
? subArea.intersection(objectBoundary)
@@ -176,10 +176,10 @@ public abstract class PixelIterator impl
{
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;
+ final int tMinX = (areaIterate.minx - objectBoundary.x) / tileWidth + offTX;
+ final int tMinY = (areaIterate.miny - objectBoundary.y) / tileHeight + offTY;
+ final int tMaxX = (areaIterate.maxX - objectBoundary.x + tileWidth - 1) / tileWidth + offTX;
+ final int tMaxY = (areaIterate.maxY - objectBoundary.y + tileHeight - 1) / tileHeight + offTY;
tileIndexArea = new RectIter(tMinX, tMinY, tMaxX - tMinX, tMaxY - tMinY);
}
@@ -292,22 +292,12 @@ public abstract class PixelIterator impl
}
/**
- * 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.
+ * Returns the pixel coordinates of the area in which this iterator is doing the iteration.
*
- * @return {@link RenderedImage} that this iterator travel or {@code null} if iterator was built to travel {@link Raster}.
+ * @return pixel coordinates of the iteration area.
*/
- public RenderedImage getRenderedImage() {
- return renderedImage;
+ public Rectangle getDomain() {
+ return areaIterate.toRectangle();
}
//-- TODO : methodes suivantes a refactorer (code duplication) + mettre ailleur + static + package private
@@ -447,16 +437,15 @@ public abstract class PixelIterator impl
*/
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;
+ minTX = tileIndexArea.minx + (area.x - objectBoundary.x) / tileWidth;
+ minTY = tileIndexArea.miny + (area.y - objectBoundary.y) / tileHeight;
+ maxTX = tileIndexArea.minx + (area.x + area.width + tileWidth - 1) / tileWidth;
+ maxTY = tileIndexArea.miny + (area.y + area.height + tileHeight - 1) / tileHeight;
} else {
minTX = minTY = 0;
maxTX = maxTY = 1;
@@ -469,8 +458,8 @@ public abstract class PixelIterator impl
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);
+ final int maxX = Math.min(rast.getMinX() + tileWidth, area.x + area.width);
+ final int maxY = Math.min(rast.getMinY() + tileHeight, area.y + area.height);
if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
final int readLength = (maxX - minX);
@@ -529,16 +518,15 @@ public abstract class PixelIterator impl
*/
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;
+ minTX = tileIndexArea.minx + (area.x - objectBoundary.x) / tileWidth;
+ minTY = tileIndexArea.miny + (area.y - objectBoundary.y) / tileHeight;
+ maxTX = tileIndexArea.minx + (area.x + area.width + tileWidth - 1) / tileWidth;
+ maxTY = tileIndexArea.miny + (area.y + area.height + tileHeight - 1) / tileHeight;
} else {
minTX = minTY = 0;
maxTX = maxTY = 1;
@@ -551,8 +539,8 @@ public abstract class PixelIterator impl
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);
+ final int maxX = Math.min(rast.getMinX() + tileWidth, area.x + area.width);
+ final int maxY = Math.min(rast.getMinY() + tileHeight, area.y + area.height);
if (minX > maxX || minY > maxY) throw new IllegalArgumentException("Expected area don't intersect internal data.");
final int readLength = (maxX - minX);
@@ -616,16 +604,15 @@ public abstract class PixelIterator impl
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;
+ minTX = tileIndexArea.minx + (area.x - objectBoundary.x) / tileWidth;
+ minTY = tileIndexArea.miny + (area.y - objectBoundary.y) / tileHeight;
+ maxTX = tileIndexArea.minx + (area.x + area.width + tileWidth - 1) / tileWidth;
+ maxTY = tileIndexArea.miny + (area.y + area.height + tileHeight - 1) / tileHeight;
} else {
minTX = minTY = 0;
maxTX = maxTY = 1;
@@ -638,12 +625,12 @@ public abstract class PixelIterator impl
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);
+ final int maxX = Math.min(rast.getMinX() + tileWidth, area.x + area.width);
+ final int maxY = Math.min(rast.getMinY() + tileHeight, 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());
+ int srcRastId = bandOffsets[b] + ((minY - rast.getMinY()) * tileWidth + minX - rast.getMinX());
final int readLength = (maxX - minX);
int destId = 0;
for (int y = minY; y < maxY; y++) {
@@ -683,7 +670,7 @@ public abstract class PixelIterator impl
throw new IllegalStateException("Unknow datatype.");
}
}
- srcRastId += tileSize.width;
+ srcRastId += tileWidth;
destId += area.width;
}
}
@@ -759,16 +746,15 @@ public abstract class PixelIterator impl
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;
+ minTX = tileIndexArea.minx + (area.x - objectBoundary.x) / tileWidth;
+ minTY = tileIndexArea.miny + (area.y - objectBoundary.y) / tileHeight;
+ maxTX = tileIndexArea.minx + (area.x + area.width + tileWidth - 1) / tileWidth;
+ maxTY = tileIndexArea.miny + (area.y + area.height + tileHeight - 1) / tileHeight;
} else {
minTX = minTY = 0;
maxTX = maxTY = 1;
@@ -780,12 +766,12 @@ public abstract class PixelIterator impl
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);
+ final int maxX = Math.min(rast.getMinX() + tileWidth, area.x + area.width);
+ final int maxY = Math.min(rast.getMinY() + tileHeight, 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());
+ int srcRastId = bandOffsets + ((minY - rast.getMinY()) * tileWidth + minX - rast.getMinX());
final int readLength = (maxX - minX);
int destId = 0;
for (int y = minY; y < maxY; y++) {
@@ -825,7 +811,7 @@ public abstract class PixelIterator impl
throw new IllegalStateException("Unknow datatype.");
}
}
- srcRastId += tileSize.width;
+ srcRastId += tileWidth;
destId += area.width;
}
}
@@ -902,7 +888,7 @@ public abstract class PixelIterator impl
* @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) {
+ 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++) {
Modified: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/package-info.java?rev=1803381&r1=1803380&r2=1803381&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/package-info.java [UTF-8] Sat Jul 29 17:13:10 2017
@@ -17,8 +17,17 @@
/**
* Provides helper classes for handling Java2D rendered images together with some operations.
- * This package does not use any geospatial functions; it works only on "pure" images (not necessarily RGB).
- * However this package is used as a basis for georeferenced or georeferenceable <cite>grid coverages</cite>.
+ * This package does not provide any geospatial functionalities;
+ * it works only on sample or pixel values stored in {@link java.awt.image.RenderedImage}s.
+ * Note that Java2D {@code RenderedImage}s have the following capabilities:
+ *
+ * <ul>
+ * <li>Images may have an arbitrary number of bands (not necessarily RGB).</li>
+ * <li>Sample values can be bytes, shorts (signed or unsigned), integers or floating-point values.</li>
+ * <li>Images can be tiled.</li>
+ * </ul>
+ *
+ * This package is used as a basis for georeferenced or georeferenceable <cite>grid coverages</cite>.
*
* @author Rémi Maréchal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
Modified: sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/PixelIteratorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/PixelIteratorTest.java?rev=1803381&r1=1803380&r2=1803381&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/PixelIteratorTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/PixelIteratorTest.java [UTF-8] Sat Jul 29 17:13:10 2017
@@ -36,7 +36,8 @@ import static org.junit.Assert.*;
/**
- * Base class of {@link PixelIterator} tests.
+ * Base class of {@link PixelIterator} tests. This base class tests the default read-only iterator
+ * on integer values. Subclasses will test variants, for example the read-write iterator.
*
* @author Rémi Maréchal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
@@ -143,7 +144,7 @@ public strictfp class PixelIteratorTest
}
expected = new float[(subMaxX - subMinX) * (subMaxY - subMinY) * numBands];
final WritableRaster raster = Raster.createWritableRaster(new PixelInterleavedSampleModel(dataType,
- width, height, numBands, width * numBands, new int[] {0,1,2}), new Point(xmin, ymin));
+ width, height, numBands, width * numBands, TiledImage.bandOffsets(numBands)), new Point(xmin, ymin));
/*
* At this point, all data structures have been created an initialized to zero sample values.
* Now fill the data structures with arbitrary values.
@@ -196,8 +197,7 @@ public strictfp class PixelIteratorTest
subMaxY = StrictMath.min(ymax, subArea.y + subArea.height);
}
expected = new float[(subMaxX - subMinX) * (subMaxY - subMinY) * numBands];
- final IteratorTestImage image = new IteratorTestImage(xmin, ymin, width, height, tileWidth, tileHeight, xmin+tileWidth, ymin+tileHeight,
- new PixelInterleavedSampleModel(dataType, tileWidth, tileHeight, numBands, tileWidth * numBands, new int[] {0,1,2}));
+ final TiledImage image = new TiledImage(dataType, numBands, xmin, ymin, width, height, tileWidth, tileHeight, -1, 2);
/*
* At this point, all data structures have been created an initialized to zero sample values.
* Now fill the data structures with arbitrary values. We fill them tile-by-tile.
Copied: sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/TiledImage.java (from r1803380, sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/IteratorTestImage.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/TiledImage.java?p2=sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/TiledImage.java&p1=sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/IteratorTestImage.java&r1=1803380&r2=1803381&rev=1803381&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/IteratorTestImage.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-raster/src/test/java/org/apache/sis/image/TiledImage.java [UTF-8] Sat Jul 29 17:13:10 2017
@@ -16,10 +16,11 @@
*/
package org.apache.sis.image;
-import java.awt.Dimension;
+import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.ColorModel;
+import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
@@ -28,213 +29,212 @@ import java.awt.image.WritableRaster;
import java.awt.image.WritableRenderedImage;
import java.util.Vector;
+
/**
+ * A rendered image which can contain an arbitrary number of tiles. Tiles are stored in memory.
+ * We use this class for testing purpose only because tiled images in production need a more
+ * sophisticated implementation capable to store some tiles on disk (for memory consumption reasons).
*
- * @author Remi Marechal (Geomatys).
+ * @author Rémi Maréchal (Geomatys)
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
*/
-final class IteratorTestImage implements WritableRenderedImage {
-
- private final int minx;
- private final int miny;
-// private final int maxX;
-// private final int maxY;
- private final int width;
- private final int height;
- private final Dimension tileSize;
- private final SampleModel sm;
- private final int numxtile;
- private final int numytile;
- private final int tgXo;
- private final int tgYo;
- private final int minTx;
- private final int minTy;
-
+final class TiledImage implements WritableRenderedImage {
+ /**
+ * The minimum X or Y coordinate (inclusive) of the rendered image.
+ */
+ private final int minX, minY;
+
+ /**
+ * Number of pixels along X or Y axis in the whole rendered image.
+ */
+ private final int width, height;
+
+ /**
+ * Number of pixels along X or Y axis in a single tile of the image.
+ * All tiles must have the same size.
+ */
+ private final int tileWidth, tileHeight;
+
+ /**
+ * Number of tiles in the X or Y direction. This is computed from the image size and tile size.
+ */
+ private final int numXTiles, numYTiles;
+
+ /**
+ * The minimum tile index in the X or Y direction.
+ */
+ private final int minTileX, minTileY;
+
+ /**
+ * The tiles, created when first needed.
+ */
private final WritableRaster[] tiles;
- public IteratorTestImage(final int minx, final int miny, final int width, final int height,
- final int tilesWidth, final int tilesHeight, final int tileGridXOffset, final int tileGridYOffset,
- final SampleModel sampleM)
+ /**
+ * The sample model to use for creating the tiles.
+ */
+ private final SampleModel sampleModel;
+
+ /**
+ * Creates a new tiled image.
+ *
+ * @param dataType sample data type as one of the {@link java.awt.image.DataBuffer} constants.
+ * @param numBands number of bands in the sample model to create.
+ */
+ TiledImage(final int dataType, final int numBands,
+ final int minX, final int minY,
+ final int width, final int height,
+ final int tileWidth, final int tileHeight,
+ final int minTileX, final int minTileY)
{
- this.minx = minx;
- this.miny = miny;
- this.width = width;
- this.height = height;
- this.tileSize = new Dimension(tilesWidth, tilesHeight);
- numxtile = (int) StrictMath.ceil(width / (double) tilesWidth);
- numytile = (int) StrictMath.ceil(height / (double) tilesHeight);
- sm = sampleM;
- tgXo = tileGridXOffset;
- tgYo = tileGridYOffset;
- tiles = new WritableRaster[numxtile * numytile];
- minTx = (int) StrictMath.floor((tgXo - minx) / (double)tileSize.width);
- minTy = (int) StrictMath.floor((tgYo - miny) / (double)tileSize.height);
- }
-
-
-
- @Override
- public ColorModel getColorModel() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public SampleModel getSampleModel() {
- return sm;
- }
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public int getMinX() {
- return minx;
- }
-
- @Override
- public int getMinY() {
- return miny;
- }
-
- @Override
- public int getNumXTiles() {
- return tileSize.width;
- }
-
- @Override
- public int getNumYTiles() {
- return numxtile;
- }
-
- @Override
- public int getMinTileX() {
- return minTx;
- }
-
- @Override
- public int getMinTileY() {
- return minTy;
- }
-
- @Override
- public int getTileWidth() {
- return tileSize.width;
- }
-
- @Override
- public int getTileHeight() {
- return tileSize.height;
- }
-
- @Override
- public int getTileGridXOffset() {
- return tgXo;
+ this.minX = minX;
+ this.minY = minY;
+ this.width = width;
+ this.height = height;
+ this.tileWidth = tileWidth;
+ this.tileHeight = tileHeight;
+ this.minTileX = minTileX;
+ this.minTileY = minTileY;
+ this.numXTiles = (width + tileWidth - 1) / tileWidth; // Round toward upper integer value.
+ this.numYTiles = (height + tileHeight - 1) / tileHeight;
+ this.tiles = new WritableRaster[numXTiles * numYTiles];
+ this.sampleModel = new PixelInterleavedSampleModel(dataType, tileWidth, tileHeight,
+ numBands, tileWidth * numBands, bandOffsets(numBands));
+ }
+
+ /**
+ * Returns arbitrary band offsets for the given number of bands.
+ */
+ static int[] bandOffsets(final int numBands) {
+ final int[] bandOffsets = new int[numBands];
+ for (int i=1; i<numBands; i++) {
+ bandOffsets[i] = i;
+ }
+ return bandOffsets;
}
- @Override
- public int getTileGridYOffset() {
- return tgYo;
+ /*
+ * No source, no property, no color model since this test images is not for rendering on screen.
+ */
+ @Override public Vector<RenderedImage> getSources() {return null;}
+ @Override public Object getProperty(String name) {return Image.UndefinedProperty;}
+ @Override public String[] getPropertyNames() {return null;}
+ @Override public ColorModel getColorModel() {return null;}
+ @Override public SampleModel getSampleModel() {return sampleModel;}
+
+ /*
+ * Information specified to the constructor.
+ */
+ @Override public int getMinX() {return minX;}
+ @Override public int getMinY() {return minY;}
+ @Override public int getWidth() {return width;}
+ @Override public int getHeight() {return height;}
+ @Override public int getTileWidth() {return tileWidth;}
+ @Override public int getTileHeight() {return tileHeight;}
+ @Override public int getNumXTiles() {return numXTiles;}
+ @Override public int getNumYTiles() {return numYTiles;}
+ @Override public int getMinTileX() {return minTileX;}
+ @Override public int getMinTileY() {return minTileY;}
+ @Override public int getTileGridXOffset() {return minX - (minTileX * tileWidth);}
+ @Override public int getTileGridYOffset() {return minY - (minTileY * tileHeight);}
+
+ /**
+ * Sets a sample value at the given location in pixel coordinates.
+ * This is a helper method for testing purpose on small images only,
+ * since invoking this method in a loop is inefficient.
+ */
+ final void setSample(int x, int y, final int b, final double value) {
+ if ((x -= minX) < 0 || x >= width || (y -= minY) < 0 || y >= height) {
+ throw new IndexOutOfBoundsException();
+ }
+ getWritableTile(x / tileWidth + minTileX,
+ y / tileHeight + minTileY).setSample(x, y, b, value);
}
+ /**
+ * Returns the tile at the given location in tile coordinates.
+ */
@Override
- public Raster getTile(int tileX, int tileY) {
+ public Raster getTile(final int tileX, final int tileY) {
return getWritableTile(tileX, tileY);
}
- @Override
- public Raster getData() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public Raster getData(Rectangle rect) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
+ /**
+ * Returns the tile at the given location tile coordinates.
+ */
@Override
public WritableRaster getWritableTile(int tileX, int tileY) {
- final int id = (tileY - minTy) * numxtile + tileX - minTx;
- if (id == -22) {
- System.out.println("");
+ if ((tileX -= minTileX) < 0 || tileX >= numXTiles ||
+ (tileY -= minTileY) < 0 || tileY >= numYTiles)
+ {
+ throw new IndexOutOfBoundsException();
}
- if (tiles[id] == null)
- tiles[id] = Raster.createInterleavedRaster(sm.getDataType(),
- tileSize.width, tileSize.height,
- sm.getNumBands(),
- new Point(tgXo + tileX * tileSize.width, tgYo + tileY * tileSize.height));
- return tiles[id];
+ final int i = tileY * numXTiles + tileX;
+ WritableRaster raster = tiles[i];
+ if (raster == null) {
+ tiles[i] = raster = Raster.createInterleavedRaster(sampleModel.getDataType(),
+ tileWidth, tileHeight, sampleModel.getNumBands(),
+ new Point(tileX * tileWidth + minX,
+ tileY * tileHeight + minY));
+ }
+ return raster;
}
+ /**
+ * Ignored since this implementation does not need to be informed
+ * about when the user is doing with the {@link WritableRaster}.
+ */
@Override
public void releaseWritableTile(int tileX, int tileY) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
+ /**
+ * Returns {@code false} since we do not keep track of who called {@link #getWritableTile(int,int)}.
+ */
@Override
public boolean isTileWritable(int tileX, int tileY) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public Point[] getWritableTileIndices() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ return false;
}
+ /**
+ * Returns {@code false} since we do not keep track of who called {@link #getWritableTile(int,int)}.
+ */
@Override
public boolean hasTileWriters() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public void setData(Raster r) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public Vector<RenderedImage> getSources() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public Object getProperty(String name) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ return false;
}
+ /**
+ * Returns {@code null} since we do not keep track of who called {@link #getWritableTile(int,int)}.
+ */
@Override
- public String[] getPropertyNames() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ public Point[] getWritableTileIndices() {
+ return null;
}
- @Override
- public WritableRaster copyData(WritableRaster raster) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
-
+ /**
+ * Unsupported since we do not need tile observers for the tests.
+ */
@Override
public void addTileObserver(TileObserver to) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ throw new UnsupportedOperationException();
}
+ /**
+ * Ignored since no listener can have been registered.
+ */
@Override
public void removeTileObserver(TileObserver to) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- public void setSample(final int x, final int y, final int b, final double value) {
- final WritableRaster wr = getTileFromPixCoords(x, y);
- wr.setSample(x, y, b, value);
}
- private WritableRaster getTileFromPixCoords(final int x, final int y) {
- final int tx = StrictMath.floorDiv((x - tgXo), tileSize.width);
- final int ty = StrictMath.floorDiv((y - tgYo), tileSize.height);
- return getWritableTile(tx, ty);
- }
+ /*
+ * Not needed for the tests.
+ */
+ @Override public Raster getData() {throw new UnsupportedOperationException();}
+ @Override public Raster getData(Rectangle rect) {throw new UnsupportedOperationException();}
+ @Override public void setData(Raster r) {throw new UnsupportedOperationException();}
+ @Override public WritableRaster copyData(WritableRaster raster) {throw new UnsupportedOperationException();}
}