//
// This class implements Gaussian smoothing. It uses the separability
// of the function to speed up the computation.
//



public class GaussianSmooth extends Object
{
	public GaussianSmooth() {};
	public int[] smoothen(int inPixels[], double sigma, int width, int height)
	{
		int outPixels[] = new int[inPixels.length];		
		int temp[] = new int[inPixels.length];
		int windowSize = (int)(sigma * 3.0);
		int offset = (windowSize-1) / 2;
		double weight[] = new double[windowSize];
		double s = -1.5 * sigma;		
		
		
		// Calculate weights and put them in weight[] array
		
		for (int i = 0; i < windowSize; i++, s += 3.0 * sigma / ((double) windowSize - 1.0))	
			weight[i] = 1.0 / (Math.sqrt(2.0 * Math.PI) * sigma) * Math.exp(-1.0 * s * s / (2.0 * sigma * sigma));
		
		
		// Smooth along the x axis, result in temp[] array
		
		for (int x = offset; x < width - offset; x++)
			for (int y = offset; y < height - offset; y++)
			{
				outPixels[y*width+x] = 0;
				for (int i = x - offset, k = 0; i <= x + offset; i++, k++)
					temp[y*width+x] += (int)( weight[k] * inPixels[y*width+i] );
			}
		
		
		// Smooth along the y axis
		
		for (int x = offset; x < width - offset; x++)
			for (int y = offset; y < height - offset; y++)
				for (int j = y - offset, k = 0; j <= y + offset; j++, k++)
					outPixels[y*width+x] += (int)( weight[k] * temp[j*width+x] );
		
		return outPixels;
	}
}
