00001 #include "sadie.h"
00002
00003 extern PIXEL gmax;
00004 extern PIXEL bias;
00005 extern PIXEL gain;
00006 extern PIXEL gbrk[2][4];
00007 extern short nlev;
00008 extern PIXEL gmin;
00009 extern PIXEL *table;
00010 extern PIXEL thresh;
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 void
00023 STRETCH (IMAGE * in,
00024 short (*tf) (IMAGE *, IMAGE **),
00025
00026 IMAGE ** out
00027
00028
00029 )
00030 {
00031 register short i;
00032 char msg[SLEN];
00033
00034 if (TIMES)
00035 TIMING (T_STRETCH);
00036 if (NAMES)
00037 {
00038 MESSAGE ('I', "");
00039 MESSAGE ('I', "STRETCH");
00040 MESSAGE ('I', "");
00041 sprintf (msg, " Input image: %s", in->text);
00042 MESSAGE ('I', msg);
00043 if (tf == TFINVERT)
00044 {
00045 MESSAGE ('I', " Inverse stretch");
00046 sprintf (msg, " Graylevel maximum: %12.4e", gmax);
00047 MESSAGE ('I', msg);
00048 }
00049 else if (tf == TFLINEAR)
00050 {
00051 MESSAGE ('I', " Linear stretch");
00052 sprintf (msg, " Bias: %12.4e", bias);
00053 MESSAGE ('I', msg);
00054 sprintf (msg, " Gain: %12.4e", gain);
00055 MESSAGE ('I', msg);
00056 }
00057 else if (tf == TFLOG)
00058 {
00059 MESSAGE ('I', " Logarithmic stretch");
00060 }
00061 else if (tf == TFPLT)
00062 {
00063 MESSAGE ('I', " Piecewise linear stretch");
00064 sprintf (msg, " Input graylevel breakpoints: ");
00065 for (i = 0; i < 4; i++)
00066 {
00067 sprintf (msg + strlen (msg), "%12.4e", gbrk[0][i]);
00068 }
00069 MESSAGE ('I', msg);
00070 sprintf (msg, " Output graylevel breakpoints:");
00071 for (i = 0; i < 4; i++)
00072 {
00073 sprintf (msg + strlen (msg), "%12.4e", gbrk[1][i]);
00074 }
00075 MESSAGE ('I', msg);
00076 }
00077 else if (tf == TFQUANT)
00078 {
00079 MESSAGE ('I', " Requantize graylevels");
00080 sprintf (msg, " Minimum graylevel: %12.4e", gmin);
00081 MESSAGE ('I', msg);
00082 sprintf (msg, " Maximum graylevel: %12.4e", gmax);
00083 MESSAGE ('I', msg);
00084 sprintf (msg, " Quantization steps: %d", nlev);
00085 MESSAGE ('I', msg);
00086 }
00087 else if (tf == TFROOT)
00088 {
00089 MESSAGE ('I', " Square root stretch");
00090 }
00091 else if (tf == TFSAT)
00092 {
00093 MESSAGE ('I', " Saturate graylevels");
00094 sprintf (msg, " Graylevel minimum threshold: %12.4e", gmin);
00095 MESSAGE ('I', msg);
00096 sprintf (msg, " Graylevel maximum threshold: %12.4e", gmax);
00097 MESSAGE ('I', msg);
00098 }
00099 else if (tf == TFSCALE)
00100 {
00101 MESSAGE ('I', " Linear stretch");
00102 sprintf (msg, " New minimum graylevel: %12.4e", gmin);
00103 MESSAGE ('I', msg);
00104 sprintf (msg, " New maximum graylevel: %12.4e", gmax);
00105 MESSAGE ('I', msg);
00106 }
00107 else if (tf == TFSQUARE)
00108 {
00109 MESSAGE ('I', " Square stretch");
00110 }
00111 else if (tf == TFTABLE)
00112 {
00113 MESSAGE ('I', " Table lookup stretch");
00114 MESSAGE ('I', " Lookup table: index value");
00115 for (i = (short) floor (in->gmin); i <= (short) floor (in->gmax);
00116 i++)
00117 {
00118 sprintf (msg, " %20d %12.4e", i,
00119 table[i - (short) floor (in->gmin)]);
00120 MESSAGE ('I', msg);
00121 }
00122 }
00123 else if (tf == TFTHRESH)
00124 {
00125 MESSAGE ('I', " Threshold graylevels");
00126 sprintf (msg, " Graylevel threshold: %12.4e", thresh);
00127 MESSAGE ('I', msg);
00128 }
00129 MESSAGE ('I', " ...............");
00130 }
00131
00132
00133 if (!CHECKIMG (in))
00134 {
00135 MESSAGE ('E', " Can't identify image.");
00136 goto the_end;
00137 }
00138 else if (!tf)
00139 {
00140 MESSAGE ('E', " Can't identify transformation function.");
00141 goto the_end;
00142 }
00143
00144
00145 if (!CHECKIMG (*out))
00146 GETMEM (in->nbnd, in->nlin, in->npix, out);
00147 if (!*out)
00148 goto the_end;
00149
00150
00151 (*tf) (in, out);
00152
00153 the_end:
00154 if (TIMES)
00155 TIMING (T_EXIT);
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 extern PIXEL gmax;
00169 short
00170 TFINVERT (IMAGE * in,
00171 IMAGE ** out
00172
00173 )
00174 {
00175 register short i, j, k;
00176
00177 if (TIMES)
00178 TIMING (T_TFINVERT);
00179
00180 for (i = 0; i < in->nbnd; i++)
00181 {
00182 for (j = 0; j < in->nlin; j++)
00183 {
00184 for (k = 0; k < in->npix; k++)
00185 {
00186 (*out)->data[i][j][k] = gmax - in->data[i][j][k];
00187 }
00188 }
00189 }
00190 (*out)->gmin = gmax - in->gmax;
00191 (*out)->gmax = gmax - in->gmin;
00192
00193 the_end:
00194 if (TIMES)
00195 TIMING (T_EXIT);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 extern PIXEL bias;
00209 extern PIXEL gain;
00210 short
00211 TFLINEAR (IMAGE * in,
00212 IMAGE ** out
00213
00214 )
00215 {
00216 register short i, j, k;
00217
00218 if (TIMES)
00219 TIMING (T_TFLINEAR);
00220
00221 for (i = 0; i < in->nbnd; i++)
00222 {
00223 for (j = 0; j < in->nlin; j++)
00224 {
00225 for (k = 0; k < in->npix; k++)
00226 {
00227 (*out)->data[i][j][k] =
00228 (PIXEL) ((double) gain * (double) in->data[i][j][k] +
00229 (double) bias);
00230 }
00231 }
00232 }
00233 if (gain >= 0.0)
00234 {
00235 (*out)->gmin =
00236 (PIXEL) ((double) gain * (double) in->gmin + (double) bias);
00237 (*out)->gmax =
00238 (PIXEL) ((double) gain * (double) in->gmax + (double) bias);
00239 }
00240 else
00241 {
00242 (*out)->gmin =
00243 (PIXEL) ((double) gain * (double) in->gmax + (double) bias);
00244 (*out)->gmax =
00245 (PIXEL) ((double) gain * (double) in->gmin + (double) bias);
00246 }
00247
00248 the_end:
00249 if (TIMES)
00250 TIMING (T_EXIT);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 short
00264 TFLOG (IMAGE * in,
00265 IMAGE ** out
00266
00267 )
00268 {
00269 register short i, j, k;
00270
00271 if (TIMES)
00272 TIMING (T_TFLOG);
00273
00274 for (i = 0; i < in->nbnd; i++)
00275 {
00276 for (j = 0; j < in->nlin; j++)
00277 {
00278 for (k = 0; k < in->npix; k++)
00279 {
00280 (*out)->data[i][j][k] =
00281 in->data[i][j][k] <=
00282 0.0 ? in->data[i][j][k] : (PIXEL) log10 ((double) in->
00283 data[i][j][k] + 1.0);
00284 }
00285 }
00286 }
00287 (*out)->gmin =
00288 in->gmin <= 0.0 ? in->gmin : (PIXEL) log10 ((double) in->gmin + 1.0);
00289 (*out)->gmax =
00290 in->gmax <= 0.0 ? in->gmax : (PIXEL) log10 ((double) in->gmax + 1.0);
00291
00292 the_end:
00293 if (TIMES)
00294 TIMING (T_EXIT);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 extern PIXEL gbrk[2][4];
00308
00309
00310 short
00311 TFPLT (IMAGE * in,
00312 IMAGE ** out
00313
00314 )
00315 {
00316 register short i, j, k;
00317 double s1, s2, s3, b1, b2, b3;
00318
00319 if (TIMES)
00320 TIMING (T_TFPLT);
00321
00322 s1 =
00323 (double) (gbrk[1][1] - gbrk[1][0]) / (double) (gbrk[0][1] - gbrk[0][0]);
00324 s2 =
00325 (double) (gbrk[1][2] - gbrk[1][1]) / (double) (gbrk[0][2] - gbrk[0][1]);
00326 s3 =
00327 (double) (gbrk[1][3] - gbrk[1][2]) / (double) (gbrk[0][3] - gbrk[0][2]);
00328 b1 = (double) gbrk[1][0] - (double) gbrk[0][0] * s1;
00329 b2 = (double) gbrk[1][1] - (double) gbrk[0][1] * s2;
00330 b3 = (double) gbrk[1][2] - (double) gbrk[0][2] * s3;
00331 for (i = 0; i < in->nbnd; i++)
00332 {
00333 for (j = 0; j < in->nlin; j++)
00334 {
00335 for (k = 0; k < in->npix; k++)
00336 {
00337 if (in->data[i][j][k] <= gbrk[0][1])
00338 {
00339 (*out)->data[i][j][k] =
00340 max ((PIXEL) (s1 * (double) in->data[i][j][k] + b1),
00341 gbrk[1][0]);
00342 }
00343 else if (in->data[i][j][k] <= gbrk[0][2])
00344 {
00345 (*out)->data[i][j][k] =
00346 (PIXEL) (s2 * (double) in->data[i][j][k] + b2);
00347 }
00348 else
00349 {
00350 (*out)->data[i][j][k] =
00351 min ((PIXEL) (s3 * (double) in->data[i][j][k] + b3),
00352 gbrk[1][3]);
00353 }
00354 }
00355 }
00356 }
00357 if (in->gmin <= gbrk[0][1])
00358 {
00359 (*out)->gmin = max ((PIXEL) (s1 * (double) in->gmin + b1), gbrk[1][0]);
00360 }
00361 else if (in->gmin <= gbrk[0][2])
00362 {
00363 (*out)->gmin = (PIXEL) (s2 * (double) in->gmin + b2);
00364 }
00365 else
00366 {
00367 (*out)->gmin = min ((PIXEL) (s3 * (double) in->gmin + b3), gbrk[1][3]);
00368 }
00369 if (in->gmax <= gbrk[0][1])
00370 {
00371 (*out)->gmax = max ((PIXEL) (s1 * (double) in->gmax + b1), gbrk[1][0]);
00372 }
00373 else if (in->gmax <= gbrk[0][2])
00374 {
00375 (*out)->gmax = (PIXEL) (s2 * (double) in->gmax + b2);
00376 }
00377 else
00378 {
00379 (*out)->gmax = min ((PIXEL) (s3 * (double) in->gmax + b3), gbrk[1][3]);
00380 }
00381
00382 the_end:
00383 if (TIMES)
00384 TIMING (T_EXIT);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 extern short nlev;
00397 extern PIXEL gmin;
00398 extern PIXEL gmax;
00399 short
00400 TFQUANT (IMAGE * in,
00401 IMAGE ** out
00402
00403 )
00404 {
00405 register short i, j, k;
00406 double factor;
00407
00408 if (TIMES)
00409 TIMING (T_TFQUANT);
00410
00411 factor = (double) (--nlev) / (double) (gmax - gmin);
00412 for (i = 0; i < in->nbnd; i++)
00413 {
00414 for (j = 0; j < in->nlin; j++)
00415 {
00416 for (k = 0; k < in->npix; k++)
00417 {
00418 (*out)->data[i][j][k] =
00419 (PIXEL) max (0,
00420 min ((short)
00421 ((double) (in->data[i][j][k] - gmin) *
00422 factor), nlev));
00423 }
00424 }
00425 }
00426 (*out)->gmin = (PIXEL) 0;
00427 (*out)->gmax = (PIXEL) nlev;
00428
00429 the_end:
00430 if (TIMES)
00431 TIMING (T_EXIT);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 short
00445 TFROOT (IMAGE * in,
00446 IMAGE ** out
00447
00448 )
00449 {
00450 register short i, j, k;
00451
00452 if (TIMES)
00453 TIMING (T_TFROOT);
00454
00455 for (i = 0; i < in->nbnd; i++)
00456 {
00457 for (j = 0; j < in->nlin; j++)
00458 {
00459 for (k = 0; k < in->npix; k++)
00460 {
00461 (*out)->data[i][j][k] =
00462 in->data[i][j][k] <
00463 0.0 ? in->data[i][j][k] : (PIXEL) sqrt ((double) in->
00464 data[i][j][k]);
00465 }
00466 }
00467 }
00468 (*out)->gmin = in->gmin < 0.0 ? in->gmin : (PIXEL) sqrt ((double) in->gmin);
00469 (*out)->gmax = in->gmax < 0.0 ? in->gmax : (PIXEL) sqrt ((double) in->gmax);
00470
00471 the_end:
00472 if (TIMES)
00473 TIMING (T_EXIT);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 extern PIXEL gmin;
00488 extern PIXEL gmax;
00489 short
00490 TFSAT (IMAGE * in,
00491 IMAGE ** out
00492
00493 )
00494 {
00495 register short i, j, k;
00496
00497 if (TIMES)
00498 TIMING (T_TFSAT);
00499
00500 for (i = 0; i < in->nbnd; i++)
00501 {
00502 for (j = 0; j < in->nlin; j++)
00503 {
00504 for (k = 0; k < in->npix; k++)
00505 {
00506 if (in->data[i][j][k] < gmin)
00507 {
00508 (*out)->data[i][j][k] = gmin;
00509 }
00510 else if (in->data[i][j][k] < gmax)
00511 {
00512 (*out)->data[i][j][k] = in->data[i][j][k];
00513 }
00514 else
00515 {
00516 (*out)->data[i][j][k] = gmax;
00517 }
00518 }
00519 }
00520 }
00521
00522 the_end:
00523 if (TIMES)
00524 TIMING (T_EXIT);
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 extern PIXEL gmin;
00537 extern PIXEL gmax;
00538 short
00539 TFSCALE (IMAGE * in,
00540 IMAGE ** out
00541
00542 )
00543 {
00544 register short i, j, k;
00545 double factor;
00546
00547 if (TIMES)
00548 TIMING (T_TFSCALE);
00549
00550 RANGE (in);
00551 factor =
00552 in->gmin <
00553 in->gmax ? (double) (gmax - gmin) / (double) (in->gmax - in->gmin) : 0.0;
00554 for (i = 0; i < in->nbnd; i++)
00555 {
00556 for (j = 0; j < in->nlin; j++)
00557 {
00558 for (k = 0; k < in->npix; k++)
00559 {
00560 (*out)->data[i][j][k] =
00561 (PIXEL) ((double) (in->data[i][j][k] - in->gmin) * factor) +
00562 gmin;
00563 }
00564 }
00565 }
00566 if (gmin <= gmax)
00567 {
00568 (*out)->gmin = gmin;
00569 (*out)->gmax = gmax;
00570 }
00571 else
00572 {
00573 (*out)->gmin = gmax;
00574 (*out)->gmax = gmin;
00575 }
00576
00577 the_end:
00578 if (TIMES)
00579 TIMING (T_EXIT);
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 short
00592 TFSQUARE (IMAGE * in,
00593 IMAGE ** out
00594
00595 )
00596 {
00597 register short i, j, k;
00598
00599 if (TIMES)
00600 TIMING (T_TFSQUARE);
00601
00602 for (i = 0; i < in->nbnd; i++)
00603 {
00604 for (j = 0; j < in->nlin; j++)
00605 {
00606 for (k = 0; k < in->npix; k++)
00607 {
00608 (*out)->data[i][j][k] = in->data[i][j][k] * in->data[i][j][k];
00609 }
00610 }
00611 }
00612
00613 the_end:
00614 if (TIMES)
00615 TIMING (T_EXIT);
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 extern PIXEL *table;
00629
00630
00631 short
00632 TFTABLE (IMAGE * in,
00633 IMAGE ** out
00634
00635 )
00636 {
00637 register short i, j, k, offset;
00638
00639 if (TIMES)
00640 TIMING (T_TFTABLE);
00641
00642 offset = (short) floor ((double) in->gmin);
00643 for (i = 0; i < in->nbnd; i++)
00644 {
00645 for (j = 0; j < in->nlin; j++)
00646 {
00647 for (k = 0; k < in->npix; k++)
00648 {
00649 (*out)->data[i][j][k] =
00650 table[(short) floor ((double) in->data[i][j][k]) - offset];
00651 }
00652 }
00653 }
00654
00655 the_end:
00656 if (TIMES)
00657 TIMING (T_EXIT);
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 extern PIXEL thresh;
00671 short
00672 TFTHRESH (IMAGE * in,
00673 IMAGE ** out
00674
00675 )
00676 {
00677 register short i, j, k;
00678
00679 if (TIMES)
00680 TIMING (T_TFTHRESH);
00681
00682 for (i = 0; i < in->nbnd; i++)
00683 {
00684 for (j = 0; j < in->nlin; j++)
00685 {
00686 for (k = 0; k < in->npix; k++)
00687 {
00688 (*out)->data[i][j][k] =
00689 in->data[i][j][k] < thresh ? in->gmin : in->gmax;
00690 }
00691 }
00692 }
00693 (*out)->gmin = in->gmin < thresh ? in->gmin : in->gmax;
00694 (*out)->gmax = in->gmax < thresh ? in->gmin : in->gmax;
00695
00696 the_end:
00697 if (TIMES)
00698 TIMING (T_EXIT);
00699 }