/* * 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.alg.misc; import boofcv.misc.AutoTypeImage; import boofcv.misc.CodeGeneratorBase; import boofcv.struct.image.ImageType; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import static boofcv.misc.AutoTypeImage.*; /** * Generates functions inside of {@link boofcv.alg.misc.ImageMiscOps}. * * @author Peter Abeles */ public class GeneratePixelMath extends CodeGeneratorBase { String className = "PixelMath"; private AutoTypeImage input; ImageType.Family families[] = new ImageType.Family[]{ImageType.Family.GRAY,ImageType.Family.INTERLEAVED}; public void generate() throws FileNotFoundException { printPreamble(); printAbs(); printInvert(); List<TwoTemplate> listTwo = new ArrayList<>(); listTwo.add( new Multiple()); listTwo.add( new Divide()); listTwo.add( new Plus()); listTwo.add( new Minus(true)); listTwo.add( new Minus(false)); for( TwoTemplate t : listTwo ) { print_img_scalar(t,false); print_img_scalar(t,true); } printAll(); out.println("}"); } private void printPreamble() throws FileNotFoundException { setOutputFile(className); out.print("import boofcv.struct.image.*;\n" + "\n" + "import boofcv.alg.InputSanityCheck;\n" + "import javax.annotation.Generated;\n" + "\n" + "/**\n" + " * Functions which perform basic arithmetic (e.g. addition, subtraction, multiplication, or " + "division) on a pixel by pixel basis.\n" + " *\n" + " * <p>DO NOT MODIFY: Generated by " + getClass().getName() + ".</p>\n" + " *\n" + " * @author Peter Abeles\n" + " */\n" + generatedString() + "public class " + className + " {\n\n"); } public void printAll() { AutoTypeImage types[] = AutoTypeImage.getSpecificTypes(); for( AutoTypeImage t : types ) { input = t; printBoundImage(); printDiffAbs(); printAverageBand(); } AutoTypeImage outputsAdd[] = new AutoTypeImage[]{U16,S16,S32,S32,S32,S64,F32,F64}; AutoTypeImage outputsSub[] = new AutoTypeImage[]{I16,S16,S32,S32,S32,S64,F32,F64}; for( int i = 0; i < types.length; i++ ) { printAddTwoImages(types[i],outputsAdd[i]); printSubtractTwoImages(types[i],outputsSub[i]); if( !types[i].isInteger() ) { printMultTwoImages(types[i],types[i]); printDivTwoImages(types[i],types[i]); printLog(types[i],types[i]); printPow2(types[i], types[i]); printSqrt(types[i], types[i]); } } } private void print( String funcName , String javadoc , String operation , AutoTypeImage types[] ) { for( AutoTypeImage t : types ) { input = t; for (ImageType.Family family : families) { String inputName, columns; if (family == ImageType.Family.INTERLEAVED) { inputName = input.getInterleavedName(); columns = "input.width*input.numBands"; } else { inputName = input.getSingleBandName(); columns = "input.width"; } out.println(javadoc + "\n" + "\tpublic static void " + funcName + "( " + inputName + " input , " + inputName + " output ) {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape(input,output);\n" + "\n" + "\t\tint columns = " + columns + ";\n" + "\t\t" + funcName + "(input.data,input.startIndex,input.stride,\n" + "\t\t\t\toutput.data,output.startIndex,output.stride,\n" + "\t\t\t\tinput.height,columns);\n" + "\t}\n"); } printArray(funcName,operation); } } public void printArray( String funcName , String operation ) { String arrayType = input.getDataType(); out.println("\tprivate static void "+funcName+"( "+arrayType+"[] input , int inputStart , int inputStride ,\n" + "\t\t\t\t\t\t\t "+arrayType+"[] output , int outputStart , int outputStride ,\n" + "\t\t\t\t\t\t\t int rows , int cols )\n" + "\t{\n" + "\t\tfor( int y = 0; y < rows; y++ ) {\n" + "\t\t\tint indexSrc = inputStart + y*inputStride;\n" + "\t\t\tint indexDst = outputStart + y*outputStride;\n" + "\t\t\tint end = indexSrc + cols;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\toutput[indexDst] = "+input.getTypeCastFromSum()+operation +";\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n"); } public void printAbs() { String javaDoc = "\t/**\n" + "\t * Sets each pixel in the output image to be the absolute value of the input image.\n" + "\t * Both the input and output image can be the same instance.\n" + "\t * \n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output Where the absolute value image is written to. Modified.\n" + "\t */"; print("abs",javaDoc,"Math.abs(input[indexSrc])",AutoTypeImage.getSigned()); } public void printInvert() { String javaDoc = "\t/**\n" + "\t * Changes the sign of every pixel in the image: output[x,y] = -input[x,y]\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output Where the inverted image is written to. Modified.\n" + "\t */"; print("invert",javaDoc,"-input[indexSrc]",AutoTypeImage.getSigned()); } private void print_img_scalar( TwoTemplate template , boolean bounded ) { String funcName = template.getName(); String varName = template.getVariableName(); for( AutoTypeImage t : template.getTypes() ) { input = t; String variableType; if( template.isScaleOp() ) variableType = input.isInteger() ? "double" : input.getSumType(); else variableType = input.getSumType(); String funcArrayName = input.isSigned() ? funcName : funcName+"U"; funcArrayName += template.isImageFirst() ? "_A" : "_B"; for (ImageType.Family family : families) { String inputName, columns, banded; if (family == ImageType.Family.INTERLEAVED) { inputName = input.getInterleavedName(); columns = "input.width*input.numBands"; banded = "B"; } else { inputName = input.getSingleBandName(); columns = "input.width"; banded = ""; } if( bounded ) { String sumType = input.getSumType(); String prototype; if (template.isImageFirst()) { prototype = "( " + inputName + " input , " + variableType + " " + varName + " , " + sumType +" lower , " +sumType+ " upper , " + inputName + " output )"; } else { prototype = "( " + variableType + " " + varName + " , " + inputName + " input , " + sumType +" lower , " +sumType+ " upper , " + inputName + " output )";; } out.println(template.getJavaDoc()); out.println("\tpublic static void " + funcName + prototype + " {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape(input,output);\n" + "\n" + "\t\tint columns = " + columns + ";\n" + "\t\t" + funcArrayName + "(input.data,input.startIndex,input.stride," + varName + ", lower, upper ,\n" + "\t\t\t\toutput.data,output.startIndex,output.stride,\n" + "\t\t\t\tinput.height,columns);\n" + "\t}\n"); } else { String prototype; if (template.isImageFirst()) { prototype = "( " + inputName + " input , " + variableType + " " + varName + " , " + inputName + " output )"; } else { prototype = "( " + variableType + " " + varName + " , " + inputName + " input , " + inputName + " output )"; } out.println(template.getJavaDoc()); out.println("\tpublic static void " + funcName + prototype + " {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape"+banded+"(input,output);\n" + "\n" + "\t\tint columns = " + columns + ";\n" + "\t\t" + funcArrayName + "(input.data,input.startIndex,input.stride," + varName + " , \n" + "\t\t\t\toutput.data,output.startIndex,output.stride,\n" + "\t\t\t\tinput.height,columns);\n" + "\t}\n"); } } if( bounded ) { print_array_scalar_bounded(funcArrayName, variableType, varName, template.getOperation()); } else { print_array_scalar(funcArrayName, variableType, varName, template.getOperation()); } } } public void print_array_scalar(String funcName , String varType , String varName , String operation ) { String arrayType = input.getDataType(); String typeCast = varType.equals(input.getDataType()) ? "" : "("+input.getDataType()+")"; out.println("\tprivate static void "+funcName+"( "+arrayType+"[] input , int inputStart , int inputStride , \n" + "\t\t\t\t\t\t\t "+varType+" "+varName+" ,\n" + "\t\t\t\t\t\t\t "+arrayType+"[] output , int outputStart , int outputStride ,\n" + "\t\t\t\t\t\t\t int rows , int cols )\n" + "\t{\n" + "\t\tfor( int y = 0; y < rows; y++ ) {\n" + "\t\t\tint indexSrc = inputStart + y*inputStride;\n" + "\t\t\tint indexDst = outputStart + y*outputStride;\n" + "\t\t\tint end = indexSrc + cols;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\toutput[indexDst] = "+typeCast+operation +";\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n"); } public void print_array_scalar_bounded(String funcName , String varType , String varName , String operation ) { String arrayType = input.getDataType(); String sumType = input.getSumType(); String typeCast = varType.equals(sumType) ? "" : "("+sumType+")"; out.println("\tprivate static void "+funcName+"( "+arrayType+"[] input , int inputStart , int inputStride , \n" + "\t\t\t\t\t\t\t "+varType+" "+varName+" , "+sumType+" lower , "+sumType+" upper ,\n" + "\t\t\t\t\t\t\t "+arrayType+"[] output , int outputStart , int outputStride ,\n" + "\t\t\t\t\t\t\t int rows , int cols )\n" + "\t{\n" + "\t\tfor( int y = 0; y < rows; y++ ) {\n" + "\t\t\tint indexSrc = inputStart + y*inputStride;\n" + "\t\t\tint indexDst = outputStart + y*outputStride;\n" + "\t\t\tint end = indexSrc + cols;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\t"+sumType+" val = "+typeCast+operation+";\n" + "\t\t\t\tif( val < lower ) val = lower;\n" + "\t\t\t\tif( val > upper ) val = upper;\n" + "\t\t\t\toutput[indexDst] = "+input.getTypeCastFromSum()+"val;\n"+ "\t\t\t}\n" + "\t\t}\n" + "\t}\n"); } public void printBoundImage() { String bitWise = input.getBitWise(); String sumType = input.getSumType(); out.print("\t/**\n" + "\t * Bounds image pixels to be between these two values\n" + "\t * \n" + "\t * @param img Image\n" + "\t * @param min minimum value.\n" + "\t * @param max maximum value.\n" + "\t */\n" + "\tpublic static void boundImage( "+input.getSingleBandName()+" img , "+sumType+" min , "+sumType+" max ) {\n" + "\t\tfinal int h = img.getHeight();\n" + "\t\tfinal int w = img.getWidth();\n" + "\n" + "\t\t"+input.getDataType()+"[] data = img.data;\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint index = img.getStartIndex() + y * img.getStride();\n" + "\t\t\tint indexEnd = index+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; index < indexEnd; index++) {\n" + "\t\t\t\t"+sumType+" value = data[index]"+bitWise+";\n" + "\t\t\t\tif( value < min )\n" + "\t\t\t\t\tdata[index] = "+input.getTypeCastFromSum()+"min;\n" + "\t\t\t\telse if( value > max )\n" + "\t\t\t\t\tdata[index] = "+input.getTypeCastFromSum()+"max;\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printDiffAbs() { String bitWise = input.getBitWise(); String typeCast = input.isInteger() ? "("+input.getDataType()+")" : ""; out.print("\t/**\n" + "\t * <p>\n" + "\t * Computes the absolute value of the difference between each pixel in the two images.<br>\n" + "\t * d(x,y) = |img1(x,y) - img2(x,y)|\n" + "\t * </p>\n" + "\t * @param imgA Input image. Not modified.\n" + "\t * @param imgB Input image. Not modified.\n" + "\t * @param diff Absolute value of difference image. Modified.\n" + "\t */\n" + "\tpublic static void diffAbs( "+input.getSingleBandName()+" imgA , "+input.getSingleBandName()+" imgB , "+input.getSingleBandName()+" diff ) {\n" + "\t\tInputSanityCheck.checkSameShape(imgA,imgB,diff);\n" + "\t\t\n" + "\t\tfinal int h = imgA.getHeight();\n" + "\t\tfinal int w = imgA.getWidth();\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexA = imgA.getStartIndex() + y * imgA.getStride();\n" + "\t\t\tint indexB = imgB.getStartIndex() + y * imgB.getStride();\n" + "\t\t\tint indexDiff = diff.getStartIndex() + y * diff.getStride();\n" + "\t\t\t\n" + "\t\t\tint indexEnd = indexA+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexA < indexEnd; indexA++, indexB++, indexDiff++ ) {\n" + "\t\t\t\tdiff.data[indexDiff] = "+typeCast+"Math.abs((imgA.data[indexA] "+bitWise+") - (imgB.data[indexB] "+bitWise+"));\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printAddTwoImages( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut.isInteger() ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * <p>\n" + "\t * Performs pixel-wise addition<br>\n" + "\t * output(x,y) = imgA(x,y) + imgB(x,y)\n" + "\t * </p>\n" + "\t * @param imgA Input image. Not modified.\n" + "\t * @param imgB Input image. Not modified.\n" + "\t * @param output Output image. Modified.\n" + "\t */\n" + "\tpublic static void add( "+typeIn.getSingleBandName()+" imgA , "+typeIn.getSingleBandName()+" imgB , "+typeOut.getSingleBandName()+" output ) {\n" + "\t\tInputSanityCheck.checkSameShape(imgA,imgB,output);\n" + "\t\t\n" + "\t\tfinal int h = imgA.getHeight();\n" + "\t\tfinal int w = imgA.getWidth();\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexA = imgA.getStartIndex() + y * imgA.getStride();\n" + "\t\t\tint indexB = imgB.getStartIndex() + y * imgB.getStride();\n" + "\t\t\tint indexOut = output.getStartIndex() + y * output.getStride();\n" + "\t\t\t\n" + "\t\t\tint indexEnd = indexA+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) {\n" + "\t\t\t\toutput.data[indexOut] = "+typeCast+"((imgA.data[indexA] "+bitWise+") + (imgB.data[indexB] "+bitWise+"));\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printSubtractTwoImages( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut.isInteger() ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * <p>\n" + "\t * Performs pixel-wise subtraction.<br>\n" + "\t * output(x,y) = imgA(x,y) - imgB(x,y)\n" + "\t * </p>\n" + "\t * @param imgA Input image. Not modified.\n" + "\t * @param imgB Input image. Not modified.\n" + "\t * @param output Output image. Modified.\n" + "\t */\n" + "\tpublic static void subtract( "+typeIn.getSingleBandName()+" imgA , "+typeIn.getSingleBandName()+" imgB , " +typeOut.getSingleBandName()+" output ) {\n" + "\t\tInputSanityCheck.checkSameShape(imgA,imgB,output);\n" + "\t\t\n" + "\t\tfinal int h = imgA.getHeight();\n" + "\t\tfinal int w = imgA.getWidth();\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexA = imgA.getStartIndex() + y * imgA.getStride();\n" + "\t\t\tint indexB = imgB.getStartIndex() + y * imgB.getStride();\n" + "\t\t\tint indexOut = output.getStartIndex() + y * output.getStride();\n" + "\t\t\t\n" + "\t\t\tint indexEnd = indexA+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) {\n" + "\t\t\t\toutput.data[indexOut] = "+typeCast+"((imgA.data[indexA] "+bitWise+") - (imgB.data[indexB] "+bitWise+"));\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printMultTwoImages( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut.isInteger() ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * <p>\n" + "\t * Performs pixel-wise multiplication<br>\n" + "\t * output(x,y) = imgA(x,y) * imgB(x,y)\n" + "\t * </p>\n" + "\t * @param imgA Input image. Not modified.\n" + "\t * @param imgB Input image. Not modified.\n" + "\t * @param output Output image. Modified.\n" + "\t */\n" + "\tpublic static void multiply( "+typeIn.getSingleBandName()+" imgA , "+typeIn.getSingleBandName()+" imgB , "+typeOut.getSingleBandName()+" output ) {\n" + "\t\tInputSanityCheck.checkSameShape(imgA,imgB,output);\n" + "\t\t\n" + "\t\tfinal int h = imgA.getHeight();\n" + "\t\tfinal int w = imgA.getWidth();\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexA = imgA.getStartIndex() + y * imgA.getStride();\n" + "\t\t\tint indexB = imgB.getStartIndex() + y * imgB.getStride();\n" + "\t\t\tint indexOut = output.getStartIndex() + y * output.getStride();\n" + "\t\t\t\n" + "\t\t\tint indexEnd = indexA+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) {\n" + "\t\t\t\toutput.data[indexOut] = "+typeCast+"((imgA.data[indexA] "+bitWise+") * (imgB.data[indexB] "+bitWise+"));\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printLog( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut != AutoTypeImage.F64 ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * Sets each pixel in the output image to log( 1 + input(x,y)) of the input image.\n" + "\t * Both the input and output image can be the same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output Where the log image is written to. Modified.\n" + "\t */\n" + "\tpublic static void log( "+typeIn.getSingleBandName()+" input , "+typeOut.getSingleBandName()+" output ) {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape(input,output);\n" + "\n" + "\t\tfor( int y = 0; y < input.height; y++ ) {\n" + "\t\t\tint indexSrc = input.startIndex + y* input.stride;\n" + "\t\t\tint indexDst = output.startIndex + y* output.stride;\n" + "\t\t\tint end = indexSrc + input.width;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\toutput.data[indexDst] = "+typeCast+"Math.log(1 + input.data[indexSrc]"+bitWise+");\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printPow2( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); out.print("\t/**\n" + "\t * Raises each pixel in the input image to the power of two. Both the input and output image can be the \n" + "\t * same instance." + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output Where the pow2 image is written to. Modified.\n" + "\t */\n" + "\tpublic static void pow2( "+typeIn.getSingleBandName()+" input , "+typeOut.getSingleBandName()+" output ) {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape(input,output);\n" + "\n" + "\t\tfor( int y = 0; y < input.height; y++ ) {\n" + "\t\t\tint indexSrc = input.startIndex + y* input.stride;\n" + "\t\t\tint indexDst = output.startIndex + y* output.stride;\n" + "\t\t\tint end = indexSrc + input.width;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\t"+typeOut.getDataType()+" v = input.data[indexSrc]"+bitWise+";\n" + "\t\t\t\toutput.data[indexDst] = v*v;\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printSqrt( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut != AutoTypeImage.F64 ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * Computes the square root of each pixel in the input image. Both the input and output image can be the\n" + "\t * same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output Where the sqrt() image is written to. Modified.\n" + "\t */\n" + "\tpublic static void sqrt( "+typeIn.getSingleBandName()+" input , "+typeOut.getSingleBandName()+" output ) {\n" + "\n" + "\t\tInputSanityCheck.checkSameShape(input,output);\n" + "\n" + "\t\tfor( int y = 0; y < input.height; y++ ) {\n" + "\t\t\tint indexSrc = input.startIndex + y* input.stride;\n" + "\t\t\tint indexDst = output.startIndex + y* output.stride;\n" + "\t\t\tint end = indexSrc + input.width;\n" + "\n" + "\t\t\tfor( ; indexSrc < end; indexSrc++ , indexDst++) {\n" + "\t\t\t\toutput.data[indexDst] = "+typeCast+"Math.sqrt(input.data[indexSrc]"+bitWise+");\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printDivTwoImages( AutoTypeImage typeIn , AutoTypeImage typeOut ) { String bitWise = typeIn.getBitWise(); String typeCast = typeOut.isInteger() ? "("+typeOut.getDataType()+")" : ""; out.print("\t/**\n" + "\t * <p>\n" + "\t * Performs pixel-wise division<br>\n" + "\t * output(x,y) = imgA(x,y) / imgB(x,y)\n" + "\t * </p>\n" + "\t * @param imgA Input image. Not modified.\n" + "\t * @param imgB Input image. Not modified.\n" + "\t * @param output Output image. Modified.\n" + "\t */\n" + "\tpublic static void divide( "+typeIn.getSingleBandName()+" imgA , "+typeIn.getSingleBandName()+" imgB , "+typeOut.getSingleBandName()+" output ) {\n" + "\t\tInputSanityCheck.checkSameShape(imgA,imgB,output);\n" + "\t\t\n" + "\t\tfinal int h = imgA.getHeight();\n" + "\t\tfinal int w = imgA.getWidth();\n" + "\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexA = imgA.getStartIndex() + y * imgA.getStride();\n" + "\t\t\tint indexB = imgB.getStartIndex() + y * imgB.getStride();\n" + "\t\t\tint indexOut = output.getStartIndex() + y * output.getStride();\n" + "\t\t\t\n" + "\t\t\tint indexEnd = indexA+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) {\n" + "\t\t\t\toutput.data[indexOut] = "+typeCast+"((imgA.data[indexA] "+bitWise+") / (imgB.data[indexB] "+bitWise+"));\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } public void printAverageBand() { String imageName = input.getSingleBandName(); String sumType = input.getSumType(); String typecast = input.getTypeCastFromSum(); String bitwise = input.getBitWise(); out.print("\t/**\n" + "\t * Computes the average for each pixel across all bands in the {@link Planar} image.\n" + "\t * \n" + "\t * @param input Planar image\n" + "\t * @param output Gray scale image containing average pixel values\n" + "\t */\n" + "\tpublic static void averageBand( Planar<"+imageName+"> input , "+imageName+" output ) {\n" + "\t\tfinal int h = input.getHeight();\n" + "\t\tfinal int w = input.getWidth();\n" + "\n" + "\t\t"+imageName+"[] bands = input.bands;\n" + "\t\t\n" + "\t\tfor (int y = 0; y < h; y++) {\n" + "\t\t\tint indexInput = input.getStartIndex() + y * input.getStride();\n" + "\t\t\tint indexOutput = output.getStartIndex() + y * output.getStride();\n" + "\n" + "\t\t\tint indexEnd = indexInput+w;\n" + "\t\t\t// for(int x = 0; x < w; x++ ) {\n" + "\t\t\tfor (; indexInput < indexEnd; indexInput++, indexOutput++ ) {\n" + "\t\t\t\t"+sumType+" total = 0;\n" + "\t\t\t\tfor( int i = 0; i < bands.length; i++ ) {\n" + "\t\t\t\t\ttotal += bands[i].data[ indexInput ]"+bitwise+";\n" + "\t\t\t\t}\n" + "\t\t\t\toutput.data[indexOutput] = "+typecast+"(total / bands.length);\n" + "\t\t\t}\n" + "\t\t}\n" + "\t}\n\n"); } class Multiple implements TwoTemplate { @Override public String getVariableName() { return "value";} @Override public boolean isScaleOp() { return true; } @Override public boolean isImageFirst() { return true; } @Override public AutoTypeImage[] getTypes() { return AutoTypeImage.getSpecificTypes(); } @Override public String getJavaDoc() { return "\t/**\n" + "\t * Multiply each element by a scalar value. Both input and output images can\n" + "\t * be the same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param value What each element is multiplied by.\n" + "\t * @param output The output image. Modified.\n" + "\t */"; } @Override public String getName() {return "multiply";} @Override public String getOperation() { String round = input.isInteger() ? "Math.round" : ""; return round+"((input[indexSrc] "+input.getBitWise()+") * value)"; } } class Divide implements TwoTemplate { @Override public String getVariableName() { return "denominator";} @Override public boolean isScaleOp() { return true; } @Override public boolean isImageFirst() { return true; } @Override public AutoTypeImage[] getTypes() { return AutoTypeImage.getSpecificTypes(); } @Override public String getJavaDoc() { return "\t/**\n" + "\t * Divide each element by a scalar value. Both input and output images can be the same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param denominator What each element is divided by.\n" + "\t * @param output The output image. Modified.\n" + "\t */"; } @Override public String getName() {return "divide";} @Override public String getOperation() { String round = input.isInteger() ? "Math.round" : ""; return round+"((input[indexSrc] "+input.getBitWise()+") / denominator)"; } } class Plus implements TwoTemplate { @Override public String getVariableName() { return "value";} @Override public boolean isScaleOp() { return false; } @Override public boolean isImageFirst() { return true; } @Override public AutoTypeImage[] getTypes() { return AutoTypeImage.getSpecificTypes(); } @Override public String getJavaDoc() { return "\t/**\n" + "\t * Adds a scalar value to each element. Both input and output images can be the same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param value What is added to each element.\n" + "\t * @param output The output image. Modified.\n" + "\t */"; } @Override public String getName() {return "plus";} @Override public String getOperation() { return "((input[indexSrc] "+input.getBitWise()+") + value)"; } } class Minus implements TwoTemplate { boolean imageFirst; public Minus(boolean imageFirst) { this.imageFirst = imageFirst; } @Override public String getVariableName() { return "value";} @Override public boolean isScaleOp() { return false; } @Override public boolean isImageFirst() { return imageFirst; } @Override public AutoTypeImage[] getTypes() { return AutoTypeImage.getSpecificTypes(); } @Override public String getJavaDoc() { if( imageFirst ) return "\t/**\n" + "\t * Subtracts a scalar value from each element. Both input and output images can be the same instance.\n" + "\t *\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param value What is subtracted from each element.\n" + "\t * @param output The output image. Modified.\n" + "\t */"; else return "\t/**\n" + "\t * Subtracts each element's value from a scalar. Both input and output images can be the same instance.\n" + "\t *\n" + "\t * @param value Scalar value\n" + "\t * @param input The input image. Not modified.\n" + "\t * @param output The output image. Modified.\n" + "\t */"; } @Override public String getName() {return "minus";} @Override public String getOperation() { if( imageFirst ) return "((input[indexSrc] "+input.getBitWise()+") - value)"; else return "(value - (input[indexSrc] "+input.getBitWise()+"))"; } } interface Template { String getJavaDoc(); String getName(); String getOperation(); } interface TwoTemplate extends Template { String getVariableName(); boolean isScaleOp(); boolean isImageFirst(); AutoTypeImage[] getTypes(); } public static void main( String args[] ) throws FileNotFoundException { GeneratePixelMath gen = new GeneratePixelMath(); gen.generate(); } }