/*--------------------------------------------------------------------------*\
        FICHIER sequence.c
        
        
        
        auteur       : Rene Mathurin
        derniere MAJ :   

         gcc sequence.c /home/h1/labo/uei/mathurin/Radar/Source/OF/horn.c utilFicCal.c bresenham.c /home/h1/labo/uei/mathurin/Radar/Source/OF/gradient.c /home/h1/labo/uei/mathurin/Radar/Source/OF/derive.c -lm

\*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>

 
#include "erreur.h"

#include "local_def.h"
#undef  round(x) 
#define round(x)        ((int) ((x) + ((x >= 0)? 0.5: -0.5)))

/*********** Jean  ***********************************************/
void bgradient( byte ima1[256][256],byte ima2[256][256],byte ima3[256][256], float gradx[256][256] ,float grady[256][256] , float gradt[256][256])
{ register i,j;
 float normalis;
  int tmp[256][256];
normalis= 1./43.8;
 for(i=3;i<253;i++)
   {
    for(j=3;j<253;j++)
      {
        
       grady[i][j]=normalis* (5.0*ima2[i+1][j]+
       3.5*ima2[i+1][j+1]+3.5*ima2[i+1][j-1]-
       5.0*ima2[i-1][j]-
       3.5*ima2[i-1][j+1]-3.5*ima2[i-1][j-1] + 4.2*ima2[i+2][j] + 
       1.6*ima2[i+2][j+1] + 1.6*ima2[i+2][j-1]+ima2[i+1][j+2]+ima2[i+1][j-2] - 
       4.2*ima2[i-2][j] - 
       1.6*ima2[i-2][j+1] -1.6*ima2[i-2][j-1] -ima2[i-1][j+2] - ima2[i-1][j-2]);
       
       gradx[i][j]=normalis*(5.0*ima2[i][j+1]+
       3.5*ima2[i+1][j+1]+3.5*ima2[i-1][j+1]-
       5.0*ima2[i][j-1]-
       3.5*ima2[i+1][j-1]-3.5*ima2[i-1][j-1] + 4.2*ima2[i][j+2] + 
       1.6*ima2[i+1][j+2] + ima2[i+2][j+1]+1.6*ima2[i-1][j+2] +ima2[i-2][j+1] - 
       4.2*ima2[i][j-2] - 
       1.6*ima2[i+1][j-2] - ima2[i+2][j-1]-1.6*ima2[i-1][j-2]-ima2[i-2][j-1]);
       
    /*  tmp[i][j] = (float)(ima2[i][j]-ima1[i][j]);   */
     gradt[i][j]= (float)(ima2[i][j]-ima1[i][j]);  
     
     }
   }
   /*
  for(i=3;i<253;i++){
    for(j=3;j<253;j++){
       gradt[i][j] = (tmp[i][j]+tmp[i-1][j]+tmp[i+1][j]+tmp[i][j+1]+tmp[i][j-1])/5.    ;
      }
   }
   */
   


} 
void printhour(HEAD *header){
     (void) fprintf(stdout, "\nÉvènement du %c%c.%c%c.19%c%c à %c%ch%c%c",
          header->date[0], header->date[1],    /* jours   */
          header->date[2], header->date[3],    /* mois    */
          header->date[4], header->date[5],    /* annees  */
          header->hour[0], header->hour[1],    /* heures  */
          header->hour[2], header->hour[3]      /* minutes */ );         }

#ifdef NeedFunctionPrototype 
int main(int argc, char *argv[]) 
#else
int main(argc, argv) 
int argc;
char **argv;
#endif

{
extern char    *optarg;
  int             c;

  /* variables pour manipuler les fichiers Calamar */
  FILE *fp ;
  char *nomIm ;
  char heure[20] ;
  int  nbreImages ;
  /* déclaration des images            *\
  \* le type byte est un unsigned char */
  
  byte *tmp ;
#define FACT_ECHELLE 6.
#define PAS 8
 
  HEAD *header;
  byte *Im1, *Im2, *Im3, *Imx, *Imy ; 
  char nomSequence[30];
  double  df=0.0;
  int x2, y2;
  double a, b, lg;
  float uu, vv;
 int n=0;
  float alpha;
  int iter;
  register j,  i , k, l;
  float vx, vy;
  register x, y ;
  extern void get_next (byte * , FILE *, HEAD * ) ;
  extern void get_hour (FILE *, HEAD *) ;
  extern void calc_u_v(float *,float *,float *,float *,float *,double *, float);
  extern void   moy_locale  (float *, float *, float *, float *);
  int rejete ;
  float *Ex, *Ey, *Et;
  float *u, *v,*uf, *vf, *u_, *v_;
  iter = 2;
   alpha = 1;
     
    
    /* permet de passer des arguments à  la ligne de commande */
    while ((c = getopt(argc, argv, "i:")) != EOF){
    switch (c) {
    case '?': erreur(USAGE); exit(-1);
    case 'i': (void) strcpy(nomSequence, optarg); break;
       default :  exit(0);
      }
    }
     
     /* allocation dynamique des images */
    if ( (( tmp = (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)   ||
          (( Im1 = (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)   ||
          (( Im2 = (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)   ||
          (( Imx = (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)   ||
          (( Imy = (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)   ||
          (( Im3= (byte *)calloc(IMAGE_SIZE, sizeof(byte))) == NIL)){
      perror(MEMORYPB);
      exit(ERREUR);
    }
    if ( (( header = (HEAD *)calloc(1, sizeof(HEAD))) == (HEAD *)0)) {
      perror(MEMORYPB);
      exit(ERREUR);
    }
    if(((Ex=(float *)calloc((size_t)IMAGE_SIZE,sizeof(float))) == (float *)0)
|| ((Ey=(float *)calloc((size_t)IMAGE_SIZE,sizeof(float))) == (float *)0)
|| ((Et=(float *)calloc((size_t)IMAGE_SIZE,sizeof(float))) == (float *)0)
|| ((u=(float *)calloc((size_t)IMAGE_SIZE, sizeof(float))) == (float *)0)
|| ((v=(float *)calloc((size_t) IMAGE_SIZE, sizeof(float))) == (float *)0)
|| ((uf=(float *)calloc((size_t)IMAGE_SIZE, sizeof(float))) == (float *)0)
|| ((vf=(float *)calloc((size_t) IMAGE_SIZE, sizeof(float))) == (float *)0)) {
  perror(MEMORYPB);
  exit(ERREUR);
}    
#define MANUAL 1
#ifdef MANUAL    
    (void) fprintf (stdout, "\n Heure de début de séquence (ex : 173500) : ");
    (void) scanf ("%s", heure);
#else    
    (void) sprintf (heure,"175500");
#endif

     /* Ouverture du fichier Calamar */
   if ((fp = fopen(nomSequence, "r")) == (FILE *) 0) {
     printf("%s:",nomSequence );
    perror(LECTUREPB);
       exit(0);
   }  
   
   do {
     get_hour ( fp, header ) ;
     printhour( header ) ;
     get_next (Im1 , fp, header ) ;
     (void) memtopbm("toto.pbm", Im1); 
     
     get_hour ( fp, header ) ;
     printhour( header ) ;
     get_next (Im2 , fp, header ) ;
     
     get_hour ( fp, header ) ;
     printhour( header ) ;
     get_next (Im3 , fp, header ) ;
     
     bgradient(Im1 , Im2 , Im3 , Ex, Ey, Et);

     if (fseek(fp, -67112L, 1) == ERREUR) {
       erreur("début de fichier : retour arrière impossible");
      (void) rewind(fp);
     }
    
     i = 1;
    (void)fprintf(stdout, "\n Itération : ");
    do {
      (void)fprintf(stdout, ".");
      (void)fflush(stdout);     
       calc_u_v (Ex, Ey, Et, u, v, &df, 1.); 
    } while (  i++ < 50);
     
     
     for (rejete=0, j =1 ; j < 253 ; j ++) {
      for (i = 1 ; i < 253;  i ++) { 
       if( I(u, i,j)> 10E-3 || I(v, i,j)> 10E-3) {
         if(I(u, i+1,j)<10E-3 &&I(u,i+1,j+1)<10E-3 && I(u,i+1,j-1)<10E-3 && 
           I(u, i-1,j)<10E-3 &&I(u,i-1,j+1)<10E-3 && I(u,i-1,j-1)<10E-3 &&
           I(u, i,j+1)<10E-3 &&I(u,i,j-1)<10E-3) {
               I(uf, i,j) = 0.0 ;      
               I(vf, i,j) = 0.0 ;      
               rejete++;         
         } else {
               I(uf, i,j) = I(u, i,j) ;      
               I(vf, i,j) = I(v, i,j);      
         }
       }
      }
     }
   printf("\n %d vecteur%c rejete%c", rejete,rejete>1?'s':' ',rejete>1?'s':' ');
    for (j =1 ; j < 253 ; j ++) {
      for (i = 1 ; i < 253;  i ++) {
          I(Imy, i, j) = I(Im1, i, j) ;
      }
   }           
      
   for (j =1 ; j < 253 ; j ++) {
      for (i = 1 ; i < 253;  i ++) { 
         /* points a gradient temporel nul */
         if(I(Et,i, j) == 0.0)              
               I(Imx,i, j) =I(Im1,i, j) ;
         
         if( I(u, i, j) > 0.01 || I(v, i, j)> 0.01) {
             x2 = i + round(I(u, i, j));
             y2 = j + round(I(v, i, j));
           
            if ( IsinFrame(x2, y2) ) 
              if(I(Im1,i, j) )
                 I(Imx,x2, y2) =I(Im1,i, j) ;
              
        }
      } 
           

  }
    
    /* Representation du champ de vitesse par des fleches */
    for (j =1 ; j < 253 ; j +=4) {
       for (i = 1 ; i < 253;  i +=4) { 
          if( I(u, i, j) > 10E-3 || I(v, i, j)> 10E-3) {
             x2 = i + round(I(u, i, j));
             y2 = j + round(I(v, i, j));
             if ( IsinFrame(x2, y2) ) {
              (void) s_arrow(i, j, x2, y2,10, Im1);  
              }  
          }
       }
    }  
       /* Representation du champ de vitesse par des fleches */
    for (j =1 ; j < 253 ; j +=4) {
       for (i = 1 ; i < 253;  i +=4) { 
          if( I(u, i, j) > 10E-3 || I(v, i, j)> 10E-3) {
             x2 = i + round(I(uf, i, j));
             y2 = j + round(I(vf, i, j));
             if ( IsinFrame(x2, y2) ) {
              (void) s_arrow(i, j, x2, y2,100, Imy);  
             }  
          }
       }
    }     
        
   } while(n++ < 0);
   /* ************ */
          sortie("flot.pbm", Im1);  
          sortie("flot_filtre.pbm", Imy);  
          sortie("prevu.pbm", Imx);         


  }
  
  
  int sortie ( char *name, byte *buffer) 
 {
FILE *fpr;
register i;
 
 char * forXv = (char *)calloc( 100, sizeof(char));
 
 
  if ((fpr = fopen(name, "w")) == (FILE *) 0) {    
    perror("ouverture pb");
    return 0;
  }
  /* Ecriture de l'entete pbm */
  (void)fprintf(fpr, "P5\n%d %d\n255",X_SIZE, Y_SIZE);
    
   for(i=0;i<IMAGE_SIZE; i++) {
     if( *(buffer + i)) (void)fprintf(fpr, "%c", 128 - *(buffer + i));
     else (void)fprintf(fpr, "%c", (byte)255);
    }
   
  (void) sprintf(forXv, "xv %s &", name);
  (void) fprintf(stdout,"\n xv resultat\n");
  (void) system(forXv);    
  
  (void) fclose(fpr);

  
 return 1;
}


