/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * 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 boofcv.struct.image; import org.junit.Test; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Random; import static org.junit.Assert.*; /** * Standard tests for children of {@link ImageGray}. Ensures that they contain * all the expected functions and that they have the expected behavior. This is done * through extensive use of reflections. * * @author Peter Abeles */ public abstract class StandardImageInterleavedTests<T extends ImageInterleaved> { public Random rand = new Random(234); public abstract T createImage(int width, int height, int numBands); public abstract T createImage(); public abstract Number randomNumber(); public abstract Number getNumber( Number value ); /** * Sets each element in the image to a random value. */ public void setRandom(T img) { Object data = img._getData(); int N = Array.getLength(data); for (int i = 0; i < N; i++) { Array.set(data, i, randomNumber()); } } /** * Checks to see if the implementation specific to ImageInterleavedTests * works */ @Test public void isSubimage() { T a = createImage(10, 20, 3); assertFalse(a.isSubimage()); assertTrue(a.subimage(0, 5, 0, 5, null).isSubimage()); assertTrue(a.subimage(2, 5, 2, 5, null).isSubimage()); } /** * Check for a positive case of get() and set() */ @Test public void get_set() { T img = createImage(10, 20, 3); setRandom(img); for( int y = 0; y < img.height; y++ ) { for( int x = 0; x < img.width; x++ ) { Object expected = createPixelArray(img); Object orig = call(img, "get", 2, null, x, y); // make sure the two are not equal assertFalse(compareArrays(expected, orig, img.getNumBands())); // set the expected to the point in the image call(img, "set", 2, expected, x, y); Object found = call(img, "get", 2, null, x, y); assertTrue(compareArrays(expected, found, img.getNumBands())); } } } /** * Check for a positive case of get() and set() */ @Test public void getBand_setBand() { T img = createImage(10, 20, 2); setRandom(img); for( int y = 0; y < img.height; y++ ) { for( int x = 0; x < img.width; x++ ) { for( int b = 0; b < img.numBands; b++ ) { Number expected = randomNumber(); Number orig = (Number) call(img, "getBand", 0, null, x, y, b); // make sure the two are not equal assertFalse(expected.equals(orig)); // set the expected to the point in the image call(img, "setBand", 1, expected, x, y, b); Number found = (Number) call(img, "getBand", 0, null, x, y, b); assertTrue(getNumber(expected).doubleValue() == found.doubleValue() ); } } } } /** * Makes sure all the accessors do proper bounds checking */ @Test public void accessorBounds() { T img = createImage(10, 20, 3); checkBound(img, "get", 2, null); checkBoundBand(img, "getBand", 0, null); checkBound(img, "set", 2, null); checkBoundBand(img, "setBand", 1, randomNumber()); } private void checkBound(T img, String method, int type, Object typeData) { checkException(img, method, type, typeData, -1, 0); checkException(img, method, type, typeData, 0, -1); checkException(img, method, type, typeData, img.getWidth(), 0); checkException(img, method, type, typeData, 0, img.getHeight()); } private void checkBoundBand(T img, String method, int type, Object typeData) { checkException(img, method, type, typeData, -1, 0, 0); checkException(img, method, type, typeData, 0, -1, 0); checkException(img, method, type, typeData, img.getWidth(), 0, 0); checkException(img, method, type, typeData, 0, img.getHeight(), 0); checkException(img, method, type, typeData, 0, 0, img.getNumBands()); } private void checkException(ImageInterleaved img, String method, int type, Object typeData, int... where) { boolean found = false; try { call(img, method, type, typeData, where); } catch (ImageAccessException e) { found = true; } assertTrue("No exception was thrown", found); } private Object call(ImageInterleaved img, String method, int type, Object typeData, int... where) { try { Class<?>[] paramTypes = type == 0 ? new Class<?>[where.length] : new Class<?>[where.length + 1]; Object[] args = new Object[paramTypes.length]; int index; for (index = 0; index < where.length; index++) { paramTypes[index] = int.class; args[index] = where[index]; } if (type == 1) { paramTypes[index] = img.getPrimitiveDataType(); args[index] = typeData; } else if (type == 2) { String name = "[" + img.getPrimitiveDataType().getName().toUpperCase().charAt(0); if( name.charAt(1) == 'L') name = "[J"; paramTypes[index] = Class.forName(name); args[index] = typeData; } Method m = img.getClass().getMethod(method, paramTypes); return m.invoke(img, args); } catch (ClassNotFoundException | IllegalAccessException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { fail("The method " + method + " needs to be implemented"); } catch (InvocationTargetException e) { throw (RuntimeException) e.getCause(); } throw new RuntimeException("Shouldn't be here"); } private Object createPixelArray(ImageInterleaved img) { int numBands = img.getNumBands(); Object ret = Array.newInstance(img.getPrimitiveDataType(), numBands); for (int i = 0; i < numBands; i++) Array.set(ret, i, randomNumber()); return ret; } private boolean compareArrays(Object a, Object b, int length) { for (int i = 0; i < length; i++) { Number valA = (Number) Array.get(a, i); Number valB = (Number) Array.get(b, i); if (!valA.equals(valB)) return false; } return true; } @Test public void setNumBands() { T a = createImage(10, 20, 3); a.setNumBands(2); assertEquals(2,a.getNumBands()); assertEquals(2,a.getImageType().getNumBands()); } @Test public void checkImageTypeSet() { T a = createImage(10, 20, 3); assertTrue(a.getImageType() != null); assertEquals(3,a.getImageType().getNumBands()); } @Test public void checkNoArgumentConstructor() { T a = createImage(); assertTrue(a._getData() == null); assertTrue(a.getPrimitiveDataType() != null); assertTrue(a.getImageType() != null); } }