/*----------------------------------------------------------------------------*/ /** @file dfits.c @author Nicolas Devillard @date 30 Mar 2000 @version $Revision: 1.3 $ @brief FITS header display */ /*----------------------------------------------------------------------------*/ /* $Id: dfits.c,v 1.3 2005/07/19 15:38:52 yjung Exp $ $Author: yjung $ $Date: 2005/07/19 15:38:52 $ $Revision: 1.3 $ */ /*----------------------------------------------------------------------------- Includes -----------------------------------------------------------------------------*/ #include #include #include #include "qfits.h" /*----------------------------------------------------------------------------- Define -----------------------------------------------------------------------------*/ #define BLOCK_SIZE 2880 #define LGTH 80 #define MAGIC "SIMPLE =" /* If compiled against zlib, include support for gzipped files */ #if HAVE_ZLIB #include "zlib.h" #define FILE gzFile #define fopen gzopen #define fclose gzclose #define fread(b,s,n,f) gzread(f,b,n*s) #endif /*----------------------------------------------------------------------------- Function prototypes -----------------------------------------------------------------------------*/ void usage(char * pname) ; void parse_cmd_line(int, char **, int *, int *, int *) ; int dump_fits_filter(FILE *, int) ; int dump_fits(char *, int) ; char * rstrip(char *) ; /*----------------------------------------------------------------------------- Main -----------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { int xtnum ; int c_arg ; int filter ; int err ; /* No arguments prints out a usage message */ if (argc<2) usage(argv[0]); /* Parse command-line options */ parse_cmd_line(argc, argv, &xtnum, &filter, &c_arg); /* Filter mode: process data received from stdin */ if (filter) { #if HAVE_ZLIB printf("filter mode does not support gzipped files\n"); printf("use: gunzip -c file.fits | dfits -\n"); return 1 ; #else return dump_fits_filter(stdin, xtnum); #endif } /* Normal mode: loop on all file names given on command-line */ err = 0 ; while (c_arg < argc) { err += dump_fits(argv[c_arg], xtnum); c_arg++; } return err ; /* Returns number of errors during process */ } void usage(char * pname) { printf( "\n\n" "usage: %s [-x xtnum] \n" "usage: %s [-x xtnum] -\n" "\n" "The former version expects file names.\n" "The latter expects data coming in from stdin.\n" "\n" "-x xtnum specifies the extension header to print\n" "-x 0 specifies main header + all extensions\n" "\n\n", pname, pname); #if HAVE_ZLIB printf( "This program was compiled against zlib %s\n" "This means you can use it with gzipped FITS files\n" "as with uncompressed FITS files.\n" "NB: this does not apply to the '-' option (input from stdin)\n" "\n\n", ZLIB_VERSION); #endif exit(1) ; } void parse_cmd_line( int argc, char ** argv, int * xtnum, int * filter, int * c_arg) { *filter = 0 ; *xtnum = -1 ; *c_arg = argc-1 ; /* If '-' is on the command-line, it must be the last argument */ if (!strcmp(argv[argc-1], "-")) *filter = 1 ; /* If -x xtnum is on the command-line, it must be the first two arguments */ if (!strcmp(argv[1], "-x")) { *xtnum = atoi(argv[2]); *c_arg = 3 ; } else { *c_arg = 1 ; } return ; } /* Strip off all blank characters in a string from the right-side. */ char * rstrip(char * s) { int len ; if (s==NULL) return s ; len = strlen(s); if (len<1) return s ; len -- ; while (s[len]== ' ') { s[len]=(char)0 ; len --; if (len<0) break ; } return s ; } /* Dump the requested header (main or extension) from a filename. */ int dump_fits(char * name, int xtnum) { FILE * in ; int err ; if ((in=fopen(name, "r"))==NULL) { fprintf(stderr, "error: cannot open file [%s]\n", name); return 1 ; } printf("====> file %s (main) <====\n", name) ; err = dump_fits_filter(in, xtnum); fclose(in); return err ; } /* Dump the requested header (main or extension) from a FILE * */ int dump_fits_filter(FILE * in, int xtnum) { int n_xt ; char buf[LGTH+1]; int err ; int data_bytes, naxis ; char * read_val ; int skip_blocks ; int seeked ; /* Try getting the first 80 chars */ memset(buf, 0, LGTH+1); if (fread(buf, sizeof(char), LGTH, in)!=LGTH) { fprintf(stderr, "error reading input\n"); return 1; } /* Check that it is indeed FITS */ if (strncmp(buf, MAGIC, strlen(MAGIC))) { fprintf(stderr, "not a FITS file\n"); return 1 ; } naxis = 0 ; data_bytes = 1 ; if (xtnum<1) { /* Output main header */ printf("%s\n", rstrip(buf)); data_bytes = 1 ; naxis = 0 ; while ((err=fread(buf, sizeof(char), LGTH, in))==LGTH) { printf("%s\n", rstrip(buf)); /* Look for BITPIX keyword */ if (buf[0]=='B' && buf[1]=='I' && buf[2]=='T' && buf[3]=='P' && buf[4]=='I' && buf[5]=='X' && buf[6]==' ') { read_val = qfits_getvalue(buf); data_bytes *= (int)atoi(read_val) / 8 ; if (data_bytes<0) data_bytes *= -1 ; } else /* Look for NAXIS keyword */ if (buf[0]=='N' && buf[1]=='A' && buf[2]=='X' && buf[3]=='I' && buf[4]=='S') { if (buf[5]==' ') { /* NAXIS keyword */ read_val = qfits_getvalue(buf); naxis = (int)atoi(read_val); } else { /* NAXIS?? keyword (axis size) */ read_val = qfits_getvalue(buf); data_bytes *= (int)atoi(read_val); } } else /* Look for END keyword */ if (buf[0]=='E' && buf[1]=='N' && buf[2]=='D') { break ; } } if (err!=LGTH) return 1 ; } if (xtnum<0) return 0 ; n_xt=0 ; while (1) { /* * Skip the previous data section if pixels were declared */ if (naxis>0) { /* Skip as many blocks as there are declared pixels */ skip_blocks = data_bytes/BLOCK_SIZE ; if ((data_bytes % BLOCK_SIZE)!=0) skip_blocks ++ ; seeked = fseek(in, skip_blocks*BLOCK_SIZE, SEEK_CUR); if (seeked<0) return -1 ; } /* Look for next XTENSION keyword */ while ((err=fread(buf, sizeof(char), LGTH, in))==LGTH) { if (buf[0]=='X' && buf[1]=='T' && buf[2]=='E' && buf[3]=='N' && buf[4]=='S' && buf[5]=='I' && buf[6]=='O' && buf[7]=='N') break ; } if (err==0) break ; if (err!=LGTH) return 1 ; n_xt++ ; if (xtnum==0 || xtnum==n_xt) { printf("===> xtension %d\n", n_xt) ; printf("%s\n", rstrip(buf)); } data_bytes = 1 ; naxis = 0 ; while ((err=fread(buf, sizeof(char), LGTH, in))==LGTH) { if (xtnum==0 || xtnum==n_xt) printf("%s\n", rstrip(buf)); /* Look for BITPIX keyword */ if (buf[0]=='B' && buf[1]=='I' && buf[2]=='T' && buf[3]=='P' && buf[4]=='I' && buf[5]=='X' && buf[6]==' ') { read_val = qfits_getvalue(buf); data_bytes *= (int)atoi(read_val) / 8 ; if (data_bytes<0) data_bytes *= -1 ; } else /* Look for NAXIS keyword */ if (buf[0]=='N' && buf[1]=='A' && buf[2]=='X' && buf[3]=='I' && buf[4]=='S') { if (buf[5]==' ') { /* NAXIS keyword */ read_val = qfits_getvalue(buf); naxis = (int)atoi(read_val); } else { /* NAXIS?? keyword (axis size) */ read_val = qfits_getvalue(buf); data_bytes *= (int)atoi(read_val); } } else /* Look for END keyword */ if (buf[0]=='E' && buf[1]=='N' && buf[2]=='D') break ; } if (n_xt==xtnum) break ; } return 0 ; }