import java.awt.*;
import java.awt.image.*;
import java.io.*;

// Poisson Noise Generator
public class poiss_noise extends noiseFilter
{
	double variance;
	double[] prob = new double[SIZE];
	double[] Prob = new double[SIZE];
	
	// Create object and initialize data
	public poiss_noise(float var)
	{
		variance = var*7.45;
	}
		
	// Runs the algorithm
	public void performEffect()
	{		
		int finalnoiseR = 0;
		int finalnoiseG = 0;
		int finalnoiseB = 0;
		int pointOffset = 0;
		int[] newPixels = new int[width*height];
		
		// Initializes and sets probability array (Poisson)
		prob[0] = Math.exp(-variance);
		Prob[0] = 0;
		
		for (int i=1; i<SIZE; i++)
		{
			prob[i] = prob[i-1] * variance / i;
			Prob[i] = Prob[i-1] + ((prob[i-1] + prob[i])/2);
		}
		
		// Moves through the input array pixel by pixel
		for(int i=0;i<height;i++)
		{
			for(int j=0;j<width;j++)
			{
				// Location of current pixel
				pointOffset = i*width+j;

				// Finds the poisson value
				calc_array(Prob);
	
				// Creates poisson noise
				finalnoiseR = (int)(((pixels[pointOffset] >> 16)&0xff) + Mid
				- variance);
				finalnoiseG = (int)(((pixels[pointOffset] >> 8)&0xff) + Mid
				- variance);
				finalnoiseB = (int)(((pixels[pointOffset])&0xff) + Mid
				- variance);

				if (finalnoiseR > 255) finalnoiseR = 255;
				if (finalnoiseG > 255) finalnoiseG = 255;
				if (finalnoiseB > 255) finalnoiseB = 255;
				if (finalnoiseR < 0) finalnoiseR = 0;
				if (finalnoiseG < 0) finalnoiseG = 0;
				if (finalnoiseB < 0) finalnoiseB = 0;
					
				newPixels[pointOffset] = (255<<24)|(finalnoiseR<<16)|(finalnoiseG<<8)|(finalnoiseB);
			}
		}
		this.pixels = newPixels;
	}
}
