/* fitstopgm.c - read a FITS file and produce a portable graymap
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include <stdio.h>
#ifdef	SYSV
#include <string.h>
#else	SYSV
#include <strings.h>
#endif	SYSV
#include "pgm.h"

struct FITS_Header {
    int simple;		/* basic format or not */
    int bitpix;		/* number of bits per pixel */
    int naxis;		/* number of axes */
    int naxis1;		/* number of points on axis 1 */
    int naxis2;		/* number of points on axis 2 */
    int maxpix;		/* max # */
    int minpix;		/* min # */
    };

main( argc, argv )
int argc;
char *argv[];
    {
    FILE *ifd;
    register gray *grayrow, *gP;
    int argn, row;
    register int col;
    gray maxval;
    int rows, cols;
    struct FITS_Header h;

    pm_progname = argv[0];

    argn = 1;

    if ( argn < argc )
	{
	ifd = pm_openr( argv[argn] );
	argn++;
	}
    else
	ifd = stdin;

    if ( argn != argc )
	pm_usage( "[fitsfile]" );

    read_fits_header( ifd, &h );

    if ( ! h.simple )
	pm_error( "FITS file is not in simple format, can't read", 0,0,0,0,0 );
    if ( h.bitpix != 8 )
	pm_error( "bits per pixel is != 8, can't read", h.naxis, 0,0,0,0 );
    if ( h.naxis != 2 )
	pm_error( "FITS file has %d axes, can't read", h.naxis, 0,0,0,0 );
    cols = h.naxis1;
    rows = h.naxis2;

    maxval = h.maxpix - h.minpix;

    pgm_writepgminit( stdout, cols, rows, maxval );
    grayrow = pgm_allocrow( cols );
    for ( row = 0; row < rows; row++)
	{
	for ( col = 0, gP = grayrow; col < cols; col++, gP++ )
	    {
	    int ich;

	    ich = getc( ifd );
	    if ( ich == EOF )
		pm_error( "premature EOF", 0,0,0,0,0 );
	    *gP = (gray) ( ich - h.minpix );
	    /* (I'm not certain we're supposed to normalize to minpix..maxpix
		liek this, but it seems to look better this way.) */
	    }
	pgm_writepgmrow( stdout, grayrow, cols, maxval );
	}
    pm_close( ifd );

    exit( 0 );
    }

read_fits_header( fd, hP )
FILE *fd;
struct FITS_Header *hP;
    {
    char buf[80];
    int i;
    char c;

    hP->simple = 0;

    for ( i = 0; i < 36; i++ )
	{
	read_card( fd, buf );

	if ( sscanf( buf, "SIMPLE = %c", &c ) == 1 )
	    {
	    if ( c == 'T' || c == 't' )
		hP->simple = 1;
	    }
	else if ( sscanf( buf, "BITPIX = %d", &(hP->bitpix) ) == 1 )
	    ;
	else if ( sscanf( buf, "NAXIS = %d", &(hP->naxis) ) == 1 )
	    ;
	else if ( sscanf( buf, "NAXIS1 = %d", &(hP->naxis1) ) == 1 )
	    ;
	else if ( sscanf( buf, "NAXIS2 = %d", &(hP->naxis2) ) == 1 )
	    ;
	else if ( sscanf( buf, "MAXPIX = %d", &(hP->maxpix) ) == 1 )
	    ;
	else if ( sscanf( buf, "MINPIX = %d", &(hP->minpix) ) == 1 )
	    ;
	}
    }

read_card( fd, buf )
FILE *fd;
char *buf;
    {
    if ( fread( buf, 1, 80, fd ) == 0 )
	pm_error( "error reading header", 0,0,0,0,0 );
    }
