00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00066
00067
00068
00069
00070 #include <stdlib.h>
00071 #include <tiffio.h>
00072 #include <time.h>
00073 #include <math.h>
00074 #include "io_tiff_routine.h"
00075
00076
00077
00078
00079
00080
00082 #define FATAL(MSG)\
00083 do {\
00084 fprintf(stderr, MSG "\n");\
00085 abort();\
00086 } while (0);
00087
00089 #define INFO(MSG)\
00090 do {\
00091 fprintf(stderr, MSG "\n");\
00092 } while (0);
00093
00095 #define DEBUG(MSG)\
00096 do {\
00097 if (debug_flag)\
00098 fprintf(stderr, __FILE__ ":%03i " MSG "\n", __LINE__);\
00099 } while (0);
00100
00101
00102
00103
00104
00105
00135 static void heat (float *ptr_out, float *ptr_in, size_t n_col, int i,
00136 int i_prev, int i_next, int j, int j_prev, int j_next,
00137 float dt)
00138 {
00139 float laplacian;
00140 laplacian = -4.0 * (*(ptr_in + i*n_col + j)) +
00141 *(ptr_in + i_prev*n_col + j) + *(ptr_in + i*n_col + j_prev)
00142 + *(ptr_in + i*n_col + j_next) + *(ptr_in + i_next*n_col + j);
00143 *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + dt * laplacian;
00144
00145 }
00146
00147
00148
00149
00150
00151
00301 static void amss(float *ptr_out, float *ptr_in, size_t n_row, size_t n_col,
00302 float dt, float t_g)
00303 {
00304 float grad, s_x, s_y, eta0, eta1, eta2, eta3, eta4, l_comb;
00305 unsigned int i, j, i_next, i_prev, j_next, j_prev;
00306
00307
00308 for (i=0; i<n_row; i++ ) {
00309
00310
00311 i_next = (i<n_row-1?i+1:i);
00312 i_prev = (i>0?i-1:i);
00313
00314 for (j=0; j<n_col; j++) {
00315
00316
00317 j_next = (j<n_col-1?j+1:j);
00318 j_prev = (j>0?j-1:j);
00319
00320
00321 s_x = 2 * ( *(ptr_in+i*n_col+j_next) - *(ptr_in+i*n_col+j_prev) ) +
00322 *(ptr_in+i_prev*n_col+j_next) - *(ptr_in+i_prev*n_col+j_prev) +
00323 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_next*n_col+j_prev);
00324 s_y = 2 * ( *(ptr_in+i_next*n_col+j) - *(ptr_in+i_prev*n_col+j) ) +
00325 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_prev*n_col+j_next) +
00326 *(ptr_in+i_next*n_col+j_prev) - *(ptr_in+i_prev*n_col+j_prev);
00327 grad = 0.125 * sqrt( (s_x*s_x) + (s_y*s_y) );
00328
00329 if (grad<t_g)
00330
00331 heat (ptr_out, ptr_in, n_col, i, i_prev, i_next,
00332 j, j_prev, j_next, dt);
00333 else {
00334
00335 eta0 =0.5 * (s_x*s_x + s_y*s_y)-
00336 (s_x*s_x*s_y*s_y)/(s_x*s_x + s_y*s_y);
00337 eta1= 2 * eta0 - (s_x*s_x);
00338 eta2= 2 * eta0 - (s_y*s_y);
00339 eta3= - eta0 + 0.5 * (s_x*s_x + s_y*s_y - s_x*s_y);
00340 eta4= - eta0 + 0.5 * (s_x*s_x + s_y*s_y + s_x*s_y);
00341
00342 l_comb= ( -4 * eta0 * ( *(ptr_in+i*n_col+j) ) +
00343 eta1*( *(ptr_in+i*n_col+j_next) +
00344 *(ptr_in+i*n_col+j_prev) ) +
00345 eta2*( *(ptr_in+i_next*n_col+j) +
00346 *(ptr_in+i_prev*n_col+j) ) +
00347 eta3*( *(ptr_in+i_next*n_col+j_next) +
00348 *(ptr_in+i_prev*n_col+j_prev) ) +
00349 eta4*( *(ptr_in+i_prev*n_col+j_next) +
00350 *(ptr_in+i_next*n_col+j_prev) ) );
00351
00352
00353 if (l_comb>0)
00354 *(ptr_out+i*n_col+j)=
00355 *(ptr_in+i*n_col+j)+0.25* dt * pow(l_comb,0.33333333);
00356 else
00357 *(ptr_out+i*n_col+j)=
00358 *(ptr_in+i*n_col+j)-0.25* dt * pow(-l_comb,0.33333333);
00359 }
00360 }
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00380 int main(int argc, char *argv[])
00381
00382 {
00383 float *data_in;
00384 float *ptr_in_rgb[3];
00385 float *data_out;
00386 float *ptr_out_rgb[3];
00387 size_t n_col, n_row;
00388 size_t n_channels;
00389 float *ptr_in, *ptr_out, *ptr_end;
00390 int n_iter=0;
00391 float R;
00392 float t_g;
00393 float dt=0.1;
00394 float n_iter_f;
00395 int m;
00396 unsigned int k;
00397 clock_t t0, t1;
00398
00399
00400
00401
00402
00403
00404 if (4!=argc)
00405 FATAL("Error in the number of arguments!\n");
00406 if (0==sscanf(argv[1],"%f", &R))
00407 FATAL("The third argument must be a float!\n");
00408
00409
00410 if (0 > R) {
00411 printf("The normalized scale must be a positive real number!\n");
00412 return 0;
00413 }
00414
00415
00416 t0 = clock();
00417
00418
00419 n_iter_f= 0.75 * ( pow(R,1.33333333) / dt );
00420
00421
00422 n_iter= (int) (n_iter_f + 0.5);
00423
00424
00425 if (NULL == (data_in = read_tiff_f32(argv[2],
00426 &n_col, &n_row, &n_channels)))
00427 FATAL("error while reading the TIFF image");
00428
00429 ptr_in_rgb[0] = data_in;
00430 ptr_in_rgb[1] = data_in + n_row * n_col;
00431 ptr_in_rgb[2] = data_in + 2 * n_row * n_col;
00432
00433
00434 if (1!=n_channels) {
00435 n_channels = 1;
00436 for (k=0; k<((n_row*n_col)-1); k++)
00437 if ( ( (*(ptr_in_rgb[0]+k)) != (*(ptr_in_rgb[1]+k) ))||
00438 ( (*(ptr_in_rgb[0]+k)) != (*(ptr_in_rgb[2]+k) )) ) {
00439 n_channels=3;
00440 break;
00441 }
00442 }
00443
00444
00445 if (0>n_iter)
00446 printf("The number of iteration must be a positive number. \n");
00447
00448 else if (0==n_iter) {
00449 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00450 } else {
00451
00452 if (NULL == (data_out = (float *)
00453 malloc(n_channels* n_col * n_row * sizeof(float))))
00454 FATAL("allocation error");
00455
00456
00457 ptr_out_rgb[0] = data_out;
00458 ptr_out_rgb[1] = data_out + n_row * n_col;
00459 ptr_out_rgb[2] = data_out + 2 * n_row * n_col;
00460
00461 for (k=0; k<n_channels; k++) {
00462 t_g=4;
00463
00464 ptr_in=ptr_in_rgb[k];
00465 ptr_out=ptr_out_rgb[k];
00466 ptr_end=ptr_in + n_row*n_col;
00467
00468 for (m=0; m<n_iter; m++) {
00469
00470 amss(ptr_out, ptr_in, n_row, n_col, dt, t_g);
00471
00472 if (m==0) t_g=1;
00473
00474 while (ptr_in<ptr_end) {
00475 *ptr_in = *ptr_out;
00476 ptr_in++;
00477 ptr_out++;
00478 }
00479 ptr_in=ptr_in_rgb[k];
00480 ptr_out=ptr_out_rgb[k];
00481 }
00482
00483 while (ptr_in<ptr_end) {
00484 if (*ptr_in>255) *ptr_in=255;
00485 if (*ptr_in<0) *ptr_in=0;
00486 ptr_in++;
00487 }
00488 }
00489
00490 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00491
00492 free(data_out);
00493 }
00494
00495
00496 t1 = clock();
00497
00498 printf("CPU time consumed = %f seconds\n",
00499 (double)(t1-t0)/(double)CLOCKS_PER_SEC);
00500
00501 free(data_in);
00502 return 0;
00503 }
00504