//***************************************************************************
#ifndef IMAGE_H
#define IMAGE_H
//***************************************************************************
class GrayImage
{
   private:
	char magicNumber[2];
	int  allocateFlag;
	int  numBits;
	int  mincount;
	int  maxcount;
	int  MaxHist[10];
	int  MinHist[10];
	void allocateMem( );
	void deAllocateMem( );

    public:
	GrayImage( );		// Constructor
	GrayImage( int w, int h, int numLev );		// Constructor
	~GrayImage( );		// Destructor
	void Init( );
	void Init (int w, int h, int numLev );
	int  height;		// Height of image
	int  width;		// Width of image
	int  numLevels;
	int  numpixels;		// Total number of pixels (height x width)
	int  numMaxHist;
	int  numMinHist;
	int  numComponents;	// Number of connected components
	unsigned char **p;	// Gray level value
	double **Phi;		// Invariant moments
	int *hist;		// Histogram data
	void allocatePhi (int num);

	int ReadFromFile (char *FileName);
	int WriteToFile (char *FileName);
	int Threshold (unsigned char T);
	int Threshold (unsigned char T1, unsigned char T2);
	int ThresholdBinary (unsigned char T);
	int ThresholdBinary (unsigned char T1, unsigned char T2);
	int reverseThreshold (unsigned char T);
	int reverseThreshold (unsigned char T1, unsigned char T2);
	int Histogram ( );
	int smoothenHistogram ( );
	int printHistogram (char *FileName);
	int calcHistogramPeaks ( );
	int printHistogramPeaks (char *FileName);
	int getHistMinima ( );
	int getHistMinima ( int i );
	int getHistMaxima ( );
	int getHistMaxima ( int i );
	void setValue (unsigned char T);
	GrayImage &operator= (const GrayImage &);
	GrayImage &operator+ (GrayImage &I1);
	GrayImage &operator- (GrayImage &I1);
	int Perimeter (int F);
	double Elongation (int P);
	int LabelComponents ( );
	int FindNeighbors (int i, int j);
	int Area (int P);
	void ConvertToBinary ( );
	void ReverseBinary ( );
	int WriteLabelsToFile (char *FileName);
	double Moment (int x, int y, int P);
	double CentralizedMoment (int x, int y, int P);
	double NormalizedCentralMoment (int x, int y, int P);
	void InvariantMoments (int P);
	double getInvariantMoment (int P, int i);
	void MinBoundRectangle (int P);
	
	// Image Filters
	void DilationNxN_Binary (int N, int num);
	void ErosionNxN_Binary (int N, int num);
	void OpeningNxN_Binary (int N, int num);
	void ClosingNxN_Binary (int N, int num);
	void OpeningNxN_Binary (int N);
	void ClosingNxN_Binary (int N);
	void DilationNxN_Binary (int N);
	void ErosionNxN_Binary (int N);
	void ErosionNxN (int N);
	void DilationNxN (int N);
	void OpeningNxN (int N);
	void ClosingNxN (int N);
	void Skeletonization ( );
	void MeanFilterNxN (int N);
	void MedianFilterNxN (int N);
	void GaussianFilterNxN (int N);
	void kNearestNeighboringFilterNxN (int N, int k);
	void kNearestNeighboringFilterNxN (int N);

	// Image Filters
	void addSaltandPepperNoise (double percent);
	void addGaussianNoise (double mean, double variance);

};
//***************************************************************************
double RMSerror(GrayImage *I1, GrayImage *I2);
//***************************************************************************
#endif // IMAGE_H
//***************************************************************************