#include "Harris.h"



Piquesel** MultiplyArray(Piquesel** tbl1, Piquesel** tbl2, int* taille){

int max=0;
if (taille[1]>taille[0]) 
	{max=taille[1];}
else max=taille[0];

int i,j;
	Piquesel** Result = malloc(sizeof(Piquesel*) * taille[1]);
	for (i=0 ; i<taille[1] ; i++){
		Result[i] = malloc(sizeof(Piquesel) * taille[0]);
	}	
//Initialisation de la matrice résultante---------------------------------------
	for (i=0;i<taille[1];i++)
	{
		for (j=0;j<taille[0];j++)
			{
				Result[i][j].Red=0;
				Result[i][j].Green=0;
				Result[i][j].Blue=0;
			}
	}
//Calcul de la matrice résultante-----------------------------------------------
	for (i=0;i<taille[0];i++)
	{
		for (j=0;j<taille[1];j++)
		{
                    
			for (int k=0;k<max;k++)
			{
				(Result[i][j]).Red=(tbl1[i][k]).Red*(tbl2[k][j]).Red+(Result[i][j]).Red;
				if ((Result[i][j]).Red>255) 
					{(Result[i][j]).Red=255;}
					
				(Result[i][j]).Green=(tbl1[i][k]).Green*(tbl2[k][j]).Green+(Result[i][j]).Green;
				if ((Result[i][j]).Green>255)
					{(Result[i][j]).Green=255;}
					
				(Result[i][j]).Blue=(tbl1[i][k]).Blue*(tbl2[k][j]).Blue+(Result[i][j]).Blue;
				if ((Result[i][j]).Blue>255)
					{(Result[i][j]).Blue=255;}					
			}
		}
	}
	
	return(Result);
}

int** Harris(Piquesel** Orig, int* taille, int sensibility){
    
    
//Déclaration de variables à utiliser
int** SobelX = malloc(sizeof(int*)*3);

for (int i=0 ; i<3 ; i++)
    SobelX[i] = malloc(sizeof(int*)*3);

	SobelX[0][0]=1;
	SobelX[1][0]=0;
	SobelX[2][0]=-1;
	SobelX[0][1]=2;
	SobelX[1][1]=0;
	SobelX[2][1]=-2;
	SobelX[0][2]=1;
	SobelX[1][2]=0;
	SobelX[2][2]=-1;
		
int** SobelY = malloc(sizeof(int*)*3);

for (int i=0 ; i<3 ; i++)
        SobelY[i] = malloc(sizeof(int*)*3);

	SobelY[0][0]=1;
	SobelY[1][0]=2;
	SobelY[2][0]=1;
	SobelY[0][1]=0;
	SobelY[1][1]=0;
	SobelY[2][1]=0;
	SobelY[0][2]=-1;
	SobelY[1][2]=-2;
	SobelY[2][2]=-1;

int** Gauss= malloc(sizeof(int*)*3);

for (int i=0 ; i<3 ; i++)
        Gauss[i] = malloc(sizeof(int*)*3);

	Gauss[0][0]=1;
	Gauss[1][0]=1;
	Gauss[2][0]=1;
	Gauss[0][1]=1;
	Gauss[1][1]=4;
	Gauss[2][1]=1;
	Gauss[0][2]=1;
	Gauss[1][2]=2;
	Gauss[2][2]=1;	


//Mise en place matrice résultat
Piquesel** Harris = malloc(sizeof(Piquesel*) * taille[1]);
for (int i=0 ; i<taille[1] ; i++)
{
	Harris[i] = malloc(sizeof(Piquesel) * taille[0]);
}	


//Nous commençons par prendre les dérivées de l'image en ligne et en colonne via les masques de Sobel

Piquesel** ImX = malloc(sizeof(Piquesel*) * taille[1]);
for (int i=0 ; i<taille[1] ; i++)
{
	ImX[i] = malloc(sizeof(Piquesel) * taille[0]);
}	
ImX = ConvoBis(Orig, SobelX, taille[0],taille[1]);

Piquesel** ImX2 = MultiplyArray(ImX, ImX, taille);

Piquesel** ImY = malloc(sizeof(Piquesel*) * taille[1]);
for (int i=0 ; i<taille[1] ; i++)
{
	ImY[i] = malloc(sizeof(Piquesel) * taille[0]);
}	
ImY = ConvoBis(Orig, SobelY, taille[0],taille[1]);

Piquesel** ImY2 = MultiplyArray(ImY, ImY, taille);
	
Piquesel** ImXY = MultiplyArray(ImX, ImY, taille);

//On applique un filtre passe-bas à chacune.

ImX2 = ConvoBis(ImX2, Gauss,taille[0],taille[1]);
ImY2 = ConvoBis(ImY2, Gauss,taille[0],taille[1]);
ImXY = ConvoBis(ImXY, Gauss,taille[0],taille[1]);

//Nous pouvons maintenant calculer la force de coin pour chaque pixel.

int** Result = malloc(sizeof(int*) * taille[1]);
for (int i=0 ; i<taille[1] ; i++)
{
	Result[i] = malloc(sizeof(int) * taille[0]);
}	

int i,j;
for (i=0;i<taille[0];i++)
	{
		for (j=0;j<taille[1];j++)
		{
			Piquesel A=ImX2[i][j];
			Piquesel B=ImY2[i][j];
			Piquesel C=ImXY[i][j];
			
			//Q(x,y)=(AB-C)²-α(A+B)² 
			Harris[i][j].Red = (A.Red*B.Red-C.Red)*(A.Red*B.Red-C.Red) - sensibility*(A.Red+B.Red)*(A.Red+B.Red);
			Harris[i][j].Green = (A.Green*B.Green-C.Green)*(A.Green*B.Green-C.Green) - sensibility*(A.Green+B.Green)*(A.Green+B.Green);
			Harris[i][j].Blue = (A.Blue*B.Blue-C.Blue)*(A.Blue*B.Blue-C.Blue) - sensibility*(A.Blue+B.Blue)*(A.Blue+B.Blue);
                        Result[i][j]=(Harris[i][j].Red*Harris[i][j].Green*Harris[i][j].Blue)/3;
		}
	}
return(Result); //La matrice renvoyée donne, pour chaque pixel, la force de coin. 
}

void HarrisFlag(Piquesel** Img, int** coin, int seuil, int* taille,char* sortie){
 
Piquesel** Result = malloc(sizeof(Piquesel*) * taille[1]);
for (int i=0 ; i<taille[1] ; i++)
{
	Result[i] = malloc(sizeof(Piquesel) * taille[0]);
}	
  
int i,j;
for (i=0;i<taille[0];i++)
	{
		for (j=0;j<taille[1];j++)
		{
                    printf("%d\n",coin[i][j]);
                    if (coin[i][j]>seuil) //Si on a un coin, on dessine une croix rouge sur l'image. :>
                    {
                        Img[i][j].Red=255;
                        Img[i][j].Green=0;
                        Img[i][j].Blue=0;
                        Img[i+1][j].Red=255;
                        Img[i+1][j].Green=0;
                        Img[i+1][j].Blue=0;
                        Img[i][j+1].Red=255;
                        Img[i][j+1].Green=0;
                        Img[i][j+1].Blue=0;
                        Img[i-1][j].Red=255;
                        Img[i-1][j].Green=0;
                        Img[i-1][j].Blue=0;
                        Img[i][j-1].Red=255;
                        Img[i][j-1].Green=0;
                        Img[i][j-1].Blue=0;
                    }
                  
		}
	}

//On a notre tableau avec les points marqués, on le sort en utilisant une fonction de memoire1.h

TablToppm(Result,sortie,taille[0],taille[1]);
    
}