/* features for character recognition */
#include <stdlib.h>
#include "Global.h"
#include "Define.h"
#include "features.h"

double* Feature_1(double *FH1, unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int x, y, i;
	int x_step;
	int MID= 175;
	unsigned char *ptrFrame, *pre_pix;
    //double *FH1= (int *)malloc(16 * sizeof(double));
    
	for ( i= 0; i< 16; i++) FH1[i] = 0;
	x_step= (CX1- CX0)/16;    //here add 1 so x_step is not 0
	for ( i= 0; i< 16; i++)
	{
		x= CX0 + i*x_step;
		for ( y= CY0; y< CY1; y++)
		{
		ptrFrame = frame + y * widthStep + x * 3;
		pre_pix= ptrFrame-  widthStep;
		if ((ptrFrame[0]< MID)&& (pre_pix[0]> MID)) {FH1[i]++;}
		}
	}
	return FH1;
}
double* Feature_2(double *FH2, unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int x, y, i;
	int y_step;
	int MID= 175;
	unsigned char *ptrFrame, *pre_pix;
    
	for ( i= 0; i< 16; i++) FH2[i] = 0;
	y_step= (CY1- CY0)/16;
	for ( i= 0; i< 16; i++)
	{
		y= CY0 + i*y_step;
		for ( x= CX0; x< CX1; x++)
		{
		ptrFrame = frame + y * widthStep + x * 3;
		pre_pix= ptrFrame-  1;
		if ((ptrFrame[0]< MID)&& (pre_pix[0]> MID)) FH2[i]++;
		}
	}
	return FH2;
}

double* Feature_3(double *FH3, unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int x, y, i, ct1[16], ct2[16];
	int x_step;
	int MID= 175;
	unsigned char *ptrFrame;
    
	for ( i= 0; i< 16; i++) 
	{
		ct1[i] = 0;
		ct2[i] = 0;
		FH3[i] = 0;
	}
	x_step= (CX1- CX0)/16 ; 
	for ( i= 0; i< 16; i++)
	{
		x= CX0 + i*x_step;
		for ( y= CY0; y< CY1; y++)
		{
		ptrFrame = frame + y * widthStep + x * 3;
		if (ptrFrame[0]< MID)    ct1[i]++;
		if (ptrFrame[0]> MID)  ct2[i]++;
		}
		FH3[i]= 10*ct1[i]/(ct1[i]+ ct2[i]+0.00001);
	}
	return FH3;
}
double* Feature_4(double *FH4, unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int x, y, i, ct1[16], ct2[16];
	int y_step;
	int MID= 175;
	unsigned char *ptrFrame, *pre_pix;
    
	for ( i= 0; i< 16; i++)
	{
		ct1[i] = 0;
		ct2[i] = 0;
		FH4[i] = 0;
	}
	y_step= (CY1- CY0)/16;

	for ( i= 0; i< 16; i++)
	{
		y= CY0 + i*y_step;
		for ( x= CX0; x< CX1; x++)
		{
		    ptrFrame = frame + y * widthStep + x * 3;
			if (ptrFrame[0]<MID )  
			{
				ct1[i]++;
			}
			if (ptrFrame[0]>MID)     
			{
				ct2[i]++;
			}
		}
		FH4[i]= 10* ct1[i]/(ct1[i]+ ct2[i]+ 0.00001);
	}
	return FH4;
}
double* Feature_raw(double *FH_raw, unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int x, y, i, j;
	int x_step, y_step;
	unsigned char *ptrFrame, *ptrFrame2, *ptrFrame3, *ptrFrame4;
    
	for ( i= 0; i< 32; i++) FH_raw[i] = 0;
	x_step= y_step= 2;

	for ( i= 0; i< 4; i++)
    for ( j= 0; j< 8; j++)
	{
		x= CX0 + i*x_step;   //  +2i
	    y= CY0 + j*y_step;   //  +2j
		
		ptrFrame = frame + y * widthStep + x * 3;
		ptrFrame2 = frame + y * widthStep + (x+1) * 3;
		ptrFrame3 = frame + (y+1) * widthStep + x * 3;
		ptrFrame4 = frame + (y+1) * widthStep + (x+1) * 3;
       
	    //FH_raw[i+j*4]= (ptrFrame[0]+ ptrFrame2[0]+ ptrFrame3[0]+ ptrFrame4[0])/4;
		FH_raw[i+j*4]= (ptrFrame[0]+ ptrFrame2[0]+ ptrFrame3[0]+ ptrFrame4[0]+ptrFrame[1]+ ptrFrame2[1]+ ptrFrame3[1]+ ptrFrame4[1]+ptrFrame[2]+ ptrFrame2[2]+ ptrFrame3[2]+ ptrFrame4[2])/12;
		//Weight of this feature  
		FH_raw[i+j*4]/= 200;   //94%
	}
		return FH_raw;
}


void Combine_Features( double* Feature,  unsigned char * frame, int widthStep, int CX0, int CY0, int CX1, int CY1)
{
	int n, i;
    n= 0;

	double *FH1, *FH2, *FH3, *FH4, *FH_raw;
				
	FH1 = (double *)malloc( 16 * sizeof(double));
	FH2 = (double *)malloc( 16 * sizeof(double));
	FH3 = (double *)malloc( 16 * sizeof(double));
	FH4 = (double *)malloc( 16 * sizeof(double));
	FH_raw = (double *)malloc( 32 * sizeof(double));

	FH1= Feature_1(FH1, frame, widthStep, CX0, CY0, CX1, CY1);
	FH2= Feature_2(FH2, frame, widthStep, CX0, CY0, CX1, CY1);
	FH3= Feature_3(FH3, frame, widthStep, CX0, CY0, CX1, CY1);
	FH4= Feature_4(FH4, frame, widthStep, CX0, CY0, CX1, CY1);
	FH_raw= Feature_raw(FH_raw, frame, widthStep, CX0, CY0, CX1, CY1);

	for (i= 0; i< 16; i++)
	{
    Feature[n*16+ i]= FH1[i];
	}
	n++;
	for (i= 0; i< 16; i++)
	{
    Feature[n*16+ i]= FH2[i];
	}
	n++;
	for (i= 0; i< 16; i++)
	{
    Feature[n*16+ i]= FH3[i];
	}
	n++;
	for (i= 0; i< 16; i++)
	{
    Feature[n*16+ i]= FH4[i];
	}
	n++;
	for (i= 0; i< 32; i++)
	{
    Feature[n*16+ i]= FH_raw[i];
	}
    return;
}


/*

//---------------------------------------------------------------------------------------------------------//
void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
{
   float min, max, delta, rc, gc, bc;

   rc = (float)r / 255.0;
   gc = (float)g / 255.0;
   bc = (float)b / 255.0;

   max = rc; 
   if(gc > max) max = gc;
   if(bc > max) max = bc;

   min = rc;
   if(gc < min) min = gc;
   if(bc < min) min = bc;

   delta = max - min;
   *v = max;

   if (max != 0.0)
      *s = delta / max;
   else
      *s = 0.0;

   if (*s == 0.0) {
      *h = 0.0; 
   }
   else {
      if (rc == max)
	 *h = (gc - bc) / delta;
      else if (gc == max)
	 *h = 2 + (bc - rc) / delta;
      else if (bc == max)
	 *h = 4 + (rc - gc) / delta;

      *h *= 60.0;
      if (*h < 0)
	 *h += 360.0;
    }
}



void extractImageFeatures_Type1(unsigned char * image, int R0, int C0, int R1, int C1, int widthStep, 
						  double * feature, int featureSize)
{
	int r, c, i, idx;
	int cR, cG, cB;
	float h, s, v;
	unsigned char *ptr;
	int ct;

	for(i=0; i<featureSize; i++)	feature[i] = 0;

	ct = 0;
	for(r=R0; r<R1; r++)
	for(c=C0; c<C1; c++)
	{
		ptr = image + r * widthStep + c*3;
		cB = ptr[0];
		cG = ptr[1];
		cR = ptr[2];

		if((cR == 0) && (cB==0) && (cG==0))
		{
			ct = ct;
		}
		else
		{

			rgb_to_hsv(cR, cG, cB, &h, &s, &v);

			idx = cR / 16;
			feature[idx] = feature[idx] + 1;

			idx = cG / 16 + 16;
			feature[idx] = feature[idx] + 1;

			idx = cB / 16 + 32;
			feature[idx] = feature[idx] + 1;

			h = h / 360;

			idx = (int)(h * 16); 
			if(idx > 15) idx = 15;
			idx = idx + 48;
			feature[idx] = feature[idx] + 1;

			idx = (int)(s * 16); 
			if(idx > 15) idx = 15;
			idx = idx + 64;
			feature[idx] = feature[idx] + 1;

			idx = (int)(v * 16); 
			if(idx > 15) idx = 15;
			idx = idx + 80;
			feature[idx] = feature[idx] + 1;

			//additional features
			idx = ((cR - cG) + 255) / 32;
			if(idx > 15) idx = 15;
			idx = idx + 96;
			feature[idx] = feature[idx] + 1;

			idx = ((cR - cB) + 255) / 32;
			if(idx > 15) idx = 15;
			idx = idx + 112;
			feature[idx] = feature[idx] + 1;

			idx = ((cG - cB) + 255) / 32;
			if(idx > 15) idx = 15;
			idx = idx + 128;
			feature[idx] = feature[idx] + 1;


			ct++;
		}

	}

	//normalize
	for(i=0; i<featureSize; i++)
		feature[i] = 100 * feature[i] / ct;

	return;
}

*/
//-----------------------------------------------------------------------------------------------------------//