// file: $USFS/class/image_analysis/v3.1/imaga_edge_12.cc
//

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

#include "image_analysis_constants.h"
#include <integral_constants.h>

// method: edge_maxsup_cc
//
// arguments:
//  float_4* out_image: (output) the buffer having the final data after
//                      suppression
//  float_4* edge_grad: (input) the buffer having the data after
//                      computing the gradient
//  int_4 width: (input) width of the image block (or entire image)
//  int_4 height: (input) height of the image block (or entire image)
//
// return : a logical_1 value indicating status
//
// this method performs the non-maximal suppression on the gradient image
// note this version corrected the error implementation of canny edge
// detector in previous versions
//
logical_1 Image_analysis::edge_maxsup_cc(float_4* out_image_a,
					 float_4* edge_grad_a,
					 int_4 width_a, int_4 height_a) {
  
  // set the high and low thresholds
  //
  float_4 high_threshold = IMAGA_EDGE_THRESHOLD_HIGH;
  float_4 low_threshold = IMAGA_EDGE_THRESHOLD_LOW;
  
  // find edges
  //
  for (int_4 i=0; i<height_a; i++) {
    for (int_4 j=0; j<width_a; j++) {
      
      // if the gradient value is greater than the high threshold, it is
      // part of an edge
      //
      if (edge_grad_a[i * width_a + j] >= high_threshold) {
	out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
      }

      // else if the pixel is adjacent to an edge, and the value is greater
      // than the low threshold, then it is still part of that edge
      //
      else if (edge_grad_a[i * width_a + j] >= low_threshold) {

	// check if the adjacent pixel is an edge
	//
	if ((j>0) && (out_image_a[i * width_a + (j - 1)] == IMAGA_HIST_MAX)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if (((j + 1) < width_a) &&
		 (edge_grad_a[i * width_a + (j + 1)] >= high_threshold)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if ((i > 0) &&
		 (out_image_a[(i - 1) * width_a + j] == IMAGA_HIST_MAX)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if (((i + 1) < height_a) &&
		 (edge_grad_a[(i + 1) * width_a + j] >= high_threshold)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if ((j > 0) && (i > 0) &&
		 (out_image_a[(i - 1) * width_a + (j - 1)] == IMAGA_HIST_MAX)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if ((j > 0) && ((i + 1) < height_a) &&
	         (edge_grad_a[(i + 1) * width_a + (j - 1)] >= high_threshold)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if (((j + 1) < width_a) && (i > 0) &&
		 (out_image_a[(i - 1) * width_a + (j + 1)] == IMAGA_HIST_MAX)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}
	else if (((j + 1) < width_a) && ((i + 1) < height_a) &&
		 (edge_grad_a[(i + 1) * width_a + (j + 1)] >= high_threshold)) {
	  out_image_a[i * width_a + j] = IMAGA_HIST_MAX;
	}	  
      }
    
      // else the pixel is not part of an edge
      //
      else {
	out_image_a[i * width_a + j] = IMAGA_HIST_MIN;
      }
    }
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
