
/****
    Copyright (C) 1996 McGill University.
    Copyright (C) 1996 McCAT System Group.
    Copyright (C) 1996 ACAPS Benchmark Administrator
                       benadmin@acaps.cs.mcgill.ca

    This program is free software; you can redistribute it and/or modify
    it provided this copyright notice is maintained.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
****/

/* ------------------------------------------------------------------------
 * L_canny.c   Canny Edge Detection
 *
 * V
 * University of Illinois at Urbana-Champaign
 *
 * Program written by A. Tabbone (CRIN/CNRS- Lorraine, FR)
 * Modified for V by C. P. Hess  (Univ. Illinois at Urbana, USA)
 * Original copyright appears at EOF.
 *
 * $Id$
 * ------------------------------------------------------------------------ */
#include <math.h>
#include <ctype.h>
#include "V.h"

int    GaussianMask();
int    DGaussianMask();
int    dfilter();
float *dnon_max();

int L_canny(sigma, image, nc, nr, edge, err)
float    sigma;
float   *image;
int      nc;
int      nr;
float  **edge;
char    *err;
{
  float    *Ix, *Iy, *gr, *gmask, *dgmask;
  int       tgauss, tdgauss, i;
  
  if(GaussianMask (sigma, &tgauss,  &gmask,  err)) return(1);
  if(DGaussianMask(sigma, &tdgauss, &dgmask, err)) return(1);

  if(dfilter(image, gmask,  dgmask, tgauss,  tdgauss, 
	     nc, nr, &Ix, err)) return(1);
  if(dfilter(image, dgmask, gmask,  tdgauss, tgauss,  
	     nc, nr, &Iy, err)) return(1);

  gr = (float *) calloc(nr*nc, FWS);
  if (!gr) {
    sprintf(err, "Out of memory");
    return(1);
  }
  for (i=0; i<nr*nc; i++) gr[i] = MOD(Iy[i], Ix[i]);
  
  *edge = dnon_max(gr, Ix, Iy, nc, nr);

  return(0);
}


int GaussianMask(sigma, tg, mask, err)
float    sigma;
int     *tg;  
float  **mask;
char    *err;
{
  short    i;
  float   *coeff_gauss;
  float   *p;

  *tg = (short) (GAUSS_MASK*sigma);
  if (*tg % 2 == 0) *tg += 1;
 
  coeff_gauss = p = (float *)calloc(*tg, FWS);
  if (!coeff_gauss) {
    sprintf(err,"Out of memory");
    return(1);
  }

  for (i=-(*tg/2); i<=*tg/2; i++) {
    if ((i+(*tg/2)) == 0) 
      *coeff_gauss++ = 
	(float)((erf((double)(i+0.5)/(sqrt((double)2.0)*sigma))+1.0)/2.0);
    else if ((i+(*tg/2)) == *tg-1) 
      *coeff_gauss++ =
	(float)((-erf((double)(i-0.5)/(sqrt((double)2.0)*sigma))+1.0)/2.0);
    else *coeff_gauss++ =
      (float)0.5*(erf((double)(i+0.5)/(sqrt((double) 2.0)*sigma))-
		  erf((double)(i-0.5)/(sqrt((double) 2.0)*sigma)));
  }
  *mask = p; 

  return(0);
}


int DGaussianMask(sigma, tg, mask, err)
float    sigma;
int     *tg;
float  **mask;
char    *err;
{
  short   i;
  float  *coeff_dgauss;
  float  *p;
   
  *tg  = (short) (DGAUSS_MASK*sigma);
  if (*tg % 2 == 0) *tg += 1;

  coeff_dgauss = p = (float *)calloc(*tg, FWS);
  if (!coeff_dgauss) {
    sprintf(err,"Out of memory");
    return(1);
  }

  for (i=-(*tg/2); i<=*tg/2; i++) {
    if ((i+(*tg/2)) == 0)
      *coeff_dgauss++ = 
	(float)(1.0/(sigma*sqrt((double)(2.0*M_PI))))*
	  exp(-(double)((i+0.5)*(i+0.5))/(double)(2.0*sigma*sigma));
    else if ((i+(*tg/2)) == *tg-1) 
      *coeff_dgauss++ = 
	(float)-(1.0/(sigma*sqrt(2.0*M_PI)))*
	  exp(-(double)((i-0.5)*(i-0.5))/(double)(2.0*sigma*sigma));
    else *coeff_dgauss++ =
      (float)((exp(-(double)((i+0.5)*(i+0.5))/(double)(2.0*sigma*sigma))-
	       exp(-(double)((i-0.5)*(i-0.5))/(double)(2.0*sigma*sigma)))/
	      (sigma*sqrt((double) 2.0*M_PI)));
  }
  coeff_dgauss = p;
  *mask = p;

  return(0);
}


int dfilter(image, g, f, tm_g, tm_f, nc, nr, filt, err)
float  *image, *g, *f;
int     nc, nr, tm_g, tm_f;
float **filt;
char   *err;
{
  register short    i, j, l, high = nr, larg = nc;
  float             nv, *d, *d1, *d2, *temp;

  d = d1 = (float *) calloc(nc*nr, FWS);
  if (!d) {
    sprintf(err,"Out of memory");
    return(1);
  }
 
  for (i=0; i<high; i++)
    for (j=0; j<larg; j++) {
      for (l=-(tm_g/2); l<=(tm_g/2); l++) {
	if ((j+l) < 0) nv = (float) image[i*larg];
	else if ((j+l) >= larg) nv = (float) image[((i+1)*larg)-1];
	else nv = (float) image[(i*larg)+j+l];
	*d = (nv * g[(tm_g/2)-l]) + *d;
      }
      d++;
    }

  d = d1;
  
  d2 = (float *) calloc(nc*nr, FWS);
  if (!d2) {
    sprintf(err,"Out of memory");
    return(1);
  }

  for (j=0; j<larg ; j++)
    for (i=0; i<high; i++) {
      for (l=-(tm_f/2); l<=(tm_f/2); l++) {
	if ((i+l) < 0) nv = d[j];
	else if ((i+l) >= high) nv = d[((high-1)*nc)+j];
	else nv = d[((i+l)*larg)+j];
	temp = (d2+(i*larg)+j);
	*temp = (nv * f[(tm_f/2)-l]) + *temp;
      }
    }
  
  *filt = d2;
  return(0);
}

float *dnon_max(gr, Ix, Iy, nc, nr)
float  *gr;
float  *Ix;
float  *Iy;
int     nc;
int     nr;
{
  int      i, j;
  float   *maxima;
  float    R, ampl1, ampl2;
 
  maxima = (float  *) calloc(nc*nr, FWS);

  for (i=1;i<nr-2;i++)
    for (j=1;j<nc-2;j++) {
      if (ZERO(I(Ix,i,j,nc))) {
	ampl1 = I(gr,i,j-1,nc); ampl2 = I(gr,i,j+1,nc); 
      } else {
	R = I(Iy,i,j,nc) / I(Ix,i,j,nc); 
	if ((R >=0.) && (R < .4)) {  
	  ampl1 = I(gr,i+1,j+1,nc) * R + (1.-R)* I(gr,i+1,j,nc);
	  ampl2 = I(gr,i-1,j-1,nc) * R + (1.-R)* I(gr,i-1,j,nc);
	}
        /*
	  else if ( R >= 1.) {
	  ampl1 = (I(gr,i+1,j+1,nc) + (R - 1.) * I(gr,i,j+1,nc)) / R;
	  ampl2 = (I(gr,i-1,j-1,nc) + (R - 1.) * I(gr,i,j-1,nc)) / R;
	} */
          else if ((R <= 0.) && (R >  -.4)) { 
	  ampl1 = - I(gr,i+1,j-1,nc) * R + ( 1. + R)* I(gr,i+1,j,nc);
	  ampl2 = - I(gr,i-1,j+1,nc) * R + ( 1. + R)* I(gr,i-1,j,nc);
	} 
        /*
          else if (R <= -1.) {
	  ampl1 = (- I(gr,i+1,j-1,nc) + (R + 1.) * I(gr,i,j-1,nc)) / R;
	  ampl2 = (- I(gr,i-1,j+1,nc) + (R + 1.) * I(gr,i,j+1,nc)) / R;
	} */
	else
	  {
	    I(maxima,i,j,nc) = 0;
	    continue;
	  }
      }
      
      if (GEPS(I(gr,i,j,nc), ampl1) && GEPS(I(gr,i,j,nc),ampl2)) 
	I(maxima,i,j,nc) = NGMAX;
    }

  return(maxima);
}


/* ORIGINAL COPYRIGHT *****************************************************
*  Copyright (C) 1994 CRIN                                                *
*                                                                         *
*  This software was written by A. Tabbone at :                           *
*   C.R.I.N/CNRS-INRIA lorraine                                           *
*    Boite Postale 239                                                    *
*    54506 Vandoeuvre-les-Nancy Cedex                                     *
*    France                                                               *
*  It may be distributed or copied, in whole or in part, within the       *
*  following restrictions:                                                *
*    (1) It may not be sold at a profit.                                  *
*    (2) This credit and notice must remain intact.                       *
*  This software may be distributed with other software by a commercial   *
*  vendor, provided that it is included at no additional charge.          *
*                                                                         *
*  Please report bugs to tabbone@loria.crin.fr                            *
***************************************************************************/




