/*
**
** $Id: convertFITS.c,v 1.1.1.1 2004-05-19 22:55:27 price Exp $
**
** Program to convert BITPIX of FITS images.
**
**
** Paul A. Price
** 2004 January 28
** INDNJC.
**
**
** LEGAL STUFF:
**
** Copyright 2003, Paul A. Price.
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
** published by the Free Software Foundation; either version 2 of the
** License, or (at your option) any later version.
**
** This program 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
*/


/* Included standard header files */
#include <stdio.h>
#include <math.h>
/* For getopt */
#include <unistd.h>
#include <getopt.h>
/* For cfitsio */
#include <fitsio.h>

/* Included header files for components */
#include "memory.h"

/* Handy definitions */
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) > (b)) ? (b) : (a))
#define abs(a) (((a) > 0) ? (a) : (-a))


/* Global variables */
int verbose = 0;   /* Verbose output? */

int main(int argc, char **argv)
{
    /* Input variables */
    char *inputName = NULL;   /* Name of input image */
    char *outputName = NULL;   /* Name of output image */
    int bitpix = -32;   /* BITPIX for output image */

    /* Calculation variables */
    float *inputData;   /* The input pixels */
    long int inputDims[2];   /* Dimensions of the input image */
    int i;   /* Counter */

    /* Variables for cfitsio */
    int status = 0;   /* fitsio status */
    fitsfile *infp, *outfp;   /* File pointers to FITS file */
    int nkeys, keypos;   /* Keyword-handling variables */
    char card[FLEN_CARD];   /* Keyword-handling variable */

    /* Help function */
    void help(void);
    /* cfitsio error handler */
    void ckstatus(int status);

    if (argc < 3)
    {
        help();
        exit(EXIT_FAILURE);
    }
    inputName = argv[1];
    outputName = argv[2];
    if (sscanf(argv[3], "%d", &bitpix) != 1)
    {
	help ();
	exit (EXIT_FAILURE);
    }


    /* Read the input file */
    if (verbose) printf ("Opening %s.... ", inputName);
    if (fits_open_file(&infp,inputName,READONLY,&status)) ckstatus(status);
    /* Get dimensions */
    if (fits_get_img_size(infp,2,inputDims,&status)) ckstatus(status);
    if (verbose) printf ("%ldx%ld\n",inputDims[0],inputDims[1]);
    /* Allocate storage */
    inputData = farray(inputDims[0]*inputDims[1]);
    /* Read the pixels */
    if (fits_read_img(infp, TFLOAT, 1, inputDims[0]*inputDims[1], 0, inputData, NULL, &status)) ckstatus(status);

    /* Create output file */
    if (verbose) printf ("Writing %ldx%ld output image...\n",inputDims[0],inputDims[1]);
    if (fits_create_file(&outfp, outputName, &status)) ckstatus(status);

#if 0
    /* Write bare header */
    if (fits_write_imghdr (outfp, bitpix, 2, inputDims, &status)) ckstatus(status);
#endif

    /* Copy FITS headers */
    if (fits_get_hdrpos(infp, &nkeys, &keypos, &status))
        ckstatus(status);
    for (i=1; i <= nkeys; i++)
    {
        fits_read_record(infp, i, card, &status);
        fits_write_record(outfp, card, &status);
    }
    ckstatus(status);

    /* Write new BITPIX */
    if (fits_update_key (outfp, TINT, "BITPIX", &bitpix, NULL, &status)) ckstatus(status);

    /* Get correct BITPIX for cfitsio */
    switch (bitpix)
    {
    case 8:
    {
	char *charData;   /* Short version of the pixels */
	charData = carray(inputDims[0]*inputDims[1]);
	for (i = 0; i < inputDims[0]*inputDims[1]; i++) charData[i] = (char)inputData[i];
	/* Write pixels */
	if (fits_write_img(outfp, TBYTE, 1, inputDims[0]*inputDims[1], charData, &status)) ckstatus(status);
	free (charData);

	break;
    }
    case 16:
    {
	short int *intData;   /* Integer version of the pixels */

	intData = sarray(inputDims[0]*inputDims[1]);
	for (i = 0; i < inputDims[0]*inputDims[1]; i++) intData[i] = (short int) inputData[i];
	/* Write pixels */
	if (fits_write_img(outfp, TSHORT, 1, inputDims[0]*inputDims[1], intData, &status)) ckstatus(status);
	free (intData);
	break;
    }
    default:
	fprintf (stderr, "BITPIX must be 8 or 16\n");
	exit (EXIT_FAILURE);
    }

    /* Close files and clean up */
    if (fits_close_file(infp, &status)) ckstatus(status);
    if (fits_close_file(outfp, &status)) ckstatus(status);
    free (inputData);


    exit (EXIT_SUCCESS);
}


void help(void)
{
    fprintf (stderr,
	     "convertFITS [-hv] INPUT OUTPUT BITPIX\n"
	     "\n"
	     "\t-h      Help\n"
	     "\t-v      Verbose\n"
	     "\tINPUT   Input FITS file\n"
	     "\tOUTPUT  Output FITS file\n"
	     "\tBITPIX  BITPIX for output FITS file\n"
	     "\n"
	);
}


void ckstatus(int status)
{
    char msg[FLEN_ERRMSG];   /* Error message */

    if (!status)
        return;
    fprintf (stderr,"CFITSIO returned an error code of %d\n",status);
    while (fits_read_errmsg(msg))
        fprintf(stderr, "CFITSIO: %s\n", msg);
    fprintf (stderr, "Exiting....\n");
    exit(EXIT_FAILURE);
}
