// file: $USFS/class/image_analysis/v6.1/imaga_edge_20.cc
//

// isip include files
//
#include "image_analysis.h"
#include "image_analysis_constants.h"

// method: edge_compute_cc
//
// arguments:
//  uint_1* blk_r: (input) buffer for red color
//  uint_1* blk_g: (input) buffer for green color
//  uint_1* blk_b: (input) buffer for blue color
//  int_4 offset_w: (input) offset in width for the image block
//  int_4 offset_h: (input) offset in height for the image block
//  int_4 width: (input) width of the image block
//  int_4 height: (input) height of the image block
//  
// return:
//  a logical_1 value indicating the status
//
// this method computes the edges on an image block
//
logical_1 Image_analysis::edge_compute_cc(uint_1* blk_r_a, uint_1* blk_g_a,
					  uint_1* blk_b_a, int_4 offset_w_a,
					  int_4 offset_h_a, int_4 width_a,
					  int_4 height_a) {

  // declare local variable
  //
  logical_1 process_block = ISIP_TRUE;

  // check if segmentation data needed
  //
  if (check_segflag_cc() == ISIP_TRUE) {
    
    // if no region corresponding to the transcription was found in the
    // image, no computation needed
    //
    if (polygon_list_d == (Link_list*)NULL) {
      process_block = ISIP_FALSE;      
    }
    else if ((polygon_list_d->get_head_cc()) == (Link_node*)NULL) {
      process_block = ISIP_FALSE;
    }

    // else check if the block is inside the prescribed region
    //
    else {

      // compute the coordinates for the block center
      //
      int_4 center_x = offset_w_a + width_a / 2;
      int_4 center_y = offset_h_a + height_a / 2;

      // if the center of the block is not inside the prescibed region, no
      // computation needed
      //
      if (is_inside_cc(center_x, center_y) == ISIP_FALSE) {
        process_block = ISIP_FALSE;
      }
    }
  }

  if (process_block == ISIP_TRUE) {
  
    // define memory to read the gaussian mask values
    //
    float_4* edge_gauss = new float_4[edge_r_msize_d * edge_r_msize_d];
  
    // compute 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 coefficients");
      return ISIP_FALSE;
    }
  
    // define memory to read the x and the y derivative masks
    //
    float_4* edge_xderiv = new float_4[width_a * height_a];
    float_4* edge_yderiv = new float_4[width_a * height_a];
  
    // compute 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_a * height_a];
  
    // compute the equivalent gray scale value
    //
    if (edge_gray_cc(edge_gray, width_a, height_a, blk_r_a, blk_g_a,
		     blk_b_a) == 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_a * height_a];
  
    // convolve the gray scaled image with the gaussian mask
    //
    if (edge_convolve_cc(gauss_result, edge_gray, edge_gauss,
		         width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"edge_compute_cc", (char_1*)"error convolving
                       the image with gaussian mask");
      return ISIP_FALSE;
    }
  
    // delete 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_a * height_a];
    float_4* yderiv_image = new float_4[width_a * height_a];
  
    // convolve 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_a, height_a) == 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_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"edge_compute_cc", (char_1*)"error convolving
                       the image with the y derivative");
      return ISIP_FALSE;
    }
  
    // delete the memory
    //
    delete [] gauss_result;
  
    // define memory to read the gradient of the image
    //
    float_4* edge_grad = new float_4[width_a * height_a];
  
    // compute the gradient
    //
    if (edge_gradient_cc(edge_grad, width_a, height_a, xderiv_image,
		         yderiv_image) == ISIP_FALSE) {
      error_handler_cc((char_1*)"edge_compute_cc",
		       (char_1*)"error computing the gradient");
      return ISIP_FALSE;
    }
    
    // delete the memory
    //
    delete [] xderiv_image;
    delete [] yderiv_image;
  
    // define memory to read the edge_detected image
    //
    float_4* out_image = new float_4[width_a * height_a];
  
    // suppress the maximum values in the image
    //
    if (edge_maxsup_cc(out_image, edge_grad, width_a, height_a)
	== ISIP_FALSE) {
      error_handler_cc((char_1*)"edge_compute_cc",
		       (char_1*)"error doing maximum suppression");
      return ISIP_FALSE;
    }
    
    // delete the memory
    //
    delete [] edge_grad;
  
    // define memory to read the number of lines
    //
    int_4* num_lines = new int_4[width_a*height_a];
  
    if (edge_lines_cc(num_lines, out_image, width_a, height_a)
	== 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_nblks_d += (int_4)1;
   
    // delete the memory
    //
    delete [] edge_gauss;
    delete [] edge_xderiv;
    delete [] edge_yderiv;
    delete [] out_image;
    delete [] num_lines;
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
