00001
00012 #include "inricache.h"
00013 #include "utils.h"
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <time.h>
00017
00018 #include <limits.h>
00019 #include <float.h>
00020
00021 extern void imerror ( int code, char * format, ...);
00022
00023
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
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
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
00072 retour->cache = (char **)malloc(retour->cache_size*sizeof(char *));
00073 tmpbuff = i_malloc(buff_size);
00074
00075 if (mode[0]=='c')
00076 {
00077
00078
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
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
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
00113 chargePlan(iCache,z);
00114
00115
00116
00117
00118 switch (iCache->lfmt[I_BSIZE])
00119 {
00120 case 1:
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:
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)
00128 return (double) (((float *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x]);
00129 else
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
00145 chargePlan(iCache,z);
00146 switch (iCache->lfmt[I_BSIZE])
00147 {
00148 case 1:
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:
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)
00156 ((float *)(iCache->cache[(z-iCache->plan_min + iCache->debut) % iCache->cache_size])) [y*iCache->lfmt[I_NDIMX] + x] = (float)valeur;
00157 else
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
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
00192
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
00204
00205
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
00215 premier_charge = (int)min(numplan,iCache->lfmt[I_NDIMZ]-taille_cache);
00216
00217 for (i=0;i<taille_cache;i++)
00218 {
00219 indice = (iCache->debut + i)% taille_cache;
00220
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
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:
00246 return ((double) CHAR_MAX);
00247 break;
00248 case 2:
00249 return ((double) SHRT_MAX);
00250 break;
00251 case 4:
00252 if (iCache->lfmt[I_TYPE]==1)
00253
00254 return 1;
00255 else
00256 return ((double) INT_MAX);
00257 break;
00258 case 8:
00259
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
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
00326 if (time_flag)
00327 t0 = clock();
00328
00329
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
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
00372 if (time_flag)
00373 t0 = clock();
00374
00375
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
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))
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)
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
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 }