1 /*** File imhfile.c
2  *** March 27, 2012
3  *** By Jessica Mink, jmink@cfa.harvard.edu
4  *** Harvard-Smithsonian Center for Astrophysics
5  *** Copyright (C) 1996-2012
6  *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA
7 
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Lesser General Public
10     License as published by the Free Software Foundation; either
11     version 2 of the License, or (at your option) any later version.
12 
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with this library; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22     Correspondence concerning WCSTools should be addressed as follows:
23            Internet email: jmink@cfa.harvard.edu
24            Postal address: Jessica Mink
25                            Smithsonian Astrophysical Observatory
26                            60 Garden St.
27                            Cambridge, MA 02138 USA
28 
29  * Module:      imhfile.c (IRAF .imh image file reading and writing)
30  * Purpose:     Read and write IRAF image files (and translate headers)
31  * Subroutine:  check_immagic (irafheader, teststring )
32  *		Verify that file is valid IRAF imhdr or impix
33  * Subroutine:  irafrhead (filename, lfhead, fitsheader, lihead)
34  *              Read IRAF image header
35  * Subroutine:  irafrimage (fitsheader)
36  *              Read IRAF image pixels (call after irafrhead)
37  * Subroutine:	same_path (pixname, hdrname)
38  *		Put filename and header path together
39  * Subroutine:	iraf2fits (hdrname, irafheader, nbiraf, nbfits)
40  *		Convert IRAF image header to FITS image header
41  * Subroutine:	irafwhead (hdrname, irafheader, fitsheader)
42  *		Write IRAF header file
43  * Subroutine:	irafwimage (hdrname, irafheader, fitsheader, image )
44  *		Write IRAF image and header files
45  * Subroutine:	fits2iraf (fitsheader, irafheader)
46  *		Convert FITS image header to IRAF image header
47  * Subroutine:  irafgeti4 (irafheader, offset)
48  *		Get 4-byte integer from arbitrary part of IRAF header
49  * Subroutine:  irafgetc2 (irafheader, offset)
50  *		Get character string from arbitrary part of IRAF v.1 header
51  * Subroutine:  irafgetc (irafheader, offset)
52  *		Get character string from arbitrary part of IRAF header
53  * Subroutine:  iraf2str (irafstring, nchar)
54  * 		Convert 2-byte/char IRAF string to 1-byte/char string
55  * Subroutine:  str2iraf (string, irafstring, nchar)
56  * 		Convert 1-byte/char string to IRAF 2-byte/char string
57  * Subroutine:	irafswap (bitpix,string,nbytes)
58  *		Swap bytes in string in place, with FITS bits/pixel code
59  * Subroutine:	irafswap2 (string,nbytes)
60  *		Swap bytes in string in place
61  * Subroutine	irafswap4 (string,nbytes)
62  *		Reverse bytes of Integer*4 or Real*4 vector in place
63  * Subroutine	irafswap8 (string,nbytes)
64  *		Reverse bytes of Real*8 vector in place
65  * Subroutine	irafsize (filename)
66  *		Return length of file in bytes
67  * Subroutine	isiraf (filename)
68  *		Return 1 if IRAF .imh file, else 0
69 
70 
71  * Copyright:   2000 Smithsonian Astrophysical Observatory
72  *              You may do anything you like with this file except remove
73  *              this copyright.  The Smithsonian Astrophysical Observatory
74  *              makes no representations about the suitability of this
75  *              software for any purpose.  It is provided "as is" without
76  *              express or implied warranty.
77  */
78 
79 #include <stdio.h>		/* define stderr, FD, and NULL */
80 #include <stdlib.h>
81 #include <unistd.h>
82 #include <fcntl.h>
83 #include <string.h>
84 #include <time.h>
85 #include <sys/types.h>
86 #include "fitsfile.h"
87 
88 /* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */
89 #define SZ_IMPIXFILE	 79		/* name of pixel storage file */
90 #define SZ_IMHDRFILE	 79   		/* length of header storage file */
91 #define SZ_IMTITLE	 79		/* image title string */
92 #define LEN_IMHDR	2052		/* length of std header */
93 
94 /* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */
95 #define	SZ_IM2PIXFILE	255		/* name of pixel storage file */
96 #define	SZ_IM2HDRFILE	255		/* name of header storage file */
97 #define	SZ_IM2TITLE	383		/* image title string */
98 #define LEN_IM2HDR	2046		/* length of std header */
99 
100 /* Offsets into header in bytes for parameters in IRAF version 1 images */
101 #define IM_HDRLEN	 12		/* Length of header in 4-byte ints */
102 #define IM_PIXTYPE       16             /* Datatype of the pixels */
103 #define IM_NDIM          20             /* Number of dimensions */
104 #define IM_LEN           24             /* Length (as stored) */
105 #define IM_PHYSLEN       52             /* Physical length (as stored) */
106 #define IM_PIXOFF        88             /* Offset of the pixels */
107 #define IM_CTIME        108             /* Time of image creation */
108 #define IM_MTIME        112             /* Time of last modification */
109 #define IM_LIMTIME      116             /* Time of min,max computation */
110 #define IM_MAX          120             /* Maximum pixel value */
111 #define IM_MIN          124             /* Maximum pixel value */
112 #define IM_PIXFILE      412             /* Name of pixel storage file */
113 #define IM_HDRFILE      572             /* Name of header storage file */
114 #define IM_TITLE        732             /* Image name string */
115 
116 /* Offsets into header in bytes for parameters in IRAF version 2 images */
117 #define IM2_HDRLEN	  6		/* Length of header in 4-byte ints */
118 #define IM2_PIXTYPE      10             /* Datatype of the pixels */
119 #define IM2_SWAPPED      14             /* Pixels are byte swapped */
120 #define IM2_NDIM         18             /* Number of dimensions */
121 #define IM2_LEN          22             /* Length (as stored) */
122 #define IM2_PHYSLEN      50             /* Physical length (as stored) */
123 #define IM2_PIXOFF       86             /* Offset of the pixels */
124 #define IM2_CTIME       106             /* Time of image creation */
125 #define IM2_MTIME       110             /* Time of last modification */
126 #define IM2_LIMTIME     114             /* Time of min,max computation */
127 #define IM2_MAX         118             /* Maximum pixel value */
128 #define IM2_MIN         122             /* Maximum pixel value */
129 #define IM2_PIXFILE     126             /* Name of pixel storage file */
130 #define IM2_HDRFILE     382             /* Name of header storage file */
131 #define IM2_TITLE       638             /* Image name string */
132 
133 /* Codes from iraf/unix/hlib/iraf.h */
134 #define	TY_CHAR		2
135 #define	TY_SHORT	3
136 #define	TY_INT		4
137 #define	TY_LONG		5
138 #define	TY_REAL		6
139 #define	TY_DOUBLE	7
140 #define	TY_COMPLEX	8
141 #define TY_POINTER      9
142 #define TY_STRUCT       10
143 #define TY_USHORT       11
144 #define TY_UBYTE        12
145 
146 #define LEN_IRAFHDR	25000
147 #define LEN_PIXHDR	1024
148 #define LEN_FITSHDR	11520
149 
150 int check_immagic();
151 int irafgeti4();
152 float irafgetr4();
153 char *irafgetc2();
154 char *irafgetc();
155 char *iraf2str();
156 static char *same_path();
157 static void irafputr4();
158 static void irafputi4();
159 static void irafputc2();
160 static void irafputc();
161 static void str2iraf();
162 static int headswap=-1;	/* =1 to swap data bytes of foreign IRAF file */
163 static void irafswap();
164 static void irafswap2();
165 static void irafswap4();
166 static void irafswap8();
167 int head_version ();
168 int pix_version ();
169 int irafncmp ();
170 static int machswap();
171 static int irafsize();
172 
173 #define SECONDS_1970_TO_1980    315532800L
174 
175 /* Subroutine:	irafrhead
176  * Purpose:	Open and read the iraf .imh file, translating it to FITS, too.
177  * Returns:	NULL if failure, else pointer to IRAF .imh image header
178  * Notes:	The imhdr format is defined in iraf/lib/imhdr.h, some of
179  *		which defines or mimicked, above.
180  */
181 
182 char *
irafrhead(filename,lihead)183 irafrhead (filename, lihead)
184 
185 char	*filename;	/* Name of IRAF header file */
186 int	*lihead;	/* Length of IRAF image header in bytes (returned) */
187 {
188     FILE *fd;
189     int nbr;
190     char *irafheader;
191     int nbhead, nbytes;
192     int imhver;
193 
194     headswap = -1;
195     *lihead = 0;
196 
197     /* open the image header file */
198     fd = fopen (filename, "rb");
199     if (fd == NULL) {
200 	fprintf (stderr, "IRAFRHEAD:  cannot open file %s to read\n", filename);
201 	return (NULL);
202 	}
203 
204     /* Find size of image header file */
205     if ((nbhead = irafsize (fd)) <= 0) {
206 	fprintf (stderr, "IRAFRHEAD:  cannot read file %s, size = %d\n",
207 		 filename, nbhead);
208 	return (NULL);
209 	}
210 
211     /* allocate initial sized buffer */
212     nbytes = nbhead + 5000;
213     irafheader = (char *) calloc (nbytes/4, 4);
214     if (irafheader == NULL) {
215 	(void)fprintf(stderr, "IRAFRHEAD Cannot allocate %d-byte header\n",
216 		      nbytes);
217 	return (NULL);
218 	}
219     *lihead = nbytes;
220 
221     /* Read IRAF header */
222     nbr = fread (irafheader, 1, nbhead, fd);
223     fclose (fd);
224 
225     /* Reject if header less than minimum length */
226     if (nbr < LEN_PIXHDR) {
227 	(void)fprintf(stderr, "IRAFRHEAD header file %s: %d / %d bytes read.\n",
228 		      filename,nbr,LEN_PIXHDR);
229 	free (irafheader);
230 	return (NULL);
231 	}
232 
233     /* Check header magic word */
234     imhver = head_version (irafheader);
235     if (imhver < 1) {
236 	free (irafheader);
237 	(void)fprintf(stderr, "IRAFRHEAD: %s is not a valid IRAF image header\n",
238 		      filename);
239 	return(NULL);
240 	}
241 
242     /* check number of image dimensions
243     if (imhver == 2)
244 	ndim = irafgeti4 (irafheader, IM2_NDIM])
245     else
246 	ndim = irafgeti4 (irafheader, IM_NDIM])
247     if (ndim < 2) {
248 	free (irafheader);
249 	(void)fprintf(stderr, "File %s does not contain 2d image\n", filename);
250 	return (NULL);
251 	} */
252 
253     return (irafheader);
254 }
255 
256 
257 char *
irafrimage(fitsheader)258 irafrimage (fitsheader)
259 
260 char	*fitsheader;	/* FITS image header (filled) */
261 {
262     FILE *fd;
263     char *bang;
264     int naxis, naxis1, naxis2, naxis3, npaxis1, npaxis2,bitpix, bytepix, pixswap, i;
265     char *image;
266     int nbr, nbimage, nbaxis, nbl, nbdiff, lpname;
267     char *pixheader;
268     char *linebuff, *pixchar;
269     int imhver, lpixhead, len;
270     char pixname[SZ_IM2PIXFILE+1];
271     char newpixname[SZ_IM2HDRFILE+1];
272 
273     /* Convert pixel file name to character string */
274     hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname);
275 
276     /* Drop trailing spaces */
277     lpname = strlen (pixname);
278     pixchar = pixname + lpname - 1;
279     while (*pixchar == ' ')
280 	*pixchar = (char) 0;
281 
282     hgeti4 (fitsheader, "PIXOFF", &lpixhead);
283 
284     /* Open pixel file, ignoring machine name if present */
285     if ((bang = strchr (pixname, '!')) != NULL )
286 	fd = fopen (bang + 1, "rb");
287     else
288 	fd = fopen (pixname, "rb");
289 
290     /* If not at pathname in header, try same directory as header file */
291     if (!fd) {
292 	hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, newpixname);
293 	len = strlen (newpixname);
294 	newpixname[len-3] = 'p';
295 	newpixname[len-2] = 'i';
296 	newpixname[len-1] = 'x';
297 	fd = fopen (newpixname, "rb");
298 	}
299 
300     /* Print error message and exit if pixel file is not found */
301     if (!fd) {
302 	(void)fprintf(stderr,
303 	     "IRAFRIMAGE: Cannot open IRAF pixel file %s\n", pixname);
304 	return (NULL);
305 	}
306 
307     /* Read pixel header */
308     pixheader = (char *) calloc (lpixhead/4, 4);
309     if (pixheader == NULL) {
310 	(void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte pixel header\n",
311 		lpixhead);
312 	return (NULL);
313 	}
314     nbr = fread (pixheader, 1, lpixhead, fd);
315 
316     /* Check size of pixel header */
317     if (nbr < lpixhead) {
318 	(void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n",
319 		      pixname,nbr,LEN_PIXHDR);
320 	free (pixheader);
321 	fclose (fd);
322 	return (NULL);
323 	}
324 
325     /* check pixel header magic word */
326     imhver = pix_version (pixheader);
327     if (imhver < 1) {
328 	(void)fprintf(stderr, "File %s not valid IRAF pixel file.\n", pixname);
329 	free (pixheader);
330 	fclose (fd);
331 	return(NULL);
332 	}
333     free (pixheader);
334 
335     /* Find number of bytes to read */
336     hgeti4 (fitsheader,"NAXIS",&naxis);
337     hgeti4 (fitsheader,"NAXIS1",&naxis1);
338     hgeti4 (fitsheader,"NAXIS2",&naxis2);
339     hgeti4 (fitsheader,"NPAXIS1",&npaxis1);
340     hgeti4 (fitsheader,"NPAXIS2",&npaxis2);
341     hgeti4 (fitsheader,"BITPIX",&bitpix);
342     if (bitpix < 0)
343 	bytepix = -bitpix / 8;
344     else
345 	bytepix = bitpix / 8;
346 
347     /* If either dimension is one and image is 3-D, read all three dimensions */
348     if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) {
349 	hgeti4 (fitsheader,"NAXIS3",&naxis3);
350 	nbimage = naxis1 * naxis2 * naxis3 * bytepix;
351 	}
352     else {
353 	nbimage = naxis1 * naxis2 * bytepix;
354 	naxis3 = 1;
355 	}
356 
357     if (bytepix > 4)
358 	image =  (char *) calloc (nbimage/8, 8);
359     else if (bytepix > 2)
360 	image =  (char *) calloc (nbimage/4, 4);
361     else if (bytepix > 1)
362 	image =  (char *) calloc (nbimage/2, 2);
363     else
364 	image =  (char *) calloc (nbimage, 1);
365     if (image == NULL) {
366 	(void)fprintf(stderr, "IRAFRIMAGE Cannot allocate %d-byte image buffer\n",
367 		nbimage);
368 	return (NULL);
369 	}
370 
371     /* Read IRAF image all at once if physical and image dimensions are the same */
372     if (npaxis1 == naxis1)
373 	nbr = fread (image, 1, nbimage, fd);
374 
375     /* Read IRAF image one line at a time if physical and image dimensions differ */
376     else {
377 	nbdiff = (npaxis1 - naxis1) * bytepix;
378 	nbaxis = naxis1 * bytepix;
379 	linebuff = image;
380 	nbr = 0;
381 	if (naxis2 == 1 && naxis3 > 1)
382 	    naxis2 = naxis3;
383 	for (i = 0; i < naxis2; i++) {
384 	    nbl = fread (linebuff, 1, nbaxis, fd);
385 	    nbr = nbr + nbl;
386 	    (void) fseek (fd, nbdiff, SEEK_CUR);
387 	    linebuff = linebuff + nbaxis;
388 	    }
389 	}
390     fclose (fd);
391 
392     /* Check size of image */
393     if (nbr < nbimage) {
394 	(void)fprintf(stderr, "IRAF pixel file %s: %d / %d bytes read.\n",
395 		      pixname,nbr,nbimage);
396 	free (image);
397 	return (NULL);
398 	}
399 
400     /* Byte-reverse image, if necessary */
401     pixswap = 0;
402     hgetl (fitsheader, "PIXSWAP", &pixswap);
403     if (pixswap)
404 	irafswap (bitpix, image, nbimage);
405 
406     return (image);
407 }
408 
409 
410 /* Return IRAF image format version number from magic word in IRAF header*/
411 
412 int
head_version(irafheader)413 head_version (irafheader)
414 
415 char	*irafheader;	/* IRAF image header from file */
416 
417 {
418 
419     /* Check header file magic word */
420     if (irafncmp (irafheader, "imhdr", 5) != 0 ) {
421 	if (strncmp (irafheader, "imhv2", 5) != 0)
422 	    return (0);
423 	else
424 	    return (2);
425 	}
426     else
427 	return (1);
428 }
429 
430 
431 /* Return IRAF image format version number from magic word in IRAF pixel file */
432 
433 int
pix_version(irafheader)434 pix_version (irafheader)
435 
436 char	*irafheader;	/* IRAF image header from file */
437 
438 {
439 
440     /* Check pixel file header magic word */
441     if (irafncmp (irafheader, "impix", 5) != 0) {
442 	if (strncmp (irafheader, "impv2", 5) != 0)
443 	    return (0);
444 	else
445 	    return (2);
446 	}
447     else
448 	return (1);
449 }
450 
451 
452 /* Verify that file is valid IRAF imhdr or impix by checking first 5 chars
453  * Returns:	0 on success, 1 on failure */
454 
455 int
irafncmp(irafheader,teststring,nc)456 irafncmp (irafheader, teststring, nc)
457 
458 char	*irafheader;	/* IRAF image header from file */
459 char	*teststring;	/* C character string to compare */
460 int	nc;		/* Number of characters to compate */
461 
462 {
463     char *line;
464 
465     headswap = -1;
466     if ((line = iraf2str (irafheader, nc)) == NULL)
467 	return (1);
468     if (strncmp (line, teststring, nc) == 0) {
469 	free (line);
470 	return (0);
471 	}
472     else {
473 	free (line);
474 	return (1);
475 	}
476 }
477 
478 /* Convert IRAF image header to FITS image header, returning FITS header */
479 
480 char *
iraf2fits(hdrname,irafheader,nbiraf,nbfits)481 iraf2fits (hdrname, irafheader, nbiraf, nbfits)
482 
483 char	*hdrname;	/* IRAF header file name (may be path) */
484 char	*irafheader;	/* IRAF image header */
485 int	nbiraf;		/* Number of bytes in IRAF header */
486 int	*nbfits;	/* Number of bytes in FITS header (returned) */
487 
488 {
489     char *objname;	/* object name from FITS file */
490     int lstr, i, j, k, ib, nax, nbits, nl;
491     int lname = 0;
492     char *pixname, *newpixname, *bang, *chead;
493     char *fitsheader;
494     int nblock, nlines;
495     char *fhead, *fhead1, *fp, endline[81];
496     char irafchar;
497     char fitsline[81];
498     char *dstring;
499     int pixtype;
500     int imhver, n, imu, pixoff, impixoff, immax, immin, imtime;
501     int imndim, imlen, imphyslen, impixtype, pixswap, hpixswap, mtime;
502     float rmax, rmin;
503 
504     headswap = -1;
505 
506     /* Set up last line of FITS header */
507     (void)strncpy (endline,"END", 3);
508     for (i = 3; i < 80; i++)
509 	endline[i] = ' ';
510     endline[80] = 0;
511 
512     /* Check header magic word */
513     imhver = head_version (irafheader);
514     if (imhver < 1) {
515 	(void)fprintf(stderr, "File %s not valid IRAF image header\n",
516 		      hdrname);
517 	return(NULL);
518 	}
519     if (imhver == 2) {
520 	nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81);
521 	imndim = IM2_NDIM;
522 	imlen = IM2_LEN;
523 	imphyslen = IM2_PHYSLEN;
524 	impixtype = IM2_PIXTYPE;
525 	impixoff = IM2_PIXOFF;
526 	imtime = IM2_MTIME;
527 	immax = IM2_MAX;
528 	immin = IM2_MIN;
529 	}
530     else {
531 	nlines = 24 + ((nbiraf - LEN_IMHDR) / 162);
532 	imndim = IM_NDIM;
533 	imlen = IM_LEN;
534 	imphyslen = IM_PHYSLEN;
535 	impixtype = IM_PIXTYPE;
536 	impixoff = IM_PIXOFF;
537 	imtime = IM_MTIME;
538 	immax = IM_MAX;
539 	immin = IM_MIN;
540 	}
541 
542     /*  Initialize FITS header */
543     nblock = (nlines * 80) / 2880;
544     *nbfits = (nblock + 5) * 2880 + 4;
545     fitsheader = (char *) calloc (*nbfits, 1);
546     if (fitsheader == NULL) {
547 	(void)fprintf(stderr, "IRAF2FITS Cannot allocate %d-byte FITS header\n",
548 		*nbfits);
549 	return (NULL);
550 	}
551     hlength (fitsheader, *nbfits);
552     fhead = fitsheader;
553     (void)strncpy (fitsheader, endline, 80);
554     hputl (fitsheader, "SIMPLE", 1);
555     fhead = fhead + 80;
556 
557     /*  Set pixel size in FITS header */
558     pixtype = irafgeti4 (irafheader, impixtype);
559     switch (pixtype) {
560 	case TY_CHAR:
561 	    nbits = 8;
562 	    break;
563 	case TY_UBYTE:
564 	    nbits = 8;
565 	    break;
566 	case TY_SHORT:
567 	    nbits = 16;
568 	    break;
569 	case TY_USHORT:
570 	    nbits = -16;
571 	    break;
572 	case TY_INT:
573 	case TY_LONG:
574 	    nbits = 32;
575 	    break;
576 	case TY_REAL:
577 	    nbits = -32;
578 	    break;
579 	case TY_DOUBLE:
580 	    nbits = -64;
581 	    break;
582 	default:
583 	    (void)fprintf(stderr,"Unsupported data type: %d\n", pixtype);
584 	    return (NULL);
585 	}
586     hputi4 (fitsheader,"BITPIX",nbits);
587     hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type");
588     fhead = fhead + 80;
589 
590     /*  Set image dimensions in FITS header */
591     nax = irafgeti4 (irafheader, imndim);
592     hputi4 (fitsheader,"NAXIS",nax);
593     hputcom (fitsheader,"NAXIS", "IRAF .imh naxis");
594     fhead = fhead + 80;
595 
596     n = irafgeti4 (irafheader, imlen);
597     hputi4 (fitsheader, "NAXIS1", n);
598     hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]");
599     fhead = fhead + 80;
600 
601     if (nax > 1) {
602 	n = irafgeti4 (irafheader, imlen+4);
603 	hputi4 (fitsheader, "NAXIS2", n);
604 	hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]");
605 	}
606     else
607 	hputi4 (fitsheader, "NAXIS2", 1);
608 	hputcom (fitsheader,"NAXIS2", "IRAF .imh naxis[2]");
609     fhead = fhead + 80;
610 
611     if (nax > 2) {
612 	n = irafgeti4 (irafheader, imlen+8);
613 	hputi4 (fitsheader, "NAXIS3", n);
614 	hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]");
615 	fhead = fhead + 80;
616 	}
617     if (nax > 3) {
618 	n = irafgeti4 (irafheader, imlen+12);
619 	hputi4 (fitsheader, "NAXIS4", n);
620 	hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]");
621 	fhead = fhead + 80;
622 	}
623 
624     /* Set object name in FITS header */
625     if (imhver == 2)
626 	objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE);
627     else
628 	objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE);
629     if ((lstr = strlen (objname)) < 8) {
630 	for (i = lstr; i < 8; i++)
631 	    objname[i] = ' ';
632 	objname[8] = 0;
633 	}
634     hputs (fitsheader,"OBJECT",objname);
635     hputcom (fitsheader,"OBJECT", "IRAF .imh title");
636     free (objname);
637     fhead = fhead + 80;
638 
639     /* Save physical axis lengths so image file can be read */
640     n = irafgeti4 (irafheader, imphyslen);
641     hputi4 (fitsheader, "NPAXIS1", n);
642     hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]");
643     fhead = fhead + 80;
644     if (nax > 1) {
645 	n = irafgeti4 (irafheader, imphyslen+4);
646 	hputi4 (fitsheader, "NPAXIS2", n);
647 	hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]");
648 	fhead = fhead + 80;
649 	}
650     if (nax > 2) {
651 	n = irafgeti4 (irafheader, imphyslen+8);
652 	hputi4 (fitsheader, "NPAXIS3", n);
653 	hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]");
654 	fhead = fhead + 80;
655 	}
656     if (nax > 3) {
657 	n = irafgeti4 (irafheader, imphyslen+12);
658 	hputi4 (fitsheader, "NPAXIS4", n);
659 	hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]");
660 	fhead = fhead + 80;
661 	}
662 
663     /* Save image minimum and maximum in header */
664     rmax = irafgetr4 (irafheader, immax);
665     rmin = irafgetr4 (irafheader, immin);
666     if (rmin != rmax) {
667 	hputr4 (fitsheader, "IRAFMIN", &rmin);
668 	fhead = fhead + 80;
669 	hputcom (fitsheader,"IRAFMIN", "IRAF .imh minimum");
670 	hputr4 (fitsheader, "IRAFMAX", &rmax);
671 	hputcom (fitsheader,"IRAFMAX", "IRAF .imh maximum");
672 	fhead = fhead + 80;
673 	}
674 
675     /* Save image header filename in header */
676     nl = hputm (fitsheader,"IMHFIL",hdrname);
677     if (nl > 0) {
678 	lname = strlen (hdrname);
679 	strcpy (fitsline, "IRAF header file name");
680 	if (lname < 43)
681 	    hputcom (fitsheader,"IMHFIL_1", fitsline);
682 	else if (lname > 67 && lname < 110)
683 	    hputcom (fitsheader,"IMHFIL_2", fitsline);
684 	else if (lname > 134 && lname < 177)
685 	    hputcom (fitsheader,"IMHFIL_3", fitsline);
686 	}
687     if (nl > 0) fhead = fhead + (nl * 80);
688 
689     /* Save image pixel file pathname in header */
690     if (imhver == 2)
691 	pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
692     else
693 	pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE);
694     if (strncmp(pixname, "HDR", 3) == 0 ) {
695 	newpixname = same_path (pixname, hdrname);
696 	free (pixname);
697 	pixname = newpixname;
698 	}
699     if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) {
700 	newpixname = same_path (pixname, hdrname);
701 	free (pixname);
702 	pixname = newpixname;
703 	}
704 
705     if ((bang = strchr (pixname, '!')) != NULL )
706 	nl = hputm (fitsheader,"PIXFIL",bang+1);
707     else
708 	nl = hputm (fitsheader,"PIXFIL",pixname);
709     free (pixname);
710     if (nl > 0) {
711 	strcpy (fitsline, "IRAF .pix pixel file");
712 	if (lname < 43)
713 	    hputcom (fitsheader,"PIXFIL_1", fitsline);
714 	else if (lname > 67 && lname < 110)
715 	    hputcom (fitsheader,"PIXFIL_2", fitsline);
716 	else if (lname > 134 && lname < 177)
717 	    hputcom (fitsheader,"PIXFIL_3", fitsline);
718 	}
719     if (nl > 0) fhead = fhead + (nl * 80);
720 
721     /* Save image offset from star of pixel file */
722     pixoff = irafgeti4 (irafheader, impixoff);
723     pixoff = (pixoff - 1) * 2;
724     hputi4 (fitsheader, "PIXOFF", pixoff);
725     hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)");
726     fhead = fhead + 80;
727 
728     /* Save IRAF file format version in header */
729     hputi4 (fitsheader,"IMHVER",imhver);
730     hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)");
731     fhead = fhead + 80;
732 
733     /* Set flag if header numbers are byte-reversed on this machine */
734     if (machswap() != headswap)
735 	hputl (fitsheader, "HEADSWAP", 1);
736     else
737 	hputl (fitsheader, "HEADSWAP", 0);
738     hputcom (fitsheader,"HEADSWAP", "IRAF header, FITS byte orders differ if T");
739     fhead = fhead + 80;
740 
741     /* Set flag if image pixels are byte-reversed on this machine */
742     if (imhver == 2) {
743 	hpixswap = irafgeti4 (irafheader, IM2_SWAPPED);
744 	if (headswap && !hpixswap)
745 	    pixswap = 1;
746 	else if (!headswap && hpixswap)
747 	    pixswap = 1;
748 	else
749 	    pixswap = 0;
750 	}
751     else
752 	pixswap = headswap;
753     if (machswap() != pixswap)
754 	hputl (fitsheader, "PIXSWAP", 1);
755     else
756 	hputl (fitsheader, "PIXSWAP", 0);
757     hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T");
758     fhead = fhead + 80;
759 
760     /* Read modification time */
761     mtime = irafgeti4 (irafheader, imtime);
762     if (mtime == 0)
763 	dstring = lt2fd ();
764     else
765 	dstring = tsi2fd (mtime);
766     hputs (fitsheader, "DATE-MOD", dstring);
767     hputcom (fitsheader,"DATE-MOD", "Date of latest file modification");
768     free (dstring);
769     fhead = fhead + 80;
770 
771     /* Add user portion of IRAF header to FITS header */
772     fitsline[80] = 0;
773     if (imhver == 2) {
774 	imu = LEN_IM2HDR;
775 	chead = irafheader;
776 	j = 0;
777 	for (k = 0; k < 80; k++)
778 	    fitsline[k] = ' ';
779 	for (i = imu; i < nbiraf; i++) {
780 	    irafchar = chead[i];
781 	    if (irafchar == 0)
782 		break;
783 	    else if (irafchar == 10) {
784 		(void)strncpy (fhead, fitsline, 80);
785 		/* fprintf (stderr,"%80s\n",fitsline); */
786 		if (strncmp (fitsline, "OBJECT ", 7) != 0) {
787 		    fhead = fhead + 80;
788 		    }
789 		for (k = 0; k < 80; k++)
790 		    fitsline[k] = ' ';
791 		j = 0;
792 		}
793 	    else {
794 		if (j > 80) {
795 		    if (strncmp (fitsline, "OBJECT ", 7) != 0) {
796 			(void)strncpy (fhead, fitsline, 80);
797 			/* fprintf (stderr,"%80s\n",fitsline); */
798 			j = 9;
799 			fhead = fhead + 80;
800 			}
801 		    for (k = 0; k < 80; k++)
802 			fitsline[k] = ' ';
803 		    }
804 		if (irafchar > 32 && irafchar < 127)
805 		    fitsline[j] = irafchar;
806 		j++;
807 		}
808 	    }
809 	}
810     else {
811 	imu = LEN_IMHDR;
812 	chead = irafheader;
813 	if (headswap == 1)
814 	    ib = 0;
815 	else
816 	    ib = 1;
817 	for (k = 0; k < 80; k++)
818 	    fitsline[k] = ' ';
819 	j = 0;
820 	for (i = imu; i < nbiraf; i=i+2) {
821 	    irafchar = chead[i+ib];
822 	    if (irafchar == 0)
823 		break;
824 	    else if (irafchar == 10) {
825 		if (strncmp (fitsline, "OBJECT ", 7) != 0) {
826 		    (void)strncpy (fhead, fitsline, 80);
827 		    fhead = fhead + 80;
828 		    }
829 		/* fprintf (stderr,"%80s\n",fitsline); */
830 		j = 0;
831 		for (k = 0; k < 80; k++)
832 		    fitsline[k] = ' ';
833 		}
834 	    else {
835 		if (j > 80) {
836 		    if (strncmp (fitsline, "OBJECT ", 7) != 0) {
837 			(void)strncpy (fhead, fitsline, 80);
838 			j = 9;
839 			fhead = fhead + 80;
840 			}
841 		    /* fprintf (stderr,"%80s\n",fitsline); */
842 		    for (k = 0; k < 80; k++)
843 			fitsline[k] = ' ';
844 		    }
845 		if (irafchar > 32 && irafchar < 127)
846 		    fitsline[j] = irafchar;
847 		j++;
848 		}
849 	    }
850 	}
851 
852     /* Add END to last line */
853     (void)strncpy (fhead, endline, 80);
854 
855     /* Find end of last 2880-byte block of header */
856     fhead = ksearch (fitsheader, "END") + 80;
857     nblock = *nbfits / 2880;
858     fhead1 = fitsheader + (nblock * 2880);
859 
860     /* Pad rest of header with spaces */
861     strncpy (endline,"   ",3);
862     for (fp = fhead; fp < fhead1; fp = fp + 80) {
863 	(void)strncpy (fp, endline,80);
864 	}
865 
866     return (fitsheader);
867 }
868 
869 
870 int
irafwhead(hdrname,lhead,irafheader,fitsheader)871 irafwhead (hdrname, lhead, irafheader, fitsheader)
872 
873 char	*hdrname;	/* Name of IRAF header file */
874 int	lhead;		/* Length of IRAF header */
875 char	*irafheader;	/* IRAF header */
876 char	*fitsheader;	/* FITS image header */
877 
878 {
879     int fd;
880     int nbw, nbhead, lphead, pixswap;
881 
882    /* Get rid of redundant header information */
883     hgeti4 (fitsheader, "PIXOFF", &lphead);
884     hgeti4 (fitsheader, "PIXSWAP", &pixswap);
885 
886     /* Write IRAF header file */
887 
888     /* Convert FITS header to IRAF header */
889     irafheader = fits2iraf (fitsheader, irafheader, lhead, &nbhead);
890     if (irafheader == NULL) {
891 	fprintf (stderr, "IRAFWIMAGE:  file %s header error\n", hdrname);
892 	return (-1);
893 	}
894 
895     /* Open the output file */
896     if (!access (hdrname, 0)) {
897 	fd = open (hdrname, O_WRONLY);
898 	if (fd < 3) {
899 	    fprintf (stderr, "IRAFWIMAGE:  file %s not writeable\n", hdrname);
900 	    return (0);
901 	    }
902 	}
903     else {
904 	fd = open (hdrname, O_RDWR+O_CREAT, 0666);
905 	if (fd < 3) {
906 	    fprintf (stderr, "IRAFWIMAGE:  cannot create file %s\n", hdrname);
907 	    return (0);
908 	    }
909 	}
910 
911     /* Write IRAF header to disk file */
912     nbw = write (fd, irafheader, nbhead);
913     (void) ftruncate (fd, nbhead);
914     close (fd);
915     if (nbw < nbhead) {
916 	(void)fprintf(stderr, "IRAF header file %s: %d / %d bytes written.\n",
917 		      hdrname, nbw, nbhead);
918 	return (-1);
919 	}
920 
921     return (nbw);
922 }
923 
924 /* IRAFWIMAGE -- write IRAF .imh header file and .pix image file
925  * No matter what the input, this always writes in the local byte order */
926 
927 int
irafwimage(hdrname,lhead,irafheader,fitsheader,image)928 irafwimage (hdrname, lhead, irafheader, fitsheader, image )
929 
930 char	*hdrname;	/* Name of IRAF header file */
931 int	lhead;		/* Length of IRAF header */
932 char	*irafheader;	/* IRAF header */
933 char	*fitsheader;	/* FITS image header */
934 char	*image;		/* IRAF image */
935 
936 {
937     int fd;
938     char *bang;
939     int nbw, bytepix, bitpix, naxis, naxis1, naxis2, nbimage, lphead;
940     char *pixn, *newpixname;
941     char pixname[SZ_IM2PIXFILE+1];
942     int imhver, pixswap;
943 
944     hgeti4 (fitsheader, "IMHVER", &imhver);
945 
946     if (!hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixname)) {
947 	if (imhver == 2)
948 	    pixn = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
949 	else
950 	    pixn = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE);
951 	if (strncmp(pixn, "HDR", 3) == 0 ) {
952 	    newpixname = same_path (pixn, hdrname);
953 	    strcpy (pixname, newpixname);
954 	    free (newpixname);
955 	    }
956 	else {
957 	    if ((bang = strchr (pixn, '!')) != NULL )
958 		strcpy (pixname, bang+1);
959 	    else
960 		strcpy (pixname, pixn);
961 	    }
962 	free (pixn);
963         }
964 
965     /* Find number of bytes to write */
966     hgeti4 (fitsheader,"NAXIS",&naxis);
967     hgeti4 (fitsheader,"NAXIS1",&naxis1);
968     hgeti4 (fitsheader,"NAXIS2",&naxis2);
969     hgeti4 (fitsheader,"BITPIX",&bitpix);
970     if (bitpix < 0)
971 	bytepix = -bitpix / 8;
972     else
973 	bytepix = bitpix / 8;
974 
975     /* If either dimension is one and image is 3-D, read all three dimensions */
976     if (naxis == 3 && ((naxis1 == 1) | (naxis2 == 1))) {
977 	int naxis3;
978 	hgeti4 (fitsheader,"NAXIS3",&naxis3);
979 	nbimage = naxis1 * naxis2 * naxis3 * bytepix;
980 	}
981     else
982 	nbimage = naxis1 * naxis2 * bytepix;
983 
984    /* Read information about pixel file from header */
985     hgeti4 (fitsheader, "PIXOFF", &lphead);
986     hgeti4 (fitsheader, "PIXSWAP", &pixswap);
987 
988     /* Write IRAF header file */
989     if (irafwhead (hdrname, lhead, irafheader, fitsheader))
990         return (0);
991 
992     /* Open the output file */
993     if (!access (pixname, 0)) {
994 	fd = open (pixname, O_WRONLY);
995 	if (fd < 3) {
996 	    fprintf (stderr, "IRAFWIMAGE:  file %s not writeable\n", pixname);
997 	    return (0);
998 	    }
999 	}
1000     else {
1001 	fd = open (pixname, O_RDWR+O_CREAT, 0666);
1002 	if (fd < 3) {
1003 	    fprintf (stderr, "IRAFWIMAGE:  cannot create file %s\n", pixname);
1004 	    return (0);
1005 	    }
1006 	}
1007 
1008     /* Write header to IRAF pixel file */
1009     if (imhver == 2)
1010 	irafputc ("impv2", irafheader, 0, 5);
1011     else
1012 	irafputc2 ("impix", irafheader, 0, 5);
1013     nbw = write (fd, irafheader, lphead);
1014 
1015     /* Byte-reverse image, if necessary */
1016     if (pixswap)
1017 	irafswap (bitpix, image, nbimage);
1018 
1019     /* Write data to IRAF pixel file */
1020     nbw = write (fd, image, nbimage);
1021     close (fd);
1022 
1023     return (nbw);
1024 }
1025 
1026 
1027 /* Put filename and header path together */
1028 
1029 static char *
same_path(pixname,hdrname)1030 same_path (pixname, hdrname)
1031 
1032 char	*pixname;	/* IRAF pixel file pathname */
1033 char	*hdrname;	/* IRAF image header file pathname */
1034 
1035 {
1036     int len, plen;
1037     char *newpixname;
1038 
1039     newpixname = (char *) calloc (SZ_IM2PIXFILE, 1);
1040 
1041     /* Pixel file is in same directory as header */
1042     if (strncmp(pixname, "HDR$", 4) == 0 ) {
1043 	(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
1044 
1045 	/* find the end of the pathname */
1046 	len = strlen (newpixname);
1047 #ifndef VMS
1048 	while( (len > 0) && (newpixname[len-1] != '/') )
1049 #else
1050 	while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') )
1051 #endif
1052 	    len--;
1053 
1054 	/* add name */
1055 	newpixname[len] = '\0';
1056 	plen = strlen (pixname) - 4;
1057 	if (len + plen > SZ_IM2PIXFILE)
1058 	    (void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE - len);
1059 	else
1060 	    (void)strncat (newpixname, &pixname[4], plen);
1061 	}
1062 
1063     /* Bare pixel file with no path is assumed to be same as HDR$filename */
1064     else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) {
1065 	(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
1066 
1067 	/* find the end of the pathname */
1068 	len = strlen (newpixname);
1069 #ifndef VMS
1070 	while( (len > 0) && (newpixname[len-1] != '/') )
1071 #else
1072 	while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') )
1073 #endif
1074 	    len--;
1075 
1076 	/* add name */
1077 	newpixname[len] = '\0';
1078 	(void)strncat (newpixname, pixname, SZ_IM2PIXFILE);
1079 	}
1080 
1081     /* Pixel file has same name as header file, but with .pix extension */
1082     else if (strncmp (pixname, "HDR", 3) == 0) {
1083 
1084 	/* load entire header name string into name buffer */
1085 	(void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE);
1086 	len = strlen (newpixname);
1087 	newpixname[len-3] = 'p';
1088 	newpixname[len-2] = 'i';
1089 	newpixname[len-1] = 'x';
1090 	}
1091 
1092     return (newpixname);
1093 }
1094 
1095 /* Convert FITS image header to IRAF image header, returning IRAF header */
1096 /* No matter what the input, this always writes in the local byte order */
1097 
1098 char *
fits2iraf(fitsheader,irafheader,nbhead,nbiraf)1099 fits2iraf (fitsheader, irafheader, nbhead, nbiraf)
1100 
1101 char	*fitsheader;	/* FITS image header */
1102 char	*irafheader;	/* IRAF image header (returned updated) */
1103 int	nbhead;		/* Length of IRAF header */
1104 int	*nbiraf;	/* Length of returned IRAF header */
1105 
1106 {
1107     int i, n, pixoff, lhdrdir;
1108     short *irafp, *irafs, *irafu;
1109     char *iraf2u, *iraf2p, *filename, *hdrdir;
1110     char *fitsend, *fitsp, pixfile[SZ_IM2PIXFILE], hdrfile[SZ_IM2HDRFILE];
1111     char title[SZ_IM2TITLE], temp[80];
1112     int	nax, nlfits, imhver, nbits, pixtype, hdrlength, mtime;
1113     int imndim, imlen, imphyslen, impixtype, imhlen, imtime, immax, immin;
1114     float rmax, rmin;
1115 
1116     hgeti4 (fitsheader, "IMHVER", &imhver);
1117     hdel (fitsheader, "IMHVER");
1118     hdel (fitsheader, "IMHVER");
1119     hgetl (fitsheader, "HEADSWAP", &headswap);
1120     hdel (fitsheader, "HEADSWAP");
1121     hdel (fitsheader, "HEADSWAP");
1122     if (imhver == 2) {
1123 	imhlen = IM2_HDRLEN;
1124 	imndim = IM2_NDIM;
1125 	imlen = IM2_LEN;
1126 	imtime = IM2_MTIME;
1127 	imphyslen = IM2_PHYSLEN;
1128 	impixtype = IM2_PIXTYPE;
1129 	immax = IM2_MAX;
1130 	immin = IM2_MIN;
1131 	}
1132     else {
1133 	imhlen = IM_HDRLEN;
1134 	imndim = IM_NDIM;
1135 	imlen = IM_LEN;
1136 	imtime = IM_MTIME;
1137 	imphyslen = IM_PHYSLEN;
1138 	impixtype = IM_PIXTYPE;
1139 	immax = IM_MAX;
1140 	immin = IM_MIN;
1141 	}
1142 
1143     /* Delete FITS header keyword not needed by IRAF */
1144     hdel (fitsheader,"SIMPLE");
1145 
1146     /* Set IRAF image data type */
1147     hgeti4 (fitsheader,"BITPIX", &nbits);
1148     switch (nbits) {
1149 	case 8:
1150 	    pixtype = TY_CHAR;
1151 	    break;
1152 	case -8:
1153 	    pixtype = TY_UBYTE;
1154 	    break;
1155 	case 16:
1156 	    pixtype = TY_SHORT;
1157 	    break;
1158 	case -16:
1159 	    pixtype = TY_USHORT;
1160 	    break;
1161 	case 32:
1162 	    pixtype = TY_INT;
1163 	    break;
1164 	case -32:
1165 	    pixtype = TY_REAL;
1166 	    break;
1167 	case -64:
1168 	    pixtype = TY_DOUBLE;
1169 	    break;
1170 	default:
1171 	    (void)fprintf(stderr,"Unsupported data type: %d\n", nbits);
1172 	    return (NULL);
1173 	}
1174     irafputi4 (irafheader, impixtype, pixtype);
1175     hdel (fitsheader,"BITPIX");
1176 
1177     /* Set IRAF image dimensions */
1178     hgeti4 (fitsheader,"NAXIS",&nax);
1179     irafputi4 (irafheader, imndim, nax);
1180     hdel (fitsheader,"NAXIS");
1181 
1182     hgeti4 (fitsheader, "NAXIS1", &n);
1183     irafputi4 (irafheader, imlen, n);
1184     irafputi4 (irafheader, imphyslen, n);
1185     hdel (fitsheader,"NAXIS1");
1186 
1187     hgeti4 (fitsheader,"NAXIS2",&n);
1188     irafputi4 (irafheader, imlen+4, n);
1189     irafputi4 (irafheader, imphyslen+4, n);
1190     hdel (fitsheader,"NAXIS2");
1191 
1192     if (nax > 2) {
1193 	hgeti4 (fitsheader,"NAXIS3",&n);
1194 	irafputi4 (irafheader, imlen+8, n);
1195 	irafputi4 (irafheader, imphyslen+8, n);
1196 	hdel (fitsheader,"NAXIS3");
1197 	}
1198 
1199     if (nax > 3) {
1200 	hgeti4 (fitsheader,"NAXIS4",&n);
1201 	irafputi4 (irafheader, imlen+12, n);
1202 	irafputi4 (irafheader, imphyslen+12, n);
1203 	hdel (fitsheader,"NAXIS4");
1204 	}
1205 
1206     /* Set image pixel value limits */
1207     rmin = 0.0;
1208     hgetr4 (fitsheader, "IRAFMIN", &rmin);
1209     rmax = 0.0;
1210     hgetr4 (fitsheader, "IRAFMAX", &rmax);
1211     if (rmin != rmax) {
1212 	irafputr4 (irafheader, immax, rmax);
1213 	irafputr4 (irafheader, immin, rmin);
1214 	}
1215     hdel (fitsheader, "IRAFMIN");
1216     hdel (fitsheader, "IRAFMAX");
1217 
1218     /* Replace pixel file name, if it is in the FITS header */
1219     if (hgetm (fitsheader, "PIXFIL", SZ_IM2PIXFILE, pixfile)) {
1220 	if (strchr (pixfile, '/')) {
1221 	    if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, hdrfile)) {
1222 		hdrdir = strrchr (hdrfile, '/');
1223 		if (hdrdir != NULL) {
1224 		    lhdrdir = hdrdir - hdrfile + 1;
1225 		    if (!strncmp (pixfile, hdrfile, lhdrdir)) {
1226 			filename = pixfile + lhdrdir;
1227 			strcpy (temp, "HDR$");
1228 			strcat (temp,filename);
1229 			strcpy (pixfile, temp);
1230 			}
1231 		    }
1232 		if (pixfile[0] != '/' && pixfile[0] != 'H') {
1233 		    strcpy (temp, "HDR$");
1234 		    strcat (temp,pixfile);
1235 		    strcpy (pixfile, temp);
1236 		    }
1237 		}
1238 	    }
1239 
1240 	if (imhver == 2)
1241             irafputc (pixfile, irafheader, IM2_PIXFILE, SZ_IM2PIXFILE);
1242 	else
1243             irafputc2 (pixfile, irafheader, IM_PIXFILE, SZ_IMPIXFILE);
1244 	hdel (fitsheader,"PIXFIL_1");
1245 	hdel (fitsheader,"PIXFIL_2");
1246 	hdel (fitsheader,"PIXFIL_3");
1247 	hdel (fitsheader,"PIXFIL_4");
1248 	}
1249 
1250     /* Replace header file name, if it is in the FITS header */
1251     if (hgetm (fitsheader, "IMHFIL", SZ_IM2HDRFILE, pixfile)) {
1252 	if (!strchr (pixfile,'/') && !strchr (pixfile,'$')) {
1253 	    strcpy (temp, "HDR$");
1254 	    strcat (temp,pixfile);
1255 	    strcpy (pixfile, temp);
1256 	    }
1257 	if (imhver == 2)
1258             irafputc (pixfile, irafheader, IM2_HDRFILE, SZ_IM2HDRFILE);
1259 	else
1260             irafputc2 (pixfile, irafheader, IM_HDRFILE, SZ_IMHDRFILE);
1261 	hdel (fitsheader, "IMHFIL_1");
1262 	hdel (fitsheader, "IMHFIL_2");
1263 	hdel (fitsheader, "IMHFIL_3");
1264 	hdel (fitsheader, "IMHFIL_4");
1265 	}
1266 
1267     /* Replace image title, if it is in the FITS header */
1268     if (hgets (fitsheader, "OBJECT", SZ_IM2TITLE, title)) {
1269 	if (imhver == 2)
1270             irafputc (title, irafheader, IM2_TITLE, SZ_IM2TITLE);
1271 	else
1272             irafputc2 (title, irafheader, IM_TITLE, SZ_IMTITLE);
1273 	hdel (fitsheader, "OBJECT");
1274 	}
1275     hgeti4 (fitsheader, "PIXOFF", &pixoff);
1276     hdel (fitsheader, "PIXOFF");
1277     hdel (fitsheader, "PIXOFF");
1278     hdel (fitsheader, "PIXSWAP");
1279     hdel (fitsheader, "PIXSWAP");
1280     hdel (fitsheader, "DATE-MOD");
1281     hdel (fitsheader, "DATE-MOD");
1282     fitsend = ksearch (fitsheader,"END");
1283 
1284     /* Find length of FITS header */
1285     fitsend = ksearch (fitsheader,"END");
1286     nlfits = ((fitsend - fitsheader) / 80);
1287 
1288     /* Find new length of IRAF header */
1289     if (imhver == 2)
1290 	*nbiraf = LEN_IM2HDR + (81 * nlfits);
1291     else
1292 	*nbiraf = LEN_IMHDR + (162 * nlfits);
1293     if (*nbiraf > nbhead)
1294 	irafheader = realloc (irafheader, *nbiraf);
1295 
1296     /* Reset modification time */
1297     mtime = lt2tsi ();
1298     irafputi4 (irafheader, imtime, mtime);
1299 
1300     /*  Replace user portion of IRAF header with remaining FITS header */
1301     if (imhver == 2) {
1302 	iraf2u = irafheader + LEN_IM2HDR;
1303 	iraf2p = iraf2u;
1304 	for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) {
1305 	    for (i = 0; i < 80; i++)
1306 		*iraf2p++ = fitsp[i];
1307 	    *iraf2p++ = 10;
1308 	    }
1309 	*iraf2p++ = 0;
1310 	*nbiraf = iraf2p - irafheader;
1311 	hdrlength = 1 + *nbiraf / 2;
1312 	}
1313     else {
1314 	irafs = (short *)irafheader;
1315 	irafu = irafs + (LEN_IMHDR / 2);
1316 	irafp = irafu;
1317 	for (fitsp = fitsheader; fitsp < fitsend; fitsp = fitsp + 80) {
1318 	    for (i = 0; i < 80; i++)
1319 		*irafp++ = (short) fitsp[i];
1320 	    *irafp++ = 10;
1321 	    }
1322 	*irafp++ = 0;
1323 	*irafp++ = 32;
1324 	*nbiraf = 2 * (irafp - irafs);
1325 	hdrlength = *nbiraf / 4;
1326 	}
1327 
1328     /* Length of header file */
1329     irafputi4 (irafheader, imhlen, hdrlength);
1330 
1331     /* Offset in .pix file to first pixel data
1332     hputi4 (fitsheader, "PIXOFF", pixoff); */
1333 
1334     /* Return number of bytes in new IRAF header */
1335     return (irafheader);
1336 }
1337 
1338 
1339 int
irafgeti4(irafheader,offset)1340 irafgeti4 (irafheader, offset)
1341 
1342 char	*irafheader;	/* IRAF image header */
1343 int	offset;		/* Number of bytes to skip before number */
1344 
1345 {
1346     char *ctemp, *cheader;
1347     int  temp;
1348 
1349     cheader = irafheader;
1350     ctemp = (char *) &temp;
1351 
1352     /* If header swap flag not set, set it now */
1353     if (headswap < 0) {
1354 	if (cheader[offset] > 0)
1355 	    headswap = 1;
1356 	else
1357 	    headswap = 0;
1358 	}
1359 
1360     if (machswap() != headswap) {
1361 	ctemp[3] = cheader[offset];
1362 	ctemp[2] = cheader[offset+1];
1363 	ctemp[1] = cheader[offset+2];
1364 	ctemp[0] = cheader[offset+3];
1365 	}
1366     else {
1367 	ctemp[0] = cheader[offset];
1368 	ctemp[1] = cheader[offset+1];
1369 	ctemp[2] = cheader[offset+2];
1370 	ctemp[3] = cheader[offset+3];
1371 	}
1372     return (temp);
1373 }
1374 
1375 
1376 float
irafgetr4(irafheader,offset)1377 irafgetr4 (irafheader, offset)
1378 
1379 char	*irafheader;	/* IRAF image header */
1380 int	offset;		/* Number of bytes to skip before number */
1381 
1382 {
1383     char *ctemp, *cheader;
1384     float  temp;
1385 
1386     cheader = irafheader;
1387     ctemp = (char *) &temp;
1388 
1389     /* If header swap flag not set, set it now */
1390     if (headswap < 0) {
1391 	if (cheader[offset] > 0)
1392 	    headswap = 1;
1393 	else
1394 	    headswap = 0;
1395 	}
1396 
1397     if (machswap() != headswap) {
1398 	ctemp[3] = cheader[offset];
1399 	ctemp[2] = cheader[offset+1];
1400 	ctemp[1] = cheader[offset+2];
1401 	ctemp[0] = cheader[offset+3];
1402 	}
1403     else {
1404 	ctemp[0] = cheader[offset];
1405 	ctemp[1] = cheader[offset+1];
1406 	ctemp[2] = cheader[offset+2];
1407 	ctemp[3] = cheader[offset+3];
1408 	}
1409     return (temp);
1410 }
1411 
1412 
1413 /* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */
1414 
1415 char *
irafgetc2(irafheader,offset,nc)1416 irafgetc2 (irafheader, offset, nc)
1417 
1418 char	*irafheader;	/* IRAF image header */
1419 int	offset;		/* Number of bytes to skip before string */
1420 int	nc;		/* Maximum number of characters in string */
1421 
1422 {
1423     char *irafstring, *string;
1424 
1425     irafstring = irafgetc (irafheader, offset, 2*(nc+1));
1426     string = iraf2str (irafstring, nc);
1427     free (irafstring);
1428 
1429     return (string);
1430 }
1431 
1432 
1433 /* IRAFGETC -- Get character string from arbitrary part of IRAF header */
1434 
1435 char *
irafgetc(irafheader,offset,nc)1436 irafgetc (irafheader, offset, nc)
1437 
1438 char	*irafheader;	/* IRAF image header */
1439 int	offset;		/* Number of bytes to skip before string */
1440 int	nc;		/* Maximum number of characters in string */
1441 
1442 {
1443     char *ctemp, *cheader;
1444     int i;
1445 
1446     cheader = irafheader;
1447     ctemp = (char *) calloc (nc+1, 1);
1448     if (ctemp == NULL) {
1449 	(void)fprintf(stderr, "IRAFGETC Cannot allocate %d-byte variable\n",
1450 		nc+1);
1451 	return (NULL);
1452 	}
1453     for (i = 0; i < nc; i++) {
1454 	ctemp[i] = cheader[offset+i];
1455 	if (ctemp[i] > 0 && ctemp[i] < 32)
1456 	    ctemp[i] = ' ';
1457 	}
1458 
1459     return (ctemp);
1460 }
1461 
1462 
1463 /* Convert IRAF 2-byte/char string to 1-byte/char string */
1464 
1465 char *
iraf2str(irafstring,nchar)1466 iraf2str (irafstring, nchar)
1467 
1468 char	*irafstring;	/* IRAF 2-byte/character string */
1469 int	nchar;		/* Number of characters in string */
1470 {
1471     char *string;
1472     int i, j;
1473 
1474     /* Set swap flag according to position of nulls in 2-byte characters */
1475     if (headswap < 0) {
1476 	if (irafstring[0] != 0 && irafstring[1] == 0)
1477 	    headswap = 1;
1478 	else if (irafstring[0] == 0 && irafstring[1] != 0)
1479 	    headswap = 0;
1480 	else
1481 	    return (NULL);
1482 	}
1483 
1484     string = (char *) calloc (nchar+1, 1);
1485     if (string == NULL) {
1486 	(void)fprintf(stderr, "IRAF2STR Cannot allocate %d-byte variable\n",
1487 		nchar+1);
1488 	return (NULL);
1489 	}
1490 
1491     /* Swap bytes, if requested */
1492     if (headswap)
1493 	j = 0;
1494     else
1495 	j = 1;
1496 
1497     /* Convert appropriate byte of input to output character */
1498     for (i = 0; i < nchar; i++) {
1499 	string[i] = irafstring[j];
1500 	j = j + 2;
1501 	}
1502 
1503     return (string);
1504 }
1505 
1506 
1507 /* IRAFPUTI4 -- Insert 4-byte integer into arbitrary part of IRAF header */
1508 
1509 static void
irafputi4(irafheader,offset,inum)1510 irafputi4 (irafheader, offset, inum)
1511 
1512 char	*irafheader;	/* IRAF image header */
1513 int	offset;		/* Number of bytes to skip before number */
1514 int	inum;		/* Number to put into header */
1515 
1516 {
1517     char *cn, *chead;
1518 
1519     chead = irafheader;
1520     cn = (char *) &inum;
1521     if (headswap < 0)
1522 	headswap = 0;
1523     if (headswap != machswap()) {
1524 	chead[offset+3] = cn[0];
1525 	chead[offset+2] = cn[1];
1526 	chead[offset+1] = cn[2];
1527 	chead[offset] = cn[3];
1528 	}
1529     else {
1530 	chead[offset] = cn[0];
1531 	chead[offset+1] = cn[1];
1532 	chead[offset+2] = cn[2];
1533 	chead[offset+3] = cn[3];
1534 	}
1535     return;
1536 }
1537 
1538 
1539 /* IRAFPUTR4 -- Insert 4-byte real number into arbitrary part of IRAF header */
1540 
1541 static void
irafputr4(irafheader,offset,rnum)1542 irafputr4 (irafheader, offset, rnum)
1543 
1544 char	*irafheader;	/* IRAF image header */
1545 int	offset;		/* Number of bytes to skip before number */
1546 float	rnum;		/* Number to put into header */
1547 
1548 {
1549     char *cn, *chead;
1550 
1551     chead = irafheader;
1552     cn = (char *) &rnum;
1553     if (headswap < 0)
1554 	headswap = 0;
1555     if (headswap != machswap()) {
1556 	chead[offset+3] = cn[0];
1557 	chead[offset+2] = cn[1];
1558 	chead[offset+1] = cn[2];
1559 	chead[offset] = cn[3];
1560 	}
1561     else {
1562 	chead[offset] = cn[0];
1563 	chead[offset+1] = cn[1];
1564 	chead[offset+2] = cn[2];
1565 	chead[offset+3] = cn[3];
1566 	}
1567     return;
1568 }
1569 
1570 
1571 /* IRAFPUTC2 -- Insert character string into arbitrary part of v.1 IRAF header */
1572 
1573 static void
irafputc2(string,irafheader,offset,nc)1574 irafputc2 (string, irafheader, offset, nc)
1575 
1576 char	*string;	/* String to insert into header */
1577 char	*irafheader;	/* IRAF image header */
1578 int	offset;		/* Number of bytes to skip before string */
1579 int	nc;		/* Maximum number of characters in string */
1580 
1581 {
1582     char *irafstring;
1583 
1584     irafstring = (char *) calloc (2 * nc, 1);
1585     if (irafstring == NULL) {
1586 	(void)fprintf(stderr, "IRAFPUTC2 Cannot allocate %d-byte variable\n",
1587 		2 * nc);
1588 	}
1589     str2iraf (string, irafstring, nc);
1590     irafputc (irafstring, irafheader, offset, 2*nc);
1591 
1592     return;
1593 }
1594 
1595 
1596 /* IRAFPUTC -- Insert character string into arbitrary part of IRAF header */
1597 
1598 static void
irafputc(string,irafheader,offset,nc)1599 irafputc (string, irafheader, offset, nc)
1600 
1601 char	*string;	/* String to insert into header */
1602 char	*irafheader;	/* IRAF image header */
1603 int	offset;		/* Number of bytes to skip before string */
1604 int	nc;		/* Maximum number of characters in string */
1605 
1606 {
1607     char *chead;
1608     int i;
1609 
1610     chead = irafheader;
1611     for (i = 0; i < nc; i++)
1612 	chead[offset+i] = string[i];
1613 
1614     return;
1615 }
1616 
1617 
1618 /* STR2IRAF -- Convert 1-byte/char string to IRAF 2-byte/char string */
1619 
1620 static void
str2iraf(string,irafstring,nchar)1621 str2iraf (string, irafstring, nchar)
1622 
1623 char	*string;	/* 1-byte/character string */
1624 char	*irafstring;	/* IRAF 2-byte/character string */
1625 int	nchar;		/* Maximum number of characters in IRAF string */
1626 {
1627     int i, j, nc, nbytes;
1628 
1629     nc = strlen (string);
1630 
1631     /* Fill output string with zeroes */
1632     nbytes = nchar * 2;
1633     for (i = 0; i < nbytes; i++)
1634 	irafstring[i] = 0;
1635 
1636     /* If swapped, start with first byte of 2-byte characters */
1637     if (headswap)
1638 	j = 0;
1639     else
1640 	j = 1;
1641 
1642     /* Move input characters to appropriate bytes of output */
1643     for (i = 0; i < nchar; i++) {
1644 	if (i > nc)
1645 	    irafstring[j] = 0;
1646 	else
1647 	    irafstring[j] = string[i];
1648 	j = j + 2;
1649 	}
1650 
1651     return;
1652 }
1653 
1654 
1655 /* IRAFSWAP -- Reverse bytes of any type of vector in place */
1656 
1657 static void
irafswap(bitpix,string,nbytes)1658 irafswap (bitpix, string, nbytes)
1659 
1660 int	bitpix;		/* Number of bits per pixel */
1661 			/*  16 = short, -16 = unsigned short, 32 = int */
1662 			/* -32 = float, -64 = double */
1663 char	*string;	/* Address of starting point of bytes to swap */
1664 int	nbytes;		/* Number of bytes to swap */
1665 
1666 {
1667     switch (bitpix) {
1668 
1669 	case 16:
1670 	    if (nbytes < 2) return;
1671 	    irafswap2 (string,nbytes);
1672 	    break;
1673 
1674 	case 32:
1675 	    if (nbytes < 4) return;
1676 	    irafswap4 (string,nbytes);
1677 	    break;
1678 
1679 	case -16:
1680 	    if (nbytes < 2) return;
1681 	    irafswap2 (string,nbytes);
1682 	    break;
1683 
1684 	case -32:
1685 	    if (nbytes < 4) return;
1686 	    irafswap4 (string,nbytes);
1687 	    break;
1688 
1689 	case -64:
1690 	    if (nbytes < 8) return;
1691 	    irafswap8 (string,nbytes);
1692 	    break;
1693 
1694 	}
1695     return;
1696 }
1697 
1698 
1699 /* IRAFSWAP2 -- Swap bytes in string in place */
1700 
1701 static void
irafswap2(string,nbytes)1702 irafswap2 (string,nbytes)
1703 
1704 
1705 char *string;	/* Address of starting point of bytes to swap */
1706 int nbytes;	/* Number of bytes to swap */
1707 
1708 {
1709     char *sbyte, temp, *slast;
1710 
1711     slast = string + nbytes;
1712     sbyte = string;
1713     while (sbyte < slast) {
1714 	temp = sbyte[0];
1715 	sbyte[0] = sbyte[1];
1716 	sbyte[1] = temp;
1717 	sbyte= sbyte + 2;
1718 	}
1719     return;
1720 }
1721 
1722 
1723 /* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */
1724 
1725 static void
irafswap4(string,nbytes)1726 irafswap4 (string,nbytes)
1727 
1728 char *string;	/* Address of Integer*4 or Real*4 vector */
1729 int nbytes;	/* Number of bytes to reverse */
1730 
1731 {
1732     char *sbyte, *slast;
1733     char temp0, temp1, temp2, temp3;
1734 
1735     slast = string + nbytes;
1736     sbyte = string;
1737     while (sbyte < slast) {
1738 	temp3 = sbyte[0];
1739 	temp2 = sbyte[1];
1740 	temp1 = sbyte[2];
1741 	temp0 = sbyte[3];
1742 	sbyte[0] = temp0;
1743 	sbyte[1] = temp1;
1744 	sbyte[2] = temp2;
1745 	sbyte[3] = temp3;
1746 	sbyte = sbyte + 4;
1747 	}
1748 
1749     return;
1750 }
1751 
1752 
1753 /* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */
1754 
1755 static void
irafswap8(string,nbytes)1756 irafswap8 (string,nbytes)
1757 
1758 char *string;	/* Address of Real*8 vector */
1759 int nbytes;	/* Number of bytes to reverse */
1760 
1761 {
1762     char *sbyte, *slast;
1763     char temp[8];
1764 
1765     slast = string + nbytes;
1766     sbyte = string;
1767     while (sbyte < slast) {
1768 	temp[7] = sbyte[0];
1769 	temp[6] = sbyte[1];
1770 	temp[5] = sbyte[2];
1771 	temp[4] = sbyte[3];
1772 	temp[3] = sbyte[4];
1773 	temp[2] = sbyte[5];
1774 	temp[1] = sbyte[6];
1775 	temp[0] = sbyte[7];
1776 	sbyte[0] = temp[0];
1777 	sbyte[1] = temp[1];
1778 	sbyte[2] = temp[2];
1779 	sbyte[3] = temp[3];
1780 	sbyte[4] = temp[4];
1781 	sbyte[5] = temp[5];
1782 	sbyte[6] = temp[6];
1783 	sbyte[7] = temp[7];
1784 	sbyte = sbyte + 8;
1785 	}
1786     return;
1787 }
1788 
1789 
1790 /* Set flag if machine on which program is executing is not FITS byte order
1791  * ( i.e., if it is an Alpha or PC instead of a Sun ) */
1792 
1793 static int
machswap()1794 machswap ()
1795 
1796 {
1797     char *ctest;
1798     int itest;
1799 
1800     itest = 1;
1801     ctest = (char *)&itest;
1802     if (*ctest)
1803 	return (1);
1804     else
1805 	return (0);
1806 }
1807 
1808 
1809 /* ISIRAF -- return 1 if IRAF imh file, else 0 */
1810 
1811 int
isiraf(filename)1812 isiraf (filename)
1813 
1814 char	*filename;	/* Name of file for which to find size */
1815 {
1816     if (strchr (filename, '='))
1817 	return (0);
1818     else if (strsrch (filename, ".imh"))
1819 	return (1);
1820     else
1821 	return (0);
1822 }
1823 
1824 
1825 /* IRAFSIZE -- return size of file in bytes */
1826 
1827 static int
irafsize(diskfile)1828 irafsize (diskfile)
1829 
1830 FILE *diskfile;		/* Descriptor of file for which to find size */
1831 {
1832     long filesize;
1833     long offset;
1834 
1835     offset = (long) 0;
1836 
1837     /* Move to end of the file */
1838     if (fseek (diskfile, offset, SEEK_END) == 0) {
1839 
1840  	/* Position is the size of the file */
1841 	filesize = ftell (diskfile);
1842 
1843 	/* Move file pointer back tot he start of the file */
1844 	fseek (diskfile, offset, SEEK_SET);
1845 	}
1846 
1847     else
1848 	filesize = -1;
1849 
1850     return (filesize);
1851 }
1852 
1853 /* Feb 15 1996	New file
1854  * Apr 10 1996	Add more documentation
1855  * Apr 17 1996	Print error message on open failure
1856  * Jun  5 1996	Add byte swapping (reversal); use streams
1857  * Jun 10 1996	Make fixes after running lint
1858  * Jun 12 1996	Use IMSWAP subroutines instead of local ones
1859  * Jul  3 1996	Go back to using local IRAFSWAP subroutines
1860  * Jul  3 1996	Write to pixel file from FITS header
1861  * Jul 10 1996	Allocate all headers
1862  * Aug 13 1996	Add unistd.h to include list
1863  * Aug 26 1996	Allow 1-d images; fix comments; fix arguments after lint
1864  * Aug 26 1996	Add IRAF header lingth argument to IRAFWIMAGE and IRAFWHEAD
1865  * Aug 28 1996	Clean up code in IRAF2FITS
1866  * Aug 30 1996	Use write instead of fwrite
1867  * Sep  4 1996	Fix write mode bug
1868  * Oct 15 1996	Drop unused variables
1869  * Oct 17 1996	Minor fix after lint; cast arguments to STR2IRAF
1870  *
1871  * May 15 1997	Fix returned header length in IRAF2FITS
1872  * Dec 19 1997	Add IRAF version 2 .imh files
1873  *
1874  * Jan  2 1998	Allow uneven length of user parameter lines in IRAF headers
1875  * Jan  6 1998	Fix output of imh2 headers; allow newlines in imh1 headers
1876  * Jan 14 1998	Handle byte reversing correctly
1877  * Apr 17 1998	Add new IRAF data types unsigned char and unsigned short
1878  * Apr 30 1998  Fix error return if illegal data type after Allan Brighton
1879  * May 15 1998	Delete header keywords used for IRAF binary values
1880  * May 15 1998	Fix bug so FITS OBJECT is put into IRAF title
1881  * May 26 1998	Fix bug in fits2iraf keeping track of end of header
1882  * May 27 1998	Include fitsio.h instead of fitshead.h
1883  * Jun  4 1998	Write comments into header for converted IRAF binary values
1884  * Jun  4 1998	Pad FITS strings to 8 character minimum
1885  * Jul 24 1998	Write header file length to IRAF header file
1886  * Jul 27 1998	Print error messages to stderr for all failed malloc's
1887  * Jul 27 1998	Fix bug padding FITS header with spaces in iraf2fits
1888  * Jul 27 1998	Write modification time to IRAF header file
1889  * Aug  6 1998	Change fitsio.h to fitsfile.h; imhio.c to imhfile.c
1890  * Oct  1 1998	Set irafswap flag only once per file
1891  * Oct  5 1998	Add subroutines irafsize() and isiraf()
1892  * Nov 16 1998	Fix byte-swap checking
1893  *
1894  * Jan 27 1999	Read and write all of 3D image if one dimension is =1
1895  * Jul 13 1999	Improve error messages; change irafsize() argument to fd
1896  * Sep 22 1999	Don't copy OBJECT keyword from .imh file; use binary title
1897  * Oct 14 1999	Set FITS header length
1898  * Oct 20 1999	Allocate 5000 extra bytes for IRAF header
1899  * Nov  2 1999	Fix getclocktime() to use only time.h subroutines
1900  * Nov  2 1999	Add modification date and time to FITS header in iraf2fits()
1901  * Nov 24 1999	Delete HEADSWAP, IMHVER, DATE-MOD from header before writing
1902  * Nov 29 1999	Delete PIXSWAP, IRAF-MIN, IRAF-MAX from header before writing
1903  *
1904  * Jan 13 2000	Fix bug which dropped characters in iraf2fits()
1905  * Feb  3 2000	Declare timezone long, not time_t; drop unused variable
1906  * Mar  7 2000	Add more code to keep pixel file path short
1907  * Mar 10 2000	Fix bugs when writing .imh file headers
1908  * Mar 21 2000	Change computation of IRAF time tags to use only data structure
1909  * Mar 22 2000	Move IRAF time tag computation to lt2tsi() in dateutil.c
1910  * Mar 24 2000	Use Unix file update time if none in header
1911  * Mar 27 2000	Use hputm() to save file paths up to 256 characters
1912  * Mar 27 2000	Write filename comments after 1st keyword with short value
1913  * Mar 27 2000	Allocate pixel file name in same_path to imh2 length
1914  * Mar 29 2000	Add space after last linefeed of header in fits2iraf()
1915  * Apr 28 2000	Dimension pixname in irafwimage()
1916  * May  1 2000	Fix code for updating pixel file name with HDR$ in fits2iraf()
1917  * Jun  2 2000	Drop unused variables in fits2iraf() after lint
1918  * Jun 12 2000	If pixel filename has no / or $, use same path as header file
1919  * Sep  6 2000	Use header directory if pixel file not found at its pathname
1920  *
1921  * Jan 11 2001	Print all messages to stderr
1922  * Aug 24 2001	In isiraf(), return 0 if argument contains an equal sign
1923  *
1924  * Apr  8 2002	Fix bug in error message for unidentified nbits in fits2iraf()
1925  *
1926  * Feb  4 2003	Open catalog file rb instead of r (Martin Ploner, Bern)
1927  * Oct 31 2003	Read image only in irafrimage() if physical dimension > image dim.
1928  * Nov  3 2003	Set NAXISi to image, not physical dimensions in iraf2fits()
1929  *
1930  * Jun 13 2005	Drop trailing spaces on pixel file name
1931  *
1932  * Jun 20 2006	Initialize uninitialized variables
1933  *
1934  * Jan  4 2007	Change hputr4() calls to send pointer to value
1935  * Jan  8 2007	Drop unused variable nbx in irafrimage()
1936  * Jan  8 2007	Align header and image buffers properly by 4 and by BITPIX
1937  *
1938  * May 20 2011	Free newpixname, not pixname in irafwimage()
1939  *
1940  * Mar 27 2012	Fix pixname's appending to newpixname to avoid overflow
1941  */
1942