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

// system include files
//
#include <string.h>

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

// method: gabor_compute_cc
//
// arguments:
//  uint_1* blk_r: (input) red block
//  uint_1* blk_g: (input) green block
//  uint_1* blk_b: (input) blue block
//  int offset_w: (input) offset in width
//  int offset_h: (input) offset in height
//  int width: (input) width of block
//  int height: (input) height of block
//
// return: a logical_1 value indicating status
//
// this method computes gabor filters-based features
//
logical_1 Image_analysis::gabor_compute_cc(uint_1* blk_r_a, uint_1* blk_g_a,
					   uint_1* blk_b_a,
					   int offset_w_a, int offset_h_a,
					   int width_a, int 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) {

    float_8* gabor_gray = new float_8[height_a * width_a];
    memset(gabor_gray, 0, height_a * width_a * sizeof(float_8));
    
    // convert color image into gray-level image
    //
    if (gabor_gray_cc(gabor_gray, width_a, height_a, blk_r_a, blk_g_a,
		      blk_b_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"gabor_compute_cc",
		       (char_1*)"error while computing gray scale value");
      return ISIP_FALSE;
    }

    float_8** blk_fltr = new float_8*[gabor_feature_dim_d];
    memset(blk_fltr, 0, gabor_feature_dim_d * sizeof(float_8*));
    
    // filter an image block through a bank of gabor filters
    //
    for (int_4 i = 0; i < gabor_feature_dim_d; i++) {
      
      // declare local variables
      //
      float_8* gabor_filter = new float_8[gabor_num_col_d * gabor_num_row_d];
      memset(gabor_filter, 0,
	     gabor_num_col_d * gabor_num_row_d * sizeof(float_8));
      
      float_8 rad_frq = gabor_rad_frq_d[(int_4)(floor(i / gabor_num_orient_d))];
      float_8 orient = gabor_orient_d[(int_4)(i % gabor_num_orient_d)];
      
      // generate system response sequence of a gabor filter
      //
      if (gabor_gen_cc(gabor_filter, rad_frq, orient) == ISIP_FALSE) {
	error_handler_cc((char_1*)"gabor_compute_cc",
			 (char_1*)"error while generating gabor functions");
	return ISIP_FALSE;
      }
      
      blk_fltr[i] = new float_8[height_a * width_a];
      memset(blk_fltr[i], 0, height_a * width_a * sizeof(float_8));
      
      // convolve input data with system response data
      //
      if (gabor_convolve_cc(blk_fltr[i], gabor_gray, gabor_filter,
			    width_a, height_a) == ISIP_FALSE) {
	error_handler_cc((char_1*)"gabor_compute_cc",
			 (char_1*)"error while convolving");
	return ISIP_FALSE;
      }
      
      // delete memory
      //
      delete [] gabor_filter;
    }  
    
    // compute features
    //
    if (gabor_compu_features_cc(blk_fltr, width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"gabor_compute_cc",
		       (char_1*)"error while computing features");
      return ISIP_FALSE;
    }
    
    // delete memory
    //
    delete [] gabor_gray;
    for (int_4 i = 0; i < gabor_feature_dim_d; i++) {
      delete [] blk_fltr[i];
    }
    delete [] blk_fltr;

    // update counters
    //
    gabor_r_npxls_d += width_a * height_a;
    gabor_r_nblks_d += 1;
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
