diff options
Diffstat (limited to 'funtools/fitsy/headtable.c')
-rw-r--r-- | funtools/fitsy/headtable.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/funtools/fitsy/headtable.c b/funtools/fitsy/headtable.c new file mode 100644 index 0000000..0e34d59 --- /dev/null +++ b/funtools/fitsy/headtable.c @@ -0,0 +1,299 @@ +/* Fitsy FITS routines to load and store #FITSTable structures. + */ + +#include <xos.h> +#include "fitsy.h" + +char * ft_formattyp(c) + char c; +{ + switch ( c ) { + case 'L': return "c"; + case 'X': return "x"; + case 'B': return "ud"; + case 'I': return "d"; + case 'J': return "d"; + case 'K': return "lld"; + case 'U': return "ud"; + case 'V': return "ud"; + case 'F': return "f"; + case 'E': return "f"; + case 'D': return "f"; + case 'A': return "s"; + case 'C': return "f"; + case 'M': return "f"; + case 'P': return "x"; + case 'G': return "f"; + } + + /* probably won't work, but a NULL will segv */ + return ""; +} + +char *ft_format(col) + FITSTCol col; +{ + char format[80]; + + char t = col->type; + int w = col->width; + int p = col->prec; + + if ( col->disp != NULL ) { + sscanf(col->disp, " %c %d.%d", &t, &w, &p); + } + + snprintf(format, 80, "%%%d.%d%s", w, p, ft_formattyp(t)); + return strdup(format); +} + +int ft_sizeof(c) + int c; +{ + switch ( c ) { + case 'P': return 8; + case 'U': return 2; + case 'I': return 2; + case 'V': return 4; + case 'J': return 4; + case 'K': return 8; + case 'F': return 4; + case 'E': return 4; + case 'D': return 8; + case 'A': return 1; + case 'L': return 1; + case 'X': return 1; + case 'B': return 1; + case 'C': return 8; + case 'M': return 16; + + case 8: return 1; + case 16: return 2; + case 32: return 4; + case 64: return 8; + + case FT_UNSIGNED | 8: return 1; + case FT_UNSIGNED | 16: return 2; + case FT_UNSIGNED | 32: return 4; + + case -32: return 4; + case -64: return 8; + + } + + return 0; +} + + +/* Allocate and load a #FITSTable data structure. + */ +FITSTable ft_tableloadhead(fits) + FITSHead fits; +{ + FITSTable table = NULL; + FITSCard card; + char *xtension; + int i; + + int offset = 0; + + if ( (xtension = ft_headget(fits, "XTENSION", 0, &card)) != NULL + && ( !strcmp(xtension, "TABLE") + || !strcmp(xtension, "BINTABLE") + || !strcmp(xtension, "A3DTABLE") + || !strcmp(xtension, "3DTABLE") ) ) { + Malloc(table, sizeof(struct _FITSTable)); + + table->tabtype = !strcmp(xtension, "TABLE"); + if ( !(table->tfields = ft_headgeti(fits, "TFIELDS", 0, 0, &card)) ) { + (void)Free(table); + return NULL; + } + + ft_headindex(fits); + + Malloc(table->col, sizeof(struct _FITSTCol) * table->tfields); + + for ( i = 1; i <= table->tfields; i++ ) { + FITSCard card; + char *tform; + int r = 0, w = 0, p = 0; + char t = ' ', h = ' '; + char format[64]; + + table->col[i-1].name = ft_headgets(fits, "TTYPE", i, NULL, &card); + table->col[i-1].unit = ft_headgets(fits, "TUNIT", i, NULL, &card); + table->col[i-1].scale = ft_headgetr(fits, "TSCAL", i, 1.0, &card); + table->col[i-1].has_scale = card != NULL; + table->col[i-1].zero = ft_headgetr(fits, "TZERO", i, 0.0, &card); + table->col[i-1].has_zero = card != NULL; + table->col[i-1].scaled = table->col[i-1].has_zero || table->col[i-1].has_scale; + table->col[i-1].ablank = ft_headgets(fits, "TNULL", i, NULL, &card); + table->col[i-1].has_blank = card != NULL; + tform = ft_headget(fits, "TFORM", i, &card); + /* if we have no TFORM, its an illegal binary table */ + if( !card ){ + table->tfields = i; + ft_tablefree(table); + return NULL; + } + + /* hacked support for variable length arrays. we ignore the data + and just process the 2 64-bit pointers */ + if ( sscanf(tform, "%d P %c ( %d )", &r, &t, &w) == 3 ) { + /* save values for variable length array */ + table->col[i-1].vla = strdup(tform); + table->col[i-1].vla_type = t; + table->col[i-1].vla_max = w; + /* set up vla pointer values in the table */ + r = 2; + t = 'J'; + w = 0; + } + else if ( sscanf(tform, "P %c ( %d )", &t, &w) == 2 ) { + /* save values for variable length array */ + table->col[i-1].vla = strdup(tform); + table->col[i-1].vla_type = t; + table->col[i-1].vla_max = w; + /* set up vla pointer values in the table */ + r = 2; + t = 'J'; + w = 0; + } + else if ( sscanf(tform, "%d Q %c ( %d )", &r, &t, &w) == 3 ) { + /* save values for variable length array */ + table->col[i-1].vla = strdup(tform); + table->col[i-1].vla_type = t; + table->col[i-1].vla_max = w; + /* set up vla pointer values in the table */ + r = 2; + t = 'K'; + w = 0; + } + else if ( sscanf(tform, "Q %c ( %d )", &t, &w) == 2 ) { + /* save values for variable length array */ + table->col[i-1].vla = strdup(tform); + table->col[i-1].vla_type = t; + table->col[i-1].vla_max = w; + /* set up vla pointer values in the table */ + r = 2; + t = 'K'; + w = 0; + } + else{ + if ( !sscanf(tform, " %d %c %d.%d", &r, &t, &w, &p) ) { + r = 1; + sscanf(tform, " %c %d.%d", &t, &w, &p); + } + } + if ( table->tabtype ) { /* ASCII TABLE */ + table->col[i-1].format = strdup(format); + + table->col[i-1].type = 'A'; + table->col[i-1].n = 1; + table->col[i-1].size = w; + table->col[i-1].offset = ft_headgeti(fits, "TBCOL", i, 0, &card) + - 1; + table->col[i-1].heap = 0; + table->col[i-1].prec = p; + + } else { /* BINTABLE */ + + switch ( t ) { + case 'P': + table->col[i-1].heap = 1; + table->col[i-1].type = h; + table->col[i-1].n = p; + table->col[i-1].size = ft_sizeof(table->col[i-1].type); + table->col[i-1].width= table->col[i-1].size + * table->col[i-1].n; + break; + case 'A': + p = 1; + if ( !sscanf(tform, " %d %c%d", &r, &t, &p) ) { + r = 1; + sscanf(tform, " %c%d", &t, &p); + } + + table->col[i-1].heap = 0; + table->col[i-1].type = t; + table->col[i-1].n = r; + table->col[i-1].size = 1; + table->col[i-1].width= table->col[i-1].size + * table->col[i-1].n; + break; + case 'X': + table->col[i-1].heap = 0; + table->col[i-1].type = t; + table->col[i-1].n = r; + table->col[i-1].size = ft_sizeof(table->col[i-1].type); + table->col[i-1].width= + ((table->col[i-1].size * table->col[i-1].n) + 7) / 8; + table->col[i-1].prec = p; + break; + default: + table->col[i-1].heap = 0; + table->col[i-1].type = t; + table->col[i-1].n = r; + table->col[i-1].size = ft_sizeof(table->col[i-1].type); + table->col[i-1].width= table->col[i-1].size + * table->col[i-1].n; + table->col[i-1].prec = p; + break; + } + + table->col[i-1].offset = offset; + + if ( table->col[i-1].heap ) + offset += 8; + else + offset += table->col[i-1].width; + + if ( table->col[i-1].ablank ) + table->col[i-1].dblank = + strtod(table->col[i-1].ablank, NULL); + + table->col[i-1].disp = ft_headgets(fits, "TDISP", i, NULL, &card); + table->col[i-1].format = ft_format(&table->col[i-1]); + } + } + if ( table->tabtype ) { /* ASCII TABLE */ + for ( i = 1; i < table->tfields; i++ ) { + table->col[i-1].width = table->col[i].offset - table->col[i-1].offset; + } + table->col[i-1].width = fits->basic->naxis[0] - table->col[i-1].offset; + } + + } + + return table; +} + +/* Store a #FITSTable structure in a FITS header. + */ +void ft_tablestorhead(fits, table) + FITSHead fits; + FITSTable table; +{ + ft_basicstorhead(fits, fits->basic); +} + +/* Free a #FITSTable structure. + */ +void ft_tablefree(table) + FITSTable table; +{ + int i; + + for ( i = 1; i <= table->tfields; i++ ) { + if ( table->col[i-1].name ) free(table->col[i-1].name); + if ( table->col[i-1].unit ) free(table->col[i-1].unit); + if ( table->col[i-1].disp ) free(table->col[i-1].disp); + if ( table->col[i-1].format ) free(table->col[i-1].format); + if ( table->col[i-1].vla ) free(table->col[i-1].vla); + if ( table->col[i-1].ablank ) free(table->col[i-1].ablank); + } + + (void)Free(table->col); + (void)Free(table); +} |