/* listfits.c -- program to list FITS headers. Use: listfits < fitsfile > headlist.out or listfits < fitsfile | more This program is a modified version of Barry Schlesinger's program /FITS/software/headlist.c available via anonymous-FTP on host nssdca.gsfc.nasa.gov. Modifications by Don Wells, NRAO-CV, July 91: (1) commented out #include , (2) added function printcard() which truncates trailing blanks and suppresses blank header lines, (3) added test for SIMPLE at beginning of file, (4) added print of XTENSION cards, (5) fixed bug in recognition of END cards (8chars instead of 4), (6) executed indent(1) with default parameters to reformat the text, (7) made the comments more verbose, (8) added print of number of bytes&records skipped, (9) changed type of "c" to int in main() and readunit() so that EOF test works properly, (10) added static totalbytes variable with a remainder analysis printed at EOF. This version of listfits.c has been tested with: (1) GNU gcc compiler on Sun-3 under SunOS_4.0.3, (2) Borland Turbo-C compiler on PC-XT clone under DOS, (3) "cc" compiler on IBM RS/6000 under AIX, (4) Convex "cc" compiler on Convex C-1. In all four cases the default compiler options were sufficient. Bugs/Deficiencies: (1) needs protection against non-printing characters, (2) probably should predict number of data records to be skipped and then check against prediction. */ #include #include /* #include */ #define TRUE 1 #define FALSE 0 int readunit (char card1st[]); static long totalbytes; /* global variable */ main () { int c; char card[81], card1[81], keyword[9]; char *xtension = {"XTENSION"}; char *simple = {"SIMPLE "}; int infile = TRUE; int ktcard1, ktincard; int nocard; long bytecount; totalbytes = 0; /* Read the first card image and verify that it is a SIMPLE card: */ for (ktcard1 = 0; ktcard1 < 80; ktcard1++) { if ((c = getchar ()) != EOF) { card1[ktcard1] = c; totalbytes++; } else { printf ("ERROR! Unexpected end of file in SIMPLE card; job terminated\n"); return 13; } } strncpy (keyword, card1, 8); keyword[8] = '\0'; if (strcmp (keyword, simple) != 0) { printf ("ERROR! First keyword='%s', should be 'SIMPLE'; this is not FITS!\n", keyword); return 17; } /* * The first card of the file is a SIMPLE card. Print it, then invoke * readunit() to print the rest of the Basic-FITS header: */ card1[80] = '\0'; printcard (card1); readunit (card1); /* * The END card of the Basic-FITS header has been seen, and the blank * line padding has been skipped. Now we will skip any records of data * which follow the header, watching for an XTENSION card or an * end-of-file: */ bytecount = 0; while (infile == TRUE) { for (nocard = 1; nocard <= 36; nocard++) { for (ktincard = 0; ktincard < 80; ktincard++) { if (infile == TRUE) { if ((c = getchar ()) != EOF) { card[ktincard] = c; bytecount++; totalbytes++; } else infile = FALSE; } } if ((infile == TRUE) && (nocard == 1)) { /* * Test the first card of each record to see if it is an * XTENSION card: */ card[80] = '\0'; strncpy (keyword, card, 8); keyword[8] = '\0'; if (strcmp (keyword, xtension) == 0) { /* * The first card of this FITS logical record is an * XTENSION card. Print the number of bytes which we have * skipped, print the XTENSION card, and execute * readunit() to print the rest of the extension header: */ bytecount -= 80; printf (" =-=-= Skipped %d bytes (%dr%d FITS records) =-=-=\n\n", bytecount, (bytecount / 2880), (bytecount % 2880)); printcard (card); readunit (card); /* * We have seen the END card of the extension header, and * have skipped any blank line padding of the last * logical record of the header, and we can resume * skipping data records. */ bytecount = 0; nocard = 1; break; } } } } printf (" =-=-= Skipped %d bytes (%dr%d FITS records) =-=-=\n\n", bytecount, (bytecount / 2880), (bytecount % 2880)); printf (" =-=-= End-of-File, %d bytes in file (%dr%d FITS records) =-=-=\n", totalbytes, (totalbytes / 2880), (totalbytes % 2880)); if ((bytecount % 2880) != 0) { printf ("NOTE! Not an integral number of 2880-byte FITS records.\n"); if ((totalbytes % 512) == 0) printf ("NOTE! File contains %d 512-byte records.\n", (totalbytes / 512)); else { printf ("NOTE! File contains %dr%d 512-byte records.\n", (totalbytes / 512), (totalbytes % 512)); printf ("ERROR! Bytecount not a multiple of 2880 or 512 !!\n"); } } exit (0); return (0); } /* printcard: print non-blank card images */ printcard (char card1[]) { int i; char c, card2[80]; strcpy (card2, card1); for (i = 79; i > 0; i--) if (card2[i] != ' ') break; card2[i + 1] = '\0'; if (i > 0) printf ("%s\n", card2); return; } /* readunit: read and list header of hdu */ readunit (char card[]) { int c; char key[8]; char *endcard = {"END "}; int nocard, ktincard; int inunit = TRUE; int initcard = 2; int cardcount = 1; while (inunit == TRUE) { for (nocard = initcard; nocard <= 36; nocard++) { for (ktincard = 0; ktincard < 80; ktincard++) { if ((c = getchar ()) != EOF) { card[ktincard] = c; totalbytes++; } else { printf ("ERROR: Unexpected end of file; job terminated\n"); return 26; } } card[80] = '\0'; printcard (card); strncpy (key, card, 8); key[8] = '\0'; if (inunit) cardcount++; if (strcmp (key, endcard) == 0) { inunit = FALSE; } } initcard = 1; } printf ("\n =-=-= End of header. %d cards (%d FITS records) =-=-=\n\n", cardcount, ((cardcount + 35) / 36)); return 0; }