More bits from qfits
parent
28dd111b0f
commit
953d2cb3ec
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# qfits tools Makefile
|
||||
#
|
||||
|
||||
#
|
||||
# General definitions
|
||||
#
|
||||
|
||||
include ../config.make
|
||||
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
MV = mv
|
||||
BINDIR = ../bin
|
||||
|
||||
COMPF = $(CFLAGS) -I../include
|
||||
LINKF = $(LFLAGS) -L../lib -lqfits
|
||||
|
||||
default: all
|
||||
|
||||
|
||||
PROGS= $(BINDIR)/dtfits \
|
||||
$(BINDIR)/flipx \
|
||||
$(BINDIR)/dfits \
|
||||
$(BINDIR)/frameq \
|
||||
$(BINDIR)/replacekey \
|
||||
$(BINDIR)/qextract
|
||||
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
veryclean:
|
||||
@(echo "cleaning qfits programs...")
|
||||
@($(RM) $(PROGS))
|
||||
|
||||
|
||||
$(BINDIR)/dfits: dfits.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/dfits dfits.c $(LINKF)
|
||||
|
||||
$(BINDIR)/dtfits: dtfits.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/dtfits dtfits.c $(LINKF)
|
||||
|
||||
$(BINDIR)/flipx: flipx.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/flipx flipx.c $(LINKF)
|
||||
|
||||
$(BINDIR)/frameq: frameq.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/frameq frameq.c $(LINKF)
|
||||
|
||||
$(BINDIR)/replacekey: replacekey.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/replacekey replacekey.c $(LINKF)
|
||||
|
||||
$(BINDIR)/qextract: qextract.c
|
||||
$(CC) $(COMPF) -o $(BINDIR)/qextract qextract.c $(LINKF)
|
||||
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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] <list of FITS files>\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 ;
|
||||
}
|
|
@ -0,0 +1,542 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file dtfits.c
|
||||
@date July 1999
|
||||
@version $Revision: 1.14 $
|
||||
@brief FITS table dump
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: dtfits.c,v 1.14 2005/07/20 14:25:16 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/07/20 14:25:16 $
|
||||
$Revision: 1.14 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "qfits.h"
|
||||
#include "xmemory.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define ELEMENT_MAX_DISP_SIZE 50
|
||||
#define DISP_SIZE_INT 5
|
||||
#define DISP_SIZE_DOUBLE 8
|
||||
#define DISP_SIZE_FLOAT 7
|
||||
#define DISP_SIZE_CHAR 1
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int dump_extension_bin(qfits_table *, FILE *, void **, char, int,
|
||||
int) ;
|
||||
static int dump_extension_ascii(qfits_table *, FILE *, void **, char,
|
||||
int, int) ;
|
||||
static int dump_extension(qfits_table *, FILE *, char, int, int) ;
|
||||
static void qfits_dump(char *, char *, int, char, int);
|
||||
static void usage(char * pname) ;
|
||||
static char prog_desc[] = "FITS table dump" ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char name_i[FILENAMESZ] ;
|
||||
char name_o[FILENAMESZ] ;
|
||||
int i ;
|
||||
int data_only ;
|
||||
char separator ;
|
||||
int ext ;
|
||||
|
||||
/* Initialize */
|
||||
data_only = 0 ;
|
||||
separator = '|' ;
|
||||
ext = -1 ;
|
||||
|
||||
i=1 ;
|
||||
|
||||
if (argc<2) usage(argv[0]);
|
||||
|
||||
while (i<argc) {
|
||||
if (!strcmp(argv[i], "--help") ||
|
||||
!strcmp(argv[i], "-h")) {
|
||||
usage(argv[0]);
|
||||
} else if (!strcmp(argv[i], "-d")) {
|
||||
data_only=1 ;
|
||||
} else if (!strcmp(argv[i], "-s")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -s needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
separator = argv[i][0] ;
|
||||
|
||||
|
||||
} else if (!strcmp(argv[i], "-x")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -x needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
ext = atoi(argv[i]) ;
|
||||
} else {
|
||||
break ;
|
||||
}
|
||||
i++ ;
|
||||
}
|
||||
if ((argc-i)<1) {
|
||||
fprintf(stderr, "missing input file name\n");
|
||||
return -1 ;
|
||||
}
|
||||
strcpy(name_i, argv[i]);
|
||||
i++ ;
|
||||
if ((argc-i)<1) name_o[0] = 0 ;
|
||||
else strcpy(name_o, argv[i]);
|
||||
|
||||
qfits_dump(name_i, name_o, data_only, separator, ext);
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static void usage(char * pname)
|
||||
{
|
||||
printf("%s -- %s\n", pname, prog_desc);
|
||||
printf(
|
||||
"use : %s [options] <FITS table> [out]\n"
|
||||
"options are:\n"
|
||||
"\t-d to dump data only (no headers)\n"
|
||||
"\t-s <char> to output data with separator <char>\n"
|
||||
"\n",
|
||||
pname);
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
static void qfits_dump(
|
||||
char * name_i,
|
||||
char * name_o,
|
||||
int data_only,
|
||||
char separator,
|
||||
int ext)
|
||||
{
|
||||
qfits_table * tdesc ;
|
||||
FILE * out ;
|
||||
int xtnum_start, xtnum_stop ;
|
||||
int n_ext ;
|
||||
int i ;
|
||||
|
||||
/* Set where to send the output */
|
||||
if (name_o[0]==(char)0) {
|
||||
out = stdout ;
|
||||
} else {
|
||||
if ((out = fopen(name_o, "w"))==NULL) {
|
||||
fprintf(stderr, "cannot create output file [%s]\n", name_o);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data_only) {
|
||||
fprintf(out, "#\n");
|
||||
fprintf(out, "# file %s\n", name_i);
|
||||
}
|
||||
|
||||
/* Query number of extensions in the file */
|
||||
n_ext = qfits_query_n_ext(name_i);
|
||||
if (!data_only) {
|
||||
fprintf(out, "# extensions %d\n", n_ext);
|
||||
}
|
||||
/* If no extension, bail out */
|
||||
if (n_ext<1) {
|
||||
if (out!=stdout) fclose(out) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/* 1 extension required or all */
|
||||
if (ext < 1) {
|
||||
xtnum_start = 1 ;
|
||||
xtnum_stop = n_ext ;
|
||||
} else if (ext > n_ext) {
|
||||
fprintf(out, "# requested extension does not exist %d\n", ext) ;
|
||||
if (out!=stdout) fclose(out) ;
|
||||
return ;
|
||||
} else {
|
||||
xtnum_start = xtnum_stop = ext ;
|
||||
}
|
||||
|
||||
/* Loop over all extensions */
|
||||
for (i=xtnum_start ; i<=xtnum_stop ; i++) {
|
||||
if (!data_only) {
|
||||
fprintf(out, "# --------------------------------------------\n");
|
||||
fprintf(out, "# XTENSION %d\n", i);
|
||||
}
|
||||
if ((tdesc = qfits_table_open(name_i, i)) == NULL) {
|
||||
printf("cannot open table [%s]:[%d]\n", name_i, i);
|
||||
if (out!=stdout) fclose(out);
|
||||
return ;
|
||||
}
|
||||
dump_extension(tdesc, out, separator, data_only, 1) ;
|
||||
qfits_table_close(tdesc);
|
||||
}
|
||||
fclose(out) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
static int dump_extension(
|
||||
qfits_table * tdesc,
|
||||
FILE * out,
|
||||
char separator,
|
||||
int data_only,
|
||||
int use_zero_scale)
|
||||
{
|
||||
void ** cols ;
|
||||
int i, j ;
|
||||
|
||||
if (!data_only) {
|
||||
fprintf(out, "# Number of columns %d\n", tdesc->nc);
|
||||
fprintf(out, "#\n");
|
||||
}
|
||||
|
||||
/* First read the columns in memory */
|
||||
cols = malloc(tdesc->nc * sizeof(void*)) ;
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
cols[i] = qfits_query_column_data(tdesc, i, NULL, NULL) ;
|
||||
if (cols[i] == NULL) {
|
||||
fprintf(out, "# Cannot load column nb %d\n", i+1) ;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tdesc->tab_t) {
|
||||
case QFITS_BINTABLE:
|
||||
dump_extension_bin(tdesc, out, cols, separator, data_only,
|
||||
use_zero_scale) ;
|
||||
break ;
|
||||
case QFITS_ASCIITABLE:
|
||||
dump_extension_ascii(tdesc, out, cols, separator, data_only,
|
||||
use_zero_scale) ;
|
||||
break ;
|
||||
default:
|
||||
fprintf(out, "Table type not recognized") ;
|
||||
break ;
|
||||
}
|
||||
|
||||
for (i=0 ; i<tdesc->nc ; i++) if (cols[i]) free(cols[i]) ;
|
||||
free(cols) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int dump_extension_bin(
|
||||
qfits_table * tdesc,
|
||||
FILE * out,
|
||||
void ** cols,
|
||||
char separator,
|
||||
int data_only,
|
||||
int use_zero_scale)
|
||||
{
|
||||
int * col_sizes ;
|
||||
qfits_col * col ;
|
||||
char * ccol ;
|
||||
unsigned char * ucol ;
|
||||
double * dcol ;
|
||||
float * fcol ;
|
||||
short * scol ;
|
||||
int * icol ;
|
||||
int size ;
|
||||
int field_size ;
|
||||
char * str ;
|
||||
char ctmp[512];
|
||||
int i, j, k ;
|
||||
|
||||
/* GET THE FIELDS SIZES */
|
||||
col_sizes = calloc(tdesc->nc, sizeof(int)) ;
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
col = tdesc->col + i ;
|
||||
col_sizes[i] = (int)strlen(col->tlabel) ;
|
||||
switch(col->atom_type) {
|
||||
case TFITS_BIN_TYPE_A:
|
||||
size = col->atom_size * col->atom_nb ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_B:
|
||||
size = col->atom_nb * (DISP_SIZE_INT + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_D:
|
||||
case TFITS_BIN_TYPE_M:
|
||||
size = col->atom_nb * (DISP_SIZE_DOUBLE + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_E:
|
||||
case TFITS_BIN_TYPE_C:
|
||||
size = col->atom_nb * (DISP_SIZE_FLOAT + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_I:
|
||||
size = col->atom_nb * (DISP_SIZE_INT + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_J:
|
||||
size = col->atom_nb * (DISP_SIZE_INT + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_L:
|
||||
size = col->atom_nb * (DISP_SIZE_CHAR + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_X:
|
||||
size = col->atom_nb * (DISP_SIZE_INT + 2) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_P:
|
||||
size = col->atom_nb * (DISP_SIZE_INT + 2) ;
|
||||
break ;
|
||||
default:
|
||||
fprintf(out, "Type not recognized") ;
|
||||
break ;
|
||||
}
|
||||
if (size > col_sizes[i]) col_sizes[i] = size ;
|
||||
}
|
||||
|
||||
/* Print out the column names */
|
||||
if (!data_only) {
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
col = tdesc->col + i ;
|
||||
fprintf(out, "%*s", col_sizes[i], col->tlabel);
|
||||
if (i!=(tdesc->nc-1)) printf("%c", separator);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
/* Get the string to write according to the type */
|
||||
for (j=0 ; j<tdesc->nr ; j++) {
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
if (cols[i] == NULL) continue ;
|
||||
col = tdesc->col + i ;
|
||||
field_size = col->atom_nb * ELEMENT_MAX_DISP_SIZE ;
|
||||
str = malloc(field_size * sizeof(char)) ;
|
||||
str[0] = (char)0 ;
|
||||
switch(col->atom_type) {
|
||||
case TFITS_BIN_TYPE_A:
|
||||
ccol = (char*)(cols[i]) ;
|
||||
ccol += col->atom_size * col->atom_nb * j ;
|
||||
strncpy(ctmp, ccol, col->atom_size * col->atom_nb) ;
|
||||
ctmp[col->atom_size*col->atom_nb] = (char)0 ;
|
||||
strcpy(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_B:
|
||||
ucol = (unsigned char*)(cols[i]) ;
|
||||
ucol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%d, ", (int)ucol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp,"%d",(int)ucol[col->atom_nb-1]);
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_D:
|
||||
case TFITS_BIN_TYPE_M:
|
||||
dcol = (double*)(cols[i]) ;
|
||||
dcol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%g, ", dcol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%g", dcol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_E:
|
||||
case TFITS_BIN_TYPE_C:
|
||||
fcol = (float*)(cols[i]) ;
|
||||
fcol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%f, ", fcol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%f", fcol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_I:
|
||||
scol = (short*)(cols[i]) ;
|
||||
scol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%d, ", scol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%d", scol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_J:
|
||||
icol = (int*)(cols[i]) ;
|
||||
icol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%d, ", icol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%d", icol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_L:
|
||||
ccol = (char*)(cols[i]) ;
|
||||
ccol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%c, ", ccol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%c", ccol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_X:
|
||||
ucol = (unsigned char*)(cols[i]) ;
|
||||
ucol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%d, ", ucol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%d", ucol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_BIN_TYPE_P:
|
||||
icol = (int*)(cols[i]) ;
|
||||
icol += col->atom_nb * j ;
|
||||
/* For each atom of the column */
|
||||
for (k=0 ; k<col->atom_nb-1 ; k++) {
|
||||
sprintf(ctmp, "%d, ", icol[k]) ;
|
||||
strcat(str, ctmp) ;
|
||||
}
|
||||
/* Handle the last atom differently: no ',' */
|
||||
sprintf(ctmp, "%d", icol[col->atom_nb-1]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
default:
|
||||
fprintf(out, "Type not recognized") ;
|
||||
break ;
|
||||
}
|
||||
fprintf(out, "%*s", col_sizes[i], str);
|
||||
if (i!=(tdesc->nc-1)) printf("%c", separator);
|
||||
free(str) ;
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int dump_extension_ascii(
|
||||
qfits_table * tdesc,
|
||||
FILE * out,
|
||||
void ** cols,
|
||||
char separator,
|
||||
int data_only,
|
||||
int use_zero_scale)
|
||||
{
|
||||
int * col_sizes ;
|
||||
qfits_col * col ;
|
||||
char * ccol ;
|
||||
double * dcol ;
|
||||
float * fcol ;
|
||||
int * icol ;
|
||||
int size ;
|
||||
int field_size ;
|
||||
char * str ;
|
||||
char ctmp[512];
|
||||
int i, j, k ;
|
||||
|
||||
/* GET THE FIELDS SIZES */
|
||||
col_sizes = calloc(tdesc->nc, sizeof(int)) ;
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
col = tdesc->col + i ;
|
||||
col_sizes[i] = (int)strlen(col->tlabel) ;
|
||||
switch(col->atom_type) {
|
||||
case TFITS_ASCII_TYPE_A:
|
||||
size = col->atom_nb ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_I:
|
||||
size = DISP_SIZE_INT ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_E:
|
||||
case TFITS_ASCII_TYPE_F:
|
||||
size = DISP_SIZE_FLOAT ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_D:
|
||||
size = DISP_SIZE_DOUBLE ;
|
||||
break ;
|
||||
default:
|
||||
fprintf(out, "Type not recognized") ;
|
||||
break ;
|
||||
}
|
||||
if (size > col_sizes[i]) col_sizes[i] = size ;
|
||||
}
|
||||
|
||||
/* Print out the column names */
|
||||
if (!data_only) {
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
col = tdesc->col + i ;
|
||||
fprintf(out, "%*s", col_sizes[i], col->tlabel);
|
||||
if (i!=(tdesc->nc-1)) printf("%c", separator);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
/* Get the string to write according to the type */
|
||||
for (j=0 ; j<tdesc->nr ; j++) {
|
||||
for (i=0 ; i<tdesc->nc ; i++) {
|
||||
if (cols[i] == NULL) continue ;
|
||||
col = tdesc->col + i ;
|
||||
field_size = col->atom_nb * ELEMENT_MAX_DISP_SIZE ;
|
||||
str = malloc(field_size * sizeof(char)) ;
|
||||
str[0] = (char)0 ;
|
||||
switch(col->atom_type) {
|
||||
case TFITS_ASCII_TYPE_A:
|
||||
ccol = (char*)(cols[i]) ;
|
||||
ccol += col->atom_nb * j ;
|
||||
strncpy(ctmp, ccol, col->atom_nb) ;
|
||||
ctmp[col->atom_nb] = (char)0 ;
|
||||
strcpy(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_I:
|
||||
icol = (int*)(cols[i]) ;
|
||||
icol += j ;
|
||||
sprintf(ctmp, "%d", icol[0]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_E:
|
||||
case TFITS_ASCII_TYPE_F:
|
||||
fcol = (float*)(cols[i]) ;
|
||||
fcol += j ;
|
||||
sprintf(ctmp, "%f", fcol[0]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
case TFITS_ASCII_TYPE_D:
|
||||
dcol = (double*)(cols[i]) ;
|
||||
dcol += j ;
|
||||
sprintf(ctmp, "%g", dcol[0]) ;
|
||||
strcat(str, ctmp) ;
|
||||
break ;
|
||||
default:
|
||||
fprintf(out, "Type not recognized") ;
|
||||
break ;
|
||||
}
|
||||
fprintf(out, "%*s", col_sizes[i], str);
|
||||
if (i!=(tdesc->nc-1)) printf("%c", separator);
|
||||
free(str) ;
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file flipx.c
|
||||
@author N. Devillard
|
||||
@date July 2001
|
||||
@version $Revision: 1.5 $
|
||||
@brief flip x axis in a FITS image
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: flipx.c,v 1.5 2002/12/04 13:28:25 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2002/12/04 13:28:25 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include "qfits.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Private functions
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Swap pixels between position p1 and p2, regardless of the pixel
|
||||
* type and endian-ness of the local host.
|
||||
*/
|
||||
static void swap_pix(char * buf, int p1, int p2, int psize)
|
||||
{
|
||||
int i ;
|
||||
char c ;
|
||||
|
||||
for (i=0 ; i<psize ; i++) {
|
||||
c = buf[p1+i] ;
|
||||
buf[p1+i] = buf[p2+i];
|
||||
buf[p2+i] = c ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Main processing function. It expects one only file name
|
||||
* and will flip pixels on the input frame.
|
||||
*/
|
||||
static int fits_flip(char * pname, char * filename)
|
||||
{
|
||||
char * sval ;
|
||||
int dstart;
|
||||
int lx, ly ;
|
||||
int bpp ;
|
||||
int i, j ;
|
||||
char * buf ;
|
||||
char * fbuf ;
|
||||
int psize;
|
||||
struct stat fileinfo ;
|
||||
int fd ;
|
||||
|
||||
printf("%s: processing %s\n", pname, filename);
|
||||
|
||||
if (stat(filename, &fileinfo)!=0) {
|
||||
return -1 ;
|
||||
}
|
||||
if (fileinfo.st_size<1) {
|
||||
printf("cannot stat file\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Retrieve image attributes */
|
||||
if (is_fits_file(filename)!=1) {
|
||||
printf("not a FITS file\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
sval = qfits_query_hdr(filename, "NAXIS1");
|
||||
if (sval==NULL) {
|
||||
printf("cannot read NAXIS1\n");
|
||||
return -1 ;
|
||||
}
|
||||
lx = atoi(sval);
|
||||
sval = qfits_query_hdr(filename, "NAXIS2");
|
||||
if (sval==NULL) {
|
||||
printf("cannot read NAXIS2\n");
|
||||
return -1 ;
|
||||
}
|
||||
ly = atoi(sval);
|
||||
sval = qfits_query_hdr(filename, "BITPIX");
|
||||
if (sval==NULL) {
|
||||
printf("cannot read BITPIX\n");
|
||||
return -1 ;
|
||||
}
|
||||
bpp = atoi(sval);
|
||||
|
||||
psize = bpp/8 ;
|
||||
if (psize<0) psize=-psize ;
|
||||
|
||||
/* Retrieve start of first data section */
|
||||
if (qfits_get_hdrinfo(filename, 0, &dstart, NULL)!=0) {
|
||||
printf("reading header information\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Map the input file in read/write mode (input file is modified) */
|
||||
if ((fd=open(filename, O_RDWR))==-1) {
|
||||
perror("open");
|
||||
printf("reading file\n");
|
||||
return -1 ;
|
||||
}
|
||||
fbuf = (char*)mmap(0,
|
||||
fileinfo.st_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0);
|
||||
if (fbuf==(char*)-1) {
|
||||
perror("mmap");
|
||||
printf("mapping file\n");
|
||||
return -1 ;
|
||||
}
|
||||
buf = fbuf + dstart ;
|
||||
|
||||
/* Double loop */
|
||||
for (j=0 ; j<ly ; j++) {
|
||||
for (i=0 ; i<lx/2 ; i++) {
|
||||
/* Swap bytes */
|
||||
swap_pix(buf, i*psize, (lx-i-1)*psize, psize);
|
||||
}
|
||||
buf += lx * psize ;
|
||||
}
|
||||
if (munmap(fbuf, fileinfo.st_size)!=0) {
|
||||
printf("unmapping file\n");
|
||||
return -1 ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int i ;
|
||||
int err ;
|
||||
|
||||
if (argc<2) {
|
||||
printf("use: %s <list of FITS files...>\n", argv[0]);
|
||||
return 1 ;
|
||||
}
|
||||
err=0 ;
|
||||
for (i=1 ; i<argc ; i++) {
|
||||
err += fits_flip(argv[0], argv[i]) ;
|
||||
}
|
||||
if (err>0) {
|
||||
fprintf(stderr, "%s: %d error(s) occurred\n", argv[0], err);
|
||||
return -1 ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
|
@ -0,0 +1,461 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file frameq.c
|
||||
@author N. Devillard
|
||||
@date Aug 2000
|
||||
@version $Revision: 1.7 $
|
||||
@brief Classify frames
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: frameq.c,v 1.7 2004/07/21 16:03:21 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2004/07/21 16:03:21 $
|
||||
$Revision: 1.7 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <glob.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "qfits.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* Frame informations needed to classify it */
|
||||
typedef struct _framei {
|
||||
char * name ;
|
||||
char * tplid ;
|
||||
char * origfile ;
|
||||
int expno ;
|
||||
int nexp ;
|
||||
|
||||
struct _framei * next ;
|
||||
} framei ;
|
||||
|
||||
/* Frame queue: is mostly a pointer to a list of frame information objects */
|
||||
typedef struct _frameq {
|
||||
framei * first ;
|
||||
int n ;
|
||||
} frameq ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Global variables
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* List of strings to identify unwanted templates. */
|
||||
char * tpl_filter[] = {
|
||||
"_acq_",
|
||||
"_CheckAoCorrection",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Functions code
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Build a new framei object
|
||||
@param filename FITS file name
|
||||
@return A newly allocated framei obj. NULL in error case
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static framei * framei_new(char * filename)
|
||||
{
|
||||
framei * fi ;
|
||||
char * sval ;
|
||||
char * sval2 ;
|
||||
int i ;
|
||||
|
||||
fi = malloc(sizeof(framei));
|
||||
fi->name = strdup(filename);
|
||||
sval = qfits_query_hdr(filename, "tpl.id");
|
||||
if (sval!=NULL) {
|
||||
/* Filter out unwanted template IDs */
|
||||
i=0 ;
|
||||
while (tpl_filter[i]!=NULL) {
|
||||
if (strstr(sval, tpl_filter[i])!=NULL) return NULL ;
|
||||
i++ ;
|
||||
}
|
||||
fi->tplid = strdup(qfits_pretty_string(sval)) ;
|
||||
} else {
|
||||
fi->tplid = NULL ;
|
||||
}
|
||||
sval = qfits_query_hdr(filename, "origfile");
|
||||
if (sval!=NULL) {
|
||||
sval2 = qfits_pretty_string(sval) ;
|
||||
fi->origfile = strdup(qfits_get_root_name(sval2)) ;
|
||||
} else {
|
||||
fi->origfile = NULL ;
|
||||
}
|
||||
sval = qfits_query_hdr(filename, "tpl.expno");
|
||||
if (sval!=NULL) fi->expno = (int)atoi(sval);
|
||||
else fi->expno = -1 ;
|
||||
sval = qfits_query_hdr(filename, "tpl.nexp");
|
||||
if (sval!=NULL) fi->nexp = (int)atoi(sval);
|
||||
else fi->nexp = -1 ;
|
||||
|
||||
fi->next = NULL ;
|
||||
return fi ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a framei object
|
||||
@param fi Object to delete
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void framei_del(framei * fi)
|
||||
{
|
||||
if (fi==NULL) return ;
|
||||
if (fi->name!=NULL)
|
||||
free(fi->name);
|
||||
if (fi->tplid!=NULL) {
|
||||
free(fi->tplid);
|
||||
}
|
||||
if (fi->origfile!=NULL) {
|
||||
free(fi->origfile);
|
||||
}
|
||||
free(fi);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a frameq object
|
||||
@return A newly allocated empty frameq object
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
frameq * frameq_new(void)
|
||||
{
|
||||
frameq * fq ;
|
||||
|
||||
fq = malloc(sizeof(frameq));
|
||||
fq->first = NULL ;
|
||||
fq->n = 0 ;
|
||||
return fq ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a frameq object
|
||||
@param fq The object to delete
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void frameq_del(frameq * fq)
|
||||
{
|
||||
framei * fi ;
|
||||
framei * fin ;
|
||||
|
||||
if (fq==NULL) return ;
|
||||
|
||||
fi = fq->first ;
|
||||
while (fi!=NULL) {
|
||||
fin = fi->next ;
|
||||
framei_del(fi);
|
||||
fi = fin ;
|
||||
}
|
||||
free(fq);
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Append a new frame to an existing frame queue
|
||||
@param fq The existing frame queue
|
||||
@param filename The file to append name
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void frameq_append(frameq * fq, char * filename)
|
||||
{
|
||||
framei * fi ;
|
||||
framei * fn ;
|
||||
|
||||
if (fq==NULL || filename==NULL) return ;
|
||||
fi = framei_new(filename);
|
||||
if (fi==NULL)
|
||||
return ;
|
||||
if (fq->n==0) {
|
||||
fq->first = fi ;
|
||||
fq->n = 1 ;
|
||||
return ;
|
||||
}
|
||||
|
||||
fn = fq->first ;
|
||||
while (fn->next!=NULL)
|
||||
fn = fn->next ;
|
||||
|
||||
fn->next = fi ;
|
||||
fq->n ++ ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Pop a frame out of the queue
|
||||
@param fq The frame queue
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void frameq_pop(frameq * fq)
|
||||
{
|
||||
framei * first ;
|
||||
|
||||
first = fq->first->next ;
|
||||
framei_del(fq->first);
|
||||
fq->first = first ;
|
||||
fq->n -- ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a frame queue in a file
|
||||
@param fq Frame queue to dump
|
||||
@param out File where the queue is dumped
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void frameq_dump(frameq * fq, FILE * out)
|
||||
{
|
||||
int i ;
|
||||
framei * fi ;
|
||||
|
||||
fi = fq->first ;
|
||||
for (i=0 ; i<fq->n ; i++) {
|
||||
fprintf(out,
|
||||
"%s %s %02d/%02d\n",
|
||||
fi->name,
|
||||
fi->tplid,
|
||||
fi->expno,
|
||||
fi->nexp);
|
||||
fi = fi->next ;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a frame queue from a directory
|
||||
@param dirname Directory name
|
||||
@return A newly allocated frame queue
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
frameq * frameq_load(char * dirname)
|
||||
{
|
||||
frameq * fq ;
|
||||
int i ;
|
||||
glob_t pglob ;
|
||||
char filename[FILENAMESZ];
|
||||
|
||||
/* Look for *.fits *.FITS *.fits.gz *.FITS.gz */
|
||||
sprintf(filename, "%s/*.fits", dirname);
|
||||
glob(filename, GLOB_MARK, NULL, &pglob);
|
||||
sprintf(filename, "%s/*.FITS", dirname);
|
||||
glob(filename, GLOB_APPEND, NULL, &pglob);
|
||||
sprintf(filename, "%s/*.fits.gz", dirname);
|
||||
glob(filename, GLOB_APPEND, NULL, &pglob);
|
||||
sprintf(filename, "%s/*.FITS.gz", dirname);
|
||||
glob(filename, GLOB_APPEND, NULL, &pglob);
|
||||
if (pglob.gl_pathc<1) {
|
||||
printf("found no frame\n");
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
/* Build frame queue */
|
||||
fq = frameq_new();
|
||||
for (i=0 ; i<pglob.gl_pathc ; i++) {
|
||||
printf("\radding %d of %d", i+1, pglob.gl_pathc);
|
||||
fflush(stdout);
|
||||
frameq_append(fq, pglob.gl_pathv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
globfree(&pglob);
|
||||
return fq ;
|
||||
}
|
||||
|
||||
static int stringsort(const void * e1, const void * e2)
|
||||
{
|
||||
return strcmp(*(char**)e1, *(char**)e2);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get TPL.ID keywords from a frame queue
|
||||
@param fq The frame queue
|
||||
@param n Number of values in output
|
||||
@return List of n strings
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char ** frameq_get_tplid(frameq * fq, int * n)
|
||||
{
|
||||
framei * fn ;
|
||||
char ** tplid_all ;
|
||||
char ** tplid ;
|
||||
int i, j ;
|
||||
int ntplid ;
|
||||
|
||||
/* Get all possible values for tplid */
|
||||
tplid_all = malloc(fq->n * sizeof(char*));
|
||||
fn = fq->first ;
|
||||
for (i=0 ; i<fq->n ; i++) {
|
||||
if (fn->tplid==NULL) {
|
||||
tplid_all[i] = strdup("none");
|
||||
} else {
|
||||
tplid_all[i] = strdup(fn->tplid);
|
||||
}
|
||||
fn = fn->next ;
|
||||
}
|
||||
/* Sort all tplid's */
|
||||
qsort(tplid_all, fq->n, sizeof(char*), stringsort);
|
||||
|
||||
/* Compute how many different tplid's can be found */
|
||||
ntplid=1 ;
|
||||
for (i=1 ; i<fq->n ; i++) {
|
||||
if (strcmp(tplid_all[i], tplid_all[i-1])) {
|
||||
ntplid++ ;
|
||||
}
|
||||
}
|
||||
|
||||
tplid = malloc(ntplid * sizeof(char*));
|
||||
tplid[0] = tplid_all[0] ;
|
||||
tplid_all[0] = NULL ;
|
||||
j=0 ;
|
||||
for (i=1 ; i<fq->n ; i++) {
|
||||
if (strcmp(tplid_all[i], tplid[j])) {
|
||||
j++ ;
|
||||
tplid[j] = tplid_all[i] ;
|
||||
} else {
|
||||
free(tplid_all[i]);
|
||||
}
|
||||
tplid_all[i] = NULL ;
|
||||
}
|
||||
free(tplid_all);
|
||||
|
||||
*n = ntplid ;
|
||||
return tplid ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the setting number
|
||||
@param dirname Directory name
|
||||
@return Setting number
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int frameq_getsetnum(char * dirname)
|
||||
{
|
||||
char pattern[FILENAMESZ];
|
||||
glob_t pglob ;
|
||||
int i ;
|
||||
int max ;
|
||||
int num ;
|
||||
|
||||
sprintf(pattern, "%s/set*", dirname);
|
||||
glob(pattern, GLOB_MARK, NULL, &pglob);
|
||||
if (pglob.gl_pathc<1) {
|
||||
max=0 ;
|
||||
} else {
|
||||
sprintf(pattern, "%s/set%%02d", dirname);
|
||||
max=0 ;
|
||||
for (i=0 ; i<pglob.gl_pathc ; i++) {
|
||||
sscanf(pglob.gl_pathv[i], pattern, &num);
|
||||
if (num>max)
|
||||
max=num ;
|
||||
}
|
||||
}
|
||||
globfree(&pglob);
|
||||
return max+1 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Classify the frames
|
||||
@param fq Frame queue
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void frameq_makelists(frameq * fq)
|
||||
{
|
||||
FILE * list ;
|
||||
char filename[FILENAMESZ];
|
||||
framei * fi ;
|
||||
int setnum ;
|
||||
int count ;
|
||||
int batches ;
|
||||
|
||||
/* Count # of batches in input */
|
||||
fi = fq->first ;
|
||||
batches=0 ;
|
||||
while (fi!=NULL) {
|
||||
if (fi->expno==1)
|
||||
batches++ ;
|
||||
fi = fi->next ;
|
||||
}
|
||||
|
||||
fi = fq->first ;
|
||||
count=0 ;
|
||||
list=NULL ;
|
||||
while (fi!=NULL) {
|
||||
printf("\rclassifying batches: %d of %d", count, batches);
|
||||
fflush(stdout);
|
||||
if (fi->expno<0) {
|
||||
fi=fi->next ;
|
||||
continue ;
|
||||
}
|
||||
if (fi->expno==1) {
|
||||
count++ ;
|
||||
if (list!=NULL) {
|
||||
fclose(list);
|
||||
}
|
||||
if (fi->tplid == NULL) {
|
||||
printf("No TPL ID - abort\n") ;
|
||||
return ;
|
||||
}
|
||||
if (fi->origfile == NULL) {
|
||||
printf("No ORIGFILE - abort\n") ;
|
||||
return ;
|
||||
}
|
||||
mkdir(fi->tplid, 0755);
|
||||
setnum = frameq_getsetnum(fi->tplid);
|
||||
sprintf(filename, "%s/%s_%02d", fi->tplid, fi->origfile, fi->nexp);
|
||||
mkdir(filename, 0755);
|
||||
sprintf(filename, "%s/%s_%02d/IN", fi->tplid,fi->origfile,fi->nexp);
|
||||
list = fopen(filename, "w");
|
||||
fprintf(list,"# TPL.ID= %s\n", fi->tplid);
|
||||
fprintf(list,"# NEXP = %02d\n", fi->nexp);
|
||||
}
|
||||
if (list) fprintf(list, "%s\n", fi->name);
|
||||
fi = fi->next ;
|
||||
}
|
||||
printf("\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
frameq * fq ;
|
||||
|
||||
if (argc<2) {
|
||||
printf("use: %s <dirname>\n", argv[0]);
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
printf("loading frames from %s...\n", argv[1]);
|
||||
fq = frameq_load(argv[1]);
|
||||
printf("processing lists...\n");
|
||||
frameq_makelists(fq);
|
||||
frameq_del(fq);
|
||||
printf("done\n");
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file qextract.c
|
||||
@author Y. Jung
|
||||
@date Nov, 2002
|
||||
@version $Revision: 1.5 $
|
||||
@brief Extract a FITS extension and write it in a new FITS file
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: qextract.c,v 1.5 2005/06/29 15:14:50 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/06/29 15:14:50 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "qfits.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int textract_write_ext(char *, int) ;
|
||||
static int iextract_write_ext(char *, int) ;
|
||||
static char prog_desc[] = "Extract and write FITS extensions" ;
|
||||
static void usage(char *) ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char * name_in ;
|
||||
int ext ;
|
||||
int nb_ext ;
|
||||
int ext_type ;
|
||||
|
||||
if (argc<3) usage(argv[0]) ;
|
||||
|
||||
/* Get input file name and extension number */
|
||||
name_in = strdup(argv[1]) ;
|
||||
ext = (int)atoi(argv[2]) ;
|
||||
|
||||
/* Check if the file is a FITS file */
|
||||
if (!is_fits_file(name_in)) {
|
||||
printf("[%s] is not a FITS file\n", name_in) ;
|
||||
free(name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Check if the extension is valid */
|
||||
nb_ext = qfits_query_n_ext(name_in) ;
|
||||
if (nb_ext < ext) {
|
||||
printf("Only %d extensions in this file\n", nb_ext) ;
|
||||
free(name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Check if it's a table or an image */
|
||||
ext_type = qfits_is_table(name_in, ext) ;
|
||||
|
||||
switch (ext_type) {
|
||||
case QFITS_BINTABLE:
|
||||
case QFITS_ASCIITABLE:
|
||||
if (textract_write_ext(name_in, ext) == -1) {
|
||||
printf("cannot read-write extension no %d\n", ext) ;
|
||||
free(name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
break ;
|
||||
case QFITS_INVALIDTABLE:
|
||||
if (iextract_write_ext(name_in, ext) == -1) {
|
||||
printf("cannot read-write extension no %d\n", ext) ;
|
||||
free(name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
printf("Unrecognized FITS type\n") ;
|
||||
free(name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
free(name_in) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Functions code
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void usage(char * pname)
|
||||
{
|
||||
printf("%s : %s\n", pname, prog_desc) ;
|
||||
printf(
|
||||
"use : %s <in> <extension>\n"
|
||||
"\n", pname) ;
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
static int textract_write_ext(
|
||||
char * in,
|
||||
int ext)
|
||||
{
|
||||
qfits_table * th ;
|
||||
void ** array ;
|
||||
qfits_header * fh ;
|
||||
int array_size ;
|
||||
int i ;
|
||||
|
||||
/* Get the table infos */
|
||||
if ((th = qfits_table_open(in, ext)) == NULL) {
|
||||
printf("cannot read extension: %d\n", ext) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Compute array_size */
|
||||
array_size = 0 ;
|
||||
for (i=0 ; i<th->nc ; i++) {
|
||||
switch (th->col[i].atom_type) {
|
||||
case TFITS_ASCII_TYPE_A:
|
||||
case TFITS_ASCII_TYPE_I:
|
||||
case TFITS_ASCII_TYPE_E:
|
||||
case TFITS_ASCII_TYPE_F:
|
||||
case TFITS_ASCII_TYPE_D:
|
||||
case TFITS_BIN_TYPE_A:
|
||||
case TFITS_BIN_TYPE_L:
|
||||
case TFITS_BIN_TYPE_B:
|
||||
case TFITS_BIN_TYPE_X:
|
||||
array_size += sizeof(char*) ;
|
||||
break ;
|
||||
|
||||
case TFITS_BIN_TYPE_I:
|
||||
array_size += sizeof(short*) ;
|
||||
break ;
|
||||
|
||||
case TFITS_BIN_TYPE_J:
|
||||
case TFITS_BIN_TYPE_E:
|
||||
array_size += sizeof(int*) ;
|
||||
break ;
|
||||
|
||||
case TFITS_BIN_TYPE_C:
|
||||
case TFITS_BIN_TYPE_P:
|
||||
array_size += sizeof(float*) ;
|
||||
break ;
|
||||
|
||||
case TFITS_BIN_TYPE_D:
|
||||
case TFITS_BIN_TYPE_M:
|
||||
array_size += sizeof(double*) ;
|
||||
break ;
|
||||
default:
|
||||
return -1 ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory for array */
|
||||
array = malloc(array_size) ;
|
||||
|
||||
/* Load columns in array */
|
||||
for (i=0 ; i<th->nc ; i++) {
|
||||
array[i] = qfits_query_column_data(th, i, NULL, NULL) ;
|
||||
if (array[i] == NULL) {
|
||||
printf("cannot read column %d\n", i+1) ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update th : filename */
|
||||
sprintf(th->filename, "ext%d.tfits", ext) ;
|
||||
|
||||
/* Get fits primary header */
|
||||
if ((fh = qfits_header_read(in)) == NULL) {
|
||||
for (i=0 ; i<th->nc ; i++) if (array[i] != NULL) free(array[i]) ;
|
||||
qfits_table_close(th) ;
|
||||
free(array) ;
|
||||
printf("cannot read fits header\n") ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
if (ext != 0) {
|
||||
/* No data in primary HDU */
|
||||
qfits_header_mod(fh, "NAXIS", "0", NULL) ;
|
||||
qfits_header_del(fh, "NAXIS1") ;
|
||||
qfits_header_del(fh, "NAXIS2") ;
|
||||
}
|
||||
|
||||
/* Write the tfits file */
|
||||
if (qfits_save_table_hdrdump((void **)array, th, fh) == -1) {
|
||||
qfits_header_destroy(fh) ;
|
||||
for (i=0 ; i<th->nc ; i++) if (array[i] != NULL) free(array[i]) ;
|
||||
qfits_table_close(th) ;
|
||||
free(array) ;
|
||||
printf("cannot write fits table\n") ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Free and return */
|
||||
qfits_header_destroy(fh) ;
|
||||
for (i=0 ; i<th->nc ; i++) if (array[i] != NULL) free(array[i]) ;
|
||||
qfits_table_close(th) ;
|
||||
free(array) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int iextract_write_ext(
|
||||
char * in,
|
||||
int ext)
|
||||
{
|
||||
qfitsloader ql ;
|
||||
qfitsdumper qd ;
|
||||
qfits_header * fh ;
|
||||
char outname[1024] ;
|
||||
FILE * out ;
|
||||
|
||||
sprintf(outname, "ext%d.fits", ext) ;
|
||||
|
||||
/* Initialize a FITS loader */
|
||||
ql.filename = in ;
|
||||
ql.xtnum = ext ;
|
||||
ql.pnum = 0 ;
|
||||
ql.map = 1 ;
|
||||
ql.ptype = PTYPE_DOUBLE ;
|
||||
if (qfitsloader_init(&ql)!=0) return -1 ;
|
||||
|
||||
/* Load the primary header */
|
||||
if ((fh = qfits_header_read(ql.filename)) == NULL) return -1 ;
|
||||
|
||||
if (ext != 0) {
|
||||
/* No data in primary HDU */
|
||||
qfits_header_mod(fh, "NAXIS", "0", NULL) ;
|
||||
qfits_header_del(fh, "NAXIS1") ;
|
||||
qfits_header_del(fh, "NAXIS2") ;
|
||||
}
|
||||
|
||||
/* Dump the primary header */
|
||||
if ((out = fopen(outname, "w")) == NULL) return -1 ;
|
||||
qfits_header_dump(fh, out);
|
||||
qfits_header_destroy(fh) ;
|
||||
|
||||
if (ext != 0) {
|
||||
/* Load the extension header */
|
||||
if ((fh = qfits_header_readext(ql.filename, ext)) == NULL) return -1 ;
|
||||
/* Dump the extension header */
|
||||
qfits_header_dump(fh, out);
|
||||
qfits_header_destroy(fh) ;
|
||||
}
|
||||
fclose(out) ;
|
||||
|
||||
/* Load the FITS image */
|
||||
if (qfits_loadpix(&ql)!=0) return -1 ;
|
||||
|
||||
/* Write the FITS image */
|
||||
qd.filename = outname ;
|
||||
qd.npix = ql.lx * ql.ly ;
|
||||
qd.ptype = PTYPE_DOUBLE ;
|
||||
qd.dbuf = ql.dbuf ;
|
||||
qd.out_ptype = ql.bitpix ;
|
||||
if (qfits_pixdump(&qd)!=0) return -1 ;
|
||||
/* qfits_zeropad(outname) ; */
|
||||
free(ql.dbuf) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file replacekey.c
|
||||
@author N. Devillard
|
||||
@date July 14th, 1998
|
||||
@version $Revision: 1.6 $
|
||||
@brief Search & Replace operations in FITS headers
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: replacekey.c,v 1.6 2003/08/21 10:44:32 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/08/21 10:44:32 $
|
||||
$Revision: 1.6 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Include
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "qfits.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define NM_SIZ 512
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Functions prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static char prog_desc[] = "replace keyword in a FITS header" ;
|
||||
static void usage(char *) ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char * name_in ;
|
||||
char * card ;
|
||||
char * place ;
|
||||
char * key ;
|
||||
char * key_tmp ;
|
||||
char * val ;
|
||||
char * val_tmp ;
|
||||
char * com ;
|
||||
char * com_tmp ;
|
||||
int keep_com ;
|
||||
int numeric ;
|
||||
char * stmp ;
|
||||
int i ;
|
||||
|
||||
char card_tmp[NM_SIZ] ;
|
||||
|
||||
if (argc<2) usage(argv[0]) ;
|
||||
|
||||
/* Initialize */
|
||||
name_in = NULL ;
|
||||
card = NULL ;
|
||||
place = NULL ;
|
||||
key = NULL ;
|
||||
val = NULL ;
|
||||
com = NULL ;
|
||||
keep_com = 0 ;
|
||||
numeric = 0 ;
|
||||
|
||||
/* Command line handling */
|
||||
i=1 ;
|
||||
while (i<argc) {
|
||||
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
|
||||
usage(argv[0]);
|
||||
} else if (!strcmp(argv[i], "-p")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -p needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
place = strdup(argv[i]);
|
||||
} else if (!strcmp(argv[i], "-k")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -k needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
key = strdup(argv[i]);
|
||||
} else if (!strcmp(argv[i], "-v")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -v needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
val = strdup(argv[i]);
|
||||
} else if (!strcmp(argv[i], "-c")) {
|
||||
if ((i+1)>=argc) {
|
||||
fprintf(stderr, "option -c needs an argument\n");
|
||||
return -1 ;
|
||||
}
|
||||
i++ ;
|
||||
com = strdup(argv[i]);
|
||||
} else if (!strcmp(argv[i], "-C")) {
|
||||
keep_com = 1 ;
|
||||
} else if (!strcmp(argv[i], "-n")) {
|
||||
numeric = 1 ;
|
||||
} else {
|
||||
break ;
|
||||
}
|
||||
i++ ;
|
||||
}
|
||||
|
||||
/* Check options coherence */
|
||||
if ((keep_com == 1) && (com != NULL)) {
|
||||
fprintf(stderr, "options -c and -C should not be used together\n") ;
|
||||
if (place) free(place) ;
|
||||
if (key) free(key) ;
|
||||
if (val) free(val) ;
|
||||
free(com) ;
|
||||
return -1 ;
|
||||
}
|
||||
if (place == NULL) {
|
||||
fprintf(stderr, "options -p has to be used\n") ;
|
||||
if (key) free(key) ;
|
||||
if (val) free(val) ;
|
||||
if (com) free(com) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Get input file name */
|
||||
if ((argc-i)<1) {
|
||||
fprintf(stderr, "missing input file name\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Loop on the input files */
|
||||
while (argc-i >= 1) {
|
||||
name_in = strdup(argv[i]) ;
|
||||
|
||||
/* Set keyword to write */
|
||||
key_tmp = NULL ;
|
||||
if (key==NULL) key_tmp = strdup(place) ;
|
||||
else key_tmp = strdup(key) ;
|
||||
|
||||
/* Set value to write */
|
||||
val_tmp = NULL ;
|
||||
if (val==NULL) {
|
||||
card = qfits_query_card(name_in, place) ;
|
||||
if (card!= NULL) {
|
||||
stmp = qfits_getvalue(card) ;
|
||||
val_tmp = strdup(stmp) ;
|
||||
}
|
||||
} else val_tmp = strdup(val) ;
|
||||
|
||||
com_tmp = NULL ;
|
||||
/* Set comment to write */
|
||||
if ((com == NULL) && (keep_com == 1)) {
|
||||
if (card == NULL) card = qfits_query_card(name_in, place) ;
|
||||
if (card != NULL) {
|
||||
stmp = qfits_getcomment(card) ;
|
||||
com_tmp = strdup(stmp) ;
|
||||
}
|
||||
} else if (com != NULL) com_tmp = strdup(com) ;
|
||||
if (card != NULL) free(card) ;
|
||||
card = NULL ;
|
||||
printf("DEBUG: %s\n", key_tmp) ;
|
||||
|
||||
/* Create the card */
|
||||
keytuple2str(card_tmp, key_tmp, val_tmp, com_tmp) ;
|
||||
if (key_tmp) free(key_tmp) ;
|
||||
if (val_tmp) free(val_tmp) ;
|
||||
if (com_tmp) free(com_tmp) ;
|
||||
card = strdup(card_tmp) ;
|
||||
|
||||
/* Display what will be written where */
|
||||
printf("File %s\n", name_in) ;
|
||||
printf("\tcard : \n\t\t%s\n", card) ;
|
||||
printf("\tplace : \n\t\t%s\n", place) ;
|
||||
|
||||
/* Try to replace the first key */
|
||||
if (qfits_replace_card(name_in, place, card) == -1) {
|
||||
fprintf(stderr, "cannot replace the key %s\n", place) ;
|
||||
}
|
||||
free(name_in);
|
||||
free(card) ;
|
||||
card = NULL ;
|
||||
i++ ;
|
||||
}
|
||||
|
||||
if (val) free(val) ;
|
||||
if (com) free(com) ;
|
||||
if (key) free(key) ;
|
||||
free(place) ;
|
||||
/* Free and return */
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static void usage(char * pname)
|
||||
{
|
||||
printf("%s : %s\n", pname, prog_desc) ;
|
||||
printf(
|
||||
"use : %s [options] <in>\n"
|
||||
"options are:\n"
|
||||
"\t-p place gives the keyword to write over (required).\n"
|
||||
"\t-k key gives the new keyword name (optional).\n"
|
||||
"\t-v val gives the value to write (optional).\n"
|
||||
"\t-c com gives the comment to write (optional).\n"
|
||||
"\t-C flag to keep comment\n"
|
||||
"\n", pname) ;
|
||||
exit(0) ;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# General definitions
|
||||
#
|
||||
|
||||
include ../config.make
|
||||
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
MV = mv
|
||||
BINDIR = ../bin
|
||||
|
||||
default: all
|
||||
|
||||
|
||||
PROGS = $(BINDIR)/fitsort \
|
||||
$(BINDIR)/hierarch28 \
|
||||
$(BINDIR)/iofits \
|
||||
$(BINDIR)/fitsmd5
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
veryclean:
|
||||
@(echo "cleaning saft programs...")
|
||||
@($(RM) $(PROGS))
|
||||
|
||||
|
||||
$(BINDIR)/fitsort: fitsort.c
|
||||
@(echo "building $@ ...")
|
||||
@($(CC) $(CFLAGS) $(LFLAGS) -o $(BINDIR)/fitsort fitsort.c)
|
||||
|
||||
$(BINDIR)/hierarch28: hierarch28.c
|
||||
@(echo "building $@ ...")
|
||||
@($(CC) $(CFLAGS) $(LFLAGS) -o $(BINDIR)/hierarch28 hierarch28.c)
|
||||
|
||||
$(BINDIR)/iofits: iofits.c
|
||||
@(echo "building $@ ...")
|
||||
@($(CC) $(CFLAGS) $(LFLAGS) -o $(BINDIR)/iofits iofits.c)
|
||||
|
||||
$(BINDIR)/fitsmd5: fitsmd5.c
|
||||
@(echo "building $@ ...")
|
||||
@($(CC) $(CFLAGS) $(LFLAGS) -o $(BINDIR)/fitsmd5 fitsmd5.c)
|
||||
|
|
@ -0,0 +1,790 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fitsmd5.c
|
||||
@author N. Devillard
|
||||
@date May 2001
|
||||
@version $Revision: 1.5 $
|
||||
@brief Display/Add/Update the DATAMD5 keyword/value
|
||||
This is a stand-alone utility. Compile it with any ANSI C compiler:
|
||||
% cc -o fitsmd5 fitsmd5.c [optional optimization options]
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fitsmd5.c,v 1.5 2003/07/04 15:08:04 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/07/04 15:08:04 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Support for gzipped files if linked against zlib.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#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)
|
||||
|
||||
#define GZIP_MAGIC1 0x1f
|
||||
#define GZIP_MAGIC2 0x8b
|
||||
|
||||
static is_gzipped(char * filename)
|
||||
{
|
||||
FILE * in ;
|
||||
unsigned char b1, b2 ;
|
||||
int r1, r2 ;
|
||||
|
||||
if ((in=fopen(filename, "r"))==NULL) {
|
||||
return -1 ;
|
||||
}
|
||||
r1 = fread(&b1, 1, 1, in);
|
||||
r2 = fread(&b2, 1, 1, in);
|
||||
fclose(in);
|
||||
if (r1!=1 || r2!=1)
|
||||
return 0 ;
|
||||
if ((int)b1!=GZIP_MAGIC1 || (int)b2!=GZIP_MAGIC2) {
|
||||
return 0 ;
|
||||
}
|
||||
return 1 ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* Definitions related to FITS */
|
||||
#define FITSLINESZ 80 /* a FITS line is 80 chars */
|
||||
#define FITSCARDS 36 /* 36 cards per block */
|
||||
#define FITSBLOCKSZ (FITSLINESZ*FITSCARDS) /* FITS block size=2880 */
|
||||
|
||||
/* Definitions related to MD5 */
|
||||
#define MD5HASHSZ 32 /* an MD5 key length is 32 bytes = 128 bits */
|
||||
|
||||
/* FITS keyword used to store MD5 key */
|
||||
#define FITSMD5KEY "DATAMD5 "
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* The following types defined for MD5 computation only */
|
||||
typedef unsigned int word32 ;
|
||||
|
||||
struct MD5Context {
|
||||
word32 buf[4];
|
||||
word32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Private function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void MD5Init(struct MD5Context *);
|
||||
static void MD5Update(struct MD5Context *, unsigned char *, unsigned);
|
||||
static void MD5Final(unsigned char *, struct MD5Context *);
|
||||
static void MD5Transform(word32 *, word32 *);
|
||||
static void byteReverse(unsigned char *, unsigned);
|
||||
|
||||
static int fits_md5_check(char *, int);
|
||||
static char * fits_pretty_string(char *);
|
||||
static char * fits_getvalue(char *);
|
||||
|
||||
static void usage(void);
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Global variables
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static char * pname = NULL ;
|
||||
static char prog_desc[] = "Compute/Update the DATAMD5 keyword/value" ;
|
||||
static int silent_process=0 ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
MD5 function code
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* Reverse bytes in a 32-bit word. Harmless on little endian machines */
|
||||
static void byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
word32 t;
|
||||
do {
|
||||
t = (word32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(word32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
|
||||
/* Start MD5 accumulation. Set bit count to 0 and buffer to MD5 init. const. */
|
||||
static void MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/* Update to reflect the concatenation of another buffer full of bytes. */
|
||||
static void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len)
|
||||
{
|
||||
register word32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((word32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memmove(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memmove(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (word32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= 64) {
|
||||
memmove(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (word32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memmove(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/* Final wrapup - pad to 64-byte boundary with the bit pattern 1 0* */
|
||||
/* (64-bit count of bits processed, MSB-first) */
|
||||
static void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned int count ;
|
||||
unsigned char * p ;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (word32 *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((word32 *) ctx->in)[14] = ctx->bits[0];
|
||||
((word32 *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (word32 *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memmove(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void MD5Transform(word32 buf[4], word32 in[16])
|
||||
{
|
||||
register word32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
FITS-related functions
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* Pretty-print a FITS string value */
|
||||
static char * fits_pretty_string(char * s)
|
||||
{
|
||||
static char pretty[FITSLINESZ+1] ;
|
||||
int i,j ;
|
||||
|
||||
if (s==NULL) return NULL ;
|
||||
|
||||
pretty[0] = (char)0 ;
|
||||
if (s[0]!='\'') return s ;
|
||||
|
||||
/* skip first quote */
|
||||
i=1 ;
|
||||
j=0 ;
|
||||
/* trim left-side blanks */
|
||||
while (s[i]==' ') {
|
||||
if (i==(int)strlen(s)) break ;
|
||||
i++ ;
|
||||
}
|
||||
if (i>=(int)(strlen(s)-1)) return pretty ;
|
||||
/* copy string, changing double quotes to single ones */
|
||||
while (i<(int)strlen(s)) {
|
||||
if (s[i]=='\'') i++ ;
|
||||
pretty[j]=s[i];
|
||||
i++ ;
|
||||
j++ ;
|
||||
}
|
||||
/* NULL-terminate the pretty string */
|
||||
pretty[j+1]=(char)0;
|
||||
/* trim right-side blanks */
|
||||
j = (int)strlen(pretty)-1;
|
||||
while (pretty[j]==' ') j-- ;
|
||||
pretty[j+1]=(char)0;
|
||||
return pretty;
|
||||
}
|
||||
|
||||
/* Get the FITS value in a FITS card */
|
||||
static char * fits_getvalue(char * line)
|
||||
{
|
||||
static char value[FITSLINESZ+1] ;
|
||||
int from, to ;
|
||||
int inq ;
|
||||
int i ;
|
||||
|
||||
if (line==NULL) return NULL ;
|
||||
memset(value, 0, FITSLINESZ+1);
|
||||
/* Get past the keyword */
|
||||
i=0 ;
|
||||
while (line[i]!='=' && i<FITSLINESZ) i++ ;
|
||||
if (i>FITSLINESZ) return NULL ;
|
||||
i++ ;
|
||||
while (line[i]==' ' && i<FITSLINESZ) i++ ;
|
||||
if (i>FITSLINESZ) return NULL ;
|
||||
from=i;
|
||||
/* Now in the value section */
|
||||
/* Look for the first slash '/' outside of a string */
|
||||
inq = 0 ;
|
||||
while (i<FITSLINESZ) {
|
||||
if (line[i]=='\'') inq=!inq ;
|
||||
if (line[i]=='/') if (!inq) break ;
|
||||
i++;
|
||||
}
|
||||
i-- ;
|
||||
/* Backtrack on blanks */
|
||||
while (line[i]==' ' && i>=0) i-- ;
|
||||
if (i<0) return NULL ;
|
||||
to=i ;
|
||||
if (to<from) return NULL ;
|
||||
/* Copy relevant characters into output buffer */
|
||||
strncpy(value, line+from, to-from+1);
|
||||
/* Null-terminate the string */
|
||||
value[to-from+1] = (char)0;
|
||||
/*
|
||||
* Make it pretty: remove head and tail quote, change double
|
||||
* quotes to simple ones.
|
||||
*/
|
||||
strcpy(value, fits_pretty_string(value));
|
||||
return value ;
|
||||
}
|
||||
|
||||
/* Replace the MD5 card in the input header */
|
||||
static int fits_replace_card(char * filename, int off_md5, char * datamd5)
|
||||
{
|
||||
char * buf ;
|
||||
int fd ;
|
||||
struct stat sta ;
|
||||
char card[FITSLINESZ];
|
||||
int i ;
|
||||
int err ;
|
||||
|
||||
/* Get file size */
|
||||
if (stat(filename, &sta)==-1) {
|
||||
fprintf(stderr, "%s: cannot stat file [%s]: no update done\n",
|
||||
pname,
|
||||
filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Open file */
|
||||
fd = open(filename, O_RDWR);
|
||||
if (fd==-1) {
|
||||
fprintf(stderr,
|
||||
"%s: cannot open file [%s] for modification: no update done\n",
|
||||
pname,
|
||||
filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Memory-map the file */
|
||||
buf = (char*)mmap(0,
|
||||
sta.st_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0);
|
||||
if (buf==(char*)-1 || buf==NULL) {
|
||||
perror("mmap");
|
||||
close(fd);
|
||||
return 1 ;
|
||||
}
|
||||
/* sprintf should be safe, the MD5 signature size is 32 chars */
|
||||
sprintf(card, "%s= '%s' / data MD5 signature", FITSMD5KEY, datamd5);
|
||||
i=FITSLINESZ-1 ;
|
||||
while (card[i]!='e') {
|
||||
card[i]=' ';
|
||||
i-- ;
|
||||
}
|
||||
/* Copy card into file */
|
||||
memcpy(buf+off_md5, card, FITSLINESZ);
|
||||
/* flush output, unmap buffer, close file and quit */
|
||||
err=0 ;
|
||||
sync();
|
||||
if (close(fd)==-1) {
|
||||
fprintf(stderr, "%s: error closing modified file [%s]",
|
||||
pname,
|
||||
filename);
|
||||
err++ ;
|
||||
}
|
||||
if (munmap(buf, sta.st_size)==-1) {
|
||||
perror("munmap");
|
||||
err++ ;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Display or modify the DATAMD5 value. Returns the number of errors. */
|
||||
static int fits_md5_check(char * filename, int update_header)
|
||||
{
|
||||
FILE * in ;
|
||||
char buf[FITSBLOCKSZ];
|
||||
char * buf_c ;
|
||||
int i ;
|
||||
int in_header ;
|
||||
char * hdrmd5 ;
|
||||
struct MD5Context ctx ;
|
||||
unsigned char digest[16] ;
|
||||
static char datamd5[MD5HASHSZ+1];
|
||||
int off_md5 ;
|
||||
int cur_off ;
|
||||
int md5keysz ;
|
||||
int err ;
|
||||
int check_fits ;
|
||||
struct stat sta ;
|
||||
|
||||
if (filename==NULL) return 1 ;
|
||||
|
||||
/* Try to stat file */
|
||||
if (stat(filename, &sta)!=0) {
|
||||
fprintf(stderr, "%s: cannot stat file %s\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* See if this is a regular file */
|
||||
if (!S_ISREG(sta.st_mode)) {
|
||||
fprintf(stderr, "%s: not a regular file: %s\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Open input file */
|
||||
if ((in=fopen(filename, "r"))==NULL) {
|
||||
fprintf(stderr, "%s: cannot open file [%s]\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Initialize all variables */
|
||||
MD5Init(&ctx);
|
||||
in_header=1 ;
|
||||
hdrmd5=NULL ;
|
||||
off_md5=0;
|
||||
cur_off=0;
|
||||
md5keysz = (int)strlen(FITSMD5KEY) ;
|
||||
check_fits=0 ;
|
||||
/* Loop over input file */
|
||||
while (fread(buf, 1, FITSBLOCKSZ, in)==FITSBLOCKSZ) {
|
||||
/* First time in the loop: check the file is FITS */
|
||||
if (check_fits==0) {
|
||||
/* Examine first characters in block */
|
||||
if (buf[0]!='S' ||
|
||||
buf[1]!='I' ||
|
||||
buf[2]!='M' ||
|
||||
buf[3]!='P' ||
|
||||
buf[4]!='L' ||
|
||||
buf[5]!='E' ||
|
||||
buf[6]!=' ' ||
|
||||
buf[7]!=' ' ||
|
||||
buf[8]!='=') {
|
||||
fprintf(stderr, "%s: file [%s] is not FITS\n",
|
||||
pname,
|
||||
filename);
|
||||
fclose(in);
|
||||
return 1 ;
|
||||
} else {
|
||||
check_fits=1 ;
|
||||
}
|
||||
}
|
||||
/* If current block is a header block */
|
||||
if (in_header) {
|
||||
buf_c = buf ;
|
||||
for (i=0 ; i<FITSCARDS ; i++) {
|
||||
/* Try to locate MD5 keyword if not located already */
|
||||
if (hdrmd5==NULL) {
|
||||
if (!strncmp(buf_c, FITSMD5KEY, md5keysz)) {
|
||||
hdrmd5 = fits_getvalue(buf_c) ;
|
||||
off_md5 = cur_off ;
|
||||
}
|
||||
}
|
||||
/* Try to locate an END key */
|
||||
if (buf_c[0]=='E' &&
|
||||
buf_c[1]=='N' &&
|
||||
buf_c[2]=='D' &&
|
||||
buf_c[3]==' ') {
|
||||
in_header=0 ;
|
||||
break ;
|
||||
}
|
||||
buf_c += FITSLINESZ ;
|
||||
cur_off += FITSLINESZ ;
|
||||
}
|
||||
} else {
|
||||
/* If current block is a data block */
|
||||
/* Try to locate an extension header */
|
||||
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' &&
|
||||
buf[8]=='=') {
|
||||
in_header=1 ;
|
||||
buf_c = buf ;
|
||||
for (i=0 ; i<FITSCARDS ; i++) {
|
||||
/* Try to find an END marker in this block */
|
||||
if (buf_c[0]=='E' &&
|
||||
buf_c[1]=='N' &&
|
||||
buf_c[2]=='D' &&
|
||||
buf_c[3]==' ') {
|
||||
/* Found END marker in same block as XTENSION */
|
||||
in_header=0 ;
|
||||
break ;
|
||||
}
|
||||
buf_c += FITSLINESZ ;
|
||||
}
|
||||
} else {
|
||||
/* Data block: accumulate for MD5 */
|
||||
MD5Update(&ctx, (unsigned char *)buf, FITSBLOCKSZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
if (check_fits==0) {
|
||||
/* Never went through the read loop: file is not FITS */
|
||||
fprintf(stderr, "%s: file [%s] is not FITS\n",
|
||||
pname,
|
||||
filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Got to the end of file: summarize */
|
||||
MD5Final(digest, &ctx);
|
||||
|
||||
/* Write digest into a string */
|
||||
sprintf(datamd5,
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
digest[ 0], digest[ 1], digest[ 2], digest[ 3], digest[ 4],
|
||||
digest[ 5], digest[ 6], digest[ 7], digest[ 8], digest[ 9],
|
||||
digest[10], digest[11], digest[12], digest[13], digest[14],
|
||||
digest[15]);
|
||||
if (!silent_process) {
|
||||
printf("%s %s", datamd5, filename);
|
||||
if (hdrmd5) {
|
||||
if (!strcmp(hdrmd5, datamd5)) {
|
||||
printf(" (header Ok)");
|
||||
} else {
|
||||
printf(" (header is wrong)");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
/* Update header if requested */
|
||||
err=0 ;
|
||||
if (update_header) {
|
||||
if (hdrmd5==NULL) {
|
||||
fprintf(stderr, "%s: cannot update header: missing %s\n",
|
||||
pname,
|
||||
FITSMD5KEY);
|
||||
return 1 ;
|
||||
}
|
||||
#if HAVE_ZLIB
|
||||
if (is_gzipped(filename)) {
|
||||
fprintf(stderr, "%s: cannot update header in gzipped file\n");
|
||||
return 1 ;
|
||||
}
|
||||
#endif
|
||||
err = fits_replace_card(filename, off_md5, datamd5);
|
||||
}
|
||||
return err ;
|
||||
}
|
||||
|
||||
|
||||
/* Compute MD5 sum on the whole file and print out results on stdout */
|
||||
static int compute_md5(char * filename)
|
||||
{
|
||||
struct MD5Context ctx ;
|
||||
unsigned char digest[16] ;
|
||||
struct stat sta ;
|
||||
int fd ;
|
||||
unsigned char * buf ;
|
||||
|
||||
/* Try to stat file */
|
||||
if (stat(filename, &sta)!=0) {
|
||||
fprintf(stderr, "%s: cannot stat file %s\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* See if this is a regular file */
|
||||
if (!S_ISREG(sta.st_mode)) {
|
||||
fprintf(stderr, "%s: not a regular file: %s\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Open file */
|
||||
if ((fd = open(filename, O_RDONLY))==-1) {
|
||||
fprintf(stderr, "%s: cannot open file %s\n", pname, filename);
|
||||
return 1 ;
|
||||
}
|
||||
/* Memory-map the file */
|
||||
buf = (unsigned char*)mmap(0, sta.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (buf==(unsigned char*)-1 || buf==NULL) {
|
||||
perror("mmap");
|
||||
close(fd);
|
||||
return 1 ;
|
||||
}
|
||||
/* Initialize MD5 context */
|
||||
MD5Init(&ctx);
|
||||
/* Compute MD5 on all bits in the file */
|
||||
MD5Update(&ctx, buf, sta.st_size);
|
||||
/* Finalize and print results */
|
||||
close(fd);
|
||||
munmap((char*)buf, sta.st_size);
|
||||
MD5Final(digest, &ctx);
|
||||
printf(
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %s\n",
|
||||
digest[ 0], digest[ 1], digest[ 2], digest[ 3], digest[ 4],
|
||||
digest[ 5], digest[ 6], digest[ 7], digest[ 8], digest[ 9],
|
||||
digest[10], digest[11], digest[12], digest[13], digest[14],
|
||||
digest[15],
|
||||
filename);
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf(
|
||||
"%s -- %s\n"
|
||||
"version: $Revision: 1.5 $\n",
|
||||
pname,
|
||||
prog_desc);
|
||||
printf(
|
||||
"\n"
|
||||
"use : %s [-u] [-s] [-a] <FITS files...>\n"
|
||||
"options are:\n"
|
||||
"\t-u update MD5 keyword in the file: %s\n"
|
||||
"\t-s silent mode\n"
|
||||
"\n"
|
||||
"\t-a compute MD5 sum of the complete file (incl.header)\n"
|
||||
"\n"
|
||||
"This utility computes the MD5 checksum of all data sections\n"
|
||||
"in a given FITS file, and compares it against the value\n"
|
||||
"declared in DATAMD5 if present. It can also update the value\n"
|
||||
"of this keyword (if present) with its own computed MD5 sum.\n"
|
||||
"\n", pname, FITSMD5KEY) ;
|
||||
printf(
|
||||
"You can also use it with the -a option to compute the MD5 sum\n"
|
||||
"on the complete file (all bits). In this case, the file needs\n"
|
||||
"not be FITS. This option is only provided to check this program\n"
|
||||
"against other MD5 computation tools.\n"
|
||||
"NB: Other options cannot be used together with -a.\n"
|
||||
"\n");
|
||||
|
||||
#if HAVE_ZLIB
|
||||
printf(
|
||||
"\n"
|
||||
"This program was compiled against zlib %s\n"
|
||||
"which allows to process gzipped FITS files\n"
|
||||
"as if they were normal FITS files.\n"
|
||||
"Notice that you cannot use the -u option on\n"
|
||||
"gzipped files, though.\n"
|
||||
"\n"
|
||||
"\n",
|
||||
ZLIB_VERSION
|
||||
);
|
||||
#endif
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i ;
|
||||
int update_header ;
|
||||
int total_md5 ;
|
||||
int err ;
|
||||
|
||||
/* Initialize */
|
||||
pname=argv[0];
|
||||
update_header = 0 ;
|
||||
total_md5 = 0 ;
|
||||
|
||||
if (argc<2) usage();
|
||||
|
||||
/* Parse arguments for options */
|
||||
for (i=1 ; i<argc ; i++) {
|
||||
if (!strcmp(argv[i], "-u")) {
|
||||
update_header=1 ;
|
||||
} else if (!strcmp(argv[i], "-s")) {
|
||||
silent_process=1;
|
||||
} else if (!strcmp(argv[i], "-a")) {
|
||||
total_md5=1 ;
|
||||
}
|
||||
}
|
||||
/* Loop on input file names */
|
||||
err=0 ;
|
||||
for (i=1 ; i<argc ; i++) {
|
||||
/* If not a command-line option */
|
||||
if (strcmp(argv[i], "-u") &&
|
||||
strcmp(argv[i], "-s") &&
|
||||
strcmp(argv[i], "-a")) {
|
||||
/* Launch MD5 process on this file */
|
||||
if (total_md5) {
|
||||
err+=compute_md5(argv[i]);
|
||||
} else {
|
||||
err += fits_md5_check(argv[i], update_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err>0) {
|
||||
fprintf(stderr, "%s: %d error(s) during process\n", pname, err);
|
||||
}
|
||||
return err ;
|
||||
}
|
|
@ -0,0 +1,373 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fitsort.c
|
||||
@author Nicolas Devillard
|
||||
@date May 1st, 1996
|
||||
@version $Revision: 1.4 $
|
||||
@brief Sorts out FITS keywords
|
||||
|
||||
The input is a succession of FITS headers delivered through stdin by
|
||||
'dfits'. On the command line, specify which keywords you wish to display, the
|
||||
output contains for each file, the file name and the keyword values in
|
||||
column format. Example:
|
||||
|
||||
dfits *.fits | fitsort BITPIX NAXIS NAXIS1 NAXIS2 NAXIS3
|
||||
The output would be like:
|
||||
File BITPIX NAXIS NAXIS1 NAXIS2 NAXIS3
|
||||
image1.fits 32 2 256 256
|
||||
image2.fits -32 3 128 128 40
|
||||
|
||||
Using 'fitsort -d ...' would prevent printing the first line (filename and
|
||||
keyword names).
|
||||
The output format is simple: values are separated by tabs, records by
|
||||
linefeeds. When no value is present (no keyword in this header), only a tab
|
||||
is printed out. Example:
|
||||
|
||||
file1.fits contains NAXIS1=100 NAXIS2=200
|
||||
file2.fits contains NAXIS1=20
|
||||
dfits file1.fits file2.fits | fitsort NAXIS2 NAXIS1
|
||||
would litterally print out (\t stands for tab, \n for linefeed):
|
||||
file1.fits\t200\t100\n
|
||||
file2.fits\t\t20\n
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fitsort.c,v 1.4 2005/07/04 14:21:31 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/07/04 14:21:31 $
|
||||
$Revision: 1.4 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Include
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MAX_STRING 128
|
||||
#define MAX_KEY 512
|
||||
#define FMT_STRING "%%-%ds\t"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* This holds a keyword value and a flag to indicate its presence */
|
||||
typedef struct _KEYWORD_ {
|
||||
char value[MAX_STRING] ;
|
||||
int present ;
|
||||
} keyword ;
|
||||
|
||||
/* Each detected file in input has such an associated structure */
|
||||
typedef struct _RECORD_ {
|
||||
char filename[MAX_STRING] ;
|
||||
keyword listkw[MAX_KEY] ;
|
||||
} record ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int isfilename(char *string) ;
|
||||
static void getfilename(char *line, char *word) ;
|
||||
static char * expand_hierarch_keyword(char *, char *) ;
|
||||
static int isdetectedkeyword(char *line, char *keywords[], int nkeys) ;
|
||||
static void getkeywordvalue(char *line, char *word) ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char curline[MAX_STRING] ;
|
||||
char word[MAX_STRING] ;
|
||||
int i, j ;
|
||||
int nfiles ;
|
||||
record *allrecords ;
|
||||
int kwnum ;
|
||||
int len ;
|
||||
int max_width[MAX_KEY] ;
|
||||
int max_filnam ;
|
||||
char fmt[8] ;
|
||||
int flag ;
|
||||
int printnames ;
|
||||
int print_hdr ;
|
||||
|
||||
if (argc<2) {
|
||||
printf("\n\nuse : %s [-d] KEY1 KEY2 ... KEYn\n", argv[0]) ;
|
||||
printf("Input data is received from stdin\n") ;
|
||||
printf("See man page for more details and examples\n\n") ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Initialize */
|
||||
printnames = 0 ;
|
||||
print_hdr = 1 ;
|
||||
nfiles = 0 ;
|
||||
allrecords = (record*)calloc(1, sizeof(record));
|
||||
if (!strcmp(argv[1], "-d")) {
|
||||
print_hdr = 0;
|
||||
argv++ ;
|
||||
argc-- ;
|
||||
}
|
||||
argv++ ;
|
||||
|
||||
/* Uppercase all inputs */
|
||||
for (i=0 ; i<(argc-1) ; i++) {
|
||||
j=0 ;
|
||||
while (argv[i][j]!=0) {
|
||||
argv[i][j] = toupper(argv[i][j]);
|
||||
j++ ;
|
||||
}
|
||||
}
|
||||
|
||||
while (fgets(curline, MAX_STRING, stdin) != (char*)NULL) {
|
||||
flag=isfilename(curline) ;
|
||||
if (flag == 1) {
|
||||
/* New file name is detected, get the new file name */
|
||||
printnames = 1 ;
|
||||
getfilename(curline, allrecords[nfiles].filename) ;
|
||||
nfiles++ ;
|
||||
|
||||
/* Initialize a new record structure to store data for this file. */
|
||||
allrecords = (record*)realloc(allrecords,(nfiles+1)*sizeof(record));
|
||||
for (i=0 ; i<MAX_KEY ; i++) allrecords[nfiles].listkw[i].present=0;
|
||||
} else if (flag==0) {
|
||||
/* Is not a file name, is it a searched keyword? */
|
||||
if ((kwnum = isdetectedkeyword( curline, argv, argc-1)) != -1) {
|
||||
/* Is there anything allocated yet to store this? */
|
||||
if (nfiles>0) {
|
||||
/* It has been detected as a searched keyword. */
|
||||
/* Get its value, store it, present flag up */
|
||||
getkeywordvalue(curline, word) ;
|
||||
strcpy(allrecords[nfiles-1].listkw[kwnum].value, word) ;
|
||||
allrecords[nfiles-1].listkw[kwnum].present ++ ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0 ; i<argc-1 ; i++) max_width[i] = (int)strlen(argv[i]) ;
|
||||
|
||||
/* Record the maximum width for each column */
|
||||
max_filnam = 0 ;
|
||||
for (i=0 ; i<nfiles ; i++) {
|
||||
len = (int)strlen(allrecords[i].filename) ;
|
||||
if (len>max_filnam) max_filnam=len ;
|
||||
for (kwnum=0 ; kwnum<argc-1 ; kwnum++) {
|
||||
if (allrecords[i].listkw[kwnum].present) {
|
||||
len = (int)strlen(allrecords[i].listkw[kwnum].value) ;
|
||||
} else {
|
||||
len = 0 ;
|
||||
}
|
||||
if (len>max_width[kwnum]) max_width[kwnum] = len ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print out header line */
|
||||
if (print_hdr) {
|
||||
sprintf(fmt, FMT_STRING, max_filnam) ;
|
||||
if (printnames) printf(fmt, "FILE");
|
||||
for (i=0 ; i<argc-1 ; i++) {
|
||||
sprintf(fmt, FMT_STRING, max_width[i]) ;
|
||||
printf(fmt, argv[i]) ;
|
||||
}
|
||||
printf("\n") ;
|
||||
}
|
||||
|
||||
/* Now print out stored data */
|
||||
if (nfiles<1) {
|
||||
printf("*** error: no input data corresponding to dfits output\n");
|
||||
return -1 ;
|
||||
}
|
||||
for (i=0 ; i<nfiles ; i++) {
|
||||
if (printnames) {
|
||||
sprintf(fmt, FMT_STRING, max_filnam) ;
|
||||
printf(fmt, allrecords[i].filename) ;
|
||||
}
|
||||
for (kwnum=0 ; kwnum<argc-1 ; kwnum++) {
|
||||
sprintf(fmt, FMT_STRING, max_width[kwnum]);
|
||||
if (allrecords[i].listkw[kwnum].present)
|
||||
printf(fmt, allrecords[i].listkw[kwnum].value) ;
|
||||
else printf(fmt, " ");
|
||||
}
|
||||
printf("\n") ;
|
||||
}
|
||||
free(allrecords) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Functions code
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief find out if an input line contains a file name or a FITS magic nb.
|
||||
@param string dfits output line
|
||||
@return int (see below)
|
||||
Filename recognition is based on 'dfits' output. The function returns 1 if
|
||||
the line contains a valid file name as produced by dfits, 2 if it is for an
|
||||
extension, 0 otherwise.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int isfilename(char * string)
|
||||
{
|
||||
if (!strncmp(string, "====>", 5)) return 1 ;
|
||||
if (!strncmp(string, "===>", 4)) return 2 ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief returns a file name from a dfits output line
|
||||
@param line dfits output line
|
||||
@param word file name
|
||||
@return a file name from a dfits output line
|
||||
This is dfits dependent.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void getfilename(char * line, char * word)
|
||||
{
|
||||
/* get filename from a dfits output */
|
||||
sscanf(line, "%*s %*s %s", word) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief detects a if a keyword is present in a FITS line
|
||||
@param line FITS line
|
||||
@param keywords set of keywords
|
||||
@param nkeys number of kw in the set
|
||||
@return keyword rank, -1 if unidentified
|
||||
Feed this function a FITS line, a set of keywords in the *argv[] fashion
|
||||
(*keywords[]). If the provided line appears to contain one of the keywords
|
||||
registered in the list, the rank of the keyword in the list is returned,
|
||||
otherwise, -1 is returned.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int isdetectedkeyword(
|
||||
char * line,
|
||||
char * keywords[],
|
||||
int nkeys)
|
||||
{
|
||||
char kw[MAX_STRING] ;
|
||||
char esokw[MAX_STRING] ;
|
||||
int i ;
|
||||
|
||||
/* The keyword is up to the equal character, with trailing blanks removed */
|
||||
strcpy(kw, line) ;
|
||||
strtok(kw, "=") ;
|
||||
/* Now remove all trailing blanks (if any) */
|
||||
i = (int)strlen(kw) -1 ;
|
||||
while (kw[i] == ' ') i -- ;
|
||||
kw[i+1] = (char)0 ;
|
||||
|
||||
/* Now compare what we got with what's available */
|
||||
for (i=0 ; i<nkeys ; i++) {
|
||||
if (strstr(keywords[i], ".")!=NULL) {
|
||||
/*
|
||||
* keyword contains a dot, it is a hierarchical keyword that
|
||||
* must be expanded. Pattern is:
|
||||
* A.B.C... becomes HIERARCH ESO A B C ...
|
||||
*/
|
||||
expand_hierarch_keyword(keywords[i], esokw) ;
|
||||
if (!strcmp(kw, esokw)) {
|
||||
return i ;
|
||||
}
|
||||
} else if (!strcmp(kw, keywords[i])) {
|
||||
return i ;
|
||||
}
|
||||
}
|
||||
/* Keyword not found */
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Expand a HIERARCH keyword in format A.B.C to HIERARCH ESO A B C
|
||||
@param dotkey Keyword
|
||||
@param hierarchy HIERARCH
|
||||
@return char *, pointer to second input string (modified)
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static char * expand_hierarch_keyword(
|
||||
char * dotkey,
|
||||
char * hierarchy)
|
||||
{
|
||||
char * token ;
|
||||
char ws[MAX_STRING] ;
|
||||
|
||||
sprintf(hierarchy, "HIERARCH ESO");
|
||||
strcpy(ws, dotkey) ;
|
||||
token = strtok(ws, ".") ;
|
||||
while (token!=NULL) {
|
||||
strcat(hierarchy, " ") ;
|
||||
strcat(hierarchy, token) ;
|
||||
token = strtok(NULL, ".");
|
||||
}
|
||||
return hierarchy ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get a keyword value within a FITS line
|
||||
@param line FITS line to process
|
||||
@param word char string to return result
|
||||
@return void, result returned in word
|
||||
No complex value is recognized
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void getkeywordvalue(
|
||||
char * line,
|
||||
char * word)
|
||||
{
|
||||
int c, w ;
|
||||
char tmp[MAX_STRING] ;
|
||||
char *begin, *end ;
|
||||
int length ;
|
||||
int quote = 0 ;
|
||||
int search = 1 ;
|
||||
|
||||
memset(tmp, (char)0, MAX_STRING) ;
|
||||
memset(word, (char)0, MAX_STRING) ;
|
||||
c = w = 0;
|
||||
|
||||
/* Parse the line till the equal '=' sign is found */
|
||||
while (line[c] != '=') c++ ;
|
||||
c++ ;
|
||||
|
||||
/* Copy the line till the slash '/' sign or the end of data is found. */
|
||||
while (search == 1) {
|
||||
if (c>=80) search = 0 ;
|
||||
else if ((line[c] == '/') && (quote == 0)) search = 0 ;
|
||||
if (line[c] == '\'') quote = !quote ;
|
||||
tmp[w++] = line[c++] ;
|
||||
}
|
||||
|
||||
/* NULL termination of the string */
|
||||
tmp[--w] = (char)0 ;
|
||||
|
||||
/* Return the keyword only : a diff is made between text fields and nbs. */
|
||||
if ((begin = strchr(tmp, '\'')) != (char*)NULL) {
|
||||
/* A quote has been found: it is a string value */
|
||||
begin++ ;
|
||||
end = strrchr(tmp, '\'') ;
|
||||
length = (int)strlen(begin) - (int)strlen(end) ;
|
||||
strncpy(word, begin, length) ;
|
||||
} else {
|
||||
/* No quote, just get the value (only one, no complex supported) */
|
||||
sscanf(tmp, "%s", word) ;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
|
@ -0,0 +1,603 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file hierarch28.c
|
||||
@author N. Devillard
|
||||
@date July 14th, 1998
|
||||
@version $Revision: 1.6 $
|
||||
@brief header conversion from ESO-FITS to standard FITS
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: hierarch28.c,v 1.6 2005/06/29 15:14:50 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/06/29 15:14:50 $
|
||||
$Revision: 1.6 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Include
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define NM_SIZ 512
|
||||
#define FITS_LINE 80
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static char prog_desc[] = "header conversion from ESO to standard FITS" ;
|
||||
static void usage(char *) ;
|
||||
static int convert_eso_to_std_FITS(char *, char *) ;
|
||||
static void free_keys(char **, int n) ;
|
||||
static void strip_beg_end(char *) ;
|
||||
static int search_and_replace_kw(char *, int, char **, char **, int) ;
|
||||
static void search_rep(char *, char *, char *);
|
||||
static void generate_default_convtab(void);
|
||||
static char * convert_deg_to_str(double deg) ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Static variables
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static char CONVTAB_DEFAULT1[] =
|
||||
"#\n"
|
||||
"# Example of conversion table for hierarch28\n"
|
||||
"#\n"
|
||||
"# A note about this file's format:\n"
|
||||
"# Any blank line or line starting with a hash is ignored.\n"
|
||||
"# Declare the keyword names to search and replace with:\n"
|
||||
"#\n"
|
||||
"# OLDKEYWORD = NEWKEYWORD\n"
|
||||
"#\n"
|
||||
"# Spaces are allowed within keyword names, to allow e.g.:\n"
|
||||
"#\n"
|
||||
"# HIERARCH ESO DET NDIT = DET NDIT\n"
|
||||
"#\n"
|
||||
"# The most important restriction is that new keywords shall not be\n"
|
||||
"# longer than the keywords they replace.\n"
|
||||
"#\n" ;
|
||||
|
||||
|
||||
static char CONVTAB_DEFAULT2[] =
|
||||
"#\n"
|
||||
"# Translation table for basic keywords used by IRAF\n"
|
||||
"# -------------------------------------------------\n"
|
||||
"#\n"
|
||||
"# Note: hierarch28 will replace keywords in the main header\n"
|
||||
"# and also in extensions.\n"
|
||||
"#\n"
|
||||
"# Disclaimer:\n"
|
||||
"# this table has been compiled to best knowledge of present\n"
|
||||
"# IRAF packages. Please let us know of any addition/change.\n"
|
||||
"#\n"
|
||||
"\n" ;
|
||||
|
||||
|
||||
static char CONVTAB_DEFAULT3[] =
|
||||
"UTC = UT\n"
|
||||
"LST = ST\n"
|
||||
"RA = RA\n"
|
||||
"DEC = DEC\n"
|
||||
"\n"
|
||||
"HIERARCH ESO TEL AIRM START = AIRMASS\n"
|
||||
"HIERARCH ESO DPR TYPE = IMAGETYP\n"
|
||||
"HIERARCH ESO INS FILT1 NAME = FILTER1\n"
|
||||
"HIERARCH ESO INS SLIT2 NAME = SLIT\n"
|
||||
"HIERARCH ESO INS GRIS1 NAME = GRISM\n"
|
||||
"HIERARCH ESO INS GRAT NAME = GRAT\n"
|
||||
"HIERARCH ESO INS GRAT1 NAME = GRAT1\n"
|
||||
"HIERARCH ESO INS GRAT2 NAME = GRAT2\n"
|
||||
"HIERARCH ESO INS GRAT WLEN = WLEN\n"
|
||||
"HIERARCH ESO INS GRAT1 WLEN = WLEN1\n"
|
||||
"HIERARCH ESO INS GRAT2 WLEN = WLEN2\n"
|
||||
"HIERARCH ESO INS GRAT ORDER = ORDER\n"
|
||||
"\n" ;
|
||||
|
||||
static char CONVTAB_DEFAULT4[] =
|
||||
"#\n"
|
||||
"# A note for IRAF users:\n"
|
||||
"# Be aware also that the ESO convention names the keywords UTC and\n"
|
||||
"# LST, whereas the IRAF convention is 'UT' and 'ST'.\n"
|
||||
"#\n"
|
||||
"# The ESO standard (see http://archive.eso.org/dicb) defines these\n"
|
||||
"# keywords as floating point values with the units degrees for RA/DEC\n"
|
||||
"# and elapsed seconds since midnight for UT/ST.\n"
|
||||
"#\n"
|
||||
"# In order to have this tranlation performed, add\n"
|
||||
"# RA = RA\n"
|
||||
"# DEC = DEC\n"
|
||||
"# UTC = UT\n"
|
||||
"# LST = ST\n"
|
||||
"# to the conversion table.\n"
|
||||
"#\n";
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char name_conv[NM_SIZ] ;
|
||||
char name_in[NM_SIZ] ;
|
||||
|
||||
if (argc<2) usage(argv[0]) ;
|
||||
if (!strcmp(argv[1], "-g")) {
|
||||
generate_default_convtab() ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
strcpy(name_in, argv[1]) ;
|
||||
if (argc==3) {
|
||||
strcpy(name_conv, argv[2]) ;
|
||||
} else {
|
||||
strcpy(name_conv, "table.conv") ;
|
||||
}
|
||||
|
||||
if (convert_eso_to_std_FITS(name_in, name_conv) != 0) {
|
||||
fprintf(stderr, "error during conversion: aborting\n") ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static void usage(char * pname)
|
||||
{
|
||||
printf(
|
||||
"\n\n"
|
||||
"hierarch28 (hierarch-to-eight)\n"
|
||||
"%s : %s\n"
|
||||
"use : %s [options] <in> [table]\n"
|
||||
"options are:\n"
|
||||
"\t-g generates a generic table\n"
|
||||
"\n"
|
||||
"default conversion table name is 'table.conv'\n"
|
||||
"\n"
|
||||
"More help can be found in the comments included in the default\n"
|
||||
"conversion table. Generate one with the -g option and read it.\n"
|
||||
"\n\n",
|
||||
pname, prog_desc, pname);
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Search and replace FITS keywords in main/extension headers.
|
||||
@param name_in File to modify.
|
||||
@param name_conv Conversion table name.
|
||||
@return int 0 if Ok, non-zero if error occurred.
|
||||
|
||||
The input file is modified in place. Keyword names are replaced
|
||||
according to the input conversion table. In some special cases, the
|
||||
keyword values are also modified to follow the IRAF convention.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int convert_eso_to_std_FITS(char * name_in, char * name_conv)
|
||||
{
|
||||
FILE * convtab ;
|
||||
int nkeys ;
|
||||
int i ;
|
||||
char ** key_in ;
|
||||
char ** key_out ;
|
||||
int fd ;
|
||||
char * buf ;
|
||||
char line[NM_SIZ] ;
|
||||
char kw1[FITS_LINE],
|
||||
kw2[FITS_LINE] ;
|
||||
int lineno ;
|
||||
int fs ;
|
||||
struct stat fileinfo ;
|
||||
|
||||
/* Read conversion table and translate it to key_in, key_out */
|
||||
if ((convtab = fopen(name_conv, "r")) == NULL) {
|
||||
fprintf(stderr, "cannot open conversion table: %s\n", name_conv) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* First, count how many keywords we need to translate */
|
||||
nkeys = 0 ;
|
||||
while (fgets(line, FITS_LINE, convtab)!=NULL) {
|
||||
if ((line[0] != '#') && (line[0] != '\n')) {
|
||||
nkeys ++ ;
|
||||
}
|
||||
}
|
||||
rewind(convtab) ;
|
||||
|
||||
/* Allocate space to store keyword info */
|
||||
key_in = malloc(nkeys * sizeof(char*)) ;
|
||||
key_out = malloc(nkeys * sizeof(char*)) ;
|
||||
|
||||
/* Now read the file through and get the keywords */
|
||||
i = 0 ;
|
||||
lineno = 0 ;
|
||||
while (fgets(line, FITS_LINE, convtab)!=NULL) {
|
||||
lineno++ ;
|
||||
if ((line[0]!='#') && (line[0]!='\n')) {
|
||||
if (sscanf(line, "%[^=] = %[^;#]", kw1, kw2)!=2) {
|
||||
fprintf(stderr,
|
||||
"*** error parsing table file %s\n", name_conv);
|
||||
fprintf(stderr, "line: %d\n", lineno) ;
|
||||
free_keys(key_in, i) ;
|
||||
free_keys(key_out, i) ;
|
||||
fclose(convtab) ;
|
||||
return -1 ;
|
||||
}
|
||||
strip_beg_end(kw1) ;
|
||||
strip_beg_end(kw2) ;
|
||||
if (strlen(kw2)>strlen(kw1)) {
|
||||
fprintf(stderr,
|
||||
"*** error in conversion table %s (line %d)\n",
|
||||
name_conv, lineno);
|
||||
fprintf(stderr,
|
||||
"*** error: dest keyword is longer than original\n");
|
||||
fprintf(stderr, "orig: [%s] dest: [%s]\n", kw1, kw2);
|
||||
fclose(convtab) ;
|
||||
free_keys(key_in, i) ;
|
||||
free_keys(key_out, i) ;
|
||||
return -1 ;
|
||||
}
|
||||
key_in[i] = strdup(kw1) ;
|
||||
key_out[i] = strdup(kw2) ;
|
||||
i++ ;
|
||||
}
|
||||
}
|
||||
fclose(convtab) ;
|
||||
|
||||
/* Print out some information about what is being done */
|
||||
printf("\n\n") ;
|
||||
printf("*** hierarch28\n") ;
|
||||
printf("\n") ;
|
||||
printf("searching %s and replacing the following keywords:\n", name_in) ;
|
||||
for (i=0 ; i<nkeys ; i++) {
|
||||
printf("\t[%s]\t=>\t[%s]\n", key_in[i], key_out[i]) ;
|
||||
}
|
||||
printf("\n\n") ;
|
||||
|
||||
/* mmap the input file entirely */
|
||||
if (stat(name_in, &fileinfo)!=0) {
|
||||
fprintf(stderr, "*** error: accessing file [%s]\n", name_in);
|
||||
free_keys(key_in, nkeys) ;
|
||||
free_keys(key_out, nkeys) ;
|
||||
return -1 ;
|
||||
}
|
||||
fs = (int)fileinfo.st_size ;
|
||||
if (fs < 1) {
|
||||
fprintf(stderr, "error getting FITS header size for %s\n", name_in);
|
||||
free_keys(key_in, nkeys) ;
|
||||
free_keys(key_out, nkeys) ;
|
||||
return -1 ;
|
||||
}
|
||||
fd = open(name_in, O_RDWR) ;
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "cannot open %s: aborting\n", name_in) ;
|
||||
free_keys(key_in, nkeys) ;
|
||||
free_keys(key_out, nkeys) ;
|
||||
return -1 ;
|
||||
}
|
||||
buf = (char*)mmap(0,
|
||||
fs,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0) ;
|
||||
if (buf == (char*)-1) {
|
||||
perror("mmap") ;
|
||||
fprintf(stderr, "cannot mmap file: %s\n", name_in) ;
|
||||
free_keys(key_in, nkeys) ;
|
||||
free_keys(key_out, nkeys) ;
|
||||
close(fd) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Apply search and replace for the input keyword lists */
|
||||
if (search_and_replace_kw(buf, fs, key_in, key_out, nkeys) != 0) {
|
||||
fprintf(stderr, "error while doing search and replace\n") ;
|
||||
}
|
||||
free_keys(key_in, nkeys) ;
|
||||
free_keys(key_out, nkeys) ;
|
||||
close(fd) ;
|
||||
munmap(buf, fs) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Strips out blank characters off a character string.
|
||||
@param s NULL-terminated string to process.
|
||||
@return void
|
||||
|
||||
This function removes heading and trailing blanks from a
|
||||
NULL-terminated character string. The input string is modified. The
|
||||
input string is assumed to contain only blanks or alphanumeric
|
||||
characters (like FITS keywords).
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void strip_beg_end(char * s)
|
||||
{
|
||||
int beg, len ;
|
||||
|
||||
beg = 0 ;
|
||||
while (!isalnum((unsigned char)(s[beg]))) beg++ ;
|
||||
|
||||
len = (int)strlen(s) -1 ;
|
||||
while (!isalnum((unsigned char)(s[len]))) len -- ;
|
||||
|
||||
strncpy(s, s+beg, len-beg+1) ;
|
||||
s[len-beg+1] = (char)0 ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Free memory associated to an array of keys.
|
||||
@param keyt Key table.
|
||||
@param n Number of keys in the table.
|
||||
@return void
|
||||
|
||||
Memory was initially allocated using strdup(). This frees all the
|
||||
keys and the master table pointer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void free_keys(char ** keyt, int n)
|
||||
{
|
||||
int i ;
|
||||
|
||||
if (n<1) return ;
|
||||
for (i=0 ; i<n ; i++) free(keyt[i]) ;
|
||||
free(keyt) ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Search keywords and replace them over a whole buffer.
|
||||
@param buf Buffer to modify.
|
||||
@param bufsize Buffer size in bytes.
|
||||
@param key_in Input key table.
|
||||
@param key_out Output key table.
|
||||
@param nk Number of keys in each table (same).
|
||||
@return int 0 if Ok, non-zero if error occurred.
|
||||
|
||||
Main replace function: it browses through the entire file to support
|
||||
keyword changes in extensions too. Heavily optimized for speed.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int search_and_replace_kw(
|
||||
char * buf,
|
||||
int bufsize,
|
||||
char ** key_in,
|
||||
char ** key_out,
|
||||
int nk)
|
||||
{
|
||||
char * w ;
|
||||
int i, j ;
|
||||
int in_header ;
|
||||
int match_flag ;
|
||||
int * keysizes ;
|
||||
|
||||
/* Pre-compute key sizes to gain time */
|
||||
keysizes = malloc(nk * sizeof(int));
|
||||
for (i=0 ; i<nk ; i++) keysizes[i] = (int)strlen(key_in[i]);
|
||||
|
||||
/* Browse through file line by line */
|
||||
w = buf ;
|
||||
in_header=1 ;
|
||||
while ((w-buf+FITS_LINE)<bufsize) {
|
||||
if (in_header) { /* Currently browsing a header */
|
||||
if (w[0]=='E' &&
|
||||
w[1]=='N' &&
|
||||
w[2]=='D' &&
|
||||
w[3]==' ') {
|
||||
/* Found an END keyword: exit from header */
|
||||
in_header=0 ;
|
||||
} else {
|
||||
/* Compare the current line with all searched keys */
|
||||
for (i=0 ; i<nk ; i++) {
|
||||
match_flag=1 ;
|
||||
for (j=0 ; j<=keysizes[i] ; j++) {
|
||||
if (j<keysizes[i]) {
|
||||
if (key_in[i][j]!=w[j]) {
|
||||
match_flag=0 ;
|
||||
break ;
|
||||
}
|
||||
} else {
|
||||
if ((w[j] != '=') && (w[j] != ' ')) {
|
||||
match_flag=0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match_flag) {
|
||||
search_rep(w, key_in[i], key_out[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Currently out of header, look for next extension */
|
||||
if (w[0]=='X' &&
|
||||
w[1]=='T' &&
|
||||
w[2]=='E' &&
|
||||
w[3]=='N' &&
|
||||
w[4]=='S' &&
|
||||
w[5]=='I' &&
|
||||
w[6]=='O' &&
|
||||
w[7]=='N') {
|
||||
/* Found a header start */
|
||||
in_header=1 ;
|
||||
}
|
||||
}
|
||||
w+=FITS_LINE ;
|
||||
}
|
||||
free(keysizes);
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Atomic keyword replacement.
|
||||
@param line Line to work on.
|
||||
@param key_i Input key.
|
||||
@param key_o Output key.
|
||||
@return void
|
||||
|
||||
Replace in 'line' the keyword name 'key_i' by 'key_o'. In some
|
||||
special cases, the value is also modified to reflect the IRAF
|
||||
conventions.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void search_rep(char * line, char * key_i, char * key_o)
|
||||
{
|
||||
int i, j ;
|
||||
char * equal ;
|
||||
int to_copy ;
|
||||
char * p ;
|
||||
char tmp[FITS_LINE+1];
|
||||
char comment[FITS_LINE+1];
|
||||
|
||||
equal = strstr(line, "=");
|
||||
to_copy = FITS_LINE - (equal-line);
|
||||
for (i=0 ; i<(int)strlen(key_o) ; i++) {
|
||||
line[i] = key_o[i] ;
|
||||
}
|
||||
if (strlen(key_o)<=8) {
|
||||
/* Blank-pad until equal sign is reached */
|
||||
for ( ; i<8 ; i++) {
|
||||
line[i]=' ';
|
||||
}
|
||||
/* Add equal sign */
|
||||
line[i] = '=' ;
|
||||
i++ ;
|
||||
|
||||
/* Handle special cases: the value also needs conversion */
|
||||
if(!strcmp(key_o, "RA")) {
|
||||
if (*(equal+2)!='\'') {
|
||||
/* out key is RA, translate to ' HH:MM:SS.SSS' */
|
||||
p = strchr(line+i, '/');
|
||||
if (p)
|
||||
strncpy(comment, p, line+FITS_LINE-p);
|
||||
sprintf(tmp, " %-29.29s %-40.40s",
|
||||
convert_deg_to_str(atof(equal+1)/15.),
|
||||
(p)? comment : "/ Right Ascension");
|
||||
memcpy(line+i, tmp, 71);
|
||||
}
|
||||
} else if(!strcmp(key_o, "DEC")) {
|
||||
if( *(equal+2)!='\'') {
|
||||
/* out key is DEC, translate to '+DD:MM:SS.SSS' */
|
||||
p = strchr(line+i, '/');
|
||||
if (p)
|
||||
strncpy(comment, p, line+FITS_LINE-p);
|
||||
sprintf(tmp, " %-29.29s %-40.40s",
|
||||
convert_deg_to_str(atof(equal+1)),
|
||||
(p)? comment : "/ Declination");
|
||||
memcpy(line+i, tmp, 71);
|
||||
}
|
||||
} else if(!strcmp(key_o, "UT")) {
|
||||
if( *(equal+2)!='\'') {
|
||||
/* out key is UT, translate to ' HH:MM:SS.SSS' */
|
||||
p = strchr(line+i, '/');
|
||||
if (p)
|
||||
strncpy(comment, p, line+FITS_LINE-p);
|
||||
sprintf(tmp, " %-29.29s %-40.40s",
|
||||
convert_deg_to_str(atof(equal+1)/3600.),
|
||||
(p)? comment : "/ UT");
|
||||
memcpy(line+i, tmp, 71);
|
||||
}
|
||||
} else if(!strcmp(key_o, "ST")) {
|
||||
if( *(equal+2)!='\'') {
|
||||
/* out key is ST, translate to ' HH:MM:SS.SSS' */
|
||||
p = strchr(line+i, '/');
|
||||
if (p)
|
||||
strncpy(comment, p, line+FITS_LINE-p);
|
||||
sprintf(tmp, " %-29.29s %-40.40s",
|
||||
convert_deg_to_str(atof(equal+1)/3600.),
|
||||
(p)? comment : "/ ST");
|
||||
memcpy(line+i, tmp, 71);
|
||||
}
|
||||
} else {
|
||||
/* Copy line from first char after real equal sign */
|
||||
for (j=0 ; j<to_copy ; j++) {
|
||||
line[i+j] = equal[j+1];
|
||||
}
|
||||
i+=to_copy-1 ;
|
||||
/* Blank padding */
|
||||
for ( ; i<FITS_LINE ; i++) {
|
||||
line[i]=' ';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Blank padding */
|
||||
for (i=(int)strlen(key_o) ; i<(int)strlen(key_i) ; i++) {
|
||||
line[i]=' ';
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a default conversion table.
|
||||
@param ins Table name.
|
||||
@return void
|
||||
|
||||
Creates a translation table for the requested instrument. If no
|
||||
instrument is specified (ins==NULL) a default table is generated.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void generate_default_convtab(void)
|
||||
{
|
||||
FILE * convtab ;
|
||||
|
||||
if ((convtab = fopen("table.conv", "w")) == NULL) {
|
||||
fprintf(stderr, "*** error: cannot create table.conv: aborting\n") ;
|
||||
return ;
|
||||
}
|
||||
fprintf(convtab, CONVTAB_DEFAULT1);
|
||||
fprintf(convtab, CONVTAB_DEFAULT2);
|
||||
fprintf(convtab, CONVTAB_DEFAULT3);
|
||||
fprintf(convtab, CONVTAB_DEFAULT4);
|
||||
fclose(convtab) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Convert decimal degrees to ASCII representation.
|
||||
@param d Double value, decimal degrees in [-90 ; +90].
|
||||
@return Pointer to statically allocated character string.
|
||||
|
||||
Converts an angle value from degrees to ASCII representation
|
||||
following the IRAF convention. Do not free or modify the returned
|
||||
string.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static char * convert_deg_to_str( double deg )
|
||||
{
|
||||
int d, m;
|
||||
double s;
|
||||
int sign;
|
||||
static char buf[13];
|
||||
|
||||
sign = 1;
|
||||
if(deg < 0.) sign = -1;
|
||||
|
||||
deg *= sign;
|
||||
d = (int)deg;
|
||||
m = (int)( (deg - d) * 60);
|
||||
s = (deg - d) * 3600. - m * 60;
|
||||
|
||||
sprintf(buf, "'%c%02d:%02d:%06.3f'", (sign<0)? '-' : ' ', d, m, s);
|
||||
|
||||
return(buf);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,340 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file stripfits.c
|
||||
@author N. Devillard
|
||||
@date January 1999
|
||||
@version $Revision: 1.2 $
|
||||
@brief Dumps all the pixels from a FITS header into another file.
|
||||
This is a stand-alone tool, compile it with:
|
||||
gcc -o stripfits stripfits.c -O
|
||||
|
||||
This program dumps all the pixels from a FITS header into another file.
|
||||
It has been written in less than 10 minutes (reusing most of the code
|
||||
from iofits.c) to help the guys working on the ISAAC detector that day.
|
||||
Since it is a good example of how to write a stand-alone FITS command, I
|
||||
leave it here in the distribution.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: stripfits.c,v 1.2 2002/11/21 14:18:18 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2002/11/21 14:18:18 $
|
||||
$Revision: 1.2 $
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Include
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Define
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define NM_SIZ 512
|
||||
#define FITS_BLSZ 2880
|
||||
#define ONE_MEGABYTE (1024 * 1024)
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int dump_pix(char*, char*);
|
||||
static int get_FITS_header_size(char *) ;
|
||||
static int filesize(char*) ;
|
||||
static int get_bitpix(char*) ;
|
||||
static int get_npix(char*) ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Main
|
||||
-----------------------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc<3) {
|
||||
printf("\n\n") ;
|
||||
printf("use: %s <in> <out>\n", argv[0]) ;
|
||||
printf("\n") ;
|
||||
printf("\t<in> is a valid FITS file in the current directory\n") ;
|
||||
printf("\t<out> is the name of the output file\n") ;
|
||||
printf("\n\n") ;
|
||||
return 0 ;
|
||||
}
|
||||
if (!strcmp(argv[1], argv[2])) {
|
||||
fprintf(stderr, "cannot convert a file to itself\n") ;
|
||||
fprintf(stderr, "specify another name for the output\n") ;
|
||||
return -1 ;
|
||||
}
|
||||
return dump_pix(argv[1], argv[2]);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief dump pixels from a FITS file to a binary file
|
||||
@param name_in Input file name
|
||||
@param name_out Output file name
|
||||
@return int 0 if Ok, anything else otherwise
|
||||
Heavy use of mmap() to speed up the process
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int dump_pix(
|
||||
char * name_in,
|
||||
char * name_out)
|
||||
{
|
||||
int fd_in,
|
||||
fd_out ;
|
||||
char * buf_in ;
|
||||
char * buf_out ;
|
||||
int fsize_in,
|
||||
fsize_out,
|
||||
header_size ;
|
||||
int npix ;
|
||||
|
||||
/*
|
||||
* Open input file and get information we need:
|
||||
* - pixel depth
|
||||
* - number of pixels
|
||||
*/
|
||||
|
||||
fsize_in = filesize(name_in) ;
|
||||
header_size = get_FITS_header_size(name_in) ;
|
||||
if ((fd_in = open(name_in, O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "cannot open file %s: aborting\n", name_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
buf_in = (char*)mmap(0, fsize_in, PROT_READ, MAP_SHARED, fd_in, 0) ;
|
||||
if (buf_in == (char*)-1) {
|
||||
perror("mmap") ;
|
||||
fprintf(stderr, "cannot mmap file: %s\n", name_in) ;
|
||||
close(fd_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
if (get_bitpix(buf_in) != -32) {
|
||||
fprintf(stderr, "only 32-bit IEEE floating point format supported\n");
|
||||
close(fd_in) ; munmap(buf_in, fsize_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the size of the output file
|
||||
* same header size, + pixel area + blank padding
|
||||
*/
|
||||
npix = get_npix(buf_in) ;
|
||||
if (npix < 1) {
|
||||
fprintf(stderr, "cannot compute number of pixels\n");
|
||||
close(fd_in) ;
|
||||
munmap(buf_in, fsize_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
fsize_out = npix * 4 ;
|
||||
/*
|
||||
* Now create the output file and fill it with zeros, then mmap it.
|
||||
* The permissions are rw-rw-r-- by default.
|
||||
*/
|
||||
if ((fd_out=creat(name_out,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH))==-1){
|
||||
perror("creat") ;
|
||||
fprintf(stderr, "cannot create file %s: aborting\n", name_out) ;
|
||||
close(fd_in) ; munmap(buf_in, fsize_in) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
buf_out = malloc(fsize_out) ;
|
||||
if (buf_out == NULL) {
|
||||
fprintf(stderr, "not enough memory\n");
|
||||
fprintf(stderr, "failed to allocate %d bytes\n", fsize_out);
|
||||
close(fd_in) ; munmap(buf_in, fsize_in) ;
|
||||
return -1;
|
||||
}
|
||||
write(fd_out, buf_out, fsize_out);
|
||||
close(fd_out);
|
||||
free(buf_out);
|
||||
|
||||
fd_out = open(name_out, O_RDWR);
|
||||
if (fd_out==-1) {
|
||||
fprintf(stderr, "error opening file %s\n", name_out);
|
||||
close(fd_in) ; munmap(buf_in, fsize_in) ;
|
||||
return -1;
|
||||
}
|
||||
buf_out = (char*)mmap(0,
|
||||
fsize_out,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd_out,
|
||||
0) ;
|
||||
if (buf_out == (char*)-1) {
|
||||
perror("mmap") ;
|
||||
fprintf(stderr, "cannot mmap file: %s\n", name_out) ;
|
||||
munmap(buf_in, fsize_in) ; close(fd_in) ; close(fd_out) ;
|
||||
return -1 ;
|
||||
}
|
||||
/*
|
||||
* Copy FITS header from input to output, modify BITPIX
|
||||
*/
|
||||
memcpy(buf_out, buf_in+header_size, fsize_out) ;
|
||||
/*
|
||||
* Close, unmap, goodbye
|
||||
*/
|
||||
close(fd_in) ;
|
||||
close(fd_out) ;
|
||||
munmap(buf_in, fsize_in) ;
|
||||
munmap(buf_out, fsize_out) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief compute the size (in bytes) of a FITS header
|
||||
@param name FITS file name
|
||||
@return unsigned long
|
||||
Should always be a multiple of 2880. This implementation assumes only that
|
||||
80 characters are found per line.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int get_FITS_header_size(char * name)
|
||||
{
|
||||
FILE * in ;
|
||||
char line[81] ;
|
||||
int found = 0 ;
|
||||
int count ;
|
||||
int hs ;
|
||||
|
||||
if ((in = fopen(name, "r")) == NULL) {
|
||||
fprintf(stderr, "cannot open %s: aborting\n", name) ;
|
||||
return 0 ;
|
||||
}
|
||||
count = 0 ;
|
||||
while (!found) {
|
||||
if (fread(line, 1, 80, in)!=80) {
|
||||
break ;
|
||||
}
|
||||
count ++ ;
|
||||
if (!strncmp(line, "END ", 4)) {
|
||||
found = 1 ;
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if (!found) return 0 ;
|
||||
/*
|
||||
* The size is the number of found cards times 80,
|
||||
* rounded to the closest higher multiple of 2880.
|
||||
*/
|
||||
hs = count * 80 ;
|
||||
if ((hs % FITS_BLSZ) != 0) {
|
||||
hs = (1+(hs/FITS_BLSZ)) * FITS_BLSZ ;
|
||||
}
|
||||
return hs ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief how many bytes can I read from this file
|
||||
@param filename File name
|
||||
@return size of the file in bytes
|
||||
Strongly non portable. Only on Unix systems!
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int filesize(char *filename)
|
||||
{
|
||||
int size ;
|
||||
struct stat fileinfo ;
|
||||
|
||||
/* POSIX compliant */
|
||||
if (stat(filename, &fileinfo) != 0) {
|
||||
size = (int)0 ;
|
||||
} else {
|
||||
size = (int)fileinfo.st_size ;
|
||||
}
|
||||
return size ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief gets the value of BITPIX from a FITS header
|
||||
@param buf allocated char buffer containing the whole FITS header
|
||||
@return int 8 16 32 -32 or -64 or 0 if cannot find it
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int get_bitpix(char * buf)
|
||||
{
|
||||
int bitpix ;
|
||||
char * where ;
|
||||
|
||||
where = strstr(buf, "BITPIX") ;
|
||||
if (where == NULL) {
|
||||
fprintf(stderr, "cannot find BITPIX in header: aborting\n") ;
|
||||
return 0 ;
|
||||
}
|
||||
sscanf(where, "%*[^=] = %d", &bitpix) ;
|
||||
/*
|
||||
* Check the returned value makes sense
|
||||
*/
|
||||
if ((bitpix != 8) &&
|
||||
(bitpix != 16) &&
|
||||
(bitpix != 32) &&
|
||||
(bitpix != -32) &&
|
||||
(bitpix != -64)) {
|
||||
bitpix = 0 ;
|
||||
}
|
||||
return bitpix ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief retrieves how many pixels in a FITS file from the header
|
||||
@param buf allocated char buffer containing the whole FITS header
|
||||
@return unsigned long: # of pixels in the file
|
||||
Does not support extensions!
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int get_npix(char * buf)
|
||||
{
|
||||
int naxes ;
|
||||
int npix ;
|
||||
int naxis ;
|
||||
char * where ;
|
||||
char lookfor[80] ;
|
||||
int i ;
|
||||
|
||||
where = strstr(buf, "NAXIS") ;
|
||||
if (where == NULL) {
|
||||
fprintf(stderr, "cannot find NAXIS in header: aborting\n") ;
|
||||
return 0 ;
|
||||
}
|
||||
sscanf(where, "%*[^=] = %d", &naxes) ;
|
||||
if ((naxes<1) || (naxes>999)) {
|
||||
fprintf(stderr, "illegal value for %s: %d\n", lookfor, naxes) ;
|
||||
return 0 ;
|
||||
}
|
||||
npix = 1 ;
|
||||
for (i=1 ; i<=naxes ; i++) {
|
||||
sprintf(lookfor, "NAXIS%d", i) ;
|
||||
where = strstr(buf, lookfor) ;
|
||||
if (where == NULL) {
|
||||
fprintf(stderr, "cannot find %s in header: aborting\n",
|
||||
lookfor) ;
|
||||
return 0 ;
|
||||
}
|
||||
sscanf(where, "%*[^=] = %d", &naxis) ;
|
||||
if (naxis<1) {
|
||||
fprintf(stderr, "error: found %s=%d\n", lookfor, naxis);
|
||||
return 0 ;
|
||||
}
|
||||
npix *= (int)naxis ;
|
||||
}
|
||||
return npix ;
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file cache.h
|
||||
@author N. Devillard
|
||||
@date Mar 2001
|
||||
@version $Revision: 1.5 $
|
||||
@brief FITS caching capabilities
|
||||
|
||||
This modules implements a cache for FITS access routines.
|
||||
The first time a FITS file is seen by the library, all corresponding
|
||||
pointers are cached here. This speeds up multiple accesses to large
|
||||
files by magnitudes.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: cache.h,v 1.5 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
#ifndef CACHE_H
|
||||
#define CACHE_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/** Query the number of extensions */
|
||||
#define QFITS_QUERY_N_EXT (1<<30)
|
||||
/** Query the offset to header start */
|
||||
#define QFITS_QUERY_HDR_START (1<<29)
|
||||
/** Query the offset to data start */
|
||||
#define QFITS_QUERY_DAT_START (1<<28)
|
||||
/** Query header size in bytes */
|
||||
#define QFITS_QUERY_HDR_SIZE (1<<27)
|
||||
/** Query data size in bytes */
|
||||
#define QFITS_QUERY_DAT_SIZE (1<<26)
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Purge the qfits cache.
|
||||
@return void
|
||||
|
||||
This function is useful for programs running for a long period,
|
||||
to clean up the cache. Ideally in a daemon, it should be called
|
||||
by a timer at regular intervals. Notice that since the cache is
|
||||
fairly small, you should not need to care too much about this.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_cache_purge(void);
|
||||
/* </dox> */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Query a FITS file offset from the cache.
|
||||
@param filename Name of the file to examine.
|
||||
@param what What should be queried (see below).
|
||||
@return an integer offset, or -1 if an error occurred.
|
||||
|
||||
This function queries the cache for FITS offset information. If the
|
||||
requested file name has never been seen before, it is completely parsed
|
||||
to extract all offset informations, which are then stored in the cache.
|
||||
The next query will get the informations from the cache, avoiding
|
||||
a complete re-parsing of the file. This is especially useful for large
|
||||
FITS files with lots of extensions, because querying the extensions
|
||||
is an expensive operation.
|
||||
|
||||
This operation has side-effects: the cache is an automatically
|
||||
allocated structure in memory, that can only grow. Every request
|
||||
on a new FITS file will make it grow. The structure is pretty
|
||||
light-weight in memory, but nonetheless this is an issue for daemon-type
|
||||
programs which must run over long periods. The solution is to clean
|
||||
the cache using qfits_cache_purge() at regular intervals. This is left
|
||||
to the user of this library.
|
||||
|
||||
To request information about a FITS file, you must pass an integer
|
||||
built from the following symbols:
|
||||
|
||||
- @c QFITS_QUERY_N_EXT
|
||||
- @c QFITS_QUERY_HDR_START
|
||||
- @c QFITS_QUERY_DAT_START
|
||||
- @c QFITS_QUERY_HDR_SIZE
|
||||
- @c QFITS_QUERY_DAT_SIZE
|
||||
|
||||
Querying the number of extensions present in a file is done
|
||||
simply with:
|
||||
|
||||
@code
|
||||
next = qfits_query(filename, QFITS_QUERY_N_EXT);
|
||||
@endcode
|
||||
|
||||
Querying the offset to the i-th extension header is done with:
|
||||
|
||||
@code
|
||||
off = qfits_query(filename, QFITS_QUERY_HDR_START | i);
|
||||
@endcode
|
||||
|
||||
i.e. you must OR (|) the extension number with the
|
||||
@c QFITS_QUERY_HDR_START symbol. Requesting offsets to extension data is
|
||||
done in the same way:
|
||||
|
||||
@code
|
||||
off = qfits_query(filename, QFITS_QUERY_DAT_START | i);
|
||||
@endcode
|
||||
|
||||
Notice that extension 0 is the main header and main data part
|
||||
of the FITS file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_query(char * filename, int what);
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,20 @@
|
|||
/* This file automatically generated */
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
|
||||
#define SIZEOF_CHAR 1
|
||||
#define SIZEOF_SHORT 2
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_LONG 8
|
||||
#define SIZEOF_FLOAT 4
|
||||
#define SIZEOF_DOUBLE 8
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define OS_LINUX 1
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file expkey.h
|
||||
@author N. Devillard
|
||||
@date Feb 2001
|
||||
@version $Revisions$
|
||||
@brief Expand keyword from shortFITS to HIERARCH notation
|
||||
|
||||
This module offers a function that is reused in a number of different
|
||||
places.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: expkey.h,v 1.6 2005/05/18 14:38:01 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/05/18 14:38:01 $
|
||||
$Revision: 1.6 $
|
||||
*/
|
||||
|
||||
#ifndef EXPKEY_H
|
||||
#define EXPKEY_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Expand a keyword from shortFITS to HIERARCH notation.
|
||||
@param keyword Keyword to expand.
|
||||
@return 1 pointer to statically allocated string.
|
||||
|
||||
This function expands a given keyword from shortFITS to HIERARCH
|
||||
notation, bringing it to uppercase at the same time.
|
||||
|
||||
Examples:
|
||||
|
||||
@verbatim
|
||||
det.dit expands to HIERARCH ESO DET DIT
|
||||
ins.filt1.id expands to HIERARCH ESO INS FILT1 ID
|
||||
@endverbatim
|
||||
|
||||
If the input keyword is a regular FITS keyword (i.e. it contains
|
||||
not dots '.') the result is identical to the input.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_expand_keyword(const char * keyword);
|
||||
/* </dox> */
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,475 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fits_h.h
|
||||
@author N. Devillard
|
||||
@date Mar 2000
|
||||
@version $Revision: 1.13 $
|
||||
@brief FITS header handling
|
||||
|
||||
This file contains definition and related methods for the FITS header
|
||||
structure. This structure is meant to remain opaque to the user, who
|
||||
only accesses it through the dedicated functions offered in this module.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fits_h.h,v 1.13 2005/05/18 14:38:01 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/05/18 14:38:01 $
|
||||
$Revision: 1.13 $
|
||||
*/
|
||||
|
||||
#ifndef FITS_HEADER_H
|
||||
#define FITS_HEADER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief FITS header object
|
||||
|
||||
This structure represents a FITS header in memory. It is actually no
|
||||
more than a thin layer on top of the keytuple object. No field in this
|
||||
structure should be directly modifiable by the user, only through
|
||||
accessor functions.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct qfits_header {
|
||||
void * first ; /* Pointer to list start */
|
||||
void * last ; /* Pointer to list end */
|
||||
int n ; /* Number of cards in list */
|
||||
} qfits_header ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief FITS header constructor
|
||||
@return 1 newly allocated (empty) FITS header object.
|
||||
|
||||
This is the main constructor for a qfits_header object. It returns
|
||||
an allocated linked-list handler with an empty card list.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_new(void) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief FITS header default constructor.
|
||||
@return 1 newly allocated qfits_header object.
|
||||
|
||||
This is a secondary constructor for a qfits_header object. It returns
|
||||
an allocated linked-list handler containing two cards: the first one
|
||||
(SIMPLE=T) and the last one (END).
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_default(void) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Add a new card to a FITS header
|
||||
@param hdr qfits_header object to modify
|
||||
@param key FITS key
|
||||
@param val FITS value
|
||||
@param com FITS comment
|
||||
@param lin FITS original line if exists
|
||||
@return void
|
||||
|
||||
This function adds a new card into a header, at the one-before-last
|
||||
position, i.e. the entry just before the END entry if it is there.
|
||||
The key must always be a non-NULL string, all other input parameters
|
||||
are allowed to get NULL values.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_add(
|
||||
qfits_header * hdr,
|
||||
char * key,
|
||||
char * val,
|
||||
char * com,
|
||||
char * lin) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief add a new card to a FITS header
|
||||
@param hdr qfits_header object to modify
|
||||
@param after Key to specify insertion place
|
||||
@param key FITS key
|
||||
@param val FITS value
|
||||
@param com FITS comment
|
||||
@param lin FITS original line if exists
|
||||
@return void
|
||||
|
||||
Adds a new card to a FITS header, after the specified key. Nothing
|
||||
happens if the specified key is not found in the header. All fields
|
||||
can be NULL, except after and key.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_add_after(
|
||||
qfits_header * hdr,
|
||||
char * after,
|
||||
char * key,
|
||||
char * val,
|
||||
char * com,
|
||||
char * lin) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Append a new card to a FITS header.
|
||||
@param hdr qfits_header object to modify
|
||||
@param key FITS key
|
||||
@param val FITS value
|
||||
@param com FITS comment
|
||||
@param lin FITS original line if exists
|
||||
@return void
|
||||
|
||||
Adds a new card in a FITS header as the last one. All fields can be
|
||||
NULL except key.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_append(
|
||||
qfits_header * hdr,
|
||||
const char * key,
|
||||
const char * val,
|
||||
const char * com,
|
||||
const char * lin) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a card in a FITS header.
|
||||
@param hdr qfits_header to modify
|
||||
@param key specifies which card to remove
|
||||
@return void
|
||||
|
||||
Removes a card from a FITS header. The first found card that matches
|
||||
the key is removed.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_del(qfits_header * hdr, char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Modifies a FITS card.
|
||||
@param hdr qfits_header to modify
|
||||
@param key FITS key
|
||||
@param val FITS value
|
||||
@param com FITS comment
|
||||
@return void
|
||||
|
||||
Finds the first card in the header matching 'key', and replaces its
|
||||
value and comment fields by the provided values. The initial FITS
|
||||
line is set to NULL in the card.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_mod(qfits_header * hdr, char * key, char * val, char * com) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Sort a FITS header
|
||||
@param hdr Header to sort (modified)
|
||||
@return -1 in error case, 0 otherwise
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_sort(qfits_header ** hdr) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Copy a FITS header
|
||||
@param src Header to replicate
|
||||
@return Pointer to newly allocated qfits_header object.
|
||||
|
||||
Makes a strict copy of all information contained in the source
|
||||
header. The returned header must be freed using qfits_header_destroy.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_copy(qfits_header * src) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Touch all cards in a FITS header
|
||||
@param hdr qfits_header to modify
|
||||
@return void
|
||||
|
||||
Touches all cards in a FITS header, i.e. all original FITS lines are
|
||||
freed and set to NULL. Useful when a header needs to be reformatted.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_touchall(qfits_header * hdr) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a FITS header to stdout
|
||||
@param hdr qfits_header to dump
|
||||
@return void
|
||||
|
||||
Dump a FITS header to stdout. Mostly for debugging purposes.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_consoledump(qfits_header * hdr) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief qfits_header destructor
|
||||
@param hdr qfits_header to deallocate
|
||||
@return void
|
||||
|
||||
Frees all memory associated to a given qfits_header object.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_header_destroy(qfits_header * hdr) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the value associated to a key, as a string
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@return pointer to statically allocated string
|
||||
|
||||
Finds the value associated to the given key and return it as a
|
||||
string. The returned pointer is statically allocated, so do not
|
||||
modify its contents or try to free it.
|
||||
|
||||
Returns NULL if no matching key is found or no value is attached.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_header_getstr(qfits_header * hdr, const char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find a matching key in a header.
|
||||
@param hdr qfits_header to parse
|
||||
@param key Key prefix to match
|
||||
@return pointer to statically allocated string.
|
||||
|
||||
This function finds the first keyword in the given header for
|
||||
which the given 'key' is a prefix, and returns the full name
|
||||
of the matching key (NOT ITS VALUE). This is useful to locate
|
||||
any keyword starting with a given prefix. Careful with HIERARCH
|
||||
keywords, the shortFITS notation is not likely to be accepted here.
|
||||
|
||||
Examples:
|
||||
|
||||
@verbatim
|
||||
s = qfits_header_findmatch(hdr, "SIMP") returns "SIMPLE"
|
||||
s = qfits_header_findmatch(hdr, "HIERARCH ESO DET") returns
|
||||
the first detector keyword among the HIERACH keys.
|
||||
@endverbatim
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_header_findmatch(qfits_header * hdr, char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the i-th key/val/com/line tuple in a header.
|
||||
@param hdr Header to consider
|
||||
@param idx Index of the requested card
|
||||
@param key Output key
|
||||
@param val Output value
|
||||
@param com Output comment
|
||||
@param lin Output initial line
|
||||
@return int 0 if Ok, -1 if error occurred.
|
||||
|
||||
This function is useful to browse a FITS header object card by card.
|
||||
By iterating on the number of cards (available in the 'n' field of
|
||||
the qfits_header struct), you can retrieve the FITS lines and their
|
||||
components one by one. Indexes run from 0 to n-1. You can pass NULL
|
||||
values for key, val, com or lin if you are not interested in a
|
||||
given field.
|
||||
|
||||
@code
|
||||
int i ;
|
||||
char key[FITS_LINESZ+1] ;
|
||||
char val[FITS_LINESZ+1] ;
|
||||
char com[FITS_LINESZ+1] ;
|
||||
char lin[FITS_LINESZ+1] ;
|
||||
|
||||
for (i=0 ; i<hdr->n ; i++) {
|
||||
qfits_header_getitem(hdr, i, key, val, com, lin);
|
||||
printf("card[%d] key[%s] val[%s] com[%s]\n", i, key, val, com);
|
||||
}
|
||||
@endcode
|
||||
|
||||
This function has primarily been written to interface a qfits_header
|
||||
object to other languages (C++/Python). If you are working within a
|
||||
C program, you should use the other header manipulation routines
|
||||
available in this module.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_getitem(
|
||||
qfits_header * hdr,
|
||||
int idx,
|
||||
char * key,
|
||||
char * val,
|
||||
char * com,
|
||||
char * lin) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the FITS line associated to a key, as a string
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@return pointer to statically allocated string
|
||||
|
||||
Finds the FITS line associated to the given key and return it as a
|
||||
string. The returned pointer is statically allocated, so do not
|
||||
modify its contents or try to free it.
|
||||
|
||||
Returns NULL if no matching key is found or no line is attached.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_header_getline(qfits_header * hdr, char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the comment associated to a key, as a string
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@return pointer to statically allocated string
|
||||
@doc
|
||||
|
||||
Finds the comment associated to the given key and return it as a
|
||||
string. The returned pointer is statically allocated, so do not
|
||||
modify its contents or try to free it.
|
||||
|
||||
Returns NULL if no matching key is found or no comment is attached.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_header_getcom(qfits_header * hdr, char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the value associated to a key, as an int
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@param errval default value to return if nothing is found
|
||||
@return int
|
||||
|
||||
Finds the value associated to the given key and return it as an
|
||||
int. Returns errval if no matching key is found or no value is
|
||||
attached.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_getint(qfits_header * hdr, const char * key, int errval) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the value associated to a key, as a double
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@param errval default value to return if nothing is found
|
||||
@return double
|
||||
|
||||
Finds the value associated to the given key and return it as a
|
||||
double. Returns errval if no matching key is found or no value is
|
||||
attached.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
double qfits_header_getdouble(qfits_header * hdr, const char * key, double errval) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Return the value associated to a key, as a boolean (int).
|
||||
@param hdr qfits_header to parse
|
||||
@param key key to find
|
||||
@param errval default value to return if nothing is found
|
||||
@return int
|
||||
|
||||
Finds the value associated to the given key and return it as a
|
||||
boolean. Returns errval if no matching key is found or no value is
|
||||
attached. A boolean is here understood as an int taking the value 0
|
||||
or 1. errval can be set to any other integer value to reflect that
|
||||
nothing was found.
|
||||
|
||||
errval is returned if no matching key is found or no value is
|
||||
attached.
|
||||
|
||||
A true value is any character string beginning with a 'y' (yes), a
|
||||
't' (true) or the digit '1'. A false value is any character string
|
||||
beginning with a 'n' (no), a 'f' (false) or the digit '0'.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_getboolean(qfits_header * hdr, const char * key, int errval) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Write out a key tuple to a string on 80 chars.
|
||||
@param line Allocated output character buffer.
|
||||
@param key Key to write.
|
||||
@param val Value to write.
|
||||
@param com Comment to write.
|
||||
@return void
|
||||
|
||||
Write out a key, value and comment into an allocated character buffer.
|
||||
The buffer must be at least 80 chars to receive the information.
|
||||
Formatting is done according to FITS standard.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void keytuple2str(char * line, char * key, char * val, char * com) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a FITS header to an opened file.
|
||||
@param hdr FITS header to dump
|
||||
@param out Opened file pointer
|
||||
@return int 0 if Ok, -1 otherwise
|
||||
|
||||
Dumps a FITS header to an opened file pointer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_dump(qfits_header * hdr, FILE * out) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a FITS header to an opened file (one card per line).
|
||||
@param hdr FITS header to dump
|
||||
@param out Opened file pointer
|
||||
@return int 0 if Ok, -1 otherwise
|
||||
@see qfits_header_dump()
|
||||
Dumps a FITS header to an opened file pointer.
|
||||
This function is meant to create hdr files.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_header_dump_hdr(qfits_header * hdr, FILE * out) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a fits header into a memory block.
|
||||
@param fh FITS header to dump
|
||||
@param hsize Size of the returned header, in bytes (output).
|
||||
@return 1 newly allocated memory block containing the FITS header.
|
||||
|
||||
This function dumps a FITS header structure into a newly allocated
|
||||
memory block. The block is composed of characters, just as they would
|
||||
appear in a FITS file. This function is useful to make a FITS header
|
||||
in memory.
|
||||
|
||||
The returned block size is indicated in the passed output variable
|
||||
'hsize'. The returned block must be deallocated using free().
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_header_to_memblock(qfits_header * fh, int * hsize) ;
|
||||
/* </dox> */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,56 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fits_md5.h
|
||||
@author N. Devillard
|
||||
@date May 2001
|
||||
@version $Revision: 1.5 $
|
||||
@brief FITS data block MD5 computation routine.
|
||||
|
||||
This module offers MD5 computation over all data areas of a FITS file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fits_md5.h,v 1.5 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
#ifndef FITS_MD5_H
|
||||
#define FITS_MD5_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the MD5 hash of data zones in a FITS file.
|
||||
@param filename Name of the FITS file to examine.
|
||||
@return 1 statically allocated character string, or NULL.
|
||||
|
||||
This function expects the name of a FITS file.
|
||||
It will compute the MD5 hash on all data blocks in the main data section
|
||||
and possibly extensions (including zero-padding blocks if necessary) and
|
||||
return it as a string suitable for inclusion into a FITS keyword.
|
||||
|
||||
The returned string is statically allocated inside this function,
|
||||
so do not free it or modify it. This function returns NULL in case
|
||||
of error.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_datamd5(char * filename);
|
||||
/* </dox> */
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,80 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fits_p.h
|
||||
@author N. Devillard
|
||||
@date Mar 2000
|
||||
@version $Revision: 1.5 $
|
||||
@brief FITS parser for a single card
|
||||
|
||||
This module contains various routines to help parsing a single FITS
|
||||
card into its components: key, value, comment.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fits_p.h,v 1.5 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
#ifndef FITSEP_H
|
||||
#define FITSEP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI C prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find the keyword in a key card (80 chars)
|
||||
@param line allocated 80-char line from a FITS header
|
||||
@return statically allocated char *
|
||||
|
||||
Find out the part of a FITS line corresponding to the keyword.
|
||||
Returns NULL in case of error. The returned pointer is statically
|
||||
allocated in this function, so do not modify or try to free it.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_getkey(char * line) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find the value in a key card (80 chars)
|
||||
@param line allocated 80-char line from a FITS header
|
||||
@return statically allocated char *
|
||||
|
||||
Find out the part of a FITS line corresponding to the value.
|
||||
Returns NULL in case of error, or if no value can be found. The
|
||||
returned pointer is statically allocated in this function, so do not
|
||||
modify or try to free it.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_getvalue(char * line) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find the comment in a key card (80 chars)
|
||||
@param line allocated 80-char line from a FITS header
|
||||
@return statically allocated char *
|
||||
|
||||
Find out the part of a FITS line corresponding to the comment.
|
||||
Returns NULL in case of error, or if no comment can be found. The
|
||||
returned pointer is statically allocated in this function, so do not
|
||||
modify or try to free it.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_getcomment(char * line) ;
|
||||
/* </dox> */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,135 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fits_rw.h
|
||||
@author N. Devillard
|
||||
@date Mar 2000
|
||||
@version $Revision: 1.11 $
|
||||
@brief FITS header reading/writing.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fits_rw.h,v 1.11 2004/06/03 15:42:06 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2004/06/03 15:42:06 $
|
||||
$Revision: 1.11 $
|
||||
*/
|
||||
|
||||
#ifndef FITS_RW_H
|
||||
#define FITS_RW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "fits_std.h"
|
||||
#include "fits_h.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Read a FITS header from a file to an internal structure.
|
||||
@param filename Name of the file to be read
|
||||
@return Pointer to newly allocated qfits_header or NULL in error case.
|
||||
|
||||
This function parses a FITS (main) header, and returns an allocated
|
||||
qfits_header object. The qfits_header object contains a linked-list of
|
||||
key "tuples". A key tuple contains:
|
||||
|
||||
- A keyword
|
||||
- A value
|
||||
- A comment
|
||||
- An original FITS line (as read from the input file)
|
||||
|
||||
Direct access to the structure is not foreseen, use accessor
|
||||
functions in fits_h.h
|
||||
|
||||
Value, comment, and original line might be NULL pointers.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_read(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Read a FITS header from a 'hdr' file.
|
||||
@param filename Name of the file to be read
|
||||
@return Pointer to newly allocated qfits_header or NULL in error case
|
||||
|
||||
This function parses a 'hdr' file, and returns an allocated qfits_header
|
||||
object. A hdr file is an ASCII format were the header is written with a
|
||||
carriage return after each line. The command dfits typically displays
|
||||
a hdr file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_read_hdr(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Read a FITS header from a 'hdr' string
|
||||
@param hdr_str String containing the hdr file
|
||||
@param nb_char Number of characters in the string
|
||||
@return Pointer to newly allocated qfits_header or NULL in error case
|
||||
|
||||
This function parses a 'hdr' string, and returns an allocated qfits_header
|
||||
object.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_read_hdr_string(
|
||||
unsigned char * hdr_str,
|
||||
int nb_char) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Read an extension header from a FITS file.
|
||||
@param filename Name of the FITS file to read
|
||||
@param xtnum Extension number to read, starting from 0.
|
||||
@return Newly allocated qfits_header structure.
|
||||
|
||||
Strictly similar to qfits_header_read() but reads headers from
|
||||
extensions instead. If the requested xtension is 0, this function
|
||||
calls qfits_header_read() to return the main header.
|
||||
|
||||
Returns NULL in case of error.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_header_readext(char * filename, int xtnum) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Pad an existing file with zeros to a multiple of 2880.
|
||||
@param filename Name of the file to pad.
|
||||
@return void
|
||||
|
||||
This function simply pads an existing file on disk with enough zeros
|
||||
for the file size to reach a multiple of 2880, as required by FITS.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_zeropad(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a file is a FITS file.
|
||||
@param filename name of the file to check
|
||||
@return int 0, 1, or -1
|
||||
|
||||
Returns 1 if the file name looks like a valid FITS file. Returns
|
||||
0 else. If the file does not exist, returns -1.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int is_fits_file(char *filename) ;
|
||||
/* </dox> */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,69 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file fits_std.h
|
||||
@author N. Devillard
|
||||
@date November 2001
|
||||
@version $Revision: 1.5 $
|
||||
@brief
|
||||
|
||||
This header file gathers a number of definitions strictly related
|
||||
to the FITS format. Include it if you need to get definitions for
|
||||
a FITS line size, header metrics, and other FITS-only symbols.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: fits_std.h,v 1.5 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
#ifndef FITS_STD_H
|
||||
#define FITS_STD_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/* FITS header constants */
|
||||
|
||||
/** FITS block size */
|
||||
#define FITS_BLOCK_SIZE (2880)
|
||||
/** FITS number of cards per block */
|
||||
#define FITS_NCARDS (36)
|
||||
/** FITS size of each line in bytes */
|
||||
#define FITS_LINESZ (80)
|
||||
|
||||
/** FITS magic number */
|
||||
#define FITS_MAGIC "SIMPLE"
|
||||
/** Size of the FITS magic number */
|
||||
#define FITS_MAGIC_SZ 6
|
||||
|
||||
|
||||
/* FITS pixel depths */
|
||||
|
||||
/** FITS BITPIX=8 */
|
||||
#define BPP_8_UNSIGNED (8)
|
||||
/** FITS BITPIX=16 */
|
||||
#define BPP_16_SIGNED (16)
|
||||
/** FITS BITPIX=32 */
|
||||
#define BPP_32_SIGNED (32)
|
||||
/** FITS BITPIX=-32 */
|
||||
#define BPP_IEEE_FLOAT (-32)
|
||||
/** FITS BITPIX=-64 */
|
||||
#define BPP_IEEE_DOUBLE (-64)
|
||||
|
||||
/** Default BITPIX for output */
|
||||
#define BPP_DEFAULT BPP_IEEE_FLOAT
|
||||
|
||||
/** Compute the number of bytes per pixel for a given BITPIX value */
|
||||
#define BYTESPERPIXEL(x) ( ((x) == BPP_8_UNSIGNED) ? 1 : \
|
||||
((x) == BPP_16_SIGNED) ? 2 : \
|
||||
((x) == BPP_32_SIGNED) ? 4 : \
|
||||
((x) == BPP_IEEE_FLOAT) ? 4 : \
|
||||
((x) == BPP_IEEE_DOUBLE) ? 8 : 0 )
|
||||
/* </dox> */
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,155 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file get_name.h
|
||||
@author Y. Jung
|
||||
@date Jan 2004
|
||||
@version $Revision: 1.4 $
|
||||
@brief Get various names (filenames, dir names, login name, etc...)
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: get_name.h,v 1.4 2004/01/20 15:05:55 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2004/01/20 15:05:55 $
|
||||
$Revision: 1.4 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GET_NAME_H
|
||||
#define GET_NAME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI C prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find the directory name in the given string.
|
||||
@param filename Full path name to scan.
|
||||
@return Pointer to statically allocated string.
|
||||
|
||||
Provide a full path name and you get in return a pointer to a statically
|
||||
allocated string containing the name of the directory only, without trailing
|
||||
slash. If the input string does not contain a slash (i.e. it is not a full
|
||||
path), the returned string is '.', corresponding to the current working
|
||||
directory. Since the returned string is statically allocated, do not try to
|
||||
free it or modify it.
|
||||
|
||||
This function does not check for the existence of the path or the file.
|
||||
|
||||
Examples:
|
||||
@verbatim
|
||||
get_dir_name("/cdrom/data/image.fits") returns "/cdrom/data"
|
||||
get_dir_name("filename.fits") returns "."
|
||||
@endverbatim
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_dir_name(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find out the base name of a file (i.e. without prefix path)
|
||||
@param filename Full path name to scan.
|
||||
@return Pointer to char within the input string.
|
||||
|
||||
Provide a full path name and you get in return a pointer to a statically
|
||||
allocated string containing the name of the file only, without prefixing
|
||||
directory names. If the input string does not contain a slash (i.e. it is
|
||||
not a full path), the returned string is a copy of the input string.
|
||||
|
||||
This function does not check for the existence of the path or the file.
|
||||
|
||||
Examples:
|
||||
@verbatim
|
||||
qfits_get_base_name("/cdrom/data/image.fits") returns "image.fits"
|
||||
qfits_get_base_name("filename.fits") returns "filename.fits"
|
||||
@endverbatim
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_base_name(const char *filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find out the root part of a basename (name without extension).
|
||||
@param filename File name to scan.
|
||||
@return Pointer to statically allocated string.
|
||||
|
||||
Find out the root part of a file name, i.e. the file name without extension.
|
||||
Since in Unix a file name can have several dots, only a number of extensions
|
||||
are supported. This includes:
|
||||
|
||||
- .fits and .FITS
|
||||
- .tfits and .TFITS
|
||||
- .paf and .PAF
|
||||
- .ascii and .ASCII
|
||||
- .dat and .DAT
|
||||
|
||||
This function does not check for the existence of the path or the file.
|
||||
|
||||
Examples:
|
||||
@verbatim
|
||||
get_root_name("/cdrom/filename.fits") returns "/cdrom/filename"
|
||||
get_root_name("filename.paf") returns "filename"
|
||||
get_root_name("filename") returns "filename"
|
||||
get_root_name("filename.ext") returns "filename.ext"
|
||||
@endverbatim
|
||||
|
||||
Since the returned string is statically allocated in this module, do not try
|
||||
to free it or modify its contents.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_root_name(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Find out the extension of a file name
|
||||
@param filename File name without path prefix.
|
||||
@return Pointer to char within the input string.
|
||||
|
||||
Find out the extension of a given file name. Notice that the input character
|
||||
string must not contain a path prefix (typically, you feed in the output of
|
||||
@c qfits_get_base_name).
|
||||
|
||||
Works with all kinds of extensions: returns the part of the string after the
|
||||
last dot. If no dot is found in the input string, NULL is returned.
|
||||
|
||||
Examples:
|
||||
@verbatim
|
||||
get_ext_name("filename.fits") returns "fits"
|
||||
get_ext_name("hello.c") returns "c"
|
||||
get_ext_name("readme") returns NULL
|
||||
@endverbatim
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_ext_name(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Returns the user login name.
|
||||
@return Pointer to statically allocated character string.
|
||||
|
||||
Finds out what the login name of the current user is. The result is
|
||||
placed in a static character string inside this module and a pointer
|
||||
to the first character in this string is returned. Do not modify or
|
||||
free the returned string!
|
||||
|
||||
If the user name cannot be determined, the returned pointer will
|
||||
point to a string which first character is a null character.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_login_name(void) ;
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,104 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file ieeefp-compat.h
|
||||
@author N. Devillard
|
||||
@date Feb 2002
|
||||
@version $Revision: 2.11 $
|
||||
@brief This module implements the isnan() and isinf() macros.
|
||||
|
||||
The isnan() and isinf() macros are unfortunately not yet part of
|
||||
the standard C math library everywhere. They can usually be found
|
||||
in different places, if they are offered at all, and require the
|
||||
application to link against the math library. To avoid portability
|
||||
problems and linking against -lm, this module implements a fast
|
||||
and portable way of finding out whether a floating-point value
|
||||
(float or double) is a NaN or an Inf.
|
||||
|
||||
Instead of calling isnan() and isinf(), the programmer including
|
||||
this file should call qfits_isnan() and qfits_isinf().
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: ieeefp-compat.h,v 2.11 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 2.11 $
|
||||
*/
|
||||
|
||||
#ifndef IEEEFP_COMPAT_H
|
||||
#define IEEEFP_COMPAT_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Macros
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Test a floating-point variable for NaN value.
|
||||
@param n Number to test (float or double)
|
||||
@return 1 if n is NaN, 0 else.
|
||||
|
||||
This macro is needed to support both float and double variables
|
||||
as input parameter. It checks on the size of the input variable
|
||||
to branch to the float or double version.
|
||||
|
||||
Portability is an issue for this function which is present on
|
||||
most Unixes but not all, under various libraries (C lib on BSD,
|
||||
Math lib on Linux, sunmath on Solaris, ...). Integrating the
|
||||
code for this function makes qfits independent from any math
|
||||
library.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define qfits_isnan(n) ((sizeof(n)==sizeof(float)) ? _qfits_isnanf(n) : \
|
||||
(sizeof(n)==sizeof(double)) ? _qfits_isnand(n) : -1)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Test a floating-point variable for Inf value.
|
||||
@param n Number to test (float or double)
|
||||
@return 1 if n is Inf or -Inf, 0 else.
|
||||
|
||||
This macro is needed to support both float and double variables
|
||||
as input parameter. It checks on the size of the input variable
|
||||
to branch to the float or double version.
|
||||
|
||||
Portability is an issue for this function which is missing on most
|
||||
Unixes. Most of the time, another function called finite() is
|
||||
offered to perform the opposite task, but it is not consistent
|
||||
among platforms and found in various libraries. Integrating the
|
||||
code for this function makes qfits independent from any math
|
||||
library.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define qfits_isinf(n) ((sizeof(n)==sizeof(float)) ? _qfits_isinff(n) : \
|
||||
(sizeof(n)==sizeof(double)) ? _qfits_isinfd(n) : -1)
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Test a float variable for NaN value.
|
||||
* Do not call directly, call qfits_isnan().
|
||||
*/
|
||||
int _qfits_isnanf(float f);
|
||||
/**
|
||||
* Test a float variable for Inf value.
|
||||
* Do not call directly, call qfits_isinf().
|
||||
*/
|
||||
int _qfits_isinff(float f);
|
||||
/**
|
||||
* Test a double variable for NaN value.
|
||||
* Do not call directly, call qfits_isnan().
|
||||
*/
|
||||
int _qfits_isnand(double d);
|
||||
/**
|
||||
* Test a double variable for Inf value.
|
||||
* Do not call directly, call qfits_isinf().
|
||||
*/
|
||||
int _qfits_isinfd(double d);
|
||||
|
||||
/* </dox> */
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
typedef unsigned int word32 ;
|
||||
|
||||
struct MD5Context {
|
||||
word32 buf[4];
|
||||
word32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
||||
unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(word32 buf[4], word32 const in[16]);
|
||||
|
||||
/*
|
||||
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
*/
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
#endif /* !MD5_H */
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,110 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file pafs.h
|
||||
@author N. Devillard
|
||||
@date Feb 1999
|
||||
@version $Revision: 1.4 $
|
||||
@brief PAF format I/O.
|
||||
|
||||
This module contains various routines related to PAF file I/O.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: pafs.h,v 1.4 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.4 $
|
||||
*/
|
||||
|
||||
#ifndef PAFS_H
|
||||
#define PAFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
---------ii------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "static_sz.h"
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Open a new PAF file, output a default header.
|
||||
@param filename Name of the file to create.
|
||||
@param paf_id PAF identificator.
|
||||
@param paf_desc PAF description.
|
||||
@param login_name Login name
|
||||
@param datetime Date
|
||||
@return Opened file pointer.
|
||||
|
||||
This function creates a new PAF file with the requested file name.
|
||||
If another file already exists with the same name, it will be
|
||||
overwritten (if the file access rights allow it).
|
||||
|
||||
A default header is produced according to the VLT DICB standard. You
|
||||
need to provide an identificator (paf_id) of the producer of the
|
||||
file. Typically, something like "ISAAC/zero_point".
|
||||
|
||||
The PAF description (paf_desc) is meant for humans. Typically,
|
||||
something like "Zero point computation results".
|
||||
|
||||
This function returns an opened file pointer, ready to receive more
|
||||
data through fprintf's. The caller is responsible for fclose()ing
|
||||
the file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
FILE * qfits_paf_print_header(
|
||||
char * filename,
|
||||
char * paf_id,
|
||||
char * paf_desc,
|
||||
char * login_name,
|
||||
char * datetime) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Query a PAF file for a value.
|
||||
@param filename Name of the PAF to query.
|
||||
@param key Name of the key to query.
|
||||
@return 1 pointer to statically allocated string, or NULL.
|
||||
|
||||
This function parses a PAF file and returns the value associated to a
|
||||
given key, as a pointer to an internal statically allocated string.
|
||||
Do not try to free or modify the contents of the returned string!
|
||||
|
||||
If the key is not found, this function returns NULL.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_paf_query(
|
||||
char * filename,
|
||||
char * key) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief returns 1 if file is in PAF format, 0 else
|
||||
@param filename name of the file to check
|
||||
@return int 0, 1, or -1
|
||||
Returns 1 if the file name corresponds to a valid PAF file. Returns
|
||||
0 else. If the file does not exist, returns -1. Validity of the PAF file
|
||||
is checked with the presence of PAF.HDR.START at the beginning
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_paf_file(char * filename) ;
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,448 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file pixload.h
|
||||
@author N. Devillard
|
||||
@date Nov 2001
|
||||
@version $Revision: 1.12 $
|
||||
@brief Pixel loader for FITS images.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: pixio.h,v 1.12 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.12 $
|
||||
*/
|
||||
|
||||
#ifndef PIXLOAD_H
|
||||
#define PIXLOAD_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "xmemory.h"
|
||||
#include "fits_std.h"
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/** Symbol to set returned pixel type to float */
|
||||
#define PTYPE_FLOAT 0
|
||||
/** Symbol to set returned pixel type to int */
|
||||
#define PTYPE_INT 1
|
||||
/** Symbol to set returned pixel type to double */
|
||||
#define PTYPE_DOUBLE 2
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Alias for unsigned char
|
||||
|
||||
A 'byte' is just an alias for an unsigned char. It is only defined
|
||||
for readability.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef unsigned char byte ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief qfits loader control object
|
||||
|
||||
This structure serves two purposes: input and output for the qfits
|
||||
pixel loading facility. To request pixels from a FITS file, you
|
||||
need to allocate (statically or dynamically) such a structure and
|
||||
fill up the input fields (filename, xtension number, etc.) to specify
|
||||
the pixels you want from the file.
|
||||
|
||||
Before performing the actual load, you must pass the initialized
|
||||
structure to qfitsloader_init() which will check whether the operation
|
||||
is feasible or not (check its returned value).
|
||||
|
||||
If the operation was deemed feasible, you can proceed to load the pixels,
|
||||
passing the same structure to qfits_loadpix() which will fill up the
|
||||
output fields of the struct. Notice that a pixel buffer will have been
|
||||
allocated (through malloc or mmap) and placed into the structure. You
|
||||
need to call free() on this pointer when you are done with it,
|
||||
typically in the image or cube destructor.
|
||||
|
||||
The qfitsloader_init() function is also useful to probe a FITS file
|
||||
for useful informations, like getting the size of images in the file,
|
||||
the pixel depth, or data offset.
|
||||
|
||||
Example of a code that prints out various informations about
|
||||
a plane to load, without actually loading it:
|
||||
|
||||
@code
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
qfitsloader ql ;
|
||||
|
||||
ql.filename = argv[1] ;
|
||||
ql.xtnum = 0 ;
|
||||
ql.pnum = 0 ;
|
||||
|
||||
if (qfitsloader_init(&ql)!=0) {
|
||||
printf("cannot read info about %s\n", argv[1]);
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
printf( "file : %s\n"
|
||||
"xtnum : %d\n"
|
||||
"pnum : %d\n"
|
||||
"# xtensions : %d\n"
|
||||
"size X : %d\n"
|
||||
"size Y : %d\n"
|
||||
"planes : %d\n"
|
||||
"bitpix : %d\n"
|
||||
"datastart : %d\n"
|
||||
"datasize : %d\n"
|
||||
"bscale : %g\n"
|
||||
"bzero : %g\n",
|
||||
ql.filename,
|
||||
ql.xtnum,
|
||||
ql.pnum,
|
||||
ql.exts,
|
||||
ql.lx,
|
||||
ql.ly,
|
||||
ql.np,
|
||||
ql.bitpix,
|
||||
ql.seg_start,
|
||||
ql.seg_size,
|
||||
ql.bscale,
|
||||
ql.bzero);
|
||||
return 0 ;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct qfitsloader {
|
||||
|
||||
/** Private field to see if structure has been initialized */
|
||||
int _init ;
|
||||
|
||||
/** input: Name of the file you want to read pixels from */
|
||||
char * filename ;
|
||||
/** input: xtension number you want to read */
|
||||
int xtnum ;
|
||||
/** input: Index of the plane you want, from 0 to np-1 */
|
||||
int pnum ;
|
||||
/** input: Pixel type you want (PTYPE_FLOAT, PTYPE_INT or PTYPE_DOUBLE) */
|
||||
int ptype ;
|
||||
/** input: Guarantee file copy or allow file mapping */
|
||||
int map ;
|
||||
|
||||
/** output: Total number of extensions found in file */
|
||||
int exts ;
|
||||
/** output: Size in X of the requested plane */
|
||||
int lx ;
|
||||
/** output: Size in Y of the requested plane */
|
||||
int ly ;
|
||||
/** output: Number of planes present in this extension */
|
||||
int np ;
|
||||
/** output: BITPIX for this extension */
|
||||
int bitpix ;
|
||||
/** output: Start of the data segment (in bytes) for your request */
|
||||
int seg_start ;
|
||||
/** output: Size of the data segment (in bytes) for your request */
|
||||
int seg_size ;
|
||||
/** output: BSCALE found for this extension */
|
||||
double bscale ;
|
||||
/** output: BZERO found for this extension */
|
||||
double bzero ;
|
||||
|
||||
/** output: Pointer to pixel buffer loaded as integer values */
|
||||
int * ibuf ;
|
||||
/** output: Pointer to pixel buffer loaded as float values */
|
||||
float * fbuf ;
|
||||
/** output: Pointer to pixel buffer loaded as double values */
|
||||
double * dbuf ;
|
||||
|
||||
} qfitsloader ;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief qfits dumper control object
|
||||
|
||||
This structure offers various control parameters to dump a pixel
|
||||
buffer to a FITS file. The buffer will be dumped as requested
|
||||
to the requested file in append mode. Of course, the requested file
|
||||
must be writeable for the operation to succeed.
|
||||
|
||||
The following example demonstrates how to save a linear ramp sized
|
||||
100x100 to a FITS file with BITPIX=16. Notice that this code only
|
||||
dumps the pixel buffer, no header information is provided in this
|
||||
case.
|
||||
|
||||
@code
|
||||
int i, j ;
|
||||
int * ibuf ;
|
||||
qfitsdumper qd ;
|
||||
|
||||
// Fill a buffer with 100x100 int pixels
|
||||
ibuf = malloc(100 * 100 * sizeof(int));
|
||||
for (j=0 ; j<100 ; j++) {
|
||||
for (i=0 ; i<100 ; i++) {
|
||||
ibuf[i+j*100] = i+j ;
|
||||
}
|
||||
}
|
||||
|
||||
qd.filename = "out.fits" ; // Output file name
|
||||
qd.npix = 100 * 100 ; // Number of pixels
|
||||
qd.ptype = PTYPE_INT ; // Input buffer type
|
||||
qd.ibuf = ibuf ; // Set buffer pointer
|
||||
qd.out_ptype = BPP_16_SIGNED ; // Save with BITPIX=16
|
||||
|
||||
// Dump buffer to file (error checking omitted for clarity)
|
||||
qfits_pixdump(&qd);
|
||||
|
||||
free(ibuf);
|
||||
@endcode
|
||||
|
||||
If the provided output file name is "STDOUT" (all capitals), the
|
||||
function will dump the pixels to the stdout steam (usually the console,
|
||||
could have been re-directed).
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct qfitsdumper {
|
||||
|
||||
/** Name of the file to dump to, "STDOUT" to dump to stdout */
|
||||
char * filename ;
|
||||
/** Number of pixels in the buffer to dump */
|
||||
int npix ;
|
||||
/** Buffer type: PTYPE_FLOAT, PTYPE_INT or PTYPE_DOUBLE */
|
||||
int ptype ;
|
||||
|
||||
/** Pointer to input integer pixel buffer */
|
||||
int * ibuf ;
|
||||
/** Pointer to input float pixel buffer */
|
||||
float * fbuf ;
|
||||
/** Pointer to input double pixel buffer */
|
||||
double * dbuf ;
|
||||
|
||||
/** Requested BITPIX in output FITS file */
|
||||
int out_ptype ;
|
||||
} qfitsdumper ;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Initialize a qfitsloader control object.
|
||||
@param ql qfitsloader object to initialize.
|
||||
@return int 0 if Ok, -1 if error occurred.
|
||||
|
||||
This function expects a qfitsloader object with a number of input
|
||||
fields correctly filled in. The minimum fields to set are:
|
||||
|
||||
- filename: Name of the file to examine.
|
||||
- xtnum: Extension number to examine (0 for main section).
|
||||
- pnum: Plane number in the requested extension.
|
||||
|
||||
You can go ahead with these fields only if you only want to get
|
||||
file information for this plane in this extension. If you want
|
||||
to later load the plane, you must additionally fill the 'ptype'
|
||||
field to a correct value (PTYPE_INT, PTYPE_FLOAT, PTYPE_DOUBLE)
|
||||
before calling qfits_loadpix() so that it knows which conversion
|
||||
to perform.
|
||||
|
||||
This function is basically a probe sent on a FITS file to ask
|
||||
qfits if loading these data would be Ok or not. The actual loading
|
||||
is performed by qfits_loadpix() afterwards.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfitsloader_init(qfitsloader * ql);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Load a pixel buffer for one image.
|
||||
@param ql Allocated and initialized qfitsloader control object.
|
||||
@return int 0 if Ok, -1 if error occurred.
|
||||
|
||||
This function performs a load of a pixel buffer into memory. It
|
||||
expects an allocated and initialized qfitsloader object in input.
|
||||
See qfitsloader_init() about initializing the object.
|
||||
|
||||
This function will fill up the ibuf/fbuf/dbuf field, depending
|
||||
on the requested pixel type (resp. int, float or double).
|
||||
|
||||
The returned buffer has been allocated using one of the special
|
||||
memory operators present in xmemory.c. To deallocate the buffer,
|
||||
you must call the version of free() offered by xmemory, not the
|
||||
usual system free(). It is enough to include "xmemory.h" in your
|
||||
code before you make calls to the pixel loader here.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_loadpix(qfitsloader * ql);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Load a pixel buffer as floats.
|
||||
@param p_source Pointer to source buffer (as bytes).
|
||||
@param npix Number of pixels to load.
|
||||
@param bitpix FITS BITPIX in original file.
|
||||
@param bscale FITS BSCALE in original file.
|
||||
@param bzero FITS BZERO in original file.
|
||||
@return 1 pointer to a newly allocated buffer of npix floats.
|
||||
|
||||
This function takes in input a pointer to a byte buffer as given
|
||||
in the original FITS file (big-endian format). It converts the
|
||||
buffer to an array of float (whatever representation is used for
|
||||
floats by this platform is used) and returns the newly allocated
|
||||
buffer, or NULL if an error occurred.
|
||||
|
||||
The returned buffer must be deallocated using the free() offered
|
||||
by xmemory. It is enough to #include "xmemory.h" before calling
|
||||
free on the returned pointer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
float * qfits_pixin_float (byte *, int, int, double, double);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Load a pixel buffer as ints.
|
||||
@param p_source Pointer to source buffer (as bytes).
|
||||
@param npix Number of pixels to load.
|
||||
@param bitpix FITS BITPIX in original file.
|
||||
@param bscale FITS BSCALE in original file.
|
||||
@param bzero FITS BZERO in original file.
|
||||
@return 1 pointer to a newly allocated buffer of npix ints.
|
||||
|
||||
This function takes in input a pointer to a byte buffer as given
|
||||
in the original FITS file (big-endian format). It converts the
|
||||
buffer to an array of int (whatever representation is used for
|
||||
int by this platform is used) and returns the newly allocated
|
||||
buffer, or NULL if an error occurred.
|
||||
|
||||
The returned buffer must be deallocated using the free() offered
|
||||
by xmemory. It is enough to #include "xmemory.h" before calling
|
||||
free on the returned pointer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int * qfits_pixin_int (byte *, int, int, double, double);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Load a pixel buffer as doubles.
|
||||
@param p_source Pointer to source buffer (as bytes).
|
||||
@param npix Number of pixels to load.
|
||||
@param bitpix FITS BITPIX in original file.
|
||||
@param bscale FITS BSCALE in original file.
|
||||
@param bzero FITS BZERO in original file.
|
||||
@return 1 pointer to a newly allocated buffer of npix doubles.
|
||||
|
||||
This function takes in input a pointer to a byte buffer as given
|
||||
in the original FITS file (big-endian format). It converts the
|
||||
buffer to an array of double (whatever representation is used for
|
||||
int by this platform is used) and returns the newly allocated
|
||||
buffer, or NULL if an error occurred.
|
||||
|
||||
The returned buffer must be deallocated using the free() offered
|
||||
by xmemory. It is enough to #include "xmemory.h" before calling
|
||||
free on the returned pointer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
double * qfits_pixin_double(byte *, int, int, double, double);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a pixel buffer to an output FITS file in append mode.
|
||||
@param qd qfitsdumper control object.
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
This function takes in input a qfitsdumper control object. This object
|
||||
must be allocated beforehand and contain valid references to the data
|
||||
to save, and how to save it.
|
||||
|
||||
The minimum fields to fill are:
|
||||
|
||||
- filename: Name of the FITS file to dump to.
|
||||
- npix: Number of pixels in the buffer to be dumped.
|
||||
- ptype: Type of the passed buffer (PTYPE_FLOAT, PTYPE_INT, PTYPE_DOUBLE)
|
||||
- out_ptype: Requested FITS BITPIX for the output.
|
||||
|
||||
One of the following fields must point to the corresponding pixel
|
||||
buffer:
|
||||
|
||||
- ibuf for an int pixel buffer (ptype=PTYPE_INT)
|
||||
- fbuf for a float pixel buffer (ptype=PTYPE_FLOAT)
|
||||
- dbuf for a double pixel buffer (ptype=PTYPE_DOUBLE)
|
||||
|
||||
This is a fairly low-level function, in the sense that it does not
|
||||
check that the output file already contains a proper header or even
|
||||
that the file it is appending to is indeed a FITS file. It will
|
||||
convert the pixel buffer to the requested BITPIX type and append
|
||||
the data to the file, without padding with zeros. See qfits_zeropad()
|
||||
about padding.
|
||||
|
||||
If the given output file name is "STDOUT" (all caps), the dump
|
||||
will be performed to stdout.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_pixdump(qfitsdumper * qd) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Convert a float pixel buffer to a byte buffer.
|
||||
@param buf Input float buffer.
|
||||
@param npix Number of pixels in the input buffer.
|
||||
@param ptype Requested output BITPIX type.
|
||||
@return 1 pointer to a newly allocated byte buffer.
|
||||
|
||||
This function converts the given float buffer to a buffer of bytes
|
||||
suitable for dumping to a FITS file (i.e. big-endian, in the
|
||||
requested pixel type). The returned pointer must be deallocated
|
||||
using the free() function offered by xmemory.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
byte * qfits_pixdump_float(float * buf, int npix, int ptype);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Convert an int pixel buffer to a byte buffer.
|
||||
@param buf Input int buffer.
|
||||
@param npix Number of pixels in the input buffer.
|
||||
@param ptype Requested output BITPIX type.
|
||||
@return 1 pointer to a newly allocated byte buffer.
|
||||
|
||||
This function converts the given int buffer to a buffer of bytes
|
||||
suitable for dumping to a FITS file (i.e. big-endian, in the
|
||||
requested pixel type). The returned pointer must be deallocated
|
||||
using the free() function offered by xmemory.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
byte * qfits_pixdump_int(int * buf, int npix, int ptype);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Convert a double pixel buffer to a byte buffer.
|
||||
@param buf Input double buffer.
|
||||
@param npix Number of pixels in the input buffer.
|
||||
@param ptype Requested output BITPIX type.
|
||||
@return 1 pointer to a newly allocated byte buffer.
|
||||
|
||||
This function converts the given double buffer to a buffer of bytes
|
||||
suitable for dumping to a FITS file (i.e. big-endian, in the
|
||||
requested pixel type). The returned pointer must be deallocated
|
||||
using the free() function offered by xmemory.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
byte * qfits_pixdump_double(double * buf, int npix, int ptype);
|
||||
|
||||
/* </dox> */
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,97 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file qerror.h
|
||||
@author N. Devillard
|
||||
@date Nov 2001
|
||||
@version $Revision: 1.8 $
|
||||
@brief qfits error handling
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: qerror.h,v 1.8 2005/05/18 14:38:01 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/05/18 14:38:01 $
|
||||
$Revision: 1.8 $
|
||||
*/
|
||||
|
||||
#ifndef QERROR_H
|
||||
#define QERROR_H
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* <dox> */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the current status of error display.
|
||||
@return int 1 if error display is active, 0 if not.
|
||||
|
||||
This function returns the current error display status. If it returns 1,
|
||||
it means that all calls to qfits_error/qfits_warning will display
|
||||
messages using the registered functions, otherwise they do nothing.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_err_statget(void);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set the current status of error display.
|
||||
@param sta New status to be set.
|
||||
@return int giving the previous display status.
|
||||
|
||||
This function sets the current error display status to the required
|
||||
value, and returns the previous value. It is useful to store the
|
||||
previous value, in view of restoring it afterwards, e.g. to make a
|
||||
function silent on all its errors. Example:
|
||||
|
||||
\begin{verbatim}
|
||||
int prev_stat = qfits_err_statset(0) ;
|
||||
function_call() ;
|
||||
qfits_err_statset(prev_stat);
|
||||
\end{verbatim}
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_err_statset(int sta);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Register a function to display error/warning messages.
|
||||
@param dispfn Display function (see doc below).
|
||||
@return int 0 if function was registered, -1 if not.
|
||||
|
||||
This function registers a display function into the error-handling
|
||||
module. Display functions have the following prototype:
|
||||
|
||||
@code
|
||||
void display_function(char * msg);
|
||||
@endcode
|
||||
|
||||
They are simple functions that expect a ready-made error message
|
||||
and return void. They can do whatever they want with the message
|
||||
(log it to a file, send it to a GUI, to the syslog, ...). The
|
||||
message is built using a printf-like statement in qfits_error and
|
||||
qfits_warning, then passed to all registered display functions.
|
||||
|
||||
A maximum of QFITS_ERR_MAXERRDISP can be registered (see source code).
|
||||
If the limit has been reached, this function will signal it by
|
||||
returning -1.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_err_register( void (*dispfn)(char*) ) ;
|
||||
/* </dox> */
|
||||
|
||||
/* Public warning/error functions */
|
||||
void qfits_warning(const char *fmt, ...);
|
||||
void qfits_error(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,311 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file simple.h
|
||||
@author N. Devillard
|
||||
@date Jan 1999
|
||||
@version $Revision: 1.12 $
|
||||
@brief Simple FITS access routines.
|
||||
|
||||
This module offers a number of very basic low-level FITS access
|
||||
routines.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: simple.h,v 1.12 2005/05/18 14:38:01 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2005/05/18 14:38:01 $
|
||||
$Revision: 1.12 $
|
||||
*/
|
||||
|
||||
#ifndef SIMPLE_H
|
||||
#define SIMPLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/** Unknown type for FITS value */
|
||||
#define QFITS_UNKNOWN 0
|
||||
/** Boolean type for FITS value */
|
||||
#define QFITS_BOOLEAN 1
|
||||
/** Int type for FITS value */
|
||||
#define QFITS_INT 2
|
||||
/** Float type for FITS value */
|
||||
#define QFITS_FLOAT 3
|
||||
/** Complex type for FITS value */
|
||||
#define QFITS_COMPLEX 4
|
||||
/** String type for FITS value */
|
||||
#define QFITS_STRING 5
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function codes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Retrieve the value of a key in a FITS header
|
||||
@param filename Name of the FITS file to browse
|
||||
@param keyword Name of the keyword to find
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
Provide the name of a FITS file and a keyword to look for. The input
|
||||
file is memory-mapped and the first keyword matching the requested one is
|
||||
located. The value corresponding to this keyword is copied to a
|
||||
statically allocated area, so do not modify it or free it.
|
||||
|
||||
The input keyword is first converted to upper case and expanded to
|
||||
the HIERARCH scheme if given in the shortFITS notation.
|
||||
|
||||
This function is pretty fast due to the mmapping. Due to buffering
|
||||
on most Unixes, it is possible to call many times this function in a
|
||||
row on the same file and do not suffer too much from performance
|
||||
problems. If the file contents are already in the cache, the file
|
||||
will not be re-opened every time.
|
||||
|
||||
It is possible, though, to modify this function to perform several
|
||||
searches in a row. See the source code.
|
||||
|
||||
Returns NULL in case the requested keyword cannot be found.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_query_hdr(char * filename, const char * keyword) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Retrieve the value of a keyin a FITS extension header.
|
||||
@param filename name of the FITS file to browse.
|
||||
@param keyword name of the FITS key to look for.
|
||||
@param xtnum xtension number
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
Same as qfits_query_hdr but for extensions. xtnum starts from 1 to
|
||||
the number of extensions. If xtnum is zero, this function is
|
||||
strictly identical to qfits_query_hdr().
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_query_ext(char * filename, const char * keyword, int xtnum) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Counts the number of extensions in a FITS file
|
||||
@param filename Name of the FITS file to browse.
|
||||
@return int
|
||||
|
||||
Counts how many extensions are in the file. Returns 0 if no
|
||||
extension is found, and -1 if an error occurred.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_query_n_ext(char * filename) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Counts the number of planes in a FITS extension.
|
||||
@param filename Name of the FITS file to browse.
|
||||
@param exnum Extensin number
|
||||
@return int
|
||||
Counts how many planes are in the extension. Returns 0 if no plane is found,
|
||||
and -1 if an error occurred.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_query_nplanes(char * filename, int extnum) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Clean out a FITS string value.
|
||||
@param s pointer to allocated FITS value string.
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
From a string FITS value like 'marvin o''hara', remove head and tail
|
||||
quotes, replace double '' with simple ', trim blanks on each side,
|
||||
and return the result in a statically allocated area.
|
||||
|
||||
Examples:
|
||||
|
||||
- ['o''hara'] becomes [o'hara]
|
||||
- [' H '] becomes [H]
|
||||
- ['1.0 '] becomes [1.0]
|
||||
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_pretty_string(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a FITS value is boolean
|
||||
@param s FITS value as a string
|
||||
@return int 0 or 1
|
||||
|
||||
Identifies if a FITS value is boolean.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_boolean(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a FITS value is an int.
|
||||
@param s FITS value as a string
|
||||
@return int 0 or 1
|
||||
|
||||
Identifies if a FITS value is an integer.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_int(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a FITS value is float.
|
||||
@param s FITS value as a string
|
||||
@return int 0 or 1
|
||||
|
||||
Identifies if a FITS value is float.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_float(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a FITS value is complex.
|
||||
@param s FITS value as a string
|
||||
@return int 0 or 1
|
||||
|
||||
Identifies if a FITS value is complex.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_complex(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify if a FITS value is string.
|
||||
@param s FITS value as a string
|
||||
@return int 0 or 1
|
||||
|
||||
Identifies if a FITS value is a string.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_string(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify the type of a FITS value given as a string.
|
||||
@param s FITS value as a string
|
||||
@return integer naming the FITS type
|
||||
|
||||
Returns the following value:
|
||||
|
||||
- QFITS_UNKNOWN (0) for an unknown type.
|
||||
- QFITS_BOOLEAN (1) for a boolean type.
|
||||
- QFITS_INT (2) for an integer type.
|
||||
- QFITS_FLOAT (3) for a floating-point type.
|
||||
- QFITS_COMPLEX (4) for a complex number.
|
||||
- QFITS_STRING (5) for a FITS string.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_get_type(char * s) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Retrieve offset to start and size of a header in a FITS file.
|
||||
@param filename Name of the file to examine
|
||||
@param xtnum Extension number (0 for main)
|
||||
@param seg_start Segment start in bytes (output)
|
||||
@param seg_size Segment size in bytes (output)
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
This function retrieves the two most important informations about
|
||||
a header in a FITS file: the offset to its beginning, and the size
|
||||
of the header in bytes. Both values are returned in the passed
|
||||
pointers to ints. It is Ok to pass NULL for any pointer if you do
|
||||
not want to retrieve the associated value.
|
||||
|
||||
You must provide an extension number for the header, 0 meaning the
|
||||
main header in the file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_get_hdrinfo(
|
||||
char * filename,
|
||||
int xtnum,
|
||||
int * seg_start,
|
||||
int * seg_size) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Retrieve offset to start and size of a data section in a file.
|
||||
@param filename Name of the file to examine.
|
||||
@param xtnum Extension number (0 for main).
|
||||
@param seg_start Segment start in bytes (output).
|
||||
@param seg_size Segment size in bytes (output).
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
This function retrieves the two most important informations about
|
||||
a data section in a FITS file: the offset to its beginning, and the size
|
||||
of the section in bytes. Both values are returned in the passed
|
||||
pointers to ints. It is Ok to pass NULL for any pointer if you do
|
||||
not want to retrieve the associated value.
|
||||
|
||||
You must provide an extension number for the header, 0 meaning the
|
||||
main header in the file.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_get_datinfo(
|
||||
char * filename,
|
||||
int xtnum,
|
||||
int * seg_start,
|
||||
int * seg_size) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Query a card in a FITS (main) header by a given key
|
||||
@param filename Name of the FITS file to check.
|
||||
@param keyword Where to read a card in the header.
|
||||
@return Allocated string containing the card or NULL
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_query_card(
|
||||
char * filename,
|
||||
char * keyword) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Replace a card in a FITS (main) header by a given card
|
||||
@param filename Name of the FITS file to modify.
|
||||
@param keyword Where to substitute a card in the header.
|
||||
@param substitute What to replace the line with.
|
||||
@return int 0 if Ok, -1 otherwise
|
||||
|
||||
Replaces a whole card (80 chars) in a FITS header by a given FITS
|
||||
line (80 chars). The replacing line is assumed correctly formatted
|
||||
and containing at least 80 characters. The file is modified: it must
|
||||
be accessible in read/write mode.
|
||||
|
||||
The input keyword is first converted to upper case and expanded to
|
||||
the HIERARCH scheme if given in the shortFITS notation.
|
||||
|
||||
Returns 0 if everything worked Ok, -1 otherwise.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_replace_card(
|
||||
char * filename,
|
||||
const char * keyword,
|
||||
char * substitute) ;
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,42 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file static_sz.h
|
||||
@author N. Devillard
|
||||
@date Dec 1999
|
||||
@version $Revision: 1.5 $
|
||||
@brief Definitions for various fixed sizes.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: static_sz.h,v 1.5 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.5 $
|
||||
*/
|
||||
|
||||
#ifndef STATIC_SZ_H
|
||||
#define STATIC_SZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/** Maximum supported file name size */
|
||||
#define FILENAMESZ 512
|
||||
|
||||
/** Maximum number of characters per line in an ASCII file */
|
||||
#define ASCIILINESZ 1024
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,93 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file t_iso8601.h
|
||||
@author N. Devillard
|
||||
@date Aug 1999
|
||||
@version $Revision: 1.8 $
|
||||
@brief Get date/time, possibly in ISO8601 format.
|
||||
|
||||
This module contains various utilities to get the current date/time,
|
||||
and possibly format it according to the ISO 8601 format.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: t_iso8601.h,v 1.8 2004/01/20 11:47:59 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2004/01/20 11:47:59 $
|
||||
$Revision: 1.8 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef T_ISO8601_H
|
||||
#define T_ISO8601_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function ANSI C prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Returns the current date as a long (CCYYMMDD).
|
||||
@return The current date as a long number.
|
||||
|
||||
Returns the current date as a long value (CCYYMMDD). Since most
|
||||
system clocks do not return a century, this function assumes that
|
||||
all years 80 and above are in the 20th century, and all years 00 to
|
||||
79 are in the 21st century. For best results, consume before 1 Jan
|
||||
2080.
|
||||
|
||||
Example: 19 Oct 2000 is returned as 20001019
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
long qfits_date_now (void);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Returns the current time as a long (HHMMSSCC).
|
||||
@return The current time as a long number.
|
||||
|
||||
Returns the current time as a long value (HHMMSSCC). If the system
|
||||
clock does not return centiseconds, these are set to zero.
|
||||
Example: 15:36:12.84 is returned as 15361284
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
long qfits_time_now(void);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Returns the current date as a static string.
|
||||
@return Pointer to statically allocated string.
|
||||
|
||||
Build and return a string containing the date of today in ISO8601
|
||||
format. The returned pointer points to a statically allocated string
|
||||
in the function, so no need to free it.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_date_iso8601(void);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Returns the current date and time as a static string.
|
||||
@return Pointer to statically allocated string
|
||||
|
||||
Build and return a string containing the date of today and the
|
||||
current time in ISO8601 format. The returned pointer points to a
|
||||
statically allocated string in the function, so no need to free it.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_get_datetime_iso8601(void);
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
|
@ -0,0 +1,546 @@
|
|||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file tfits.h
|
||||
@author Yves Jung
|
||||
@date July 1999
|
||||
@version $Revision: 1.25 $
|
||||
@brief FITS table handling
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
$Id: tfits.h,v 1.25 2003/11/24 09:44:53 yjung Exp $
|
||||
$Author: yjung $
|
||||
$Date: 2003/11/24 09:44:53 $
|
||||
$Revision: 1.25 $
|
||||
*/
|
||||
|
||||
#ifndef TFITS_H
|
||||
#define TFITS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Includes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fits_h.h"
|
||||
#include "static_sz.h"
|
||||
|
||||
/* <dox> */
|
||||
/*-----------------------------------------------------------------------------
|
||||
Defines
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* The following defines the maximum acceptable size for a FITS value */
|
||||
#define FITSVALSZ 60
|
||||
|
||||
#define QFITS_INVALIDTABLE 0
|
||||
#define QFITS_BINTABLE 1
|
||||
#define QFITS_ASCIITABLE 2
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
New types
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Column data type
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef enum _TFITS_DATA_TYPE_ {
|
||||
TFITS_ASCII_TYPE_A,
|
||||
TFITS_ASCII_TYPE_D,
|
||||
TFITS_ASCII_TYPE_E,
|
||||
TFITS_ASCII_TYPE_F,
|
||||
TFITS_ASCII_TYPE_I,
|
||||
TFITS_BIN_TYPE_A,
|
||||
TFITS_BIN_TYPE_B,
|
||||
TFITS_BIN_TYPE_C,
|
||||
TFITS_BIN_TYPE_D,
|
||||
TFITS_BIN_TYPE_E,
|
||||
TFITS_BIN_TYPE_I,
|
||||
TFITS_BIN_TYPE_J,
|
||||
TFITS_BIN_TYPE_L,
|
||||
TFITS_BIN_TYPE_M,
|
||||
TFITS_BIN_TYPE_P,
|
||||
TFITS_BIN_TYPE_X,
|
||||
TFITS_BIN_TYPE_UNKNOWN
|
||||
} tfits_type ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Column object
|
||||
|
||||
This structure contains all information needed to read a column in a table.
|
||||
These informations come from the header.
|
||||
The qfits_table object contains a list of qfits_col objects.
|
||||
|
||||
This structure has to be created from scratch and filled if one want to
|
||||
generate a FITS table.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct qfits_col
|
||||
{
|
||||
/**
|
||||
Number of atoms in one field.
|
||||
In ASCII tables, it is the number of characters in the field as defined
|
||||
in TFORM%d keyword.
|
||||
In BIN tables, it is the number of atoms in each field. For type 'A',
|
||||
it is the number of characters. A field with two complex object will
|
||||
have atom_nb = 4.
|
||||
*/
|
||||
int atom_nb ;
|
||||
|
||||
/**
|
||||
Number of decimals in a ASCII field.
|
||||
This value is always 0 for BIN tables
|
||||
*/
|
||||
int atom_dec_nb ;
|
||||
|
||||
/**
|
||||
Size of one element in bytes. In ASCII tables, atom_size is the size
|
||||
of the element once it has been converted in its 'destination' type.
|
||||
For example, if "123" is contained in an ASCII table in a column
|
||||
defined as I type, atom_nb=3, atom_size=4.
|
||||
In ASCII tables:
|
||||
- type 'A' : atom_size = atom_nb = number of chars
|
||||
- type 'I', 'F' or 'E' : atom_size = 4
|
||||
- type 'D' : atom_size = 8
|
||||
In BIN tables :
|
||||
- type 'A', 'L', 'X', 'B': atom_size = 1
|
||||
- type 'I' : atom_size = 2
|
||||
- type 'E', 'J', 'C', 'P' : atom_size = 4
|
||||
- type 'D', 'M' : atom_size = 8
|
||||
In ASCII table, there is one element per field. The size in bytes and
|
||||
in number of characters is atom_nb, and the size in bytes after
|
||||
conversion of the field is atom_size.
|
||||
In BIN tables, the size in bytes of a field is always atom_nb*atom_size.
|
||||
*/
|
||||
int atom_size ;
|
||||
|
||||
/**
|
||||
Type of data in the column as specified in TFORM keyword
|
||||
In ASCII tables : TFITS_ASCII_TYPE_* with *=A, I, F, E or D
|
||||
In BIN tables : TFITS_BIN_TYPE_* with *=L, X, B, I, J, A, E, D, C, M or P
|
||||
*/
|
||||
tfits_type atom_type ;
|
||||
|
||||
/** Label of the column */
|
||||
char tlabel[FITSVALSZ] ;
|
||||
|
||||
/** Unit of the data */
|
||||
char tunit[FITSVALSZ] ;
|
||||
|
||||
/** Null value */
|
||||
char nullval[FITSVALSZ] ;
|
||||
|
||||
/** Display format */
|
||||
char tdisp[FITSVALSZ] ;
|
||||
|
||||
/**
|
||||
zero and scale are used when the quantity in the field does not
|
||||
represent a true physical quantity. Basically, thez should be used
|
||||
when they are present: physical_value = zero + scale * field_value
|
||||
They are read from TZERO and TSCAL in the header
|
||||
*/
|
||||
int zero_present ;
|
||||
float zero ;
|
||||
int scale_present ;
|
||||
float scale ;
|
||||
|
||||
/** Offset between the beg. of the table and the beg. of the column. */
|
||||
int off_beg ;
|
||||
|
||||
/** Flag to know if the column is readable. An empty col is not readable */
|
||||
int readable ;
|
||||
} qfits_col ;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Table object
|
||||
|
||||
This structure contains all information needed to read a FITS table.
|
||||
These information come from the header. The object is created by
|
||||
qfits_open().
|
||||
|
||||
To read a FITS table, here is a code example:
|
||||
@code
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
qfits_table * table ;
|
||||
int n_ext ;
|
||||
int i ;
|
||||
|
||||
// Query the number of extensions
|
||||
n_ext = qfits_query_n_ext(argv[1]) ;
|
||||
|
||||
// For each extension
|
||||
for (i=0 ; i<n_ext ; i++) {
|
||||
// Read all the infos about the current table
|
||||
table = qfits_table_open(argv[1], i+1) ;
|
||||
// Display the current table
|
||||
dump_extension(table, stdout, '|', 1, 1) ;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct qfits_table
|
||||
{
|
||||
/**
|
||||
Name of the file the table comes from or it is intended to end to
|
||||
*/
|
||||
char filename[FILENAMESZ] ;
|
||||
/**
|
||||
Table type.
|
||||
Possible values: QFITS_INVALIDTABLE, QFITS_BINTABLE, QFITS_ASCIITABLE
|
||||
*/
|
||||
int tab_t ;
|
||||
/** Width in bytes of the table */
|
||||
int tab_w ;
|
||||
/** Number of columns */
|
||||
int nc ;
|
||||
/** Number of raws */
|
||||
int nr ;
|
||||
/** Array of qfits_col objects */
|
||||
qfits_col * col ;
|
||||
} qfits_table ;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Identify a file as containing a FITS table in extension.
|
||||
@param filename Name of the FITS file to examine.
|
||||
@param xtnum Extension number to check (starting from 1).
|
||||
@return int 1 if the extension contains a table, 0 else.
|
||||
|
||||
Examines the requested extension and identifies the presence of a
|
||||
FITS table.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_is_table(char * filename, int xtnum) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Generate a default primary header to store tables
|
||||
@return the header object
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_table_prim_header_default(void) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Generate a default extension header to store tables
|
||||
@return the header object
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_header * qfits_table_ext_header_default(qfits_table *) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Table object constructor
|
||||
@param filename Name of the FITS file associated to the table
|
||||
@param table_type Type of the table (QFITS_ASCIITABLE or QFITS_BINTABLE)
|
||||
@param table_width Width in bytes of the table
|
||||
@param nb_cols Number of columns
|
||||
@param nb_raws Number of raws
|
||||
@return The table object
|
||||
The columns are also allocated. The object has to be freed with
|
||||
qfits_table_close()
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_table * qfits_table_new(
|
||||
char * filename,
|
||||
int table_type,
|
||||
int table_width,
|
||||
int nb_cols,
|
||||
int nb_raws) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Fill a column object with some provided informations
|
||||
@param qc Pointer to the column that has to be filled
|
||||
@param unit Unit of the data
|
||||
@param label Label of the column
|
||||
@param disp Way to display the data
|
||||
@param nullval Null value
|
||||
@param atom_nb Number of atoms per field. According to the type, an atom
|
||||
is a double, an int, a char, ...
|
||||
@param atom_dec_nb Number of decimals as specified in TFORM
|
||||
@param atom_size Size in bytes of the field for ASCII tables, and of
|
||||
an atom for BIN tables. ASCII tables only contain 1
|
||||
atom per field (except for A type where you can of
|
||||
course have more than one char per field)
|
||||
@param atom_type Type of data (11 types for BIN, 5 for ASCII)
|
||||
@param zero_present Flag to use or not zero
|
||||
@param zero Zero value
|
||||
@param scale_present Flag to use or not scale
|
||||
@param scale Scale value
|
||||
@param offset_beg Gives the position of the column
|
||||
@return -1 in error case, 0 otherwise
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_col_fill(
|
||||
qfits_col * qc,
|
||||
int atom_nb,
|
||||
int atom_dec_nb,
|
||||
int atom_size,
|
||||
tfits_type atom_type,
|
||||
char * label,
|
||||
char * unit,
|
||||
char * nullval,
|
||||
char * disp,
|
||||
int zero_present,
|
||||
float zero,
|
||||
int scale_present,
|
||||
float scale,
|
||||
int offset_beg) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Read a FITS extension.
|
||||
@param filename Name of the FITS file to examine.
|
||||
@param xtnum Extension number to read (starting from 1).
|
||||
@return Pointer to newly allocated qfits_table structure.
|
||||
|
||||
Read a FITS table from a given file name and extension, and return a
|
||||
newly allocated qfits_table structure.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
qfits_table * qfits_table_open(
|
||||
char * filename,
|
||||
int xtnum) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Free a FITS table and associated pointers
|
||||
@param t qfits_table to free
|
||||
@return void
|
||||
Frees all memory associated to a qfits_table structure.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void qfits_table_close(qfits_table * t) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Extract data from a column in a FITS table
|
||||
@param th Allocated qfits_table
|
||||
@param colnum Number of the column to extract (from 0 to colnum-1)
|
||||
@param selection boolean array to define the selected rows
|
||||
@return unsigned char array
|
||||
|
||||
If selection is NULL, select the complete column.
|
||||
|
||||
Extract a column from a FITS table and return the data as a bytes
|
||||
array. The returned array type and size are determined by the
|
||||
column object in the qfits_table and by the selection parameter.
|
||||
|
||||
Returned array size in bytes is:
|
||||
nbselected * col->natoms * col->atom_size
|
||||
|
||||
Numeric types are correctly understood and byte-swapped if needed,
|
||||
to be converted to the local machine type.
|
||||
|
||||
NULL values have to be handled by the caller.
|
||||
|
||||
The returned buffer has been allocated using one of the special memory
|
||||
operators present in xmemory.c. To deallocate the buffer, you must call
|
||||
the version of free() offered by xmemory, not the usual system free(). It
|
||||
is enough to include "xmemory.h" in your code before you make calls to
|
||||
the pixel loader here.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned char * qfits_query_column(
|
||||
qfits_table * th,
|
||||
int colnum,
|
||||
int * selection) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Extract consequtive values from a column in a FITS table
|
||||
@param th Allocated qfits_table
|
||||
@param colnum Number of the column to extract (from 0 to colnum-1)
|
||||
@param start_ind Index of the first row (0 for the first)
|
||||
@param nb_rows Number of rows to extract
|
||||
@return unsigned char array
|
||||
Does the same as qfits_query_column() but on a consequtive sequence of rows
|
||||
Spares the overhead of the selection object allocation
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned char * qfits_query_column_seq(
|
||||
qfits_table * th,
|
||||
int colnum,
|
||||
int start_ind,
|
||||
int nb_rows) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the table width in bytes from the columns infos
|
||||
@param th Allocated qfits_table
|
||||
@return the width (-1 in error case)
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_compute_table_width(qfits_table * th) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Extract binary data from a column in a FITS table
|
||||
@param th Allocated qfits_table
|
||||
@param colnum Number of the column to extract (from 0 to colnum-1)
|
||||
@param selection bollean array to identify selected rows
|
||||
@param null_value Value to return when a NULL value comes
|
||||
@return Pointer to void *
|
||||
|
||||
Extract a column from a FITS table and return the data as a generic
|
||||
void* array. The returned array type and size are determined by the
|
||||
column object in the qfits_table.
|
||||
|
||||
Returned array size in bytes is:
|
||||
nb_selected * col->atom_nb * col->atom_size
|
||||
|
||||
NULL values are recognized and replaced by the specified value.
|
||||
|
||||
The returned buffer has been allocated using one of the special memory
|
||||
operators present in xmemory.c. To deallocate the buffer, you must call
|
||||
the version of free() offered by xmemory, not the usual system free(). It
|
||||
is enough to include "xmemory.h" in your code before you make calls to
|
||||
the pixel loader here.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void * qfits_query_column_data(
|
||||
qfits_table * th,
|
||||
int colnum,
|
||||
int * selection,
|
||||
void * null_value) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Extract binary data from a column in a FITS table
|
||||
@param th Allocated qfits_table
|
||||
@param colnum Number of the column to extract (from 0 to colnum-1)
|
||||
@param start_ind Index of the first row (0 for the first)
|
||||
@param nb_rows Number of rows to extract
|
||||
@param null_value Value to return when a NULL value comes
|
||||
@return Pointer to void *
|
||||
Does the same as qfits_query_column_data() but on a consequtive sequence
|
||||
of rows. Spares the overhead of the selection object allocation
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void * qfits_query_column_seq_data(
|
||||
qfits_table * th,
|
||||
int colnum,
|
||||
int start_ind,
|
||||
int nb_rows,
|
||||
void * null_value) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Detect NULL values in a column
|
||||
@param th Allocated qfits_table
|
||||
@param colnum Number of the column to check (from 0 to colnum-1)
|
||||
@param selection Array to identify selected rows
|
||||
@param nb_vals Gives the size of the output array
|
||||
@param nb_nulls Gives the number of detected null values
|
||||
@return array with 1 for NULLs and 0 for non-NULLs
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int * qfits_query_column_nulls(
|
||||
qfits_table * th,
|
||||
int colnum,
|
||||
int * selection,
|
||||
int * nb_vals,
|
||||
int * nb_nulls) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a table to a FITS file with a given FITS header.
|
||||
@param array Data array.
|
||||
@param table table
|
||||
@param fh FITS header to insert in the output file.
|
||||
@return -1 in error case, 0 otherwise
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_save_table_hdrdump(
|
||||
void ** array,
|
||||
qfits_table * table,
|
||||
qfits_header * fh) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Appends a std extension header + data to a FITS table file.
|
||||
@param outfile Pointer to (opened) file ready for writing.
|
||||
@param t Pointer to qfits_table
|
||||
@param data Table data to write
|
||||
@return int 0 if Ok, -1 otherwise
|
||||
|
||||
Dumps a FITS table to a file. The whole table described by qfits_table, and
|
||||
the data arrays contained in 'data' are dumped to the file. An extension
|
||||
header is produced with all keywords needed to describe the table, then the
|
||||
data is dumped to the file.
|
||||
The output is then padded to reach a multiple of 2880 bytes in size.
|
||||
Notice that no main header is produced, only the extension part.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_table_append_xtension(
|
||||
FILE * outfile,
|
||||
qfits_table * t,
|
||||
void ** data) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Appends a specified extension header + data to a FITS table file.
|
||||
@param outfile Pointer to (opened) file ready for writing.
|
||||
@param t Pointer to qfits_table
|
||||
@param data Table data to write
|
||||
@param hdr Specified extension header
|
||||
@return int 0 if Ok, -1 otherwise
|
||||
|
||||
Dumps a FITS table to a file. The whole table described by qfits_table, and
|
||||
the data arrays contained in 'data' are dumped to the file following the
|
||||
specified fits header.
|
||||
The output is then padded to reach a multiple of 2880 bytes in size.
|
||||
Notice that no main header is produced, only the extension part.
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int qfits_table_append_xtension_hdr(
|
||||
FILE * outfile,
|
||||
qfits_table * t,
|
||||
void ** data,
|
||||
qfits_header * hdr) ;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief given a col and a row, find out the string to write for display
|
||||
@param table table structure
|
||||
@param col_id col id (0 -> nbcol-1)
|
||||
@param row_id row id (0 -> nrow-1)
|
||||
@param use_zero_scale Flag to use or not zero and scale
|
||||
@return the string to write
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char * qfits_table_field_to_string(
|
||||
qfits_table * table,
|
||||
int col_id,
|
||||
int row_id,
|
||||
int use_zero_scale) ;
|
||||
|
||||
/* </dox> */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
Loading…
Reference in New Issue