Page principale   Liste par ordre alphabétique   Liste des composants   Liste des fichiers   Composants   Déclarations   Pages associées  

inricache.c

Aller à la documentation de ce fichier.
00001 
00012 #include "inricache.h"
00013 #include "utils.h"
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <time.h>
00017 /* on a besoin des valeurs limites pour les differents types supportes, en fonction de la machine. */
00018 #include <limits.h>
00019 #include <float.h>
00020 
00021 extern void imerror ( int code, char * format, ...);
00022 
00023 /* dans le cache on a toujours des plans consecutifs */
00024 struct inricache_
00025 {
00026   int cache_size;
00027   Fort_int lfmt[9];
00028   struct image * img; 
00029   char ** cache; 
00030   int plan_min; 
00031   int debut; 
00032 };
00033 
00041 void chargePlan(inricache * iCache,int numplan);
00042 
00043 /****************************/
00044 /* createur et destructeur  */
00045 /****************************/
00046 
00047 inricache * cree_inricache(char * nom_image,char * mode,char * verif,struct nf_fmt * gfmt,int taille_cache)
00048 {
00049   register int i;
00050   register int buff_size;
00051   //register int buff_len;
00052   char * tmpbuff;
00053   inricache * retour = (inricache *)malloc(sizeof(inricache));
00054 
00055   retour->cache_size=taille_cache;
00056   retour->plan_min=0;
00057   retour->debut=0;
00058   retour->img=image_(nom_image,mode,verif,gfmt);
00059   
00060   if (taille_cache>gfmt->lfmt[I_NDIMZ])
00061     {
00062       fprintf(stderr,"cree_inricache: %s sur %i plans, cache demande trop grand (%i),ajuste au nombre de plans de l'image.\n",nom_image,gfmt->lfmt[I_NDIMZ],taille_cache);
00063       retour->cache_size=gfmt->lfmt[I_NDIMZ];
00064     }
00065 
00066   for (i=0;i<9;i++)
00067     {
00068       retour->lfmt[i]=gfmt->lfmt[i];
00069     }
00070   buff_size = buffer_size(retour->lfmt,retour->lfmt[I_NDIMY]);
00071   //buff_len = buff_size/sizeof(char);
00072   retour->cache = (char **)malloc(retour->cache_size*sizeof(char *));
00073   tmpbuff = i_malloc(buff_size);
00074 
00075   if (mode[0]=='c')
00076     {
00077       //for (i=0;i<buff_len;i++)
00078       //tmpbuff[i]=0;
00079       for (i=0;i<retour->lfmt[I_NDIMZ];i++)
00080          c_pecr(retour->img,gfmt->lfmt[I_NDIMY],tmpbuff,1+i*gfmt->lfmt[I_NDIMY],0);
00081     }
00082 
00083   for (i=0;i<retour->cache_size;i++)
00084     {      
00085       retour->cache[i] = i_malloc(buff_size);
00086       c_plect(retour->img,gfmt->lfmt[I_NDIMY],retour->cache[i],1+i*gfmt->lfmt[I_NDIMY],0);
00087     }
00088   i_Free(&tmpbuff);
00089   return retour;
00090 }
00091 
00092 void libere_inricache(inricache * iCache)
00093 {
00094   register int i,n_dimy = iCache->lfmt[I_NDIMY];
00095 
00096   for (i=0;i<iCache->cache_size;i++)
00097     {
00098       register int indice = (iCache->debut + i)% iCache->cache_size;
00099       /* pour chaque plan charge en cache: ecriture + suppression */
00100       c_pecr(iCache->img,n_dimy,iCache->cache[indice],1+(i + iCache->plan_min)*n_dimy,0);
00101       i_Free(&(iCache->cache[indice]));
00102     }
00103   /* fermeture de l'image utilisee pour le cache */
00104   fermnf_(&(iCache->img));
00105 
00106   free(iCache->cache);
00107   free(iCache);
00108 }
00109 
00110 double getValue(inricache * iCache,int x,int y,int z)
00111 {
00112   /* chargement du plan si necessaire --> mise a jour du cache */
00113   chargePlan(iCache,z);
00114 
00115   /* z - plan_min = numero de la page de cache si le cache partait de l'indice zero */
00116   /* (z - plan_min + debut) % cache_size = indice de la page du cache correspondant au plan z */
00117 
00118   switch (iCache->lfmt[I_BSIZE])
00119     {
00120     case 1: /* on a des char */
00121       return (double) (iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size][y*iCache->lfmt[I_NDIMX] + x]);
00122       break;
00123     case 2: /* on a des short int */
00124       return (double) ( ((short int *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x]);
00125       break;
00126     case 4:
00127       if (iCache->lfmt[I_TYPE]==1) /* on a des flottants */
00128          return (double) (((float *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x]);
00129       else /* on a des int */
00130          return (double) ( ((int *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x]); 
00131       break;
00132     case 8:
00133       return ((double *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x];
00134       break;
00135     default:
00136       fprintf(stderr,"%s: (%d,%d,%d) non reconnu\n",iCache->img->nom,x,y,z);
00137       return 0;
00138       break;
00139     }
00140 }
00141 
00142 void setValue(inricache * iCache,int x,int y,int z,double valeur)
00143 {
00144   /* chargement du plan si necessaire --> mise a jour du cache */
00145   chargePlan(iCache,z);
00146   switch (iCache->lfmt[I_BSIZE])
00147     {
00148     case 1: /* on a des char */
00149       iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size][y*iCache->lfmt[I_NDIMX] + x] = (char)valeur;
00150       break;
00151     case 2: /* on a des short int */
00152       ((short int *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x] = (short int)valeur;
00153       break;
00154     case 4:
00155       if (iCache->lfmt[I_TYPE]==1) /* on a des flottants */
00156          ((float *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x] = (float)valeur;
00157       else /* on a des int */
00158          ((int *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x] = (int) valeur; 
00159       break;
00160     case 8:
00161       ((double *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x] = valeur;
00162       break;
00163     }
00164 }
00165 
00166 void copie_inricache(inricache *src,inricache *dest)
00167 {
00168   register int x,y,z;
00169   for (z=0;z<src->lfmt[I_NDIMZ];z++)
00170     for (y=0;y<src->lfmt[I_NDIMY];y++)
00171       for (x=0;x<src->lfmt[I_NDIMX];x++)
00172          setValue(dest,x,y,z,getValue(src,x,y,z));
00173 }
00174 
00175 /*********************/
00176 /* fonctions locales */
00177 /*********************/
00178 
00179 void chargePlan(inricache * iCache,int numplan)
00180 {
00181   register int plan_min=iCache->plan_min;
00182   register int taille_cache=iCache->cache_size;
00183   register int i=0,n_dimy = iCache->lfmt[I_NDIMY];
00184   register int indice;
00185   register int premier_charge;
00186 
00187   if ((numplan<plan_min) || (numplan >= plan_min + taille_cache))
00188     {
00189       if (numplan == plan_min + taille_cache)  
00190          {
00191            /* charger un plan */
00192            /* on ecrit le plus vieux, on l'incremente, et on remplace */
00193            indice = iCache->debut;
00194            c_pecr(iCache->img,n_dimy,iCache->cache[indice],1+(plan_min)*n_dimy,0);
00195            (iCache->plan_min)++;
00196            iCache->debut=(indice+1) % taille_cache;
00197            c_plect(iCache->img,n_dimy,iCache->cache[indice],1+(numplan)*n_dimy,0);
00198          }
00199       else
00200          {
00201            if (numplan == plan_min-1)
00202              {
00203                /* pour les parcours avant/arriere de l'algorithme de Danielsson, il veut mieux gerer les retours en arriere */
00204                /* charger un plan */
00205                /* on ecrit le plus recent , on decremente le plus vieux plan et on remplace */
00206                indice = (iCache->debut + taille_cache - 1)%taille_cache;
00207                c_pecr(iCache->img,n_dimy,iCache->cache[indice],1+(plan_min-1)*n_dimy,0);
00208                iCache->plan_min=numplan;
00209                iCache->debut=indice;
00210                c_plect(iCache->img,n_dimy,iCache->cache[indice],1+(numplan)*n_dimy,0);
00211              }
00212            else
00213              {
00214                /* on choisit ce min afin de ne pas tenter de charger un plan dont le numero est superieur au nombre de plabs dans l'image */
00215                premier_charge = (int)min(numplan,iCache->lfmt[I_NDIMZ]-taille_cache);
00216                /* charger complementement le cache depuis 0, on revient en arriere */
00217                for (i=0;i<taille_cache;i++)
00218                   {
00219                     indice = (iCache->debut + i)% taille_cache;
00220                     /* pour chaque plan charge en cache: ecriture */
00221                     c_pecr(iCache->img,n_dimy,iCache->cache[indice],1+(i + plan_min)*n_dimy,0);
00222                   }
00223                iCache->plan_min=premier_charge;
00224                iCache->debut=0;
00225                for (i=0;i<taille_cache;i++)
00226                   {
00227                     /* rechargement du cache */
00228                     c_plect(iCache->img,n_dimy,iCache->cache[i],1+(i + premier_charge)*n_dimy,0);
00229                   }
00230              }
00231          }
00232     }
00233 }
00234 
00241 double max_inricache(inricache *iCache)
00242 {
00243   switch (iCache->lfmt[I_BSIZE])
00244     {
00245     case 1: /* on a des char */
00246       return ((double) CHAR_MAX);
00247       break;
00248     case 2: /* on a des short int */
00249       return ((double) SHRT_MAX);
00250       break;
00251     case 4:
00252       if (iCache->lfmt[I_TYPE]==1) /* on a des flottants, ceux-ci doivent etre compris entre -1 et 1 */
00253          //       return ((double) FLT_MAX);
00254          return 1;
00255       else /* on a des int */
00256          return ((double) INT_MAX);
00257       break;
00258     case 8: /* on a un double le comportement est le meme que pour un flottant */
00259       //      return (DBL_MAX);
00260       return 1;
00261       break;
00262     default:
00263       fprintf(stderr,"%s: format non reconnu\n",iCache->img->nom);
00264       return 0;
00265       break;
00266     }
00267 }
00268 
00278 void extrema_inricache(inricache *iCache,double *mini,double *maxi)
00279 {
00280   register int x,y,z,x_max,y_max,z_max;
00281 
00282   x_max = iCache->lfmt[I_NDIMX];
00283   y_max = iCache->lfmt[I_NDIMY];
00284   z_max = iCache->lfmt[I_NDIMZ];
00285   /* on initialise les extrema au premier pixel des caches, quitte a relire ces derniers */
00286   *mini=getValue(iCache,0,0,0);
00287   *maxi=*mini;
00288 
00289   for (z=0;z<z_max;z++)
00290     for (y=0;y<y_max;y++)
00291       for (x=0;x<x_max;x++)
00292          {
00293            *mini=min(*mini,getValue(iCache,x,y,z));
00294            *maxi=max(*maxi,getValue(iCache,x,y,z));
00295          }
00296 }
00297 
00304 char * getName(inricache * iCache)
00305 {
00306   return (iCache->img->nom);
00307 }
00308 
00319 void resize_inricache(inricache *iCache,inricache *dest,int x0,int y0,int z0,int time_flag)
00320 {
00321   clock_t t0=0,t1=0;
00322   double x_pas,y_pas,z_pas;
00323   register int i,j,k,x_max,y_max,z_max;
00324 
00325   /* chronometrage si on le demande */
00326   if (time_flag)
00327     t0 = clock(); 
00328 
00329   /* initialisation des parametres */
00330 
00331   x_max = dest->lfmt[I_NDIMX];
00332   y_max = dest->lfmt[I_NDIMY];
00333   z_max = dest->lfmt[I_NDIMZ];
00334   x_pas = (double)(iCache->lfmt[I_NDIMX]-x0)/x_max;
00335   y_pas = (double)(iCache->lfmt[I_NDIMY]-y0)/y_max;
00336   z_pas = (double)(iCache->lfmt[I_NDIMZ]-z0)/z_max;
00337 
00338   /* sous-echantillonage */
00339 
00340   for (k=0;k<z_max;k++)
00341     for (j=0;j<y_max;j++)
00342       for (i=0;i<x_max;i++)
00343          setValue(dest,i,j,k,getValue(iCache,x0+(int)(i*x_pas),y0+(int)(j*y_pas),z0+(int)(k*z_pas)));
00344 
00345   if (time_flag)
00346     {
00347       t1=clock()-t0;
00348       fprintf(stderr,"resize_inricache: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00349     }
00350 }
00351 
00364 void normalize_inricache(inricache *iCache,inricache *iNormed,double mini,double maxi,int time_flag)
00365 {
00366   clock_t t0=0,t1=0;
00367   register int i,j,k,x_max,y_max,z_max;
00368   double min_calc=0,max_calc=0;
00369   double delta,coeff;
00370 
00371   /* chronometrage si on le demande */
00372   if (time_flag)
00373     t0 = clock();
00374 
00375   /* si jamais les deux inricaches ne sont pas de meme dimension on quitte avec imerror code 6 */
00376   if ((iCache->lfmt[I_NDIMX]!=iNormed->lfmt[I_NDIMX]) ||
00377       (iCache->lfmt[I_NDIMY]!=iNormed->lfmt[I_NDIMY]) ||
00378       (iCache->lfmt[I_NDIMZ]!=iNormed->lfmt[I_NDIMZ]))
00379     imerror(6,"normalize_inricache: dimensions differentes pour les caches source et destination");
00380 
00381   /* initialisation des parametres */
00382   x_max = iCache->lfmt[I_NDIMX];
00383   y_max = iCache->lfmt[I_NDIMY];
00384   z_max = iCache->lfmt[I_NDIMZ];
00385 
00386   extrema_inricache(iCache,&min_calc,&max_calc);
00387   if ((mini<0) || (mini>min_calc)) /* le minimum n'est pas impose */
00388     {
00389       if (mini>min_calc)
00390          fprintf(stderr,"min demande (%f) superieur au min calcule (%f) : [Ignore]\n",mini,min_calc);
00391     }
00392   else
00393     {min_calc=mini;}
00394   
00395   if (maxi<0 || maxi<max_calc) /* le maximum n'est pas impose */
00396     {
00397       if (maxi>0)
00398          fprintf(stderr,"max demande (%f) inferieur au max calcule (%f) : [Ignore]\n",maxi,max_calc);
00399     }
00400   else
00401     {max_calc=maxi;}
00402   
00403   delta=max_calc-min_calc;
00404   if (delta==0)
00405     imerror(9,"normalize_inricache: tentative de normalisation d'une image constante\n");
00406 
00407   /* ce coefficient sert a passer d'un element compris entre 0 et src_max, a un element compris entre 0 et dest_max */
00408   coeff=max_inricache(iNormed)/max_inricache(iCache);
00409 
00410   for (k=0;k<z_max;k++)
00411     for (j=0;j<y_max;j++)
00412       for (i=0;i<x_max;i++)
00413          setValue(iNormed,i,j,k,coeff*(getValue(iCache,i,j,k)-min_calc)/delta);
00414 
00415   if (time_flag)
00416     {
00417       t1=clock()-t0;
00418       fprintf(stderr,"normalize_inricache: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00419     } 
00420 }

Généré le Mon Nov 3 11:50:10 2003 par doxygen1.2.18