// Utility for listing FITS header text and skipping binary data.

// compile with  gcc -o list_fits list_fits.c

#include <stdio.h>

#define BLK_SIZE	2880
#define LINES_PER_HDR	36
#define CHAR_PER_LINE	80

int main ( int argc, char *argv[] )
{
    FILE *fd;

    char abuf[100];
    char bbuf[1000000];
    int line_count;
    int total_line_count;
    int naxis;
    int saxis[4];
    int bin_size;
    int num_blks;
    int end_flag;
    int i;

    if (argc < 2) {
	printf ("Usage: list_fits file_name\n");
	return 1;
    }
    fd = fopen(argv[1], "rb");
    if (fd == NULL) {
	printf ("Cannot open file '%s'\n");
	return 1;
    }
    line_count = 0;
    end_flag = 0;
    // read the 80-character lines one at a time
    while (fread(abuf, sizeof(char), CHAR_PER_LINE, fd) == CHAR_PER_LINE) {
	// truncate the line for easier printing
	abuf[70] = '\0';
	if (strncmp(abuf, "      ", 6) != 0) {
	    printf ("%s\n", abuf);
	}
	// watch for a few keywords to tell how long the binary table will be
	// when we need to skip it.
	if (strncmp(abuf, "NAXIS ", 6) == 0) {
	    sscanf(abuf + 9, "%d", &naxis);
	    for (i = 0; i < 4; i++) saxis[i] = 1;
	}
	if (strncmp(abuf, "NAXIS1", 6) == 0) {
	    sscanf(abuf + 9, "%d", &saxis[0]);
	}
	if (strncmp(abuf, "NAXIS2", 6) == 0) {
	    sscanf(abuf + 9, "%d", &saxis[1]);
	}
	if (strncmp(abuf, "NAXIS3", 6) == 0) {
	    sscanf(abuf + 9, "%d", &saxis[2]);
	}
	if (strncmp(abuf, "NAXIS4", 6) == 0) {
	    sscanf(abuf + 9, "%d", &saxis[3]);
	}
	if (strncmp(abuf, "END   ", 6) == 0) {
	    end_flag = 1;
	}
	total_line_count++;
	line_count++;
	// possible end of header?
	if (line_count >= LINES_PER_HDR) {
//	    printf ("naxis: %d  naxis1: %d  naxis2: %d  end_flag %d\n", naxis,
//		    saxis[0], saxis[1], end_flag);
	    line_count = 0;
	    if (end_flag == 1) {  // end of header if END keyword seen
		end_flag = 0;
		// compute binary table size, if any, and skip it
		if (naxis > 0) {
		    bin_size = saxis[0];
		    for (i = 1; i < naxis; i++) bin_size *= saxis[i];
		    num_blks = (int)(bin_size / BLK_SIZE) + 1;
		    if ((bin_size % BLK_SIZE) == 0) num_blks--;
		    bin_size = BLK_SIZE * num_blks;
		    if (fread(bbuf, sizeof(char), bin_size, fd) != bin_size) {
			printf ("Error reading binary table\n");
			return 1;
		    }
		}
		printf ("++++++++++++++++++++++++++++++++\n");
	    }
	}
    }
    fclose(fd);
    return 0;
}
