#include <windows.h>
#include "common.h"

Image_data * Equalize(Image_data *piData)
{
	int				i, numPixels;
	int				histogram[256];
	float			equalized[256];
	unsigned char	values[256];
	
	Image_data *pproData;


// ----------- Memory allocation stuff --------------//

	pproData = malloc(sizeof(Image_data));
	pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols);
	pproData->n_cols = piData->n_cols;
	pproData->n_rows = piData->n_rows;
	lstrcpy(pproData->filename, "Equalized Image");

// -------------------------------------------------//


	numPixels = piData->n_rows * piData->n_cols;

	for(i = 0; i < 256; i++)			// Initialize histogram array
		histogram[i] = 0;

	for (i = 0; i < numPixels; i++)		// Compute histogram
		++histogram[piData->image_G_ptr[i]];


	for (i = 0; i < 256; i++)
		equalized[i] = (float)histogram[i]/(float)numPixels;
	for (i = 1; i < 256; i++)			// Summation
		equalized[i] += equalized[i-1];
	for (i = 1; i < 256; i++)			// Normalize to 255
		values[i] = (unsigned char)(equalized[i]*255.0);	
	
	for (i = 0; i < numPixels; i++)		// final image
		pproData->image_G_ptr[i] = values[piData->image_G_ptr[i]];


	return pproData;

}


Image_data * EqualizeLocal(Image_data *piData, int startx, int starty, int endx, int endy, int inplace)
{
	int				i, x, y, width, numPixels;
	int				histogram[256];
	float			equalized[256];
	unsigned char	values[256];
	
	Image_data *pproData;


	if (inplace == 1)	// do not create new image
		pproData = piData;
	else				// create new image
	{
		// ----------- Memory allocation stuff --------------//

		pproData = malloc(sizeof(Image_data));
		pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols);
		memcpy(pproData->image_G_ptr, piData->image_G_ptr, piData->n_rows * piData->n_cols);
		pproData->n_cols = piData->n_cols;
		pproData->n_rows = piData->n_rows;
		lstrcpy(pproData->filename, "Equalized Image");

		// -------------------------------------------------//
	}

	
	if (startx > endx)	// If endx < startx, swap them, otherwise for loop will fail
	{
		i = startx;
		startx = endx;
		endx = i;
	}


	if (starty > endy)	// If endy < starty, swap them, otherwise for loop will fail
	{
		i = starty;
		starty = endy;
		endy = i;
	}


	numPixels = (endx - startx) * (endy - starty);
	width = piData->n_cols;

	for(i = 0; i < 256; i++)			// Initialize histogram array
		histogram[i] = 0;

	for (x = startx; x < endx; x++)		// Compute histogram of subimage
		for (y = starty; y < endy; y++)
			++histogram[piData->image_G_ptr[y * width + x]];


	for (i = 0; i < 256; i++)
		equalized[i] = (float)histogram[i]/(float)numPixels;
	for (i = 1; i < 256; i++)
		equalized[i] += equalized[i-1];
	for (i = 1; i < 256; i++)			// Normalize to 255
		values[i] = (unsigned char)(equalized[i]*255.0);	


	for (x = startx; x < endx; x++)
		for (y = starty; y < endy; y++)
			pproData->image_G_ptr[y*width + x] = values[piData->image_G_ptr[y*width + x]];


	return pproData;

}


Image_data * Equalize4Areas(Image_data *piData)
{
	int width, height;

	Image_data *pproData;


// ----------- Memory allocation stuff --------------//

	pproData = malloc(sizeof(Image_data));
	pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols);
	memcpy(pproData->image_G_ptr, piData->image_G_ptr, piData->n_rows * piData->n_cols);
	pproData->n_cols = piData->n_cols;
	pproData->n_rows = piData->n_rows;
	lstrcpy(pproData->filename, "Equalized 4 Image");

// -------------------------------------------------//


	width = piData->n_cols;
	height = piData->n_rows;

	EqualizeLocal(pproData, 0, 0, width/2, height/2, 1);
	EqualizeLocal(pproData, width/2, 0, width, height/2, 1);
	EqualizeLocal(pproData, 0,height/2, width/2, height, 1);
	EqualizeLocal(pproData, width/2, height/2, width, height, 1);

	return pproData;
}

Image_data * Equalize16Areas(Image_data *piData)
{
	int width, height;

	Image_data *pproData;


// ----------- Memory allocation stuff --------------//

	pproData = malloc(sizeof(Image_data));
	pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols);
	memcpy(pproData->image_G_ptr, piData->image_G_ptr, piData->n_rows * piData->n_cols);
	pproData->n_cols = piData->n_cols;
	pproData->n_rows = piData->n_rows;
	lstrcpy(pproData->filename, "Equalized 16 Image");

// -------------------------------------------------//


	width = piData->n_cols;
	height = piData->n_rows;

	EqualizeLocal(pproData, 0        , 0, width/4  , height/4, 1);
	EqualizeLocal(pproData, width/4  , 0, width/2  , height/4, 1);
	EqualizeLocal(pproData, width/2  , 0, 3*width/4, height/4, 1);
	EqualizeLocal(pproData, 3*width/4, 0, width    , height/4, 1);

	EqualizeLocal(pproData, 0        , height/4, width/4  , height/2, 1);
	EqualizeLocal(pproData, width/4  , height/4, width/2  , height/2, 1);
	EqualizeLocal(pproData, width/2  , height/4, 3*width/4, height/2, 1);
	EqualizeLocal(pproData, 3*width/4, height/4, width    , height/2, 1);

	EqualizeLocal(pproData, 0        , height/2, width/4  , 3*height/4, 1);
	EqualizeLocal(pproData, width/4  , height/2, width/2  , 3*height/4, 1);
	EqualizeLocal(pproData, width/2  , height/2, 3*width/4, 3*height/4, 1);
	EqualizeLocal(pproData, 3*width/4, height/2, width    , 3*height/4, 1);
	
	EqualizeLocal(pproData, 0        , 3*height/4, width/4  , height, 1);
	EqualizeLocal(pproData, width/4  , 3*height/4, width/2  , height, 1);
	EqualizeLocal(pproData, width/2  , 3*height/4, 3*width/4, height, 1);
	EqualizeLocal(pproData, 3*width/4, 3*height/4, width    , height, 1);
	
	return pproData;

}