 // PoissonSolver.cpp
// Feris, August 2004

#include "PoissonSolver.h"
#include "gradImage.h"

// Constructor
// take as input a .txt gradient file (created outside by a Matlab program)
// Then it calls function to initialize m_gradx, m_grady, m_width, m_height
//
CPoissonSolver::CPoissonSolver(char *filename)
{
	
	ImageGradient(filename);// Initialize m_gradx, m_grady, m_width, m_height

	m_export = new BYTE[m_width * m_height];
	ZeroMemory(m_export,m_width*m_height);
}


// Destructor
//
CPoissonSolver::~CPoissonSolver()
{
	ImageDestroy(m_gradx);
	ImageDestroy(m_grady);
}


// Solve Poisson equation to reconstruct img from gradient field
//
void CPoissonSolver::ReconstructImg()
{
	int n, nn, i;
	double **u;
	int Vcylces = 5; //number of iterations
	double  maxMinNoMask[2]; // dynamic range for normalization

	n = nn = m_width - 1; // the grad images will be one pixel unit small

	u=dmatrix(0,nn,0,nn); // Allocate space for divergent matrix
	
	SetDivergent((double **) u); // save divergent image into u

	mglin((double **) u,n,Vcylces);	printf("\tDone with mgline with masking\n\n"); // Full Multigrid Algorithm using linear method

	//after intergrate the image, we need to match the color
	//to match constant factor
	
	double **uOut;
	uOut=dmatrix(0,n,0,n); 
	if (!uOut) nrerror("allocation failure 1 in matrix()");
	
	saveArrayAsImage((double **) u, (double **) uOut, m_export, n, n, "3reconYesMask.ppm", NORMALIZE, maxMinNoMask);

	double a = 1.0; double b = 0; 

	for(i = 1; i < m_width - 1; i++){
		for(int j = 1; j < m_height - 1; j++){
			int temp = (int)(a * 255 * uOut[i][j] + b);
			if(temp >= 255) temp = 255;
			if(temp <= 0) temp = 0;

			m_export[j * m_width + i] = temp;
		}
	}
	// just to write in disk
	Image * depth_image = (Image *) malloc(sizeof(Image)); 	
    depth_image->width = m_width;
    depth_image->height = m_height;
    depth_image->data = m_export;
	ImageWriteP2(depth_image,"depthmap.pgm");
}


void CPoissonSolver::SetDivergent(double ** u)
{
	int i,j;
	int n = m_width-1;
	Image *divG = ImageCreate(n+1,n+1);

	imageGradientTodivG(m_gradx, m_grady, divG);

	for (i=1; i <= n; i++) {
		for (j=1; j <= n; j++) {
			u[i][j] = (double) (ImageGetPixelf(divG, i, j, 0, GRAY)/255.0);
		}
	}
	ImageDestroy(divG);
}


// Initialize m_gradx, m_grady, m_width, m_height from file
//

void CPoissonSolver::ImageGradient(char *filename)
{ 
  int i, j, gradX, gradY;
  FILE *fp;

  fp = fopen(filename,"rt");
  
  // parse filename - initialize m_width, m_height
  fscanf(fp,"%d %d \n",&m_width,&m_height);

  int n = m_width-1;
  m_gradx = ImageCreate(n+1,n+1);
  m_grady = ImageCreate(n+1,n+1);
	

  for (i=1; i <= m_height; i++) {
	  for (j=1; j <= m_width; j++) 
	  {
	      // parse filename - initialize gradX, gradY 
		  fscanf(fp,"(%d,%d) ",&gradX,&gradY);
		  
		  ImageSetPixelf(m_gradx, j, i, 0, double(gradX), GRAY) ; 
		  ImageSetPixelf(m_grady, j, i, 0, double(gradY), GRAY) ;
		  
	  }
	  fscanf(fp,"\n");
  }
  fclose(fp);

  // debug feris
  /*Image * feris_image = (Image *) malloc(sizeof(Image)); 	
  feris_image->width = m_width;
  feris_image->height = m_height;
  BYTE *feris_data = new BYTE[m_width*m_height];
  ZeroMemory(feris_data,m_width*m_height);
  feris_image->data = feris_data;
  for (int i=0;i<m_width;i++)
	  for (int j=0;j<m_height;j++)
		  feris_data[j*m_width+i] = (BYTE)fabs(ImageGetPixelf(m_gradx,i+1,j+1,0,GRAY));
  ImageWriteP2(feris_image,"gradx.pgm");*/
  
}



// debug feris
 /* Image * feris_image = (Image *) malloc(sizeof(Image)); 	
  feris_image->width = width;
  feris_image->height = height;
  BYTE *feris_data = new BYTE[width*height];
  ZeroMemory(feris_data,width*height);
  feris_image->data = feris_data;
  for (int i=0;i<width;i++)
	  for (int j=0;j<height;j++)
		  feris_data[j*width+i] = (BYTE)fabs(ImageGetPixelf(gradHx,i+1,j+1,0,GRAY));
  ImageWriteP2(feris_image,"d:\\Rogerio\\temp\\gradx.pgm");

  ZeroMemory(feris_data,width*height);
  for (int i=0;i<width;i++)
	  for (int j=0;j<height;j++)
		  feris_data[j*width+i] = (BYTE)fabs(ImageGetPixelf(gradHy,i+1,j+1,0,GRAY));
  ImageWriteP2(feris_image,"d:\\Rogerio\\temp\\grady.pgm");*/
  //end debug feris

