/* * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory */ #include #include extern char *optarg; extern int optind; #define MAXROW 8192 static int maxrow=MAXROW; /* from funtoolsP.h */ #define COL_REGION_NAME "$REGION" #define COL_REGION_ONAME "REGION" #define COL_NUM_NAME "$N" #define COL_NUM_ONAME "N" /* display directives */ #define DMODE_MASKONLY 1 #define DMODE_RDB 2 #define NFORMAT 12 /* default format values */ static int _fmti[NFORMAT] = {21, 11, 10, 8, 6, 12, 10, 8, 10, 6, 20, 1}; static char *_fmts[NFORMAT] = {"%21.21s", "%11.11s", "%10.10s", "%8.8s", "%6.6s", "%12.12s", "%10.10s", "%8.8s", "%10.10s", "%6.6s", "%20.20s", "%1.1s"}; static char *_fmt[NFORMAT] = {"%21.8f", "%11.2f", "%10d", "%8d", "%6d", "%12.12s", "%10.10s", "%8d", "%10d", "%6s", "%20lld", "%1x"}; /* global format values, used everywhere */ static int fmti[NFORMAT]; static char *fmts[NFORMAT]; static char *fmt[NFORMAT]; /* holds temp index string for header */ static char _tdim[SZ_LINE]; /* column delimiter */ static int coldelim=' '; #define MAX_COLFMTS 1024 /* column-specific formats */ static struct colfmtrec{ char *name; int fmti; char *fmts; char *fmt; } colfmts[MAX_COLFMTS]; static int ncolfmt=0; #ifdef ANSI_FUNC int Index(int type) #else int Index(type) int type; #endif { switch ( type ) { case 'D': return 0; case -64: return 0; case 'E': return 1; case -32: return 1; case 'J': return 2; case 32: return 2; case 'I': return 3; case 16: return 3; case 'B': return 4; case 8: return 4; case 'A': return 5; case 'X': return 6; case 'U': return 7; case -16: return 7; case 'V': return 8; case 'L': return 9; case 'K': return 10; case 64: return 10; } return(-1); } /* order of formats: double float int short byte string bits ushort uint */ #ifdef ANSI_FUNC static void Format (char *s, char **names, int n) #else static void Format (s, names, n) char *s; char **names; int n; #endif { int i, j, x; int col; int ival; int ip=0; char format[SZ_LINE]; char tbuf[SZ_LINE]; char *e; char *f; i = 0; newdtable(","); while( 1 ){ col = -1; x = i; if( !word(s, format, &ip) ) break; if( !strcmp(format, "-") || !strncasecmp(format, "def", 3) ){ i++; continue; } /* look for "=", meaning we have a column format */ if( (e = strchr(format, '=')) != NULL ){ if( ncolfmt >= MAX_COLFMTS ){ fprintf(stderr, "WARNING: too many column formats; skipping %s\n", format); continue; } f = e+1; *e = '\0'; if( (strlen(format) != 1) || ((x=Index(*format)) < 0) ){ for(j=0; j= 0 ){ colfmts[ncolfmt].fmti = ival; snprintf(tbuf, SZ_LINE-1, "%%%d.%ds", ival, ival); if( colfmts[ncolfmt].fmts ) xfree(colfmts[ncolfmt].fmts); colfmts[ncolfmt].fmts = xstrdup(tbuf); if( strchr(f, '%') ) snprintf(tbuf, SZ_LINE-1, "%s", f); else snprintf(tbuf, SZ_LINE-1, "%%%s", f); if( colfmts[ncolfmt].fmt ) xfree(colfmts[ncolfmt].fmt); colfmts[ncolfmt].fmt = xstrdup(tbuf); ncolfmt++; } else{ fmti[x] = ival; snprintf(tbuf, SZ_LINE-1, "%%%d.%ds", ival, ival); if( fmts[x] ) xfree(fmts[x]); fmts[x] = xstrdup(tbuf); if( strchr(f, '%') ) snprintf(tbuf, SZ_LINE-1, "%s", f); else snprintf(tbuf, SZ_LINE-1, "%%%s", f); if( fmt[x] ) xfree(fmt[x]); fmt[x] = xstrdup(tbuf); if( x == i ){ i++; } } } freedtable(); } #ifdef ANSI_FUNC static char * tdimstr (int *dims, int ndim, int ival) #else static char * tdimstr (dims, ndim, ival) int *dims; int ndim; int ival; #endif { int i, j; int *prods; int *idxs; char tbuf[SZ_LINE]; *_tdim = '\0'; if( ndim <= 1 ){ snprintf(_tdim, SZ_LINE, "%d", ival); } else{ prods=xcalloc(ndim, sizeof(int)); idxs=xcalloc(ndim, sizeof(int)); for(i=0; i=0; i--){ if( i == 0 ){ idxs[i] = ival; } else{ idxs[i] = ival / prods[i]; ival %= prods[i]; } } for(i=0; i1) && tdim ){ newdtable(",()"); for(ip=0; word(tdim, tbuf, &ip); ndim++){ if( ndim >= SZ_LINE ) gerror(stderr, "too many dimensions in TDIM\n"); dims[ndim] = atoi(tbuf); } freedtable(); } /* output each sub-column in this column */ for(i=0; i 1 ){ if( dmode & DMODE_RDB ){ if( i == (n-1) ) strcpy(tbuf, t); else strcpy(tbuf, " "); } else{ snprintf(tbuf, SZ_LINE-1, "%s[%s]", t, tdimstr(dims,ndim,i)); } } else strcpy(tbuf, t); /* only display last characters of string, if its too long */ j = strlen(tbuf) - xfmti; if( j > 0 ) { /* this ensures we print out at least one character */ j = MIN((int)strlen(tbuf)-1,j); if( !(dmode & DMODE_RDB) ) t = tbuf + j; /* for rdb, we want the whole string, since alignment is unimportant */ else t = tbuf; } else t = tbuf; if( i ) fprintf(fp, " "); /* for rdb, we want the whole string, since alignment is unimportant */ if( (dmode & DMODE_RDB) && (j > 0) ) fprintf(fp, "%s", t); /* else print out what we can */ else fprintf(fp, xfmts, t); } } #ifdef ANSI_FUNC static void Dashes (FILE *fp, int dmode, char *name, int type, int n) #else static void Dashes (fp, dmode, name, type, n) FILE *fp; int dmode; char *name; int type; int n; #endif { int ind; int i, j; int xfmti; // char *xfmts; // char *xfmt; if( dmode & DMODE_MASKONLY ) ind = NFORMAT-1; else{ if( (ind = Index(type)) == -1 ) ind = NFORMAT-1; } /* see values for format */ // xfmts = fmts[ind]; xfmti = fmti[ind]; // xfmt = fmt[ind]; /* some columns don't have a name */ if( !name || !*name ) name = ""; /* see if we have a column format and overwrite format values if so */ else{ for(i=0; i= 4) && (tbuf[2] == '0') && ((tbuf[3] == 'x') || (tbuf[3] == 'X')) ) fprintf(fp, xfmt, &tbuf[2]); else fprintf(fp, xfmt, tbuf); } switch(xn){ case 1: buf += sizeof(unsigned short); break; case 2: buf += sizeof(unsigned int); break; case 0: default: buf += sizeof(unsigned char); break; } break; case 'B': case 8: ival = (int)*(unsigned char *)buf; if( maskonly && !ival ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, ival); buf += sizeof(unsigned char); break; case 'I': case 16: ival = (int)*(short *)buf; if( maskonly && !ival ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, ival); buf += sizeof(short); break; case 'U': case -16: ival = (int)*((unsigned short *)buf); if( maskonly && !ival ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, ival); buf += sizeof(unsigned short); break; case 'J': case 32: ival = *(int *)buf; if( maskonly && !ival ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, ival); buf += sizeof(int); break; case 'K': case 64: #if HAVE_LONG_LONG == 0 gerror(stderr, "64-bit data support not built (long long not available)\n"); #endif lval = *(longlong *)buf; if( maskonly && !lval ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, lval); buf += sizeof(longlong); break; case 'V': ival = *(unsigned int *)buf; if( maskonly && !ival ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, ival); buf += sizeof(unsigned int); break; case 'E': case -32: fval = *(float *)buf; if( maskonly && (fval==0) ) fprintf(fp, xfmts, "."); else if( maskonly ) fprintf(fp, xfmt, (int)fval); else fprintf(fp, xfmt, fval); buf += sizeof(float); break; case 'D': case -64: dval = *(double *)buf; if( maskonly && (dval==0) ) fprintf(fp, xfmts, "."); else if( maskonly ) fprintf(fp, xfmt, (int)dval); else fprintf(fp, xfmt, dval); buf += sizeof(double); break; case 'A': if( maskonly && !*buf ) fprintf(fp, xfmts, "."); else if( maskonly ) fprintf(fp, "%c", *buf); else{ if( dmode & DMODE_RDB ){ fprintf(fp, xfmt, buf); } else{ /* make sure we have enough room */ if( (n+3) >= SZ_LINE) n = SZ_LINE-3; /* enclose string in single quotes */ strncpy(tbuf, "'", SZ_LINE-1); memmove(&tbuf[1], buf, n); strncat(tbuf, "'", SZ_LINE-1); snprintf(tbuf2, SZ_LINE-1, xfmt, tbuf); /* make sure we end with a single quote */ if( tbuf2[strlen(tbuf2)-1] != '\'' ) tbuf2[strlen(tbuf2)-1] = '\''; fprintf(fp, "%s", tbuf2); } } i += n; break; case 'L': ival = (int)*(unsigned char *)buf; if( maskonly ){ if( !ival || (ival == 'F') || (ival == 'f') ) fprintf(fp, xfmts, "."); else fprintf(fp, xfmt, "T"); } else{ if( !ival || (ival == 'F') || (ival == 'f') ) fprintf(fp, xfmt, "F"); else fprintf(fp, xfmt, "T"); } buf += sizeof(char); break; default: fprintf(fp, xfmts, "?"); break; } } } #ifdef ANSI_FUNC static void usage (char *fname) #else static void usage(fname) char *fname; #endif { fprintf(stderr, "usage: %s [-f format] [-l] [-n] [-T] iname [columns|bitpix=n]\n", fname); fprintf(stderr, "optional switches:\n"); fprintf(stderr, " -f 'format' # format definitions for table columns\n"); fprintf(stderr, " -l # display image as a list containing the columns X, Y, VAL\n"); fprintf(stderr, " -n # don't output header\n"); fprintf(stderr, " -F [c] # use specified character as column separator (def: space)\n"); fprintf(stderr, " -T # output in rdb/starbase format (tab separators)\n"); fprintf(stderr, "For tables, columns to display can be specified.\n"); fprintf(stderr, "For images, data type (bitpix) of display can be specified.\n"); fprintf(stderr, "\n(version: %s)\n", FUN_VERSION); exit(1); } #ifdef ANSI_FUNC int main (int argc, char **argv) #else int main(argc, argv) int argc; char **argv; #endif { int c; int i, j, k; int args; int got; int type; int x0; int y0; int dim1; int dim2; int block; int bitpix; int dtype; int scaled; int ibitpix; int rowsize; int val; int ncol=0; int dmode=0; int dolist=0; int dohead=1; size_t size; char *mode=NULL; char *formatstr=NULL; char *actcols=NULL; char *vfmt=NULL; char *s; char *buf; char *ebuf; char *eptr; char *mbuf; char tbuf[SZ_LINE]; char **names=NULL; char **tdims=NULL; int *types=NULL; int *modes=NULL; int *ns=NULL; int *offsets=NULL; double dval; Fun fun; /* exit on gio errors */ if( !getenv("GERROR") ) setgerror(2); /* get maxrow,if user-specified */ if( (s=getenv("FUN_MAXROW")) != NULL ) maxrow = atoi(s); /* we want the args in the same order in which they arrived, and gnu getopt sometimes changes things without this */ putenv("POSIXLY_CORRECT=true"); /* process the type of data we have */ /* process switch arguments */ while ((c = getopt(argc, argv, "f:lnF:T")) != -1){ switch(c){ case 'f': formatstr = xstrdup(optarg); break; case 'l': dolist = 1; break; case 'n': dohead = 0; break; case 'F': coldelim = *optarg; break; case 'T': dmode |= DMODE_RDB; coldelim = '\t'; break; } } args = argc - optind; if( args < 1 ) usage(argv[0]); /* seed the format buffers with the default values */ for(i=0; i= 2 ){ mode = argv[optind+1]; } else{ /* if not present and if the data is scaled and int, read it as float */ FunInfoGet(fun, FUN_SCALED, &scaled, FUN_DTYPE, &dtype, 0); if( scaled && (dtype>=-2) ) mode = "bitpix=-32"; } /* see if we want only the mask */ mbuf = xstrdup(mode); if( _FunKeyword(mbuf, "mask", "FUN_MASK", tbuf, SZ_LINE) ){ if( !strcasecmp(tbuf, "all") ) dmode |= DMODE_MASKONLY; } if( mbuf ) xfree(mbuf); /* extract and bin the data section into an image buffer */ if( !(buf = FunImageGet(fun, NULL, mode)) ) gerror(stderr, "can't FunImageGet: %s\n", argv[optind]); /* get required information from funtools structure. this should come after the ImageGet call, in case that call changed fun_sect_bitpix value */ FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, FUN_SECT_X0, &x0, FUN_SECT_Y0, &y0, FUN_SECT_BLOCK, &block, FUN_SECT_BITPIX, &bitpix, FUN_BITPIX, &ibitpix, 0); /* set dim2 to 1 for a 1D image */ if( dim2 == 0 ) dim2 = 1; /* display header */ if( dolist ){ if( dmode & DMODE_MASKONLY ) gerror(stderr, "'list' and 'maskonly' are mutually exclusive\n"); if( dohead ){ Header(stdout, dmode, "X", 'J', 1, NULL); fprintf(stdout, "%c", coldelim); Header(stdout, dmode, "Y", 'J', 1, NULL); fprintf(stdout, "%c", coldelim); Header(stdout, dmode, "VALUE", bitpix, 1, NULL); fprintf(stdout, "%c", '\n'); Dashes(stdout, dmode, NULL, 'J', 1); fprintf(stdout, "%c", coldelim); Dashes(stdout, dmode, NULL, 'J', 1); fprintf(stdout, "%c", coldelim); Dashes(stdout, dmode, NULL, bitpix, 1); fprintf(stdout, "%c", '\n'); } if( ft_sizeof(bitpix) ) size = ft_sizeof(bitpix); else size = ft_sizeof(ibitpix); /* print out values */ for(i=0; i=0; i--){ if( block == 1 ){ fprintf(stdout, "%8d:", y0+i); } else{ for(dval=0.0, j=0; j= 2 ) actcols = argv[optind+1]; FunColumnActivate(fun, actcols, NULL); /* if we specified columns, we also can specify "mask=transparent" and get all events, with the regionid (assuming we specified the region column to display as well) */ if( args >= 3 ){ mode = argv[optind+2]; } FunInfoGet(fun, FUN_ROWSIZE, &rowsize, FUN_NCOL, &ncol, 0); /* get information for each column */ names = (char **)xcalloc(ncol, sizeof(char *)); tdims = (char **)xcalloc(ncol, sizeof(char *)); types = (int *)xcalloc(ncol, sizeof(int)); modes = (int *)xcalloc(ncol, sizeof(int)); ns = (int *)xcalloc(ncol, sizeof(int)); offsets = (int *)xcalloc(ncol, sizeof(int)); for(i=0; i, using the first free int value for */ else{ for(j=1; ; j++){ snprintf(tbuf, SZ_LINE-1, "%s%d", COL_REGION_ONAME, j); if( !FunColumnLookup(fun, tbuf, 0, NULL, NULL, NULL, NULL, NULL, NULL) ){ names[i] = xstrdup(tbuf); break; } } } } /* ... since might have to change "$n" to something else */ if( names[i] && !strcasecmp(names[i], COL_NUM_NAME) ){ xfree(names[i]); /* best to use "n", if its not already used */ if( !FunColumnLookup(fun, COL_NUM_ONAME, 0, NULL, NULL, NULL, NULL, NULL, NULL) ) names[i] = xstrdup(COL_NUM_ONAME); /* otherwise use region, using the first free int value for */ else{ for(j=1; ; j++){ snprintf(tbuf, SZ_LINE-1, "%s%d", COL_NUM_ONAME, j); if( !FunColumnLookup(fun, tbuf, 0, NULL, NULL, NULL, NULL, NULL, NULL) ){ names[i] = xstrdup(tbuf); break; } } } } } /* if we have a formatstring, we need to process it now */ if( formatstr ){ Format(formatstr, names, ncol); } /* otherwise look for a view format or an environment variable */ else{ FunInfoGet(fun, FUN_VFMT, &vfmt, 0); if( vfmt ){ Format(vfmt, names, ncol); } /* look for environment variable */ else if( (s=getenv("FUN_FORMAT")) != NULL ){ Format(s, names, ncol); } } /* output header, if necessary */ if( dohead ){ /* output header */ for(i=0, j=0; i