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 STRETCH (
00023 IMAGE *in,
00024 short (*tf)(IMAGE *, IMAGE **),
00025
00026 IMAGE **out
00027
00028
00029 ) { register short i;
00030 char msg[SLEN];
00031
00032 if (TIMES) TIMING(T_STRETCH);
00033 if (NAMES) {
00034 MESSAGE('I',"");
00035 MESSAGE('I',"STRETCH");
00036 MESSAGE('I',"");
00037 sprintf(msg," Input image: %s",in->text);
00038 MESSAGE('I',msg);
00039 if (tf == TFINVERT) {
00040 MESSAGE('I'," Inverse stretch");
00041 sprintf(msg," Graylevel maximum: %12.4e",gmax);
00042 MESSAGE('I',msg);
00043 } else if (tf == TFLINEAR) {
00044 MESSAGE('I'," Linear stretch");
00045 sprintf(msg," Bias: %12.4e",bias);
00046 MESSAGE('I',msg);
00047 sprintf(msg," Gain: %12.4e",gain);
00048 MESSAGE('I',msg);
00049 } else if (tf == TFLOG) {
00050 MESSAGE('I'," Logarithmic stretch");
00051 } else if (tf == TFPLT) {
00052 MESSAGE('I'," Piecewise linear stretch");
00053 sprintf(msg," Input graylevel breakpoints: ");
00054 for (i=0; i<4; i++) {
00055 sprintf(msg+strlen(msg),"%12.4e",gbrk[0][i]);
00056 }
00057 MESSAGE('I',msg);
00058 sprintf(msg," Output graylevel breakpoints:");
00059 for (i=0; i<4; i++) {
00060 sprintf(msg+strlen(msg),"%12.4e",gbrk[1][i]);
00061 }
00062 MESSAGE('I',msg);
00063 } else if (tf == TFQUANT) {
00064 MESSAGE('I'," Requantize graylevels");
00065 sprintf(msg," Minimum graylevel: %12.4e",gmin);
00066 MESSAGE('I',msg);
00067 sprintf(msg," Maximum graylevel: %12.4e",gmax);
00068 MESSAGE('I',msg);
00069 sprintf(msg," Quantization steps: %d",nlev);
00070 MESSAGE('I',msg);
00071 } else if (tf == TFROOT) {
00072 MESSAGE('I'," Square root stretch");
00073 } else if (tf == TFSAT) {
00074 MESSAGE('I'," Saturate graylevels");
00075 sprintf(msg," Graylevel minimum threshold: %12.4e",gmin);
00076 MESSAGE('I',msg);
00077 sprintf(msg," Graylevel maximum threshold: %12.4e",gmax);
00078 MESSAGE('I',msg);
00079 } else if (tf == TFSCALE) {
00080 MESSAGE('I'," Linear stretch");
00081 sprintf(msg," New minimum graylevel: %12.4e",gmin);
00082 MESSAGE('I',msg);
00083 sprintf(msg," New maximum graylevel: %12.4e",gmax);
00084 MESSAGE('I',msg);
00085 } else if (tf == TFSQUARE) {
00086 MESSAGE('I'," Square stretch");
00087 } else if (tf == TFTABLE) {
00088 MESSAGE('I'," Table lookup stretch");
00089 MESSAGE('I'," Lookup table: index value");
00090 for (i=(short)floor(in->gmin); i<=(short)floor(in->gmax); i++) {
00091 sprintf(msg," %20d %12.4e",i,table[i-(short)floor(in->gmin)]);
00092 MESSAGE('I',msg);
00093 }
00094 } else if (tf == TFTHRESH) {
00095 MESSAGE('I'," Threshold graylevels");
00096 sprintf(msg," Graylevel threshold: %12.4e",thresh);
00097 MESSAGE('I',msg);
00098 }
00099 MESSAGE('I'," ...............");
00100 }
00101
00102
00103 if (!CHECKIMG(in)) {
00104 MESSAGE('E'," Can't identify image.");
00105 goto the_end;
00106 } else if (!tf) {
00107 MESSAGE('E'," Can't identify transformation function.");
00108 goto the_end;
00109 }
00110
00111
00112 if (!CHECKIMG(*out)) GETMEM(in->nbnd,in->nlin,in->npix,out);
00113 if (!*out) goto the_end;
00114
00115
00116 (*tf)(in,out);
00117
00118 the_end:
00119 if (TIMES) TIMING(T_EXIT);
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 extern PIXEL gmax;
00133 short TFINVERT (
00134 IMAGE *in,
00135 IMAGE **out
00136
00137 ) { register short i, j, k;
00138
00139 if (TIMES) TIMING(T_TFINVERT);
00140
00141 for (i=0; i<in->nbnd; i++) {
00142 for (j=0; j<in->nlin; j++) {
00143 for (k=0; k<in->npix; k++) {
00144 (*out)->data[i][j][k] = gmax - in->data[i][j][k];
00145 }
00146 }
00147 }
00148 (*out)->gmin = gmax - in->gmax;
00149 (*out)->gmax = gmax - in->gmin;
00150
00151 the_end:
00152 if (TIMES) TIMING(T_EXIT);
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 extern PIXEL bias;
00166 extern PIXEL gain;
00167 short TFLINEAR (
00168 IMAGE *in,
00169 IMAGE **out
00170
00171 ) { register short i, j, k;
00172
00173 if (TIMES) TIMING(T_TFLINEAR);
00174
00175 for (i=0; i<in->nbnd; i++) {
00176 for (j=0; j<in->nlin; j++) {
00177 for (k=0; k<in->npix; k++) {
00178 (*out)->data[i][j][k] = (PIXEL)((double)gain*(double)in->data[i][j][k]+(double)bias);
00179 }
00180 }
00181 }
00182 if (gain >= 0.0) {
00183 (*out)->gmin = (PIXEL)((double)gain*(double)in->gmin+(double)bias);
00184 (*out)->gmax = (PIXEL)((double)gain*(double)in->gmax+(double)bias);
00185 } else {
00186 (*out)->gmin = (PIXEL)((double)gain*(double)in->gmax+(double)bias);
00187 (*out)->gmax = (PIXEL)((double)gain*(double)in->gmin+(double)bias);
00188 }
00189
00190 the_end:
00191 if (TIMES) TIMING(T_EXIT);
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 short TFLOG (
00205 IMAGE *in,
00206 IMAGE **out
00207
00208 ) { register short i, j, k;
00209
00210 if (TIMES) TIMING(T_TFLOG);
00211
00212 for (i=0; i<in->nbnd; i++) {
00213 for (j=0; j<in->nlin; j++) {
00214 for (k=0; k<in->npix; k++) {
00215 (*out)->data[i][j][k] = in->data[i][j][k] <= 0.0 ? in->data[i][j][k] : (PIXEL)log10((double)in->data[i][j][k]+1.0);
00216 }
00217 }
00218 }
00219 (*out)->gmin = in->gmin <= 0.0 ? in->gmin : (PIXEL)log10((double)in->gmin+1.0);
00220 (*out)->gmax = in->gmax <= 0.0 ? in->gmax : (PIXEL)log10((double)in->gmax+1.0);
00221
00222 the_end:
00223 if (TIMES) TIMING(T_EXIT);
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 extern PIXEL gbrk[2][4];
00237
00238
00239 short TFPLT (
00240 IMAGE *in,
00241 IMAGE **out
00242
00243 ) { register short i, j, k;
00244 double s1, s2, s3, b1, b2, b3;
00245
00246 if (TIMES) TIMING(T_TFPLT);
00247
00248 s1 = (double)(gbrk[1][1]-gbrk[1][0])/(double)(gbrk[0][1]-gbrk[0][0]);
00249 s2 = (double)(gbrk[1][2]-gbrk[1][1])/(double)(gbrk[0][2]-gbrk[0][1]);
00250 s3 = (double)(gbrk[1][3]-gbrk[1][2])/(double)(gbrk[0][3]-gbrk[0][2]);
00251 b1 = (double)gbrk[1][0] - (double)gbrk[0][0]*s1;
00252 b2 = (double)gbrk[1][1] - (double)gbrk[0][1]*s2;
00253 b3 = (double)gbrk[1][2] - (double)gbrk[0][2]*s3;
00254 for (i=0; i<in->nbnd; i++) {
00255 for (j=0; j<in->nlin; j++) {
00256 for (k=0; k<in->npix; k++) {
00257 if (in->data[i][j][k] <= gbrk[0][1]) {
00258 (*out)->data[i][j][k] = max((PIXEL)(s1*(double)in->data[i][j][k]+b1),gbrk[1][0]);
00259 } else if (in->data[i][j][k] <= gbrk[0][2]) {
00260 (*out)->data[i][j][k] = (PIXEL)(s2*(double)in->data[i][j][k] + b2);
00261 } else {
00262 (*out)->data[i][j][k] = min((PIXEL)(s3*(double)in->data[i][j][k]+b3),gbrk[1][3]);
00263 }
00264 }
00265 }
00266 }
00267 if (in->gmin <= gbrk[0][1]) {
00268 (*out)->gmin = max((PIXEL)(s1*(double)in->gmin+b1),gbrk[1][0]);
00269 } else if (in->gmin <= gbrk[0][2]) {
00270 (*out)->gmin = (PIXEL)(s2*(double)in->gmin + b2);
00271 } else {
00272 (*out)->gmin = min((PIXEL)(s3*(double)in->gmin+b3),gbrk[1][3]);
00273 }
00274 if (in->gmax <= gbrk[0][1]) {
00275 (*out)->gmax = max((PIXEL)(s1*(double)in->gmax+b1),gbrk[1][0]);
00276 } else if (in->gmax <= gbrk[0][2]) {
00277 (*out)->gmax = (PIXEL)(s2*(double)in->gmax + b2);
00278 } else {
00279 (*out)->gmax = min((PIXEL)(s3*(double)in->gmax+b3),gbrk[1][3]);
00280 }
00281
00282 the_end:
00283 if (TIMES) TIMING(T_EXIT);
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 extern short nlev;
00296 extern PIXEL gmin;
00297 extern PIXEL gmax;
00298 short TFQUANT (
00299 IMAGE *in,
00300 IMAGE **out
00301
00302 ) { register short i, j, k;
00303 double factor;
00304
00305 if (TIMES) TIMING(T_TFQUANT);
00306
00307 factor = (double)(--nlev)/(double)(gmax-gmin);
00308 for (i=0; i<in->nbnd; i++) {
00309 for (j=0; j<in->nlin; j++) {
00310 for (k=0; k<in->npix; k++) {
00311 (*out)->data[i][j][k] = (PIXEL)max(0,min((short)((double)(in->data[i][j][k]-gmin)*factor),nlev));
00312 }
00313 }
00314 }
00315 (*out)->gmin = (PIXEL)0;
00316 (*out)->gmax = (PIXEL)nlev;
00317
00318 the_end:
00319 if (TIMES) TIMING(T_EXIT);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 short TFROOT (
00333 IMAGE *in,
00334 IMAGE **out
00335
00336 ) { register short i, j, k;
00337
00338 if (TIMES) TIMING(T_TFROOT);
00339
00340 for (i=0; i<in->nbnd; i++) {
00341 for (j=0; j<in->nlin; j++) {
00342 for (k=0; k<in->npix; k++) {
00343 (*out)->data[i][j][k] = in->data[i][j][k] < 0.0 ? in->data[i][j][k] : (PIXEL)sqrt((double)in->data[i][j][k]);
00344 }
00345 }
00346 }
00347 (*out)->gmin = in->gmin < 0.0 ? in->gmin : (PIXEL)sqrt((double)in->gmin);
00348 (*out)->gmax = in->gmax < 0.0 ? in->gmax : (PIXEL)sqrt((double)in->gmax);
00349
00350 the_end:
00351 if (TIMES) TIMING(T_EXIT);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 extern PIXEL gmin;
00366 extern PIXEL gmax;
00367 short TFSAT (
00368 IMAGE *in,
00369 IMAGE **out
00370
00371 ) { register short i, j, k;
00372
00373 if (TIMES) TIMING(T_TFSAT);
00374
00375 for (i=0; i<in->nbnd; i++) {
00376 for (j=0; j<in->nlin; j++) {
00377 for (k=0; k<in->npix; k++) {
00378 if (in->data[i][j][k] < gmin) {
00379 (*out)->data[i][j][k] = gmin;
00380 } else if (in->data[i][j][k] < gmax) {
00381 (*out)->data[i][j][k] = in->data[i][j][k];
00382 } else {
00383 (*out)->data[i][j][k] = gmax;
00384 }
00385 }
00386 }
00387 }
00388
00389 the_end:
00390 if (TIMES) TIMING(T_EXIT);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 extern PIXEL gmin;
00403 extern PIXEL gmax;
00404 short TFSCALE (
00405 IMAGE *in,
00406 IMAGE **out
00407
00408 ) { register short i, j, k;
00409 double factor;
00410
00411 if (TIMES) TIMING(T_TFSCALE);
00412
00413 RANGE(in);
00414 factor = in->gmin < in->gmax ? (double)(gmax-gmin)/(double)(in->gmax-in->gmin) : 0.0;
00415 for (i=0; i<in->nbnd; i++) {
00416 for (j=0; j<in->nlin; j++) {
00417 for (k=0; k<in->npix; k++) {
00418 (*out)->data[i][j][k] = (PIXEL)((double)(in->data[i][j][k]-in->gmin)*factor) + gmin;
00419 }
00420 }
00421 }
00422 if (gmin <= gmax) {
00423 (*out)->gmin = gmin;
00424 (*out)->gmax = gmax;
00425 } else {
00426 (*out)->gmin = gmax;
00427 (*out)->gmax = gmin;
00428 }
00429
00430 the_end:
00431 if (TIMES) TIMING(T_EXIT);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 short TFSQUARE (
00444 IMAGE *in,
00445 IMAGE **out
00446
00447 ) { register short i, j, k;
00448
00449 if (TIMES) TIMING(T_TFSQUARE);
00450
00451 for (i=0; i<in->nbnd; i++) {
00452 for (j=0; j<in->nlin; j++) {
00453 for (k=0; k<in->npix; k++) {
00454 (*out)->data[i][j][k] = in->data[i][j][k]*in->data[i][j][k];
00455 }
00456 }
00457 }
00458
00459 the_end:
00460 if (TIMES) TIMING(T_EXIT);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 extern PIXEL *table;
00474
00475
00476 short TFTABLE (
00477 IMAGE *in,
00478 IMAGE **out
00479
00480 ) { register short i, j, k, offset;
00481
00482 if (TIMES) TIMING(T_TFTABLE);
00483
00484 offset = (short)floor((double)in->gmin);
00485 for (i=0; i<in->nbnd; i++) {
00486 for (j=0; j<in->nlin; j++) {
00487 for (k=0; k<in->npix; k++) {
00488 (*out)->data[i][j][k] = table[(short)floor((double)in->data[i][j][k])-offset];
00489 }
00490 }
00491 }
00492
00493 the_end:
00494 if (TIMES) TIMING(T_EXIT);
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 extern PIXEL thresh;
00508 short TFTHRESH (
00509 IMAGE *in,
00510 IMAGE **out
00511
00512 ) { register short i, j, k;
00513
00514 if (TIMES) TIMING(T_TFTHRESH);
00515
00516 for (i=0; i<in->nbnd; i++) {
00517 for (j=0; j<in->nlin; j++) {
00518 for (k=0; k<in->npix; k++) {
00519 (*out)->data[i][j][k] = in->data[i][j][k] < thresh ? in->gmin : in->gmax;
00520 }
00521 }
00522 }
00523 (*out)->gmin = in->gmin < thresh ? in->gmin : in->gmax;
00524 (*out)->gmax = in->gmax < thresh ? in->gmin : in->gmax;
00525
00526 the_end:
00527 if (TIMES) TIMING(T_EXIT);
00528 }