00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00068 
00069 
00070 
00071 
00072 #include <stdlib.h>
00073 #include <tiffio.h>
00074 #include "io_tiff_routine.h"
00075 #include <time.h>
00076 #include <math.h>
00077 
00078 
00079 
00080 
00081 
00082 
00084 #define FATAL(MSG)\
00085         do {\
00086           fprintf(stderr, MSG "\n");\
00087         abort();\
00088         } while (0);
00089 
00091 #define INFO(MSG)\
00092     do {\
00093         fprintf(stderr, MSG "\n");\
00094     } while (0);
00095 
00097 #define DEBUG(MSG)\
00098     do {\
00099         if (debug_flag)\
00100             fprintf(stderr, __FILE__ ":%03i " MSG "\n", __LINE__);\
00101     } while (0);
00102 
00103 
00104 
00105 
00106 
00107 
00138 static void heat (float *ptr_out, float *ptr_in, size_t n_col, int i, 
00139                   int i_prev, int i_next, int j, int j_prev, int j_next, 
00140                   float dt)
00141 {
00142     float laplacian;
00143     laplacian = -4.0 * (*(ptr_in + i*n_col + j)) +
00144                 *(ptr_in + i_prev*n_col + j) + *(ptr_in + i*n_col + j_prev) +
00145                 *(ptr_in + i*n_col + j_next) + *(ptr_in + i_next*n_col + j);
00146 
00147     *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + 0.5 * dt * laplacian;
00148 }
00149 
00150 
00151 
00152 
00153 
00281 static void mcm(float *ptr_out, float *ptr_in, size_t n_row, size_t n_col,
00282                 float dt, float t_g)
00283 {
00284     unsigned int  i, j, i_next, i_prev, j_next, j_prev;
00285     float         grad, s_x, s_y, lambda0, lambda1, lambda2, lambda3, lambda4;
00286 
00287     
00288     for (i=0; i<n_row; i++ )  {
00289 
00290         
00291         i_next = (i<n_row-1?i+1:i);
00292         i_prev = (i>0?i-1:i);
00293 
00294         for (j=0; j<n_col; j++)  {
00295 
00296             
00297             j_next = (j<n_col-1?j+1:j);
00298             j_prev = (j>0?j-1:j);
00299 
00300             
00301             s_x= 2 * ( *(ptr_in+i*n_col+j_next) - *(ptr_in+i*n_col+j_prev) ) +
00302                 *(ptr_in+i_prev*n_col+j_next) - *(ptr_in+i_prev*n_col+j_prev) +
00303                  *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_next*n_col+j_prev);
00304             s_y= 2 * ( *(ptr_in+i_next*n_col+j) - *(ptr_in+i_prev*n_col+j) ) +
00305                 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_prev*n_col+j_next) +
00306                 *(ptr_in+i_next*n_col+j_prev) - *(ptr_in+i_prev*n_col+j_prev);
00307             grad = 0.125 * sqrt( (s_x*s_x) + (s_y*s_y) );
00308 
00309             if (grad>t_g) {
00310                 
00311                 grad*=8;   
00312                 lambda0 = 0.5 - ( (s_x*s_x*s_y*s_y) / ( pow(grad,4) ) );
00313                 lambda1= 2 * lambda0 - ( (s_x*s_x) / (grad*grad) );
00314                 lambda2= 2 * lambda0 - ( (s_y*s_y) / (grad*grad) );
00315                 lambda3= -lambda0 + 0.5 * ( 1 - ( (s_x*s_y)/(grad*grad) ) );
00316                 lambda4= -lambda0 + 0.5 * ( 1 + ( (s_x*s_y)/(grad*grad) ) );
00317 
00318                 *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + dt * (
00319                                          -4 * lambda0 * (*(ptr_in+i*n_col+j)) +
00320                                          lambda1 * (*(ptr_in+i*n_col+j_next)  +
00321                                                     *(ptr_in+i*n_col+j_prev)) +
00322                                          lambda2 * (*(ptr_in+i_next*n_col+j)  +
00323                                                     *(ptr_in+i_prev*n_col+j)) +
00324                                          lambda3 * (*(ptr_in+i_prev*n_col
00325                                                                      +j_prev) +
00326                                                     *(ptr_in+i_next*n_col
00327                                                                      +j_next))+
00328                                          lambda4 * (*(ptr_in+i_prev*n_col
00329                                                                      +j_next) +
00330                                                     *(ptr_in+i_next*n_col
00331                                                                     +j_prev)));
00332             }
00333 
00334             else
00335                 
00336                 heat (ptr_out, ptr_in, n_col, i, i_prev, i_next, 
00337                       j, j_prev, j_next, dt);
00338         }
00339     }
00340 }
00341 
00342 
00343 
00344 
00345 
00346 
00357 int main(int argc, char *argv[])
00358 
00359 {
00360     float        *data_in;                    
00361     float           *ptr_in_rgb[3];
00362     float        *data_out;                   
00363     float           *ptr_out_rgb[3];
00364     size_t       n_col, n_row;                
00365     size_t       n_channels;                  
00366     float        *ptr_in, *ptr_out, *ptr_end;
00367     int          n_iter=0;                    
00368     float        R;                           
00369     float        t_g=4;                       
00370     float        dt=0.1;                      
00371     float        n_iter_f;                    
00372     unsigned int k;
00373     int          m;
00374     clock_t      t0, t1;
00375 
00376     
00377 
00378 
00379 
00380 
00381     if (4!=argc)
00382         FATAL("Error in the number of arguments!\n");
00383     if (0==sscanf(argv[1],"%f", &R))
00384         FATAL("The third argument must be a float!\n");
00385 
00386     
00387     if (0 > R) {
00388         printf("The normalized scale must be a positive real number!\n");
00389         return 0;
00390     }
00391 
00392     
00393     t0 = clock();
00394 
00395     
00396     n_iter_f= (R * R) / (2 * dt);
00397 
00398     
00399     n_iter= (int) (n_iter_f+0.5);
00400 
00401     
00402     if (NULL == (data_in = read_tiff_f32(argv[2], 
00403                                          &n_col, &n_row, &n_channels)))
00404         FATAL("error while reading the TIFF image");
00405 
00406     ptr_in_rgb[0] = data_in;
00407     ptr_in_rgb[1] = data_in + n_row * n_col;
00408     ptr_in_rgb[2] = data_in + 2 * n_row * n_col;
00409 
00410     
00411     if (1!=n_channels) {
00412         n_channels = 1;
00413         for (k=0; k<(n_row*n_col-1); k++)
00414             if ((*(ptr_in_rgb[0]+k)!= *(ptr_in_rgb[1]+k))||
00415                 (*(ptr_in_rgb[0]+k)!=*(ptr_in_rgb[2]+k))) {
00416                 n_channels=3;
00417                 break;
00418             }
00419     }
00420 
00421     
00422     if (0>n_iter)
00423         printf("The number of iteration must be a positive number. \n");
00424     
00425     else if (0==n_iter) {
00426         write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00427     } else {
00428         
00429         if (NULL == (data_out = (float *) 
00430                             malloc(n_channels* n_col * n_row * sizeof(float))))
00431             FATAL("allocation error");
00432 
00433         
00434         ptr_out_rgb[0] = data_out;
00435         ptr_out_rgb[1] = data_out +  n_row * n_col;
00436         ptr_out_rgb[2] = data_out + 2 * n_row * n_col;
00437         for (k=0; k<n_channels; k++) {
00438             
00439             ptr_in  = ptr_in_rgb[k];
00440             ptr_out = ptr_out_rgb[k];
00441             ptr_end = ptr_in + n_row*n_col;
00442             for (m=0; m<n_iter; m++)   {
00443                 
00444                 mcm (ptr_out, ptr_in, n_row, n_col, dt, t_g);
00445                 
00446                 while (ptr_in<ptr_end) {
00447                     *ptr_in = *ptr_out;
00448                     ptr_in++;
00449                     ptr_out++;
00450                 }
00451                 ptr_in=ptr_in_rgb[k];
00452                 ptr_out=ptr_out_rgb[k];
00453             }
00454             
00455             while (ptr_in<ptr_end) {
00456                 if (*ptr_in>255) *ptr_in=255;
00457                 if (*ptr_in<0) *ptr_in=0;
00458                 ptr_in++;
00459             }
00460         }
00461         
00462         write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00463         
00464         free(data_out);
00465     }
00466 
00467     
00468     t1 = clock();
00469     
00470     printf("CPU time consumed = %f seconds\n", 
00471            (double)(t1-t0)/(double)CLOCKS_PER_SEC);
00472     
00473     free(data_in);
00474     return 0;
00475 }