00001
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <tiffio.h>
00041 #include <time.h>
00042 #include <math.h>
00043 #include "io_tiff_routine.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
00103 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)
00104
00105 {
00106 float laplacian;
00107 laplacian = -4.0 * (*(ptr_in + i*n_col + j)) +
00108 *(ptr_in + i_prev*n_col + j) + *(ptr_in + i*n_col + j_prev)
00109 + *(ptr_in + i*n_col + j_next) + *(ptr_in + i_next*n_col + j);
00110 *(ptr_out+i*n_col + j)= *(ptr_in+i*n_col+j) + dt * laplacian;
00111
00112 }
00113
00114
00115
00116
00117
00118
00259 static void amss(float *ptr_out, float *ptr_in, size_t n_row, size_t n_col, float dt, float t_g)
00260
00261 {
00262 float grad, s_x, s_y, eta0, eta1, eta2, eta3, eta4, l_comb;
00263 unsigned int i, j, i_next, i_prev, j_next, j_prev;
00264
00265
00266 for (i=0; i<n_row; i++ ) {
00267
00268
00269 i_next = (i<n_row-1?i+1:i);
00270 i_prev = (i>0?i-1:i);
00271
00272 for (j=0; j<n_col; j++) {
00273
00274
00275 j_next = (j<n_col-1?j+1:j);
00276 j_prev = (j>0?j-1:j);
00277
00278
00279 s_x= 2 * ( *(ptr_in+i*n_col+j_next) - *(ptr_in+i*n_col+j_prev) ) +
00280 *(ptr_in+i_prev*n_col+j_next) - *(ptr_in+i_prev*n_col+j_prev) +
00281 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_next*n_col+j_prev);
00282 s_y= 2 * ( *(ptr_in+i_next*n_col+j) - *(ptr_in+i_prev*n_col+j) ) +
00283 *(ptr_in+i_next*n_col+j_next) - *(ptr_in+i_prev*n_col+j_next) +
00284 *(ptr_in+i_next*n_col+j_prev) - *(ptr_in+i_prev*n_col+j_prev);
00285 grad = 0.125 * sqrt( (s_x*s_x) + (s_y*s_y) );
00286
00287 if (grad<t_g)
00288
00289 heat (ptr_out, ptr_in, n_col, i, i_prev, i_next, j, j_prev, j_next, dt);
00290 else {
00291
00292 eta0 =0.5 * (s_x*s_x + s_y*s_y)- (s_x*s_x*s_y*s_y)/(s_x*s_x + s_y*s_y);
00293 eta1= 2 * eta0 - (s_x*s_x);
00294 eta2= 2 * eta0 - (s_y*s_y);
00295 eta3= - eta0 + 0.5 * (s_x*s_x + s_y*s_y - s_x*s_y);
00296 eta4= - eta0 + 0.5 * (s_x*s_x + s_y*s_y + s_x*s_y);
00297
00298 l_comb= ( -4 * eta0 * ( *(ptr_in+i*n_col+j) ) +
00299 eta1*( *(ptr_in+i*n_col+j_next) + *(ptr_in+i*n_col+j_prev) ) +
00300 eta2*( *(ptr_in+i_next*n_col+j) + *(ptr_in+i_prev*n_col+j) ) +
00301 eta3*( *(ptr_in+i_next*n_col+j_next) + *(ptr_in+i_prev*n_col+j_prev) ) +
00302 eta4*( *(ptr_in+i_prev*n_col+j_next) + *(ptr_in+i_next*n_col+j_prev) ) );
00303
00304
00305 if (l_comb>0)
00306 *(ptr_out+i*n_col+j)=
00307 *(ptr_in+i*n_col+j) + 0.25 * dt * pow(l_comb,0.33333333);
00308 else
00309 *(ptr_out+i*n_col+j)=
00310 *(ptr_in+i*n_col+j) - 0.25 * dt * pow(-l_comb,0.33333333);
00311 }
00312 }
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00331 int main(int argc, char *argv[])
00332
00333 {
00334 float *data_in;
00335 float *ptr_in_rgb[3];
00336 float *data_out;
00337 float *ptr_out_rgb[3];
00338 size_t n_col, n_row;
00339 size_t n_channels;
00340 float *ptr_in, *ptr_out, *ptr_end;
00341 int n_iter=0;
00342 float R;
00343 float t_g;
00344 float dt=0.1;
00345 float n_iter_f;
00346 int m;
00347 unsigned int k;
00348 clock_t t0, t1;
00349
00350
00351
00352
00353
00354
00355 if (4!=argc)
00356 FATAL("Error in the number of arguments!\n");
00357 if (0==sscanf(argv[1],"%f", &R))
00358 FATAL("The third argument must be a float!\n");
00359
00360
00361 if (0 > R) {
00362 printf("The normalized scale must be a positive real number!\n");
00363 return 0;
00364 }
00365
00366
00367 t0 = clock();
00368
00369
00370 n_iter_f= 0.75 * ( pow(R,1.33333333) / dt );
00371
00372
00373 n_iter= (int) (n_iter_f + 0.5);
00374
00375
00376 if (NULL == (data_in = read_tiff_f32(argv[2], &n_col, &n_row, &n_channels)))
00377 FATAL("error while reading the TIFF image");
00378
00379 ptr_in_rgb[0] = data_in;
00380 ptr_in_rgb[1] = data_in + n_row * n_col;
00381 ptr_in_rgb[2] = data_in + 2 * n_row * n_col;
00382
00383
00384 if (1!=n_channels){
00385 n_channels = 1;
00386 for (k=0; k<((n_row*n_col)-1); k++)
00387 if ( ( (*(ptr_in_rgb[0]+k)) != (*(ptr_in_rgb[1]+k) ))||
00388 ( (*(ptr_in_rgb[0]+k)) != (*(ptr_in_rgb[2]+k) )) ) {
00389 n_channels=3;
00390 break;
00391 }
00392 }
00393
00394
00395 if (0>n_iter)
00396 printf("The number of iteration must be a positive number. \n");
00397
00398 else if (0==n_iter) {
00399 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00400 }
00401 else {
00402
00403 if (NULL == (data_out = (float *) malloc(n_channels* n_col * n_row * sizeof(float))))
00404 FATAL("allocation error");
00405
00406
00407 ptr_out_rgb[0] = data_out;
00408 ptr_out_rgb[1] = data_out + n_row * n_col;
00409 ptr_out_rgb[2] = data_out + 2 * n_row * n_col;
00410
00411 for (k=0; k<n_channels; k++) {
00412 t_g=4;
00413
00414 ptr_in=ptr_in_rgb[k];
00415 ptr_out=ptr_out_rgb[k];
00416 ptr_end=ptr_in + n_row*n_col;
00417
00418 for (m=0; m<n_iter; m++) {
00419
00420 amss(ptr_out, ptr_in, n_row, n_col, dt, t_g);
00421
00422 if (m==0) t_g=1;
00423
00424 while (ptr_in<ptr_end) {
00425 *ptr_in = *ptr_out;
00426 ptr_in++;
00427 ptr_out++;
00428 }
00429 ptr_in=ptr_in_rgb[k];
00430 ptr_out=ptr_out_rgb[k];
00431 }
00432
00433 while (ptr_in<ptr_end){
00434 if (*ptr_in>255) *ptr_in=255;
00435 if (*ptr_in<0) *ptr_in=0;
00436 ptr_in++;
00437 }
00438 }
00439
00440 write_tiff_f32(argv[3], data_in, n_col, n_row, n_channels);
00441
00442 free(data_out);
00443 }
00444
00445
00446 t1 = clock();
00447
00448 printf("Time elapsed = %f seconds\n", (double)(t1-t0)/(double)CLOCKS_PER_SEC);
00449
00450 free(data_in);
00451 return 0;
00452 }