diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-26 21:13:00 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-26 21:13:00 (GMT) |
commit | da2e3d212171bbe64c1af39114fd067308656990 (patch) | |
tree | 9601f7ed15fa1394762124630c12a792bc073ec2 /funtools/wcs/fitsfile.c | |
parent | 76b109ad6d97d19ab835596dc70149ef379f3733 (diff) | |
download | blt-da2e3d212171bbe64c1af39114fd067308656990.zip blt-da2e3d212171bbe64c1af39114fd067308656990.tar.gz blt-da2e3d212171bbe64c1af39114fd067308656990.tar.bz2 |
rm funtools for update
Diffstat (limited to 'funtools/wcs/fitsfile.c')
-rw-r--r-- | funtools/wcs/fitsfile.c | 2308 |
1 files changed, 0 insertions, 2308 deletions
diff --git a/funtools/wcs/fitsfile.c b/funtools/wcs/fitsfile.c deleted file mode 100644 index 0ff9479..0000000 --- a/funtools/wcs/fitsfile.c +++ /dev/null @@ -1,2308 +0,0 @@ -/*** File libwcs/fitsfile.c - *** September 15, 2011 - *** By Jessica Mink, jmink@cfa.harvard.edu - *** Harvard-Smithsonian Center for Astrophysics - *** Copyright (C) 1996-2011 - *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Correspondence concerning WCSTools should be addressed as follows: - Internet email: jmink@cfa.harvard.edu - Postal address: Jessica Mink - Smithsonian Astrophysical Observatory - 60 Garden St. - Cambridge, MA 02138 USA - - * Module: fitsfile.c (FITS file reading and writing) - * Purpose: Read and write FITS image and table files - * fitsropen (inpath) - * Open a FITS file for reading, returning a FILE pointer - * fitsrhead (filename, lhead, nbhead) - * Read FITS header and return it - * fitsrtail (filename, lhead, nbhead) - * Read appended FITS header and return it - * fitsrsect (filename, nbhead, header, fd, x0, y0, nx, ny) - * Read section of a FITS image, having already read the header - * fitsrimage (filename, nbhead, header) - * Read FITS image, having already ready the header - * fitsrfull (filename, nbhead, header) - * Read a FITS image of any dimension - * fitsrtopen (inpath, nk, kw, nrows, nchar, nbhead) - * Open a FITS table file for reading; return header information - * fitsrthead (header, nk, kw, nrows, nchar, nbhead) - * Extract FITS table information from a FITS header - * fitsrtline (fd, nbhead, lbuff, tbuff, irow, nbline, line) - * Read next line of FITS table file - * ftgetr8 (entry, kw) - * Extract column from FITS table line as double - * ftgetr4 (entry, kw) - * Extract column from FITS table line as float - * ftgeti4 (entry, kw) - * Extract column from FITS table line as int - * ftgeti2 (entry, kw) - * Extract column from FITS table line as short - * ftgetc (entry, kw, string, maxchar) - * Extract column from FITS table line as a character string - * fitswimage (filename, header, image) - * Write FITS header and image - * fitswext (filename, header, image) - * Write FITS header and image as extension to existing FITS file - * fitswhdu (fd, filename, header, image) - * Write FITS header and image as extension to file descriptor - * fitscimage (filename, header, filename0) - * Write FITS header and copy FITS image - * fitswhead (filename, header) - * Write FITS header and keep file open for further writing - * fitswexhead (filename, header) - * Write FITS header only to FITS extension without writing data - * isfits (filename) - * Return 1 if file is a FITS file, else 0 - * fitsheadsize (header) - * Return size of FITS header in bytes - */ - -#include <stdlib.h> -#ifndef VMS -#include <unistd.h> -#endif -#include <stdio.h> -#include <fcntl.h> -#include <sys/file.h> -#include <errno.h> -#include <string.h> -#include "fitsfile.h" - -static int verbose=0; /* Print diagnostics */ -static char fitserrmsg[80]; -static int fitsinherit = 1; /* Append primary header to extension header */ -void -setfitsinherit (inh) -int inh; -{fitsinherit = inh; return;} - -static off_t ibhead = 0; /* Number of bytes read before header starts */ - -off_t -getfitsskip() -{return (ibhead);} - -/* FITSRHEAD -- Read a FITS header */ - -char * -fitsrhead (filename, lhead, nbhead) - -char *filename; /* Name of FITS image file */ -int *lhead; /* Allocated length of FITS header in bytes (returned) */ -int *nbhead; /* Number of bytes before start of data (returned) */ - /* This includes all skipped image extensions */ - -{ - int fd; - char *header; /* FITS image header (filled) */ - int extend; - int nbytes,naxis, i; - int ntry,nbr,irec,nrec, nbh, ipos, npos, nbprim, lprim, lext; - int nax1, nax2, nax3, nax4, nbpix, ibpix, nblock, nbskip; - char fitsbuf[2884]; - char *headend; /* Pointer to last line of header */ - char *headnext; /* Pointer to next line of header to be added */ - int hdu; /* header/data unit counter */ - int extnum; /* desired header data number - (0=primary -1=first with data -2=use EXTNAME) */ - char extname[32]; /* FITS extension name */ - char extnam[32]; /* Desired FITS extension name */ - char *ext; /* FITS extension name or number in header, if any */ - char *pheader; /* Primary header (naxis is 0) */ - char cext = 0; - char *rbrac; /* Pointer to right bracket if present in file name */ - char *mwcs; /* Pointer to WCS name separated by % */ - char *newhead; /* New larger header */ - int nbh0; /* Length of old too small header */ - char *pheadend; - int inherit = 1; /* Value of INHERIT keyword in FITS extension header */ - int extfound = 0; /* Set to one if desired FITS extension is found */ - int npcount; - - pheader = NULL; - lprim = 0; - header = NULL; - - /* Check for FITS WCS specification and ignore for file opening */ - mwcs = strchr (filename, '%'); - if (mwcs != NULL) - *mwcs = (char) 0; - - /* Check for FITS extension and ignore for file opening */ - rbrac = NULL; - ext = strchr (filename, ','); - if (ext == NULL) { - ext = strchr (filename, '['); - if (ext != NULL) { - rbrac = strchr (filename, ']'); - if (rbrac != NULL) - *rbrac = (char) 0; - } - } - if (ext != NULL) { - cext = *ext; - *ext = (char) 0; - } - - /* Open the image file and read the header */ - if (strncasecmp (filename,"stdin",5)) { - fd = -1; - fd = fitsropen (filename); - } -#ifndef VMS - else { - fd = STDIN_FILENO; - extnum = -1; - } -#endif - - if (ext != NULL) { - if (isnum (ext+1)) - extnum = atoi (ext+1); - else { - extnum = -2; - strcpy (extnam, ext+1); - } - } - else - extnum = -1; - - /* Repair the damage done to the file-name string during parsing */ - if (ext != NULL) - *ext = cext; - if (rbrac != NULL) - *rbrac = ']'; - if (mwcs != NULL) - *mwcs = '%'; - - if (fd < 0) { - fprintf (stderr,"FITSRHEAD: cannot read file %s\n", filename); - return (NULL); - } - - nbytes = FITSBLOCK; - *nbhead = 0; - headend = NULL; - nbh = FITSBLOCK * 20 + 4; - header = (char *) calloc ((unsigned int) nbh, 1); - (void) hlength (header, nbh); - headnext = header; - nrec = 1; - hdu = 0; - ibhead = 0; - - /* Read FITS header from input file one FITS block at a time */ - irec = 0; - ibhead = 0; - while (irec < 200) { - nbytes = FITSBLOCK; - for (ntry = 0; ntry < 10; ntry++) { - for (i = 0; i < 2884; i++) fitsbuf[i] = 0; - nbr = read (fd, fitsbuf, nbytes); - - /* Short records allowed only if they have the last header line */ - if (nbr < nbytes) { - headend = ksearch (fitsbuf,"END"); - if (headend == NULL) { - if (ntry < 9) { - if (verbose) - fprintf (stderr,"FITSRHEAD: %d / %d bytes read %d\n", - nbr,nbytes,ntry); - } - else { - snprintf(fitserrmsg,79,"FITSRHEAD: '%d / %d bytes of header read from %s\n" - ,nbr,nbytes,filename); -#ifndef VMS - if (fd != STDIN_FILENO) -#endif - (void)close (fd); - free (header); - /* if (pheader != NULL) - return (pheader); */ - if (extnum != -1 && !extfound) { - *ext = (char) 0; - if (extnum < 0) { - snprintf (fitserrmsg,79, - "FITSRHEAD: Extension %s not found in file %s", - extnam, filename); - } - else { - snprintf (fitserrmsg,79, - "FITSRHEAD: Extension %d not found in file %s", - extnum, filename); - } - *ext = cext; - } - else if (hdu > 0) { - snprintf (fitserrmsg,79, - "FITSRHEAD: No extensions found in file %s", filename); - hdu = 0; - if (pheader != NULL) { - *lhead = nbprim; - *nbhead = nbprim; - return (pheader); - } - break; - } - else { - snprintf (fitserrmsg,79, - "FITSRHEAD: No header found in file %s", filename); - } - return (NULL); - } - } - else - break; - } - else - break; - } - - /* Move current FITS record into header string */ - for (i = 0; i < 2880; i++) - if (fitsbuf[i] < 32 || i > nbr) fitsbuf[i] = 32; - if (nbr < 2880) - nbr = 2880; - strncpy (headnext, fitsbuf, nbr); - *nbhead = *nbhead + nbr; - nrec = nrec + 1; - *(headnext+nbr) = 0; - ibhead = ibhead + 2880; - - /* Check to see if this is the final record in this header */ - headend = ksearch (fitsbuf,"END"); - if (headend == NULL) { - - /* Increase size of header buffer by 4 blocks if too small */ - if (nrec * FITSBLOCK > nbh) { - nbh0 = nbh; - nbh = (nrec + 4) * FITSBLOCK + 4; - newhead = (char *) calloc (1,(unsigned int) nbh); - for (i = 0; i < nbh0; i++) - newhead[i] = header[i]; - free (header); - header = newhead; - (void) hlength (header, nbh); - headnext = header + *nbhead - FITSBLOCK; - } - headnext = headnext + FITSBLOCK; - } - - else { - naxis = 0; - hgeti4 (header,"NAXIS",&naxis); - - /* If header has no data, save it for appending to desired header */ - if (naxis < 1) { - nbprim = nrec * FITSBLOCK; - headend = ksearch (header,"END"); - lprim = headend + 80 - header; - pheader = (char *) calloc ((unsigned int) nbprim, 1); - for (i = 0; i < lprim; i++) - pheader[i] = header[i]; - strncpy (pheader, header, lprim); - } - - /* If header has no data, start with the next record */ - if (naxis < 1 && extnum == -1) { - extend = 0; - hgetl (header,"EXTEND",&extend); - if (naxis == 0 && extend) { - headnext = header; - *headend = ' '; - headend = NULL; - nrec = 1; - hdu = hdu + 1; - } - else { - break; - } - } - - /* If this is the desired header data unit, keep it */ - else if (extnum != -1) { - if (extnum > -1 && hdu == extnum) { - extfound = 1; - break; - } - else if (extnum < 0) { - extname[0] = 0; - hgets (header, "EXTNAME", 32, extname); - if (!strcmp (extnam,extname)) { - extfound = 1; - break; - } - } - - /* If this is not desired header data unit, skip over data */ - hdu = hdu + 1; - nblock = 0; - ibhead = 0; - if (naxis > 0) { - ibpix = 0; - hgeti4 (header,"BITPIX",&ibpix); - if (ibpix < 0) { - nbpix = -ibpix / 8; - } - else { - nbpix = ibpix / 8; - } - nax1 = 1; - hgeti4 (header,"NAXIS1",&nax1); - nax2 = 1; - if (naxis > 1) { - hgeti4 (header,"NAXIS2",&nax2); - } - nax3 = 1; - if (naxis > 2) { - hgeti4 (header,"NAXIS3",&nax3); - } - nax4 = 1; - if (naxis > 3) { - hgeti4 (header,"NAXIS4",&nax4); - } - nbskip = nax1 * nax2 * nax3 * nax4 * nbpix; - nblock = nbskip / 2880; - if (nblock*2880 < nbskip) { - nblock = nblock + 1; - } - npcount = 0; - hgeti4 (header,"PCOUNT", &npcount); - if (npcount > 0) { - nbskip = nbskip + npcount; - nblock = nbskip / 2880; - if (nblock*2880 < nbskip) - nblock = nblock + 1; - } - } - else { - nblock = 0; - } - *nbhead = *nbhead + (nblock * 2880); - - /* Set file pointer to beginning of next header/data unit */ - if (nblock > 0) { -#ifndef VMS - if (fd != STDIN_FILENO) { - ipos = lseek (fd, *nbhead, SEEK_SET); - npos = *nbhead; - } - else { -#else - { -#endif - ipos = 0; - for (i = 0; i < nblock; i++) { - nbytes = FITSBLOCK; - nbr = read (fd, fitsbuf, nbytes); - if (nbr < nbytes) { - ipos = ipos + nbr; - break; - } - else { - ipos = ipos + nbytes; - } - } - npos = nblock * 2880; - } - if (ipos < npos) { - snprintf (fitserrmsg,79,"FITSRHEAD: %d / %d bytes skipped\n", - ipos,npos); - extfound = 0; - break; - } - } - headnext = header; - headend = NULL; - nrec = 1; - } - else { - break; - } - } - } - -#ifndef VMS - if (fd != STDIN_FILENO) - (void)close (fd); -#endif - -/* Print error message and return null if extension not found */ - if (extnum != -1 && !extfound) { - if (extnum < 0) - fprintf (stderr, "FITSRHEAD: Extension %s not found in file %s\n",extnam, filename); - else - fprintf (stderr, "FITSRHEAD: Extension %d not found in file %s\n",extnum, filename); - if (pheader != NULL) { - free (pheader); - pheader = NULL; - } - return (NULL); - } - - /* Allocate an extra block for good measure */ - *lhead = (nrec + 1) * FITSBLOCK; - if (*lhead > nbh) { - newhead = (char *) calloc (1,(unsigned int) *lhead); - for (i = 0; i < nbh; i++) - newhead[i] = header[i]; - free (header); - header = newhead; - (void) hlength (header, *lhead); - } - else - *lhead = nbh; - - /* If INHERIT keyword is FALSE, never append primary header */ - if (hgetl (header, "INHERIT", &inherit)) { - if (!inherit && fitsinherit) - fitsinherit = 0; - } - - /* Append primary data header to extension header */ - if (pheader != NULL && extnum != 0 && fitsinherit && hdu > 0) { - extname[0] = 0; - hgets (header, "XTENSION", 32, extname); - if (!strcmp (extname,"IMAGE")) { - strncpy (header, "SIMPLE ", 8); - hputl (header, "SIMPLE", 1); - } - headend = blsearch (header,"END"); - if (headend == NULL) - headend = ksearch (header, "END"); - lext = headend - header; - - /* Update primary header for inclusion at end of extension header */ - hchange (pheader, "SIMPLE", "ROOTHEAD"); - hchange (pheader, "NEXTEND", "NUMEXT"); - hdel (pheader, "BITPIX"); - hdel (pheader, "NAXIS"); - hdel (pheader, "EXTEND"); - hputl (pheader, "ROOTEND",1); - pheadend = ksearch (pheader,"END"); - lprim = pheadend + 320 - pheader; - if (lext + lprim > nbh) { - nrec = (lext + lprim) / FITSBLOCK; - if (FITSBLOCK*nrec < lext+lprim) - nrec = nrec + 1; - *lhead = (nrec+1) * FITSBLOCK; - newhead = (char *) calloc (1,(unsigned int) *lhead); - for (i = 0; i < nbh; i++) - newhead[i] = header[i]; - free (header); - header = newhead; - headend = header + lext; - (void) hlength (header, *lhead); - } - hputs (header,"COMMENT","-------------------------------------------"); - hputs (header,"COMMENT","Information from Primary Header"); - hputs (header,"COMMENT","-------------------------------------------"); - headend = blsearch (header,"END"); - if (headend == NULL) - headend = ksearch (header, "END"); - pheader[lprim] = 0; - strncpy (headend, pheader, lprim); - if (pheader != NULL) { - free (pheader); - pheader = NULL; - } - } - - ibhead = *nbhead - ibhead; - - return (header); -} - - -/* FITSRTAIL -- Read FITS header appended to graphics file */ - -char * -fitsrtail (filename, lhead, nbhead) - -char *filename; /* Name of image file */ -int *lhead; /* Allocated length of FITS header in bytes (returned) */ -int *nbhead; /* Number of bytes before start of data (returned) */ - /* This includes all skipped image extensions */ - -{ - int fd; - char *header; /* FITS image header (filled) */ - int nbytes, i, ndiff; - int nbr, irec; - off_t offset; - char *mwcs; /* Pointer to WCS name separated by % */ - char *headstart; - char *newhead; - - header = NULL; - - /* Check for FITS WCS specification and ignore for file opening */ - mwcs = strchr (filename, '%'); - if (mwcs != NULL) - *mwcs = (char) 0; - - /* Open the image file and read the header */ - if (strncasecmp (filename,"stdin",5)) { - fd = -1; - fd = fitsropen (filename); - } -#ifndef VMS - else { - fd = STDIN_FILENO; - } -#endif - - /* Repair the damage done to the file-name string during parsing */ - if (mwcs != NULL) - *mwcs = '%'; - - if (fd < 0) { - fprintf (stderr,"FITSRTAIL: cannot read file %s\n", filename); - return (NULL); - } - - nbytes = FITSBLOCK; - *nbhead = 0; - *lhead = 0; - - /* Read FITS header from end of input file one FITS block at a time */ - irec = 0; - while (irec < 100) { - nbytes = FITSBLOCK * (irec + 2); - header = (char *) calloc ((unsigned int) nbytes, 1); - offset = lseek (fd, -nbytes, SEEK_END); - if (offset < 0) { - free (header); - header = NULL; - nbytes = 0; - break; - } - for (i = 0; i < nbytes; i++) header[i] = 0; - nbr = read (fd, header, nbytes); - - /* Check for SIMPLE at start of header */ - for (i = 0; i < nbr; i++) - if (header[i] < 32) header[i] = 32; - if ((headstart = ksearch (header,"SIMPLE"))) { - if (headstart != header) { - ndiff = headstart - header; - newhead = (char *) calloc ((unsigned int) nbytes, 1); - for (i = 0; i < nbytes-ndiff; i++) - newhead[i] = headstart[i]; - free (header); - header = newhead; - } - *lhead = nbytes; - *nbhead = nbytes; - break; - } - free (header); - } - (void) hlength (header, nbytes); - -#ifndef VMS - if (fd != STDIN_FILENO) - (void)close (fd); -#endif - - return (header); -} - - -/* FITSRSECT -- Read a piece of a FITS image, having already read the header */ - -char * -fitsrsect (filename, header, nbhead, x0, y0, nx, ny, nlog) - -char *filename; /* Name of FITS image file */ -char *header; /* FITS header for image (previously read) */ -int nbhead; /* Actual length of image header(s) in bytes */ -int x0, y0; /* FITS image coordinate of first pixel */ -int nx; /* Number of columns to read (less than NAXIS1) */ -int ny; /* Number of rows to read (less than NAXIS2) */ -int nlog; /* Note progress mod this rows */ -{ - int fd; /* File descriptor */ - int nbimage, naxis1, naxis2, bytepix, nbread; - int bitpix, naxis, nblocks, nbytes, nbr; - int x1, y1, nbline, nyleft; - off_t impos, nblin; - char *image, *imline, *imlast; - int ilog = 0; - int row; - - /* Open the image file and read the header */ - if (strncasecmp (filename,"stdin", 5)) { - fd = -1; - - fd = fitsropen (filename); - if (fd < 0) { - snprintf (fitserrmsg,79, "FITSRSECT: cannot read file %s\n", filename); - return (NULL); - } - - /* Skip over FITS header and whatever else needs to be skipped */ - if (lseek (fd, nbhead, SEEK_SET) < 0) { - (void)close (fd); - snprintf (fitserrmsg,79, "FITSRSECT: cannot skip header of file %s\n", - filename); - return (NULL); - } - } -#ifndef VMS - else - fd = STDIN_FILENO; -#endif - - /* Compute size of image in bytes using relevant header parameters */ - naxis = 1; - hgeti4 (header,"NAXIS",&naxis); - naxis1 = 1; - hgeti4 (header,"NAXIS1",&naxis1); - naxis2 = 1; - hgeti4 (header,"NAXIS2",&naxis2); - bitpix = 0; - hgeti4 (header,"BITPIX",&bitpix); - if (bitpix == 0) { - /* snprintf (fitserrmsg,79, "FITSRSECT: BITPIX is 0; image not read\n"); */ - (void)close (fd); - return (NULL); - } - bytepix = bitpix / 8; - if (bytepix < 0) bytepix = -bytepix; - - /* Keep X coordinates within image limits */ - if (x0 < 1) - x0 = 1; - else if (x0 > naxis1) - x0 = naxis1; - x1 = x0 + nx - 1; - if (x1 < 1) - x1 = 1; - else if (x1 > naxis1) - x1 = naxis1; - nx = x1 - x0 + 1; - - /* Keep Y coordinates within image limits */ - if (y0 < 1) - y0 = 1; - else if (y0 > naxis2) - y0 = naxis2; - y1 = y0 + ny - 1; - if (y1 < 1) - y1 = 1; - else if (y1 > naxis2) - y1 = naxis2; - ny = y1 - y0 + 1; - - /* Number of bytes in output image */ - nbline = nx * bytepix; - nbimage = nbline * ny; - - /* Set number of bytes to integral number of 2880-byte blocks */ - nblocks = nbimage / FITSBLOCK; - if (nblocks * FITSBLOCK < nbimage) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Allocate image section to be read */ - image = (char *) malloc (nbytes); - nyleft = ny; - imline = image; - nbr = 0; - - /* Computer pointer to first byte of input image to read */ - nblin = naxis1 * bytepix; - impos = ((y0 - 1) * nblin) + ((x0 - 1) * bytepix); - row = y0 - 1; - - /* Read image section one line at a time */ - while (nyleft-- > 0) { - if (lseek (fd, impos, SEEK_CUR) >= 0) { - nbread = read (fd, imline, nbline); - nbr = nbr + nbread; - impos = nblin - nbread; - imline = imline + nbline; - row++; - if (++ilog == nlog) { - ilog = 0; - fprintf (stderr, "Row %5d extracted ", row); - (void) putc (13,stderr); - } - } - } - if (nlog) - fprintf (stderr, "\n"); - - /* Fill rest of image with zeroes */ - imline = image + nbimage; - imlast = image + nbytes; - while (imline++ < imlast) - *imline = (char) 0; - - /* Byte-reverse image, if necessary */ - if (imswapped ()) - imswap (bitpix, image, nbytes); - - return (image); -} - - -/* FITSRIMAGE -- Read a FITS image */ - -char * -fitsrimage (filename, nbhead, header) - -char *filename; /* Name of FITS image file */ -int nbhead; /* Actual length of image header(s) in bytes */ -char *header; /* FITS header for image (previously read) */ -{ - int fd; - int nbimage, naxis1, naxis2, bytepix, nbread; - int bitpix, naxis, nblocks, nbytes, nbleft, nbr; - int simple; - char *image, *imleft; - - /* Open the image file and read the header */ - if (strncasecmp (filename,"stdin", 5)) { - fd = -1; - - fd = fitsropen (filename); - if (fd < 0) { - snprintf (fitserrmsg,79, "FITSRIMAGE: cannot read file %s\n", filename); - return (NULL); - } - - /* Skip over FITS header and whatever else needs to be skipped */ - if (lseek (fd, nbhead, SEEK_SET) < 0) { - (void)close (fd); - snprintf (fitserrmsg,79, "FITSRIMAGE: cannot skip header of file %s\n", - filename); - return (NULL); - } - } -#ifndef VMS - else - fd = STDIN_FILENO; -#endif - - /* If SIMPLE=F in header, simply put post-header part of file in buffer */ - hgetl (header, "SIMPLE", &simple); - if (!simple) { - nbytes = getfilesize (filename) - nbhead; - if ((image = (char *) malloc (nbytes + 1)) == NULL) { - /* snprintf (fitserrmsg,79, "FITSRIMAGE: %d-byte image buffer cannot be allocated\n"); */ - (void)close (fd); - return (NULL); - } - hputi4 (header, "NBDATA", nbytes); - nbread = read (fd, image, nbytes); - return (image); - } - - /* Compute size of image in bytes using relevant header parameters */ - naxis = 1; - hgeti4 (header,"NAXIS",&naxis); - naxis1 = 1; - hgeti4 (header,"NAXIS1",&naxis1); - naxis2 = 1; - hgeti4 (header,"NAXIS2",&naxis2); - bitpix = 0; - hgeti4 (header,"BITPIX",&bitpix); - if (bitpix == 0) { - /* snprintf (fitserrmsg,79, "FITSRIMAGE: BITPIX is 0; image not read\n"); */ - (void)close (fd); - return (NULL); - } - bytepix = bitpix / 8; - if (bytepix < 0) bytepix = -bytepix; - - /* If either dimension is one and image is 3-D, read all three dimensions */ - if (naxis == 3 && (naxis1 ==1 || naxis2 == 1)) { - int naxis3; - hgeti4 (header,"NAXIS3",&naxis3); - nbimage = naxis1 * naxis2 * naxis3 * bytepix; - } - else - nbimage = naxis1 * naxis2 * bytepix; - - /* Set number of bytes to integral number of 2880-byte blocks */ - nblocks = nbimage / FITSBLOCK; - if (nblocks * FITSBLOCK < nbimage) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Allocate and read image */ - image = (char *) malloc (nbytes); - nbleft = nbytes; - imleft = image; - nbr = 0; - while (nbleft > 0) { - nbread = read (fd, imleft, nbleft); - nbr = nbr + nbread; -#ifndef VMS - if (fd == STDIN_FILENO && nbread < nbleft && nbread > 0) { - nbleft = nbleft - nbread; - imleft = imleft + nbread; - } - else -#endif - nbleft = 0; - } -#ifndef VMS - if (fd != STDIN_FILENO) - (void)close (fd); -#endif - if (nbr < nbimage) { - snprintf (fitserrmsg,79, "FITSRIMAGE: %d of %d bytes read from file %s\n", - nbr, nbimage, filename); - return (NULL); - } - - /* Byte-reverse image, if necessary */ - if (imswapped ()) - imswap (bitpix, image, nbytes); - - return (image); -} - - -/* FITSRFULL -- Read a FITS image of any dimension */ - -char * -fitsrfull (filename, nbhead, header) - -char *filename; /* Name of FITS image file */ -int nbhead; /* Actual length of image header(s) in bytes */ -char *header; /* FITS header for image (previously read) */ -{ - int fd; - int nbimage, naxisi, iaxis, bytepix, nbread; - int bitpix, naxis, nblocks, nbytes, nbleft, nbr, simple; - char keyword[16]; - char *image, *imleft; - - /* Open the image file and read the header */ - if (strncasecmp (filename,"stdin", 5)) { - fd = -1; - - fd = fitsropen (filename); - if (fd < 0) { - snprintf (fitserrmsg,79, "FITSRFULL: cannot read file %s\n", filename); - return (NULL); - } - - /* Skip over FITS header and whatever else needs to be skipped */ - if (lseek (fd, nbhead, SEEK_SET) < 0) { - (void)close (fd); - snprintf (fitserrmsg,79, "FITSRFULL: cannot skip header of file %s\n", - filename); - return (NULL); - } - } -#ifndef VMS - else - fd = STDIN_FILENO; -#endif - - /* If SIMPLE=F in header, simply put post-header part of file in buffer */ - hgetl (header, "SIMPLE", &simple); - if (!simple) { - nbytes = getfilesize (filename) - nbhead; - if ((image = (char *) malloc (nbytes + 1)) == NULL) { - snprintf (fitserrmsg,79, "FITSRFULL: %d-byte image buffer cannot be allocated\n",nbytes+1); - (void)close (fd); - return (NULL); - } - hputi4 (header, "NBDATA", nbytes); - nbread = read (fd, image, nbytes); - return (image); - } - - /* Find number of bytes per pixel */ - bitpix = 0; - hgeti4 (header,"BITPIX",&bitpix); - if (bitpix == 0) { - snprintf (fitserrmsg,79, "FITSRFULL: BITPIX is 0; image not read\n"); - (void)close (fd); - return (NULL); - } - bytepix = bitpix / 8; - if (bytepix < 0) bytepix = -bytepix; - nbimage = bytepix; - - /* Compute size of image in bytes using relevant header parameters */ - naxis = 1; - hgeti4 (header,"NAXIS",&naxis); - for (iaxis = 1; iaxis <= naxis; iaxis++) { - sprintf (keyword, "NAXIS%d", iaxis); - naxisi = 1; - hgeti4 (header,keyword,&naxisi); - nbimage = nbimage * naxisi; - } - - /* Set number of bytes to integral number of 2880-byte blocks */ - nblocks = nbimage / FITSBLOCK; - if (nblocks * FITSBLOCK < nbimage) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Allocate and read image */ - image = (char *) malloc (nbytes); - nbleft = nbytes; - imleft = image; - nbr = 0; - while (nbleft > 0) { - nbread = read (fd, imleft, nbleft); - nbr = nbr + nbread; -#ifndef VMS - if (fd == STDIN_FILENO && nbread < nbleft && nbread > 0) { - nbleft = nbleft - nbread; - imleft = imleft + nbread; - } - else -#endif - nbleft = 0; - } -#ifndef VMS - if (fd != STDIN_FILENO) - (void)close (fd); -#endif - if (nbr < nbimage) { - snprintf (fitserrmsg,79, "FITSRFULL: %d of %d image bytes read from file %s\n", - nbr, nbimage, filename); - return (NULL); - } - - /* Byte-reverse image, if necessary */ - if (imswapped ()) - imswap (bitpix, image, nbytes); - - return (image); -} - - -/* FITSROPEN -- Open a FITS file, returning the file descriptor */ - -int -fitsropen (inpath) - -char *inpath; /* Pathname for FITS tables file to read */ - -{ - int ntry; - int fd; /* file descriptor for FITS tables file (returned) */ - char *ext; /* extension name or number */ - char cext = 0; - char *rbrac; - char *mwcs; /* Pointer to WCS name separated by % */ - -/* Check for FITS WCS specification and ignore for file opening */ - mwcs = strchr (inpath, '%'); - -/* Check for FITS extension and ignore for file opening */ - ext = strchr (inpath, ','); - rbrac = NULL; - if (ext == NULL) { - ext = strchr (inpath, '['); - if (ext != NULL) { - rbrac = strchr (inpath, ']'); - } - } - -/* Open input file */ - for (ntry = 0; ntry < 3; ntry++) { - if (ext != NULL) { - cext = *ext; - *ext = 0; - } - if (rbrac != NULL) - *rbrac = (char) 0; - if (mwcs != NULL) - *mwcs = (char) 0; - fd = open (inpath, O_RDONLY); - if (ext != NULL) - *ext = cext; - if (rbrac != NULL) - *rbrac = ']'; - if (mwcs != NULL) - *mwcs = '%'; - if (fd >= 0) - break; - else if (ntry == 2) { - snprintf (fitserrmsg,79, "FITSROPEN: cannot read file %s\n", inpath); - return (-1); - } - } - - if (verbose) - fprintf (stderr,"FITSROPEN: input file %s opened\n",inpath); - - return (fd); -} - - -static int offset1=0; -static int offset2=0; - -/* FITSRTOPEN -- Open FITS table file and fill structure with - * pointers to selected keywords - * Return file descriptor (-1 if unsuccessful) - */ - -int -fitsrtopen (inpath, nk, kw, nrows, nchar, nbhead) - -char *inpath; /* Pathname for FITS tables file to read */ -int *nk; /* Number of keywords to use */ -struct Keyword **kw; /* Structure for desired entries */ -int *nrows; /* Number of rows in table (returned) */ -int *nchar; /* Number of characters in one table row (returned) */ -int *nbhead; /* Number of characters before table starts */ - -{ - char temp[16]; - int fd; - int lhead; /* Maximum length in bytes of FITS header */ - char *header; /* Header for FITS tables file to read */ - -/* Read FITS header from input file */ - header = fitsrhead (inpath, &lhead, nbhead); - if (!header) { - snprintf (fitserrmsg,79,"FITSRTOPEN: %s is not a FITS file\n",inpath); - return (0); - } - -/* Make sure this file is really a FITS table file */ - temp[0] = 0; - (void) hgets (header,"XTENSION",16,temp); - if (strlen (temp) == 0) { - snprintf (fitserrmsg,79, - "FITSRTOPEN: %s is not a FITS table file\n",inpath); - free ((void *) header); - return (0); - } - -/* If it is a FITS file, get table information from the header */ - else if (!strcmp (temp, "TABLE") || !strcmp (temp, "BINTABLE")) { - if (fitsrthead (header, nk, kw, nrows, nchar)) { - snprintf (fitserrmsg,79, - "FITSRTOPEN: Cannot read FITS table from %s\n",inpath); - free ((void *) header); - return (-1); - } - else { - fd = fitsropen (inpath); - offset1 = 0; - offset2 = 0; - free ((void *) header); - return (fd); - } - } - -/* If it is another FITS extension note it and return */ - else { - snprintf (fitserrmsg,79, - "FITSRTOPEN: %s is a %s extension, not table\n", - inpath, temp); - free ((void *) header); - return (0); - } -} - -static struct Keyword *pw; /* Structure for all entries */ -static int *lpnam; /* length of name for each field */ -static int bfields = 0; - -/* FITSRTHEAD -- From FITS table header, read pointers to selected keywords */ - -int -fitsrthead (header, nk, kw, nrows, nchar) - -char *header; /* Header for FITS tables file to read */ -int *nk; /* Number of keywords to use */ -struct Keyword **kw; /* Structure for desired entries */ -int *nrows; /* Number of rows in table (returned) */ -int *nchar; /* Number of characters in one table row (returned) */ - -{ - struct Keyword *rw; /* Structure for desired entries */ - int nfields; - int ifield, ik, i, ikf, ltform, kl; - char *h0, *h1, *tf1, *tf2; - char tname[12]; - char temp[16]; - char tform[16]; - int tverb; - int bintable = 0; - - h0 = header; - -/* Make sure this is really a FITS table file header */ - temp[0] = 0; - hgets (header,"XTENSION",16,temp); - if (strlen (temp) == 0) { - snprintf (fitserrmsg,79, "FITSRTHEAD: Not a FITS table header\n"); - return (-1); - } - else if (!strcmp (temp, "BINTABLE")) { - bintable = 1; - } - else if (strcmp (temp, "TABLE")) { - snprintf (fitserrmsg,79, "FITSRTHEAD: %s extension, not TABLE\n",temp); - return (-1); - } - -/* Get table size from FITS header */ - *nchar = 0; - hgeti4 (header,"NAXIS1",nchar); - *nrows = 0; - hgeti4 (header,"NAXIS2", nrows); - if (*nrows <= 0 || *nchar <= 0) { - snprintf (fitserrmsg,79, "FITSRTHEAD: cannot read %d x %d table\n", - *nrows,*nchar); - return (-1); - } - -/* Set up table for access to individual fields */ - nfields = 0; - hgeti4 (header,"TFIELDS",&nfields); - if (verbose) - fprintf (stderr, "FITSRTHEAD: %d fields per table entry\n", nfields); - if (nfields > bfields) { - if (bfields > 0) - free ((void *)pw); - pw = (struct Keyword *) calloc (nfields, sizeof(struct Keyword)); - if (pw == NULL) { - snprintf (fitserrmsg,79,"FITSRTHEAD: cannot allocate table structure\n"); - return (-1); - } - if (bfields > 0) - free ((void *)lpnam); - lpnam = (int *) calloc (nfields, sizeof(int)); - if (lpnam == NULL) { - snprintf (fitserrmsg,79,"FITSRTHEAD: cannot allocate length structure\n"); - return (-1); - } - bfields = nfields; - } - - tverb = verbose; - verbose = 0; - ikf = 0; - - for (ifield = 0; ifield < nfields; ifield++) { - - /* Name of field */ - for (i = 0; i < 12; i++) tname[i] = 0; - sprintf (tname, "TTYPE%d", ifield+1);; - temp[0] = 0; - h1 = ksearch (h0,tname); - h0 = h1; - hgets (h0,tname,16,temp); - strcpy (pw[ifield].kname,temp); - pw[ifield].lname = strlen (pw[ifield].kname); - - /* Sequence of field on line */ - pw[ifield].kn = ifield + 1; - - /* First column of field */ - if (bintable) - pw[ifield].kf = ikf; - else { - for (i = 0; i < 12; i++) tname[i] = 0; - sprintf (tname, "TBCOL%d", ifield+1); - pw[ifield].kf = 0; - hgeti4 (h0,tname, &pw[ifield].kf); - } - - /* Length of field */ - for (i = 0; i < 12; i++) tname[i] = 0; - sprintf (tname, "TFORM%d", ifield+1);; - tform[0] = 0; - hgets (h0,tname,16,tform); - strcpy (pw[ifield].kform, tform); - ltform = strlen (tform); - if (tform[ltform-1] == 'A') { - pw[ifield].kform[0] = 'A'; - for (i = 0; i < ltform-1; i++) - pw[ifield].kform[i+1] = tform[i]; - pw[ifield].kform[ltform] = (char) 0; - tf1 = pw[ifield].kform + 1; - kl = atof (tf1); - } - else if (!strcmp (tform,"I")) - kl = 2; - else if (!strcmp (tform, "J")) - kl = 4; - else if (!strcmp (tform, "E")) - kl = 4; - else if (!strcmp (tform, "D")) - kl = 8; - else { - tf1 = tform + 1; - tf2 = strchr (tform,'.'); - if (tf2 != NULL) - *tf2 = ' '; - kl = atoi (tf1); - } - pw[ifield].kl = kl; - ikf = ikf + kl; - } - -/* Set up table for access to desired fields */ - verbose = tverb; - if (verbose) - fprintf (stderr, "FITSRTHEAD: %d keywords read\n", *nk); - -/* If nk = 0, allocate and return structures for all table fields */ - if (*nk <= 0) { - *kw = pw; - *nk = nfields; - return (0); - } - else - rw = *kw; - -/* Find each desired keyword in the header */ - for (ik = 0; ik < *nk; ik++) { - if (rw[ik].kn <= 0) { - for (ifield = 0; ifield < nfields; ifield++) { - if (rw[ik].lname != pw[ifield].lname) - continue; - if (strcmp (pw[ifield].kname, rw[ik].kname) == 0) { - break; - } - } - } - else - ifield = rw[ik].kn - 1; - -/* Set pointer, lentth, and name in returned array of structures */ - rw[ik].kn = ifield + 1; - rw[ik].kf = pw[ifield].kf - 1; - rw[ik].kl = pw[ifield].kl; - strcpy (rw[ik].kform, pw[ifield].kform); - strcpy (rw[ik].kname, pw[ifield].kname); - } - - return (0); -} - - -int -fitsrtline (fd, nbhead, lbuff, tbuff, irow, nbline, line) - -int fd; /* File descriptor for FITS file */ -int nbhead; /* Number of bytes in FITS header */ -int lbuff; /* Number of bytes in table buffer */ -char *tbuff; /* FITS table buffer */ -int irow; /* Number of table row to read */ -int nbline; /* Number of bytes to read for this line */ -char *line; /* One line of FITS table (returned) */ - -{ - int nbuff, nlbuff; - int nbr = 0; - int offset, offend, ntry, ioff; - char *tbuff1; - - offset = nbhead + (nbline * irow); - offend = offset + nbline - 1; - -/* Read a new buffer of the FITS table into memory if needed */ - if (offset < offset1 || offend > offset2) { - nlbuff = lbuff / nbline; - nbuff = nlbuff * nbline; - for (ntry = 0; ntry < 3; ntry++) { - ioff = lseek (fd, offset, SEEK_SET); - if (ioff < offset) { - if (ntry == 2) - return (0); - else - continue; - } - nbr = read (fd, tbuff, nbuff); - if (nbr < nbline) { - if (verbose) - fprintf (stderr, "FITSRTLINE: %d / %d bytes read %d\n", - nbr,nbuff,ntry); - if (ntry == 2) - return (nbr); - } - else - break; - } - offset1 = offset; - offset2 = offset + nbr - 1; - strncpy (line, tbuff, nbline); - return (nbline); - } - else { - tbuff1 = tbuff + (offset - offset1); - strncpy (line, tbuff1, nbline); - return (nbline); - } -} - - -void -fitsrtlset () -{ - offset1 = 0; - offset2 = 0; - return; -} - - -/* FTGETI2 -- Extract n'th column from FITS table line as short */ - -short -ftgeti2 (entry, kw) - -char *entry; /* Row or entry from table */ -struct Keyword *kw; /* Table column information from FITS header */ -{ - char temp[30]; - short i; - int j; - float r; - double d; - - if (ftgetc (entry, kw, temp, 30)) { - if (!strcmp (kw->kform, "I")) - moveb (temp, (char *) &i, 2, 0, 0); - else if (!strcmp (kw->kform, "J")) { - moveb (temp, (char *) &j, 4, 0, 0); - i = (short) j; - } - else if (!strcmp (kw->kform, "E")) { - moveb (temp, (char *) &r, 4, 0, 0); - i = (short) r; - } - else if (!strcmp (kw->kform, "D")) { - moveb (temp, (char *) &d, 8, 0, 0); - i = (short) d; - } - else - i = (short) atof (temp); - return (i); - } - else - return ((short) 0); -} - - -/* FTGETI4 -- Extract n'th column from FITS table line as int */ - -int -ftgeti4 (entry, kw) - -char *entry; /* Row or entry from table */ -struct Keyword *kw; /* Table column information from FITS header */ -{ - char temp[30]; - short i; - int j; - float r; - double d; - - if (ftgetc (entry, kw, temp, 30)) { - if (!strcmp (kw->kform, "I")) { - moveb (temp, (char *) &i, 2, 0, 0); - j = (int) i; - } - else if (!strcmp (kw->kform, "J")) - moveb (temp, (char *) &j, 4, 0, 0); - else if (!strcmp (kw->kform, "E")) { - moveb (temp, (char *) &r, 4, 0, 0); - j = (int) r; - } - else if (!strcmp (kw->kform, "D")) { - moveb (temp, (char *) &d, 8, 0, 0); - j = (int) d; - } - else - j = (int) atof (temp); - return (j); - } - else - return (0); -} - - -/* FTGETR4 -- Extract n'th column from FITS table line as float */ - -float -ftgetr4 (entry, kw) - -char *entry; /* Row or entry from table */ -struct Keyword *kw; /* Table column information from FITS header */ -{ - char temp[30]; - short i; - int j; - float r; - double d; - - if (ftgetc (entry, kw, temp, 30)) { - if (!strcmp (kw->kform, "I")) { - moveb (temp, (char *) &i, 2, 0, 0); - r = (float) i; - } - else if (!strcmp (kw->kform, "J")) { - moveb (temp, (char *) &j, 4, 0, 0); - r = (float) j; - } - else if (!strcmp (kw->kform, "E")) - moveb (temp, (char *) &r, 4, 0, 0); - else if (!strcmp (kw->kform, "D")) { - moveb (temp, (char *) &d, 8, 0, 0); - r = (float) d; - } - else - r = (float) atof (temp); - return (r); - } - else - return ((float) 0.0); -} - - -/* FTGETR8 -- Extract n'th column from FITS table line as double */ - -double -ftgetr8 (entry, kw) - -char *entry; /* Row or entry from table */ -struct Keyword *kw; /* Table column information from FITS header */ -{ - char temp[30]; - short i; - int j; - float r; - double d; - - if (ftgetc (entry, kw, temp, 30)) { - if (!strcmp (kw->kform, "I")) { - moveb (temp, (char *) &i, 2, 0, 0); - d = (double) i; - } - else if (!strcmp (kw->kform, "J")) { - moveb (temp, (char *) &j, 4, 0, 0); - d = (double) j; - } - else if (!strcmp (kw->kform, "E")) { - moveb (temp, (char *) &r, 4, 0, 0); - d = (double) r; - } - else if (!strcmp (kw->kform, "D")) - moveb (temp, (char *) &d, 8, 0, 0); - else - d = atof (temp); - return (d); - } - else - return ((double) 0.0); -} - - -/* FTGETC -- Extract n'th column from FITS table line as character string */ - -int -ftgetc (entry, kw, string, maxchar) - -char *entry; /* Row or entry from table */ -struct Keyword *kw; /* Table column information from FITS header */ -char *string; /* Returned string */ -int maxchar; /* Maximum number of characters in returned string */ -{ - int length = maxchar; - - if (kw->kl < length) - length = kw->kl; - if (length > 0) { - strncpy (string, entry+kw->kf, length); - string[length] = 0; - return ( 1 ); - } - else - return ( 0 ); -} - -extern int errno; - - -/*FITSWIMAGE -- Write FITS header and image */ - -int -fitswimage (filename, header, image) - -char *filename; /* Name of FITS image file */ -char *header; /* FITS image header */ -char *image; /* FITS image pixels */ - -{ - int fd; - - /* Open the output file */ - if (strcasecmp (filename,"stdout") ) { - - if (!access (filename, 0)) { - fd = open (filename, O_WRONLY); - if (fd < 3) { - snprintf (fitserrmsg,79, "FITSWIMAGE: file %s not writeable\n", filename); - return (0); - } - } - else { - fd = open (filename, O_RDWR+O_CREAT, 0666); - if (fd < 3) { - snprintf (fitserrmsg,79, "FITSWIMAGE: cannot create file %s\n", filename); - return (0); - } - } - } -#ifndef VMS - else - fd = STDOUT_FILENO; -#endif - - return (fitswhdu (fd, filename, header, image)); -} - - -/*FITSWEXT -- Write FITS header and image as extension to a file */ - -int -fitswext (filename, header, image) - -char *filename; /* Name of IFTS image file */ -char *header; /* FITS image header */ -char *image; /* FITS image pixels */ - -{ - int fd; - - /* Open the output file */ - if (strcasecmp (filename,"stdout") ) { - - if (!access (filename, 0)) { - fd = open (filename, O_WRONLY); - if (fd < 3) { - snprintf (fitserrmsg,79, "FITSWEXT: file %s not writeable\n", - filename); - return (0); - } - } - else { - fd = open (filename, O_APPEND, 0666); - if (fd < 3) { - snprintf (fitserrmsg,79, "FITSWEXT: cannot append to file %s\n", - filename); - return (0); - } - } - } -#ifndef VMS - else - fd = STDOUT_FILENO; -#endif - - return (fitswhdu (fd, filename, header, image)); -} - - -/* FITSWHDU -- Write FITS head and image as extension */ - -int -fitswhdu (fd, filename, header, image) - -int fd; /* File descriptor */ -char *filename; /* Name of IFTS image file */ -char *header; /* FITS image header */ -char *image; /* FITS image pixels */ -{ - int nbhead, nbimage, nblocks, bytepix, i, nbhw; - int bitpix, naxis, iaxis, naxisi, nbytes, nbw, nbpad, nbwp, simple; - char *endhead, *padding; - double bzero, bscale; - char keyword[32]; - - /* Change BITPIX=-16 files to BITPIX=16 with BZERO and BSCALE */ - bitpix = 0; - hgeti4 (header,"BITPIX",&bitpix); - if (bitpix == -16) { - if (!hgetr8 (header, "BZERO", &bzero) && - !hgetr8 (header, "BSCALE", &bscale)) { - bitpix = 16; - hputi4 (header, "BITPIX", bitpix); - hputr8 (header, "BZERO", 32768.0); - hputr8 (header, "BSCALE", 1.0); - } - } - - /* Write header to file */ - endhead = ksearch (header,"END") + 80; - nbhead = endhead - header; - nbhw = write (fd, header, nbhead); - if (nbhw < nbhead) { - snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of header to file %s\n", - nbhw, nbhead, filename); - (void)close (fd); - return (0); - } - - /* Write extra spaces to make an integral number of 2880-byte blocks */ - nblocks = nbhead / FITSBLOCK; - if (nblocks * FITSBLOCK < nbhead) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - nbpad = nbytes - nbhead; - padding = (char *)calloc (1, nbpad); - for (i = 0; i < nbpad; i++) - padding[i] = ' '; - nbwp = write (fd, padding, nbpad); - if (nbwp < nbpad) { - snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of header padding to file %s\n", - nbwp, nbpad, filename); - (void)close (fd); - return (0); - } - nbhw = nbhw + nbwp; - free (padding); - - /* Return if file has no data */ - if (bitpix == 0 || image == NULL) { - /* snprintf (fitserrmsg,79, "FITSWHDU: BITPIX is 0; image not written\n"); */ - (void)close (fd); - return (0); - } - - /* If SIMPLE=F in header, just write whatever is in the buffer */ - hgetl (header, "SIMPLE", &simple); - if (!simple) { - hgeti4 (header, "NBDATA", &nbytes); - nbimage = nbytes; - } - - else { - - /* Compute size of pixel in bytes */ - bytepix = bitpix / 8; - if (bytepix < 0) bytepix = -bytepix; - nbimage = bytepix; - - /* Compute size of image in bytes using relevant header parameters */ - naxis = 1; - hgeti4 (header,"NAXIS",&naxis); - for (iaxis = 1; iaxis <= naxis; iaxis++) { - sprintf (keyword, "NAXIS%d", iaxis); - naxisi = 1; - hgeti4 (header,keyword,&naxisi); - nbimage = nbimage * naxisi; - } - - /* Number of bytes to write is an integral number of FITS blocks */ - nblocks = nbimage / FITSBLOCK; - if (nblocks * FITSBLOCK < nbimage) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Byte-reverse image before writing, if necessary */ - if (imswapped ()) - imswap (bitpix, image, nbimage); - } - - /* Write image to file */ - nbw = write (fd, image, nbimage); - if (nbw < nbimage) { - snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of image to file %s\n", - nbw, nbimage, filename); - return (0); - } - - /* Write extra zeroes to make an integral number of 2880-byte blocks */ - nbpad = nbytes - nbimage; - if (nbpad > 0) { - padding = (char *)calloc (1, nbpad); - nbwp = write (fd, padding, nbpad); - if (nbwp < nbpad) { - snprintf (fitserrmsg,79, "FITSWHDU: wrote %d / %d bytes of image padding to file %s\n", - nbwp, nbpad, filename); - (void)close (fd); - return (0); - } - free (padding); - } - else - nbwp = 0; - - (void)close (fd); - - /* Byte-reverse image after writing, if necessary */ - if (imswapped ()) - imswap (bitpix, image, nbimage); - - nbw = nbw + nbwp + nbhw; - return (nbw); -} - - -/*FITSCIMAGE -- Write FITS header and copy FITS image - Return number of bytes in output image, 0 if failure */ - -int -fitscimage (filename, header, filename0) - -char *filename; /* Name of output FITS image file */ -char *header; /* FITS image header */ -char *filename0; /* Name of input FITS image file */ - -{ - int fdout, fdin; - int nbhead, nbimage, nblocks, bytepix; - int bitpix, naxis, naxis1, naxis2, nbytes, nbw, nbpad, nbwp; - char *endhead, *lasthead, *padding; - char *image; /* FITS image pixels */ - char *oldhead; /* Input file image header */ - int nbhead0; /* Length of input file image header */ - int lhead0; - int nbbuff, nbuff, ibuff, nbr, nbdata; - - /* Compute size of image in bytes using relevant header parameters */ - naxis = 1; - hgeti4 (header, "NAXIS", &naxis); - naxis1 = 1; - hgeti4 (header, "NAXIS1", &naxis1); - naxis2 = 1; - hgeti4 (header, "NAXIS2", &naxis2); - hgeti4 (header, "BITPIX", &bitpix); - bytepix = bitpix / 8; - if (bytepix < 0) bytepix = -bytepix; - - /* If either dimension is one and image is 3-D, read all three dimensions */ - if (naxis == 3 && (naxis1 ==1 || naxis2 == 1)) { - int naxis3; - hgeti4 (header,"NAXIS3",&naxis3); - nbimage = naxis1 * naxis2 * naxis3 * bytepix; - } - else - nbimage = naxis1 * naxis2 * bytepix; - - nblocks = nbimage / FITSBLOCK; - if (nblocks * FITSBLOCK < nbimage) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Allocate image buffer */ - nbbuff = FITSBLOCK * 100; - if (nbytes < nbbuff) - nbbuff = nbytes; - image = (char *) calloc (1, nbbuff); - nbuff = nbytes / nbbuff; - if (nbytes > nbuff * nbbuff) - nbuff = nbuff + 1; - - /* Read input file header */ - if ((oldhead = fitsrhead (filename0, &lhead0, &nbhead0)) == NULL) { - snprintf (fitserrmsg, 79,"FITSCIMAGE: header of input file %s cannot be read\n", - filename0); - return (0); - } - - /* Find size of output header */ - nbhead = fitsheadsize (header); - - /* If overwriting, be more careful if new header is longer than old */ - if (!strcmp (filename, filename0) && nbhead > nbhead0) { - if ((image = fitsrimage (filename0, nbhead0, oldhead)) == NULL) { - snprintf (fitserrmsg,79, "FITSCIMAGE: cannot read image from file %s\n", - filename0); - free (oldhead); - return (0); - } - return (fitswimage (filename, header, image)); - } - free (oldhead); - - /* Open the input file and skip over the header */ - if (strcasecmp (filename0,"stdin")) { - fdin = -1; - fdin = fitsropen (filename0); - if (fdin < 0) { - snprintf (fitserrmsg, 79,"FITSCIMAGE: cannot read file %s\n", filename0); - return (0); - } - - /* Skip over FITS header */ - if (lseek (fdin, nbhead0, SEEK_SET) < 0) { - (void)close (fdin); - snprintf (fitserrmsg,79, "FITSCIMAGE: cannot skip header of file %s\n", - filename0); - return (0); - } - } -#ifndef VMS - else - fdin = STDIN_FILENO; -#endif - - /* Open the output file */ - if (!access (filename, 0)) { - fdout = open (filename, O_WRONLY); - if (fdout < 3) { - snprintf (fitserrmsg,79, "FITSCIMAGE: file %s not writeable\n", filename); - return (0); - } - } - else { - fdout = open (filename, O_RDWR+O_CREAT, 0666); - if (fdout < 3) { - snprintf (fitserrmsg,79, "FITSCHEAD: cannot create file %s\n", filename); - return (0); - } - } - - /* Pad header with spaces */ - endhead = ksearch (header,"END") + 80; - lasthead = header + nbhead; - while (endhead < lasthead) - *(endhead++) = ' '; - - /* Write header to file */ - nbw = write (fdout, header, nbhead); - if (nbw < nbhead) { - snprintf (fitserrmsg, 79,"FITSCIMAGE: wrote %d / %d bytes of header to file %s\n", - nbw, nbytes, filename); - (void)close (fdout); - (void)close (fdin); - return (0); - } - - /* Return if no data */ - if (bitpix == 0) { - (void)close (fdout); - (void)close (fdin); - return (nbhead); - } - - nbdata = 0; - for (ibuff = 0; ibuff < nbuff; ibuff++) { - nbr = read (fdin, image, nbbuff); - if (nbr > 0) { - nbw = write (fdout, image, nbr); - nbdata = nbdata + nbw; - } - } - - /* Write extra to make integral number of 2880-byte blocks */ - nblocks = nbdata / FITSBLOCK; - if (nblocks * FITSBLOCK < nbdata) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - nbpad = nbytes - nbdata; - padding = (char *)calloc (1,nbpad); - nbwp = write (fdout, padding, nbpad); - nbw = nbdata + nbwp; - free (padding); - - (void)close (fdout); - (void)close (fdin); - - if (nbw < nbimage) { - snprintf (fitserrmsg, 79, "FITSWIMAGE: wrote %d / %d bytes of image to file %s\n", - nbw, nbimage, filename); - return (0); - } - else - return (nbw); -} - - -/* FITSWHEAD -- Write FITS header and keep file open for further writing */ - -int -fitswhead (filename, header) - -char *filename; /* Name of IFTS image file */ -char *header; /* FITS image header */ - -{ - int fd; - int nbhead, nblocks; - int nbytes, nbw; - char *endhead, *lasthead; - - /* Open the output file */ - if (!access (filename, 0)) { - fd = open (filename, O_WRONLY); - if (fd < 3) { - snprintf (fitserrmsg, 79, "FITSWHEAD: file %s not writeable\n", filename); - return (0); - } - } - else { - fd = open (filename, O_RDWR+O_CREAT, 0666); - if (fd < 3) { - snprintf (fitserrmsg, 79, "FITSWHEAD: cannot create file %s\n", filename); - return (0); - } - } - - /* Write header to file */ - endhead = ksearch (header,"END") + 80; - nbhead = endhead - header; - nblocks = nbhead / FITSBLOCK; - if (nblocks * FITSBLOCK < nbhead) - nblocks = nblocks + 1; - nbytes = nblocks * FITSBLOCK; - - /* Pad header with spaces */ - lasthead = header + nbytes; - while (endhead < lasthead) - *(endhead++) = ' '; - - nbw = write (fd, header, nbytes); - if (nbw < nbytes) { - fprintf (stderr, "FITSWHEAD: wrote %d / %d bytes of header to file %s\n", - nbw, nbytes, filename); - (void)close (fd); - return (0); - } - return (fd); -} - - -/* FITSWEXHEAD -- Write FITS header in place */ - -int -fitswexhead (filename, header) - -char *filename; /* Name of FITS image file with ,extension */ -char *header; /* FITS image header */ - -{ - int fd; - int nbhead, lhead; - int nbw, nbnew, nbold; - char *endhead, *lasthead, *oldheader; - char *ext, cext; - - /* Compare size of existing header to size of new header */ - fitsinherit = 0; - oldheader = fitsrhead (filename, &lhead, &nbhead); - if (oldheader == NULL) { - snprintf (fitserrmsg, 79, "FITSWEXHEAD: file %s cannot be read\n", filename); - return (-1); - } - nbold = fitsheadsize (oldheader); - nbnew = fitsheadsize (header); - - /* Return if the new header is bigger than the old header */ - if (nbnew > nbold) { - snprintf (fitserrmsg, 79, "FITSWEXHEAD: old header %d bytes, new header %d bytes\n", nbold,nbnew); - free (oldheader); - oldheader = NULL; - return (-1); - } - - /* Add blank lines if new header is smaller than the old header */ - else if (nbnew < nbold) { - strcpy (oldheader, header); - endhead = ksearch (oldheader,"END"); - lasthead = oldheader + nbold; - while (endhead < lasthead) - *(endhead++) = ' '; - strncpy (lasthead-80, "END", 3); - } - - /* Pad header with spaces */ - else { - endhead = ksearch (header,"END") + 80; - lasthead = header + nbnew; - while (endhead < lasthead) - *(endhead++) = ' '; - strncpy (oldheader, header, nbnew); - } - - /* Check for FITS extension and ignore for file opening */ - ext = strchr (filename, ','); - if (ext == NULL) - ext = strchr (filename, '['); - if (ext != NULL) { - cext = *ext; - *ext = (char) 0; - } - - /* Open the output file */ - fd = open (filename, O_WRONLY); - if (ext != NULL) - *ext = cext; - if (fd < 3) { - snprintf (fitserrmsg, 79, "FITSWEXHEAD: file %s not writeable\n", filename); - return (-1); - } - - /* Skip to appropriate place in file */ - (void) lseek (fd, ibhead, SEEK_SET); - - /* Write header to file */ - nbw = write (fd, oldheader, nbold); - (void)close (fd); - free (oldheader); - oldheader = NULL; - if (nbw < nbold) { - fprintf (stderr, "FITSWHEAD: wrote %d / %d bytes of header to file %s\n", - nbw, nbold, filename); - return (-1); - } - return (0); -} - - -/* ISFITS -- Return 1 if FITS file, else 0 */ -int -isfits (filename) - -char *filename; /* Name of file for which to find size */ -{ - int diskfile; - char keyword[16]; - char *comma; - int nbr; - - /* First check to see if this is an assignment */ - if (strchr (filename, '=')) - return (0); - - /* Check for stdin (input from pipe) */ - else if (!strcasecmp (filename,"stdin")) - return (1); - - /* Then check file extension - else if (strsrch (filename, ".fit") || - strsrch (filename, ".fits") || - strsrch (filename, ".fts")) - return (1); */ - - /* If no FITS file extension, try opening the file */ - else { - if ((comma = strchr (filename,','))) - *comma = (char) 0; - if ((diskfile = open (filename, O_RDONLY)) < 0) { - if (comma) - *comma = ','; - return (0); - } - else { - nbr = read (diskfile, keyword, 8); - if (comma) - *comma = ','; - close (diskfile); - if (nbr < 8) - return (0); - else if (!strncmp (keyword, "SIMPLE", 6)) - return (1); - else - return (0); - } - } -} - - -/* FITSHEADSIZE -- Find size of FITS header */ - -int -fitsheadsize (header) - -char *header; /* FITS header */ -{ - char *endhead; - int nbhead, nblocks; - - endhead = ksearch (header,"END") + 80; - nbhead = endhead - header; - nblocks = nbhead / FITSBLOCK; - if (nblocks * FITSBLOCK < nbhead) - nblocks = nblocks + 1; - return (nblocks * FITSBLOCK); -} - - -/* Print error message */ -void -fitserr () -{ fprintf (stderr, "%s\n",fitserrmsg); - return; } - - -/* MOVEB -- Copy nbytes bytes from source+offs to dest+offd (any data type) */ - -void -moveb (source, dest, nbytes, offs, offd) - -char *source; /* Pointer to source */ -char *dest; /* Pointer to destination */ -int nbytes; /* Number of bytes to move */ -int offs; /* Offset in bytes in source from which to start copying */ -int offd; /* Offset in bytes in destination to which to start copying */ -{ -char *from, *last, *to; - from = source + offs; - to = dest + offd; - last = from + nbytes; - while (from < last) *(to++) = *(from++); - return; -} - -/* - * Feb 8 1996 New subroutines - * Apr 10 1996 Add subroutine list at start of file - * Apr 17 1996 Print error message to stderr - * May 2 1996 Write using stream IO - * May 14 1996 If FITSRTOPEN NK is zero, return all keywords in header - * May 17 1996 Make header internal to FITSRTOPEN - * Jun 3 1996 Use stream I/O for input as well as output - * Jun 10 1996 Remove unused variables after running lint - * Jun 12 1996 Deal with byte-swapped images - * Jul 11 1996 Rewrite code to separate header and data reading - * Aug 6 1996 Fixed small defects after lint - * Aug 6 1996 Drop unused NBHEAD argument from FITSRTHEAD - * Aug 13 1996 If filename is stdin, read from standard input instead of file - * Aug 30 1996 Use write for output, not fwrite - * Sep 4 1996 Fix mode when file is created - * Oct 15 1996 Drop column argument from FGET* subroutines - * Oct 15 1996 Drop unused variable - * Dec 17 1996 Add option to skip bytes in file before reading the header - * Dec 27 1996 Turn nonprinting header characters into spaces - * - * Oct 9 1997 Add FITS extension support as filename,extension - * Dec 15 1997 Fix minor bugs after lint - * - * Feb 23 1998 Do not append primary header if getting header for ext. 0 - * Feb 23 1998 Accept either bracketed or comma extension - * Feb 24 1998 Add SIMPLE keyword to start of extracted extension - * Apr 30 1998 Fix error return if not table file after Allan Brighton - * May 4 1998 Fix error in argument sequence in HGETS call - * May 27 1998 Include fitsio.h and imio.h - * Jun 1 1998 Add VMS fixes from Harry Payne at STScI - * Jun 3 1998 Fix bug reading EXTNAME - * Jun 11 1998 Initialize all header parameters before reading them - * Jul 13 1998 Clarify argument definitions - * Aug 6 1998 Rename fitsio.c to fitsfile.c to avoid conflict with CFITSIO - * Aug 13 1998 Add FITSWHEAD to write only header - * Sep 25 1998 Allow STDIN or stdin for standard input reading - * Oct 5 1998 Add isfits() to decide whether a file is FITS - * Oct 9 1998 Assume stdin and STDIN to be FITS files in isfits() - * Nov 30 1998 Fix bug found by Andreas Wicenec when reading large headers - * Dec 8 1998 Fix bug introduced by previous bug fix - * - * Jan 4 1999 Do not print error message if BITPIX is 0 - * Jan 27 1999 Read and write all of 3D images if one dimension is 1 - * Jan 27 1999 Pad out data to integral number of 2880-byte blocks - * Apr 29 1999 Write BITPIX=-16 files as BITPIX=16 with BSCALE and BZERO - * Apr 30 1999 Add % as alternative to , to denote sub-images - * May 25 1999 Set buffer offsets to 0 when FITS table file is opened - * Jul 14 1999 Do not try to write image data if BITPIX is 0 - * Sep 27 1999 Add STDOUT as output filename option in fitswimage() - * Oct 6 1999 Set header length global variable hget.lhead0 in fitsrhead() - * Oct 14 1999 Update header length as it is changed in fitsrhead() - * Oct 20 1999 Change | in if statements to || - * Oct 25 1999 Change most malloc() calls to calloc() - * Nov 24 1999 Add fitscimage() - * - * Feb 23 2000 Fix problem with some error returns in fitscimage() - * Mar 17 2000 Drop unused variables after lint - * Jul 20 2000 Drop BITPIX and NAXIS from primary header if extension printerd - * Jul 20 2000 Start primary part of header with ROOTHEAD keyword - * Jul 28 2000 Add loop to deal with buffered stdin - * - * Jan 11 2001 Print all messages to stderr - * Jan 12 2001 Add extension back onto filename after fitsropen() (Guy Rixon) - * Jan 18 2001 Drop EXTEND keyword when extracting an extension - * Jan 18 2001 Add fitswext() to append HDU and fitswhdu() to do actual writing - * Jan 22 2001 Ignore WCS name or letter following a : in file name in fitsrhead() - * Jan 30 2001 Fix FITSCIMAGE so it doesn't overwrite data when overwriting a file - * Feb 20 2001 Ignore WCS name or letter following a : in file name in fitsropen() - * Feb 23 2001 Initialize rbrac in fitsropen() - * Mar 8 2001 Use % instead of : for WCS specification in file name - * Mar 9 2001 Fix bug so primary header is always appended to secondary header - * Mar 9 2001 Change NEXTEND to NUMEXT in appended primary header - * Mar 20 2001 Declare fitsheadsize() in fitschead() - * Apr 24 2001 When matching column names, use longest length - * Jun 27 2001 In fitsrthead(), allocate pw and lpnam only if more space needed - * Aug 24 2001 In isfits(), return 0 if argument contains an equal sign - * - * Jan 28 2002 In fitsrhead(), allow stdin to include extension and/or WCS selection - * Jun 18 2002 Save error messages as fitserrmsg and use fitserr() to print them - * Oct 21 2002 Add fitsrsect() to read a section of an image - * - * Feb 4 2003 Open catalog file rb instead of r (Martin Ploner, Bern) - * Apr 2 2003 Drop unused variable in fitsrsect() - * Jul 11 2003 Use strcasecmp() to check for stdout and stdin - * Aug 1 2003 If no other header, return root header from fitsrhead() - * Aug 20 2003 Add fitsrfull() to read n-dimensional FITS images - * Aug 21 2003 Modify fitswimage() to always write n-dimensional FITS images - * Nov 18 2003 Fix minor bug in fitswhdu() - * Dec 3 2003 Remove unused variable lasthead in fitswhdu() - * - * May 3 2004 Do not always append primary header to extension header - * May 3 2004 Add ibhead as position of header read in file - * May 19 2004 Do not reset ext if NULL in fitswexhead() - * Jul 1 2004 Initialize INHERIT to 1 - * Aug 30 2004 Move fitsheadsize() declaration to fitsfile.h - * Aug 31 2004 If SIMPLE=F, put whatever is in file after header in image - * - * Mar 17 2005 Use unbuffered I/O in isfits() for robustness - * Jun 27 2005 Drop unused variable nblocks in fitswexhead() - * Aug 8 2005 Fix space-padding bug in fitswexhead() found by Armin Rest - * Sep 30 2005 Fix fitsrsect() to position relatively, not absolutely - * Oct 28 2005 Add error message if desired FITS extension is not found - * Oct 28 2005 Fix initialization problem found by Sergey Koposov - * - * Feb 23 2006 Add fitsrtail() to read appended FITS headers - * Feb 27 2006 Add file name to header-reading error messages - * May 3 2006 Remove declarations of unused variables - * Jun 20 2006 Initialize uninitialized variables - * Nov 2 2006 Change all realloc() calls to calloc() - * - * Jan 5 2007 In fitsrtail(), change control characters in header to spaces - * Apr 30 2007 Improve error reporting in FITSRFULL - * Nov 28 2007 Add support to BINTABLE in ftget*() and fitsrthead() - * Dec 20 2007 Add data heap numerated by PCOUNT when skipping HDU in fitsrhead() - * Dec 20 2007 Return NULL pointer if fitsrhead() cannot find requested HDU - * - * Apr 7 2008 Drop comma from name when reading file in isfits() - * Jun 27 2008 Do not append primary data header if it is the only header - * Nov 21 2008 In fitswhead(), print message if too few bytes written - * - * Sep 18 2009 In fitswexhead() write to error string instead of stderr - * Sep 22 2009 In fitsrthead(), fix lengths for ASCII numeric table entries - * Sep 25 2009 Add subroutine moveb() and fix calls to it - * Sep 25 2009 Fix several small errors found by Jessicalas Burke - * - * Mar 29 2010 In fitswhead(), always pad blocks to 2880 bytes with spaces - * Mar 31 2010 In fitsrhead(), fix bug reading long primary headers - * - * Sep 15 2011 In fitsrsect() declare impos and nblin off_t - * Sep 15 2011 In fitsrtail() declare offset off_t - * Sep 15 2011 Declare global variable ibhead off_t - */ |