// file: $USFS/class/image_analysis/v6.2/imaga_hist_05.cc
//

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

// method: hist_assign_cc
//
// arguments:
//  uint_1* b_red: (input) red buffer
//  uint_1* b_green: (input) green buffer
//  uint_1* b_blue: (input) blue buffer
//  int_4 offset_width: (input) offset in width
//  int_4 offset_height: (input) offset in height
//  int_4 actual_width: (input) actual width of the block
//  int_4 actual_height: (input) actual height of the block
//
// return:
//  a logical_1 value indicating the status
//
// this method assigns data points to bins in the histogram.
// note that the histogram is assumed to extend from:
//
//   [min_val - bin_width/2] to [max_val + bin_width/2]
//
// points outside this range are assigned to the end bins.
//
logical_1 Image_analysis::hist_assign_cc(uint_1* b_red_a, uint_1* b_green_a,
					 uint_1* b_blue_a,
					 int_4 offset_width_a,
					 int_4 offset_height_a,
					 int_4 actual_width_a,
					 int_4 actual_height_a) {
  
  // compute the quantization constants
  //
  float_8 bin_width = (hist_r_max_d - hist_r_min_d) / (float_8)hist_r_nbins_d;
  float_8 min_val = hist_r_min_d - 0.5 * bin_width;
  float_8 max_val = hist_r_max_d + 0.5 * bin_width;
  float_8 range = max_val - min_val;
  float_8 scale = (float_8)hist_r_nbins_d / range;
  int_4 npixels = actual_width_a * actual_height_a;
  
  // the intensities of yellow and brown, calculated from the rgb values
  //
  uint_1 p_yellow, p_brown;
  
  // loop over all the data
  //
  int_4 index;

  for (int_4 i=0; i<npixels; i++) {

    // set a flag
    //
    logical_1 process_pixel = ISIP_TRUE;
    
    // check the segmentation flag
    //
    if (check_segflag_cc() == ISIP_TRUE) {

      // run segmentation-based evaluation
      //
      // calculate the coordinates for the pixel
      //
      int_4 x_val = offset_width_a + i % actual_width_a;
      int_4 y_val = offset_height_a + i / actual_width_a;
	
      if (is_inside_cc(x_val, y_val) == ISIP_FALSE) {

	// the pixel is not inside the prescribed region, no processing
	//
	process_pixel = ISIP_FALSE;
      }
    }
      
    if (process_pixel == ISIP_TRUE) {
     
      if (sel_vec_d[0] == 1) {

	// process the red pixel
	//
	index = hist_compute_index_cc((float_8)b_red_a[i],
				      min_val, max_val, scale);
	hist_t_rpdf_d[index] += (float_8)1.0;
      }

      if (sel_vec_d[10] == 1) {

	// process the green pixel
	//
	index = hist_compute_index_cc((float_8)b_green_a[i],
				      min_val, max_val, scale);
	hist_t_gpdf_d[index] += (float_8)1.0;
      }

      if (sel_vec_d[20] == 1) {
	
	// process the blue pixel
	//
	index = hist_compute_index_cc((float_8)b_blue_a[i],
				      min_val, max_val, scale);
	hist_t_bpdf_d[index] += (float_8)1.0;
      }

      if (sel_vec_d[45] == 1) {
	
	// calculate the intensity of yellow for the given pixel
	// the formula used is yellow = 0.5 * red + 0.5 * green
	//
	p_yellow = (uint_1)(0.5 * b_red_a[i] + 0.5 * b_green_a[i]);
	index = hist_compute_index_cc((float_8)p_yellow,
				      min_val, max_val, scale);
	hist_t_ylwpdf_d[index] += (float_8)1.0;
      }

      if (sel_vec_d[55] == 1) {
	
	// calculate the intensity of brown for the given pixel
	// the formula used is brown = 2/3 * red + 1/6 * green + 1/6 * blue
	//
	p_brown = (uint_1)(2.0 * b_red_a[i] / 3.0 + b_green_a[i] / 6.0
			   + b_blue_a[i] / 6.0);
	index = hist_compute_index_cc((float_8)p_brown,
				      min_val, max_val, scale);
	hist_t_brnpdf_d[index] += (float_8)1.0;
      }
	  
      // increment the pixel counters
      //
      hist_t_npxls_d++;
    }
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
