/** Tests the {@link #rescaleToBytes()} operation. */ @Test public void rescaleToBytes() { assertTrue("Assertions should be enabled.", ImageWorker.class.desiredAssertionStatus()); // set up synthetic images for testing final RenderedImage test1 = ConstantDescriptor.create(128.0f, 128.0f, new Double[] {20000.0}, null); final RenderedImage test2 = ConstantDescriptor.create(128.0f, 128.0f, new Double[] {255.0}, null); final RenderedImage test3 = getSynthetic(20000); final RenderedImage test4 = getSynthetic(255); // starting to check the results // single band value exceed the byte upper bound and is constant final ImageWorker test1I = new ImageWorker(test1).rescaleToBytes(); Assert.assertEquals("Format", test1I.getRenderedOperation().getOperationName()); final double[] maximums1 = test1I.getMaximums(); Assert.assertTrue(maximums1.length == 1); Assert.assertEquals(255.0, maximums1[0], 1E-10); final double[] minimums1 = test1I.getMinimums(); Assert.assertTrue(minimums1.length == 1); Assert.assertEquals(255.0, minimums1[0], 1E-10); // single band value does not exceed the byte upper bound and is constant final ImageWorker test2I = new ImageWorker(test2).rescaleToBytes(); Assert.assertEquals("Format", test2I.getRenderedOperation().getOperationName()); final double[] maximums2 = test1I.getMaximums(); Assert.assertTrue(maximums2.length == 1); Assert.assertEquals(255.0, maximums2[0], 1E-10); final double[] minimums2 = test1I.getMinimums(); Assert.assertTrue(minimums2.length == 1); Assert.assertEquals(255.0, minimums2[0], 1E-10); // single band value exceed the byte upper bound ImageWorker test3I = new ImageWorker(test3); final double[] maximums3a = test3I.getMaximums(); final double[] minimums3a = test3I.getMinimums(); test3I.rescaleToBytes(); Assert.assertEquals("Rescale", test3I.getRenderedOperation().getOperationName()); final double[] maximums3b = test3I.getMaximums(); final double[] minimums3b = test3I.getMinimums(); if (maximums3a[0] > 255) { Assert.assertTrue(Math.abs(maximums3a[0] - maximums3b[0]) > 1E-10); Assert.assertTrue(Math.abs(255.0 - maximums3b[0]) >= 0); } if (minimums3a[0] < 0) { Assert.assertTrue(minimums3b[0] >= 0); } // single band value does not exceed the byte upper bound ImageWorker test4I = new ImageWorker(test4); final double[] maximums4a = test4I.getMaximums(); final double[] minimums4a = test4I.getMinimums(); test4I.rescaleToBytes(); Assert.assertEquals("Format", test4I.getRenderedOperation().getOperationName()); final double[] maximums4b = test4I.getMaximums(); final double[] minimums4b = test4I.getMinimums(); Assert.assertEquals(maximums4a[0], maximums4b[0], 1E-10); Assert.assertEquals(minimums4a[0], minimums4b[0], 1E-10); // now test multibands case final RenderedImage multiband = BandMergeDescriptor.create(test2, test3, null); ImageWorker testmultibandI = new ImageWorker(multiband); final double[] maximums5a = testmultibandI.getMaximums(); final double[] minimums5a = testmultibandI.getMinimums(); testmultibandI.rescaleToBytes(); final double[] maximums5b = testmultibandI.getMaximums(); final double[] minimums5b = testmultibandI.getMinimums(); Assert.assertEquals(maximums5a[0], maximums5b[0], 1E-10); Assert.assertEquals(minimums5a[0], minimums5b[0], 1E-10); Assert.assertTrue(Math.abs(maximums5a[1] - maximums5b[1]) > 1E-10); Assert.assertTrue(Math.abs(minimums5a[1] - minimums5b[1]) > 1E-10); }
/** * Returns the specified property. * * @param name Property name. * @param opNode Operation node. */ public Object getProperty(String name, Object opNode) { validate(name, opNode); if (opNode instanceof RenderedOp && name.equalsIgnoreCase("roi")) { RenderedOp op = (RenderedOp) opNode; ParameterBlock pb = op.getParameterBlock(); // Retrieve the rendered source image and its ROI. RenderedImage src = pb.getRenderedSource(0); Object property = src.getProperty("ROI"); if (property == null || property.equals(java.awt.Image.UndefinedProperty) || !(property instanceof ROI)) { return java.awt.Image.UndefinedProperty; } // Return undefined also if source ROI is empty. ROI srcROI = (ROI) property; if (srcROI.getBounds().isEmpty()) { return java.awt.Image.UndefinedProperty; } // Retrieve the Interpolation object. Interpolation interp = (Interpolation) pb.getObjectParameter(1); // Determine the effective source bounds. Rectangle srcBounds = null; PlanarImage dst = op.getRendering(); if (dst instanceof GeometricOpImage && ((GeometricOpImage) dst).getBorderExtender() == null) { srcBounds = new Rectangle( src.getMinX() + interp.getLeftPadding(), src.getMinY() + interp.getTopPadding(), src.getWidth() - interp.getWidth() + 1, src.getHeight() - interp.getHeight() + 1); } else { srcBounds = new Rectangle(src.getMinX(), src.getMinY(), src.getWidth(), src.getHeight()); } // If necessary, clip the ROI to the effective source bounds. if (!srcBounds.contains(srcROI.getBounds())) { srcROI = srcROI.intersect(new ROIShape(srcBounds)); } // Retrieve the Warp object. Warp warp = (Warp) pb.getObjectParameter(0); // Setting constant image to be warped as a ROI Rectangle dstBounds = op.getBounds(); // Setting layout of the constant image ImageLayout2 layout = new ImageLayout2(); int minx = (int) srcBounds.getMinX(); int miny = (int) srcBounds.getMinY(); int w = (int) srcBounds.getWidth(); int h = (int) srcBounds.getHeight(); layout.setMinX(minx); layout.setMinY(miny); layout.setWidth(w); layout.setHeight(h); RenderingHints hints = op.getRenderingHints(); hints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout)); final PlanarImage constantImage = ConstantDescriptor.create(new Float(w), new Float(h), new Byte[] {(byte) 255}, hints); PlanarImage roiImage = null; // Make sure to specify tileCache, tileScheduler, tileRecyclier, by cloning hints. RenderingHints warpingHints = op.getRenderingHints(); warpingHints.remove(JAI.KEY_IMAGE_LAYOUT); // Creating warped roi by the same way (Warp, Interpolation, source ROI) we warped the // input image. final ParameterBlock paramBlk = new ParameterBlock(); paramBlk.addSource(constantImage); paramBlk.add(warp); paramBlk.add(interp); paramBlk.add(null); paramBlk.add(srcROI); // force in the image layout, this way we get exactly the same // as the affine we're eliminating Hints localHints = new Hints(op.getRenderingHints()); localHints.remove(JAI.KEY_IMAGE_LAYOUT); ImageLayout il = new ImageLayout(); il.setMinX(dstBounds.x); il.setMinY(dstBounds.y); il.setWidth(dstBounds.width); il.setHeight(dstBounds.height); localHints.put(JAI.KEY_IMAGE_LAYOUT, il); roiImage = JAI.create("Warp", paramBlk, localHints); ROI dstROI = new ROI(roiImage, 1); // If necessary, clip the warped ROI to the destination bounds. if (!dstBounds.contains(dstROI.getBounds())) { dstROI = dstROI.intersect(new ROIShape(dstBounds)); } // Return the warped and possibly clipped ROI. return dstROI; } return java.awt.Image.UndefinedProperty; }