00001 #include <string.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include "cfitsio.h"
00005 #include "tasrw.h"
00006 #include "cfitsio.h"
00007 #include "fitsio.h"
00008 #include "hcontainer.h"
00009 #include "list.h"
00010 #include "timer.h"
00011 #include "xassert.h"
00012
00013
00014
00015 #ifdef DEBUG
00016 #include "timer.h"
00017 #endif
00018
00019
00020
00021 #define MAXFFILES 300
00022
00023 #ifdef SKIPWS
00024 #undef SKIPWS
00025 #endif
00026
00027 #ifdef ISBLANK
00028 #undef ISBLANK
00029 #endif
00030
00031 #define ISBLANK(c) (c==' ' || c=='\t' || c=='\r')
00032 #define SKIPWS(p) {while(*p && ISBLANK(*p)) { ++p; }}
00033
00034 HContainer_t *gFFiles = NULL;
00035 HContainer_t *gFFPtrInfo = NULL;
00036
00037 static int IsWriteable(const char *fhash)
00038 {
00039 char *pmode = strrchr(fhash, ':');
00040 int writeable = -1;
00041
00042 if (!pmode)
00043 {
00044 fprintf(stderr, "Invalid file hash '%s'.\n", fhash);
00045 }
00046 else
00047 {
00048 if (*(pmode + 1) == 'r')
00049 {
00050 writeable = 0;
00051 }
00052 else if (*(pmode + 1) == 'w')
00053 {
00054 writeable = 1;
00055 }
00056 }
00057
00058 return writeable;
00059 }
00060
00061 static int fitsrw_getfpinfo(fitsfile *fptr, TASRW_FilePtrInfo_t *info)
00062 {
00063 int err = 1;
00064 TASRW_FilePtrInfo_t *pfpinfo = NULL;
00065 char fileinfokey[64];
00066
00067 if (fptr && info)
00068 {
00069 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)fptr);
00070 err = ((pfpinfo = (TASRW_FilePtrInfo_t *)hcon_lookup(gFFPtrInfo, fileinfokey)) == NULL);
00071 }
00072
00073 if (!err)
00074 {
00075 if (pfpinfo)
00076 {
00077 *info = *pfpinfo;
00078 }
00079 }
00080
00081 return err;
00082 }
00083
00084 static int fitsrw_setfpinfo(fitsfile *fptr, TASRW_FilePtrInfo_t *info)
00085 {
00086 int err = 1;
00087 TASRW_FilePtrInfo_t *pfpinfo = NULL;
00088 char fileinfokey[64];
00089
00090 if (fptr && info)
00091 {
00092 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)fptr);
00093 err = ((pfpinfo = (TASRW_FilePtrInfo_t *)hcon_lookup(gFFPtrInfo, fileinfokey)) == NULL);
00094 }
00095
00096 if (!err)
00097 {
00098 if (pfpinfo)
00099 {
00100 *pfpinfo = *info;
00101 }
00102 }
00103
00104 return err;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 fitsfile *fitsrw_getfptr_internal(int verbose, const char *filename, int writeable, int verchksum, int *status, int *fileCreated)
00119 {
00120 fitsfile *fptr = NULL;
00121 fitsfile **pfptr = NULL;
00122 char filehashkey[PATH_MAX + 2];
00123 char tmpfilehashkey[PATH_MAX + 2];
00124 char fileinfokey[64];
00125 int stat = CFITSIO_SUCCESS;
00126 int fiostat = 0;
00127 int datachk;
00128 int hduchk;
00129 int newfile = 0;
00130 char cfitsiostat[FLEN_STATUS];
00131 int exit_code = CFITSIO_SUCCESS;
00132
00133 if (fileCreated)
00134 {
00135 *fileCreated = 0;
00136 }
00137
00138 if (!gFFiles)
00139 {
00140 gFFiles = hcon_create(sizeof(fitsfile *), sizeof(filehashkey), NULL, NULL, NULL, NULL, 0);
00141 }
00142
00143 if (!gFFPtrInfo)
00144 {
00145 gFFPtrInfo = hcon_create(sizeof(TASRW_FilePtrInfo_t), sizeof(fileinfokey), NULL, NULL, NULL, NULL, 0);
00146 }
00147
00148 snprintf(filehashkey, sizeof(filehashkey), "%s:%s", filename, writeable ? "w" : "r");
00149
00150
00151 pfptr = (fitsfile **)hcon_lookup(gFFiles, filehashkey);
00152 if (pfptr && !*pfptr)
00153 {
00154 hcon_remove(gFFiles, filehashkey);
00155 pfptr = NULL;
00156 }
00157
00158 if (pfptr != NULL)
00159 {
00160 fptr = *pfptr;
00161 }
00162 else if (!writeable)
00163 {
00164 snprintf(tmpfilehashkey, sizeof(tmpfilehashkey), "%s:w", filename);
00165 pfptr = (fitsfile **)hcon_lookup(gFFiles, tmpfilehashkey);
00166 if (pfptr && !*pfptr)
00167 {
00168 hcon_remove(gFFiles, tmpfilehashkey);
00169 pfptr = NULL;
00170 }
00171
00172 if (pfptr != NULL)
00173 {
00174
00175 fptr = *pfptr;
00176 }
00177 }
00178
00179 if (!fptr)
00180 {
00181 if (writeable)
00182 {
00183 snprintf(tmpfilehashkey, sizeof(tmpfilehashkey), "%s:r", filename);
00184 if ((pfptr = (fitsfile **)hcon_lookup(gFFiles, tmpfilehashkey)) != NULL)
00185 {
00186
00187
00188
00189 if (*pfptr)
00190 {
00191
00192 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)*pfptr);
00193 hcon_remove(gFFPtrInfo, fileinfokey);
00194
00195 if (verbose)
00196 {
00197 fprintf(stdout, "Closing fits file '%s'.\n", filename);
00198 PushTimer();
00199 }
00200
00201
00202 fiostat = 0;
00203 fits_close_file(*pfptr, &fiostat);
00204
00205 if (fiostat != 0)
00206 {
00207 fprintf(stderr, "FITSIO error: %d.\n", fiostat);
00208 fprintf(stdout, "Unable to close fits file '%s'.\n", filename);
00209 perror("fitsrw_getfptr_internal() system error");
00210 stat = CFITSIO_ERROR_FILE_IO;
00211 }
00212
00213 if (verbose)
00214 {
00215 fprintf(stdout, "Time to close fitsfile '%s'= %f sec.\n", filename, PopTimer());
00216 }
00217 }
00218
00219 hcon_remove(gFFiles, tmpfilehashkey);
00220
00221 pfptr = NULL;
00222 }
00223 }
00224
00225 if (verbose)
00226 {
00227 PushTimer();
00228 }
00229
00230 if (!stat)
00231 {
00232 fiostat = 0;
00233 if (fits_open_image(&fptr, filename, writeable ? READWRITE : READONLY, &fiostat))
00234 {
00235
00236 if (writeable)
00237 {
00238
00239 fiostat = 0;
00240
00241
00242 newfile = 1;
00243 if (fits_create_file(&fptr, filename, &fiostat))
00244 {
00245
00246 fprintf(stderr, "FITSIO error: %d; ", fiostat);
00247 fits_report_error(stderr, fiostat);
00248 fprintf(stderr, "\n");
00249 stat = CFITSIO_ERROR_FILE_IO;
00250 }
00251 else if (fileCreated)
00252 {
00253 *fileCreated = 1;
00254 }
00255 }
00256 else
00257 {
00258 stat = CFITSIO_ERROR_FILE_DOESNT_EXIST;
00259 }
00260 }
00261 }
00262
00263 if (verbose)
00264 {
00265 fprintf(stdout, "Time to open fitsfile '%s' = %f sec.\n", filehashkey, PopTimer());
00266 }
00267
00268 if (!stat)
00269 {
00270 if (verbose)
00271 {
00272 PushTimer();
00273 }
00274
00275
00276 if (verchksum)
00277 {
00278 fiostat = 0;
00279 if (fits_verify_chksum(fptr, &datachk, &hduchk, &fiostat))
00280 {
00281 fprintf(stderr, "FITSIO error: %d.\n", fiostat);
00282 fprintf(stderr, "Unable to verify fits-file checksum.\n");
00283 stat = CFITSIO_ERROR_LIBRARY;
00284 }
00285 else
00286 {
00287 if (datachk == -1 || hduchk == -1)
00288 {
00289
00290 fprintf(stderr, "Failed to verify data and/or HDU checksum (file corrupted).\n");
00291 stat = CFITSIO_ERROR_FILE_IO;
00292 }
00293 }
00294 }
00295
00296 if (verbose)
00297 {
00298 fprintf(stdout, "Time to verify checksum = %f sec.\n", PopTimer());
00299 }
00300 }
00301
00302 exit_code = stat;
00303
00304 if (!stat && gFFiles->num_total >= MAXFFILES - 1)
00305 {
00306
00307 int ifile = 0;
00308 HIterator_t *hit = hiter_create(gFFiles);
00309 LinkedList_t *llist = list_llcreate(sizeof(char *), NULL);
00310 const char *fhkey = NULL;
00311 ListNode_t *node = NULL;
00312 char *onefile = NULL;
00313 TASRW_FilePtrInfo_t finfo;
00314
00315 if (hit)
00316 {
00317 while (ifile < MAXFFILES / 2)
00318 {
00319 stat = 0;
00320 pfptr = (fitsfile **)hiter_extgetnext(hit, &fhkey);
00321
00322 if (pfptr)
00323 {
00324 if (*pfptr)
00325 {
00326
00327 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)*pfptr);
00328
00329 hcon_remove(gFFPtrInfo, fileinfokey);
00330
00331 if (IsWriteable(fhkey))
00332 {
00333
00334 stat = fitsrw_getfpinfo(*pfptr, &finfo);
00335
00336 if (stat)
00337 {
00338 fprintf(stderr, "missing file info for fits file '%s'\n", fhkey);
00339 stat = CFITSIO_ERROR_CANT_GET_FILEINFO;
00340 }
00341 else
00342 {
00343 if (finfo.bitfield & kInfoPresent_Dirt)
00344 {
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 int dimlen;
00355 int imgType;
00356 long long *axes = NULL;
00357 int iaxis;
00358
00359 axes = calloc(finfo.naxis, sizeof(long long));
00360
00361 if (!axes)
00362 {
00363 stat = CFITSIO_ERROR_OUT_OF_MEMORY;
00364 }
00365 else
00366 {
00367 for (iaxis = 0; iaxis < finfo.naxis; iaxis++)
00368 {
00369 axes[iaxis] = finfo.naxes[iaxis];
00370 }
00371
00372 switch(finfo.bitpix)
00373 {
00374 case(BYTE_IMG): imgType = SBYTE_IMG; break;
00375 case(SHORT_IMG): imgType = SHORT_IMG; break;
00376 case(LONG_IMG): imgType = LONG_IMG; break;
00377 case(LONGLONG_IMG): imgType = LONGLONG_IMG; break;
00378 case(FLOAT_IMG): imgType = FLOAT_IMG; break;
00379 case(DOUBLE_IMG): imgType = DOUBLE_IMG; break;
00380 }
00381
00382 fiostat = 0;
00383 fits_resize_imgll(*pfptr, imgType, finfo.naxis, axes, &fiostat);
00384
00385 if (fiostat)
00386 {
00387 fprintf(stderr, "FITSIO error: %d\n", fiostat);
00388 fprintf(stderr, "unable to resize image in fits file %s\n", filename);
00389 stat = CFITSIO_ERROR_LIBRARY;
00390 }
00391
00392
00393
00394
00395
00396 free(axes);
00397 axes = NULL;
00398 }
00399 }
00400 }
00401
00402 if (!stat)
00403 {
00404 if (verbose)
00405 {
00406 PushTimer();
00407 }
00408
00409 fiostat = 0;
00410 fits_write_chksum(*pfptr, &fiostat);
00411
00412 if (fiostat)
00413 {
00414 fits_get_errstatus(fiostat, cfitsiostat);
00415 fprintf(stderr, "Purging cache: error calculating and writing checksum for fitsfile '%s'.\n", fhkey);
00416 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
00417 stat = CFITSIO_ERROR_LIBRARY;
00418 }
00419
00420 if (verbose)
00421 {
00422 fprintf(stdout, "Time to write checksum on fitsfile '%s' = %f sec.\n", fhkey, PopTimer());
00423 }
00424 }
00425 }
00426
00427 if (verbose)
00428 {
00429 PushTimer();
00430 }
00431
00432 fiostat = 0;
00433 fits_close_file(*pfptr, &fiostat);
00434
00435 if (fiostat == 0)
00436 {
00437 if (verbose)
00438 {
00439 fprintf(stderr, "Closing fits file '%s'.\n", fhkey);
00440 }
00441 }
00442 else
00443 {
00444 fits_get_errstatus(fiostat, cfitsiostat);
00445 fprintf(stderr, "Purging cache: error closing fitsfile '%s'.\n", fhkey);
00446 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
00447 perror("fitsrw_getfptr_internal() system error");
00448 if (!stat)
00449 {
00450 stat = CFITSIO_ERROR_FILE_IO;
00451 }
00452 }
00453
00454 if (verbose)
00455 {
00456 fprintf(stdout, "Time to close fitsfile '%s' = %f sec.\n", fhkey, PopTimer());
00457 }
00458 }
00459
00460
00461
00462
00463 list_llinserttail(llist, (void *)&fhkey);
00464
00465 ifile++;
00466 }
00467 else
00468 {
00469 break;
00470 }
00471
00472 if (stat && exit_code == CFITSIO_SUCCESS)
00473 {
00474 exit_code = stat;
00475 }
00476
00477 }
00478
00479 hiter_destroy(&hit);
00480 }
00481
00482
00483 list_llreset(llist);
00484 while ((node = list_llnext(llist)) != NULL)
00485 {
00486 onefile = *((char **)node->data);
00487 hcon_remove(gFFiles, onefile);
00488 }
00489
00490 list_llfree(&llist);
00491 }
00492
00493 if (!exit_code)
00494 {
00495
00496 stat = 0;
00497 CFITSIO_IMAGE_INFO *imginfo = NULL;
00498
00499
00500 if (newfile)
00501 {
00502 imginfo = (CFITSIO_IMAGE_INFO *)malloc(sizeof(CFITSIO_IMAGE_INFO));
00503 memset(imginfo, 0, sizeof(CFITSIO_IMAGE_INFO));
00504 }
00505 else
00506 {
00507 if (fitsrw_read_keylist_and_image_info((FITSRW_fhandle)fptr, NULL, &imginfo) != CFITSIO_SUCCESS)
00508 {
00509 fprintf(stderr, "Unable to get file information for %s.\n", filehashkey);
00510 stat = CFITSIO_ERROR_CANT_GET_FILEINFO;
00511 }
00512 }
00513
00514 if (!stat)
00515 {
00516 if (gFFPtrInfo)
00517 {
00518 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)fptr);
00519
00520 snprintf(imginfo->fhash, sizeof(imginfo->fhash), "%s", filehashkey);
00521 hcon_insert(gFFPtrInfo, fileinfokey, imginfo);
00522 }
00523 }
00524
00525 if (imginfo)
00526 {
00527 cfitsio_free_these(&imginfo, NULL, NULL);
00528 }
00529
00530 if (!stat)
00531 {
00532 hcon_insert(gFFiles, filehashkey, &fptr);
00533 }
00534
00535 if (verbose)
00536 {
00537 fprintf(stdout, "Number fitsfiles opened: %d\n", gFFiles->num_total);
00538 }
00539
00540 exit_code = stat;
00541 }
00542 }
00543
00544 if (status)
00545 {
00546 *status = exit_code;
00547 }
00548
00549 return fptr;
00550 }
00551
00552 fitsfile *fitsrw_getfptr(int verbose, const char *filename, int writeable, int *status, int *fileCreated)
00553 {
00554 return fitsrw_getfptr_internal(verbose, filename, writeable, 1, status, fileCreated);
00555 }
00556
00557 fitsfile *fitsrw_getfptr_nochksum(int verbose, const char *filename, int writeable, int *status, int *fileCreated)
00558 {
00559 return fitsrw_getfptr_internal(verbose, filename, writeable, 0, status, fileCreated);
00560 }
00561
00562 int fitsrw_readslice(int verbose,
00563 const char *filename,
00564 int *fpixel,
00565 int *lpixel,
00566 CFITSIO_IMAGE_INFO** image_info,
00567 void** image)
00568 {
00569 fitsfile *fptr=NULL;
00570 int error_code = CFITSIO_SUCCESS;
00571 int status;
00572 int istat;
00573 long increments[CFITSIO_MAX_DIM];
00574
00575
00576
00577 long long npixels;
00578 int bytepix, data_type;
00579 long lfpixel[CFITSIO_MAX_DIM];
00580 long llpixel[CFITSIO_MAX_DIM];
00581 int idim = 0;
00582 void *pixels = NULL;
00583 char cfitsiostat[FLEN_STATUS];
00584 TASRW_FilePtrInfo_t fpinfo;
00585
00586 long i;
00587
00588 int fileCreated = 0;
00589
00590 if (!image_info)
00591 {
00592 fprintf(stderr, "Invalid image_info argument.\n");
00593 error_code = CFITSIO_ERROR_ARGS;
00594 goto error_exit;
00595 }
00596
00597 if(*image_info) cfitsio_free_image_info(image_info);
00598 *image_info = (CFITSIO_IMAGE_INFO *)malloc(sizeof(CFITSIO_IMAGE_INFO));
00599
00600 if(*image_info == NULL)
00601 {
00602 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00603 goto error_exit;
00604 }
00605
00606 memset((void*)(*image_info), 0, sizeof(CFITSIO_IMAGE_INFO));
00607
00608 status = 0;
00609 istat = 0;
00610
00611 fptr = fitsrw_getfptr_nochksum(verbose, filename, 0, &istat, &fileCreated);
00612 XASSERT(!fileCreated);
00613
00614
00615
00616
00617 if (!fptr || istat)
00618 {
00619 error_code = CFITSIO_ERROR_FILE_IO;
00620 goto error_exit;
00621 }
00622
00623
00624 if (fitsrw_getfpinfo(fptr, &fpinfo))
00625 {
00626 fprintf(stderr, "Unable to get fitsfile image parameters.\n");
00627 error_code = CFITSIO_ERROR_FILE_IO;
00628 goto error_exit;
00629 }
00630
00631 **image_info = fpinfo;
00632
00633 if((*image_info)->naxis == 0)
00634 {
00635 error_code = CFITSIO_ERROR_DATA_EMPTY;
00636 goto error_exit;
00637 }
00638
00639 switch((*image_info)->bitpix)
00640 {
00641 case(BYTE_IMG): data_type = TBYTE; break;
00642 case(SHORT_IMG): data_type = TSHORT; break;
00643 case(LONG_IMG): data_type = TINT; break;
00644 case(LONGLONG_IMG):data_type = TLONGLONG; break;
00645 case(FLOAT_IMG): data_type = TFLOAT; break;
00646 case(DOUBLE_IMG): data_type = TDOUBLE; break;
00647 }
00648
00649 bytepix = abs((*image_info)->bitpix)/8;
00650
00651 npixels = 1;
00652 for(i=0;i<(*image_info)->naxis;i++)
00653 {
00654
00655
00656 (*image_info)->naxes[i] = (lpixel[i]-fpixel[i]+1);
00657 npixels *= (*image_info)->naxes[i];
00658 increments[i]=1;
00659 }
00660
00661 pixels = calloc(npixels, bytepix);
00662 if(!pixels)
00663 {
00664 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00665 goto error_exit;
00666 }
00667
00668
00669 fits_set_bscale(fptr, 1.0, 0.0, &status);
00670 fits_set_imgnull(fptr, 0, &status);
00671 if(status)
00672 {
00673 error_code= CFITSIO_ERROR_LIBRARY;
00674 goto error_exit;
00675 }
00676
00677
00678 int anynul;
00679
00680
00681
00682 memset(lfpixel, 0, sizeof(lfpixel));
00683 memset(llpixel, 0, sizeof(llpixel));
00684
00685 for (idim = 0; idim < (*image_info)->naxis; idim++)
00686 {
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 lfpixel[idim] = (long)fpixel[idim] + 1;
00698 llpixel[idim] = (long)lpixel[idim] + 1;
00699 }
00700
00701 if(fits_read_subset(fptr, data_type, lfpixel, llpixel, increments, NULL, pixels, &anynul,
00702 &status))
00703 {
00704 error_code = CFITSIO_ERROR_LIBRARY;
00705 goto error_exit;
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 if (data_type == TBYTE)
00717 {
00718 long long ipix;
00719 signed char *opix = NULL;
00720 unsigned char *val = NULL;
00721 signed char *oval = NULL;
00722
00723 if ((*image_info)->bscale != 1 || (*image_info)->bzero != -128)
00724 {
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 error_code = CFITSIO_ERROR_LIBRARY;
00735 goto error_exit;
00736 }
00737
00738 opix = calloc(npixels, bytepix);
00739
00740 if (!opix)
00741 {
00742 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
00743 goto error_exit;
00744 }
00745
00746 for (ipix = npixels, val = (unsigned char *)pixels, oval = opix; ipix >= 1; ipix--)
00747 {
00748
00749
00750
00751
00752
00753
00754 *oval = (signed char)((int)(*image_info)->bzero + *val);
00755 val++;
00756 oval++;
00757 }
00758
00759 (*image_info)->bzero = 0;
00760 (*image_info)->bscale = 1;
00761
00762
00763
00764
00765
00766
00767
00768
00769 (*image_info)->blank = -128;
00770
00771 *image = opix;
00772 opix = NULL;
00773
00774 free(pixels);
00775 pixels = NULL;
00776 }
00777 else
00778 {
00779 *image = pixels;
00780 pixels = NULL;
00781 }
00782
00783 return CFITSIO_SUCCESS;
00784
00785 error_exit:
00786
00787 if (status != 0)
00788 {
00789 fits_get_errstatus(status, cfitsiostat);
00790 fprintf(stderr, "cfitsio error '%s'.\n", cfitsiostat);
00791 }
00792
00793 if(fptr)
00794 {
00795
00796
00797 fitsrw_closefptr(verbose, fptr);
00798 }
00799
00800 if(pixels) free(pixels);
00801
00802 return error_code;
00803 }
00804
00805
00806
00807
00808 int fitsrw_writeslice(int verbose, const char *filename, int *fpixel, int *lpixel, void *image)
00809 {
00810 fitsfile *fptr=NULL;
00811 int error_code = CFITSIO_SUCCESS;
00812 int status;
00813 int istat;
00814 int data_type;
00815 long lfpixel[CFITSIO_MAX_DIM];
00816 long llpixel[CFITSIO_MAX_DIM];
00817 int idim = 0;
00818 int idim2 = 0;
00819 char cfitsiostat[FLEN_STATUS];
00820 long long npix;
00821 int contiguous;
00822 long long firstpix;
00823 long long intermed;
00824 TASRW_FilePtrInfo_t fpinfo;
00825 int dimlen = 0;
00826 int fileCreated = 0;
00827
00828 status = 0;
00829 istat = 0;
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841 fptr = fitsrw_getfptr(verbose, filename, 1, &istat, &fileCreated);
00842
00843
00844
00845 XASSERT(!fileCreated);
00846
00847 if (!fptr || istat)
00848 {
00849 error_code = CFITSIO_ERROR_FILE_IO;
00850 goto error_exit;
00851 }
00852
00853
00854 if (fitsrw_getfpinfo(fptr, &fpinfo))
00855 {
00856 fprintf(stderr, "Unable to get fitsfile image parameters.\n");
00857 error_code = CFITSIO_ERROR_FILE_IO;
00858 goto error_exit;
00859 }
00860
00861 if(fpinfo.naxis == 0)
00862 {
00863 error_code = CFITSIO_ERROR_DATA_EMPTY;
00864 goto error_exit;
00865 }
00866
00867 switch(fpinfo.bitpix)
00868 {
00869 case(BYTE_IMG): data_type = TSBYTE; break;
00870 case(SHORT_IMG): data_type = TSHORT; break;
00871 case(LONG_IMG): data_type = TINT; break;
00872 case(LONGLONG_IMG): data_type = TLONGLONG; break;
00873 case(FLOAT_IMG): data_type = TFLOAT; break;
00874 case(DOUBLE_IMG): data_type = TDOUBLE; break;
00875 }
00876
00877
00878 fits_set_bscale(fptr, 1.0, 0.0, &status);
00879 fits_set_imgnull(fptr, 0, &status);
00880 if(status)
00881 {
00882 error_code = CFITSIO_ERROR_LIBRARY;
00883 goto error_exit;
00884 }
00885
00886
00887
00888
00889 memset(lfpixel, 0, sizeof(lfpixel));
00890 memset(llpixel, 0, sizeof(llpixel));
00891 npix = 1;
00892 firstpix = 0;
00893 contiguous = 1;
00894
00895
00896
00897
00898
00899
00900 for (idim = 0; idim < fpinfo.naxis; idim++)
00901 {
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 lfpixel[idim] = (long)fpixel[idim] + 1;
00913 llpixel[idim] = (long)lpixel[idim] + 1;
00914 npix += npix * (lpixel[idim] - fpixel[idim]);
00915 intermed = 1;
00916
00917 if (fpinfo.naxis > 1)
00918 {
00919 if (idim == fpinfo.naxis - 1)
00920 {
00921
00922
00923
00924
00925
00926
00927 for (idim2 = idim - 1; idim2 >= 0; idim2--)
00928 {
00929 intermed = intermed * fpinfo.naxes[idim2];
00930 }
00931
00932
00933
00934
00935 firstpix = fpixel[idim - 1] + intermed * fpixel[idim];
00936 }
00937 }
00938 else
00939 {
00940
00941 firstpix = fpixel[idim];
00942 }
00943
00944
00945
00946
00947 if (contiguous &&
00948 idim > 0 &&
00949 (lpixel[idim] - fpixel[idim] > 0) &&
00950 (fpixel[idim - 1] > 0 || lpixel[idim - 1] < fpinfo.naxes[idim - 1] - 1))
00951 {
00952 contiguous = 0;
00953 }
00954 }
00955
00956
00957
00958
00959
00960 #ifdef DEBUG
00961 StartTimer(26);
00962 fprintf(stderr, "Calling fits_write_subset() or fits_write_img().\n");
00963 #endif
00964
00965 if (contiguous)
00966 {
00967
00968 firstpix++;
00969
00970 if (fits_write_img(fptr, data_type, firstpix, npix, image, &status))
00971 {
00972 error_code = CFITSIO_ERROR_LIBRARY;
00973 goto error_exit;
00974 }
00975 }
00976 else
00977 {
00978 if(fits_write_subset(fptr, data_type, lfpixel, llpixel, image, &status))
00979 {
00980 error_code = CFITSIO_ERROR_LIBRARY;
00981 goto error_exit;
00982 }
00983 }
00984
00985 #if 0
00986
00987
00988
00989
00990
00991
00992 char naxisname[64];
00993 snprintf(naxisname, sizeof(naxisname), "NAXIS%d", fpinfo.naxis);
00994 dimlen = lpixel[fpinfo.naxis - 1] + 1;
00995 fits_update_key(fptr, TINT, naxisname, &dimlen, NULL, &status);
00996 #endif
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 dimlen = lpixel[fpinfo.naxis - 1] + 1;
01008 if (dimlen > fpinfo.naxes[fpinfo.naxis - 1])
01009 {
01010 TASRW_FilePtrInfo_t newinfo = fpinfo;
01011 newinfo.naxes[fpinfo.naxis - 1] = dimlen;
01012 newinfo.bitfield |= kInfoPresent_Dirt;
01013 fitsrw_setfpinfo(fptr, &newinfo);
01014 }
01015
01016 #ifdef DEBUG
01017 fprintf(stdout, "Time to write subset: %f\n", StopTimer(26));
01018 #endif
01019
01020 return CFITSIO_SUCCESS;
01021
01022 error_exit:
01023
01024 if (status != 0)
01025 {
01026 fits_get_errstatus(status, cfitsiostat);
01027 fprintf(stderr, "cfitsio error '%s'.\n", cfitsiostat);
01028 }
01029
01030
01031 if(fptr)
01032 {
01033
01034 fitsrw_closefptr(verbose, fptr);
01035 }
01036
01037 return error_code;
01038 }
01039
01040 int fitsrw_closefptr(int verbose, fitsfile *fptr)
01041 {
01042 char fileinfokey[64];
01043 int fiostat = 0;
01044 TASRW_FilePtrInfo_t fpinfo;
01045 char cfitsiostat[FLEN_STATUS];
01046 int error_code = CFITSIO_SUCCESS;
01047
01048 if (fptr)
01049 {
01050
01051 if (fitsrw_getfpinfo(fptr, &fpinfo))
01052 {
01053 fprintf(stderr, "Invalid fitsfile pointer '%p'.\n", fptr);
01054 error_code = CFITSIO_ERROR_FILE_IO;
01055 }
01056 else if (gFFiles)
01057 {
01058 if (hcon_lookup(gFFiles, fpinfo.fhash))
01059 {
01060 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)fptr);
01061 hcon_remove(gFFPtrInfo, fileinfokey);
01062
01063 if (IsWriteable(fpinfo.fhash))
01064 {
01065 if (fpinfo.bitfield & kInfoPresent_Dirt)
01066 {
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 int dimlen;
01077 int imgType;
01078 long long *axes = NULL;
01079 int iaxis;
01080
01081 axes = calloc(fpinfo.naxis, sizeof(long long));
01082
01083 if (!axes)
01084 {
01085 error_code = CFITSIO_ERROR_OUT_OF_MEMORY;
01086 }
01087 else
01088 {
01089 for (iaxis = 0; iaxis < fpinfo.naxis; iaxis++)
01090 {
01091 axes[iaxis] = fpinfo.naxes[iaxis];
01092 }
01093
01094 switch(fpinfo.bitpix)
01095 {
01096 case(BYTE_IMG): imgType = SBYTE_IMG; break;
01097 case(SHORT_IMG): imgType = SHORT_IMG; break;
01098 case(LONG_IMG): imgType = LONG_IMG; break;
01099 case(LONGLONG_IMG): imgType = LONGLONG_IMG; break;
01100 case(FLOAT_IMG): imgType = FLOAT_IMG; break;
01101 case(DOUBLE_IMG): imgType = DOUBLE_IMG; break;
01102 }
01103
01104 fiostat = 0;
01105 fits_resize_imgll(fptr, imgType, fpinfo.naxis, axes, &fiostat);
01106
01107 if (fiostat)
01108 {
01109 fprintf(stderr, "FITSIO error: %d\n", fiostat);
01110 fprintf(stderr, "unable to resize image in fits file\n");
01111 error_code = CFITSIO_ERROR_LIBRARY;
01112 }
01113
01114
01115
01116
01117
01118 free(axes);
01119 axes = NULL;
01120 }
01121 }
01122
01123 if (!error_code)
01124 {
01125 if (verbose)
01126 {
01127 PushTimer();
01128 }
01129
01130 fiostat = 0;
01131 fits_write_chksum(fptr, &fiostat);
01132
01133 if (fiostat)
01134 {
01135 fits_get_errstatus(fiostat, cfitsiostat);
01136 fprintf(stderr, "Closing fitsfile: error calculating and writing checksum for fitsfile '%s'.\n", fpinfo.fhash);
01137 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
01138 fits_report_error(stderr, fiostat);
01139 error_code = CFITSIO_ERROR_LIBRARY;
01140 }
01141
01142 if (verbose)
01143 {
01144 fprintf(stdout, "Time to write checksum on fitsfile '%s' = %f sec.\n", fpinfo.fhash, PopTimer());
01145 }
01146 }
01147 }
01148
01149 if (verbose)
01150 {
01151 PushTimer();
01152 }
01153
01154 fiostat = 0;
01155 fits_close_file(fptr, &fiostat);
01156
01157 if (fiostat == 0)
01158 {
01159 if (verbose)
01160 {
01161 fprintf(stdout, "Closing fits file '%s'.\n", fpinfo.fhash);
01162 }
01163 }
01164 else
01165 {
01166 fits_get_errstatus(fiostat, cfitsiostat);
01167 fprintf(stderr, "Closing fitsfile: error closing fitsfile '%s'.\n", fpinfo.fhash);
01168 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
01169 perror("fitsrw_closefptr() system error");
01170
01171 if (!error_code)
01172 {
01173 error_code = CFITSIO_ERROR_FILE_IO;
01174 }
01175 }
01176
01177 if (verbose)
01178 {
01179 fprintf(stdout, "Time to close fitsfile '%s' = %f sec.\n", fpinfo.fhash, PopTimer());
01180 }
01181
01182 hcon_remove(gFFiles, fpinfo.fhash);
01183 }
01184 else
01185 {
01186 fprintf(stderr, "Unknown fitsfile '%s'.\n", fpinfo.fhash);
01187 error_code = CFITSIO_ERROR_ARGS;
01188 }
01189 }
01190 else
01191 {
01192 fprintf(stderr, "Not keeping track of fitsfile pointers!\n");
01193 }
01194 }
01195
01196 return error_code;
01197 }
01198
01199 int fitsrw_closefptrByName(int verbose, const char *filename)
01200 {
01201 char filehashkeyOnefile[PATH_MAX + 2];
01202 fitsfile **pfptr = NULL;
01203
01204 if (gFFiles)
01205 {
01206
01207
01208 snprintf(filehashkeyOnefile, sizeof(filehashkeyOnefile), "%s:w", filename);
01209 pfptr = (fitsfile **)hcon_lookup(gFFiles, filehashkeyOnefile);
01210 if (!pfptr || !*pfptr)
01211 {
01212 snprintf(filehashkeyOnefile, sizeof(filehashkeyOnefile), "%s:r", filename);
01213 pfptr = (fitsfile **)hcon_lookup(gFFiles, filehashkeyOnefile);
01214 }
01215
01216 if (pfptr && *pfptr)
01217 {
01218 return fitsrw_closefptr(verbose, *pfptr);
01219 }
01220 }
01221
01222
01223 return CFITSIO_SUCCESS;
01224 }
01225
01226 int fitsrw_closefptrs(int verbose)
01227 {
01228 int exit_code = CFITSIO_SUCCESS;
01229
01230 if (gFFiles)
01231 {
01232 if (hcon_size(gFFiles) > 0)
01233 {
01234 HIterator_t *hit = NULL;
01235 fitsfile **pfptr = NULL;
01236 int stat = 0;
01237 int fiostat = 0;
01238 const char *filehashkey = NULL;
01239 char fileinfokey[64];
01240 int ifile;
01241 char cfitsiostat[FLEN_STATUS];
01242 TASRW_FilePtrInfo_t fpinfo;
01243
01244 LinkedList_t *llist = NULL;
01245 ListNode_t *node = NULL;
01246 char *onefile = NULL;
01247
01248 llist = list_llcreate(sizeof(char *), NULL);
01249
01250 if (llist)
01251 {
01252
01253 hit = hiter_create(gFFiles);
01254
01255 if (hit)
01256 {
01257 if (verbose)
01258 {
01259 fprintf(stdout, "fitsrw_closefptrs(): Attempting to close %d fitsfile pointers.\n", gFFiles->num_total);
01260 }
01261
01262 ifile = 0;
01263 while ((pfptr = (fitsfile **)hiter_extgetnext(hit, &filehashkey)) != NULL)
01264 {
01265
01266
01267
01268
01269
01270
01271 list_llinserttail(llist, (void *)&filehashkey);
01272 ifile++;
01273 }
01274
01275 hiter_destroy(&hit);
01276 }
01277
01278
01279 list_llreset(llist);
01280 while ((node = list_llnext(llist)) != NULL)
01281 {
01282 stat = 0;
01283 onefile = *((char **)node->data);
01284 pfptr = (fitsfile **)hcon_lookup(gFFiles, onefile);
01285
01286 if (pfptr && *pfptr)
01287 {
01288
01289 snprintf(fileinfokey, sizeof(fileinfokey), "%p", (void *)*pfptr);
01290
01291 hcon_remove(gFFPtrInfo, fileinfokey);
01292
01293 if (IsWriteable(onefile))
01294 {
01295
01296
01297
01298
01299 stat = fitsrw_getfpinfo(*pfptr, &fpinfo);
01300
01301 if (stat)
01302 {
01303 fprintf(stderr, "Missing file info for fits file '%s'.\n", onefile);
01304
01305 }
01306 else
01307 {
01308 if (fpinfo.bitfield & kInfoPresent_Dirt)
01309 {
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319 int dimlen;
01320 int imgType;
01321 long long *axes = NULL;
01322 int iaxis;
01323
01324 axes = calloc(fpinfo.naxis, sizeof(long long));
01325
01326 if (!axes)
01327 {
01328 stat = CFITSIO_ERROR_OUT_OF_MEMORY;
01329 }
01330 else
01331 {
01332 for (iaxis = 0; iaxis < fpinfo.naxis; iaxis++)
01333 {
01334 axes[iaxis] = fpinfo.naxes[iaxis];
01335 }
01336
01337 switch(fpinfo.bitpix)
01338 {
01339 case(BYTE_IMG): imgType = SBYTE_IMG; break;
01340 case(SHORT_IMG): imgType = SHORT_IMG; break;
01341 case(LONG_IMG): imgType = LONG_IMG; break;
01342 case(LONGLONG_IMG): imgType = LONGLONG_IMG; break;
01343 case(FLOAT_IMG): imgType = FLOAT_IMG; break;
01344 case(DOUBLE_IMG): imgType = DOUBLE_IMG; break;
01345 }
01346
01347 fiostat = 0;
01348 fits_resize_imgll(*pfptr, imgType, fpinfo.naxis, axes, &fiostat);
01349
01350 if (fiostat)
01351 {
01352 fprintf(stderr, "FITSIO error: %d.\n", fiostat);
01353 fprintf(stderr, "unable to resize image in fits file\n");
01354 stat = CFITSIO_ERROR_LIBRARY;
01355 }
01356
01357
01358
01359
01360
01361 free(axes);
01362 axes = NULL;
01363 }
01364 }
01365 }
01366
01367 if (!stat)
01368 {
01369 if (verbose)
01370 {
01371 PushTimer();
01372 }
01373
01374 fiostat = 0;
01375 fits_write_chksum(*pfptr, &fiostat);
01376
01377 if (fiostat)
01378 {
01379 fits_get_errstatus(fiostat, cfitsiostat);
01380 fprintf(stderr, "Closing all fitsfiles: error calculating and writing checksum for fitsfile '%s'.\n", onefile);
01381 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
01382 stat = CFITSIO_ERROR_LIBRARY;
01383 }
01384
01385 if (verbose)
01386 {
01387 fprintf(stdout, "Time to write checksum on fitsfile '%s' = %f sec.\n", onefile, PopTimer());
01388 }
01389 }
01390 }
01391
01392 if (verbose)
01393 {
01394 PushTimer();
01395 }
01396
01397 fiostat = 0;
01398 fits_close_file(*pfptr, &fiostat);
01399
01400 if (fiostat == 0)
01401 {
01402 if (verbose)
01403 {
01404 fprintf(stdout, "Closing fits file '%s'.\n", onefile);
01405 }
01406 }
01407 else
01408 {
01409 fits_get_errstatus(fiostat, cfitsiostat);
01410 fprintf(stderr, "Closing all fitsfiles: error closing fitsfile '%s'.\n", onefile);
01411 fprintf(stderr, "CFITSIO error '%s'\n", cfitsiostat);
01412 perror("fitsrw_closefptrs() system error");
01413 if (!stat)
01414 {
01415 stat = CFITSIO_ERROR_FILE_IO;
01416 }
01417 }
01418
01419 if (verbose)
01420 {
01421 fprintf(stdout, "Time to close fitsfile '%s' = %f sec.\n", onefile, PopTimer());
01422 }
01423 }
01424 else
01425 { if (!stat)
01426 {
01427 stat = CFITSIO_ERROR_FILE_IO;
01428 }
01429
01430 fprintf(stderr, "Unknown fitsfile '%s'.\n", onefile);
01431 }
01432
01433 if (stat)
01434 {
01435 fprintf(stderr, "Error closing fitsfile '%s'.\n", onefile);
01436 }
01437
01438 hcon_remove(gFFiles, onefile);
01439 if (verbose)
01440 {
01441 fprintf(stdout, "Number fitsfiles still open: %d\n", gFFiles->num_total);
01442 }
01443
01444 if (stat && exit_code == CFITSIO_SUCCESS)
01445 {
01446 exit_code = stat;
01447 }
01448 }
01449
01450 list_llfree(&llist);
01451 }
01452 }
01453
01454 hcon_destroy(&gFFPtrInfo);
01455 hcon_destroy(&gFFiles);
01456 }
01457
01458 return exit_code;
01459 }
01460
01461 int fitsrw_getfpinfo_ext(fitsfile *fptr, CFITSIO_IMAGE_INFO *info)
01462 {
01463 return fitsrw_getfpinfo(fptr, (TASRW_FilePtrInfo_t *)info);
01464 }
01465
01466 int fitsrw_setfpinfo_ext(fitsfile *fptr, CFITSIO_IMAGE_INFO *info)
01467 {
01468 return fitsrw_setfpinfo(fptr, (TASRW_FilePtrInfo_t *)info);
01469 }
01470
01471 int fitsrw_iscompressed(const char *cparms)
01472 {
01473 int rv = 0;
01474
01475 if (cparms && *cparms)
01476 {
01477 const char *pc = cparms;
01478
01479 SKIPWS(pc);
01480
01481
01482 if (strncmp(pc, "compress", 8) || strncmp(pc, "COMPRESS", 8))
01483 {
01484 pc += 8;
01485 SKIPWS(pc);
01486
01487 if (*pc == 'r' || *pc == 'R')
01488 {
01489 rv = 1;
01490 }
01491 }
01492 }
01493
01494 return rv;
01495 }
01496
01497 int fitsrw_initializeTAS(int verbose, const char *filename)
01498 {
01499 int fitsrwErr = CFITSIO_SUCCESS;
01500 fitsfile *fptr = fitsrw_getfptr(verbose, filename, 1, &fitsrwErr, NULL);
01501
01502 if (!fptr || fitsrwErr != CFITSIO_SUCCESS)
01503 {
01504 fprintf(stderr, "could not locate FITS TAS file '%s'\n", filename);
01505 fitsrwErr = CFITSIO_ERROR_FILE_IO;
01506 }
01507 else
01508 {
01509 TASRW_FilePtrInfo_t fpinfo;
01510
01511 if (fitsrw_getfpinfo(fptr, &fpinfo))
01512 {
01513 fprintf(stderr, "unable to get fitsfile image parameters\n");
01514 fitsrwErr = CFITSIO_ERROR_CANT_GET_FILEINFO;
01515 }
01516 else
01517 {
01518 TASRW_FilePtrInfo_t newinfo = fpinfo;
01519
01520 newinfo.naxes[fpinfo.naxis - 1] = 0;
01521 newinfo.bitfield |= kInfoPresent_Dirt;
01522 if (fitsrw_setfpinfo(fptr, &newinfo) != 0)
01523 {
01524 fprintf(stderr, "could not set FITS TAS-file (%s) information\n", filename);
01525 fitsrwErr = CFITSIO_ERROR_FILE_IO;
01526 }
01527 }
01528 }
01529
01530 return fitsrwErr;
01531 }