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

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

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

// method: pca_train_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 status
//
// this method trains on the images using the algorithm of factor analysis
//
logical_1 Image_analysis::pca_train_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 variables
  //
  int_4 k = 0;
  logical_1 done_statistics = ISIP_FALSE;

  if ((sel_vec_d[0] == 1) || (sel_vec_d[10] == 1) || (sel_vec_d[20] == 1)
      || (sel_vec_d[45] == 1) || (sel_vec_d[55] == 1)) {
  
    // initializing the private data to zero
    //
    if (hist_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
               	       (char_1*)"error initializing the data");
      return ISIP_FALSE;
    }
  
    // compute the histogram
    //
    if (hist_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
			width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error while computing the histogram");
      return ISIP_FALSE;
    }
  
    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += hist_t_npxls_d;
      pca_t_nblks_d += hist_t_nblks_d;
      done_statistics = ISIP_TRUE;
    }
    
    // normalize the histogram data
    //
    if (hist_normalize_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error normalizing the data");
      return ISIP_FALSE;
    }
  }

  if ((sel_vec_d[30] == 1) || (sel_vec_d[31] == 1)) {

    // initialize the edge data
    //
    if (edge_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error normalizing the data");
      return ISIP_FALSE;
    }
  
    // compute the edge detection
    //
    if (edge_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
			width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error while computing the edge detection");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_nblks_d += edge_t_nblks_d;
      done_statistics = ISIP_TRUE;
    }
    
    // normalize the edge detected data
    //
    if (edge_normalize_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error normalizing the data");
      return ISIP_FALSE;
    }
  }

  if (sel_vec_d[32] == 1) {

    // initialize the parameters related to the sharpness
    //
    if (dent_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error initializing the sharpness paramaters");
      return ISIP_FALSE;
    }
  
    // compute the sharpness of the image
    //
    if (dent_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
			width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error while computing the sharpness");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += dent_r_npxls_d;
      pca_t_nblks_d += dent_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
    
    // normalizing the data
    //
    if (dent_normalize_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error while normalizing the sharpness");
      return ISIP_FALSE;
    }
  }

  if (sel_vec_d[35] == 1) {

    // initialize the standard deviation parameters
    //
    if (sd_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error intializing the SD parameters");
      return ISIP_FALSE;
    }
  
    // compute the standard deviation of the image
    //
    if (sd_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
		      width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the standard deviation");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += sd_r_npxls_d;
      pca_t_nblks_d += sd_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
    
    // normalize the values
    //
    if (sd_normalize_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error normalizing the values");
      return ISIP_FALSE;
    }
  }

  if (sel_vec_d[38] == 1) {

    // initialize the entropy
    //
    if (ent_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the entropy");
      return ISIP_FALSE;
    }
  
    // compute the entropy of the image
    //
    if (ent_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
		       width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the standard deviation");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += huf_r_npxls_d;
      pca_t_nblks_d += huf_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
  }

  if (sel_vec_d[41] == 1) {
    
    // initializing the run length coding
    //
    if (rle_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the run lenght coding");
      return ISIP_FALSE;
    }
  
    // computing the run length coding
    //
    if (rle_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
		       width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error while computing the run lenght coding");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += rle_r_npxls_d;
      pca_t_nblks_d += rle_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
  }

  if (sel_vec_d[42] == 1) {

    // initialising the fractal dimensions
    //
    if (fract_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the fractal dimension");
      return ISIP_FALSE;
    }
  
    // computing the fractal dimension
    //
    if (fract_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
			 width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing the fractal dimension");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += fract_r_npxls_d;
      pca_t_nblks_d += fract_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
  }

  if (sel_vec_d[65] == 1 || sel_vec_d[97] == 1 || sel_vec_d[129] == 1) {
    
    // initializing the dct transformation
    //
    if (dct_init_cc() == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error initializing the dct transformation");
      return ISIP_FALSE;
    }
  
    // computing the dct transformation
    //
    if (dct_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
		       width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing dct transformation");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += dct_r_npxls_d;
      pca_t_nblks_d += dct_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
  }

  if (sel_vec_d[161] == 1) {
    
    // initializing Gabor filtering
    //
    if (gabor_init_cc(width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error initializing the Gabor filtering");
      return ISIP_FALSE;
    }
  
    // computing the Gabor features
    //
    if (gabor_compute_cc(blk_r_a, blk_g_a, blk_b_a, offset_w_a, offset_h_a,
		         width_a, height_a) == ISIP_FALSE) {
      error_handler_cc((char_1*)"pca_train_cc",
		       (char_1*)"error computing gabor features");
      return ISIP_FALSE;
    }

    // updating the statistics
    //
    if (done_statistics == ISIP_FALSE) {
      pca_t_npxls_d += gabor_r_npxls_d;
      pca_t_nblks_d += gabor_r_nblks_d;
      done_statistics = ISIP_TRUE;
    }
  }
  
  // reading the values into the feature vector
  //
  for (int_4 i=0; i<pca_t_num_vectors_d; i++) {

    if (sel_vec_d[i] == 1) {
    
      // reading the red values
      //
      if (i < 10) {
	pca_t_data_d[k] = hist_t_rpdf_d[i];
	k++;
      }
      
      // reading the green values
      //
      if ((i >= 10) && (i < 20)) {
      	pca_t_data_d[k] = hist_t_gpdf_d[i - 10];
	k++;
      }
      
      // reading the blue values
      //
      if ((i >= 20) && (i < 30)) {
	pca_t_data_d[k] = hist_t_bpdf_d[i - 20];
	k++;
      }

      // reading the short and long lines
      //
      if (i == 30) {
	pca_t_data_d[k] = edge_perlong_t_lines_d;
	k++;
      }
      
      if (i == 31) {
	pca_t_data_d[k] = edge_pershrt_t_lines_d;
	k++;
      }

      // reading the sharpness values
      //
      if (i == 32) {
	pca_t_data_d[k] = dent_t_sumred_d;
	k++;
      }
      
      if (i == 33) {
	pca_t_data_d[k] = dent_t_sumgrn_d;
	k++;
      }
      
      if (i == 34) {
	pca_t_data_d[k] = dent_t_sumblu_d;
	k++;
      }
      
      // reading the standard deviaiton values
      //
      if (i == 35) {
	pca_t_data_d[k] = sd_t_red_d;
	k++;
      }
      
      if (i == 36) {
	pca_t_data_d[k] = sd_t_grn_d;
	k++;
      }
      
      if (i == 37) {
	pca_t_data_d[k] = sd_t_blu_d;
	k++;
      }
      
      // reading the entropy values
      //
      if (i == 38) {
	pca_t_data_d[k] = huf_t_red_d;
	k++;
      }

      if (i == 39) {
	pca_t_data_d[k] = huf_t_grn_d;
	k++;
      }

      if (i == 40) {
	pca_t_data_d[k] = huf_t_blu_d;
	k++;
      }

      // reading the compression ratio
      //
      if (i == 41) {
	pca_t_data_d[k] = rle_t_compression_d;
	k++;
      }

      // reading the fractal dimension
      //
      if (i == 42) {
	pca_t_data_d[k] = fract_t_dimred_d;
	k++;
      }
      
      if (i == 43) {
	pca_t_data_d[k] = fract_t_dimgrn_d;
	k++;
      }
      
      if (i == 44) {
	pca_t_data_d[k] = fract_t_dimblu_d;
	k++;
      }
      
      // reading the yellow values
      //
      if ((i >= 45) && (i < 55)) {
      	pca_t_data_d[k] = hist_t_ylwpdf_d[i - 45];
	k++;
      }
      
      // reading the brown values
      //
      if ((i >= 55) && (i < 65)) {
      	pca_t_data_d[k] = hist_t_brnpdf_d[i - 55];
	k++;
      }

      // reading the dct features for red color
      //
      if ((i >= 65) && (i < 97)) {
	pca_t_data_d[k] = dct_t_red_filter_d[i - 65];
	k++;
      }

      // reading the dct features for green color
      //
      if ((i >= 97) && (i < 129)) {
	pca_t_data_d[k] = dct_t_grn_filter_d[i - 97];
	k++;
      }

      // reading the dct features for blue color
      //
      if ((i >= 129) && (i < 161)) {
	pca_t_data_d[k] = dct_t_blu_filter_d[i - 129];
	k++;
      }      

      // reading the gabor features
      //
      if ((i >= 161) && (i < 181)) {
	pca_t_data_d[k] = gabor_feature_d[i - 161];
	k++;
      }      
    }
  }

  // updating the covariance matrix with image
  //
  if (pca_covar_cc() == ISIP_FALSE) {
    error_handler_cc((char_1*)"pca_train_cc",
		     (char_1*)"error computing the covariance matrix");
    return ISIP_FALSE;
  }

  for (int_4 i=0; i<pca_t_values_read_d; i++) {
    fprintf(stdout, "%f ", pca_t_data_d[i]);
  }
  fprintf(stdout, "\n");
  
  // debugging information
  //
  if (debug_level_d > ISIP_DEBUG_DETAILED) {
    
    // printing the  feature vector information
    //
    fprintf(stdout, "<Image_analysis::pca_train_cc>\n");
    fprintf(stdout, "\n feature vector of the image block\n");
    
    for (int_4 i=0; i < pca_t_values_read_d; i++) {
      fprintf(stdout, "%ld\t%f\n", i, pca_t_data_d[i]);
    }
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
