00001
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <tiffio.h>
00041 #include "io_tiff_routine.h"
00042 #include <time.h>
00043 #include <math.h>
00044
00045
00046
00047
00048
00049
00051 #define FATAL(MSG)\
00052 do {\
00053 fprintf(stderr, MSG "\n");\
00054 abort();\
00055 } while (0);
00056
00058 #define INFO(MSG)\
00059 do {\
00060 fprintf(stderr, MSG "\n");\
00061 } while (0);
00062
00064 #define DEBUG(MSG)\
00065 do {\
00066 if (debug_flag)\
00067 fprintf(stderr, __FILE__ ":%03i " MSG "\n", __LINE__);\
00068 } while (0);
00069
00070
00071
00072
00073
00074
00104 static void heat (float *ptr_out, float *ptr_in, size_t n_col, int i, int i_prev, int i_next, int j, int j_prev, int j_next, float dt)
00105
00106 {
00107 float laplacian;
00108 laplacian = -4.0 * (*(ptr_in + i*n_col + j)) +
00109 *(ptr_in + i_prev*n_col + j) + *(ptr_in + i*n_col + j_prev) +
00110 *(ptr_in + i*n_col + j_next) + *(ptr_in + i_next*n_col + j);
00111
00112 *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + 0.5 * dt * laplacian;
00113 }
00114
00115
00116
00117
00118
00239 static void mcm(float *ptr_out, float *ptr_in, size_t n_row, size_t n_col, float dt, float t_g)
00240
00241 {
00242 unsigned int i, j, i_next, i_prev, j_next, j_prev;
00243 float grad, s_x, s_y, lambda0, lambda1, lambda2, lambda3, lambda4;
00244
00245
00246 for (i=0; i<n_row; i++ ) {
00247
00248
00249 i_next = (i<n_row-1?i+1:i);
00250 i_prev = (i>0?i-1:i);
00251
00252 for (j=0; j<n_col; j++) {
00253
00254
00255 j_next = (j<n_col-1?j+1:j);
00256 j_prev = (j>0?j-1:j);
00257
00258
00259 s_x= 2 * ( *(ptr_in+i*n_col+j_next) - *(ptr_in+i*n_col+j_prev) ) +
00260 *(ptr_in+i_prev*n_col+j_next) - *(ptr_in+i_prev*n_col+j_prev) +
00261 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_next*n_col+j_prev);
00262 s_y= 2 * ( *(ptr_in+i_next*n_col+j) - *(ptr_in+i_prev*n_col+j) ) +
00263 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_prev*n_col+j_next) +
00264 *(ptr_in+i_next*n_col+j_prev) - *(ptr_in+i_prev*n_col+j_prev);
00265 grad = 0.125 * sqrt( (s_x*s_x) + (s_y*s_y) );
00266
00267 if (grad>t_g) {
00268
00269 grad*=8;
00270 lambda0 = 0.5 - ( (s_x*s_x*s_y*s_y) / ( pow(grad,4) ) );
00271 lambda1= 2 * lambda0 - ( (s_x*s_x) / (grad*grad) );
00272 lambda2= 2 * lambda0 - ( (s_y*s_y) / (grad*grad) );
00273 lambda3= -lambda0 + 0.5 * ( 1 - ( (s_x*s_y)/(grad*grad) ) );
00274 lambda4= -lambda0 + 0.5 * ( 1 + ( (s_x*s_y)/(grad*grad) ) );
00275
00276 *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + dt * (
00277 -4 * lambda0 * (*(ptr_in+i*n_col+j)) +
00278 lambda1 * (*(ptr_in+i*n_col+j_next) + *(ptr_in+i*n_col+j_prev)) +
00279 lambda2 * (*(ptr_in+i_next*n_col+j) + *(ptr_in+i_prev*n_col+j)) +
00280 lambda3 * (*(ptr_in+i_prev*n_col+j_prev) + *(ptr_in+i_next*n_col+j_next)) +
00281 lambda4 * (*(ptr_in+i_prev*n_col+j_next) + *(ptr_in+i_next*n_col+j_prev)) );
00282 }
00283
00284 else
00285
00286 heat (ptr_out, ptr_in, n_col, i, i_prev, i_next, j, j_prev, j_next, dt);
00287 }
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00305 int main(int argc, char *argv[])
00306
00307 {
00308 float *data_in;
00309 float *ptr_in_rgb[3];
00310 float *data_out;
00311 float *ptr_out_rgb[3];
00312 size_t n_col, n_row;
00313 size_t n_channels;
00314 float *ptr_in, *ptr_out, *ptr_end;
00315 int n_iter=0;
00316 float R;
00317 float t_g=4;
00318 float dt=0.1;
00319 float n_iter_f;
00320 unsigned int k;
00321 int m;
00322 clock_t t0, t1;
00323
00324
00325
00326
00327
00328
00329 if (4!=argc)
00330 FATAL("Error in the number of arguments!\n");
00331 if (0==sscanf(argv[1],"%f", &R))
00332 FATAL("The third argument must be a float!\n");
00333
00334
00335 if (0 > R) {
00336 printf("The normalized scale must be a positive real number!\n");
00337 return 0;
00338 }
00339
00340
00341 t0 = clock();
00342
00343
00344 n_iter_f= (R * R) / (2 * dt);
00345
00346
00347 n_iter= (int) (n_iter_f+0.5);
00348
00349
00350 if (NULL == (data_in = read_tiff_f32(argv[2], &n_col, &n_row, &n_channels)))
00351 FATAL("error while reading the TIFF image");
00352
00353 ptr_in_rgb[0] = data_in;
00354 ptr_in_rgb[1] = data_in + n_row * n_col;
00355 ptr_in_rgb[2] = data_in + 2 * n_row * n_col;
00356
00357
00358 if (1!=n_channels){
00359 n_channels = 1;
00360 for (k=0; k<(n_row*n_col-1); k++)
00361 if((*(ptr_in_rgb[0]+k)!= *(ptr_in_rgb[1]+k))||(*(ptr_in_rgb[0]+k)!=*(ptr_in_rgb[2]+k))){
00362 n_channels=3;
00363 break;
00364 }
00365 }
00366
00367
00368 if (0>n_iter)
00369 printf("The number of iteration must be a positive number. \n");
00370
00371 else if (0==n_iter) {
00372 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00373 }
00374 else {
00375
00376 if (NULL == (data_out = (float *) malloc(n_channels* n_col * n_row * sizeof(float))))
00377 FATAL("allocation error");
00378
00379
00380 ptr_out_rgb[0] = data_out;
00381 ptr_out_rgb[1] = data_out + n_row * n_col;
00382 ptr_out_rgb[2] = data_out + 2 * n_row * n_col;
00383 for (k=0; k<n_channels; k++) {
00384
00385 ptr_in = ptr_in_rgb[k];
00386 ptr_out = ptr_out_rgb[k];
00387 ptr_end = ptr_in + n_row*n_col;
00388 for (m=0; m<n_iter; m++) {
00389
00390 mcm (ptr_out, ptr_in, n_row, n_col, dt, t_g);
00391
00392 while (ptr_in<ptr_end) {
00393 *ptr_in = *ptr_out;
00394 ptr_in++;
00395 ptr_out++;
00396 }
00397 ptr_in=ptr_in_rgb[k];
00398 ptr_out=ptr_out_rgb[k];
00399 }
00400
00401 while (ptr_in<ptr_end) {
00402 if (*ptr_in>255) *ptr_in=255;
00403 if (*ptr_in<0) *ptr_in=0;
00404 ptr_in++;
00405 }
00406 }
00407
00408 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00409
00410 free(data_out);
00411 }
00412
00413
00414 t1 = clock();
00415
00416 printf("Time elapsed = %f seconds\n", (double)(t1-t0)/(double)CLOCKS_PER_SEC);
00417
00418 free(data_in);
00419 return 0;
00420 }