00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include "fitsio.h"
00013 #include "cfitsio.h"
00014 #include "jsoc.h"
00015 #include "foundation.h"
00016 #include "tasrw.h"
00017 #include "xassert.h"
00018
00019
00020
00021 #ifdef __CFISTIO_DEBUG__ //Turn on/off DEBUGMSG
00022 #define DEBUGMSG(msg) printf msg //ex: DEBUGMSG ((stderr, "Hello World %d\n", 123));
00023 #else
00024 #define DEBUGMSG(msg) //nop
00025 #endif
00026
00027 const unsigned int kInfoPresent_SIMPLE = 0x00000001;
00028 const unsigned int kInfoPresent_EXTEND = 0x00000002;
00029 const unsigned int kInfoPresent_BLANK = 0x00000004;
00030 const unsigned int kInfoPresent_BSCALE = 0x00000008;
00031 const unsigned int kInfoPresent_BZERO = 0x00000010;
00032 const unsigned int kInfoPresent_Dirt = 0x00000020;
00033
00034 #define kMISSPIXBLOCK 1310720
00035
00036
00037
00038
00039 static int cfitsio_keyval2int(const CFITSIO_KEYWORD *kw, int *stat)
00040 {
00041 int val = 0;
00042 int err = 1;
00043
00044 if (kw)
00045 {
00046 switch(kw->key_type)
00047 {
00048 case kFITSRW_Type_String:
00049 if (kw->key_value.vs)
00050 {
00051 err = (sscanf(kw->key_value.vs, "%d", &val) != 1);
00052 }
00053 else
00054 {
00055
00056 err = 0;
00057 }
00058 break;
00059 case kFITSRW_Type_Logical:
00060 val = (int)(kw->key_value.vl);
00061 err = 0;
00062 break;
00063 case kFITSRW_Type_Integer:
00064 val = (int)(kw->key_value.vi);
00065 err = 0;
00066 break;
00067 case kFITSRW_Type_Float:
00068 val = (int)(kw->key_value.vf);
00069 err = 0;
00070 break;
00071 default:
00072 fprintf(stderr, "Unsupported data type '%d'.", kw->key_type);
00073 }
00074 }
00075
00076 if (stat)
00077 {
00078 *stat = err;
00079 }
00080
00081 return val;
00082 }
00083
00084 static long long cfitsio_keyval2longlong(const CFITSIO_KEYWORD *kw, int *stat)
00085 {
00086 long long val = 0;
00087 int err = 1;
00088
00089 if (kw)
00090 {
00091 switch(kw->key_type)
00092 {
00093 case kFITSRW_Type_String:
00094 if (kw->key_value.vs)
00095 {
00096 err = (sscanf(kw->key_value.vs, "%lld", &val) != 1);
00097 }
00098 else
00099 {
00100 err = 0;
00101 }
00102 break;
00103 case kFITSRW_Type_Logical:
00104 val = (long long)(kw->key_value.vl);
00105 err = 0;
00106 break;
00107 case kFITSRW_Type_Integer:
00108 val = (long long)(kw->key_value.vi);
00109 err = 0;
00110 break;
00111 case kFITSRW_Type_Float:
00112 val = (long long)(kw->key_value.vf);
00113 err = 0;
00114 break;
00115 default:
00116 fprintf(stderr, "Unsupported data type '%d'.", kw->key_type);
00117 }
00118 }
00119
00120 if (stat)
00121 {
00122 *stat = err;
00123 }
00124
00125 return val;
00126 }
00127
00128 static double cfitsio_keyval2double(const CFITSIO_KEYWORD *kw, int *stat)
00129 {
00130 double val = 0;
00131 int err = 1;
00132
00133 if (kw)
00134 {
00135 switch(kw->key_type)
00136 {
00137 case kFITSRW_Type_String:
00138 if (kw->key_value.vs)
00139 {
00140 err = (sscanf(kw->key_value.vs, "%lf", &val) != 1);
00141 }
00142 else
00143 {
00144 err = 0;
00145 }
00146 break;
00147 case kFITSRW_Type_Logical:
00148 val = (double)(kw->key_value.vl);
00149 err = 0;
00150 break;
00151 case kFITSRW_Type_Integer:
00152 val = (double)(kw->key_value.vi);
00153 err = 0;
00154 break;
00155 case kFITSRW_Type_Float:
00156 val = (double)(kw->key_value.vf);
00157 err = 0;
00158 break;
00159 default:
00160 fprintf(stderr, "Unsupported data type '%d'.", kw->key_type);
00161 }
00162 }
00163
00164 if (stat)
00165 {
00166 *stat = err;
00167 }
00168
00169 return val;
00170 }
00171
00172 static int cfitsio_writekeys(fitsfile *fptr, CFITSIO_KEYWORD *keylist)
00173 {
00174 char card[FLEN_CARD];
00175 CFITSIO_KEYWORD* kptr = NULL;
00176 int err = CFITSIO_SUCCESS;
00177 int cfiostat = CFITSIO_SUCCESS;
00178
00179 if (keylist)
00180 {
00181 kptr = keylist;
00182
00183 while (kptr)
00184 {
00185 if (!strcmp(kptr->key_name,"HISTORY"))
00186 {
00187 if (kptr->key_value.vs)
00188 {
00189 fits_write_history(fptr, kptr->key_value.vs, &cfiostat);
00190 }
00191 }
00192 else if (!strcmp(kptr->key_name,"COMMENT"))
00193 {
00194 if (kptr->key_value.vs)
00195 {
00196 fits_write_comment(fptr, kptr->key_value.vs, &cfiostat);
00197 }
00198 }
00199 else
00200 {
00201 if (cfitsio_key_to_card(kptr, card) != CFITSIO_SUCCESS)
00202 {
00203 err = CFITSIO_ERROR_ARGS;
00204 break;
00205 }
00206
00207 if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
00208 {
00209 if(fits_write_record(fptr, card, &cfiostat))
00210 {
00211 err = CFITSIO_ERROR_LIBRARY;
00212 break;
00213 }
00214 }
00215 }
00216
00217 if (cfiostat != CFITSIO_SUCCESS)
00218 {
00219 err = CFITSIO_ERROR_LIBRARY;
00220 break;
00221 }
00222
00223 kptr = kptr->next;
00224 }
00225 }
00226
00227 return err;
00228 }
00229
00230
00231
00232
00233
00234 int cfitsio_free_keys(CFITSIO_KEYWORD** keylist)
00235 {
00236 if (keylist)
00237 {
00238 CFITSIO_KEYWORD *kptr = *keylist;
00239 CFITSIO_KEYWORD *del = NULL;
00240
00241 while (kptr)
00242 {
00243 del = kptr;
00244 kptr = kptr->next;
00245
00246 if (del->key_type == kFITSRW_Type_String && del->key_value.vs)
00247 {
00248 free(del->key_value.vs);
00249 del->key_value.vs = NULL;
00250 }
00251
00252 free(del);
00253 }
00254
00255 *keylist = NULL;
00256 }
00257 return CFITSIO_SUCCESS;
00258 }
00259
00260 int cfitsio_create_key(const char *name, const char type, const char *comment, const void *value, const char *format, CFITSIO_KEYWORD **keyOut)
00261 {
00262 CFITSIO_KEYWORD *rv = NULL;
00263 int err = CFITSIO_SUCCESS;
00264
00265 if (name && value && keyOut)
00266 {
00267 rv = (CFITSIO_KEYWORD *)calloc(1, sizeof(CFITSIO_KEYWORD));
00268
00269 if (!rv)
00270 {
00271 fprintf(stderr, "cfitsio_create_key(): out of memory\n");
00272 err = CFITSIO_ERROR_OUT_OF_MEMORY;
00273 }
00274 else
00275 {
00276 snprintf(rv->key_name, FLEN_KEYWORD, "%s", name);
00277 rv->key_type = type;
00278
00279 switch (type)
00280 {
00281 case( 'X'):
00282 case (kFITSRW_Type_String):
00283
00284
00285
00286
00287 rv->key_value.vs = strdup((char *)value);
00288 break;
00289 case (kFITSRW_Type_Logical):
00290 rv->key_value.vl = *((int *)value);
00291 break;
00292 case (kFITSRW_Type_Integer):
00293 rv->key_value.vi = *((long long *)value);
00294 break;
00295 case (kFITSRW_Type_Float):
00296 rv->key_value.vf = *((double *)value);
00297 break;
00298 default:
00299 fprintf(stderr, "Invalid FITSRW keyword type '%c'.\n", (char)type);
00300 err = CFITSIO_ERROR_ARGS;
00301 break;
00302 }
00303
00304 if (comment)
00305 {
00306 snprintf(rv->key_comment, FLEN_COMMENT, "%s", comment);
00307 }
00308
00309 if (format)
00310 {
00311 snprintf(rv->key_format, CFITSIO_MAX_FORMAT, "%s", format);
00312 }
00313 }
00314 }
00315 else
00316 {
00317 err = CFITSIO_ERROR_ARGS;
00318 }
00319
00320 if (keyOut)
00321 {
00322 *keyOut = rv;
00323 rv = NULL;
00324 }
00325
00326 return err;
00327 }
00328
00329
00330
00331
00332 int cfitsio_append_key(CFITSIO_KEYWORD** keylist,
00333 char *name,
00334 char type,
00335 char *comment,
00336 void * value,
00337 const char *format)
00338 {
00339 CFITSIO_KEYWORD *node, *last;
00340 int error_code = CFITSIO_SUCCESS;
00341
00342
00343 if (name && value)
00344 {
00345 node = (CFITSIO_KEYWORD *) malloc(sizeof(CFITSIO_KEYWORD));
00346
00347 if (!node) return CFITSIO_ERROR_OUT_OF_MEMORY;
00348 else
00349 {
00350 memset(node, 0, sizeof(CFITSIO_KEYWORD));
00351 node->next = NULL;
00352
00353
00354 if (*keylist)
00355 {
00356 last = *keylist;
00357 while(last->next) last = last->next;
00358 last->next = node;
00359 }
00360 else
00361 {
00362 *keylist = node;
00363 }
00364
00365 snprintf(node->key_name, FLEN_KEYWORD, "%s", name);
00366 node->key_type = type;
00367
00368
00369 switch (type)
00370 {
00371 case( 'X'):
00372 case (kFITSRW_Type_String):
00373
00374
00375
00376
00377 node->key_value.vs = strdup((char *)value);
00378 break;
00379 case (kFITSRW_Type_Logical):
00380 node->key_value.vl = *((int *)value);
00381 break;
00382 case (kFITSRW_Type_Integer):
00383 node->key_value.vi = *((long long *)value);
00384 break;
00385 case (kFITSRW_Type_Float):
00386 node->key_value.vf = *((double *)value);
00387 break;
00388 default:
00389 fprintf(stderr, "Invalid FITSRW keyword type '%c'.\n", (char)type);
00390 error_code = CFITSIO_ERROR_ARGS;
00391 break;
00392 }
00393
00394 if (comment)
00395 {
00396 snprintf(node->key_comment, FLEN_COMMENT, "%s", comment);
00397 }
00398
00399 if (format)
00400 {
00401 snprintf(node->key_format, CFITSIO_MAX_FORMAT, "%s", format);
00402 }
00403 }
00404 }
00405 else
00406 {
00407 error_code = CFITSIO_ERROR_ARGS;
00408 }
00409
00410 return error_code;
00411
00412 }
00413
00414
00415
00416
00417
00418
00419
00420 int cfitsio_dump_image(void* image, CFITSIO_IMAGE_INFO* info, long from_row,
00421 long to_row, long from_col, long to_col)
00422 {
00423 short* iptr;
00424 long i, j;
00425
00426 DEBUGMSG((stderr,"In cfitsio_dump_image() => image = %p\n", image));
00427
00428 if((from_row < 1)||(to_row > info->naxes[1])||(from_col < 1)||
00429 (to_col > info->naxes[0]))
00430 {
00431 DEBUGMSG((stderr,"cfitsio_dump_image() out of range.\n"));
00432 return CFITSIO_FAIL;
00433 }
00434
00435 for(i=from_row;i<=to_row;i++)
00436 {
00437 iptr = ((short*) (image)) + ((i-1)* info->naxes[0])+ (from_col-1);
00438 for(j=from_col;j<=to_col;j++,iptr++)
00439 {
00440 printf("%d ",*iptr);
00441 }
00442 printf("\n");
00443 }
00444
00445 return CFITSIO_SUCCESS;
00446 }
00447
00448
00449
00450 int cfitsio_free_image_info(CFITSIO_IMAGE_INFO** image_info)
00451 {
00452 if(*image_info) free(*image_info);
00453 *image_info = NULL;
00454
00455 return CFITSIO_SUCCESS;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 static int cfitsio_read_keylist_and_image_info(fitsfile* fptr, CFITSIO_KEYWORD** keylistout, CFITSIO_IMAGE_INFO** image_info)
00470 {
00471
00472 char card[FLEN_CARD];
00473 int status = 0;
00474 int nkeys;
00475 int error_code = CFITSIO_FAIL;
00476
00477
00478 CFITSIO_KEYWORD* node, *last, *kptr;
00479
00480 char key_name[FLEN_KEYWORD];
00481 char key_value[FLEN_VALUE];
00482
00483 int len, i;
00484
00485 CFITSIO_KEYWORD *keylist = NULL;
00486
00487 int currHDU = 0;
00488 int val = 0;
00489
00490
00491
00492 if(keylistout && *keylistout)
00493 {
00494 cfitsio_free_keys(keylistout);
00495 *keylistout = NULL;
00496 }
00497
00498 if(fits_get_hdrspace(fptr, &nkeys, NULL, &status))
00499 {
00500 error_code = CFITSIO_ERROR_LIBRARY;
00501 goto error_exit;
00502 }
00503
00504 for(i=1; i<=nkeys; i++)
00505 {
00506 if(fits_read_record(fptr, i, card, &status))
00507 {
00508 error_code = CFITSIO_ERROR_LIBRARY;
00509 goto error_exit;
00510 }
00511
00512 if (fits_get_keyclass(card) == TYP_CMPRS_KEY)
00513 {
00514 continue;
00515 }
00516
00517 if(fits_get_keyname(card, key_name, &len, &status))
00518 {
00519 error_code = CFITSIO_ERROR_LIBRARY;
00520 goto error_exit;
00521 }
00522
00523 node = (CFITSIO_KEYWORD *) malloc(sizeof(CFITSIO_KEYWORD));
00524
00525 if(node == NULL)
00526 {
00527 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00528 goto error_exit;
00529 }
00530
00531 memset(node, 0, sizeof(CFITSIO_KEYWORD));
00532
00533 if(keylist==NULL)
00534 {
00535 keylist = node;
00536 node->next = NULL;
00537 last = node;
00538 }
00539 else
00540 {
00541 node->next = NULL;
00542 last->next = node;
00543 last = node;
00544 }
00545
00546
00547 if((!strcmp(key_name,"COMMENT")) || (!strcmp(key_name,"HISTORY")))
00548 {
00549 strcpy(node->key_name, key_name);
00550 node->key_type=kFITSRW_Type_String;
00551
00552 if(fits_parse_value(card, key_value, node->key_comment, &status))
00553 {
00554 error_code = CFITSIO_ERROR_LIBRARY;
00555 goto error_exit;
00556 }
00557
00558
00559
00560 node->key_value.vs = strdup(node->key_comment);
00561 }
00562 else
00563 {
00564
00565 strcpy(node->key_name, key_name);
00566 if(fits_parse_value(card, key_value, node->key_comment, &status))
00567 {
00568 error_code = CFITSIO_ERROR_LIBRARY;
00569 goto error_exit;
00570 }
00571
00572 if(strlen(key_value)) fits_get_keytype(key_value, &node->key_type, &status);
00573 else node->key_type = ' ';
00574
00575 switch(node->key_type)
00576 {
00577 case ('X'):
00578 case (kFITSRW_Type_String):
00579 node->key_value.vs = strdup(key_value);
00580 break;
00581 case (kFITSRW_Type_Logical): if (key_value[0]=='0') node->key_value.vl = 0;
00582 else node->key_value.vl = 1;
00583 break;
00584
00585 case (kFITSRW_Type_Integer): sscanf(key_value,"%lld", &node->key_value.vi);
00586 break;
00587
00588 case (kFITSRW_Type_Float): sscanf(key_value,"%lf", &node->key_value.vf);
00589 break;
00590
00591 case (' '):
00592 node->key_type = kFITSRW_Type_String;
00593 node->key_value.vs = strdup("");
00594 default :
00595 DEBUGMSG((stderr,"Key of unknown type detected [%s][%c]?\n",
00596 key_value,node->key_type));
00597 break;
00598 }
00599 }
00600 }
00601
00602
00603 if (status == END_OF_FILE) status = 0;
00604 if(status)
00605 {
00606 error_code = CFITSIO_FAIL;
00607 goto error_exit;
00608 }
00609
00610
00611
00612
00613
00614
00615 if(image_info && *image_info) cfitsio_free_image_info(image_info);
00616
00617 *image_info = (CFITSIO_IMAGE_INFO*) malloc(sizeof(CFITSIO_IMAGE_INFO));
00618 if(*image_info == NULL)
00619 {
00620 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00621 goto error_exit;
00622 }
00623
00624 memset((void*) *image_info,0, sizeof(CFITSIO_IMAGE_INFO));
00625
00626
00627 (*image_info)->blank =0;
00628 (*image_info)->bscale =1.0;
00629 (*image_info)->bzero =0.0;
00630
00631
00632
00633
00634 kptr = keylist;
00635 while (kptr && !status)
00636 {
00637 if(!strcmp(kptr->key_name,"SIMPLE"))
00638 {
00639 (*image_info)->simple = cfitsio_keyval2int(kptr, &status);
00640 if (!status)
00641 {
00642 (*image_info)->bitfield |= kInfoPresent_SIMPLE;
00643 }
00644 else
00645 {
00646 fprintf(stderr, "Invalid value for keyword 'SIMPLE'.\n");
00647 }
00648 }
00649 else if(!strcmp(kptr->key_name,"EXTEND"))
00650 {
00651 (*image_info)->extend = cfitsio_keyval2int(kptr, &status);
00652 if (!status)
00653 {
00654 (*image_info)->bitfield |= kInfoPresent_EXTEND;
00655 }
00656 else
00657 {
00658 fprintf(stderr, "Invalid value for keyword 'EXTEND'.\n");
00659 }
00660 }
00661 else if(!strcmp(kptr->key_name,"BLANK"))
00662 {
00663 (*image_info)->blank = cfitsio_keyval2longlong(kptr, &status);
00664 if (!status)
00665 {
00666 (*image_info)->bitfield |= kInfoPresent_BLANK;
00667 }
00668 else
00669 {
00670 fprintf(stderr, "Invalid value for keyword 'BLANK'.\n");
00671 }
00672 }
00673 else if(!strcmp(kptr->key_name,"BSCALE"))
00674 {
00675 (*image_info)->bscale = cfitsio_keyval2double(kptr, &status);
00676 if (!status)
00677 {
00678 (*image_info)->bitfield |= kInfoPresent_BSCALE;
00679 }
00680 else
00681 {
00682 fprintf(stderr, "Invalid value for keyword 'BSCALE'.\n");
00683 }
00684 }
00685 else if(!strcmp(kptr->key_name,"BZERO"))
00686 {
00687 (*image_info)->bzero = cfitsio_keyval2double(kptr, &status);
00688 if (!status)
00689 {
00690 (*image_info)->bitfield |= kInfoPresent_BZERO;
00691 }
00692 else
00693 {
00694 fprintf(stderr, "Invalid value for keyword 'BZERO'.\n");
00695 }
00696 }
00697
00698 kptr = kptr->next;
00699 }
00700
00701 if (status)
00702 {
00703 goto error_exit;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 fits_get_img_dim(fptr, &((*image_info)->naxis), &status);
00713 if((*image_info)->naxis == 0)
00714 {
00715
00716 error_code = CFITSIO_ERROR_DATA_EMPTY;
00717 goto error_exit;
00718 }
00719
00720
00721 fits_get_img_param(fptr, CFITSIO_MAX_DIM, &((*image_info)->bitpix), &((*image_info)->naxis),
00722 &((*image_info)->naxes[0]), &status);
00723
00724
00725
00726 fits_get_hdu_num(fptr, &currHDU);
00727 if (currHDU != 1)
00728 {
00729
00730 fits_movabs_hdu(fptr, 1, NULL, &status);
00731
00732
00733 fits_read_key(fptr, TLOGICAL, "SIMPLE", &val, NULL, &status);
00734 if (!status)
00735 {
00736 (*image_info)->simple = val;
00737 (*image_info)->bitfield |= kInfoPresent_SIMPLE;
00738 }
00739
00740 fits_read_key(fptr, TLOGICAL, "EXTEND", &val, NULL, &status);
00741 if (!status)
00742 {
00743 (*image_info)->extend = val;
00744 (*image_info)->bitfield |= kInfoPresent_EXTEND;
00745 }
00746
00747 fits_movabs_hdu(fptr, currHDU, NULL, &status);
00748 }
00749
00750 for(i=(*image_info)->naxis;i<(int) CFITSIO_MAX_DIM ;i++) (*image_info)->naxes[i]=0;
00751
00752 if (keylistout)
00753 {
00754 *keylistout = keylist;
00755 }
00756 else
00757 {
00758 cfitsio_free_keys(&keylist);
00759 }
00760
00761 return CFITSIO_SUCCESS;
00762
00763
00764 error_exit:
00765
00766 if(keylist) cfitsio_free_keys(&keylist);
00767
00768 if(image_info && *image_info)
00769 {
00770 free(*image_info);
00771 *image_info = NULL;
00772 }
00773
00774 return error_code;
00775
00776 }
00777
00778 int fitsrw_read_keylist_and_image_info(FITSRW_fhandle fhandle,
00779 CFITSIO_KEYWORD** keylistout,
00780 CFITSIO_IMAGE_INFO** image_info)
00781 {
00782 return cfitsio_read_keylist_and_image_info((fitsfile *)fhandle, keylistout, image_info);
00783 }
00784
00785
00786
00787 int fitsrw_readintfile(int verbose,
00788 char* fits_filename,
00789 CFITSIO_IMAGE_INFO** image_info,
00790 void** image,
00791 CFITSIO_KEYWORD** keylist)
00792 {
00793 fitsfile *fptr=NULL;
00794
00795 int status = 0;
00796 int error_code = CFITSIO_FAIL;
00797
00798 int data_type, bytepix, i;
00799 long npixels;
00800
00801 void* pixels = NULL;
00802
00803 char cfitsiostat[FLEN_STATUS];
00804
00805 int fileCreated = 0;
00806
00807
00808 fptr = fitsrw_getfptr(verbose, fits_filename, 0, &status, &fileCreated);
00809
00810 XASSERT(!fileCreated);
00811
00812 if (!fptr)
00813 {
00814 error_code = CFITSIO_ERROR_FILE_DOESNT_EXIST;
00815 goto error_exit;
00816 }
00817
00818
00819 error_code = cfitsio_read_keylist_and_image_info(fptr, keylist, image_info);
00820 if(error_code != CFITSIO_SUCCESS) goto error_exit;
00821
00822
00823 switch((*image_info)->bitpix)
00824 {
00825 case(BYTE_IMG): data_type = TBYTE; break;
00826 case(SHORT_IMG): data_type = TSHORT; break;
00827 case(LONG_IMG): data_type = TINT; break;
00828 case(LONGLONG_IMG):data_type = TLONGLONG; break;
00829 case(FLOAT_IMG): data_type = TFLOAT; break;
00830 case(DOUBLE_IMG): data_type = TDOUBLE; break;
00831 }
00832
00833 bytepix = abs((*image_info)->bitpix)/8;
00834
00835 npixels = 1;
00836 for(i=0;i<(*image_info)->naxis;i++) npixels *= (*image_info)->naxes[i];
00837
00838 pixels = (double*) calloc(npixels, bytepix);
00839 if(pixels == NULL)
00840 {
00841 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00842 goto error_exit;
00843 }
00844
00845
00846
00847
00848
00849
00850
00851 fits_set_bscale(fptr, 1.0, 0.0, &status);
00852 fits_set_imgnull(fptr, 0, &status);
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 if(fits_read_img(fptr, data_type, 1, npixels, NULL, pixels, NULL, &status))
00880 {
00881 error_code = CFITSIO_ERROR_LIBRARY;
00882 goto error_exit;
00883 }
00884
00885 if (fptr)
00886 {
00887
00888 fitsrw_closefptr(verbose, fptr);
00889 }
00890
00891
00892
00893
00894
00895
00896 if ((*image_info)->bitpix == BYTE_IMG)
00897 {
00898
00899
00900 long ipix;
00901 unsigned char *pDataIn = (unsigned char *)pixels;
00902 signed char *pDataOut = (signed char *)pixels;
00903
00904 for (ipix = 0; ipix < npixels; ipix++)
00905 {
00906 pDataOut[ipix] = (signed char)(pDataIn[ipix] - 128);
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 (*image_info)->bzero = 128.0 * (*image_info)->bscale + (*image_info)->bzero;
00930
00931
00932 (*image_info)->blank = (*image_info)->blank - 128;
00933 }
00934
00935
00936
00937 if(keylist==NULL)
00938 {
00939 cfitsio_free_keys(keylist);
00940 }
00941
00942 *image = pixels;
00943
00944 if (status == 0) return (CFITSIO_SUCCESS);
00945
00946 error_exit:
00947
00948 fits_get_errstatus(status, cfitsiostat);
00949 fprintf(stderr, "cfitsio error '%s'.\n", cfitsiostat);
00950
00951 cfitsio_free_these(image_info, &pixels, keylist);
00952
00953 if (fptr)
00954 {
00955
00956 fitsrw_closefptr(verbose, fptr);
00957 }
00958
00959 return error_code;
00960 }
00961
00962
00963
00964
00965 void cfitsio_free_these(CFITSIO_IMAGE_INFO** image_info,
00966 void** image,
00967 CFITSIO_KEYWORD** keylist)
00968 {
00969
00970 if(image_info)
00971 {
00972 free(*image_info);
00973 *image_info = NULL;
00974 }
00975
00976 if(image)
00977 {
00978 free(*image);
00979 *image = NULL;
00980 }
00981
00982
00983 if (keylist)
00984 {
00985 CFITSIO_KEYWORD *kptr = *keylist;
00986 CFITSIO_KEYWORD *del = NULL;
00987
00988 while (kptr)
00989 {
00990 del = kptr;
00991 kptr = kptr->next;
00992
00993 if (del->key_type == kFITSRW_Type_String && del->key_value.vs)
00994 {
00995 free(del->key_value.vs);
00996 del->key_value.vs = NULL;
00997 }
00998
00999 free(del);
01000 }
01001
01002 *keylist = NULL;
01003 }
01004
01005 }
01006
01007
01008
01009
01010 int fitsrw_writeintfile(int verbose,
01011 const char* fits_filename,
01012 CFITSIO_IMAGE_INFO* image_info,
01013 void* image,
01014 const char* compspec,
01015 CFITSIO_KEYWORD* keylist)
01016 {
01017
01018 fitsfile *fptr=NULL;
01019 int status=0, error_code = CFITSIO_FAIL;
01020 char filename[PATH_MAX];
01021 int data_type;
01022 int img_type;
01023 char cfitsiostat[FLEN_STATUS];
01024 long long oblank = 0;
01025
01026 long long npixels;
01027
01028 int i = 0;
01029
01030 void *misspix = NULL;
01031 long long pixleft;
01032 long long pixtowrt;
01033 long long pixptr;
01034
01035 int fileCreated = 0;
01036 long long imgSize = 0;
01037
01038
01039 if(image_info == NULL) return CFITSIO_ERROR_ARGS;
01040
01041
01042 for (i = 0, npixels = 1; i < image_info->naxis; i++)
01043 {
01044 npixels *= image_info->naxes[i];
01045 }
01046
01047 switch(image_info->bitpix)
01048 {
01049 case(BYTE_IMG): data_type = TSBYTE; img_type = SBYTE_IMG; break;
01050 case(SHORT_IMG): data_type = TSHORT; img_type = SHORT_IMG; break;
01051 case(LONG_IMG): data_type = TINT; img_type = LONG_IMG; break;
01052 case(LONGLONG_IMG): data_type = TLONGLONG; img_type = LONGLONG_IMG; break;
01053 case(FLOAT_IMG): data_type = TFLOAT; img_type = FLOAT_IMG; break;
01054 case(DOUBLE_IMG): data_type = TDOUBLE; img_type = DOUBLE_IMG; break;
01055 }
01056
01057 imgSize = (abs(img_type) / 8) * npixels;
01058
01059
01060 remove(fits_filename);
01061
01062
01063 if (compspec && *compspec)
01064 {
01065 snprintf(filename, sizeof(filename), "%s[%s]", fits_filename, compspec);
01066 }
01067 else
01068 {
01069 snprintf(filename, sizeof(filename), "%s", fits_filename);
01070 }
01071
01072 status = 0;
01073
01074 fptr = fitsrw_getfptr(verbose, filename, 1, &status, &fileCreated);
01075
01076 if (!fptr)
01077 {
01078 error_code = CFITSIO_ERROR_FILE_IO;
01079 goto error_exit;
01080 }
01081
01082 #if CFITSIO_MAJOR >= 4 || (CFITSIO_MAJOR == 3 && CFITSIO_MINOR >= 35)
01083 if (imgSize > HUGE_HDU_THRESHOLD && fileCreated)
01084 {
01085
01086 if (fits_set_huge_hdu(fptr, 1, &status))
01087 {
01088 error_code = CFITSIO_ERROR_FILE_IO;
01089 goto error_exit;
01090 }
01091 }
01092 #endif
01093
01094 if(fits_create_img(fptr, img_type, image_info->naxis, image_info->naxes, &status))
01095 {
01096 error_code = CFITSIO_ERROR_LIBRARY;
01097 goto error_exit;
01098 }
01099
01100 if (fits_is_compressed_image(fptr, &status))
01101 {
01102
01103 if (data_type == TLONGLONG)
01104 {
01105 fprintf(stderr, "CFITSIO doesn't support compression of 64-bit data.\n");
01106 error_code = CFITSIO_ERROR_CANT_COMPRESS;
01107 goto error_exit;
01108 }
01109 else if (data_type == TFLOAT || data_type == TDOUBLE)
01110 {
01111 fprintf(stderr, "CFITSIO compression of floating-point data is lossy, bailing.\n");
01112 error_code = CFITSIO_ERROR_CANT_COMPRESS;
01113 goto error_exit;
01114 }
01115 }
01116 else if (status)
01117 {
01118 error_code = CFITSIO_ERROR_LIBRARY;
01119 goto error_exit;
01120 }
01121
01122
01123 error_code = cfitsio_writekeys(fptr, keylist);
01124 if (error_code != CFITSIO_SUCCESS)
01125 {
01126 goto error_exit;
01127 }
01128
01129
01130
01131
01132
01133 if (image_info->bitfield & kInfoPresent_BLANK)
01134 {
01135 oblank = (long long)image_info->blank;
01136
01137 if (image_info->bitpix == BYTE_IMG)
01138 {
01139
01140
01141
01142
01143 oblank = 0;
01144 }
01145
01146 fits_update_key(fptr, TLONGLONG, "BLANK", &oblank, "", &status);
01147 }
01148 if (image_info->bitfield & kInfoPresent_BZERO)
01149 {
01150 double obzero = image_info->bzero;
01151 if (image_info->bitpix == BYTE_IMG)
01152 {
01153 obzero = (double) (obzero -(128.0 * image_info->bscale));
01154 }
01155
01156 fits_update_key(fptr, TDOUBLE, "BZERO", &obzero, "", &status);
01157 }
01158 if (image_info->bitfield & kInfoPresent_BSCALE)
01159 {
01160 double obscale = image_info->bscale;
01161 fits_update_key(fptr, TDOUBLE, "BSCALE", &obscale, "", &status);
01162 }
01163
01164 if (image_info->bitpix == BYTE_IMG)
01165 {
01166
01167
01168
01169
01170
01171
01172
01173 fits_set_bscale(fptr, 1.0, -128, &status);
01174 }
01175 else
01176 {
01177 fits_set_bscale(fptr, 1.0, 0.0, &status);
01178
01179
01180
01181
01182
01183
01184 }
01185
01186 fits_set_imgnull(fptr, 0, &status);
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 if (image)
01198 {
01199 if(fits_write_img(fptr, data_type, 1, npixels, image, &status))
01200 {
01201 error_code = CFITSIO_ERROR_LIBRARY;
01202 goto error_exit;
01203 }
01204 }
01205 else
01206 {
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 if (image_info->bitpix == FLOAT_IMG)
01218 {
01219
01220 float *pix = 0;
01221 int ipix;
01222
01223 misspix = malloc(kMISSPIXBLOCK * sizeof(float));
01224 pix = misspix;
01225
01226 for (ipix = 0; ipix < kMISSPIXBLOCK; ipix++)
01227 {
01228 *pix++ = F_NAN;
01229 }
01230 }
01231 else if (image_info->bitpix == DOUBLE_IMG)
01232 {
01233
01234 double *pix = 0;
01235 int ipix;
01236
01237 misspix = malloc(kMISSPIXBLOCK * sizeof(double));
01238 pix = misspix;
01239
01240 for (ipix = 0; ipix < kMISSPIXBLOCK; ipix++)
01241 {
01242 *pix++ = D_NAN;
01243 }
01244 }
01245 else if (image_info->bitpix == BYTE_IMG)
01246 {
01247
01248 misspix = malloc(kMISSPIXBLOCK * sizeof(char));
01249 memset(misspix, (char)oblank, kMISSPIXBLOCK);
01250 }
01251 else if (image_info->bitpix == SHORT_IMG)
01252 {
01253 short *p = NULL;
01254
01255
01256 misspix = malloc(kMISSPIXBLOCK * sizeof(short));
01257 p = (short *)misspix + (kMISSPIXBLOCK - 1);
01258 while (p >= misspix)
01259 {
01260 *p = (short)oblank;
01261 p--;
01262 }
01263 }
01264 else if (image_info->bitpix == LONG_IMG)
01265 {
01266 int *p = NULL;
01267
01268
01269 misspix = malloc(kMISSPIXBLOCK * sizeof(int));
01270 p = (int *)misspix + (kMISSPIXBLOCK - 1);
01271 while (p >= misspix)
01272 {
01273 *p = (int)oblank;
01274 p--;
01275 }
01276 }
01277 else if (image_info->bitpix == LONGLONG_IMG)
01278 {
01279 long long *p = NULL;
01280
01281
01282 misspix = malloc(kMISSPIXBLOCK * sizeof(long long));
01283 p = (long long *)misspix + (kMISSPIXBLOCK - 1);
01284 while (p >= misspix)
01285 {
01286 *p = (long long)oblank;
01287 p--;
01288 }
01289 }
01290
01291 pixleft = npixels;
01292 pixtowrt = 0;
01293 pixptr = 0;
01294
01295 while(pixleft > 0)
01296 {
01297 pixtowrt = pixleft > kMISSPIXBLOCK ? kMISSPIXBLOCK : pixleft;
01298 if(fits_write_img(fptr,
01299 data_type,
01300 1 + pixptr,
01301 pixtowrt,
01302 misspix,
01303 &status))
01304 {
01305 error_code = CFITSIO_ERROR_LIBRARY;
01306 goto error_exit;
01307 }
01308
01309 pixleft -= pixtowrt;
01310 pixptr += pixtowrt;
01311 }
01312
01313 if (misspix)
01314 {
01315 free(misspix);
01316 }
01317 }
01318
01319 if (fptr)
01320 {
01321
01322 CFITSIO_IMAGE_INFO fpinfo;
01323 CFITSIO_IMAGE_INFO fpinfonew;
01324
01325 if (fitsrw_getfpinfo_ext(fptr, &fpinfo))
01326 {
01327 fprintf(stderr, "Invalid fitsfile pointer '%p'.\n", fptr);
01328 error_code = CFITSIO_ERROR_FILE_IO;
01329 }
01330 else
01331 {
01332 fpinfonew = *image_info;
01333 snprintf(fpinfonew.fhash, sizeof(fpinfonew.fhash), "%s", fpinfo.fhash);
01334
01335 if (fitsrw_setfpinfo_ext(fptr, &fpinfonew))
01336 {
01337 fprintf(stderr, "Unable to update file pointer information.\n");
01338 error_code = CFITSIO_ERROR_FILE_IO;
01339 }
01340 else
01341 {
01342 if ((status = fitsrw_closefptr(verbose, fptr)) != 0)
01343 {
01344 error_code = CFITSIO_ERROR_FILE_IO;
01345 }
01346 }
01347 }
01348 }
01349
01350 if(status == 0) return CFITSIO_SUCCESS;
01351
01352
01353 error_exit:
01354
01355 if (status)
01356 {
01357 fits_get_errstatus(status, cfitsiostat);
01358 }
01359
01360 fprintf(stderr, "cfitsio error '%s'.\n", cfitsiostat);
01361
01362 if (fptr)
01363 {
01364
01365 fitsrw_closefptr(verbose, fptr);
01366 }
01367
01368 return error_code;
01369 }
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 int cfitsio_key_to_card(CFITSIO_KEYWORD* kptr, char* card)
01399 {
01400 char temp[FLEN_CARD];
01401 char buf[128];
01402
01403 memset(card,0,sizeof(FLEN_CARD));
01404 if(!kptr) return CFITSIO_FAIL;
01405
01406
01407 switch(kptr->key_type)
01408 {
01409 case(kFITSRW_Type_String):
01410 case('X'):
01411 {
01412
01413
01414
01415
01416
01417
01418
01419 int isspecial = (strcasecmp(kptr->key_name, "history") == 0 || strcasecmp(kptr->key_name, "comment") == 0);
01420 char format[128] = {0};
01421 char formatspecial[128] = {0};
01422
01423 if (strlen(kptr->key_comment) > 0)
01424 {
01425 snprintf(format, sizeof(format), "%s / %s", "%-8s= '%.68s'", kptr->key_comment);
01426 snprintf(formatspecial, sizeof(formatspecial), "%s / %s", "%-8s= '%s'", kptr->key_comment);
01427 }
01428 else
01429 {
01430 snprintf(format, sizeof(format), "%s", "%-8s= '%.68s'");
01431 snprintf(formatspecial, sizeof(formatspecial), "%s", "%-8s= '%s'");
01432 }
01433
01434 if (isspecial)
01435 {
01436 snprintf(temp,
01437 sizeof(temp),
01438 formatspecial,
01439 kptr->key_name,
01440 kptr->key_value.vs);
01441 }
01442 else
01443 {
01444 snprintf(temp,
01445 sizeof(temp),
01446 format,
01447 kptr->key_name,
01448 kptr->key_value.vs);
01449 }
01450
01451 }
01452 break;
01453
01454 case(kFITSRW_Type_Logical):
01455 if(strlen(kptr->key_comment) >0)
01456 {
01457 if(kptr->key_value.vl)
01458 sprintf(temp,"%-8s= T / %s", kptr->key_name, kptr->key_comment);
01459 else
01460 sprintf(temp,"%-8s= F / %s", kptr->key_name, kptr->key_comment);
01461 }
01462 else
01463 {
01464 if(kptr->key_value.vl)
01465 sprintf(temp,"%-8s= T", kptr->key_name);
01466 else
01467 sprintf(temp,"%-8s= F", kptr->key_name);
01468 }
01469
01470 break;
01471
01472 case(kFITSRW_Type_Integer):
01473 if(strlen(kptr->key_comment) >0)
01474 {
01475 sprintf(temp,"%-8s= %20lld / %s", kptr->key_name, kptr->key_value.vi, kptr->key_comment);
01476 }
01477 else
01478 {
01479 sprintf(temp,"%-8s= %20lld", kptr->key_name, kptr->key_value.vi);
01480 }
01481 break;
01482
01483 case(kFITSRW_Type_Float):
01484 {
01485 int usedef = 1;
01486
01487 if (*kptr->key_format != '\0')
01488 {
01489 double tester = 0;
01490 snprintf(buf, sizeof(buf), kptr->key_format, kptr->key_value.vf);
01491 if (sscanf(buf, "%lf", &tester) == 1)
01492 {
01493 snprintf(temp, sizeof(temp), "%-8s= %s", kptr->key_name, buf);
01494 usedef = 0;
01495 }
01496 }
01497
01498
01499 if (usedef)
01500 {
01501 snprintf(temp, sizeof(temp), "%-8s= %20.15e", kptr->key_name, kptr->key_value.vf);
01502 }
01503
01504 if(strlen(kptr->key_comment) > 0)
01505 {
01506 char *pref = strdup(temp);
01507
01508 if (pref)
01509 {
01510 snprintf(temp, sizeof(temp), "%s / %s", pref, kptr->key_comment);
01511 free(pref);
01512 }
01513 else
01514 {
01515 return CFITSIO_ERROR_OUT_OF_MEMORY;
01516 }
01517 }
01518 }
01519 break;
01520 }
01521
01522 sprintf(card,"%-80s",temp);
01523
01524
01525
01526
01527 return CFITSIO_SUCCESS;
01528 }
01529
01530
01531
01532 int fitsrw_read(int verbose,
01533 const char *filename,
01534 CFITSIO_IMAGE_INFO** image_info,
01535 void** image,
01536 CFITSIO_KEYWORD** keylist)
01537 {
01538 fitsfile *fptr = NULL;
01539 long long npixels;
01540 int bytepix;
01541 int data_type;
01542 void *pixels = NULL;
01543 int status;
01544 int error_code = 0;
01545 char cfitsiostat[FLEN_STATUS];
01546 int idim;
01547 char *fnamedup = strdup(filename);
01548 int datachk;
01549 int hduchk;
01550 int fileCreated = 0;
01551
01552 if (!image_info || *image_info)
01553 {
01554 fprintf(stderr, "Invalid image_info argument.\n");
01555 error_code = CFITSIO_ERROR_ARGS;
01556 }
01557
01558 if (!error_code)
01559 {
01560 *image_info = (CFITSIO_IMAGE_INFO *)malloc(sizeof(CFITSIO_IMAGE_INFO));
01561
01562 if(*image_info == NULL)
01563 {
01564 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
01565 }
01566 }
01567
01568 if (!error_code)
01569 {
01570 memset((void*)(*image_info), 0, sizeof(CFITSIO_IMAGE_INFO));
01571
01572
01573
01574 status = 0;
01575
01576 fptr = fitsrw_getfptr(verbose, fnamedup, 0, &status, &fileCreated);
01577 XASSERT(!fileCreated);
01578
01579 if (!fptr)
01580 {
01581 error_code = CFITSIO_ERROR_FILE_DOESNT_EXIST;
01582 }
01583
01584 if (!error_code)
01585 {
01586 error_code = cfitsio_read_keylist_and_image_info(fptr, keylist, image_info);
01587 }
01588
01589 if (!error_code)
01590 {
01591 switch((*image_info)->bitpix)
01592 {
01593 case(BYTE_IMG): data_type = TBYTE; break;
01594
01595 case(SHORT_IMG): data_type = TSHORT; break;
01596 case(LONG_IMG): data_type = TINT; break;
01597 case(LONGLONG_IMG):data_type = TLONGLONG; break;
01598 case(FLOAT_IMG): data_type = TFLOAT; break;
01599 case(DOUBLE_IMG): data_type = TDOUBLE; break;
01600 }
01601
01602 bytepix = abs((*image_info)->bitpix) / 8;
01603
01604 npixels = 1;
01605 for(idim = 0; idim < (*image_info)->naxis; idim++)
01606 {
01607 npixels *= (*image_info)->naxes[idim];
01608 }
01609
01610 pixels = calloc(npixels, bytepix);
01611 if(!pixels)
01612 {
01613 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
01614 }
01615 }
01616 }
01617
01618 if (!error_code)
01619 {
01620
01621 fits_set_bscale(fptr, 1.0, 0.0, &status);
01622
01623 if (!status)
01624 {
01625 fits_set_imgnull(fptr, 0, &status);
01626 }
01627
01628 if (status)
01629 {
01630 error_code = CFITSIO_ERROR_LIBRARY;
01631 }
01632 }
01633
01634 if (!error_code)
01635 {
01636 if(fits_read_img(fptr, data_type, 1, npixels, NULL, pixels, NULL, &status))
01637 {
01638 error_code = CFITSIO_ERROR_LIBRARY;
01639 }
01640
01641
01642 if (fits_verify_chksum(fptr, &datachk, &hduchk, &status))
01643 {
01644 error_code = CFITSIO_ERROR_LIBRARY;
01645 }
01646 else
01647 {
01648 if (datachk == -1 || hduchk == -1)
01649 {
01650
01651 fprintf(stderr, "Failed to verify data and/or HDU checksum (file corrupted).\n");
01652 error_code = CFITSIO_ERROR_FILE_IO;
01653 }
01654 }
01655 }
01656
01657 if(fptr)
01658 {
01659 status = fitsrw_closefptr(verbose, fptr);
01660 if (status)
01661 {
01662 error_code = CFITSIO_ERROR_FILE_IO;
01663 }
01664 }
01665
01666 if (status)
01667 {
01668 fits_get_errstatus(status, cfitsiostat);
01669 fprintf(stderr, "In fitsrw_read(), cfitsio error '%s'.\n", cfitsiostat);
01670 if(pixels)
01671 {
01672 free(pixels);
01673 }
01674 }
01675 else
01676 {
01677 *image = pixels;
01678 }
01679
01680 if (fnamedup)
01681 {
01682 free(fnamedup);
01683 }
01684
01685 return error_code;
01686 }
01687
01688 int fitsrw_write(int verbose,
01689 const char* filein,
01690 CFITSIO_IMAGE_INFO* info,
01691 void* image,
01692 const char* cparms,
01693 CFITSIO_KEYWORD* keylist)
01694 {
01695 return fitsrw_write2(verbose, filein, info, image, cparms, keylist, (export_callback_func_t) NULL);
01696 }
01697
01698 int fitsrw_write2(int verbose,
01699 const char* filein,
01700 CFITSIO_IMAGE_INFO* info,
01701 void* image,
01702 const char* cparms,
01703 CFITSIO_KEYWORD* keylist,
01704 export_callback_func_t callback)
01705 {
01706 int err = CFITSIO_SUCCESS;
01707 int idim;
01708 long long npixels;
01709 int datatype;
01710 int imgtype;
01711 char filename[PATH_MAX];
01712 fitsfile *fptr = NULL;
01713 int cfiostat = 0;
01714 int fileCreated = 0;
01715 long long imgSize =0;
01716
01717 if (filein && info && image)
01718 {
01719 for (idim = 0, npixels = 1; idim < info->naxis; idim++)
01720 {
01721 npixels *= info->naxes[idim];
01722 }
01723
01724 switch (info->bitpix)
01725 {
01726 case(BYTE_IMG):
01727 {
01728 datatype = TSBYTE;
01729 imgtype = SBYTE_IMG;
01730 }
01731 break;
01732 case(SHORT_IMG):
01733 {
01734 datatype = TSHORT;
01735 imgtype = SHORT_IMG;
01736 }
01737 break;
01738 case(LONG_IMG):
01739 {
01740 datatype = TINT;
01741 imgtype = LONG_IMG;
01742 }
01743 break;
01744 case(LONGLONG_IMG):
01745 {
01746 datatype = TLONGLONG;
01747 imgtype = LONGLONG_IMG;
01748 }
01749 break;
01750 case(FLOAT_IMG):
01751 {
01752 datatype = TFLOAT;
01753 imgtype = FLOAT_IMG;
01754 }
01755 break;
01756 case(DOUBLE_IMG):
01757 {
01758 datatype = TDOUBLE;
01759 imgtype = DOUBLE_IMG;
01760 }
01761 break;
01762 default:
01763 fprintf(stderr, "fitsrw_write(): Unsupported image data type.\n");
01764 err = CFITSIO_ERROR_ARGS;
01765 }
01766
01767 if (!err)
01768 {
01769 imgSize = (abs(imgtype) / 8) * npixels;
01770
01771
01772
01773 if (strcmp(filein, "-") != 0)
01774 {
01775
01776 if (cparms && *cparms)
01777 {
01778 snprintf(filename, sizeof(filename), "%s[%s]", filein, cparms);
01779 }
01780 else
01781 {
01782 snprintf(filename, sizeof(filename), "%s", filein);
01783 }
01784
01785 remove(filein);
01786 }
01787
01788
01789 if (callback != NULL)
01790 {
01791 if (strcmp(filein, "-") != 0)
01792 {
01793
01794 int retVal =0;
01795
01796 (*callback)("create", &fptr, filein, cparms, &cfiostat, &retVal);
01797 if (retVal)
01798 {
01799 err = CFITSIO_ERROR_FILE_IO;
01800 }
01801 }
01802 else
01803 {
01804
01805
01806 fptr = (fitsfile *)callback;
01807 }
01808 }
01809 else
01810 {
01811 fptr = fitsrw_getfptr(verbose, filename, 1, &err, &fileCreated);
01812
01813 if (!fptr)
01814 {
01815 err = CFITSIO_ERROR_FILE_IO;
01816 }
01817 else
01818 {
01819 #if CFITSIO_MAJOR >= 4 || (CFITSIO_MAJOR == 3 && CFITSIO_MINOR >= 35)
01820 if (imgSize > HUGE_HDU_THRESHOLD && fileCreated)
01821 {
01822
01823 if (fits_set_huge_hdu(fptr, 1, &cfiostat))
01824 {
01825 err = CFITSIO_ERROR_FILE_IO;
01826 }
01827 }
01828 #endif
01829 }
01830
01831 }
01832
01833 }
01834
01835 if (!err)
01836 {
01837 if(fits_create_img(fptr, imgtype, info->naxis, info->naxes, &cfiostat))
01838 {
01839 err = CFITSIO_ERROR_LIBRARY;
01840 }
01841 }
01842
01843 if (!err)
01844 {
01845 if (fits_is_compressed_image(fptr, &cfiostat))
01846 {
01847 if (datatype == TLONGLONG)
01848 {
01849 fprintf(stderr, "CFITSIO doesn't support compression of 64-bit data.\n");
01850 err = CFITSIO_ERROR_ARGS;
01851 }
01852 else if (datatype == TFLOAT || datatype == TDOUBLE)
01853 {
01854 fprintf(stderr, "WARNING: CFITSIO compression of floating-point data is lossy.\n");
01855 }
01856 }
01857 else if (cfiostat)
01858 {
01859 err = CFITSIO_ERROR_LIBRARY;
01860 }
01861 }
01862
01863 if (!err)
01864 {
01865
01866 err = cfitsio_writekeys(fptr, keylist);
01867 }
01868
01869 if (!err)
01870 {
01871
01872 if (info->bitfield & kInfoPresent_BLANK)
01873 {
01874 long long oblank = (long long)info->blank;
01875 fits_update_key(fptr, TLONGLONG, "BLANK", &oblank, "", &cfiostat);
01876 }
01877
01878 if (!cfiostat && (info->bitfield & kInfoPresent_BZERO))
01879 {
01880 double obzero = info->bzero;
01881 fits_update_key(fptr, TDOUBLE, "BZERO", &obzero, "", &cfiostat);
01882 }
01883
01884 if (!cfiostat && (info->bitfield & kInfoPresent_BSCALE))
01885 {
01886 double obscale = info->bscale;
01887 fits_update_key(fptr, TDOUBLE, "BSCALE", &obscale, "", &cfiostat);
01888 }
01889
01890
01891
01892
01893
01894
01895 if (!cfiostat)
01896 {
01897 fits_set_bscale(fptr, 1.0, 0.0, &cfiostat);
01898 }
01899
01900 if (!cfiostat)
01901 {
01902 fits_set_imgnull(fptr, 0, &cfiostat);
01903 }
01904
01905 if (cfiostat)
01906 {
01907 fprintf(stderr, "Trouble setting BZERO, BSCALE, or BLANK keywords.\n");
01908 err = CFITSIO_ERROR_LIBRARY;
01909 }
01910 }
01911
01912 if (!err)
01913 {
01914 if(fits_write_img(fptr, datatype, 1, npixels, image, &cfiostat))
01915 {
01916 err = CFITSIO_ERROR_LIBRARY;
01917 }
01918 }
01919 }
01920 else
01921 {
01922 err = CFITSIO_ERROR_ARGS;
01923 }
01924
01925 if (err && cfiostat)
01926 {
01927 char errmsg[FLEN_STATUS];
01928 fits_get_errstatus(cfiostat, errmsg);
01929 fprintf(stderr, "CFITSIO error '%s'.\n", errmsg);
01930 }
01931
01932 if (fptr)
01933 {
01934
01935
01936
01937 if (callback != NULL )
01938 {
01939 if (strcmp(filein, "-") != 0)
01940 {
01941
01942 (*callback)("stdout", fptr, image, &cfiostat);
01943 if (cfiostat)
01944 {
01945 fprintf(stderr, "Trouble executing callback [%s]\n", filename);
01946 err = CFITSIO_ERROR_LIBRARY;
01947 }
01948 }
01949 }
01950 else
01951 {
01952 CFITSIO_IMAGE_INFO fpinfo;
01953 CFITSIO_IMAGE_INFO fpinfonew;
01954
01955 if (fitsrw_getfpinfo_ext(fptr, &fpinfo))
01956 {
01957 fprintf(stderr, "Invalid fitsfile pointer '%p'.\n", fptr);
01958 err = CFITSIO_ERROR_FILE_IO;
01959 }
01960 else
01961 {
01962 fpinfonew = *info;
01963 snprintf(fpinfonew.fhash, sizeof(fpinfonew.fhash), "%s", fpinfo.fhash);
01964
01965 if (fitsrw_setfpinfo_ext(fptr, &fpinfonew))
01966 {
01967 fprintf(stderr, "Unable to update file pointer information.\n");
01968 err = CFITSIO_ERROR_FILE_IO;
01969 }
01970 else
01971 {
01972 if (fitsrw_closefptr(verbose, fptr))
01973 {
01974 err = CFITSIO_ERROR_FILE_IO;
01975 }
01976 }
01977 }
01978 }
01979 }
01980
01981 return err;
01982 }
01983
01984