/*
  stats_o0-s16.c
  histogramme d'un fichier d'entiers signés
          et calcul de l'entropie

  création : Mon Sep 15 05:23:51 CEST 2003
    par whygee@f-cpu.org

  compilation :
    gcc -W -Wall -lm -o stats_o0-s16 stats_o0-s16.c
*/

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

#define MAX_X 800

unsigned long int histogramme[512];

int main(int argc, char *argv[]) {
  FILE *file_in;
  FILE *file_out;
  signed short int s16;
  unsigned long int taille=0, i, j, max=0, imax=0;
  unsigned long long int lli;
  double total_entropie=0.0, entropie, proba;

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

        /* collecte de l'histogramme */
        while (fread(&s16,1,2,file_in) == 2) {
          histogramme[(s16>>7)+256]++;
          taille++;
        }

        if (taille > 0) {
          /* recherche du maximum */
          for (i=0; i<512; i++) {
            if (histogramme[i]>max) {
              max=histogramme[i];
              imax=i;
            }

            /* calcul de l'entropie */
            if (histogramme[i] > 0) {
              proba=histogramme[i];
              proba/=taille;
              entropie=proba*-log(proba)/M_LN2;
              total_entropie+=entropie;
              printf("histogramme[%ld]=%ld,      entropie=%G\n",
                i,histogramme[i],entropie);
            }
          }

          /* écriture du résultat */
          for (i=0; i<512; i++) {
            lli=histogramme[i];
            lli*=MAX_X;
            lli=lli/max;
            for (j=0; j<lli; j++)
              fputc(15 ,file_out);
            /* remplissage en fin de la ligne */
            for (; j<MAX_X; j++)
              fputc(1 ,file_out);
          }
          printf("max : histogramme[%ld]=%ld\n",imax,max);
          printf("entropie = %G\n",total_entropie);
        }
      }
    }
  }
  exit(EXIT_SUCCESS);
}
