/**
 * BoxFilter.java
 *
 * Box filtering engine for 3x3 kernel.
 *
 * www.tech-algorithm.com
 *
 */
public class BoxFilter {
    
    /** a box filtering with kernel */
    public static int[] BoxFiltering(
            int[] pixels,int width, int height, float[] kernel) {
        int[] temp = new int[width*height] ;
        float denominator = 0.0f ;
        float red, green, blue ;
        int ired, igreen, iblue, indexOffset, rgb ;        
        int[] indices = {             
            -(width + 1),   -width,     -(width - 1), 
            -1,             0,          +1, 
            width - 1,      width,      width + 1 
        } ;                
        for (int i=0;i<kernel.length;i++)
            denominator += kernel[i] ;      
        if (denominator==0.0f) denominator = 1.0f ;
        for (int i=1;i<height-1;i++) {
            for (int j=1;j<width-1;j++) {
                red = green = blue = 0.0f ;
                indexOffset = (i*width)+j ;
                for (int k=0;k<kernel.length;k++) {        
                    rgb = pixels[indexOffset+indices[k]] ;
                    red += ((rgb & 0xff0000)>>16)*kernel[k] ;
                    green += ((rgb & 0xff00)>>8)*kernel[k] ;
                    blue += (rgb & 0xff)*kernel[k] ;
                }                                
                // calculate average for r, g, b
                ired = (int)(red / denominator) ;
                igreen = (int)(green / denominator) ;
                iblue = (int)(blue / denominator) ;
                if (ired>0xff) ired = 0xff ;
                    else if (ired<0) ired = 0 ;                
                if (igreen>0xff) igreen = 0xff ;
                    else if (igreen<0) igreen = 0 ;                
                if (iblue>0xff) iblue = 0xff ;                                
                    else if (iblue<0) iblue = 0 ;
                // combine r,g,b and save
                temp[(i*width)+j] = 0xff000000 | ((ired<<16) & 0xff0000) | 
                        ((igreen<<8) & 0xff00) | (iblue & 0xff) ;
            }
        }
        return temp ;
    }    
}
