//==============================================================================
//
// pgmconv55.c
//
// use:
// pgmconv55 convmatr.txt  file.pgm  result.pgm
//
//==============================================================================

#include <stdio.h>
#include "pgm.h"


//=======================================================================================
int FrameConvolution5x5(byte* pInp, byte* pOut, int nW, int nH, int conv[25], int denom)
{
 int i, j;
 int i1m, i1p, i2m, i2p;
 int j1m, j1p, j2m, j2p;
 int res;
 int denom2 = (denom+1)/2;
 
 for(i=2; i<(nH-2); i++) // rows
 {
   i1m = i - 1;
   i1p = i + 1;
   i2m = i - 2;
   i2p = i + 2;
   if(i1m == (-1)) i1m = 0;
   if(i1p == nH) i1p = (nH-1);
   if(i2m <= (-1)) i2m = 0;
   if(i2p >= nH) i2p = (nH-1);
   for(j=2; j<(nW-2); j++)
   {
     j1m = j - 1;
     j1p = j + 1;
     j2m = j - 2;
     j2p = j + 2;
     if(j1m == (-1)) j1m = 0;
     if(j1p == nW) j1p = (nW-1);
     if(j2m <= (-1)) j2m = 0;
     if(j2p >= nW) j2p = (nW-1);
     
     res  = conv[0] *pInp[j2m + nW*i2m]+conv[1]*pInp[j1m+nW*i2m]+conv[2]*pInp[j+nW*i2m]+conv[3]*pInp[j1p+nW*i2m]+conv[4]*pInp[j2p+nW*i2m];
     res += conv[5] *pInp[j2m + nW*i1m]+conv[6]*pInp[j1m+nW*i1m]+conv[7]*pInp[j+nW*i1m]+conv[8]*pInp[j1p+nW*i1m]+conv[9]*pInp[j2p+nW*i1m];
     res += conv[10]*pInp[j2m + nW*i] +conv[11]*pInp[j1m+nW*i] +conv[12]*pInp[j+nW*i] +conv[13]*pInp[j1p+nW*i] +conv[14]*pInp[j2p+nW*i];
     res += conv[15]*pInp[j2m + nW*i1p]+conv[16]*pInp[j1m+nW*i1p]+conv[17]*pInp[j+nW*i1p]+conv[18]*pInp[j1p+nW*i1p]+conv[19]*pInp[j2p+nW*i1p];
     res += conv[20]*pInp[j2m + nW*i2p]+conv[21]*pInp[j1m+nW*i2p]+conv[22]*pInp[j+nW*i2p]+conv[23]*pInp[j1p+nW*i2p]+conv[24]*pInp[j2p+nW*i2p];
     res  = (res+denom2) / denom;
	 
	 res = abs(res);
	 
	 if(res>255) res = 255;

     pOut[j + nW*i] = res;
   }
 }
 return 0;
}
//=======================================================================================
int main(int nArg, char** ppArg)
{
	int i, j;
	int nW, nH; // image width and height
	int nBr;    // image brightness
	byte* pIm;  // pointer to image matrix
	byte* pIm2; // pointer to result image matrix
	int nSize;  // image size in bytes
	int nX;
	FILE* pF;
	int coef[25]; // convolution's coefficients
	int nSum = 0;
	
	if(nArg==1) 
	{
		puts("2-Dim convolution filter with convolution vector 5x5");
		puts("pgmconv55abs matr.txt   file.pgm   result.pgm");
		exit(1);
	}

	pF = fopen(ppArg[1], "r");
	printf("matrix: ");
	for(i=0; i<25; i++)
	{
		fscanf(pF, "%d", &coef[i]);
		nSum = nSum + coef[i];
		printf("%d ", coef[i]);
	}
	printf("\n");
	if(nSum == 0) nSum = 1;
	
	ReadPGM(ppArg[2], &pIm, &nW, &nH);
	
	nSize = nW * nH;
	pIm2 = (byte*) malloc(nSize);
	
    FrameConvolution5x5(pIm, pIm2, nW, nH, coef, nSum);
	
	WritePGM(ppArg[3], pIm2, nW, nH);
	
	free(pIm2);
	free(pIm);
	
	return 0;
}