/*** File imhfile.c
*** November 3, 2003
*** By Doug Mink, dmink@cfa.harvard.edu
*** Harvard-Smithsonian Center for Astrophysics
*** Copyright (C) 1996-2003
*** 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: dmink@cfa.harvard.edu
Postal address: Doug Mink
Smithsonian Astrophysical Observatory
60 Garden St.
Cambridge, MA 02138 USA
* Module: imhfile.c (IRAF .imh image file reading and writing)
* Purpose: Read and write IRAF image files (and translate headers)
* Subroutine: check_immagic (irafheader, teststring )
* Verify that file is valid IRAF imhdr or impix
* Subroutine: irafrhead (filename, lfhead, fitsheader, lihead)
* Read IRAF image header
* Subroutine: irafrimage (fitsheader)
* Read IRAF image pixels (call after irafrhead)
* Subroutine: same_path (pixname, hdrname)
* Put filename and header path together
* Subroutine: iraf2fits (hdrname, irafheader, nbiraf, nbfits)
* Convert IRAF image header to FITS image header
* Subroutine: irafwhead (hdrname, irafheader, fitsheader)
* Write IRAF header file
* Subroutine: irafwimage (hdrname, irafheader, fitsheader, image )
* Write IRAF image and header files
* Subroutine: fits2iraf (fitsheader, irafheader)
* Convert FITS image header to IRAF image header
* Subroutine: irafgeti4 (irafheader, offset)
* Get 4-byte integer from arbitrary part of IRAF header
* Subroutine: irafgetc2 (irafheader, offset)
* Get character string from arbitrary part of IRAF v.1 header
* Subroutine: irafgetc (irafheader, offset)
* Get character string from arbitrary part of IRAF header
* Subroutine: iraf2str (irafstring, nchar)
* Convert 2-byte/char IRAF string to 1-byte/char string
* Subroutine: str2iraf (string, irafstring, nchar)
* Convert 1-byte/char string to IRAF 2-byte/char string
* Subroutine: irafswap (bitpix,string,nbytes)
* Swap bytes in string in place, with FITS bits/pixel code
* Subroutine: irafswap2 (string,nbytes)
* Swap bytes in string in place
* Subroutine irafswap4 (string,nbytes)
* Reverse bytes of Integer*4 or Real*4 vector in place
* Subroutine irafswap8 (string,nbytes)
* Reverse bytes of Real*8 vector in place
* Subroutine irafsize (filename)
* Return length of file in bytes
* Subroutine isiraf (filename)
* Return 1 if IRAF .imh file, else 0
* Copyright: 2000 Smithsonian Astrophysical Observatory
* You may do anything you like with this file except remove
* this copyright. The Smithsonian Astrophysical Observatory
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#include <stdio.h> /* define stderr, FD, and NULL */
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include "fitsfile.h"
/* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */
#define SZ_IMPIXFILE 79 /* name of pixel storage file */
#define SZ_IMHDRFILE 79 /* length of header storage file */
#define SZ_IMTITLE 79 /* image title string */
#define LEN_IMHDR 2052 /* length of std header */
/* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */
#define SZ_IM2PIXFILE 255 /* name of pixel storage file */
#define SZ_IM2HDRFILE 255 /* name of header storage file */
#define SZ_IM2TITLE 383 /* image title string */
#define LEN_IM2HDR 2046 /* length of std header */
/* Offsets into header in bytes for parameters in IRAF version 1 images */
#define IM_HDRLEN 12 /* Length of header in 4-byte ints */
#define IM_PIXTYPE 16 /* Datatype of the pixels */
#define IM_NDIM 20 /* Number of dimensions */
#define IM_LEN 24 /* Length (as stored) */
#define IM_PHYSLEN 52 /* Physical length (as stored) */
#define IM_PIXOFF 88 /* Offset of the pixels */
#define IM_CTIME 108 /* Time of image creation */
#define IM_MTIME 112 /* Time of last modification */
#define IM_LIMTIME 116 /* Time of min,max computation */
#define IM_MAX 120 /* Maximum pixel value */
#define IM_MIN 124 /* Maximum pixel value */
#define IM_PIXFILE 412 /* Name of pixel storage file */
#define IM_HDRFILE 572 /* Name of header storage file */
#define IM_TITLE 732 /* Image name string */
/* Offsets into header in bytes for parameters in IRAF version 2 images */
#define IM2_HDRLEN 6 /* Length of header in 4-byte ints */
#define IM2_PIXTYPE 10 /* Datatype of the pixels */
#define IM2_SWAPPED 14 /* Pixels are byte swapped */
#define IM2_NDIM 18 /* Number of dimensions */
#define IM2_LEN 22 /* Length (as stored) */
#define IM2_PHYSLEN 50 /* Physical length (as stored) */
#define IM2_PIXOFF 86 /* Offset of the pixels */
#define IM2_CTIME 106 /* Time of image creation */
#define IM2_MTIME 110 /* Time of last modification */
#define IM2_LIMTIME 114 /* Time of min,max computation */
#define IM2_MAX 118 /* Maximum pixel value */
#define IM2_MIN 122 /* Maximum pixel value */
#define IM2_PIXFILE 126 /* Name of pixel storage file */
#define IM2_HDRFILE 382 /* Name of header storage file */
#define IM2_TITLE 638 /* Image name string */
/* Codes from iraf/unix/hlib/iraf.h */
#define TY_CHAR 2
#define TY_SHORT 3
#define TY_INT 4
#define TY_LONG 5
#define TY_REAL 6
#define TY_DOUBLE 7
#define TY_COMPLEX 8
#define TY_POINTER 9
#define TY_STRUCT 10
#define TY_USHORT 11
#define TY_UBYTE 12
#define LEN_IRAFHDR 25000
#define LEN_PIXHDR 1024
#define LEN_FITSHDR 11520
int check_immagic();
int irafgeti4();
float irafgetr4();
char *irafgetc2();
char *irafgetc();
char *iraf2str();
static char *same_path();
static void irafputr4();
static void irafputi4();
static void irafputc2();
static void irafputc();
static void str2iraf();
static int headswap=-1; /* =1 to swap data bytes of foreign IRAF file */
static void irafswap();
static void irafswap2();
static void irafswap4();
static void irafswap8();
int head_version ();
int pix_version ();
int irafncmp ();
static int machswap();
static int irafsize();
#define SECONDS_1970_TO_1980 315532800L
/* Subroutine: irafrhead
* Purpose: Open and read the iraf .imh file, translating it to FITS, too.
* Returns: NULL if failure, else pointer to IRAF .imh image header
* Notes: The imhdr format is defined in iraf/lib/imhdr.h, some of
* which defines or mimicked, above.
*/
char *
irafrhead (filename, lihead)
char *filename; /* Name of IRAF header file */
int *lihead; /* Length of IRAF image header in bytes (returned) */
{
FILE *fd;
int nbr;
char *irafheader;
int nbhead, nbytes;
int imhver;
headswap = -1;
*lihead = 0;
/* open the image header file */
fd = fopen (filename, "rb");
if (fd == NULL) {
fprintf (stderr, "IRAFRHEAD: cannot open file %s to read\n", filename);
return (NULL);
}
/* Find size of image header file */
if ((nbhead = irafsize (fd)) <= 0) {
fprintf (stderr, "IRAFRHEAD: cannot read file %s, size = %d\n",
filename, nbhead);
return (NULL);
}
/* allocate initial sized buffer */
nbytes = nbhead + 5000;
irafheader = (char *) calloc (1, nbytes);
if (irafheader == NULL) {
(void)fprintf(stderr, "IRAFRHEAD Cannot allocate %d-byte header\n",
nbytes);
return (NULL);
}
*lihead = nbytes;
/* Read IRAF header */
nbr = fread (irafheader, 1, nbhead, fd);
fclose (fd);
/* Reject if header less than minimum length */
if (nbr < LEN_PIXHDR) {
(void)fprintf(stderr, "IRAFRHEAD header file %s: %d / %d bytes read.\n",
filename,nbr,LEN_PIXHDR);
free (irafheader);
return (NULL);
}
/* Check header magic word */
imhver = head_version (irafheader);
if (imhver < 1) {
free (irafheader);
(void)fprintf(stderr, "IRAFRHEAD: %s is not a valid IRAF image header\n",
filename);
return(NULL);
}
/* check number of image dimensions
if (imhver == 2)
ndim = irafgeti4 (irafheader, IM2_NDIM])
else
ndim = irafgeti4 (irafheader, IM_NDIM])
if (ndim < 2) {
free (irafheader);
(void)fprintf(stderr, "File %s does not contain 2d image\n", filename);
return (NULL);
} */
return (irafheader);
}
char *
irafrimage (fitsheader)
char *fitsheader; /* FITS image header (filled) */
{
FILE *fd;
char *bang;
int naxis, naxis1, naxis2, naxis3, npaxis1, npaxis2,bitpix, bytepix, pixswap, i;
char *image;
int nbr, nbimage, nbaxis, nbl, nbx, nbdiff;
char *pixheader;
char *linebuff;
int imhver, lpixhead, len;
char pixname[SZ_IM2PIXFILE+1];
char newpixname[SZ_IM2HDRFILE+1];
/* Convert pixel file name to character string */
hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname);
hgeti4 (fitsheader, "PIXOFF", &lpixhead);
/* Open pixel file, ignoring machine name if present */
if ((bang = strchr (pixname, '!')) != NULL )
fd = fopen (bang + 1, "rb");
else
fd = fopen (pixname, "rb");
/* If not at pathname in header, try same directory as header file */
if (!fd) {
hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, newpixname);
len = strlen (newpixname);
newpixname[len-3] = 'p';
newpixname[len-2] = 'i';
newpixname[len-1] = 'x';
fd = fopen (newpixname, "rb");
}
/* Print error message and exit if pixel file is not found */
if (!fd) {
(void)fprintf(stderr,
"IRAFRIMAGE: Cannot open IRAF pixel file %s\n", pixname);
return (NULL);
}
/* Read pixel header */
pixheader = (char *) calloc (lpixhead, 1);
if (pixheader == NULL) {
(void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte pixel header\n",
lpixhead);
return (NULL);
}
nbr = fread (pixheader, 1, lpixhead, fd);
/* Check size of pixel header */
if (nbr < lpixhead) {
(void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n",
pixname,nbr,LEN_PIXHDR);
free (pixheader);
fclose (fd);
return (NULL);
}
/* check pixel header magic word */
imhver = pix_version (pixheader);
if (imhver < 1) {
(void)fprintf(stderr, "File %s not valid IRAF pixel file.\n", pixname);
free (pixheader);
fclose (fd);
return(NULL);
}
free (pixheader);
/* Find number of bytes to read */
hgeti4 (fitsheader,"NAXIS",&naxis);
hgeti4 (fitsheader,"NAXIS1",&naxis1);
hgeti4 (fitsheader,"NAXIS2",&naxis2);
hgeti4 (fitsheader,"NPAXIS1",&npaxis1);
hgeti4 (fitsheader,"NPAXIS2",&npaxis2);
hgeti4 (fitsheader,"BITPIX",&bitpix);
if (bitpix < 0)
bytepix = -bitpix / 8;
else
bytepix = bitpix / 8;
/* If either dimension is one and image is 3-D, read all three dimensions */
if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) {
hgeti4 (fitsheader,"NAXIS3",&naxis3);
nbimage = naxis1 * naxis2 * naxis3 * bytepix;
}
else {
nbimage = naxis1 * naxis2 * bytepix;
naxis3 = 1;
}
image = (char *) calloc (nbimage, 1);
if (image == NULL) {
(void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte image buffer\n",
nbimage);
return (NULL);
}
/* Read IRAF image all at once if physical and image dimensions are the same */
if (npaxis1 == naxis1)
nbr = fread (image, 1, nbimage, fd);
/* Read IRAF image one line at a time if physical and image dimensions differ */
else {
nbdiff = (npaxis1 - naxis1) * bytepix;
nbaxis = naxis1 * bytepix;
linebuff = image;
nbr = 0;
if (naxis2 == 1 && naxis3 > 1)
naxis2 = naxis3;
for (i = 0; i < naxis2; i++) {
nbl = fread (linebuff, 1, nbaxis, fd);
nbr = nbr + nbl;
nbx = fseek (fd, nbdiff, SEEK_CUR);
linebuff = linebuff + nbaxis;
}
}
fclose (fd);
/* Check size of image */
if (nbr < nbimage) {
(void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n",
pixname,nbr,nbimage);
free (image);
return (NULL);
}
/* Byte-reverse image, if necessary */
pixswap = 0;
hgetl (fitsheader, "PIXSWAP", &pixswap);
if (pixswap)
irafswap (bitpix, image, nbimage);
return (image);
}
/* Return IRAF image format version number from magic word in IRAF header*/
int
head_version (irafheader)
char *irafheader; /* IRAF image header from file */
{
/* Check header file magic word */
if (irafncmp (irafheader, "imhdr", 5) != 0 ) {
if (strncmp (irafheader, "imhv2", 5) != 0)
return (0);
else
return (2);
}
else
return (1);
}
/* Return IRAF image format version number from magic word in IRAF pixel file */
int
pix_version (irafheader)
char *irafheader; /* IRAF image header from file */
{
/* Check pixel file header magic word */
if (irafncmp (irafheader, "impix", 5) != 0) {
if (strncmp (irafheader, "impv2", 5) != 0)
return (0);
else
return (2);
}
else
return (1);
}
/* Verify that file is valid IRAF imhdr or impix by checking first 5 chars
* Returns: 0 on success, 1 on failure */
int
irafncmp (irafheader, teststring, nc)
char *irafheader; /* IRAF image header from file */
char *teststring; /* C character string to compare */
int nc; /* Number of characters to compate */
{
char *line;
headswap = -1;
if ((line = iraf2str (irafheader, nc)) == NULL)
return (1);
if (strncmp (line, teststring, nc) == 0) {
free (line);
return (0);
}
else {
free (line);
return (1);
}
}
/* Convert IRAF image header to FITS image header, returning FITS header */
char *
iraf2fits (hdrname, irafheader, nbiraf, nbfits)
char *hdrname; /* IRAF header file name (may be path) */
char *irafheader; /* IRAF image header */
int nbiraf; /* Number of bytes in IRAF header */
int *nbfits; /* Number of bytes in FITS header (returned) */
{
char *objname; /* object name from FITS file */
int lstr, i, j, k, ib, nax, nbits, nl, lname;
char *pixname, *newpixname, *bang, *chead;
char *fitsheader;
int nblock, nlines;
char *fhead, *fhead1, *fp, endline[81];
char irafchar;
char fitsline[81];
char *dstring;
int pixtype;
int imhver, n, imu, pixoff, impixoff, immax, immin, imtime;
int imndim, imlen, imphyslen, impixtype, pixswap, hpixswap, mtime;
float rmax, rmin;
headswap = -1;
/* Set up last line of FITS header */
(void)strncpy (endline,"END", 3);
for (i = 3; i < 80; i++)
endline[i] = ' ';
endline[80] = 0;
/* Check header magic word */
imhver = head_version (irafheader);
if (imhver < 1) {
(void)fprintf(stderr, "File %s not valid IRAF image header\n",
hdrname);
return(NULL);
}
if (imhver == 2) {
nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81);
imndim = IM2_NDIM;
imlen = IM2_LEN;
imphyslen = IM2_PHYSLEN;
impixtype = IM2_PIXTYPE;
impixoff = IM2_PIXOFF;
imtime = IM2_MTIME;
immax = IM2_MAX;
immin = IM2_MIN;
}
else {
nlines = 24 + ((nbiraf - LEN_IMHDR) / 162);
imndim = IM_NDIM;
imlen = IM_LEN;
imphyslen = IM_PHYSLEN;
impixtype = IM_PIXTYPE;
impixoff = IM_PIXOFF;
imtime = IM_MTIME;
immax = IM_MAX;
immin = IM_MIN;
}
/* Initialize FITS header */
nblock = (nlines * 80) / 2880;
*nbfits = (nblock + 5) * 2880 + 4;
fitsheader = (char *) calloc (*nbfits, 1);
if (fitsheader == NULL) {
(void)fprintf(stderr, "IRAF2FITS Cannot allocate %d-byte FITS header\n",
*nbfits);
return (NULL);
}
hlength (fitsheader, *nbfits);
fhead = fitsheader;
(void)strncpy (fitsheader, endline, 80);
hputl (fitsheader, "SIMPLE", 1);
fhead = fhead + 80;
/* Set pixel size in FITS header */
pixtype = irafgeti4 (irafheader, impixtype);
switch (pixtype) {
case TY_CHAR:
nbits = 8;
break;
case TY_UBYTE:
nbits = 8;
break;
case TY_SHORT:
nbits = 16;
break;
case TY_USHORT:
nbits = -16;
break;
case TY_INT:
case TY_LONG:
nbits = 32;
break;
case TY_REAL:
nbits = -32;
break;
case TY_DOUBLE:
nbits = -64;
break;
default:
(void)fprintf(stderr,"Unsupported data type: %d\n", pixtype);
return (NULL);
}
hputi4 (fitsheader,"BITPIX",nbits);
hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type");
fhead = fhead + 80;
/* Set image dimensions in FITS header */
nax = irafgeti4 (irafheader, imndim);
hputi4 (fitsheader,"NAXIS",nax);
hputcom (fitsheader,"NAXIS", "IRAF .imh naxis");
fhead = fhead + 80;
n = irafgeti4 (irafheader, imlen);
hputi4 (fitsheader, "NAXIS1", n);
hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]");
fhead = fhead + 80;
if (nax > 1) {
n = irafgeti4 (irafheader, imlen+4);
hputi4 (fitsheader, "NAXIS2", n);
hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]");
}
else
hputi4 (fitsheader, "NAXIS2", 1);
hputcom (fitsheader,"NAXIS2", "IRAF .imh naxis[2]");
fhead = fhead + 80;
if (nax > 2) {
n = irafgeti4 (irafheader, imlen+8);
hputi4 (fitsheader, "NAXIS3", n);
hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]");
fhead = fhead + 80;
}
if (nax > 3) {
n = irafgeti4 (irafheader, imlen+12);
hputi4 (fitsheader, "NAXIS4", n);
hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]");
fhead = fhead + 80;
}
/* Set object name in FITS header */
if (imhver == 2)
objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE);
else
objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE);
if ((lstr = strlen (objname)) < 8) {
for (i = lstr; i < 8; i++)
objname[i] = ' ';
objname[8] = 0;
}
hputs (fitsheader,"OBJECT",objname);
hputcom (fitsheader,"OBJECT", "IRAF .imh title");
free (objname);
fhead = fhead + 80;
/* Save physical axis lengths so image file can be read */
n = irafgeti4 (irafheader, imphyslen);
hputi4 (fitsheader, "NPAXIS1", n);
hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]");
fhead = fhead + 80;
if (nax > 1) {
n = irafgeti4 (irafheader, imphyslen+4);
hputi4 (fitsheader, "NPAXIS2", n);
hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]");
fhead = fhead + 80;
}
if (nax > 2) {
n = irafgeti4 (irafheader, imphyslen+8);
hputi4 (fitsheader, "NPAXIS3", n);
hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]");
fhead = fhead + 80;
}
if (nax > 3) {
n = irafgeti4 (irafheader, imphyslen+12);
hputi4 (fitsheader, "NPAXIS4", n);
hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]");
fhead = fhead + 80;
}
/* Save image minimum and maximum in header */
rmax = irafgetr4 (irafheader, immax);
rmin = irafgetr4 (irafheader, immin);
if (rmin != rmax) {
hputr4 (fitsheader, "IRAFMIN", rmin);
fhead = fhead + 80;
hputcom (fitsheader,"IRAFMIN", "IRAF .imh minimum");
hputr4 (fitsheader, "IRAFMAX", rmax);
hputcom (fitsheader,"IRAFMAX", "IRAF .imh maximum");
fhead = fhead + 80;
}
/* Save image header filename in header */
nl = hputm (fitsheader,"IMHFIL",hdrname);
if (nl > 0) {
lname = strlen (hdrname);
strcpy (fitsline, "IRAF header file name");
if (lname < 43)
hputcom (fitsheader,"IMHFIL_1", fitsline);
else if (lname > 67 && lname < 110)
hputcom (fitsheader,"IMHFIL_2", fitsline);
else if (lname > 134 && lname < 177)
hputcom (fitsheader,"IMHFIL_3", fitsline);
}
if (nl > 0) fhead = fhead + (nl * 80);
/* Save image pixel file pathname in header */
if (imhver == 2)
pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
else
pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE);
if (strncmp(pixname, "HDR", 3) == 0 ) {
newpixname = same_path (pixname, hdrname);
free (pixname);
pixname = newpixname;
}
if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) {
newpixname = same_path (pixname, hdrname);
free (pixname);
pixname = newpixname;
}
if ((bang = strchr (pixname, '!')) != NULL )
nl = hputm (fitsheader,"PIXFIL",bang+1);
else
nl = hputm (fitsheader,"PIXFIL",pixname);
free (pixname);
if (nl > 0) {
strcpy (fitsline, "IRAF .pix pixel file");
if (lname < 43)
hputcom (fitsheader,"PIXFIL_1", fitsline);
else if (lname > 67 && lname < 110)
hputcom (fitsheader,"PIXFIL_2", fitsline);
else if (lname > 134 && lname < 177)
hputcom (fitsheader,"PIXFIL_3", fitsline);
}
if (nl > 0) fhead = fhead + (nl * 80);
/* Save image offset from star of pixel file */
pixoff = irafgeti4 (irafheader, impixoff);
pixoff = (pixoff - 1) * 2;
hputi4 (fitsheader, "PIXOFF", pixoff);
hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)");
fhead = fhead + 80;
/* Save IRAF file format version in header */
hputi4 (fitsheader,"IMHVER",imhver);
hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)");
fhead = fhead + 80;
/* Set flag if header numbers are byte-reversed on this machine */
if (machswap() != headswap)
hputl (fitsheader, "HEADSWAP", 1);
else
hputl (fitsheader, "HEADSWAP", 0);
hputcom (fitsheader,"HEADSWAP", "IRAF header, FITS byte orders differ if T");
fhead = fhead + 80;
/* Set flag if image pixels are byte-reversed on this machine */
if (imhver == 2) {
hpixswap = irafgeti4 (irafheader, IM2_SWAPPED);
if (headswap && !hpixswap)
pixswap = 1;
else if (!headswap && hpixswap)
pixswap = 1;
else
pixswap = 0;
}
else
pixswap = headswap;
if (machswap() != pixswap)
hputl (fitsheader, "PIXSWAP", 1);
else
hputl (fitsheader, "PIXSWAP", 0);
hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T");
fhead = fhead + 80;
/* Read modification time */
mtime = irafgeti4 (irafheader, imtime);
if (mtime == 0)
dstring = lt2fd ();
else
dstring = tsi2fd (mtime);
hputs (fitsheader, "DATE-MOD", dstring);
hputcom (fitsheader,"DATE-MOD", "Date of latest file modification");
free (dstring);
fhead = fhead + 80;
/* Add user portion of IRAF header to FITS header */
fitsline[80] = 0;
if (imhver == 2) {
imu = LEN_IM2HDR;
chead = irafheader;
j = 0;
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
for (i = imu; i < nbiraf; i++) {
irafchar = chead[i];
if (irafchar == 0)
break;
else if (irafchar == 10) {
(void)strncpy (fhead, fitsline, 80);
/* fprintf (stderr,"%80s\n",fitsline); */
if (strncmp (fitsline, "OBJECT ", 7) != 0) {
fhead = fhead + 80;
}
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
j = 0;
}
else {
if (j > 80) {
if (strncmp (fitsline, "OBJECT ", 7) != 0) {
(void)strncpy (fhead, fitsline, 80);
/* fprintf (stderr,"%80s\n",fitsline); */
j = 9;
fhead = fhead + 80;
}
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
}
if (irafchar > 32 && irafchar < 127)
fitsline[j] = irafchar;
j++;
}
}
}
else {
imu = LEN_IMHDR;
chead = irafheader;
if (headswap == 1)
ib = 0;
else
ib = 1;
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
j = 0;
for (i = imu; i < nbiraf; i=i+2) {
irafchar = chead[i+ib];
if (irafchar == 0)
break;
else if (irafchar == 10) {
if (strncmp (fitsline, "OBJECT ", 7) != 0) {
(void)strncpy (fhead, fitsline, 80);
fhead = fhead + 80;
}
/* fprintf (stderr,"%80s\n",fitsline); */
j = 0;
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
}
else {
if (j > 80) {
if (strncmp (fitsline, "OBJECT ", 7) != 0) {
(void)strncpy (fhead, fitsline, 80);
j = 9;
fhead = fhead + 80;
}
/* fprintf (stderr,"%80s\n",fitsline); */
for (k = 0; k < 80; k++)
fitsline[k] = ' ';
}
if (irafchar > 32 && irafchar < 127)
fitsline[j] = irafchar;
j++;
}
}
}
/* Add END to last line */
(void)strncpy (fhead, endline, 80);
/* Find end of last 2880-byte block of header */
fhead = ksearch (fitsheader, "END") + 80;
nblock = *nbfits / 2880;
fhead1 = fitsheader + (nblock * 2880);
/* Pad rest of header with spaces */
strncpy (endline," ",3);
for (fp = fhead; fp < fhead1; fp = fp + 80) {
(void)strncpy (fp, endline,80);
}
return (fitsheader);
}
int
irafwhead (hdrname, lhead, irafheader, fitsheader)
char *hdrname; /* Name of IRAF header file */
int lhead; /* Length of IRAF header */
char *irafheader; /* IRAF header */
char *fitsheader; /* FITS image header */
{
int fd;
int nbw, nbhead, lphead, pixswap;
/* Get rid of redundant header information */
hgeti4 (fitsheader, "PIXOFF", &lphead);
hgeti4 (fitsheader, "PIXSWAP", &pixswap);
/* Write IRAF header file */
/* Convert FITS header to IRAF header */
irafheader = fits2iraf (fitsheader, irafheader, lhead, &nbhead);
if (irafheader == NULL) {
fprintf (stderr, "IRAFWIMAGE: file %s header error\n", hdrname);
return (-1);
}
/* Open the output file */
if (!access (hdrname, 0)) {
fd = open (hdrname, O_WRONLY);
if (fd < 3) {
fprintf (stderr, "IRAFWIMAGE: file %s not writeable\n", hdrname);
return (0);
}
}
else {
fd = open (hdrname, O_RDWR+O_CREAT, 0666);
if (fd < 3) {
fprintf (stderr, "IRAFWIMAGE: cannot create file %s\n", hdrname);
return (0);
}
}
/* Write IRAF header to disk file */
nbw = write (fd, irafheader, nbhead);
ftruncate (fd, nbhead);
close (fd);
if (nbw < nbhead) {
(void)fprintf(stderr, "IRAF header file %s: %d / %d bytes written.\n",
hdrname, nbw, nbhead);
return (-1);
}
return (nbw);
}
/* IRAFWIMAGE -- write IRAF .imh header file and .pix image file
* No matter what the input, this always writes in the local byte order */
int
irafwimage (hdrname, lhead, irafheader, fitsheader, image )
char *hdrname; /* Name of IRAF header file */
int lhead; /* Length of IRAF header */
char *irafheader; /* IRAF header */
char *fitsheader; /* FITS image header */
char *image; /* IRAF image */
{
int fd;
char *bang;
int nbw, bytepix, bitpix, naxis, naxis1, naxis2, nbimage, lphead;
char *pixn, *newpixname;
char pixname[SZ_IM2PIXFILE+1];
int imhver, pixswap;
hgeti4 (fitsheader, "IMHVER", &imhver);
if (!hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname)) {
if (imhver == 2)
pixn = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
else
pixn = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE);
if (strncmp(pixn, "HDR", 3) == 0 ) {
newpixname = same_path (pixn, hdrname);
strcpy (pixname, newpixname);
}
else {
if ((bang = strchr (pixn, '!')) != NULL )
strcpy (pixname, bang+1);
else
strcpy (pixname, pixn);
}
free (pixn);
}
/* Find number of bytes to write */
hgeti4 (fitsheader,"NAXIS",&naxis);
hgeti4 (fitsheader,"NAXIS1",&naxis1);
hgeti4 (fitsheader,"NAXIS2",&naxis2);
hgeti4 (fitsheader,"BITPIX",&bitpix);
if (bitpix < 0)
bytepix = -bitpix / 8;
else
bytepix = bitpix / 8;
/* If either dimension is one and image is 3-D, read all three dimensions */
if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) {
int naxis3;
hgeti4 (fitsheader,"NAXIS3",&naxis3);
nbimage = naxis1 * naxis2 * naxis3 * bytepix;
}
else
nbimage = naxis1 * naxis2 * bytepix;
/* Read information about pixel file from header */
hgeti4 (fitsheader, "PIXOFF", &lphead);
hgeti4 (fitsheader, "PIXSWAP", &pixswap);
/* Write IRAF header file */
if (irafwhead (hdrname, lhead, irafheader, fitsheader))
return (0);
/* Open the output file */
if (!access (pixname, 0)) {
fd = open (pixname, O_WRONLY);
if (fd < 3) {
fprintf (stderr, "IRAFWIMAGE: file %s not writeable\n", pixname);
return (0);
}
}
else {
fd = open (pixname, O_RDWR+O_CREAT, 0666);
if (fd < 3) {
fprintf (stderr, "IRAFWIMAGE: cannot create file %s\n", pixname);
return (0);
}
}
/* Write header to IRAF pixel file */
if (imhver == 2)
irafputc ("impv2", irafheader, 0, 5);
else
irafputc2 ("impix", irafheader, 0, 5);
nbw = write (fd, irafheader, lphead);
/* Byte-reverse image, if necessary */
if (pixswap)
irafswap (bitpix, image, nbimage);
/* Write data to IRAF pixel file */
nbw = write (fd, image, nbimage);
close (fd);
free (pixname);
return (nbw);
}
/* Put filename and header path together */
static char *
same_path (pixname, hdrname)
char *pixname; /* IRAF pixel file pathname */
char *hdrname; /* IRAF image header file pathname */
{
int len;
char *newpixname;
newpixname = (char *) calloc (SZ_IM2PIXFILE, sizeof (char));
/* Pixel file is in same directory as header */
if (strncmp(pixname, "HDR$", 4) == 0 ) {
(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
/* find the end of the pathname */
len = strlen (newpixname);
#ifndef VMS
while( (len > 0) && (newpixname[len-1] != '/') )
#else
while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') )
#endif
len--;
/* add name */
newpixname[len] = '\0';
(void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE);
}
/* Bare pixel file with no path is assumed to be same as HDR$filename */
else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) {
(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
/* find the end of the pathname */
len = strlen (newpixname);
#ifndef VMS
while( (len > 0) && (newpixname[len-1] != '/') )
#else
while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') )
#endif
len--;
/* add name */
newpixname[len] = '\0';
(void)strncat (newpixname, pixname, SZ_IM2PIXFILE);
}
/* Pixel file has same name as header file, but with .pix extension */
else if (strncmp (pixname, "HDR", 3) == 0) {
/* load entire header name string into name buffer */
(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
len = strlen (newpixname);
newpixname[len-3] = 'p';
newpixname[len-2] = 'i';
newpixname[len-1] = 'x';
}
return (newpixname);
}
/* Convert FITS image header to IRAF image header, returning IRAF header */
/* No matter what the input, this always writes in the local byte order */
char *
fits2iraf (fitsheader, irafheader, nbhead, nbiraf)
char *fitsheader; /* FITS image header */
char *irafheader; /* IRAF image header (returned updated) */
int nbhead; /* Length of IRAF header */
int *nbiraf; /* Length of returned IRAF header */
{
int i, n, pixoff, lhdrdir;
short *irafp, *irafs, *irafu;
char *iraf2u, *iraf2p, *filename, *hdrdir;
char *fitsend, *fitsp, pixfile[SZ_IM2PIXFILE], hdrfile[SZ_IM2HDRFILE];
char title[SZ_IM2TITLE], temp[80];
int nax, nlfits, imhver, nbits, pixtype, hdrlength, mtime;
int imndim, imlen, imphyslen, impixtype, imhlen, imtime, immax, immin;
float rmax, rmin;
hgeti4 (fitsheader, "IMHVER", &imhver);
hdel (fitsheader, "IMHVER");
hdel (fitsheader, "IMHVER");
hgetl (fitsheader, "HEADSWAP", &headswap);
hdel (fitsheader, "HEADSWAP");
hdel (fitsheader, "HEADSWAP");
if (imhver == 2) {
imhlen = IM2_HDRLEN;
imndim = IM2_NDIM;
imlen = IM2_LEN;
imtime = IM2_MTIME;
imphyslen = IM2_PHYSLEN;
impixtype = IM2_PIXTYPE;
immax = IM2_MAX;
immin = IM2_MIN;
}
else {
imhlen = IM_HDRLEN;
imndim = IM_NDIM;
imlen = IM_LEN;
imtime = IM_MTIME;
imphyslen = IM_PHYSLEN;
impixtype = IM_PIXTYPE;
immax = IM_MAX;
immin = IM_MIN;
}
/* Delete FITS header keyword not needed by IRAF */
hdel (fitsheader,"SIMPLE");
/* Set IRAF image data type */
hgeti4 (fitsheader,"BITPIX", &nbits);
switch (nbits) {
case 8:
pixtype = TY_CHAR;
break;
case -8:
pixtype = TY_UBYTE;
break;
case 16:
pixtype = TY_SHORT;
break;
case -16:
pixtype = TY_USHORT;
break;
case 32:
pixtype = TY_INT;
break;
case -32:
pixtype = TY_REAL;
break;
case -64:
pixtype = TY_DOUBLE;
break;
default:
(void)fprintf(stderr,"Unsupported data type: %d\n", nbits);
return (NULL);
}
irafputi4 (irafheader, impixtype, pixtype);
hdel (fitsheader,"BITPIX");
/* Set IRAF image dimensions */
hgeti4 (fitsheader,"NAXIS",&nax);
irafputi4 (irafheader, imndim, nax);
hdel (fitsheader,"NAXIS");
hgeti4 (fitsheader, "NAXIS1", &n);
irafputi4 (irafheader, imlen, n);
irafputi4 (irafheader, imphyslen, n);
hdel (fitsheader,"NAXIS1");
hgeti4 (fitsheader,"NAXIS2",&n);
irafputi4 (irafheader, imlen+4, n);
irafputi4 (irafheader, imphyslen+4, n);
hdel (fitsheader,"NAXIS2");
if (nax > 2) {
hgeti4 (fitsheader,"NAXIS3",&n);
irafputi4 (irafheader, imlen+8, n);
irafputi4 (irafheader, imphyslen+8, n);
hdel (fitsheader,"NAXIS3");
}
if (nax > 3) {
hgeti4 (fitsheader,"NAXIS4",&n);
irafputi4 (irafheader, imlen+12, n);
irafputi4 (irafheader, imphyslen+12, n);
hdel (fitsheader,"NAXIS4");
}
/* Set image pixel value limits */
rmin = 0.0;
hgetr4 (fitsheader, "IRAFMIN", &rmin);
rmax = 0.0;
hgetr4 (fitsheader, "IRAFMAX", &rmax);
if (rmin != rmax) {
irafputr4 (irafheader, immax, rmax);
irafputr4 (irafheader, immin, rmin);
}
hdel (fitsheader, "IRAFMIN");
hdel (fitsheader, "IRAFMAX");
/* Replace pixel file name, if it is in the FITS header */
if (hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixfile)) {
if (strchr (pixfile, '/')) {
if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, hdrfile)) {
hdrdir = strrchr (hdrfile, '/');
if (hdrdir != NULL) {
lhdrdir = hdrdir - hdrfile + 1;
if (!strncmp (pixfile, hdrfile, lhdrdir)) {
filename = pixfile + lhdrdir;
strcpy (temp, "HDR$");
strcat (temp,filename);
strcpy (pixfile, temp);
}
}
if (pixfile[0] != '/' && pixfile[0] != 'H') {
strcpy (temp, "HDR$");
strcat (temp,pixfile);
strcpy (pixfile, temp);
}
}
}
if (imhver == 2)
irafputc (pixfile, irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
else
irafputc2 (pixfile, irafheader, IM_PIXFILE, SZ_IMPIXFILE);
hdel (fitsheader,"PIXFIL_1");
hdel (fitsheader,"PIXFIL_2");
hdel (fitsheader,"PIXFIL_3");
hdel (fitsheader,"PIXFIL_4");
}
/* Replace header file name, if it is in the FITS header */
if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, pixfile)) {
if (!strchr (pixfile,'/') && !strchr (pixfile,'$')) {
strcpy (temp, "HDR$");
strcat (temp,pixfile);
strcpy (pixfile, temp);
}
if (imhver == 2)
irafputc (pixfile, irafheader, IM2_HDRFILE, SZ_IM2HDRFILE);
else
irafputc2 (pixfile, irafheader, IM_HDRFILE, SZ_IMHDRFILE);
hdel (fitsheader, "IMHFIL_1");
hdel (fitsheader, "IMHFIL_2");
hdel (fitsheader, "IMHFIL_3");
hdel (fitsheader, "IMHFIL_4");
}
/* Replace image title, if it is in the FITS header */
if (hgets (fitsheader, "OBJECT", SZ_IM2TITLE, title)) {
if (imhver == 2)
irafputc (title, irafheader, IM2_TITLE, SZ_IM2TITLE);
else
irafputc2 (title, irafheader, IM_TITLE, SZ_IMTITLE);
hdel (fitsheader, "OBJECT");
}
hgeti4 (fitsheader, "PIXOFF", &pixoff);
hdel (fitsheader, "PIXOFF");
hdel (fitsheader, "PIXOFF");
hdel (fitsheader, "PIXSWAP");
hdel (fitsheader, "PIXSWAP");
hdel (fitsheader, "DATE-MOD");
hdel (fitsheader, "DATE-MOD");
fitsend = ksearch (fitsheader,"END");
/* Find length of FITS header */
fitsend = ksearch (fitsheader,"END");
nlfits = ((fitsend - fitsheader) / 80);
/* Find new length of IRAF header */
if (imhver == 2)
*nbiraf = LEN_IM2HDR + (81 * nlfits);
else
*nbiraf = LEN_IMHDR + (162 * nlfits);
if (*nbiraf > nbhead)
irafheader = realloc (irafheader, *nbiraf);
/* Reset modification time */
mtime = lt2tsi ();
irafputi4 (irafheader, imtime, mtime);
/* Replace user portion of IRAF header with remaining FITS header */
if (imhver == 2) {
iraf2u = irafheader + LEN_IM2HDR;
iraf2p = iraf2u;
for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) {
for (i = 0; i < 80; i++)
*iraf2p++ = fitsp[i];
*iraf2p++ = 10;
}
*iraf2p++ = 0;
*nbiraf = iraf2p - irafheader;
hdrlength = 1 + *nbiraf / 2;
}
else {
irafs = (short *)irafheader;
irafu = irafs + (LEN_IMHDR / 2);
irafp = irafu;
for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) {
for (i = 0; i < 80; i++)
*irafp++ = (short) fitsp[i];
*irafp++ = 10;
}
*irafp++ = 0;
*irafp++ = 32;
*nbiraf = 2 * (irafp - irafs);
hdrlength = *nbiraf / 4;
}
/* Length of header file */
irafputi4 (irafheader, imhlen, hdrlength);
/* Offset in .pix file to first pixel data
hputi4 (fitsheader, "PIXOFF", pixoff); */
/* Return number of bytes in new IRAF header */
return (irafheader);
}
int
irafgeti4 (irafheader, offset)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before number */
{
char *ctemp, *cheader;
int temp;
cheader = irafheader;
ctemp = (char *) &temp;
/* If header swap flag not set, set it now */
if (headswap < 0) {
if (cheader[offset] > 0)
headswap = 1;
else
headswap = 0;
}
if (machswap() != headswap) {
ctemp[3] = cheader[offset];
ctemp[2] = cheader[offset+1];
ctemp[1] = cheader[offset+2];
ctemp[0] = cheader[offset+3];
}
else {
ctemp[0] = cheader[offset];
ctemp[1] = cheader[offset+1];
ctemp[2] = cheader[offset+2];
ctemp[3] = cheader[offset+3];
}
return (temp);
}
float
irafgetr4 (irafheader, offset)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before number */
{
char *ctemp, *cheader;
float temp;
cheader = irafheader;
ctemp = (char *) &temp;
/* If header swap flag not set, set it now */
if (headswap < 0) {
if (cheader[offset] > 0)
headswap = 1;
else
headswap = 0;
}
if (machswap() != headswap) {
ctemp[3] = cheader[offset];
ctemp[2] = cheader[offset+1];
ctemp[1] = cheader[offset+2];
ctemp[0] = cheader[offset+3];
}
else {
ctemp[0] = cheader[offset];
ctemp[1] = cheader[offset+1];
ctemp[2] = cheader[offset+2];
ctemp[3] = cheader[offset+3];
}
return (temp);
}
/* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */
char *
irafgetc2 (irafheader, offset, nc)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before string */
int nc; /* Maximum number of characters in string */
{
char *irafstring, *string;
irafstring = irafgetc (irafheader, offset, 2*(nc+1));
string = iraf2str (irafstring, nc);
free (irafstring);
return (string);
}
/* IRAFGETC -- Get character string from arbitrary part of IRAF header */
char *
irafgetc (irafheader, offset, nc)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before string */
int nc; /* Maximum number of characters in string */
{
char *ctemp, *cheader;
int i;
cheader = irafheader;
ctemp = (char *) calloc (nc+1, 1);
if (ctemp == NULL) {
(void)fprintf(stderr, "IRAFGETC Cannot allocate %d-byte variable\n",
nc+1);
return (NULL);
}
for (i = 0; i < nc; i++) {
ctemp[i] = cheader[offset+i];
if (ctemp[i] > 0 && ctemp[i] < 32)
ctemp[i] = ' ';
}
return (ctemp);
}
/* Convert IRAF 2-byte/char string to 1-byte/char string */
char *
iraf2str (irafstring, nchar)
char *irafstring; /* IRAF 2-byte/character string */
int nchar; /* Number of characters in string */
{
char *string;
int i, j;
/* Set swap flag according to position of nulls in 2-byte characters */
if (headswap < 0) {
if (irafstring[0] != 0 && irafstring[1] == 0)
headswap = 1;
else if (irafstring[0] == 0 && irafstring[1] != 0)
headswap = 0;
else
return (NULL);
}
string = (char *) calloc (nchar+1, 1);
if (string == NULL) {
(void)fprintf(stderr, "IRAF2STR Cannot allocate %d-byte variable\n",
nchar+1);
return (NULL);
}
/* Swap bytes, if requested */
if (headswap)
j = 0;
else
j = 1;
/* Convert appropriate byte of input to output character */
for (i = 0; i < nchar; i++) {
string[i] = irafstring[j];
j = j + 2;
}
return (string);
}
/* IRAFPUTI4 -- Insert 4-byte integer into arbitrary part of IRAF header */
static void
irafputi4 (irafheader, offset, inum)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before number */
int inum; /* Number to put into header */
{
char *cn, *chead;
chead = irafheader;
cn = (char *) &inum;
if (headswap < 0)
headswap = 0;
if (headswap != machswap()) {
chead[offset+3] = cn[0];
chead[offset+2] = cn[1];
chead[offset+1] = cn[2];
chead[offset] = cn[3];
}
else {
chead[offset] = cn[0];
chead[offset+1] = cn[1];
chead[offset+2] = cn[2];
chead[offset+3] = cn[3];
}
return;
}
/* IRAFPUTR4 -- Insert 4-byte real number into arbitrary part of IRAF header */
static void
irafputr4 (irafheader, offset, rnum)
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before number */
float rnum; /* Number to put into header */
{
char *cn, *chead;
chead = irafheader;
cn = (char *) &rnum;
if (headswap < 0)
headswap = 0;
if (headswap != machswap()) {
chead[offset+3] = cn[0];
chead[offset+2] = cn[1];
chead[offset+1] = cn[2];
chead[offset] = cn[3];
}
else {
chead[offset] = cn[0];
chead[offset+1] = cn[1];
chead[offset+2] = cn[2];
chead[offset+3] = cn[3];
}
return;
}
/* IRAFPUTC2 -- Insert character string into arbitrary part of v.1 IRAF header */
static void
irafputc2 (string, irafheader, offset, nc)
char *string; /* String to insert into header */
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before string */
int nc; /* Maximum number of characters in string */
{
char *irafstring;
irafstring = (char *) calloc (2 * nc, 1);
if (irafstring == NULL) {
(void)fprintf(stderr, "IRAFPUTC2 Cannot allocate %d-byte variable\n",
2 * nc);
}
str2iraf (string, irafstring, nc);
irafputc (irafstring, irafheader, offset, 2*nc);
return;
}
/* IRAFPUTC -- Insert character string into arbitrary part of IRAF header */
static void
irafputc (string, irafheader, offset, nc)
char *string; /* String to insert into header */
char *irafheader; /* IRAF image header */
int offset; /* Number of bytes to skip before string */
int nc; /* Maximum number of characters in string */
{
char *chead;
int i;
chead = irafheader;
for (i = 0; i < nc; i++)
chead[offset+i] = string[i];
return;
}
/* STR2IRAF -- Convert 1-byte/char string to IRAF 2-byte/char string */
static void
str2iraf (string, irafstring, nchar)
char *string; /* 1-byte/character string */
char *irafstring; /* IRAF 2-byte/character string */
int nchar; /* Maximum number of characters in IRAF string */
{
int i, j, nc, nbytes;
nc = strlen (string);
/* Fill output string with zeroes */
nbytes = nchar * 2;
for (i = 0; i < nbytes; i++)
irafstring[i] = 0;
/* If swapped, start with first byte of 2-byte characters */
if (headswap)
j = 0;
else
j = 1;
/* Move input characters to appropriate bytes of output */
for (i = 0; i < nchar; i++) {
if (i > nc)
irafstring[j] = 0;
else
irafstring[j] = string[i];
j = j + 2;
}
return;
}
/* IRAFSWAP -- Reverse bytes of any type of vector in place */
static void
irafswap (bitpix, string, nbytes)
int bitpix; /* Number of bits per pixel */
/* 16 = short, -16 = unsigned short, 32 = int */
/* -32 = float, -64 = double */
char *string; /* Address of starting point of bytes to swap */
int nbytes; /* Number of bytes to swap */
{
switch (bitpix) {
case 16:
if (nbytes < 2) return;
irafswap2 (string,nbytes);
break;
case 32:
if (nbytes < 4) return;
irafswap4 (string,nbytes);
break;
case -16:
if (nbytes < 2) return;
irafswap2 (string,nbytes);
break;
case -32:
if (nbytes < 4) return;
irafswap4 (string,nbytes);
break;
case -64:
if (nbytes < 8) return;
irafswap8 (string,nbytes);
break;
}
return;
}
/* IRAFSWAP2 -- Swap bytes in string in place */
static void
irafswap2 (string,nbytes)
char *string; /* Address of starting point of bytes to swap */
int nbytes; /* Number of bytes to swap */
{
char *sbyte, temp, *slast;
slast = string + nbytes;
sbyte = string;
while (sbyte < slast) {
temp = sbyte[0];
sbyte[0] = sbyte[1];
sbyte[1] = temp;
sbyte= sbyte + 2;
}
return;
}
/* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */
static void
irafswap4 (string,nbytes)
char *string; /* Address of Integer*4 or Real*4 vector */
int nbytes; /* Number of bytes to reverse */
{
char *sbyte, *slast;
char temp0, temp1, temp2, temp3;
slast = string + nbytes;
sbyte = string;
while (sbyte < slast) {
temp3 = sbyte[0];
temp2 = sbyte[1];
temp1 = sbyte[2];
temp0 = sbyte[3];
sbyte[0] = temp0;
sbyte[1] = temp1;
sbyte[2] = temp2;
sbyte[3] = temp3;
sbyte = sbyte + 4;
}
return;
}
/* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */
static void
irafswap8 (string,nbytes)
char *string; /* Address of Real*8 vector */
int nbytes; /* Number of bytes to reverse */
{
char *sbyte, *slast;
char temp[8];
slast = string + nbytes;
sbyte = string;
while (sbyte < slast) {
temp[7] = sbyte[0];
temp[6] = sbyte[1];
temp[5] = sbyte[2];
temp[4] = sbyte[3];
temp[3] = sbyte[4];
temp[2] = sbyte[5];
temp[1] = sbyte[6];
temp[0] = sbyte[7];
sbyte[0] = temp[0];
sbyte[1] = temp[1];
sbyte[2] = temp[2];
sbyte[3] = temp[3];
sbyte[4] = temp[4];
sbyte[5] = temp[5];
sbyte[6] = temp[6];
sbyte[7] = temp[7];
sbyte = sbyte + 8;
}
return;
}
/* Set flag if machine on which program is executing is not FITS byte order
* ( i.e., if it is an Alpha or PC instead of a Sun ) */
static int
machswap ()
{
char *ctest;
int itest;
itest = 1;
ctest = (char *)&itest;
if (*ctest)
return (1);
else
return (0);
}
/* ISIRAF -- return 1 if IRAF imh file, else 0 */
int
isiraf (filename)
char *filename; /* Name of file for which to find size */
{
if (strchr (filename, '='))
return (0);
else if (strsrch (filename, ".imh"))
return (1);
else
return (0);
}
/* IRAFSIZE -- return size of file in bytes */
static int
irafsize (diskfile)
FILE *diskfile; /* Descriptor of file for which to find size */
{
long filesize;
long offset;
offset = (long) 0;
/* Move to end of the file */
if (fseek (diskfile, offset, SEEK_END) == 0) {
/* Position is the size of the file */
filesize = ftell (diskfile);
/* Move file pointer back tot he start of the file */
fseek (diskfile, offset, SEEK_SET);
}
else
filesize = -1;
return (filesize);
}
/* Feb 15 1996 New file
* Apr 10 1996 Add more documentation
* Apr 17 1996 Print error message on open failure
* Jun 5 1996 Add byte swapping (reversal); use streams
* Jun 10 1996 Make fixes after running lint
* Jun 12 1996 Use IMSWAP subroutines instead of local ones
* Jul 3 1996 Go back to using local IRAFSWAP subroutines
* Jul 3 1996 Write to pixel file from FITS header
* Jul 10 1996 Allocate all headers
* Aug 13 1996 Add unistd.h to include list
* Aug 26 1996 Allow 1-d images; fix comments; fix arguments after lint
* Aug 26 1996 Add IRAF header lingth argument to IRAFWIMAGE and IRAFWHEAD
* Aug 28 1996 Clean up code in IRAF2FITS
* Aug 30 1996 Use write instead of fwrite
* Sep 4 1996 Fix write mode bug
* Oct 15 1996 Drop unused variables
* Oct 17 1996 Minor fix after lint; cast arguments to STR2IRAF
*
* May 15 1997 Fix returned header length in IRAF2FITS
* Dec 19 1997 Add IRAF version 2 .imh files
*
* Jan 2 1998 Allow uneven length of user parameter lines in IRAF headers
* Jan 6 1998 Fix output of imh2 headers; allow newlines in imh1 headers
* Jan 14 1998 Handle byte reversing correctly
* Apr 17 1998 Add new IRAF data types unsigned char and unsigned short
* Apr 30 1998 Fix error return if illegal data type after Allan Brighton
* May 15 1998 Delete header keywords used for IRAF binary values
* May 15 1998 Fix bug so FITS OBJECT is put into IRAF title
* May 26 1998 Fix bug in fits2iraf keeping track of end of header
* May 27 1998 Include fitsio.h instead of fitshead.h
* Jun 4 1998 Write comments into header for converted IRAF binary values
* Jun 4 1998 Pad FITS strings to 8 character minimum
* Jul 24 1998 Write header file length to IRAF header file
* Jul 27 1998 Print error messages to stderr for all failed malloc's
* Jul 27 1998 Fix bug padding FITS header with spaces in iraf2fits
* Jul 27 1998 Write modification time to IRAF header file
* Aug 6 1998 Change fitsio.h to fitsfile.h; imhio.c to imhfile.c
* Oct 1 1998 Set irafswap flag only once per file
* Oct 5 1998 Add subroutines irafsize() and isiraf()
* Nov 16 1998 Fix byte-swap checking
*
* Jan 27 1999 Read and write all of 3D image if one dimension is =1
* Jul 13 1999 Improve error messages; change irafsize() argument to fd
* Sep 22 1999 Don't copy OBJECT keyword from .imh file; use binary title
* Oct 14 1999 Set FITS header length
* Oct 20 1999 Allocate 5000 extra bytes for IRAF header
* Nov 2 1999 Fix getclocktime() to use only time.h subroutines
* Nov 2 1999 Add modification date and time to FITS header in iraf2fits()
* Nov 24 1999 Delete HEADSWAP, IMHVER, DATE-MOD from header before writing
* Nov 29 1999 Delete PIXSWAP, IRAF-MIN, IRAF-MAX from header before writing
*
* Jan 13 2000 Fix bug which dropped characters in iraf2fits()
* Feb 3 2000 Declare timezone long, not time_t; drop unused variable
* Mar 7 2000 Add more code to keep pixel file path short
* Mar 10 2000 Fix bugs when writing .imh file headers
* Mar 21 2000 Change computation of IRAF time tags to use only data structure
* Mar 22 2000 Move IRAF time tag computation to lt2tsi() in dateutil.c
* Mar 24 2000 Use Unix file update time if none in header
* Mar 27 2000 Use hputm() to save file paths up to 256 characters
* Mar 27 2000 Write filename comments after 1st keyword with short value
* Mar 27 2000 Allocate pixel file name in same_path to imh2 length
* Mar 29 2000 Add space after last linefeed of header in fits2iraf()
* Apr 28 2000 Dimension pixname in irafwimage()
* May 1 2000 Fix code for updating pixel file name with HDR$ in fits2iraf()
* Jun 2 2000 Drop unused variables in fits2iraf() after lint
* Jun 12 2000 If pixel filename has no / or $, use same path as header file
* Sep 6 2000 Use header directory if pixel file not found at its pathname
*
* Jan 11 2001 Print all messages to stderr
* Aug 24 2001 In isiraf(), return 0 if argument contains an equal sign
*
* Apr 8 2002 Fix bug in error message for unidentified nbits in fits2iraf()
*
* Feb 4 2003 Open catalog file rb instead of r (Martin Ploner, Bern)
* Oct 31 2003 Read image only in irafrimage() if physical dimension > image dim.
* Nov 3 2003 Set NAXISi to image, not physical dimensions in iraf2fits()
*/
syntax highlighted by Code2HTML, v. 0.9.1