/* 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.stats; import it.geosolutions.jaiext.range.Range; import it.geosolutions.jaiext.range.RangeFactory; import it.geosolutions.jaiext.stats.Statistics.StatsType; import it.geosolutions.jaiext.testclasses.TestBase; import java.awt.Rectangle; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import javax.media.jai.ROI; import javax.media.jai.ROIShape; 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 StatisticalDescriptor operation and the old JAI version. Roi or NoData range can be * used by setting to true JAI.Ext.ROIUsed or JAI.Ext.RangeUsed JVM boolean parameters are set to true. 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.If the user want to use the old descriptor must pass to the JVM the JAI.Ext.OldDescriptor parameter set to true. For selecting a * specific data type the user must set the JAI.Ext.TestSelector JVM integer parameter to a number between 0 and 5 (where 0 means byte, 1 Ushort, 2 * Short, 3 Integer, 4 Float and 5 Double). The possible statistics to calculate can be chosen by setting the JVM Integer parameter JAI.Ext.Statistic * to the associated value: * <ul> * <li>Mean 0</li> * <li>Extrema 1</li> * <li>Histogram 2</li> * </ul> */ 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); /** Boolean indicating if the old descriptor must be used */ private final static boolean OLD_DESCRIPTOR = Boolean.getBoolean("JAI.Ext.OldDescriptor"); /** Boolean indicating if the native acceleration must be used */ private final static boolean NATIVE_ACCELERATION = Boolean.getBoolean("JAI.Ext.Acceleration"); /** Boolean indicating if a No Data Range must be used */ private final static boolean RANGE_USED = Boolean.getBoolean("JAI.Ext.RangeUsed"); /** Boolean indicating if a ROI must be used */ private final static boolean ROI_USED = Boolean.getBoolean("JAI.Ext.ROIUsed"); /** Integer for selecting which statistic to compare */ private final static int STATISTIC = Integer.getInteger("JAI.Ext.Statistic", 0); /** Source test image */ private static RenderedImage testImage; /** No Data Range for Byte */ private static Range rangeNDByte; /** No Data Range for UShort */ private static Range rangeNDUSHort; /** No Data Range for Short */ private static Range rangeNDShort; /** No Data Range for Integer */ private static Range rangeNDInteger; /** No Data Range for Float */ private static Range rangeNDFloat; /** No Data Range for Double */ private static Range rangeNDDouble; /** Horizontal subsampling parameter */ private static int xPeriod; /** Vertical subsampling parameter */ private static int yPeriod; /** Array indicating the statistics to calculate */ private static StatsType[] arrayStats; /** Array with band indexes */ private static int[] bands; /** ROI object used for selecting the active area of the image */ private static ROI roi; /** Array indicating the number of bins for each band */ private static int[] numBins; /** Array indicating the maximum bounds for each band */ private static double[] maxBounds; /** Array indicating the minimum bounds for each band */ private static double[] minBounds; // Initial static method for preparing all the test data @BeforeClass public static void initialSetup() { // Setting of the image filler parameter to true for a better image creation IMAGE_FILLER = true; // Images initialization byte noDataB = 100; short noDataUS = 100; short noDataS = 100; int noDataI = 100; float noDataF = 100; double noDataD = 100; // Image creations switch (TEST_SELECTOR) { case DataBuffer.TYPE_BYTE: testImage = createTestImage(DataBuffer.TYPE_BYTE, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataB, false); break; case DataBuffer.TYPE_USHORT: testImage = createTestImage(DataBuffer.TYPE_USHORT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataUS, false); break; case DataBuffer.TYPE_SHORT: testImage = createTestImage(DataBuffer.TYPE_SHORT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataS, false); break; case DataBuffer.TYPE_INT: testImage = createTestImage(DataBuffer.TYPE_INT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataI, false); break; case DataBuffer.TYPE_FLOAT: testImage = createTestImage(DataBuffer.TYPE_FLOAT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataF, false); break; case DataBuffer.TYPE_DOUBLE: testImage = createTestImage(DataBuffer.TYPE_DOUBLE, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataD, false); break; default: throw new IllegalArgumentException("Wrong data type"); } // Image filler must be reset IMAGE_FILLER = false; // Range creation if selected if (RANGE_USED && !OLD_DESCRIPTOR) { switch (TEST_SELECTOR) { case DataBuffer.TYPE_BYTE: rangeNDByte = RangeFactory.create(noDataB, true, noDataB, true); break; case DataBuffer.TYPE_USHORT: rangeNDUSHort = RangeFactory.createU(noDataUS, true, noDataUS, true); break; case DataBuffer.TYPE_SHORT: rangeNDShort = RangeFactory.create(noDataS, true, noDataS, true); break; case DataBuffer.TYPE_INT: rangeNDInteger = RangeFactory.create(noDataI, true, noDataI, true); break; case DataBuffer.TYPE_FLOAT: rangeNDFloat = RangeFactory.create(noDataF, true, noDataF, true, true); break; case DataBuffer.TYPE_DOUBLE: rangeNDDouble = RangeFactory.create(noDataD, true, noDataD, true, true); break; default: throw new IllegalArgumentException("Wrong data type"); } } // ROI creation if (ROI_USED) { Rectangle rect = new Rectangle(0, 0, DEFAULT_WIDTH / 4, DEFAULT_HEIGHT / 4); roi = new ROIShape(rect); } else { roi = null; } // Statistic types definition if (STATISTIC == 0) { arrayStats = new StatsType[] { StatsType.MEAN }; } else if (STATISTIC == 1) { arrayStats = new StatsType[] { StatsType.EXTREMA }; } else if (STATISTIC == 2) { arrayStats = new StatsType[] { StatsType.HISTOGRAM }; } // Band definition bands = new int[] { 0, 1, 2 }; // Period Definitions xPeriod = 1; yPeriod = 1; // Histogram variables definition numBins = new int[] { 5 }; maxBounds = new double[] { 3 }; minBounds = new double[] { -3 }; } // General method for showing calculation time of the 2 StatisticDescriptors @Test public void testStatsDescriptor() { int[] numBinsTest = null; double[] maxBoundsTest = null; double[] minBoundsTest = null; // Statistic string String stat = ""; if (STATISTIC == 0) { stat += "Mean"; } else if (STATISTIC == 1) { stat += "Extrema"; } else if (STATISTIC == 2) { stat += "Histogram"; numBinsTest = numBins; maxBoundsTest = maxBounds; minBoundsTest = minBounds; } // Range initialization Range rangeND = null; // Image dataType int dataType = TEST_SELECTOR; // Descriptor string String description = "\n "; String propertyName = ""; // Control if the acceleration should be used for the old descriptor if (OLD_DESCRIPTOR) { propertyName += stat; description = "Old " + stat; if (NATIVE_ACCELERATION) { description += " accelerated "; System.setProperty("com.sun.media.jai.disableMediaLib", "false"); } else { System.setProperty("com.sun.media.jai.disableMediaLib", "true"); } // Control if the Range should be used for the new descriptor } else { propertyName += Statistics.STATS_PROPERTY; description = "New " + stat; System.setProperty("com.sun.media.jai.disableMediaLib", "true"); if (RANGE_USED) { switch (dataType) { case DataBuffer.TYPE_BYTE: rangeND = rangeNDByte; break; case DataBuffer.TYPE_USHORT: rangeND = rangeNDUSHort; break; case DataBuffer.TYPE_SHORT: rangeND = rangeNDShort; break; case DataBuffer.TYPE_INT: rangeND = rangeNDInteger; break; case DataBuffer.TYPE_FLOAT: rangeND = rangeNDFloat; break; case DataBuffer.TYPE_DOUBLE: rangeND = rangeNDDouble; break; default: throw new IllegalArgumentException("Wrong data type"); } } } // Data type string String dataTypeString = ""; switch (dataType) { case DataBuffer.TYPE_BYTE: dataTypeString += "Byte"; break; case DataBuffer.TYPE_USHORT: dataTypeString += "UShort"; break; case DataBuffer.TYPE_SHORT: dataTypeString += "Short"; break; case DataBuffer.TYPE_INT: dataTypeString += "Integer"; break; case DataBuffer.TYPE_FLOAT: dataTypeString += "Float"; break; case DataBuffer.TYPE_DOUBLE: dataTypeString += "Double"; break; default: throw new IllegalArgumentException("Wrong data type"); } // Total cycles number int totalCycles = BENCHMARK_ITERATION + NOT_BENCHMARK_ITERATION; // PlanarImage PlanarImage imageStats = null; // Initialization of the statistics 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 descriptor if (OLD_DESCRIPTOR) { if (STATISTIC == 0) { imageStats = javax.media.jai.operator.MeanDescriptor.create(testImage, roi, xPeriod, yPeriod, null); } else if (STATISTIC == 1) { imageStats = javax.media.jai.operator.ExtremaDescriptor.create(testImage, roi, xPeriod, yPeriod, false, 1, null); } else if (STATISTIC == 2) { imageStats = javax.media.jai.operator.HistogramDescriptor.create(testImage, roi, xPeriod, yPeriod, numBinsTest, minBoundsTest, maxBoundsTest, null); } } else { imageStats = StatisticsDescriptor.create(testImage, xPeriod, yPeriod, roi, rangeND, false, bands, arrayStats, minBoundsTest, maxBoundsTest, numBinsTest, null); } // Total statistic calculation time long start = System.nanoTime(); imageStats.getProperty(propertyName); 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 recalculated 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(dataTypeString); // Output print 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 (imageStats instanceof RenderedOp) { ((RenderedOp) imageStats).dispose(); } } }