/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 - 2016 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.testclasses; import it.geosolutions.jaiext.JAIExt; import java.awt.Rectangle; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import javax.media.jai.ROIShape; import javax.media.jai.TiledImage; import org.junit.BeforeClass; /** * This class is an abstract class used for creating test images used by the affine and scale operation test-classes. The * only two methods defined are roiCreation() and createTestImage(). The first is used for creating a new ROI object with * height and width respectively half of the image height and width. The second is used for creating a test image of the * selected data type. The image can be filled with data inside by setting the JAI.Ext.ImageFill parameter to true from * the console, but this slows the test-computations. The image is by default a cross surrounded by lots of pixel with * value 0. For binary images a big rectangle is added into the left half of the image; for not-binary images a simple * square is added in the upper left of the image. The square is useful for the rotate operation(inside the jt-affine * project) because it shows if the image has been correctly rotated. */ public abstract class TestBase { /** Default value for image width */ public static int DEFAULT_WIDTH = 256; /** Default value for image height */ public static int DEFAULT_HEIGHT = 256; /** * Default value for subsample bits * */ public static final int DEFAULT_SUBSAMPLE_BITS = 8; /** * Default value for precision bits * */ public static final int DEFAULT_PRECISION_BITS = 8; public static boolean INTERACTIVE = Boolean.getBoolean("JAI.Ext.Interactive"); public static boolean IMAGE_FILLER = Boolean.getBoolean("JAI.Ext.ImageFill"); public static Integer INVERSE_SCALE = Integer.getInteger("JAI.Ext.InverseScale",0); public static Integer TEST_SELECTOR = Integer.getInteger("JAI.Ext.TestSelector",0); protected double destinationNoData; protected float transX = 0; protected float transY = 0; protected float scaleX = 0.5f; protected float scaleY = 0.5f; public enum InterpolationType { NEAREST_INTERP(0), BILINEAR_INTERP(1), BICUBIC_INTERP(2),GENERAL_INTERP(3); private int type; InterpolationType(int type){ this.type=type; } public int getType() { return type; } } public enum ScaleType { MAGNIFY(0), REDUCTION(1); private int type; ScaleType(int type){ this.type=type; } public int getType() { return type; } } public enum TestSelection { NO_ROI_ONLY_DATA(0) , ROI_ACCESSOR_ONLY_DATA(1) , ROI_ONLY_DATA(2) , ROI_ACCESSOR_NO_DATA(3) ,NO_ROI_NO_DATA(4) ,ROI_NO_DATA(5) ,BINARY_ROI_ACCESSOR_NO_DATA(6); private int type; TestSelection(int type) { this.type = type; } public int getType() { return type; } } public enum TransformationType { ROTATE_OP(0), TRANSLATE_OP(2), SCALE_OP(1), ALL(3); private int value; TransformationType(int value) { this.value = value; } public int getValue() { return value; } } protected ROIShape roiCreation() { int roiHeight = DEFAULT_HEIGHT *3/ 4; int roiWidth = DEFAULT_WIDTH *3/ 4; Rectangle roiBound = new Rectangle(0, 0, roiWidth, roiHeight); ROIShape roi = new ROIShape(roiBound); return roi; } /** Simple method for image creation */ public static RenderedImage createTestImage(int dataType, int width, int height, Number noDataValue, boolean isBinary) { return createTestImage(dataType, width,height, noDataValue, isBinary, 3); } public static RenderedImage createTestImage(int dataType, int width, int height, Number noDataValue, boolean isBinary, int bands){ return createTestImage(dataType, width, height, noDataValue, isBinary, bands, null); } /** Simple method for image creation */ public static RenderedImage createTestImage(int dataType, int width, int height, Number noDataValue, boolean isBinary, int bands, Number validData) { // parameter block initialization int tileW = width / 8; int tileH = height / 8; int imageDim = width * height; // This values could be used for fill all the image byte valueB = validData != null ? validData.byteValue() : 64; short valueUS = validData != null ? validData.shortValue() : Short.MAX_VALUE / 4; short valueS = validData != null ? validData.shortValue() : -50; int valueI = validData != null ? validData.intValue() : 100; float valueF = validData != null ? validData.floatValue() : (255 / 2) * 5f; double valueD = validData != null ? validData.doubleValue() : (255 / 1) * 4d; boolean fillImage = IMAGE_FILLER; Byte crossValueByte = null; Short crossValueUShort = null; Short crossValueShort = null; Integer crossValueInteger = null; Float crossValueFloat = null; Double crossValueDouble = null; int numBands = bands; final SampleModel sm; if (isBinary) { // Binary images Sample Model sm = new MultiPixelPackedSampleModel(dataType, width, height, 1); numBands = 1; } else { if(numBands == 3){ sm = new ComponentSampleModel(dataType, width, height, 3, width, new int[] { 0, imageDim, imageDim * 2 }); }else{ sm = new ComponentSampleModel(dataType, width, height, 1, width, new int[] {0}); } } // Create the constant operation. TiledImage used = new TiledImage(sm, tileW, tileH); switch (dataType) { case DataBuffer.TYPE_BYTE: crossValueByte = (Byte) noDataValue; break; case DataBuffer.TYPE_USHORT: crossValueUShort = (Short) noDataValue; break; case DataBuffer.TYPE_SHORT: crossValueShort = (Short) noDataValue; break; case DataBuffer.TYPE_INT: crossValueInteger = (Integer) noDataValue; break; case DataBuffer.TYPE_FLOAT: crossValueFloat = (Float) noDataValue; break; case DataBuffer.TYPE_DOUBLE: crossValueDouble = (Double) noDataValue; break; default: throw new IllegalArgumentException("Wrong data type"); } int imgBinX=width/4; int imgBinY=height/4; int imgBinWidth=imgBinX + width/4; int imgBinHeight=imgBinY + height/4; for (int b = 0; b < numBands; b++) { for (int j = 0; j < width; j++) { for (int k = 0; k < height; k++) { //Addition of a cross on the image if (j == k || j == width - k - 1) { switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, crossValueByte); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, crossValueUShort); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, crossValueShort); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, crossValueInteger); break; case DataBuffer.TYPE_FLOAT: used.setSample(j, k, b, crossValueFloat); break; case DataBuffer.TYPE_DOUBLE: used.setSample(j, k, b, crossValueDouble); break; default: throw new IllegalArgumentException("Wrong data type"); } //If selected, the image could be filled } else if (!isBinary && fillImage) { // a little square of no data on the upper left is inserted if( (j>=20) && (j<50) && (k>=20) && (k<50)){ switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, 0); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, 0); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, 0); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, 0); break; case DataBuffer.TYPE_FLOAT: used.setSample(j, k, b, 0); break; case DataBuffer.TYPE_DOUBLE: used.setSample(j, k, b,0); break; default: throw new IllegalArgumentException("Wrong data type"); } if( (j>=30) && (j<40) && (k>=20) && (k<30)){ switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, crossValueByte); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, crossValueUShort); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, crossValueShort); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, crossValueInteger); break; case DataBuffer.TYPE_FLOAT: used.setSample(j, k, b, crossValueFloat); break; case DataBuffer.TYPE_DOUBLE: used.setSample(j, k, b, crossValueDouble); break; default: throw new IllegalArgumentException("Wrong data type"); } } }else{ switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, valueB + b); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, valueUS + b); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, valueS + b); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, valueI + b); break; case DataBuffer.TYPE_FLOAT: float data = valueF + b / 3.0f; used.setSample(j, k, b, data); break; case DataBuffer.TYPE_DOUBLE: double dataD = valueD + b / 3.0d; used.setSample(j, k, b, dataD); break; default: throw new IllegalArgumentException("Wrong data type"); } } //If is binary a rectangle is added }else if (isBinary && (j>imgBinX && j<imgBinWidth) && (j>imgBinY && j<imgBinHeight)) { switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, crossValueByte); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, crossValueUShort); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, crossValueShort); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, crossValueInteger); break; default: throw new IllegalArgumentException("Wrong data type"); } // Else, a little square of no data on the upper left is inserted }else{ if( (j>=2) && (j<10) && (k>=2) && (k<10)){ switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, crossValueByte); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, crossValueUShort); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, crossValueShort); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, crossValueInteger); break; case DataBuffer.TYPE_FLOAT: used.setSample(j, k, b, crossValueFloat); break; case DataBuffer.TYPE_DOUBLE: used.setSample(j, k, b, crossValueDouble); break; default: throw new IllegalArgumentException("Wrong data type"); } } if( (j>=150) && (j<170) && (k>=90) && (k<110)){ switch (dataType) { case DataBuffer.TYPE_BYTE: used.setSample(j, k, b, crossValueByte); break; case DataBuffer.TYPE_USHORT: used.setSample(j, k, b, crossValueUShort); break; case DataBuffer.TYPE_SHORT: used.setSample(j, k, b, crossValueShort); break; case DataBuffer.TYPE_INT: used.setSample(j, k, b, crossValueInteger); break; case DataBuffer.TYPE_FLOAT: used.setSample(j, k, b, crossValueFloat); break; case DataBuffer.TYPE_DOUBLE: used.setSample(j, k, b, crossValueDouble); break; default: throw new IllegalArgumentException("Wrong data type"); } } } } } } return used; } @BeforeClass public static void setup(){ JAIExt.initJAIEXT(); } }