/*
          stats_o1-s16.c
  histogramme du premier ordre d'un fichier
  d'échantillons stéréo et calcul de l'entropie

  création : Mon Jun 28 08:13:29 CEST 2004
    par whygee@f-cpu.org

  compilation :
    gcc -lm -o stats_o1-s16 stats_o1-s16.c

  invocation :
    ./stats_o1-s16 nom_fichier.raw sortie_image.raw
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifndef NB
#define NB (9)
#endif
#define TAILLE (1 << NB)

unsigned long int histo[TAILLE][TAILLE];

int main(int argc, char *argv[]) {
  FILE *file_in, *file_out;
  signed short int droite, gauche,
    last_droite=TAILLE>>1, last_gauche=TAILLE>>1;
  unsigned long long int taille=0;
  unsigned long int i, j, k, max, min;
  double h=0.0, entropie, proba;

  file_in=fopen(argv[1], "rb");
  if (file_in!=NULL) {
    file_out=fopen(argv[2], "wb");
    if (file_out!=NULL) {

      /* creation de l'histogramme en 2D */
      while (
        ( fread(&gauche, 1, sizeof(gauche), file_in)
        + fread(&droite, 1, sizeof(droite), file_in))
              == (sizeof(gauche) * 2 )) {
        taille++;
        droite=(droite >> (16-NB))+(TAILLE>>1);
        gauche=(gauche >> (16-NB))+(TAILLE>>1);
        histo[last_droite][droite]++;
        histo[last_gauche][gauche]++;
        last_droite=droite;
        last_gauche=gauche;
      }

      min=max=histo[0][0];
      for (i=0; i<TAILLE; i++)
        for (j=0; j<TAILLE; j++) {
          k=histo[i][j];
          /* recherche du maximum et du minimum */
          if (k>max)
            max=k;
          if (k<min)
            min=k;
          /* calcul de l'entropie */
          if (k>0) {
            proba=k;
            proba/=taille;
            entropie=proba*-log(proba)/M_LN2;
            h+=entropie;
            /*  */
            fputc( k        & 255, file_out);
            fputc((k >> 8)  & 255, file_out);
            fputc((k >> 16) & 255, file_out);
          }
          else {
            /* pixel blanc */
            fputc(255, file_out);
            fputc(255, file_out);
            fputc(255, file_out);
          }

        }
      printf("max = %ld\n",max);
      printf("min = %ld\n",min);
      printf("entropie = %G\n",(h/4)+(16-NB));
    }
  }
  exit(EXIT_SUCCESS);
}
