/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed 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 it.geosolutions.jaiext.scale; import java.awt.RenderingHints; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import it.geosolutions.jaiext.JAIExt; import it.geosolutions.jaiext.interpolators.InterpolationBicubic; import it.geosolutions.jaiext.interpolators.InterpolationBilinear; import it.geosolutions.jaiext.interpolators.InterpolationNearest; import it.geosolutions.jaiext.range.Range; import it.geosolutions.jaiext.range.RangeFactory; import it.geosolutions.jaiext.testclasses.TestBase; import it.geosolutions.jaiext.testclasses.TestData; import javax.media.jai.BorderExtender; import javax.media.jai.Interpolation; import javax.media.jai.JAI; import javax.media.jai.ParameterBlockJAI; import javax.media.jai.PlanarImage; import javax.media.jai.RenderedOp; import org.junit.BeforeClass; import org.junit.Test; /** * This test class is used for compare the timing between the new Nearest,Bilinear and Bicubic interpolators and their JAI version on the scale * operation. No Roi or No Data range are used. If the user wants to change the number of the benchmark cycles or of the not benchmark cycles, should * only pass the new values to the JAI.Ext.BenchmarkCycles or JAI.Ext.NotBenchmarkCycles parameters. The tests are quite different because the * interpolator used is always one of the 3 JAI interpolators but the other operations are similar: * <ul> * </ul> * <ul> * <li>Selection of the descriptor (new ScaleDescriptor or old ScaleDescriptor)</li> * <li>Selection of the interpolator (Standard or New)</li> * <li>Image Magnification\Reduction</li> * <li>statistic calculation (if the cycle belongs to the benchmark cycles)</li> * </ul> * The interpolator can be chosen by passing the JAI.Ext.TestSelector Integer JVM parameter: 0 for nearest interpolation, 1 for bilinear, 2 for * bicubic. The selection of the old or new descriptor must be done by setting to true or false the JVM parameter JAI.Ext.OldDescriptor. If the user * wants to use the accelerated code, the JVM parameter JAI.Ext.Acceleration must be set to true. */ public class ComparisonTest extends TestBase{ /** Number of benchmark iterations (Default 1) */ private final static Integer BENCHMARK_ITERATION = Integer.getInteger( "JAI.Ext.BenchmarkCycles", 1); /** Number of not benchmark iterations (Default 0) */ private final static int NOT_BENCHMARK_ITERATION = Integer.getInteger( "JAI.Ext.NotBenchmarkCycles", 0); /** Index for selecting one of the 3 interpolators(Default 0) */ private final static int TEST_SELECTOR = Integer.getInteger("JAI.Ext.TestSelector", 0); /** Boolean indicating if the native acceleration must be used */ private final static boolean NATIVE_ACCELERATION = Boolean.getBoolean("JAI.Ext.Acceleration"); /** Boolean indicating if the image should be reduced instead of increased */ public static Boolean IMAGE_REDUCTION = Boolean.getBoolean("JAI.Ext.ImageReduction"); /** Default subsampling bits used for the bilinear and bicubic interpolation */ private final static int DEFAULT_SUBSAMPLE_BITS = 8; /** Boolean indicating if the old descriptor must be used */ private final static boolean OLD_DESCRIPTOR = Boolean.getBoolean("JAI.Ext.OldDescriptor"); /** Boolean indicating if a No Data Range must be used */ private final static boolean RANGE_USED = Boolean.getBoolean("JAI.Ext.RangeUsed"); /** Default precision bits used in the bicubic calculation */ private final static int DEFAULT_PRECISION_BITS = 8; /** Value indicating No Data for the destination image */ private static double destinationNoData = 0; /** Translation parameter on the X axis */ private float xTrans = 0; /** Translation parameter on the Y axis */ private float yTrans = 0; /** Scale parameter on the X axis */ private float xScale = 1.5f; /** Scale parameter on the Y axis */ private float yScale = 1.5f; /** JAI nearest Interpolator */ private static javax.media.jai.InterpolationNearest interpNearOld; /** New nearest Interpolator */ private static InterpolationNearest interpNearNew; /** JAI bilinear Interpolator */ private static javax.media.jai.InterpolationBilinear interpBilOld; /** New bilinear Interpolator */ private static InterpolationBilinear interpBilNew; /** JAI bicubic Interpolator */ private static javax.media.jai.InterpolationBicubic interpBicOld; /** New bicubic Interpolator */ private static InterpolationBicubic interpBicNew; /** Image to elaborate */ private static RenderedImage image; /** RenderingHints used for selecting the borderExtender */ private static RenderingHints hints; @BeforeClass public static void initialSetup() throws FileNotFoundException, IOException { int dataType = DataBuffer.TYPE_BYTE; // Selection of the RGB image ParameterBlockJAI pbj = new ParameterBlockJAI("ImageRead"); // String file = "../jt-utilities/src/test/resources/it/geosolutions/jaiext/images/testImageLittle.tif"; File file = TestData.file(ComparisonTest.class, "testImageLittle.tif"); pbj.setParameter("Input", file); image = JAI.create("ImageRead", pbj); hints = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY)); //Range creation if selected Range rangeND= null; if(RANGE_USED){ rangeND = RangeFactory.create((byte)100,true,(byte)100,true); } // Interpolators instantiation interpNearOld = new javax.media.jai.InterpolationNearest(); interpNearNew = new InterpolationNearest(rangeND, false, destinationNoData, dataType); interpBilOld = new javax.media.jai.InterpolationBilinear(DEFAULT_SUBSAMPLE_BITS); interpBilNew = new InterpolationBilinear(DEFAULT_SUBSAMPLE_BITS, rangeND, false, destinationNoData, dataType); interpBicOld = new javax.media.jai.InterpolationBicubic(DEFAULT_SUBSAMPLE_BITS); interpBicNew = new InterpolationBicubic(DEFAULT_SUBSAMPLE_BITS, rangeND, false, dataType, dataType, false, DEFAULT_PRECISION_BITS); if(OLD_DESCRIPTOR){ JAIExt.registerJAIDescriptor("Scale"); } } @Test public void testNearestNewScaleDescriptor() { if (!OLD_DESCRIPTOR && TEST_SELECTOR == 0) { testInterpolators(interpNearNew, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } @Test public void testNearestOldScaleDescriptor() { if (OLD_DESCRIPTOR && TEST_SELECTOR == 0) { testInterpolators(interpNearOld, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } @Test public void testBilinearNewScaleDescriptor() { if (!OLD_DESCRIPTOR && TEST_SELECTOR == 1) { testInterpolators(interpBilNew, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } @Test public void testBilinearOldScaleDescriptor() { if (OLD_DESCRIPTOR && TEST_SELECTOR == 1) { testInterpolators(interpBilOld, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } @Test public void testBicubicNewScaleDescriptor() { if (!OLD_DESCRIPTOR && TEST_SELECTOR == 2) { testInterpolators(interpBicNew, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } @Test public void testBicubicOldScaleDescriptor() { if (OLD_DESCRIPTOR && TEST_SELECTOR == 2) { testInterpolators(interpBicOld, IMAGE_REDUCTION, OLD_DESCRIPTOR); } } public void testInterpolators(Interpolation interp, boolean reductionBoolean, boolean old) { float scaleX; float scaleY; String reduction = ""; if (reductionBoolean) { reduction = "Reduction"; scaleX = 1 / xScale; scaleY = 1 / yScale; } else { reduction = "Magnification"; scaleX = xScale; scaleY = yScale; } String description = ""; if (old) { description = "Old Scale"; if (NATIVE_ACCELERATION) { description += " accelerated "; System.setProperty("com.sun.media.jai.disableMediaLib", "false"); } else { System.setProperty("com.sun.media.jai.disableMediaLib", "true"); } } else { description = "New Scale"; System.setProperty("com.sun.media.jai.disableMediaLib", "true"); } String interpType = ""; if (interp instanceof InterpolationBilinear || interp instanceof javax.media.jai.InterpolationBilinear) { interpType = "Bilinear"; } else if (interp instanceof InterpolationBicubic || interp instanceof javax.media.jai.InterpolationBicubic) { interpType = "Bicubic"; } else if (interp instanceof InterpolationNearest || interp instanceof javax.media.jai.InterpolationNearest) { interpType = "Nearest"; } // Total cycles number int totalCycles = BENCHMARK_ITERATION + NOT_BENCHMARK_ITERATION; // Image with the interpolator PlanarImage imageScale = null; long mean = 0; long max = Long.MIN_VALUE; long min = Long.MAX_VALUE; // Cycle for calculating the mean, maximum and minimum calculation time for (int i = 0; i < totalCycles; i++) { // creation of the image with the selected interpolator if (old) { imageScale = javax.media.jai.operator.ScaleDescriptor.create(image, scaleX, scaleY, xTrans, yTrans, interp, hints); } else { imageScale = ScaleDescriptor.create(image, scaleX, scaleY, xTrans, yTrans, interp, null, false, null, null, hints); } // Total calculation time long start = System.nanoTime(); imageScale.getTiles(); long end = System.nanoTime() - start; // If the the first NOT_BENCHMARK_ITERATION cycles has been done, then the mean, maximum and minimum values are stored if (i > NOT_BENCHMARK_ITERATION - 1) { if (i == NOT_BENCHMARK_ITERATION) { mean = end; } else { mean = mean + end; } if (end > max) { max = end; } if (end < min) { min = end; } } // For every cycle the cache is flushed such that all the tiles must be recalculates JAI.getDefaultInstance().getTileCache().flush(); } // Mean values double meanValue = mean / BENCHMARK_ITERATION * 1E-6; // Max and Min values stored as double double maxD = max * 1E-6; double minD = min * 1E-6; // Comparison between the mean times System.out.println("\n" + reduction); // Output print of the System.out.println("\n" + interpType); System.out.println("\nMean value for " + description + "Descriptor : " + meanValue + " msec."); System.out.println("Maximum value for " + description + "Descriptor : " + maxD + " msec."); System.out.println("Minimum value for " + description + "Descriptor : " + minD + " msec."); // Final Image disposal if (imageScale instanceof RenderedOp) { ((RenderedOp) imageScale).dispose(); } } }