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 }