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

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

// method: gabor_compu_features_cc
//
// arguments:
//  float_8** blk_fltr: (input) pointer to a series of filtered block data
//  int_4 width: (input) block width
//  int_4 height: (input) block height
//
// return: a logical_1 value indicating status
//
// this method computes a feature vector on the given filtered data blocks.
// each filtered data block is firstly transformed nonlinearly by tanh
// function, then "energy" is computed at each pixel by gaussian windowing
// as described in Jain's paper. an average of this "energy" value over
// the whole block is counted as one element of the feature vector.
//
logical_1 Image_analysis::gabor_compu_features_cc(float_8** blk_fltr_a,
						  int_4 width_a,
						  int_4 height_a) {
  
  for (int_4 i = 0; i < gabor_feature_dim_d; i++) {

    // gaussian window related parameters
    //
    float_8 sigma = 0.5 /
      gabor_rad_frq_d[(int_4)(floor(i / gabor_num_orient_d))];
    int_4 win_size = (int_4)(rint(gabor_win_scale_d * sigma));
    int_4 half_winsize = (int_4)(rint(win_size / 2));

    // only compute on the block center
    //
    int_4 x = width_a / 2;
    int_4 y = height_a / 2;
    
    float_8 temp = 0;

    // compute Jain's feature at each pixel
    //
    for (int_4 a = (x - half_winsize); a <= (x + half_winsize); a++) {
      for (int_4 b = (y - half_winsize); b <= (y + half_winsize); b++) {
	
	int_4 tmp_a = a, tmp_b = b;
	
	// even reflection boundary condition
	//
	if (a < 0) {
	  tmp_a *= (-1);
	}
	else if (a > (width_a - 1)) {
	  tmp_a = 2 * (width_a - 1) - a;
	}
	
	if (b < 0) {
	  tmp_b *= (-1);
	}
	else if (b > (height_a - 1)) {
	  tmp_b = 2 * (height_a - 1) - b;
	}
	
	// gaussian window
	//
	float_8 g_win = exp(-0.5 * (pow((x - a), 2) + pow((y - b), 2))
			    / pow(sigma, 2));
	
	// nonlinear transformation (tanh)
	// 
	temp += fabs(g_win * tanh(gabor_alpha_d *
				  blk_fltr_a[i][tmp_b * width_a + tmp_a]));
      }
    }
    
    gabor_feature_d[i] += temp / pow((2 * half_winsize + 1), 2);    
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
