Changeset 1216 for trunk/psLib/src/image/psImageManip.c
- Timestamp:
- Jul 14, 2004, 1:22:49 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/image/psImageManip.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/image/psImageManip.c
r1205 r1216 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1. 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-07- 09 21:48:07$12 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-07-14 23:22:49 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 17 17 #include <math.h> // for isfinite(), etc. 18 18 #include <stdlib.h> 19 #include <stdbool.h> 19 20 20 21 #include "psError.h" 21 22 #include "psImage.h" 22 23 int psImageClip(psImage* input,float min,float vmin,float max,float vmax) 23 #include "psStats.h" 24 #include "psMemory.h" 25 26 bool getSpecifiedStatValue(const psStats* stats, double* value); 27 28 int psImageClip(psImage* input, psF64 min, psF64 vmin, psF64 max, psF64 vmax) 24 29 { 25 30 int numClipped = 0; … … 41 46 switch (input->type.type) { 42 47 43 #define psImageClipCase(type )\48 #define psImageClipCase(type,typename) \ 44 49 case PS_TYPE_##type: { \ 50 if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \ 51 psError(__func__, "Specified vmin (%g) is outside of image's " \ 52 typename " pixel range", \ 53 vmin); \ 54 } \ 55 if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \ 56 psError(__func__, "Specified vmax (%g) is outside of image's " \ 57 typename " pixel range", \ 58 vmax); \ 59 } \ 45 60 ps##type minimum = (ps##type) min; \ 46 61 ps##type maximum = (ps##type) max; \ … … 59 74 } \ 60 75 break; 61 #define psImageClipCaseComplex(type)\ 76 77 #define psImageClipCaseComplex(type,typename,absfcn)\ 62 78 case PS_TYPE_##type: { \ 79 if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \ 80 psError(__func__, "Specified vmin (%g) is outside of image's " \ 81 typename " pixel range", \ 82 vmin); \ 83 } \ 84 if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \ 85 psError(__func__, "Specified vmax (%g) is outside of image's " \ 86 typename " pixel range", \ 87 vmax); \ 88 } \ 63 89 for (unsigned int row = 0;row<numRows;row++) { \ 64 90 ps##type* inputRow = input->data.type[row]; \ 65 91 for (unsigned int col = 0; col < numCols; col++) { \ 66 if ( cabsf(inputRow[col]) < min) { \92 if (absfcn(inputRow[col]) < min) { \ 67 93 inputRow[col] = (ps##type)vmin; \ 68 94 numClipped++; \ 69 } else if ( cabsf(inputRow[col]) > max) { \95 } else if (absfcn(inputRow[col]) > max) { \ 70 96 inputRow[col] = (ps##type)vmax; \ 71 97 numClipped++; \ … … 76 102 break; 77 103 78 psImageClipCase(S8 )79 psImageClipCase(S16 )80 psImageClipCase(S32 )81 psImageClipCase(S64 )82 psImageClipCase(U8 )83 psImageClipCase(U16 )84 psImageClipCase(U32 )85 psImageClipCase(U64 )86 psImageClipCase(F32 )87 psImageClipCase(F64 )88 psImageClipCaseComplex(C32 )89 psImageClipCaseComplex(C64 )104 psImageClipCase(S8,"psS8") 105 psImageClipCase(S16,"psS16") 106 psImageClipCase(S32,"psS32") 107 psImageClipCase(S64,"psS64") 108 psImageClipCase(U8,"psU8") 109 psImageClipCase(U16,"psU16") 110 psImageClipCase(U32,"psU32") 111 psImageClipCase(U64,"psU64") 112 psImageClipCase(F32,"psF32") 113 psImageClipCase(F64,"psF64") 114 psImageClipCaseComplex(C32,"psC32",cabsf) 115 psImageClipCaseComplex(C64,"psC64",cabs) 90 116 91 117 default: … … 97 123 } 98 124 99 int psImageClipNaN(psImage* input, floatvalue)125 int psImageClipNaN(psImage* input,psF64 value) 100 126 { 101 127 int numClipped = 0; … … 240 266 return 0; 241 267 } 268 269 int psImageClipComplexRegion(psImage* input, psC64 min, psC64 vmin, psC64 max, psC64 vmax) 270 { 271 int numClipped = 0; 272 unsigned int numRows; 273 unsigned int numCols; 274 psF64 realMin = creal(min); 275 psF64 imagMin = cimag(min); 276 psF64 realMax = creal(max); 277 psF64 imagMax = cimag(max); 278 279 if (input == NULL) { 280 return 0; 281 } 282 283 if ( realMax < realMin ) { 284 psError(__func__,"psImageClipComplexRegion can not be invoked with " 285 "max < min in the real image space."); 286 return 0; 287 } 288 if ( imagMax < imagMin ) { 289 psError(__func__,"psImageClipComplexRegion can not be invoked with " 290 "max < min in the imaginary image space."); 291 return 0; 292 } 293 294 numRows = input->numRows; 295 numCols = input->numCols; 296 297 switch (input->type.type) { 298 299 #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \ 300 case PS_TYPE_##type: { \ 301 if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \ 302 realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \ 303 psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \ 304 typename " pixel range", \ 305 realfcn(vmin),imagfcn(vmin)); \ 306 } \ 307 if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \ 308 realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \ 309 psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \ 310 typename " pixel range", \ 311 realfcn(vmax),imagfcn(vmax)); \ 312 } \ 313 for (unsigned int row = 0;row<numRows;row++) { \ 314 ps##type* inputRow = input->data.type[row]; \ 315 for (unsigned int col = 0; col < numCols; col++) { \ 316 if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \ 317 inputRow[col] = (ps##type)vmin; \ 318 numClipped++; \ 319 } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMax) ){ \ 320 inputRow[col] = (ps##type)vmax; \ 321 numClipped++; \ 322 } \ 323 } \ 324 } \ 325 } \ 326 break; 327 328 psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf) 329 psImageClipComplexRegionCase(C64,"psC64",creal,cimag) 330 331 default: 332 psError(__func__,"psImageClip does not support the given datatype (%d)", 333 input->type.type); 334 } 335 336 return numClipped; 337 } 338 339 bool getSpecifiedStatValue(const psStats* stats, double* value) 340 { 341 342 switch (stats->options & 343 ! (PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE)) { 344 case PS_STAT_SAMPLE_MEAN: 345 *value = stats->sampleMean; 346 return true; 347 348 case PS_STAT_SAMPLE_MEDIAN: 349 *value = stats->sampleMedian; 350 return true; 351 352 case PS_STAT_SAMPLE_STDEV: 353 *value = stats->sampleStdev; 354 return true; 355 356 case PS_STAT_ROBUST_MEAN: 357 *value = stats->robustMean; 358 return true; 359 360 case PS_STAT_ROBUST_MEDIAN: 361 *value = stats->robustMedian; 362 return true; 363 364 case PS_STAT_ROBUST_MODE: 365 *value = stats->robustMode; 366 return true; 367 368 case PS_STAT_ROBUST_STDEV: 369 *value = stats->robustStdev; 370 return true; 371 372 case PS_STAT_CLIPPED_MEAN: 373 *value = stats->clippedMean; 374 return true; 375 376 case PS_STAT_CLIPPED_STDEV: 377 *value = stats->clippedStdev; 378 return true; 379 380 case PS_STAT_MAX: 381 *value = stats->max; 382 return true; 383 384 case PS_STAT_MIN: 385 *value = stats->min; 386 return true; 387 388 default: 389 return false; 390 } 391 } 392 393 394 psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats) 395 { 396 int inRows; 397 int inCols; 398 int outRows; 399 int outCols; 400 psVector* vec; // vector to hold the values of a single bin. 401 psStats* myStats; 402 double statVal; 403 404 if (in == NULL) { 405 psError(__func__,"Input image is NULL."); 406 return NULL; 407 } 408 409 if (scale < 1) { 410 psError(__func__,"The scale must be positive."); 411 return NULL; 412 } 413 414 if (stats == NULL) { 415 psError(__func__,"The stats input can not be NULL."); 416 return NULL; 417 } 418 419 if (getSpecifiedStatValue(stats,&statVal) == false) { 420 psError(__func__,"The stat options didn't specify a single supported statistic type."); 421 return NULL; 422 } 423 424 myStats = psAlloc(sizeof(psStats)); 425 *myStats = *stats; 426 427 vec = psVectorAlloc(scale*scale,in->type.type); 428 429 // create output image. 430 inRows = in->numRows; 431 inCols = in->numCols; 432 outRows = (inRows+scale-1) / scale; // round-up for remainders 433 outCols = (inCols+scale-1) / scale; // round-up for remainders 434 out = psImageRecycle(out,outCols,outRows,in->type.type); 435 436 #define PS_IMAGE_REBIN_CASE(type) \ 437 case PS_TYPE_##type: { \ 438 ps##type* vecData = vec->data.type; \ 439 for (int row = 0; row < outRows; row++) { \ 440 ps##type* outRowData = out->data.type[row]; \ 441 int inCurrentRow = row*scale; \ 442 int inNextRow = (row+1)*scale; \ 443 for (int col = 0; col < outCols; col++) { \ 444 int inCurrentCol = col*scale; \ 445 int inNextCol = (col+1)*scale; \ 446 int n = 0; \ 447 for (int inRow = inCurrentRow; inRow < inNextRow && inRow < inRows; inRow++) { \ 448 ps##type* inRowData = in->data.type[inRow]; \ 449 for (int inCol = inCurrentCol; inCol < inNextCol && inCol < inCols; inCol++) { \ 450 vecData[n++] = inRowData[inCol]; \ 451 } \ 452 } \ 453 vec->n = n; \ 454 myStats = psVectorStats(myStats,vec,NULL,0); \ 455 getSpecifiedStatValue(myStats,&statVal); \ 456 outRowData[col] = (ps##type)statVal; \ 457 } \ 458 } \ 459 } \ 460 break; 461 462 switch (in->type.type) { 463 PS_IMAGE_REBIN_CASE(U8); 464 PS_IMAGE_REBIN_CASE(U16); 465 PS_IMAGE_REBIN_CASE(U32); 466 PS_IMAGE_REBIN_CASE(U64); 467 PS_IMAGE_REBIN_CASE(S8); 468 PS_IMAGE_REBIN_CASE(S16); 469 PS_IMAGE_REBIN_CASE(S32); 470 PS_IMAGE_REBIN_CASE(S64); 471 PS_IMAGE_REBIN_CASE(F32); 472 PS_IMAGE_REBIN_CASE(F64); 473 PS_IMAGE_REBIN_CASE(C32); 474 PS_IMAGE_REBIN_CASE(C64); 475 default: 476 psError(__func__,"Input image type not supported."); 477 psFree(out); 478 out = NULL; 479 } 480 481 psFree(vec); 482 psFree(myStats); 483 484 return out; 485 }
Note:
See TracChangeset
for help on using the changeset viewer.
