// file: $USFS/class/image_analysis/v6.0/imaga_edge_19.cc
//

// isip include files
//
#include "image_analysis.h"
#include <ppm.h>

#include "image_analysis_constants.h"

// method: edge_compute_cc
//
// arguments:
//  char_1* image_fname: (input) the image file name
//  char_1* seg_fname: (input) the segmentation file name
//
// return:
//  a logical_1 value indicating the status
//
// this method computes the edges on a prescribed region
//
logical_1 Image_analysis::edge_compute_cc(char_1* image_fname_a,
					  char_1* seg_fname_a) {
  
  // declare local variables
  //
  char_1* fname = new char_1[ISIP_MAX_STRING_LENGTH];
  
  // declare a ppm object
  //
  Ppm ppm;

  // load the segmentation data
  //
  if (load_polygons_cc(seg_fname_a) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error reading the segmentation data");
    return ISIP_FALSE;
  }
  
  // if no region corresponding to the transcription was found in the
  // image, no computation needed
  //
  if (polygon_list_d == (Link_list*)NULL) {
    return ISIP_TRUE;
  }
  else if ((polygon_list_d->get_head_cc()) == (Link_node*)NULL) {
    return ISIP_TRUE;
  }

  // open the ppm image
  //
  if (ppm.open_cc(image_fname_a, ISIP_READ_ONLY) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error opening the image file");
    return ISIP_FALSE;
  }
  
  // read the dimensions of the image
  //
  int_4 width = ppm.get_width_cc();
  int_4 height = ppm.get_height_cc();
  
  // intializing the arrays for the image data
  //
  uint_1 b_red[width * height];
  uint_1 b_green[width * height];
  uint_1 b_blue[width * height];
  
  // read the ppm file block by block
  //
  if (ppm.read_cc(b_red, b_green, b_blue, IMAGA_EDGE_WOFF, IMAGA_EDGE_HOFF,
		  width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error while reading the file");
    return ISIP_FALSE;
  }

  // define memory to read the gaussian mask values
  //
  float_4* edge_gauss = new float_4[edge_r_msize_d * edge_r_msize_d];
  
  // computing the gaussian matrix
  //
  if (edge_gauss_cc(edge_gauss) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error computing the gaussian coeffients");
    return ISIP_FALSE;
  }
  
  // define memory to read the x and the y derivative masks
  //
  float_4* edge_xderiv = new float_4[width * height];
  float_4* edge_yderiv = new float_4[width * height];
  
  // computing the derivatives matrix
  //
  if (edge_derivatives_cc(edge_xderiv, edge_yderiv) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error computing the derivative coefficients");
    return ISIP_FALSE;
  }
  
  // define memory to read the gray scale values
  //
  float_4* edge_gray = new float_4[width * height];
  
  // compute the equivalent gray scale value
  //
  if (edge_gray_cc(edge_gray, width, height, b_red, b_green,
		   b_blue) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error while computing the gray scale value");
    return ISIP_FALSE;
  }
  
  // define memory to read the gaussian smoothed image
  //
  float_4* gauss_result = new float_4[width * height];
  
  // convolving the gray scaled image with the gaussian mask
  //
  if (edge_convolve_cc(gauss_result, edge_gray, edge_gauss,
		       width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error convolving the image with gaussian mask");
    return ISIP_FALSE;
  }
  
  // deleting the memory
  //
  delete [] edge_gray;
  
  // define memory to read the image after convolving with
  // x and y derivative masks
  //
  float_4* xderiv_image = new float_4[width * height];
  float_4* yderiv_image = new float_4[width * height];
  
  // convolving the image after convolution with the gaussian mask
  // with the x derivative and y derivative masks
  //
  if (edge_convolve_cc(xderiv_image, gauss_result, edge_xderiv,
		       width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error convolving the image with the x derivative");
    return ISIP_FALSE;
  }
  
  if (edge_convolve_cc(yderiv_image, gauss_result, edge_yderiv,
		       width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error convolving the image with the y derivative");
    return ISIP_FALSE;
  }
  
  // deleting the memory
  //
  delete [] gauss_result;
  
  // define memory to read the gradient of the image
  //
  float_4* edge_grad = new float_4[width * height];
  
  // computing the gradient
  //
  if (edge_gradient_cc(edge_grad, width, height, xderiv_image,
		       yderiv_image) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error computing the gradient");
    return ISIP_FALSE;
  }
  
  // deleting the memory
  //
  delete [] xderiv_image;
  delete [] yderiv_image;
  
  // define memory to read the edge_detected image
  //
  float_4* out_image = new float_4[width * height];
  
  // suppressing the maximum values in the image
  //
  if (edge_maxsup_cc(out_image, edge_grad, width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error doing maximum suppression");
    return ISIP_FALSE;
  }
  
  // deleting the memory
  //
  delete [] edge_grad;
  
  // define memory to read the number of lines
  //
  int_4* num_lines = new int_4[width*height];
  
  if (edge_lines_cc(num_lines, out_image, width, height) == ISIP_FALSE) {
    error_handler_cc((char_1*)"edge_compute_cc",
		     (char_1*)"error computing the number of lines");
    return ISIP_FALSE;
  }
  
  // increment the images processed
  //
  edge_t_nimages_d += (int_4)1;
  
  // closing the file
  //
  ppm.close_cc();
  
  // deallocate the memory
  //
  delete [] edge_gauss;
  delete [] edge_xderiv;
  delete [] edge_yderiv;
  delete [] out_image;
  delete [] num_lines;
  delete [] fname;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
