Changeset 15179 for trunk/psLib/src/fits/psFits.c
- Timestamp:
- Oct 3, 2007, 11:27:21 AM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/fits/psFits.c (modified) (28 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/fits/psFits.c
r14878 r15179 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1.7 1$ $Name: not supported by cvs2svn $10 * @date $Date: 2007- 09-18 03:01:17$9 * @version $Revision: 1.72 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-10-03 21:27:21 $ 11 11 * 12 12 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 20 20 21 21 #include "psFits.h" 22 #include "psFitsHeader.h" 22 23 #include "string.h" 23 24 #include "psError.h" … … 65 66 return false; 66 67 } 67 fits->fd = NULL;68 fits->fd = NULL; 68 69 } 69 70 return true; … … 74 75 if (!fits) return; 75 76 if (fits->fd) { 76 fitsClose(fits);77 fitsClose(fits); 77 78 } 78 79 psFree (fits->extword); … … 81 82 bool psFitsClose(psFits* fits) 82 83 { 83 if (fits == NULL) { 84 psError(PS_ERR_BAD_PARAMETER_NULL, true, 85 _("The input psFits object can not NULL.")); 86 return false; 87 } 84 PS_ASSERT_FITS_NON_NULL(fits, false); 88 85 89 86 bool status = fitsClose(fits); … … 95 92 psFits* psFitsOpen(const char* name, const char* mode) 96 93 { 94 PS_ASSERT_STRING_NON_EMPTY(name, NULL); 95 97 96 int status = 0; 98 97 fitsfile *fptr = NULL; /* Pointer to the FITS file */ 99 100 if (name == NULL) {101 psError(PS_ERR_BAD_PARAMETER_NULL, true,102 _("Specified filename can not be NULL."));103 return NULL;104 }105 98 106 99 /* check the mode to determine how to open/create file */ … … 131 124 if (access(name, F_OK) == 0) { 132 125 // file exists, delete old one first 133 remove 134 (name); 126 remove(name); 135 127 } 136 128 … … 140 132 (void)fits_create_file 141 133 #endif 142 (&fptr, 143 name, 144 &status); 134 (&fptr, name, &status); 145 135 if (fptr == NULL || status != 0) { 146 char fitsErr[MAX_STRING_LENGTH] 147 ; 136 char fitsErr[MAX_STRING_LENGTH]; 148 137 fits_get_errstatus(status, fitsErr); 149 138 psError(PS_ERR_IO, true, … … 158 147 (void)fits_open_file 159 148 #endif 160 (&fptr, 161 name, 162 iomode, 163 &status); 149 (&fptr, name, iomode, &status); 164 150 if (fptr == NULL || status != 0) { 165 char fitsErr[MAX_STRING_LENGTH] 166 ; 151 char fitsErr[MAX_STRING_LENGTH]; 167 152 fits_get_errstatus(status, fitsErr); 168 153 psError(PS_ERR_IO, true, … … 177 162 fits->writable = (iomode == READWRITE); 178 163 fits->extword = NULL; 164 fits->conventions.compression = true; 179 165 psMemSetDeallocator(fits,(psFreeFunc)fitsFree); 180 166 … … 182 168 } 183 169 184 static void psFitsOptionsFree(psFitsOptions *opt) 185 { 186 psFree(opt->tilesize); 187 } 188 189 psFitsOptions* psFitsOptionsAlloc( 170 psErrorCode p_psFitsError(const char* filename, unsigned int lineno, const char* func, int status, 171 bool new, const char *errorMsg, ...) 172 { 173 if (status == 0) { 174 return PS_ERR_NONE; 175 } 176 177 va_list ap; // Variable arguments 178 va_start(ap, errorMsg); 179 psString msg = NULL; // Message to pass to psError 180 psStringAppendV(&msg, errorMsg, ap); 181 va_end(ap); 182 183 char cfitsioMsg[MAX_STRING_LENGTH]; // Error message from cfitsio 184 (void)fits_get_errstatus(status, cfitsioMsg); 185 186 psStringAppend(&msg, "[CFITSIO error: %s]", cfitsioMsg); 187 188 psErrorCode code = p_psError(filename, lineno, func, PS_ERR_IO, new, msg); // Error code 189 psFree(msg); 190 return code; 191 } 192 193 static void psFitsCompressionFree(psFitsCompression *comp) 194 { 195 PS_ASSERT_PTR_NON_NULL(comp,); 196 psFree(comp->tilesize); 197 } 198 199 psFitsCompression* psFitsCompressionAlloc( 190 200 psFitsCompressionType type, ///< type of compression 191 201 psVector *tilesize, ///< vector defining compression tile size … … 195 205 ) 196 206 { 197 psFitsOptions *opt = psAlloc(sizeof(psFitsOptions)); 198 199 opt->type = type; 200 opt->tilesize = psVectorCopy(NULL, tilesize, PS_DATA_S64); 201 opt->noisebits = noisebits; 202 opt->scale = scale; 203 opt->smooth = smooth; 204 205 psMemSetDeallocator(opt, (psFreeFunc) psFitsOptionsFree); 206 207 return opt; 207 psFitsCompression *comp = psAlloc(sizeof(psFitsCompression)); 208 psMemSetDeallocator(comp, (psFreeFunc) psFitsCompressionFree); 209 210 comp->type = type; 211 comp->tilesize = psVectorCopy(NULL, tilesize, PS_DATA_S64); 212 comp->noisebits = noisebits; 213 comp->scale = scale; 214 comp->smooth = smooth; 215 216 return comp; 208 217 } 209 218 … … 224 233 } 225 234 226 // move to the first HDU where extword == extname. this is equivalent to fits_movnam_hdu() for 227 // a user-defined word in place of EXTNAME 228 bool p_psFitsMoveExtName_UserKey(const psFits *fits, 229 const char *extname, 230 const char *extword) 231 { 232 PS_ASSERT_PTR_NON_NULL(fits, false); 233 PS_ASSERT_PTR_NON_NULL(extname, false); 234 PS_ASSERT_PTR_NON_NULL(extword, false); 235 236 int hdutype = 0; 237 char name[MAX_STRING_LENGTH]; 238 char extstring[MAX_STRING_LENGTH]; 239 240 sprintf (extstring, "'%s'", extname); 241 242 // NOTE: fits_* return 0 for success 243 for (int i = 1; true; i++) { 244 // are we able to read the next HDU? 245 246 int status = 0; 247 if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) { 248 char fitsErr[MAX_STRING_LENGTH]; 249 fits_get_errstatus(status, fitsErr); 250 psError(PS_ERR_LOCATION_INVALID, true, 251 _("Could not find HDU with %s = '%s'. CFITSIO Error: %s"), 252 extword, extname, fitsErr); 253 return false; 254 } 255 // is there a keyword called 'extword'? (read as string regardless of type) 256 status = 0; 257 if (fits_read_keyword(fits->fd, (char *)extword, name, NULL, &status)) { 258 continue; 259 } 260 // if this was read as a string, we will have leading and trailing single-quotes 261 // try both for comparison 262 263 // do we have the right hdu (names match)? 264 if (!strcmp (name, extname) || !strcmp (name, extstring)) { 265 return true; 266 } 267 } 268 psAbort("we should not reach here"); 269 } 270 271 // XXX I will need to define a low-level function p_psFitsMoveExtName_UserKey () which 272 // uses fits_movabs_hdu() to replicate the functionality of fits_movnam_hdu using an 273 // alternate name for EXTNAME 235 // Files compressed with cfitsio's "imcopy" program may have multiple EXTNAME keywords, with the first set to 236 // COMPRESSED_IMAGE. However, fits_movnam_hdu won't find the second (proper) value of EXTNAME, and so can 237 // fail to find a perfectly legitimate extension, simply because imcopy does something silly. However, we 238 // really want to be able to read these files (MegaCam data are shipped as imcopy-compressed images). 239 // Therefore, we implement our own version of moving to an extension specified by name. The pure cfitsio 240 // version is used if "conventions.compression" handling is turned off in the psFits structure. 274 241 bool psFitsMoveExtName(const psFits* fits, 275 242 const char* extname) 276 243 { 277 int status = 0; 278 279 if (fits == NULL) { 280 psError(PS_ERR_BAD_PARAMETER_NULL, true, 281 _("The input psFits object can not NULL.")); 282 return false; 283 } 284 285 if (extname == NULL) { 286 psError(PS_ERR_BAD_PARAMETER_NULL, true, 287 _("Specified extension name can not be NULL.")); 288 return false; 289 } 290 291 if (fits->extword != NULL) { 292 bool result = p_psFitsMoveExtName_UserKey(fits, extname, fits->extword); 293 return (result); 294 } 295 296 if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) { 297 char fitsErr[MAX_STRING_LENGTH]; 298 fits_get_errstatus(status, fitsErr); 299 psError(PS_ERR_LOCATION_INVALID, true, 300 _("Could not find HDU '%s'. CFITSIO Error: %s"), 301 extname, fitsErr); 302 return false; 303 } 304 305 return true; 244 PS_ASSERT_FITS_NON_NULL(fits, false); 245 PS_ASSERT_STRING_NON_EMPTY(extname, false); 246 247 int status = 0; 248 249 if (!fits->conventions.compression && !fits->extword) { 250 // User wants to use cfitsio. Good luck to them! 251 if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) { 252 psFitsError(status, true, _("Could not find HDU '%s'"), extname); 253 return false; 254 } 255 return true; 256 } 257 258 bool ignoreCI = (fits->conventions.compression && 259 (strcmp(extname, "COMPRESSED_IMAGE") != 0)); // Ignore COMPRESSED_IMAGE extension name? 260 char *extword = (fits->extword ? fits->extword : "EXTNAME"); // Word to use as extension name 261 262 #if 0 263 // XXX Future optimisation: loop through from the current HDU to the end, then from the start to the 264 // current position. This will save seeking through the file multiple times. 265 int currentExt = psFitsGetExtNum(fits); // Current extension number 266 int numExt = psFitsGetSize(fits); // Total number of extensions 267 #endif 268 269 for (int i = 1; true; i++) { 270 int hdutype = 0; 271 if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) { 272 // We've run off the end 273 psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname); 274 return false; 275 } 276 // Is there a keyword called 'extword'? (read as string regardless of type) 277 char name[MAX_STRING_LENGTH]; // Name of extension 278 if (fits_read_keyword(fits->fd, extword, name, NULL, &status)) { 279 // It doesn't exist in the header. 280 // This isn't the extension you're looking for. Move along. 281 status = 0; 282 continue; 283 } 284 char *fixed = p_psFitsHeaderParseString(name); // Parsed version (removing quotes and spaces) 285 286 if (ignoreCI && strcmp(fixed, "COMPRESSED_IMAGE") == 0) { 287 // Read it again, Sam 288 if (fits_read_keyword(fits->fd, extword, name, NULL, &status)) { 289 status = 0; 290 continue; 291 } 292 fixed = p_psFitsHeaderParseString(name); 293 } 294 295 if (strcmp(fixed, extname) == 0) { 296 // We've arrived 297 return true; 298 } 299 } 300 psAbort("Should never reach here."); 306 301 } 307 302 … … 310 305 bool relative) 311 306 { 312 if (fits == NULL) { 313 psError(PS_ERR_BAD_PARAMETER_NULL, true, 314 _("The input psFits object can not NULL.")); 315 return false; 316 } 307 PS_ASSERT_FITS_NON_NULL(fits, false); 317 308 318 309 int status = 0; … … 346 337 bool psFitsMoveLast(psFits* fits) 347 338 { 348 if (fits == NULL) { 349 psError(PS_ERR_BAD_PARAMETER_NULL, true, 350 _("The input psFits object can not NULL.")); 351 return false; 352 } 339 PS_ASSERT_FITS_NON_NULL(fits, false); 340 353 341 int size = psFitsGetSize(fits); 354 342 if (size == 0) { // empty file -- no action needed … … 361 349 int psFitsGetExtNum(const psFits* fits) 362 350 { 351 PS_ASSERT_FITS_NON_NULL(fits, false); 363 352 int hdunum; 364 365 if (fits == NULL) {366 psError(PS_ERR_BAD_PARAMETER_NULL, true,367 _("The input psFits object can not NULL."));368 return PS_FITS_TYPE_NONE;369 }370 371 372 353 return fits_get_hdu_num(fits->fd,&hdunum) - 1; 373 354 } … … 375 356 psString psFitsGetExtName(const psFits* fits) 376 357 { 377 if (fits == NULL) { 378 psError(PS_ERR_BAD_PARAMETER_NULL, true, 379 _("The input psFits object can not NULL.")); 380 return NULL; 381 } 358 PS_ASSERT_FITS_NON_NULL(fits, NULL); 382 359 383 360 int status = 0; … … 389 366 psError(PS_ERR_BAD_PARAMETER_NULL, true, 390 367 _("Header keyword %s is not found"), extword); 391 return NULL;368 return NULL; 392 369 } 393 370 return psStringCopy(name); … … 396 373 bool psFitsSetExtName(psFits* fits, const char* name) 397 374 { 398 if (fits == NULL) { 399 psError(PS_ERR_BAD_PARAMETER_NULL, true, 400 _("The input psFits object can not NULL.")); 401 return false; 402 } 403 404 if (name == NULL) { 405 psError(PS_ERR_BAD_PARAMETER_NULL, true, 406 _("Specified extension name can not be NULL.")); 407 return false; 408 } 375 PS_ASSERT_FITS_NON_NULL(fits, false); 376 PS_ASSERT_STRING_NON_EMPTY(name, false); 409 377 410 378 int status = 0; … … 428 396 bool relative) 429 397 { 430 if (fits == NULL) { 431 psError(PS_ERR_BAD_PARAMETER_NULL, true, 432 _("The input psFits object can not NULL.")); 433 return false; 434 } 398 PS_ASSERT_FITS_NON_NULL(fits, false); 435 399 436 400 if (! fits->writable) { … … 466 430 const char* extname) 467 431 { 468 if (fits == NULL) { 469 psError(PS_ERR_BAD_PARAMETER_NULL, true, 470 _("The input psFits object can not NULL.")); 471 return false; 472 } 432 PS_ASSERT_FITS_NON_NULL(fits, false); 433 PS_ASSERT_STRING_NON_EMPTY(extname, false); 473 434 474 435 if (! fits->writable) { … … 504 465 int psFitsGetSize(const psFits* fits) 505 466 { 506 if (fits == NULL) { 507 psError(PS_ERR_BAD_PARAMETER_NULL, true, 508 _("The input psFits object can not NULL.")); 509 return 0; 510 } 467 PS_ASSERT_FITS_NON_NULL(fits, 0); 511 468 512 469 int num = 0; … … 527 484 psFitsType psFitsGetExtType(const psFits* fits) 528 485 { 529 if (fits == NULL) { 530 psError(PS_ERR_BAD_PARAMETER_NULL, true, 531 _("The input psFits object can not NULL.")); 532 return PS_FITS_TYPE_NONE; 533 } 486 PS_ASSERT_FITS_NON_NULL(fits, PS_FITS_TYPE_NONE); 534 487 535 488 int status = 0; … … 556 509 bool psFitsTruncate(psFits* fits) 557 510 { 558 if (fits == NULL) { 559 psError(PS_ERR_BAD_PARAMETER_NULL, true, 560 _("The input psFits object can not NULL.")); 561 return PS_FITS_TYPE_NONE; 562 } 511 PS_ASSERT_FITS_NON_NULL(fits, NULL); 563 512 564 513 if (! fits->writable) { … … 597 546 ) 598 547 { 548 PS_ASSERT_FITS_NON_NULL(fits, false); 549 599 550 // convert psFitsCompressionType to cfitsio compression types 600 551 int comptype; … … 640 591 psAbort("can't map (long) type to a psLib type"); 641 592 } 593 psFree(dim); 642 594 // status check belongs to fits_set_tile_dim() call 643 595 if (status) { … … 681 633 } 682 634 683 684 bool psFitsSetOptions( 635 psFitsCompression *psFitsCompressionGet(psFits* fits) 636 { 637 PS_ASSERT_FITS_NON_NULL(fits, NULL); 638 639 int status = 0; // cfitsio status 640 641 psFitsCompressionType type = psFitsCompressionGetType(fits); 642 if (type < 0) { 643 psError(PS_ERR_UNKNOWN, false, "Unable to get compression type."); 644 return NULL; 645 } 646 647 psElemType tileType; // Type corresponding to "long" 648 if (sizeof(long) == sizeof(psS64)) { 649 tileType = PS_TYPE_S64; 650 } else if (sizeof(long) == sizeof(psS32)) { 651 tileType = PS_TYPE_S32; 652 } else { 653 psAbort("can't map (long) type to a psLib type"); 654 } 655 656 psVector *tiles = psVectorAlloc(3, tileType); // Tile sizes 657 if (fits_get_tile_dim(fits->fd, 3, (long*)tiles->data.U8, &status)) { 658 psFitsError(status, true, "Unable to get compression tile sizes."); 659 psFree(tiles); 660 return NULL; 661 } 662 663 int noisebits; // Noise bits for compression 664 if (fits_get_noise_bits(fits->fd, &noisebits, &status)) { 665 psFitsError(status, true, "Unable to get compression noise bits."); 666 psFree(tiles); 667 return NULL; 668 } 669 670 int hscale = 0, hsmooth = 0; // Scaling and smoothing for HCOMPRESS 671 672 #if FITS_HCOMP 673 if (fits_get_hcomp_scale(fits->fd, &hscale, &status)) { 674 psFitsError(status, true, "Unable to get HCOMPRESS scaling."); 675 psFree(tiles); 676 return NULL; 677 } 678 if (fits_get_hcomp_smooth(fits->fd, &hsmooth, &status)) { 679 psFitsError(status, true, "Unable to get HCOMPRESS smoothing."); 680 psFree(tiles); 681 return NULL; 682 } 683 #endif // FITS_HCOMP 684 685 psFitsCompression *compress = psFitsCompressionAlloc(type, tiles, noisebits, hscale, hsmooth); 686 psFree(tiles); // Drop reference 687 688 return compress; 689 } 690 691 psFitsCompressionType psFitsCompressionGetType(psFits* fits) 692 { 693 PS_ASSERT_FITS_NON_NULL(fits, -1); 694 695 int status = 0; // cfitsio status 696 int comptype = 0; // cfitsio compression type 697 if (fits_get_compression_type(fits->fd, &comptype, &status)) { 698 psFitsError(status, true, "Unable to get compression type."); 699 return -1; 700 } 701 702 psFitsCompressionType type; 703 switch (comptype) { 704 case 0: 705 type = PS_FITS_COMPRESS_NONE; 706 break; 707 case GZIP_1: 708 type = PS_FITS_COMPRESS_GZIP; 709 break; 710 case RICE_1: 711 type = PS_FITS_COMPRESS_RICE; 712 break; 713 case HCOMPRESS_1: 714 type = PS_FITS_COMPRESS_HCOMPRESS; 715 break; 716 case PLIO_1: 717 type = PS_FITS_COMPRESS_PLIO; 718 break; 719 default: 720 psError(PS_ERR_UNKNOWN, true, "cfitsio reports unknown compression type."); 721 return -1; 722 } 723 724 return type; 725 } 726 727 728 bool psFitsCompressionApply( 685 729 psFits* fits, ///< psFits object to close 686 psFits Options *opt///< options object730 psFitsCompression *comp ///< options object 687 731 ) 688 732 { 689 return psFitsSetCompression( 690 fits, 691 opt->type, 692 opt->tilesize, 693 opt->noisebits, 694 opt->scale, 695 opt->smooth); 733 return psFitsSetCompression(fits, comp->type, comp->tilesize, comp->noisebits, comp->scale, comp->smooth); 696 734 } 697 735 … … 826 864 827 865 866 psFitsCompressionType psFitsCompressionTypeFromString(const char *string) 867 { 868 if (!string || strlen(string) == 0) { 869 psWarning("Unable to identify compression type --- none set."); 870 return PS_FITS_COMPRESS_NONE; 871 } 872 873 if (strcmp(string, "GZIP") == 0) return PS_FITS_COMPRESS_GZIP; 874 if (strcmp(string, "RICE") == 0) return PS_FITS_COMPRESS_RICE; 875 if (strcmp(string, "HCOMPRESS") == 0) return PS_FITS_COMPRESS_HCOMPRESS; 876 if (strcmp(string, "PLIO") == 0) return PS_FITS_COMPRESS_PLIO; 877 878 psWarning("Unable to identify compression type (%s) --- none set.", string); 879 return PS_FITS_COMPRESS_NONE; 880 }
Note:
See TracChangeset
for help on using the changeset viewer.
