/* 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.lookup; import it.geosolutions.jaiext.JAIExt; import it.geosolutions.jaiext.range.Range; import it.geosolutions.jaiext.range.RangeFactory; import it.geosolutions.jaiext.testclasses.TestBase; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import javax.media.jai.JAI; import javax.media.jai.LookupTableJAI; 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 LookupDescriptor and the its old JAI version. 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.If the user want to use the old LookupDescriptor 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 3 (where 0 means byte, 1 Ushort, 2 Short, 3 Integer). Inside this test class the various tests are executed in the same * manner: * <ul> * <li>Selection of the LookupDescriptor(Old or New)</li> * <li>Selection of the source image(4 different dataType)</li> * <li>statistic calculation (if the cycle belongs to the benchmark cycles)</li> * </ul> * 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); /** 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"); /** Destination No Data value */ private static double destinationNoDataValue; /** Byte image */ private static RenderedImage testImageByte; /** Unsigned Short image */ private static RenderedImage testImageUShort; /** Short image */ private static RenderedImage testImageShort; /** Integer image */ private static RenderedImage testImageInt; /** LookupTable from byte to byte */ private static LookupTable byteToByteTableNew; /** LookupTable from ushort to byte */ private static LookupTable ushortToByteTableNew; /** LookupTable from short to byte */ private static LookupTable shortToByteTableNew; /** LookupTable from int to byte */ private static LookupTable intToByteTableNew; /** LookupTableJAI from byte to byte */ private static LookupTableJAI byteToByteTableOld; /** LookupTableJAI from ushort to byte */ private static LookupTableJAI ushortToByteTableOld; /** LookupTableJAI from short to byte */ private static LookupTableJAI shortToByteTableOld; /** LookupTableJAI from int to byte */ private static LookupTableJAI intToByteTableOld; private static Range rangeND; // Initial static method for preparing all the test data @BeforeClass public static void initialSetup() { // Setting of the imaage filler parameter to false for a faster image creation IMAGE_FILLER = false; // Images initialization // Byte Range goes from 0 to 255 byte noDataB = -100; short noDataUS = 100; short noDataS = -100; int noDataI = -100; // Image creations testImageByte = createTestImage(DataBuffer.TYPE_BYTE, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataB, false); testImageUShort = createTestImage(DataBuffer.TYPE_USHORT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataUS, false); testImageShort = createTestImage(DataBuffer.TYPE_SHORT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataS, false); testImageInt = createTestImage(DataBuffer.TYPE_INT, DEFAULT_WIDTH, DEFAULT_HEIGHT, noDataI, false); // Offset creation int byteOffset = 0; int ushortOffset = 0; int shortOffset = noDataS; int intOffset = noDataI; // Array Lookup creation int arrayLength = 201; int startValue = -100; // Array Initialization byte[] dataByteB = new byte[arrayLength]; byte[] dataUShortB = new byte[arrayLength]; byte[] dataShortB = new byte[arrayLength]; byte[] dataIntB = new byte[arrayLength]; // Construction of the various arrays for (int i = 0; i < arrayLength; i++) { dataByteB[i] = 0; dataUShortB[i] = 0; dataShortB[i] = 0; dataIntB[i] = 0; int value = i + startValue; if (value == noDataI) { dataShortB[i] = 50; dataIntB[i] = 50; dataByteB[i] = 50; } if (i == noDataUS) { // ushort-to-all arrays dataUShortB[i] = 50; } } // LookupTables creation byteToByteTableNew = new LookupTable(dataByteB, byteOffset); ushortToByteTableNew = new LookupTable(dataUShortB, ushortOffset); shortToByteTableNew = new LookupTable(dataShortB, shortOffset); intToByteTableNew = new LookupTable(dataIntB, intOffset); byteToByteTableOld = new LookupTableJAI(dataByteB, byteOffset); ushortToByteTableOld = new LookupTableJAI(dataUShortB, ushortOffset); shortToByteTableOld = new LookupTableJAI(dataShortB, shortOffset); intToByteTableOld = new LookupTableJAI(dataIntB, intOffset); // Destination No Data destinationNoDataValue = 50; //Range creation if selected rangeND= null; if(RANGE_USED && !OLD_DESCRIPTOR){ switch(TEST_SELECTOR){ case DataBuffer.TYPE_BYTE: rangeND = RangeFactory.create((byte)100,true,(byte)100,true); break; case DataBuffer.TYPE_USHORT: rangeND = RangeFactory.createU((short)100,true,(short)100,true); break; case DataBuffer.TYPE_SHORT: rangeND = RangeFactory.create((short)100,true,(short)100,true); break; case DataBuffer.TYPE_INT: rangeND = RangeFactory.create(100,true,100,true); break; default: throw new IllegalArgumentException("Wrong data type"); } } if(OLD_DESCRIPTOR){ JAIExt.registerJAIDescriptor("lookup"); } } @Test public void testNewLookupDescriptorByte() { if (TEST_SELECTOR == DataBuffer.TYPE_BYTE && !OLD_DESCRIPTOR) { testLookup(testImageByte, DataBuffer.TYPE_BYTE, byteToByteTableNew,rangeND, OLD_DESCRIPTOR); } } @Test public void testOldLookupDescriptorByte() { if (TEST_SELECTOR == DataBuffer.TYPE_BYTE && OLD_DESCRIPTOR) { testLookup(testImageByte, DataBuffer.TYPE_BYTE, byteToByteTableOld,rangeND, OLD_DESCRIPTOR); } } @Test public void testNewLookupDescriptorUShort() { if (TEST_SELECTOR == DataBuffer.TYPE_USHORT && !OLD_DESCRIPTOR) { testLookup(testImageUShort, DataBuffer.TYPE_USHORT, ushortToByteTableNew,rangeND, OLD_DESCRIPTOR); } } @Test public void testOldLookupDescriptorUShort() { if (TEST_SELECTOR == DataBuffer.TYPE_USHORT && OLD_DESCRIPTOR) { testLookup(testImageUShort, DataBuffer.TYPE_USHORT, ushortToByteTableOld,rangeND, OLD_DESCRIPTOR); } } @Test public void testNewLookupDescriptorShort() { if (TEST_SELECTOR == DataBuffer.TYPE_SHORT && !OLD_DESCRIPTOR) { testLookup(testImageShort, DataBuffer.TYPE_SHORT, shortToByteTableNew,rangeND, OLD_DESCRIPTOR); } } @Test public void testOldLookupDescriptorShort() { if (TEST_SELECTOR == DataBuffer.TYPE_SHORT && OLD_DESCRIPTOR) { testLookup(testImageShort, DataBuffer.TYPE_SHORT, shortToByteTableOld,rangeND, OLD_DESCRIPTOR); } } @Test public void testNewLookupDescriptorInt() { if (TEST_SELECTOR == DataBuffer.TYPE_INT && !OLD_DESCRIPTOR) { testLookup(testImageInt, DataBuffer.TYPE_INT, intToByteTableNew,rangeND, OLD_DESCRIPTOR); } } @Test public void testOldLookupDescriptorInt() { if (TEST_SELECTOR == DataBuffer.TYPE_INT && OLD_DESCRIPTOR) { testLookup(testImageInt, DataBuffer.TYPE_INT, intToByteTableOld,rangeND, OLD_DESCRIPTOR); } } // General method for showing calculation time of the 2 LookupDescriptors public void testLookup(RenderedImage testIMG, int dataType, Object table,Range rangeND, boolean old) { // Descriptor string String description = "\n "; if (old) { description = "Old Lookup"; 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 Lookup"; System.setProperty("com.sun.media.jai.disableMediaLib", "true"); } // 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; } // Total cycles number int totalCycles = BENCHMARK_ITERATION + NOT_BENCHMARK_ITERATION; // PlanarImage PlanarImage imageLookup = 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) { imageLookup = javax.media.jai.operator.LookupDescriptor.create(testIMG, (LookupTableJAI) table, null); } else { imageLookup = LookupDescriptor.create(testIMG, (LookupTable) table, destinationNoDataValue, null, rangeND, false, null); } // Total calculation time long start = System.nanoTime(); imageLookup.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(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 (imageLookup instanceof RenderedOp) { ((RenderedOp) imageLookup).dispose(); } } }