/*
             CREATOR: DAn williams
                DATE: dec 17 2000
         DESCRIPTION: find the luminessance peak in the image
            FILENAME: findpeak.c
             STARTED: see date
    OPERATING SYSTEM: Linux
1st VERSION FINISHED: dec 18 02000

*/

#include <sys/types.h>
#include "tga_read.h"
#include "findpeak.h"
#include <malloc.h> //malloc

/*********************************************
 return the "intensity" of a colour
 This should really look for only red intensity,
  as per laser
 
 IN: 
  - RGBStruct24 colour
 OUT:
  - integer representing the intensity. if it 
    returns -1, there is no definite peak
*********************************************/
u_int8_t intensity(RGBStruct24 colour) {
  return ((long)colour.Red + (long)colour.Blue + (long) colour.Green)/3;
}



/*********************************************
 find the "brightest" point on the line
 IN:
  - structure for a tga image
  - which line to check
 OUT:
  - returns a positive number representing the
     position of the peak intensity pixel
  - if nothing found returns -1 (black line)
  - memory problems return -2
*********************************************/
int32_t scanline(TgaStruct* Image, u_int16_t Line) {

  u_int16_t   scanPosition;
  int32_t     peakStart, peakEnd;
  u_int8_t    peakIntensity, currIntensity;
  u_int8_t    *arrayData;
  long        averageIntensity;

  peakStart        = -1;
  peakEnd          = -1;
  peakIntensity    = 0;
  averageIntensity = 0;


  // allocate some memory for our intensity data
  if ((arrayData = (u_int8_t *)malloc(sizeof(u_int8_t)*(Image->Width+1))) == NULL) {
    return -2; // didn't work
  }  

  // scan the line into memory so we can do faster work on it
  for (scanPosition = 0; scanPosition < Image->Width; scanPosition++) {
    arrayData[scanPosition] =  intensity(get_tga_pixel(Image, scanPosition, Line));
    averageIntensity        += arrayData[scanPosition];
  } 

  averageIntensity /= Image->Width;
  //!!!???!!! hardcoded miniumum of 20% contrast
  // the +2 covers lines that consist of just one colour
  //peakIntensity    =  (averageIntensity + 2) * 2; // preset a 'noise' level.
  peakIntensity = 75;
  
  //printf("Av: %d Pk: %d\n", averageIntensity, peakIntensity);
  
  // scan for the peak value
  for (scanPosition = 0; scanPosition < Image->Width; scanPosition++) {

    if (arrayData[scanPosition] > (peakIntensity  )) {    
      peakIntensity = arrayData[scanPosition]; // new peak level
      peakStart     = scanPosition;            // set the start of a peak
      peakEnd       = scanPosition;            // reset the end of a peak
    }
    
    // track wide peaks
    if (arrayData[scanPosition] == peakIntensity) {
      peakEnd = scanPosition;
    }
   
    
  } 

  free(arrayData);
  // peak is in the middle of the peak, of course
  return (peakStart+peakEnd)/2;
  
}
