#include <string.h>
#include <math.h>	// for logf
#include <stdio.h>

#include "sonixcam.h"


static float histo_log[256];
static int cut_l=0;
static int cut_r=0;


void SonixCam::Analyze(unsigned char *vals, int histo[256], bool ispost)
{
  int i;
  for (i=0; i<256; i++)
    histo[i]=0;
  for (i=0; i<w*h*3; i++)
  {
    histo[*vals++]++;
  }
  if (ispost)
    return;
  i=0;
  while (!histo[i])
    i++;
  cut_l = i;
  i=255;
  while (!histo[i])
    i--;
  cut_r = i;
}


void SonixCam::AnalyzeSuperimpose
(
  unsigned char *vals, 
  int histo[256], 
  unsigned char rgb[3], 
  int chartheight
)
{
  int i;
  float maxl=0.0;
  for (i=0; i<256; i++)
  {
    histo_log[i] = (histo[i])?logf(histo[i]):0.0;
    if (histo_log[i] > maxl)
      maxl = histo_log[i];
  }
  float step = chartheight / maxl;
  for (i=0; i<256; i++)
  {
    int col = (int) ((i/256.0)*w);
    unsigned char *writer = vals+((h-1)*w+col)*3;
    for (int j=0; j<histo_log[i]*step; j++)
    {
      writer[0]=rgb[0];
      writer[1]=rgb[1];
      writer[2]=rgb[2];
      writer -= w*3;
    }
  }
}


void SonixCam::AnalyzeNormalize(unsigned char *vals, int histo[256])
{
  int rng = 1 + cut_r - cut_l;
  if (rng<10)
    return; // don't bother
  float step = 255.0/rng;
  unsigned char lut [256];
  for (int v=0; v<256; v++)
    lut[v] = (unsigned char) ((v-cut_l)*step);
  for (int i=0; i<w*h*3; i++)
    vals[i] = lut[vals[i]];
}


float SonixCam::AnalyzeGainChange(float speed)
{
  int m = (cut_l + cut_r) / 2;
  return -speed * (m-128);
}


