//**************************************************************************
//
//      CSE 585 Project #1
//      By Anirudh Modi (anirudh@bart.aero.psu.edu) on 3/10/2000-Fri
//	 & Shin Chin (scc136@psu.edu)
//	 & Ming Ni (ni@cse.psu.edu)
//
//**************************************************************************
//	Running time of algorithm -> O[width x height]
//**************************************************************************
// 	Have implemented the following ->
//		1. Smoothening of histogram to determine minima/maxima
//		2. Basic image operations (+, -, =)
//		3. There is no memory leak
//**************************************************************************
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>	// for atoi()
#include <string.h>
#include <math.h>
#include "image.h"
//**************************************************************************
//#define GAUSSIAN_NOISE
//**************************************************************************
void myFilter(int type, int N, GrayImage *img, char *name);
//**************************************************************************
int main (int argc, char *argv[])
{
GrayImage origImage, noisyImage, filteredImage;
char name[50], filtername[20];
double err, err2, err_noise_orig;
char imagefile[][20]={"lenna", "peppers", "cleanwheel"};
int numfiles = sizeof(imagefile)/sizeof(char[20]);

ofstream out("RMS.out");
int noise_percent = 20;
int mean = 0;
int std_dev = 1;

for (int i = 0; i < numfiles; i++)
#ifdef GAUSSIAN_NOISE
for (int dev = 1; dev <= 21; dev += 4)
#else
for (int percent = 5; percent <= 25; percent += 5)
#endif
	{
	 sprintf(name,"images/%s.pgm",imagefile[i]);
	 origImage.ReadFromFile(name);
	 noisyImage = origImage;
#ifdef GAUSSIAN_NOISE
	 noisyImage.addGaussianNoise(mean*1.0,dev*dev*1.0);
	 sprintf(name,"%s_gnoise%02d.dat",imagefile[i],dev);
#else
	 noisyImage.addSaltandPepperNoise(percent*1.0);
	 sprintf(name,"%s_spnoise%02d.dat",imagefile[i],percent);
#endif
	 err_noise_orig = RMSerror(&noisyImage, &origImage);
	 noisyImage.WriteToFile(name);
	 for (int type = 1; type <= 4; type++)
	    for (int N = 3; N <= 7; N += 2)
		{
		 filteredImage = noisyImage;
		 myFilter(type, N, &filteredImage, filtername);
		 err = RMSerror(&origImage, &filteredImage);
		 err2 = RMSerror(&noisyImage, &filteredImage);
		 cout << "RMS error for " << N << "x" << N << " " 
			<< filtername << " filter = " << err << endl;
		 cout << "RMS error between noisy image and filtered image = "
			<< err2 << " (between orig and noise = " 
			<< err_noise_orig << ")" << endl;
#ifdef GAUSSIAN_NOISE
		 sprintf(name,"%s_gnoise%02d_%s_%dx%d.dat",imagefile[i],
			dev, filtername, N, N);
#else
		 sprintf(name,"%s_spnoise%02d_%s_%dx%d.dat",imagefile[i],
			percent, filtername, N, N);
#endif
		 out << name << " " << err << " " << err2 
			<< " " << err_noise_orig << endl;
		 out.flush();
		 filteredImage.WriteToFile(name);
		}
	}
out.close();
}
//**************************************************************************
void myFilter(int type, int N, GrayImage *img, char *name)
{
switch (type)
	{
	 case 1:
		strcpy(name,"mean");
		img->MeanFilterNxN(N);
		break;
	 case 2:
		strcpy(name,"median");
		img->MedianFilterNxN(N);
		break;
	 case 3:
		strcpy(name,"gaussian");
		img->GaussianFilterNxN(N);
		break;
	 case 4:
		strcpy(name,"kNearest");
		img->kNearestNeighboringFilterNxN(N);
		break;
	 default:
		break;
	}
}
//**************************************************************************