int main(int argc, char **argv) { int i, got; int maxrow=1024; Ev ev, ebuf=NULL; Fun fun, ofun; /* open file for reading */ if( !(fun=FunOpen(argv[1], "r", NULL)) ){ fprintf(stderr, "ERROR: can't open input funtools file: %s\n", argv[1]); return 1; } if( !(ofun=FunOpen(argv[2], "w", fun)) ){ fprintf(stderr, "ERROR: can't open output funtools file: %s\n", argv[2]); return 1; } /* select columns to read (and data types to convert to) */ got = FunColumnSelect(fun, sizeof(EvRec), "merge=update", "pi", "J", "rw", FUN_OFFSET(Ev, pi), NULL); /* read and process events */ while(ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got) ){ for(i=0; i<got; i++){ ev = (Ev)ebuf+i; ev->pi = ev->pi + 1; } if( FunTableRowPut(ofun, ebuf, got, 0, NULL) != got ){ fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[2]); return 1; } if( ebuf) free(ebuf); } /* close files */ FunClose(ofun); FunClose(fun); }
int main(int argc, char **argv) { int i; Fun fun; struct WorldCoor *wcs; /* WCS info */ double x,y,ra,dec,xr,yr; if(argc == 1){ fprintf(stderr, "usage: twcs iname\n"); exit(1); } /* open Funtools file */ /* Funopen makes initial WCS library call: wcs = wcsinit(header_string) */ if( !(fun = FunOpen(argv[1], "r ", NULL)) ){ fprintf(stderr, "ERROR can't open file: %s\n", argv[1]); exit(1); } /* get wcs structure */ FunInfoGet(fun,FUN_WCS,&wcs,0); if( !wcs || !iswcs(wcs) ){ fprintf(stderr,"No WCS data"); return(1); } /* read input, convert pixels to wcs and back */ while(1){ fprintf(stdout,"\nInput x y: "); if(scanf("%lf %lf", &x, &y) != EOF){ if(x <= -999) break; /* convert image pixels to sky coords */ pix2wcs(wcs, x, y, &ra, &dec); fprintf(stdout,"Convert from pixels to ra,dec using pix2wcs()\n"); fprintf(stdout, "x=%.10g y=%.10g -> ra=%.10g dec=%.10g\n", x, y, ra, dec); /* convert sky coords to image pixels */ fprintf(stdout,"Convert from ra,dec -> pixels using wcs2pix()\n"); wcs2pix(wcs, ra, dec, &xr, &yr, &i); fprintf(stdout, "ra=%.10g dec=%.10g -> x=%.10g y=%.10g offscale=%d\n", ra, dec, xr, yr, i); } else break; } /* clean up */ /* FunClose makes final WCS library call: wcsfree(wcs) */ FunClose(fun); return(0); }
/* global definitions and init calls go here */ $GLOBAL /* main program */ int main (int argc, char **argv) { int c, i, got, total, rectype, start, stop, skip, args; int del=0; char *s; Fun fun, ofun; Row rowbuf, rowptr; Row cur, prev, next; $AUTO /* local definitions, followed by init calls go here */ $LOCAL /* exit on gio errors */ setgerror(1); /* avoid shared library problems by using "process" type for filtering */ putenv("FILTER_PTYPE=process"); /* process switch arguments */ while ((c = getopt(argc, argv, "d")) != -1){ switch(c){ case 'd': del = 1; break; } } /* check for required arguments */ args = argc - optind; /* make sure we have minimal arguments */ if( args < $ARGS ){ if( $ARGS == 1 ) fprintf(stderr, "usage: [expr] | funcalc [-e expr] [-f file] iname\n"); else fprintf(stderr, "usage: [expr] | funcalc [-e expr] [-f file] iname oname [cols]\n"); goto error; } /* set rectype: determine whether we need prev,next records */ rectype=$RECTYPE; /* get maxrow,if user-specified */ if( (s=(char *)getenv("FUN_MAXROW")) != NULL ) maxrow = atoi(s); /* make sure max row is large enough to handle prev, next */ if( rectype & (REC_PREV|REC_NEXT) ) maxrow = MAX(3,maxrow); /* open input file */ if( !(fun = FunOpen(argv[optind+0], "rc", NULL)) ){ gerror(stderr, "could not FunOpen input file: %s\n", argv[optind+0]); goto error; } /* open the output FITS image, inheriting params from input */ if( $ARGS > 1 ){ if( !(ofun = FunOpen(argv[optind+1], "w", fun)) ){ gerror(stderr, "could not FunOpen output file: %s\n", argv[optind+1]); goto error; } } /* select columns */ FunColumnSelect(fun, sizeof(RowRec), "merge=replace", $SELECT NULL); /* activate specified columns -- these will be written to the output file */ if( args >= 3 ) FunColumnActivate(fun, argv[optind+2], NULL); /* allocate space for rowbuf -- we will manage this buffer ourselves */ rowbuf = (Row)calloc(maxrow, sizeof(RowRec)); /* no record read yet */ total = 0; /* any user-defined calls before we enter the row loop go here */ $BEFORE /* main loop -- get rows and process */ while( 1 ){ /* need prev record */ if( rectype & REC_PREV ){ /* no records yet: read new batch of records into start of rowbuf */ if( total == 0 ){ rowptr = rowbuf; } /* we have read records: move last record from last batch into first new record and read new records after that */ else{ /* if we are accessing next, we did not actually process final record, therefore we do it now */ if( rectype & REC_NEXT ){ memcpy(rowbuf, rowbuf+(got-2), sizeof(RowRec)*2); rowptr = rowbuf+2; } /* not accessing next, so we just move last record processed */ else{ memcpy(rowbuf, rowbuf+(got-1), sizeof(RowRec)); rowptr = rowbuf+1; } } /* start at 2nd record so as to have a valid prev */ start = 1; } /* processing that does not require prev */ else{ rowptr = rowbuf; start = 0; } /* adjust maxrow to account for handling of prev record */ skip = (rowptr - rowbuf)/sizeof(RowRec); /* read new rows */ if( !FunTableRowGet(fun, rowptr, maxrow-skip, NULL, &got) ) break; /* if we need access to next record, don't process the last one we read */ if( rectype & REC_NEXT ){ stop = got - 1; } /* processing that does not require acces to next, process as cur */ else{ stop = got; } /* process all rows */ for(i=start; i<stop; i++){ /* set up pointer to current row */ cur = rowbuf+i; /* set up pointer to prev and next as needed */ if( rectype & REC_PREV ) prev = rowbuf+(i-1); if( rectype & REC_NEXT ) next = rowbuf+(i+1); /* execute the expression */ $EXPR /* write out this row with the new column */ if( $ARGS > 1 ) FunTableRowPut(ofun, (char *)cur, 1, i, NULL); } total += got; } /* any user-defined calls after we finish the row loop go here */ $AFTER /* free row data */ if( rowbuf ) free(rowbuf); /* clean up -- close output before input to perform flush automatically */ if( $ARGS > 1 ) FunClose(ofun); FunClose(fun); /* delete program if necessary */ if( del ) unlink(argv[0]); return(0); error: /* delete program if necessary */ if( del ) unlink(argv[0]); return(1); }
int main (int argc, char **argv) { int i, got; int maxrow=MAXROW; double x=0.5; char *tmode; char *s; Fun fun, fun2; Ev ebuf, ev; /* exit on gio errors */ setgerror(2); /* make sure we have minimal arguments */ if( argc < 3 ) gerror(stderr, "usage: %s iname oname [columns]\n", argv[0]); /* get maxrow,if user-specified */ if( (s=(char *)getenv("FUN_MAXROW")) != NULL ) maxrow = atoi(s); /* open input file */ if( !(fun = FunOpen(argv[1], "rc", NULL)) ) gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); /* open the output FITS image, inheriting params from input */ if( !(fun2 = FunOpen(argv[2], "w", fun)) ) gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); /* if we have "time2", read it, else create it */ if( FunColumnLookup(fun, "tinc", 0, NULL, NULL, NULL, NULL, NULL, NULL) ) tmode = "rw"; else tmode = "w"; FunColumnSelect(fun, sizeof(EvRec), "merge=replace", "time", "D", "r", FUN_OFFSET(Ev, time), "ntime", "D", "rw", FUN_OFFSET(Ev, ntime), "tinc", "D", tmode, FUN_OFFSET(Ev, tinc), NULL); /* activate specified columns -- these will be written to the output file */ if( argc >= 4 ) FunColumnActivate(fun, argv[3], NULL); /* get rows -- let routine allocate the row array */ while( (ebuf = (Ev)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) ){ /* process all rows */ for(i=0; i<got; i++){ /* point to the i'th row */ ev = ebuf+i; ev->tinc += (i*sqrt(cos(x)*cos(x) + sin(x)*sin(x))); ev->ntime = ev->time + ev->tinc; /* write out row with the new columns */ FunTableRowPut(fun2, (char *)ev, 1, i, NULL); } /* free row data */ if( ebuf ) free(ebuf); } /* clean up -- close output before input to perform flush automatically */ FunClose(fun2); FunClose(fun); return(0); }
int main(int argc, char **argv) { int c; int args; int offscl; int dim1, dim2; int ix, iy; int offset; int debug=0; int dowcs=1; int idx=0; char tbuf[SZ_LINE]; double dval1, dval2; double dx, dy; double *dbuf; struct WorldCoor *wcs; Fun fun; /* process switch arguments */ while( (c = getopt(argc, argv, "d")) != -1){ switch(c){ case 'd': debug = 1; break; case 'i': dowcs = 0; break; } } /* check for required arguments */ args = argc - optind; if( args < 1 ){ fprintf(stderr, "usage: %s iname -d -i\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "where:\n"); fprintf(stderr, " -d\tprint out input and output position values\n"); fprintf(stderr, " -i\tinput values are image x,y (not ra,dec in deg)\n"); fprintf(stderr, "\n"); exit(1); } /* exit on gio errors */ setgerror(2); /* open the input FITS file */ if( !(fun = FunOpen(argv[optind], "r", NULL)) ) gerror(stderr, "could not FunOpen input file: %s\n", argv[optind]); /* extract and bin the data section into a double float image buffer */ if( !(dbuf = FunImageGet(fun, NULL, "bitpix=-64")) ) gerror(stderr, "could not FunImageGet: %s\n", argv[1]); /* get required information from funtools structure */ FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, FUN_WCS, &wcs, 0); /* for each line in the contour file ... */ while( fgets(tbuf, SZ_LINE, stdin) ){ /* ignore comments */ if( *tbuf == '#' ) continue; /* blank lines means reset counter */ if( *tbuf == '\n' ){ fprintf(stdout, "\n"); idx = 0; continue; } /* input contour values: ra, dec in degrees (or image coords if -i) */ if(sscanf(tbuf, "%lf %lf", &dval1, &dval2) != 2){ gerror(stderr, "invalid line in contour file: %s\n", tbuf); } /* convert input ra, dec to image x, y */ if( dowcs ){ wcs2pix(wcs, dval1, dval2, &dx, &dy, &offscl); /* make sure we are not off scale */ if( offscl ){ fprintf(stderr, "warning: wcs position is offscale: %s\n", tbuf); continue; } } else{ dx = dval1; dy = dval2; } /* convert image values to integers */ ix = (int)(dx+0.5); iy = (int)(dy+0.5); /* sanity checks -- must be inside the image */ if( (ix < 1) || (ix > dim1) || (iy < 1) || (iy > dim2)){ fprintf(stderr, "warning: image position off image: %s\n", tbuf); continue; } /* calculate offset into dbuf */ offset = (iy-1)*dim1 + ix-1; /* write out the index and the pixel value at the image position */ fprintf(stdout, "%d\t%f", idx, dbuf[offset]); /* debugging info, if necessary */ if( debug ){ fprintf(stdout, "\t %f %f\t%d %d", dval1, dval2, ix, iy); } /* finish off line */ fprintf(stdout, "\n"); /* bump to next index */ idx++; } /* close output first so that flush happens automatically */ FunClose(fun); if( dbuf ) free(dbuf); return(0); }
int main(int argc, char **argv) { int i; int got; int npha; char tbuf[SZ_LINE]; Ev ebuf, ev, nev; Fun fun, fun2; /* make sure we have minimal arguments */ if( argc < 3 ){ fprintf(stderr, "usage: %s iname oname [columns]\n", argv[0]); exit(1); } /* exit on gio errors */ setgerror(2); /* open input FITS file for reading, and allowing copy of other extensions */ if( !(fun = FunOpen(argv[1], "rc", NULL)) ) gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); /* look for the size of the phas vector */ if( !FunColumnLookup(fun, "phas", 0, NULL, NULL, NULL, NULL, &npha, NULL) ) gerror(stderr, "can't find phas column\n"); /* open the output FITS image, inheriting params from input */ if( !(fun2 = FunOpen(argv[2], "w", fun)) ) gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); /* allocate a new row buffer, now that we know the size of phas */ nev = (Ev)calloc(1, sizeof(EvRec)); nev->phas = (int *)calloc(npha, sizeof(int)); /* create format statement for the pha vector, @ means its a pointer */ sprintf(tbuf, "@%dJ", npha); /* specify input columns we want brought into user space */ FunColumnSelect(fun, sizeof(EvRec), "merge=replace", "$x", "D", "rw", FUN_OFFSET(Ev, x), "$y", "D", "rw", FUN_OFFSET(Ev, y), "phas", tbuf, "rw", FUN_OFFSET(Ev, phas), NULL); /* set columns to be written to the output file */ if( argc >= 4 ) FunColumnActivate(fun, argv[3], NULL); /* loop through rows and replicate */ while( (ebuf=(Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ for(i=0; i<got; i++){ /* get pointer to the user info containing x,y, phas */ ev = ebuf+i; /* generate a new rows (with new x, y, phas values) */ Reverse(ev->x, ev->y, ev->phas, &(nev->x), &(nev->y), nev->phas, npha); /* write this new row -- with the replacements from user space */ FunTableRowPut(fun2, nev, 1, i, NULL); } if( ebuf ) free(ebuf); } /* free the new row */ if( nev ){ if( nev->phas ) free(nev->phas); free(nev); } /* close output before input so that funtools will copy the rest of the input extensions to the output (if such copy is requred) */ FunClose(fun2); FunClose(fun); return(0); }
int main(int argc, char **argv) { int c, i, j, got, args, jsonlen, istart; int odim1, odim2, blen, pad; int idim1=0, idim2=0, bitpix=0, ncard=0; int verbose=0; size_t totbytes, dlen; char tbuf[SZ_LINE]; char *buf=NULL; char *jsonheader=NULL; char *iname=NULL, *oname=NULL; FILE *ofp=NULL; Optinfo optinfo; #if HAVE_CFITSIO int status = 0; int n; int hdutype; int maxcard, morekeys; int dims[2] = {0, 0}; int block = 1; void *dbuf; double d1, d2, d3, d4; double cens[2] = {0.0, 0.0}; char *s; char *filter=NULL; char *evtlist = DEF_EVTLIST; char card[81]; char s1[BUFLEN], s2[BUFLEN], s3[BUFLEN], s4[BUFLEN]; fitsfile *fptr=NULL, *ofptr=NULL; #elif HAVE_FUNTOOLS char *s=NULL; int dtype; Fun ifun=NULL, tfun=NULL; #endif /* we want the args in the same order in which they arrived, and gnu getopt sometimes changes things without this */ putenv("POSIXLY_CORRECT=true"); /* process switch arguments */ while ((c = getopt(argc, argv, "b:e:f:s:v")) != -1){ switch(c){ case 'b': #if HAVE_CFITSIO block = atoi(optarg); #else fprintf(stderr, "warning: -b switch only for cfitsio (ignoring)\n"); #endif break; case 'e': #if HAVE_CFITSIO evtlist = optarg; #else fprintf(stderr, "warning: -e switch only for cfitsio (ignoring)\n"); #endif break; case 'f': #if HAVE_CFITSIO filter = optarg; #else fprintf(stderr, "warning: -f switch only for cfitsio (ignoring)\n"); #endif break; case 's': #if HAVE_CFITSIO s = strdup(optarg); if( strlen(s) > BUFLEN ) s[BUFLEN-1] = '\0'; if( sscanf(s, "%[0-9.*] @ %[-0-9.*] , %[0-9.*] @ %[-0-9.*]%n", s1, s2, s3, s4, &n) == 4){ dims[0] = atof(s1); cens[0] = atof(s2); dims[1] = atof(s3); cens[1] = atof(s4); } else if(sscanf(s, "%[-0-9.*] : %[-0-9.*] , %[-0-9.*] : %[-0-9.*]%n", s1, s2, s3, s4, &n) == 4){ d1 = atof(s1); d2 = atof(s2); d3 = atof(s3); d4 = atof(s4); dims[0] = d2 - d1 + 1; cens[0] = dims[0] / 2; dims[1] = d4 - d3 + 1; cens[1] = dims[1] / 2; } else { fprintf(stderr, "warning: unknown arg for -s switch (ignoring)\n"); } if( s ) free(s); #else fprintf(stderr, "warning: -s switch only for cfitsio (ignoring)\n"); #endif break; case 'v': verbose++; break; } } /* check for required arguments */ args = argc - optind; if( args < 2 ){ fprintf(stderr, "usage: %s iname oname\n", argv[0]); exit(1); } iname = argv[optind++]; oname = argv[optind++]; /* optional info */ if( !(optinfo = (Optinfo)calloc(sizeof(OptinfoRec), 1)) ){ fprintf(stderr, "ERROR: can't allocate optional info rec\n"); exit(1); } /* open the input FITS file */ #if HAVE_CFITSIO fptr = openFITSFile(iname, evtlist, &hdutype, &status); errchk(status); #elif HAVE_FUNTOOLS if( !(ifun = FunOpen(iname, "r", NULL)) ){ fprintf(stderr, "ERROR could not open input FITS file: %s (%s)\n", iname, strerror(errno)); exit(1); } #endif /* save the input filename in the png file */ optinfo->fitsname = iname; /* open the output PGN file */ if( !strcmp(oname, "-") || !strcmp(oname, "stdout") ){ ofp = stdout; } else if( !(ofp = fopen(oname, "w")) ){ fprintf(stderr, "ERROR: could not create output PNG file: %s (%s)\n", oname, strerror(errno)); exit(1); } #if HAVE_CFITSIO switch(hdutype){ case IMAGE_HDU: // get image array dbuf = getImageToArray(fptr, NULL, NULL, &idim1, &idim2, &bitpix, &status); errchk(status); fits_get_hdrspace(fptr, &maxcard, &morekeys, &status); errchk(status); ofptr = fptr; break; default: ofptr = filterTableToImage(fptr, filter, NULL, dims, cens, block, &status); errchk(status); // get image array dbuf = getImageToArray(ofptr, NULL, NULL, &idim1, &idim2, &bitpix, &status); errchk(status); // get number of keys fits_get_hdrspace(ofptr, &maxcard, &morekeys, &status); errchk(status); break; } #elif HAVE_FUNTOOLS /* copy the input fits header into a FITS image header */ if( !(tfun = (Fun)calloc(1, sizeof(FunRec))) ){ fprintf(stderr, "ERROR: could not create tfun struct\n"); exit(1); } _FunCopy2ImageHeader(ifun, tfun); /* and save for storage in the png file */ optinfo->fitsheader = (char *)tfun->header->cards; /* get image parameters. its safe to do this before calling image get so long as we don't change bitpix before that call */ FunInfoGet(ifun, FUN_SECT_BITPIX, &bitpix, FUN_SECT_DIM1, &idim1, FUN_SECT_DIM2, &idim2, 0); #endif /* convert FITS header into a json string */ snprintf(tbuf, SZ_LINE-1, "{\"js9Protocol\": %s, ", JS9_PROTOCOL); scat(tbuf, &jsonheader); snprintf(tbuf, SZ_LINE-1, "\"js9Endian\": \"%s\", ", JS9_ENDIAN); scat(tbuf, &jsonheader); snprintf(tbuf, SZ_LINE-1, "\"cardstr\": \""); scat(tbuf, &jsonheader); // concat header cards into a single string #if HAVE_CFITSIO while( ++ncard <= maxcard ){ fits_read_record(ofptr, ncard, card, &status); errchk(status); // change " to ' for(i=0; i<80; i++){ if( card[i] == '"' ){ card[i] = '\''; } } snprintf(tbuf, SZ_LINE-1, "%-80s", card); scat(tbuf, &jsonheader); } #elif HAVE_FUNTOOLS while( (s = FunParamGets(tfun, NULL, ++ncard, NULL, &dtype)) ){ for(i=0; i<80; i++){ if( s[i] == '"' ){ s[i] = '\''; } } scat(s, &jsonheader); if( s ) free(s); } #endif // end with the number of cards snprintf(tbuf, SZ_LINE-1, "\", \"ncard\": %d}", ncard); scat(tbuf, &jsonheader); /* we want the image buffer to start on an 8-byte boundary, so make jsonheader + null byte end on one */ pad = 8 - (strlen(jsonheader) % 8) - 1; for(i=0; i<pad; i++){ strcat(jsonheader, " "); } /* get final length of json header */ jsonlen = strlen(jsonheader); /* total length of the header + null + image we are storing */ blen = ABS(bitpix/8); dlen = (size_t)idim1 * (size_t)idim2 * blen; totbytes = jsonlen + 1 + dlen; /* all of this should now fit into the png image */ /* somewhat arbitrarily, we use idim1 for odim1, and adjust odim2 to fit */ odim1 = idim1; odim2 = (int)(((totbytes + odim1 - 1) / odim1) + (COLOR_CHANNELS-1)) / COLOR_CHANNELS; /* allocate buf to hold json header + null byte + RGB image */ if( !(buf=calloc(COLOR_CHANNELS, odim1 * odim2)) ){ fprintf(stderr, "ERROR: can't allocate image buf\n"); exit(1); } /* move the json header into the output buffer */ memmove(buf, jsonheader, jsonlen); /* add a null byte to signify end of json header */ buf[jsonlen] = '\0'; /* offset into image buffer where image starts, past header and null byte */ istart = jsonlen + 1; /* debug output */ if( verbose ){ fprintf(stderr, "idim=%d,%d (bitpix=%d jsonlen=%d istart=%d endian=%s) [%ld] -> odim=%d,%d [%d]\n", idim1, idim2, bitpix, jsonlen, istart, JS9_ENDIAN, totbytes, odim1, odim2, odim1 * odim2 * COLOR_CHANNELS); } #if HAVE_CFITSIO /* move the json header into the output buffer */ memmove(&buf[istart], dbuf, dlen); #elif HAVE_FUNTOOLS /* extract and bin the data section into an image buffer */ if( !FunImageGet(ifun, &buf[istart], NULL) ){ fprintf(stderr, "ERROR: could not FunImageGet: %s\n", iname); exit(1); } #endif /* debugging output to check against javascript input */ if( verbose > 1 ){ fprintf(stderr, "jsonheader: %s\n", jsonheader); for(j=0; j<idim2; j++){ fprintf(stderr, "data #%d: ", j); for(i=0; i<idim1; i++){ switch(bitpix){ case 8: fprintf(stderr, "%d ", *(unsigned char *)(buf + istart + ((j * idim1) + i) * blen)); break; case 16: fprintf(stderr, "%d ", *(short *)(buf + istart + ((j * idim1) + i) * blen)); break; case -16: fprintf(stderr, "%d ", *(unsigned short *)(buf + istart + ((j * idim1) + i) * blen)); break; case 32: fprintf(stderr, "%d ", *(int *)(buf + istart + ((j * idim1) + i) * blen)); break; case -32: fprintf(stderr, "%.3f ", *(float *)(buf + istart + ((j * idim1) + i) * blen)); break; case -64: fprintf(stderr, "%.3f ", *(double *)(buf + istart + ((j * idim1) + i) * blen)); break; } } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } /* might have to swap to preferred endian for png creation */ if( (!strncmp(JS9_ENDIAN, "l", 1) && is_bigendian()) || (!strncmp(JS9_ENDIAN, "b", 1) && !is_bigendian()) ){ swap_data(&buf[istart], idim1 * idim2, bitpix/8); } /* write the PNG file */ got = writePNG(ofp, buf, odim1, odim2, optinfo); /* free up space */ if( buf ) free(buf); if( optinfo ) free(optinfo); if( jsonheader ) free(jsonheader); /* close files */ #if HAVE_CFITSIO status = 0; if( ofptr && (ofptr != fptr) ) closeFITSFile(ofptr, &status); if( fptr ) closeFITSFile(fptr, &status); if( dbuf ) free(dbuf); #elif HAVE_FUNTOOLS if( ifun ) FunClose(ifun); if( tfun ){ FunClose(tfun); free(tfun); } #endif if( ofp) fclose(ofp); /* return the news */ return got; }