Author: simonegiannecchini Date: 2009-04-30 12:16:22 -0400 (Thu, 30 Apr 2009) New Revision: 32888 Modified: trunk/modules/library/coverage/src/main/java/org/geotools/coverage/processing/AbstractStatisticsOperationJAI.java trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java trunk/modules/library/coverage/src/test/java/org/geotools/coverage/grid/GridCoverageTestBase.java trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java Log: -porting fixes for statistic operations -porting ImageWorker improvements Modified: trunk/modules/library/coverage/src/main/java/org/geotools/coverage/processing/AbstractStatisticsOperationJAI.java =================================================================== --- trunk/modules/library/coverage/src/main/java/org/geotools/coverage/processing/AbstractStatisticsOperationJAI.java 2009-04-30 15:59:23 UTC (rev 32887) +++ trunk/modules/library/coverage/src/main/java/org/geotools/coverage/processing/AbstractStatisticsOperationJAI.java 2009-04-30 16:16:22 UTC (rev 32888) @@ -209,6 +209,15 @@ e); throw ce; } + + // // + // + // get the original envelope and the crs + // + // // + final CoordinateReferenceSystem crs = source + .getCoordinateReferenceSystem2D(); + final Envelope2D envelope = source.getEnvelope2D(); // ///////////////////////////////////////////////////////////////////// // @@ -223,35 +232,28 @@ .doubleValue(); final double yPeriod = parameters.parameter("yPeriod") .doubleValue(); + if(!Double.isNaN(xPeriod)&&!Double.isNaN(yPeriod)){ - // // - // - // get the original envelope and the crs - // - // // - final CoordinateReferenceSystem crs = source - .getCoordinateReferenceSystem2D(); - final Envelope2D envelope = source.getEnvelope2D(); - // build the new one that spans over the requested area - // NOTE: - final DirectPosition2D LLC = new DirectPosition2D(crs, envelope.x, - envelope.y); - LLC.setCoordinateReferenceSystem(crs); - final DirectPosition2D URC = new DirectPosition2D(crs, envelope.x - + xPeriod, envelope.y + yPeriod); - URC.setCoordinateReferenceSystem(crs); - final Envelope2D shrinkedEnvelope = new Envelope2D(LLC, URC); - - // transform back into raster space - final Rectangle2D transformedEnv = CRS.transform( - worldToGridTransform, shrinkedEnvelope).toRectangle2D(); - - // block settings - block.setParameter("xPeriod", Integer.valueOf((int) transformedEnv - .getWidth())); - block.setParameter("yPeriod", Integer.valueOf((int) transformedEnv - .getHeight())); - + // build the new one that spans over the requested area + // NOTE: + final DirectPosition2D LLC = new DirectPosition2D(crs, envelope.x, + envelope.y); + LLC.setCoordinateReferenceSystem(crs); + final DirectPosition2D URC = new DirectPosition2D(crs, envelope.x + + xPeriod, envelope.y + yPeriod); + URC.setCoordinateReferenceSystem(crs); + final Envelope2D shrinkedEnvelope = new Envelope2D(LLC, URC); + + // transform back into raster space + final Rectangle2D transformedEnv = CRS.transform( + worldToGridTransform, shrinkedEnvelope).toRectangle2D(); + + // block settings + block.setParameter("xPeriod", Integer.valueOf((int) transformedEnv + .getWidth())); + block.setParameter("yPeriod", Integer.valueOf((int) transformedEnv + .getHeight())); + } // ///////////////////////////////////////////////////////////////////// // // Transcode the polygon parameter into a roi. Modified: trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java =================================================================== --- trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2009-04-30 15:59:23 UTC (rev 32887) +++ trunk/modules/library/coverage/src/main/java/org/geotools/image/ImageWorker.java 2009-04-30 16:16:22 UTC (rev 32888) @@ -1118,7 +1118,9 @@ lut = new LookupTableJAI(data,datatype==DataBuffer.TYPE_USHORT); - } + } + break; + default: throw new IllegalArgumentException( Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,"datatype", datatype)); @@ -1632,14 +1634,14 @@ int transparency = cm.getTransparency(); int transparencyIndex = cm.getTransparentPixel(); final int mapSize = cm.getMapSize(); - final int transparentRGB = transparentColor.getRGB() & 0xFFFFFF; + final int transparentRGB = transparentColor.getRGB() & 0x00FFFFFF; /* * Optimization in case of Transparency.BITMASK. * If the color we want to use as the fully transparent one is the same * that is actually used as the transparent color, we leave doing nothing. */ if (transparency == Transparency.BITMASK && transparencyIndex != -1) { - int transpColor = cm.getRGB(transparencyIndex) & 0xFFFFFF; + int transpColor = cm.getRGB(transparencyIndex) & 0x00FFFFFF; if (transpColor == transparentRGB) { return this; } @@ -1763,19 +1765,20 @@ * we need first to interact with the single bands then to combine the * result into a single band that will provide us with the alpha band. */ - final int numBands = image.getSampleModel().getNumBands(); + int numBands = image.getSampleModel().getNumBands(); final int numColorBands = image.getColorModel().getNumColorComponents(); final RenderingHints hints = getRenderingHints(); - RenderedImage transparentBand = null; if (numColorBands != numBands) { // Typically, numColorBands will be equals to numBands-1. - transparentBand = BandSelectDescriptor.create(image, new int[] {numColorBands}, hints); final int[] opaqueBands = new int[numColorBands]; for (int i=0; i<opaqueBands.length; i++) { opaqueBands[i] = i; } image = BandSelectDescriptor.create(image, opaqueBands, hints); + numBands=numColorBands; } + + // now prepare the lookups final byte[][] tableData = new byte[numColorBands][256]; final boolean singleStep = (numColorBands == 1); if (singleStep) { @@ -1783,24 +1786,19 @@ Arrays.fill(data, (byte) 255); data[transparentColor.getRed()] = 0; } else { - for (int j=0; j<numColorBands; j++) { - final byte[] data = tableData[j]; - for (int i=0; i<data.length; i++) { - data[i] = (byte) i; - } - } - if (true) { - // TODO: BUG ??????????????? - // The previous code was written in an other way with an end result as below, which - // sound like a bug to me. But I'm dont understand well enough what the code tries - // to do, so I reproduce here what the old code did. - Arrays.fill(tableData[1], (byte) 0); - Arrays.fill(tableData[2], (byte) 255); - } switch (numColorBands) { - case 3: tableData[2][transparentColor.getBlue() ] = 0; // fall through - case 2: tableData[1][transparentColor.getGreen()] = 0; // fall through - case 1: tableData[0][transparentColor.getRed() ] = 0; // fall through + case 3: + Arrays.fill(tableData[2], (byte) 255); + tableData[2][transparentColor.getBlue() ] = 0; // fall through + + case 2: + Arrays.fill(tableData[1], (byte) 255); + tableData[1][transparentColor.getGreen()] = 0; // fall through + + case 1: + Arrays.fill(tableData[0], (byte) 255); + tableData[0][transparentColor.getRed() ] = 0; // fall through + case 0: break; } } @@ -1808,16 +1806,17 @@ LookupTableJAI table = new LookupTableJAI(tableData); // Do the lookup operation. PlanarImage luImage = LookupDescriptor.create(image, table, hints); + /* * Now that we have performed the lookup operation we have to remember * what we stated here above. * - * If the input image is multibanded we will get a multiband image as + * If the input image is multiband we will get a multiband image as * the output of the lookup operation hence we need to perform some form * of band combination to get the alpha band out of the lookup image. * * The way we wanted things to be done is by exploiting the clamping - * behaviour that kicks in when we do sums and the like on pixels and + * behavior that kicks in when we do sums and the like on pixels and * we overcome the maximum value allowed by the DataBufer DataType. */ if (!singleStep) { @@ -1826,11 +1825,6 @@ // Values at index 0,1,2 are set to 1.0, value at index 3 is left to 0. Arrays.fill(matrix[0], 0, 3, 1.0); luImage = BandCombineDescriptor.create(luImage, matrix, hints); - if (transparentBand != null) { - luImage = fork(luImage).binarize(254) - .forceComponentColorModel().retainFirstBand().getPlanarImage(); - luImage = MultiplyDescriptor.create(transparentBand, luImage, hints); - } } image = BandMergeDescriptor.create(image, luImage, hints); Modified: trunk/modules/library/coverage/src/test/java/org/geotools/coverage/grid/GridCoverageTestBase.java =================================================================== --- trunk/modules/library/coverage/src/test/java/org/geotools/coverage/grid/GridCoverageTestBase.java 2009-04-30 15:59:23 UTC (rev 32887) +++ trunk/modules/library/coverage/src/test/java/org/geotools/coverage/grid/GridCoverageTestBase.java 2009-04-30 16:16:22 UTC (rev 32888) @@ -296,7 +296,7 @@ * Geographic extent : (90°S, 180°W) - (90°N, 180°E) */ case 3:{ - path = "BATHY.gif"; + path = "BATHY.png"; bounds = new Rectangle2D.Double(-180, -90, 360, 180); crs = DefaultGeographicCRS.WGS84; bands = null; Modified: trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java =================================================================== --- trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2009-04-30 15:59:23 UTC (rev 32887) +++ trunk/modules/library/coverage/src/test/java/org/geotools/image/ImageWorkerTest.java 2009-04-30 16:16:22 UTC (rev 32888) @@ -23,11 +23,13 @@ import java.awt.image.IndexColorModel; import java.awt.image.ComponentColorModel; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.FileOutputStream; import javax.imageio.ImageIO; +import javax.imageio.stream.FileImageOutputStream; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.Viewer; @@ -49,7 +51,7 @@ /** * Image to use for testing purpose. */ - private static RenderedImage sstImage, worldImage; + private static RenderedImage sstImage, worldImage, chlImage, bathy, smallWorld, gray, grayAlpha; /** * {@code true} if the image should be visualized. @@ -73,48 +75,34 @@ worldImage = ImageIO.read(input); input.close(); } - } + if (chlImage == null) { + final InputStream input = TestData.openStream(GridCoverage2D.class, "CHL01195.png"); + chlImage = ImageIO.read(input); + input.close(); + } + if (bathy == null) { + final InputStream input = TestData.openStream(GridCoverage2D.class, "BATHY.png"); + bathy = ImageIO.read(input); + input.close(); + } + + if (smallWorld == null) { + final InputStream input = TestData.openStream(GridCoverage2D.class, "small_world.png"); + smallWorld = ImageIO.read(input); + input.close(); + } - /** - * Tests the {@link ImageWorker#makeColorTransparent} methods. - * Some trivial tests are performed before. - */ - @Test - public void testMakeColorTransparent() { - assertTrue("Assertions should be enabled.", ImageWorker.class.desiredAssertionStatus()); - final ImageWorker worker = new ImageWorker(sstImage); - - assertSame(sstImage, worker.getRenderedImage()); - assertEquals( 1, worker.getNumBands()); - assertEquals( -1, worker.getTransparentPixel()); - assertTrue ( worker.isBytes()); - assertFalse ( worker.isBinary()); - assertTrue ( worker.isIndexed()); - assertTrue ( worker.isColorSpaceRGB()); - assertFalse ( worker.isColorSpaceGRAYScale()); - assertFalse ( worker.isTranslucent()); - - assertSame("Expected no operation.", sstImage, worker.rescaleToBytes() .getRenderedImage()); - assertSame("Expected no operation.", sstImage, worker.forceIndexColorModel(false).getRenderedImage()); - assertSame("Expected no operation.", sstImage, worker.forceIndexColorModel(true ).getRenderedImage()); - assertSame("Expected no operation.", sstImage, worker.forceColorSpaceRGB() .getRenderedImage()); - assertSame("Expected no operation.", sstImage, worker.retainFirstBand() .getRenderedImage()); - assertSame("Expected no operation.", sstImage, worker.retainLastBand() .getRenderedImage()); - - // Following will change image, so we need to test after the above assertions. - assertEquals( 0, worker.getMinimums()[0], 0); - assertEquals(255, worker.getMaximums()[0], 0); - assertNotSame(sstImage, worker.getRenderedImage()); - assertSame("Expected same databuffer, i.e. pixels should not be duplicated.", - sstImage.getTile(0,0).getDataBuffer(), - worker.getRenderedImage().getTile(0,0).getDataBuffer()); - - assertSame(worker, worker.makeColorTransparent(Color.WHITE)); - assertEquals(255, worker.getTransparentPixel()); - assertFalse ( worker.isTranslucent()); - assertSame("Expected same databuffer, i.e. pixels should not be duplicated.", - sstImage.getTile(0,0).getDataBuffer(), - worker.getRenderedImage().getTile(0,0).getDataBuffer()); + if (gray == null) { + final InputStream input = TestData.openStream(GridCoverage2D.class, "gray.png"); + gray = ImageIO.read(input); + input.close(); + } + + if (grayAlpha == null) { + final InputStream input = TestData.openStream(GridCoverage2D.class, "gray-alpha.png"); + grayAlpha = ImageIO.read(input); + input.close(); + } } /** @@ -281,7 +269,141 @@ } show(worker, "RGB translucent"); } + /** + * Tests the {@link ImageWorker#makeColorTransparent} methods. + * Some trivial tests are performed before. + * @throws IOException + * @throws FileNotFoundException + * @throws IllegalStateException + */ + @Test + public void testMakeColorTransparent() throws IllegalStateException, FileNotFoundException, IOException { + assertTrue("Assertions should be enabled.", ImageWorker.class.desiredAssertionStatus()); + ImageWorker worker = new ImageWorker(sstImage); + + assertSame(sstImage, worker.getRenderedImage()); + assertEquals( 1, worker.getNumBands()); + assertEquals( -1, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertFalse ( worker.isBinary()); + assertTrue ( worker.isIndexed()); + assertTrue ( worker.isColorSpaceRGB()); + assertFalse ( worker.isColorSpaceGRAYScale()); + assertFalse ( worker.isTranslucent()); + assertSame("Expected no operation.", sstImage, worker.rescaleToBytes() .getRenderedImage()); + assertSame("Expected no operation.", sstImage, worker.forceIndexColorModel(false).getRenderedImage()); + assertSame("Expected no operation.", sstImage, worker.forceIndexColorModel(true ).getRenderedImage()); + assertSame("Expected no operation.", sstImage, worker.forceColorSpaceRGB() .getRenderedImage()); + assertSame("Expected no operation.", sstImage, worker.retainFirstBand() .getRenderedImage()); + assertSame("Expected no operation.", sstImage, worker.retainLastBand() .getRenderedImage()); + + // Following will change image, so we need to test after the above assertions. + assertEquals( 0, worker.getMinimums()[0], 0); + assertEquals(255, worker.getMaximums()[0], 0); + assertNotSame(sstImage, worker.getRenderedImage()); + assertSame("Expected same databuffer, i.e. pixels should not be duplicated.", + sstImage.getTile(0,0).getDataBuffer(), + worker.getRenderedImage().getTile(0,0).getDataBuffer()); + + assertSame(worker, worker.makeColorTransparent(Color.WHITE)); + assertEquals(255, worker.getTransparentPixel()); + assertFalse ( worker.isTranslucent()); + assertSame("Expected same databuffer, i.e. pixels should not be duplicated.", + sstImage.getTile(0,0).getDataBuffer(), + worker.getRenderedImage().getTile(0,0).getDataBuffer()); + + + // INDEX TO INDEX-ALPHA + worker=new ImageWorker(chlImage).makeColorTransparent(Color.black); + show(worker, "CHL01195.png"); + assertEquals( 1, worker.getNumBands()); + assertEquals( 0, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertTrue ( worker.isIndexed()); + assertTrue ( worker.isColorSpaceRGB()); + assertFalse ( worker.isColorSpaceGRAYScale()); + assertFalse ( worker.isTranslucent()); + RenderedImage image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof IndexColorModel); + IndexColorModel iColorModel=(IndexColorModel) image.getColorModel(); + int transparentColor=iColorModel.getRGB(worker.getTransparentPixel())&0x00ffffff; + assertTrue ( transparentColor==0); + + + + // INDEX TO INDEX-ALPHA + worker=new ImageWorker(bathy).makeColorTransparent(Color.WHITE); + show(worker, "BATHY.png"); + assertEquals( 1, worker.getNumBands()); + assertEquals( 206, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertTrue ( worker.isIndexed()); + assertTrue ( worker.isColorSpaceRGB()); + assertFalse ( worker.isColorSpaceGRAYScale()); + assertFalse ( worker.isTranslucent()); + image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof IndexColorModel); + iColorModel=(IndexColorModel) image.getColorModel(); + transparentColor=iColorModel.getRGB(worker.getTransparentPixel())&0x00ffffff; + assertTrue ( transparentColor==(Color.WHITE.getRGB()&0x00ffffff)); + + // RGB TO RGBA + worker=new ImageWorker(smallWorld).makeColorTransparent(new Color(11,10,50)); + show(worker, "small_world.png"); + assertEquals( 4, worker.getNumBands()); + assertEquals( -1, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertFalse ( worker.isIndexed()); + assertTrue ( worker.isColorSpaceRGB()); + assertFalse ( worker.isColorSpaceGRAYScale()); + assertTrue ( worker.isTranslucent()); + image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof ComponentColorModel); + + + // RGBA to RGBA + worker=new ImageWorker(worldImage).makeColorTransparent(Color.white); + show(worker, "world.png"); + assertEquals( 4, worker.getNumBands()); + assertEquals( -1, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertFalse ( worker.isIndexed()); + assertTrue ( worker.isColorSpaceRGB()); + assertFalse ( worker.isColorSpaceGRAYScale()); + assertTrue ( worker.isTranslucent()); + image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof ComponentColorModel); + + + // GRAY TO GRAY-ALPHA + worker=new ImageWorker(gray).makeColorTransparent(Color.black); + show(worker, "gray.png"); + assertEquals( 2, worker.getNumBands()); + assertEquals( -1, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertFalse ( worker.isIndexed()); + assertFalse ( worker.isColorSpaceRGB()); + assertTrue ( worker.isColorSpaceGRAYScale()); + assertTrue ( worker.isTranslucent()); + image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof ComponentColorModel); + + // GRAY-ALPHA TO GRAY-ALPHA. + worker=new ImageWorker(grayAlpha).makeColorTransparent(Color.black); + show(worker, "gray-alpha.png"); + assertEquals( 2, worker.getNumBands()); + assertEquals( -1, worker.getTransparentPixel()); + assertTrue ( worker.isBytes()); + assertFalse ( worker.isIndexed()); + assertFalse ( worker.isColorSpaceRGB()); + assertTrue ( worker.isColorSpaceGRAYScale()); + assertTrue ( worker.isTranslucent()); + image= worker.getRenderedImage(); + assertTrue ( image.getColorModel() instanceof ComponentColorModel); + + + } /** * Visualize the content of given image if {@link #SHOW} is {@code true}. * @@ -292,7 +414,7 @@ if (SHOW) { Viewer.show(worker.getRenderedImage(), title); } else { - assertNotNull(worker.getBufferedImage()); // Force computation. + assertNotNull(worker.getRenderedImage().getTile(worker.getRenderedImage().getMinTileX(), worker.getRenderedImage().getMinTileY())); // Force computation. } } } |