/* 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.imagefunction;
import static org.junit.Assert.assertEquals;
import it.geosolutions.jaiext.iterators.RandomIterFactory;
import it.geosolutions.jaiext.range.Range;
import it.geosolutions.jaiext.range.RangeFactory;
import it.geosolutions.jaiext.testclasses.TestBase;
import java.awt.Rectangle;
import javax.media.jai.ROI;
import javax.media.jai.ROIShape;
import javax.media.jai.RenderedOp;
import javax.media.jai.iterator.RandomIter;
import org.junit.Test;
/**
* Test class for the imagefunction operation
*
* @author Nicola Lagomarsini GeoSolutions
*
*/
public class ImageFunctionTest extends TestBase {
private static final double TOLERANCE = 0.01;
@Test
public void testImageFunction() {
// Creating a NoData range
Range nodata = RangeFactory.create(25.0f, 25.0f);
// Definition of the translation/scale parameters
float xTrans = 5;
float yTrans = 5;
float xScale = 2;
float yScale = 2;
// ROI definition
ROI roi = new ROIShape(new Rectangle(0, 0, 15, 15));
// Output value for NoData
float destNoData = 30;
// Image size
int width = 128;
int height = 128;
// New dummy function for test
ImageFunctionJAIEXT function = new DummyFunction();
// Performing operation
RenderedOp transformed = ImageFunctionDescriptor.create(function, width, height, xScale,
yScale, xTrans, yTrans, roi, nodata, destNoData, null);
// Checking if the result is correct
checkNoDataROI(transformed, roi, nodata, xScale, yScale);
}
/**
* Method for checking if NoData and ROI are correctly handled
*
* @param finalimage
* @param roi
* @param nodata
* @param deltaX
* @param deltaY
*/
private void checkNoDataROI(RenderedOp finalimage, ROI roi, Range nodata, float deltaX,
float deltaY) {
RandomIter roiIter = RandomIterFactory.create(roi.getAsImage(), null, true, true);
Rectangle roiBounds = roi.getBounds();
RandomIter destIter = RandomIterFactory.create(finalimage, null, true, true);
// Start the iteration (we iterate only the first band)
int w = finalimage.getWidth();
int h = finalimage.getHeight();
int minX = finalimage.getMinX();
int minY = finalimage.getMinY();
int maxX = minX + w;
int maxY = minY + h;
nodata = RangeFactory.convertToDoubleRange(nodata);
double result = minX + minY;
for (int y = minY; y < maxY; y++) {
for (int x = minX; x < maxX; x++) {
double dest = destIter.getSampleDouble(x, y, 0);
boolean valid = true;
// ROI Check
if (roiBounds != null
&& !(roiBounds.contains(x, y) && roiIter.getSample(x, y, 0) > 0)) {
valid = false;
}
// NoData Check
if (nodata != null && nodata.contains(result)) {
valid = false;
}
if (!valid) {
assertEquals(30, dest, TOLERANCE);
}
result += deltaX;
}
result += deltaY;
}
}
/**
* Dummy implementation of the {@link ImageFunctionJAIEXT} interface used for testing the {@link ImageFunctionOpImage} class
*
* @author Nicola Lagomarsini
*/
public static class DummyFunction implements ImageFunctionJAIEXT {
public void getElements(float arg0, float arg1, float arg2, float arg3, int arg4, int arg5,
int arg6, float[] arg7, float[] arg8) {
getElements(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, null, null, null, 0);
}
public void getElements(double arg0, double arg1, double arg2, double arg3, int arg4,
int arg5, int arg6, double[] arg7, double[] arg8) {
getElements(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, null, null, null, 0);
}
public int getNumElements() {
return 1;
}
public boolean isComplex() {
return false;
}
public void getElements(float startX, float startY, float deltaX, float deltaY, int countX,
int countY, int element, float[] real, float[] imag, Rectangle destRect, ROI roi,
Range nodata, float destNoData) {
int index = 0;
Rectangle roiBounds = roi != null ? roi.getBounds() : null;
RandomIter it = roi != null ? RandomIterFactory.create(roi.getAsImage(), null, true,
true) : null;
// Simple function.
float result = startX + startY;
int x0 = destRect.x;
int y0 = destRect.y;
for (int j = 0; j < countY; j++) {
int y = y0 + j;
for (int i = 0; i < countX; i++) {
int x = x0 + i;
// ROI Check
if (roiBounds != null && roiBounds.contains(x, y) && it.getSample(x, y, 0) > 0) {
// NoData check
if (nodata != null && !nodata.contains(result)) {
real[index++] = result;
} else {
real[index++] = destNoData;
}
} else {
real[index++] = destNoData;
}
result += deltaX;
}
result += deltaY;
}
}
public void getElements(double startX, double startY, double deltaX, double deltaY,
int countX, int countY, int element, double[] real, double[] imag,
Rectangle destRect, ROI roi, Range nodata, float destNoData) {
int index = 0;
Rectangle roiBounds = roi != null ? roi.getBounds() : null;
RandomIter it = roi != null ? RandomIterFactory.create(roi.getAsImage(), null, true,
true) : null;
// Simple function.
double result = startX + startY;
int x0 = destRect.x;
int y0 = destRect.y;
for (int j = 0; j < countY; j++) {
int y = y0 + j;
for (int i = 0; i < countX; i++) {
int x = x0 + i;
// ROI Check
if (roiBounds != null && roiBounds.contains(x, y) && it.getSample(x, y, 0) > 0) {
// NoData check
if (nodata != null && !nodata.contains(result)) {
real[index++] = result;
} else {
real[index++] = destNoData;
}
} else {
real[index++] = destNoData;
}
result += deltaX;
}
result += deltaY;
}
}
}
}