#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <locale.h>
#include "fitsio2.h"
#define errmsgsiz 25
#define ESMARKER 27
#define DelAll 1
#define DelMark 2
#define DelNewest 3
#define GetMesg 4
#define PutMesg 5
#define PutMark 6
#ifdef _REENTRANT
pthread_mutex_t Fitsio_Lock;
int Fitsio_Pthread_Status = 0;
#endif
int STREAM_DRIVER = 0;
struct lconv *lcxxx;
float ffvers(float *version)
{
*version = (float) 3.49;
return(*version);
}
int ffflnm(fitsfile *fptr,
char *filename,
int *status)
{
strcpy(filename,(fptr->Fptr)->filename);
return(*status);
}
int ffflmd(fitsfile *fptr,
int *filemode,
int *status)
{
*filemode = (fptr->Fptr)->writemode;
return(*status);
}
void ffgerr(int status,
char *errtext)
{
errtext[0] = '\0';
if (status >= 0 && status < 300)
{
switch (status) {
case 0:
strcpy(errtext, "OK - no error");
break;
case 1:
strcpy(errtext, "non-CFITSIO program error");
break;
case 101:
strcpy(errtext, "same input and output files");
break;
case 103:
strcpy(errtext, "attempt to open too many files");
break;
case 104:
strcpy(errtext, "could not open the named file");
break;
case 105:
strcpy(errtext, "couldn't create the named file");
break;
case 106:
strcpy(errtext, "error writing to FITS file");
break;
case 107:
strcpy(errtext, "tried to move past end of file");
break;
case 108:
strcpy(errtext, "error reading from FITS file");
break;
case 110:
strcpy(errtext, "could not close the file");
break;
case 111:
strcpy(errtext, "array dimensions too big");
break;
case 112:
strcpy(errtext, "cannot write to readonly file");
break;
case 113:
strcpy(errtext, "could not allocate memory");
break;
case 114:
strcpy(errtext, "invalid fitsfile pointer");
break;
case 115:
strcpy(errtext, "NULL input pointer");
break;
case 116:
strcpy(errtext, "error seeking file position");
break;
case 117:
strcpy(errtext, "bad value for file download timeout setting");
break;
case 121:
strcpy(errtext, "invalid URL prefix");
break;
case 122:
strcpy(errtext, "too many I/O drivers");
break;
case 123:
strcpy(errtext, "I/O driver init failed");
break;
case 124:
strcpy(errtext, "no I/O driver for this URLtype");
break;
case 125:
strcpy(errtext, "parse error in input file URL");
break;
case 126:
strcpy(errtext, "parse error in range list");
break;
case 151:
strcpy(errtext, "bad argument (shared mem drvr)");
break;
case 152:
strcpy(errtext, "null ptr arg (shared mem drvr)");
break;
case 153:
strcpy(errtext, "no free shared memory handles");
break;
case 154:
strcpy(errtext, "share mem drvr not initialized");
break;
case 155:
strcpy(errtext, "IPC system error (shared mem)");
break;
case 156:
strcpy(errtext, "no memory (shared mem drvr)");
break;
case 157:
strcpy(errtext, "share mem resource deadlock");
break;
case 158:
strcpy(errtext, "lock file open/create failed");
break;
case 159:
strcpy(errtext, "can't resize share mem block");
break;
case 201:
strcpy(errtext, "header already has keywords");
break;
case 202:
strcpy(errtext, "keyword not found in header");
break;
case 203:
strcpy(errtext, "keyword number out of bounds");
break;
case 204:
strcpy(errtext, "keyword value is undefined");
break;
case 205:
strcpy(errtext, "string missing closing quote");
break;
case 206:
strcpy(errtext, "error in indexed keyword name");
break;
case 207:
strcpy(errtext, "illegal character in keyword");
break;
case 208:
strcpy(errtext, "required keywords out of order");
break;
case 209:
strcpy(errtext, "keyword value not positive int");
break;
case 210:
strcpy(errtext, "END keyword not found");
break;
case 211:
strcpy(errtext, "illegal BITPIX keyword value");
break;
case 212:
strcpy(errtext, "illegal NAXIS keyword value");
break;
case 213:
strcpy(errtext, "illegal NAXISn keyword value");
break;
case 214:
strcpy(errtext, "illegal PCOUNT keyword value");
break;
case 215:
strcpy(errtext, "illegal GCOUNT keyword value");
break;
case 216:
strcpy(errtext, "illegal TFIELDS keyword value");
break;
case 217:
strcpy(errtext, "negative table row size");
break;
case 218:
strcpy(errtext, "negative number of rows");
break;
case 219:
strcpy(errtext, "named column not found");
break;
case 220:
strcpy(errtext, "illegal SIMPLE keyword value");
break;
case 221:
strcpy(errtext, "first keyword not SIMPLE");
break;
case 222:
strcpy(errtext, "second keyword not BITPIX");
break;
case 223:
strcpy(errtext, "third keyword not NAXIS");
break;
case 224:
strcpy(errtext, "missing NAXISn keywords");
break;
case 225:
strcpy(errtext, "first keyword not XTENSION");
break;
case 226:
strcpy(errtext, "CHDU not an ASCII table");
break;
case 227:
strcpy(errtext, "CHDU not a binary table");
break;
case 228:
strcpy(errtext, "PCOUNT keyword not found");
break;
case 229:
strcpy(errtext, "GCOUNT keyword not found");
break;
case 230:
strcpy(errtext, "TFIELDS keyword not found");
break;
case 231:
strcpy(errtext, "missing TBCOLn keyword");
break;
case 232:
strcpy(errtext, "missing TFORMn keyword");
break;
case 233:
strcpy(errtext, "CHDU not an IMAGE extension");
break;
case 234:
strcpy(errtext, "illegal TBCOLn keyword value");
break;
case 235:
strcpy(errtext, "CHDU not a table extension");
break;
case 236:
strcpy(errtext, "column exceeds width of table");
break;
case 237:
strcpy(errtext, "more than 1 matching col. name");
break;
case 241:
strcpy(errtext, "row width not = field widths");
break;
case 251:
strcpy(errtext, "unknown FITS extension type");
break;
case 252:
strcpy(errtext, "1st key not SIMPLE or XTENSION");
break;
case 253:
strcpy(errtext, "END keyword is not blank");
break;
case 254:
strcpy(errtext, "Header fill area not blank");
break;
case 255:
strcpy(errtext, "Data fill area invalid");
break;
case 261:
strcpy(errtext, "illegal TFORM format code");
break;
case 262:
strcpy(errtext, "unknown TFORM datatype code");
break;
case 263:
strcpy(errtext, "illegal TDIMn keyword value");
break;
case 264:
strcpy(errtext, "invalid BINTABLE heap pointer");
break;
default:
strcpy(errtext, "unknown error status");
break;
}
}
else if (status < 600)
{
switch(status) {
case 301:
strcpy(errtext, "illegal HDU number");
break;
case 302:
strcpy(errtext, "column number < 1 or > tfields");
break;
case 304:
strcpy(errtext, "negative byte address");
break;
case 306:
strcpy(errtext, "negative number of elements");
break;
case 307:
strcpy(errtext, "bad first row number");
break;
case 308:
strcpy(errtext, "bad first element number");
break;
case 309:
strcpy(errtext, "not an ASCII (A) column");
break;
case 310:
strcpy(errtext, "not a logical (L) column");
break;
case 311:
strcpy(errtext, "bad ASCII table datatype");
break;
case 312:
strcpy(errtext, "bad binary table datatype");
break;
case 314:
strcpy(errtext, "null value not defined");
break;
case 317:
strcpy(errtext, "not a variable length column");
break;
case 320:
strcpy(errtext, "illegal number of dimensions");
break;
case 321:
strcpy(errtext, "1st pixel no. > last pixel no.");
break;
case 322:
strcpy(errtext, "BSCALE or TSCALn = 0.");
break;
case 323:
strcpy(errtext, "illegal axis length < 1");
break;
case 340:
strcpy(errtext, "not group table");
break;
case 341:
strcpy(errtext, "HDU already member of group");
break;
case 342:
strcpy(errtext, "group member not found");
break;
case 343:
strcpy(errtext, "group not found");
break;
case 344:
strcpy(errtext, "bad group id");
break;
case 345:
strcpy(errtext, "too many HDUs tracked");
break;
case 346:
strcpy(errtext, "HDU alread tracked");
break;
case 347:
strcpy(errtext, "bad Grouping option");
break;
case 348:
strcpy(errtext, "identical pointers (groups)");
break;
case 360:
strcpy(errtext, "malloc failed in parser");
break;
case 361:
strcpy(errtext, "file read error in parser");
break;
case 362:
strcpy(errtext, "null pointer arg (parser)");
break;
case 363:
strcpy(errtext, "empty line (parser)");
break;
case 364:
strcpy(errtext, "cannot unread > 1 line");
break;
case 365:
strcpy(errtext, "parser too deeply nested");
break;
case 366:
strcpy(errtext, "file open failed (parser)");
break;
case 367:
strcpy(errtext, "hit EOF (parser)");
break;
case 368:
strcpy(errtext, "bad argument (parser)");
break;
case 369:
strcpy(errtext, "unexpected token (parser)");
break;
case 401:
strcpy(errtext, "bad int to string conversion");
break;
case 402:
strcpy(errtext, "bad float to string conversion");
break;
case 403:
strcpy(errtext, "keyword value not integer");
break;
case 404:
strcpy(errtext, "keyword value not logical");
break;
case 405:
strcpy(errtext, "keyword value not floating pt");
break;
case 406:
strcpy(errtext, "keyword value not double");
break;
case 407:
strcpy(errtext, "bad string to int conversion");
break;
case 408:
strcpy(errtext, "bad string to float conversion");
break;
case 409:
strcpy(errtext, "bad string to double convert");
break;
case 410:
strcpy(errtext, "illegal datatype code value");
break;
case 411:
strcpy(errtext, "illegal no. of decimals");
break;
case 412:
strcpy(errtext, "datatype conversion overflow");
break;
case 413:
strcpy(errtext, "error compressing image");
break;
case 414:
strcpy(errtext, "error uncompressing image");
break;
case 420:
strcpy(errtext, "bad date or time conversion");
break;
case 431:
strcpy(errtext, "syntax error in expression");
break;
case 432:
strcpy(errtext, "expression result wrong type");
break;
case 433:
strcpy(errtext, "vector result too large");
break;
case 434:
strcpy(errtext, "missing output column");
break;
case 435:
strcpy(errtext, "bad data in parsed column");
break;
case 436:
strcpy(errtext, "output extension of wrong type");
break;
case 501:
strcpy(errtext, "WCS angle too large");
break;
case 502:
strcpy(errtext, "bad WCS coordinate");
break;
case 503:
strcpy(errtext, "error in WCS calculation");
break;
case 504:
strcpy(errtext, "bad WCS projection type");
break;
case 505:
strcpy(errtext, "WCS keywords not found");
break;
default:
strcpy(errtext, "unknown error status");
break;
}
}
else
{
strcpy(errtext, "unknown error status");
}
return;
}
void ffpmsg(const char *err_message)
{
ffxmsg(PutMesg, (char *)err_message);
return;
}
void ffpmrk(void)
{
char *dummy = 0;
ffxmsg(PutMark, dummy);
return;
}
int ffgmsg(char *err_message)
{
ffxmsg(GetMesg, err_message);
return(*err_message);
}
void ffcmsg(void)
{
char *dummy = 0;
ffxmsg(DelAll, dummy);
return;
}
void ffcmrk(void)
{
char *dummy = 0;
ffxmsg(DelMark, dummy);
return;
}
void ffxmsg( int action,
char *errmsg)
{
int ii;
char markflag;
static char *txtbuff[errmsgsiz], *tmpbuff, *msgptr;
static char errbuff[errmsgsiz][81];
static int nummsg = 0;
FFLOCK;
if (action == DelAll)
{
for (ii = 0; ii < nummsg; ii ++)
*txtbuff[ii] = '\0';
nummsg = 0;
}
else if (action == DelMark)
{
while (nummsg > 0) {
nummsg--;
markflag = *txtbuff[nummsg];
*txtbuff[nummsg] = '\0';
if (markflag == ESMARKER)
break;
}
}
else if (action == DelNewest)
{
if (nummsg > 0)
{
nummsg--;
*txtbuff[nummsg] = '\0';
}
}
else if (action == GetMesg)
{
while (nummsg > 0)
{
strcpy(errmsg, txtbuff[0]);
*txtbuff[0] = '\0';
nummsg--;
for (ii = 0; ii < nummsg; ii++)
txtbuff[ii] = txtbuff[ii + 1];
if (errmsg[0] != ESMARKER) {
FFUNLOCK;
return;
}
}
errmsg[0] = '\0';
}
else if (action == PutMesg)
{
msgptr = errmsg;
while (strlen(msgptr))
{
if (nummsg == errmsgsiz)
{
tmpbuff = txtbuff[0];
*txtbuff[0] = '\0';
nummsg--;
for (ii = 0; ii < nummsg; ii++)
txtbuff[ii] = txtbuff[ii + 1];
txtbuff[nummsg] = tmpbuff;
}
else
{
for (ii = 0; ii < errmsgsiz; ii++)
{
if (*errbuff[ii] == '\0')
{
txtbuff[nummsg] = errbuff[ii];
break;
}
}
}
strncat(txtbuff[nummsg], msgptr, 80);
nummsg++;
msgptr += minvalue(80, strlen(msgptr));
}
}
else if (action == PutMark)
{
if (nummsg == errmsgsiz)
{
tmpbuff = txtbuff[0];
*txtbuff[0] = '\0';
nummsg--;
for (ii = 0; ii < nummsg; ii++)
txtbuff[ii] = txtbuff[ii + 1];
txtbuff[nummsg] = tmpbuff;
}
else
{
for (ii = 0; ii < errmsgsiz; ii++)
{
if (*errbuff[ii] == '\0')
{
txtbuff[nummsg] = errbuff[ii];
break;
}
}
}
*txtbuff[nummsg] = ESMARKER;
*(txtbuff[nummsg] + 1) = '\0';
nummsg++;
}
FFUNLOCK;
return;
}
int ffpxsz(int datatype)
{
if (datatype == TBYTE)
return(sizeof(char));
else if (datatype == TUSHORT)
return(sizeof(short));
else if (datatype == TSHORT)
return(sizeof(short));
else if (datatype == TULONG)
return(sizeof(long));
else if (datatype == TLONG)
return(sizeof(long));
else if (datatype == TINT)
return(sizeof(int));
else if (datatype == TUINT)
return(sizeof(int));
else if (datatype == TFLOAT)
return(sizeof(float));
else if (datatype == TDOUBLE)
return(sizeof(double));
else if (datatype == TLOGICAL)
return(sizeof(char));
else
return(0);
}
int fftkey(const char *keyword,
int *status)
{
size_t maxchr, ii;
int spaces=0;
char msg[FLEN_ERRMSG], testchar;
if (*status > 0)
return(*status);
maxchr=strlen(keyword);
if (maxchr > 8)
maxchr = 8;
for (ii = 0; ii < maxchr; ii++)
{
if (*status == 0)
testchar = keyword[ii];
else
testchar = toupper(keyword[ii]);
if ( (testchar >= 'A' && testchar <= 'Z') ||
(testchar >= '0' && testchar <= '9') ||
testchar == '-' || testchar == '_' )
{
if (spaces)
{
if (*status == 0)
{
snprintf(msg, FLEN_ERRMSG,
"Keyword name contains embedded space(s): %.8s",
keyword);
ffpmsg(msg);
}
return(*status = BAD_KEYCHAR);
}
}
else if (keyword[ii] == ' ')
spaces = 1;
else
{
if (*status == 0)
{
snprintf(msg, FLEN_ERRMSG,"Character %d in this keyword is illegal: %.8s",
(int) (ii+1), keyword);
ffpmsg(msg);
if (keyword[ii] == 0)
ffpmsg(" (This a NULL (0) character).");
else if (keyword[ii] == 9)
ffpmsg(" (This an ASCII TAB (9) character).");
}
return(*status = BAD_KEYCHAR);
}
}
return(*status);
}
int fftrec(char *card,
int *status)
{
size_t ii, maxchr;
char msg[FLEN_ERRMSG];
if (*status > 0)
return(*status);
maxchr = strlen(card);
for (ii = 8; ii < maxchr; ii++)
{
if (card[ii] < 32 || card[ii] > 126)
{
snprintf(msg, FLEN_ERRMSG,
"Character %d in this keyword is illegal. Hex Value = %X",
(int) (ii+1), (int) card[ii] );
if (card[ii] == 0)
strncat(msg, " (NULL char.)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 9)
strncat(msg, " (TAB char.)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 10)
strncat(msg, " (Line Feed char.)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 11)
strncat(msg, " (Vertical Tab)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 12)
strncat(msg, " (Form Feed char.)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 13)
strncat(msg, " (Carriage Return)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 27)
strncat(msg, " (Escape char.)",FLEN_ERRMSG-strlen(msg)-1);
else if (card[ii] == 127)
strncat(msg, " (Delete char.)",FLEN_ERRMSG-strlen(msg)-1);
ffpmsg(msg);
strncpy(msg, card, 80);
msg[80] = '\0';
ffpmsg(msg);
return(*status = BAD_KEYCHAR);
}
}
return(*status);
}
void ffupch(char *string)
{
size_t len, ii;
len = strlen(string);
for (ii = 0; ii < len; ii++)
string[ii] = toupper(string[ii]);
return;
}
int ffmkky(const char *keyname,
char *value,
const char *comm,
char *card,
int *status)
{
size_t namelen, len, ii;
char tmpname[FLEN_KEYWORD], tmpname2[FLEN_KEYWORD],*cptr;
char *saveptr;
int tstatus = -1, nblank = 0, ntoken = 0, maxlen = 0, specialchar = 0;
if (*status > 0)
return(*status);
*tmpname = '\0';
*tmpname2 = '\0';
*card = '\0';
while(*(keyname + nblank) == ' ')
nblank++;
strncat(tmpname, keyname + nblank, FLEN_KEYWORD - 1);
len = strlen(value);
namelen = strlen(tmpname);
if (namelen) {
cptr = tmpname + namelen - 1;
while(*cptr == ' ') {
*cptr = '\0';
cptr--;
}
namelen = cptr - tmpname + 1;
}
if (strchr(tmpname, '=') ) {
ffpmsg("Illegal keyword name; contains an equals sign (=)");
ffpmsg(tmpname);
return(*status = BAD_KEYCHAR);
}
if (namelen <= 8 && fftkey(tmpname, &tstatus) <= 0 ) {
strcat(card, tmpname);
for (ii = namelen; ii < 8; ii++)
card[ii] = ' ';
card[8] = '=';
card[9] = ' ';
card[10] = '\0';
namelen = 10;
} else if ((FSTRNCMP(tmpname, "HIERARCH ", 9) == 0) ||
(FSTRNCMP(tmpname, "hierarch ", 9) == 0) ) {
strcat(card, tmpname);
if (namelen + 3 + len > 80) {
strcat(card, "= ");
namelen += 2;
} else {
strcat(card, " = ");
namelen += 3;
}
} else {
strncat(tmpname2, tmpname, FLEN_KEYWORD - 1);
cptr = ffstrtok(tmpname2, " ",&saveptr);
while (cptr) {
if (strlen(cptr) > maxlen) maxlen = strlen(cptr);
tstatus = -1;
if (fftkey(cptr, &tstatus) > 0) specialchar = 1;
cptr = ffstrtok(NULL, " ",&saveptr);
ntoken++;
}
tstatus = -1;
if (ntoken > 0) {
if (namelen + 11 > FLEN_CARD-1)
{
ffpmsg(
"The following keyword is too long to fit on a card:");
ffpmsg(keyname);
return(*status = BAD_KEYCHAR);
}
strcat(card, "HIERARCH ");
strcat(card, tmpname);
namelen += 9;
if (namelen + 3 + len > 80) {
strcat(card, "= ");
namelen += 2;
} else {
strcat(card, " = ");
namelen += 3;
}
} else if ((fftkey(tmpname, &tstatus) <= 0)) {
strncat(card, tmpname, FLEN_KEYWORD - 1);
strcat(card, "= ");
namelen += 2;
} else {
ffpmsg("Illegal keyword name:");
ffpmsg(tmpname);
return(*status = BAD_KEYCHAR);
}
}
if (len > 0)
{
if (value[0] == '\'')
{
if (namelen > 77)
{
ffpmsg(
"The following keyword + value is too long to fit on a card:");
ffpmsg(keyname);
ffpmsg(value);
return(*status = BAD_KEYCHAR);
}
strncat(card, value, 80 - namelen);
len = minvalue(80, namelen + len);
if (len == 80)
{
card[79] = '\'';
}
if (comm)
{
if (comm[0] != 0)
{
if (len < 30)
{
for (ii = len; ii < 30; ii++)
card[ii] = ' ';
card[30] = '\0';
len = 30;
}
}
}
}
else
{
if (namelen + len > 80)
{
ffpmsg(
"The following keyword + value is too long to fit on a card:");
ffpmsg(keyname);
ffpmsg(value);
return(*status = BAD_KEYCHAR);
}
else if (namelen + len < 30)
{
strncat(card, " ", 30 - (namelen + len));
}
strncat(card, value, 80 - namelen);
len = minvalue(80, namelen + len);
len = maxvalue(30, len);
}
if (comm)
{
if ((len < 77) && ( strlen(comm) > 0) )
{
strcat(card, " / ");
strncat(card, comm, 77 - len);
}
}
}
else
{
if (namelen == 10)
{
card[8] = ' ';
if (comm)
{
strncat(card, comm, 80 - namelen);
}
}
}
if (ntoken == 1 || specialchar == 1) {
ffpmsg("Warning: the following keyword does not conform to the HIERARCH convention");
ffpmsg(card);
}
return(*status);
}
int ffmkey(fitsfile *fptr,
const char *card,
int *status)
{
char tcard[81];
size_t len, ii;
int keylength = 8;
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
strncpy(tcard,card,80);
tcard[80] = '\0';
len = strlen(tcard);
for (ii=0; ii < len; ii++)
if (tcard[ii] < ' ' || tcard[ii] > 126) tcard[ii] = ' ';
for (ii=len; ii < 80; ii++)
tcard[ii] = ' ';
keylength = strcspn(tcard, "=");
if (keylength == 80) keylength = 8;
for (ii=0; ii < keylength; ii++)
tcard[ii] = toupper(tcard[ii]);
fftkey(tcard, status);
ffmbyt(fptr, ((fptr->Fptr)->nextkey) - 80, REPORT_EOF, status);
ffpbyt(fptr, 80, tcard, status);
return(*status);
}
int ffkeyn(const char *keyroot,
int value,
char *keyname,
int *status)
{
char suffix[16];
size_t rootlen;
keyname[0] = '\0';
rootlen = strlen(keyroot);
if (rootlen == 0 || value < 0 )
return(*status = 206);
snprintf(suffix, 16, "%d", value);
strcpy(keyname, keyroot);
while (rootlen > 0 && keyname[rootlen - 1] == ' ') {
rootlen--;
keyname[rootlen] = '\0';
}
if (strlen(suffix) + strlen(keyname) > 8)
return (*status=206);
strcat(keyname, suffix);
return(*status);
}
int ffnkey(int value,
const char *keyroot,
char *keyname,
int *status)
{
size_t rootlen;
keyname[0] = '\0';
rootlen = strlen(keyroot);
if (rootlen == 0 || rootlen > 7 || value < 0 )
return(*status = 206);
snprintf(keyname, FLEN_VALUE,"%d", value);
if (rootlen + strlen(keyname) > 8)
return(*status = 206);
strcat(keyname, keyroot);
return(*status);
}
int ffpsvc(char *card,
char *value,
char *comm,
int *status)
{
int jj;
size_t ii, cardlen, nblank, valpos;
if (*status > 0)
return(*status);
value[0] = '\0';
if (comm)
comm[0] = '\0';
cardlen = strlen(card);
if (FSTRNCMP(card, "HIERARCH ", 9) == 0)
{
valpos = strcspn(card, "=");
if (valpos == cardlen)
{
if (comm != NULL)
{
if (cardlen > 8)
{
strcpy(comm, &card[8]);
jj=cardlen - 8;
for (jj--; jj >= 0; jj--)
{
if (comm[jj] == ' ')
comm[jj] = '\0';
else
break;
}
}
}
return(*status);
}
valpos++;
}
else if (cardlen < 9 ||
FSTRNCMP(card, "COMMENT ", 8) == 0 ||
FSTRNCMP(card, "HISTORY ", 8) == 0 ||
FSTRNCMP(card, "END ", 8) == 0 ||
FSTRNCMP(card, "CONTINUE", 8) == 0 ||
FSTRNCMP(card, " ", 8) == 0 )
{
if (comm != NULL)
{
if (cardlen > 8)
{
strcpy(comm, &card[8]);
jj=cardlen - 8;
for (jj--; jj >= 0; jj--)
{
if (comm[jj] == ' ')
comm[jj] = '\0';
else
break;
}
}
}
return(*status);
}
else if (FSTRNCMP(&card[8], "= ", 2) == 0 )
{
valpos = 10;
}
else
{
valpos = strcspn(card, "=");
if (valpos == cardlen)
{
if (comm != NULL)
{
if (cardlen > 8)
{
strcpy(comm, &card[8]);
jj=cardlen - 8;
for (jj--; jj >= 0; jj--)
{
if (comm[jj] == ' ')
comm[jj] = '\0';
else
break;
}
}
}
return(*status);
}
valpos++;
}
nblank = strspn(&card[valpos], " ");
if (nblank + valpos == cardlen)
{
return(*status);
}
ii = valpos + nblank;
if (card[ii] == '/' )
{
ii++;
}
else if (card[ii] == '\'' )
{
value[0] = card[ii];
for (jj=1, ii++; ii < cardlen; ii++, jj++)
{
if (card[ii] == '\'')
{
if (card[ii+1] == '\'')
{
value[jj] = card[ii];
ii++;
jj++;
}
else
{
value[jj] = card[ii];
break;
}
}
value[jj] = card[ii];
}
if (ii == cardlen)
{
jj = minvalue(jj, 69);
value[jj] = '\'';
value[jj+1] = '\0';
ffpmsg("This keyword string value has no closing quote:");
ffpmsg(card);
}
else
{
value[jj+1] = '\0';
ii++;
}
}
else if (card[ii] == '(' )
{
nblank = strcspn(&card[ii], ")" );
if (nblank == strlen( &card[ii] ) )
{
ffpmsg("This complex keyword value has no closing ')':");
ffpmsg(card);
return(*status = NO_QUOTE);
}
nblank++;
strncpy(value, &card[ii], nblank);
value[nblank] = '\0';
ii = ii + nblank;
}
else
{
nblank = strcspn(&card[ii], " /");
strncpy(value, &card[ii], nblank);
value[nblank] = '\0';
ii = ii + nblank;
}
if (comm)
{
nblank = strspn(&card[ii], " ");
ii = ii + nblank;
if (ii < 80)
{
if (card[ii] == '/')
{
ii++;
if (card[ii] == ' ')
ii++;
}
strcat(comm, &card[ii]);
jj=strlen(comm);
for (jj--; jj >= 0; jj--)
{
if (comm[jj] == ' ')
comm[jj] = '\0';
else
break;
}
}
}
return(*status);
}
int ffgthd(char *tmplt,
char *card,
int *hdtype,
int *status)
{
char keyname[FLEN_KEYWORD], value[140], comment[140];
char *tok, *suffix, *loc, tvalue[140];
int len, vlen, more, tstatus, lentok1=0, remainlen=0;
double dval;
if (*status > 0)
return(*status);
card[0] = '\0';
*hdtype = 0;
if (!FSTRNCMP(tmplt, " ", 8) )
{
strncat(card, tmplt, 80);
*hdtype = 1;
return(*status);
}
tok = tmplt;
keyname[0] = '\0';
value[0] = '\0';
comment[0] = '\0';
len = strspn(tok, " ");
tok += len;
if (strncmp(tok, "--------------------", 20) == 0)
return(*status = BAD_KEYCHAR);
if (tok[0] == '-')
{
*hdtype = -1;
tok++;
len = strspn(tok, " ");
tok += len;
len = strcspn(tok, " =+");
if (len >= FLEN_KEYWORD)
return(*status = BAD_KEYCHAR);
lentok1 = len;
strncat(card, tok, len);
if (len < 9)
{
ffupch(card);
tstatus = 0;
if (fftkey(card, &tstatus) > 0)
{
card[0] = '\0';
strncat(card, tok, len);
}
}
tok += len;
if (tok[0] == '+' && len < FLEN_KEYWORD) {
strcat(card, "+");
return (*status);
}
len = strspn(tok, " ");
tok += len;
if (tok[0] == '\0' || tok[0] == '=')
return(*status);
*hdtype = -2;
len = strcspn(tok, " ");
if (lentok1 > 40)
{
card[0] = '\0';
return (*status = BAD_KEYCHAR);
}
if (len > 40)
{
card[0] = '\0';
return(*status = BAD_KEYCHAR);
}
strcat(card," ");
strncpy(&card[40], tok, len);
card[80] = '\0';
if (len < 9)
{
ffupch(&card[40]);
tstatus = 0;
if (fftkey(&card[40], &tstatus) > 0)
{
strncpy(&card[40], tok, len);
}
}
}
else
{
len = strcspn(tok, " =");
if (len >= FLEN_KEYWORD)
return(*status = BAD_KEYCHAR);
strncat(keyname, tok, len);
if (len < 9)
{
ffupch(keyname);
tstatus = 0;
if (fftkey(keyname, &tstatus) > 0)
{
keyname[0] = '\0';
strncat(keyname, tok, len);
}
}
if (!FSTRCMP(keyname, "END") )
{
strcpy(card, "END");
*hdtype = 2;
return(*status);
}
tok += len;
if (!FSTRCMP(keyname, "COMMENT") || !FSTRCMP(keyname, "HISTORY")
|| !FSTRCMP(keyname, "HIERARCH") )
{
*hdtype = 1;
strcpy(card, keyname);
strncat(card, tok, 72);
return(*status);
}
len = strspn(tok, " =");
tok += len;
if (*tok == '\'')
{
more = TRUE;
remainlen = 139;
while (more)
{
tok++;
len = strcspn(tok, "'");
tok--;
if (len+2 > remainlen)
return (*status=BAD_KEYCHAR);
strncat(value, tok, len + 2);
remainlen -= (len+2);
tok += len + 1;
if (tok[0] != '\'')
return(*status = NO_QUOTE);
tok++;
if (tok[0] != '\'')
more = FALSE;
}
}
else if (*tok == '/' || *tok == '\0')
{
strcat(value, " ");
}
else
{
len = strcspn(tok, " /");
if (len > 139)
return (*status=BAD_KEYCHAR);
strncat(value, tok, len);
if (!( (tok[0] == 'T' || tok[0] == 'F') &&
(tok[1] == ' ' || tok[1] == '/' || tok[1] == '\0') ))
{
dval = strtod(value, &suffix);
if (*suffix != '\0' && *suffix != ' ' && *suffix != '/')
{
strcpy(tvalue, value);
if ((loc = strchr(tvalue, 'D')))
{
*loc = 'E';
dval = strtod(tvalue, &suffix);
}
else if ((loc = strchr(tvalue, 'd')))
{
*loc = 'E';
dval = strtod(tvalue, &suffix);
}
else if ((loc = strchr(tvalue, '.')))
{
*loc = ',';
dval = strtod(tvalue, &suffix);
}
}
if (*suffix != '\0' && *suffix != ' ' && *suffix != '/')
{
if (len > 137)
return (*status=BAD_KEYCHAR);
strcpy(value, "'");
strncat(value, tok, len);
strcat(value, "'");
if (dval == 0.)
len += (int) dval;
}
else
{
loc = strchr(value, 'e');
if (loc)
{
*loc = 'E';
}
else
{
loc = strchr(value, 'd');
if (loc)
{
*loc = 'D';
}
}
}
}
tok += len;
}
len = strspn(tok, " /");
tok += len;
vlen = strlen(value);
if (vlen > 0 && vlen < 10 && value[0] == '\'')
{
value[vlen-1] = '\0';
strncat(value, " ", 10 - vlen);
strcat(&value[9], "'");
}
strncat(comment, tok, 70);
ffmkky(keyname, value, comment, card, status);
}
return(*status);
}
int fits_translate_keyword(
char *inrec,
char *outrec,
char *patterns[][2],
int npat,
int n_value,
int n_offset,
int n_range,
int *pat_num,
int *i,
int *j,
int *m,
int *n,
int *status)
{
int i1 = 0, j1 = 0, n1 = 0, m1 = 0;
int fac;
char a = ' ';
char oldp;
char c, s;
int ip, ic, pat, pass = 0, firstfail;
char *spat;
if (*status > 0)
return(*status);
if ((inrec == 0) || (outrec == 0))
return (*status = NULL_INPUT_PTR);
*outrec = '\0';
if (*inrec == '\0')
strcpy(inrec, " ");
oldp = '\0';
firstfail = 0;
for (pat=0; pat < npat; pat++) {
spat = patterns[pat][0];
i1 = 0; j1 = 0; m1 = -1; n1 = -1; a = ' ';
pass = 0;
if (spat[0] == '*') {
pass = 1;
break;
}
if (firstfail && spat[0] == oldp) continue;
oldp = spat[0];
for (ip=0, ic=0, firstfail=1;
(spat[ip]) && (ic < 8);
ip++, ic++, firstfail=0) {
c = inrec[ic];
s = spat[ip];
if (s == 'i') {
if (isdigit(c)) { i1 = c - '0'; pass = 1;}
} else if (s == 'j') {
if (isdigit(c)) { j1 = c - '0'; pass = 1;}
} else if ((s == 'n')||(s == 'm')||(s == '#')) {
int val = 0;
pass = 0;
if (isdigit(c)) {
pass = 1;
while (ic<8 && isdigit(c)) {
val = val*10 + (c - '0');
ic++; c = inrec[ic];
}
ic--; c = inrec[ic];
if (s == 'n') {
if ( val >= 1 && val <= 999 &&
(((n_range == 0) && (val == n_value)) ||
((n_range == -1) && (val <= n_value)) ||
((n_range == +1) && (val >= n_value))) ) {
n1 = val;
} else {
pass = 0;
}
} else if (s == 'm') {
m1 = val;
}
}
} else if (s == 'a') {
if (isupper(c) || c == ' ') { a = c; pass = 1;}
} else if (s == '?') {
pass = 1;
} else if (c == s) {
pass = 1;
} else {
pass = 0;
}
if (!pass) break;
}
if (pass && (ic >= 8 || inrec[ic] == ' ')) break;
}
if (i) { *i = i1; }
if (j) { *j = j1; }
if (n) { *n = n1; }
if (m) { *m = m1; }
if (pat_num) { *pat_num = pat; }
spat = patterns[pat][1];
if (pass && strcmp(spat,"--") == 0) {
strcpy(outrec, "-");
strncat(outrec, inrec, 8);
outrec[9] = 0;
for(i1=8; i1>1 && outrec[i1] == ' '; i1--) outrec[i1] = 0;
return 0;
}
if (pass == 0 || spat[0] == '\0' || strcmp(spat,"-") == 0) return 0;
strcpy(outrec, inrec);
if (spat[0] == '+') return 0;
for (ip=0, ic=0; spat[ip]; ip++, ic++) {
s = spat[ip];
if (s == 'i') {
outrec[ic] = (i1+'0');
} else if (s == 'j') {
outrec[ic] = (j1+'0');
} else if (s == 'n') {
if (n1 == -1) { n1 = n_value; }
if (n1 > 0) {
n1 += n_offset;
for (fac = 1; (n1/fac) > 0; fac *= 10);
fac /= 10;
while(fac > 0) {
outrec[ic] = ((n1/fac) % 10) + '0';
fac /= 10;
ic ++;
}
ic--;
}
} else if (s == 'm' && m1 >= 0) {
for (fac = 1; (m1/fac) > 0; fac *= 10);
fac /= 10;
while(fac > 0) {
outrec[ic] = ((m1/fac) % 10) + '0';
fac /= 10;
ic ++;
}
ic --;
} else if (s == 'a') {
outrec[ic] = a;
} else {
outrec[ic] = s;
}
}
for ( ; ic<8; ic++) { outrec[ic] = ' '; }
return(*status);
}
int fits_translate_keywords(
fitsfile *infptr,
fitsfile *outfptr,
int firstkey,
char *patterns[][2],
int npat,
int n_value,
int n_offset,
int n_range,
int *status)
{
int nrec, nkeys, nmore;
char rec[FLEN_CARD];
int i = 0, j = 0, n = 0, m = 0;
int pat_num = 0, maxchr, ii;
char outrec[FLEN_CARD];
if (*status > 0)
return(*status);
ffghsp(infptr, &nkeys, &nmore, status);
for (nrec = firstkey; (*status == 0) && (nrec <= nkeys); nrec++) {
outrec[0] = '\0';
ffgrec(infptr, nrec, rec, status);
maxchr = strlen(rec);
for (ii = 8; ii < maxchr; ii++)
{
if (rec[ii] < 32 || rec[ii] > 126)
rec[ii] = ' ';
}
fits_translate_keyword(rec, outrec, patterns, npat,
n_value, n_offset, n_range,
&pat_num, &i, &j, &m, &n, status);
if (*status == 0) {
if (outrec[0] == '-') {
int i1;
outrec[9] = 0;
for(i1=8; i1>1 && outrec[i1] == ' '; i1--) outrec[i1] = 0;
ffpmrk();
ffdkey(outfptr, outrec+1, status);
if (*status == 0) {
int nkeys1;
ffghsp(infptr, &nkeys1, &nmore, status);
if (nkeys1 != nkeys) {
nrec --;
nkeys = nkeys1;
}
}
*status = 0;
ffcmrk();
} else if (outrec[0]) {
ffprec(outfptr, outrec, status);
}
}
rec[8] = 0; outrec[8] = 0;
}
return(*status);
}
int fits_copy_pixlist2image(
fitsfile *infptr,
fitsfile *outfptr,
int firstkey,
int naxis,
int *colnum,
int *status)
{
int nrec, nkeys, nmore;
char rec[FLEN_CARD], outrec[FLEN_CARD];
int pat_num = 0, npat;
int iret, jret, nret, mret, lret;
char *patterns[][2] = {
{"TCTYPn", "CTYPEn" },
{"TCTYna", "CTYPEna" },
{"TCUNIn", "CUNITn" },
{"TCUNna", "CUNITna" },
{"TCRVLn", "CRVALn" },
{"TCRVna", "CRVALna" },
{"TCDLTn", "CDELTn" },
{"TCDEna", "CDELTna" },
{"TCRPXn", "CRPIXn" },
{"TCRPna", "CRPIXna" },
{"TCROTn", "CROTAn" },
{"TPn_ma", "PCn_ma" },
{"TPCn_m", "PCn_ma" },
{"TCn_ma", "CDn_ma" },
{"TCDn_m", "CDn_ma" },
{"TVn_la", "PVn_la" },
{"TPVn_l", "PVn_la" },
{"TSn_la", "PSn_la" },
{"TPSn_l", "PSn_la" },
{"TWCSna", "WCSNAMEa" },
{"TCNAna", "CNAMEna" },
{"TCRDna", "CRDERna" },
{"TCSYna", "CSYERna" },
{"LONPna", "LONPOLEa" },
{"LATPna", "LATPOLEa" },
{"EQUIna", "EQUINOXa" },
{"MJDOBn", "MJD-OBS" },
{"MJDAn", "MJD-AVG" },
{"DAVGn", "DATE-AVG" },
{"RADEna", "RADESYSa" },
{"RFRQna", "RESTFRQa" },
{"RWAVna", "RESTWAVa" },
{"SPECna", "SPECSYSa" },
{"SOBSna", "SSYSOBSa" },
{"SSRCna", "SSYSSRCa" },
{"LONPOLEa", "+" },
{"LATPOLEa", "+" },
{"EQUINOXa", "+" },
{"EPOCH", "+" },
{"MJD-????", "+" },
{"DATE????", "+" },
{"TIME????", "+" },
{"RADESYSa", "+" },
{"RADECSYS", "+" },
{"TELESCOP", "+" },
{"INSTRUME", "+" },
{"OBSERVER", "+" },
{"OBJECT", "+" },
{"XTENSION", "-" },
{"BITPIX", "-" },
{"NAXIS", "-" },
{"NAXISi", "-" },
{"PCOUNT", "-" },
{"GCOUNT", "-" },
{"TFIELDS", "-" },
{"TDIM#", "-" },
{"THEAP", "-" },
{"EXTNAME", "-" },
{"EXTVER", "-" },
{"EXTLEVEL","-" },
{"CHECKSUM","-" },
{"DATASUM", "-" },
{"NAXLEN", "-" },
{"AXLEN#", "-" },
{"CPREF", "-" },
{"T????#a", "-" },
{"TC??#a", "-" },
{"T??#_#", "-" },
{"TWCS#a", "-" },
{"LONP#a", "-" },
{"LATP#a", "-" },
{"EQUI#a", "-" },
{"MJDOB#", "-" },
{"MJDA#", "-" },
{"RADE#a", "-" },
{"DAVG#", "-" },
{"iCTYP#", "-" },
{"iCTY#a", "-" },
{"iCUNI#", "-" },
{"iCUN#a", "-" },
{"iCRVL#", "-" },
{"iCDLT#", "-" },
{"iCRPX#", "-" },
{"iCTY#a", "-" },
{"iCUN#a", "-" },
{"iCRV#a", "-" },
{"iCDE#a", "-" },
{"iCRP#a", "-" },
{"ijPC#a", "-" },
{"ijCD#a", "-" },
{"iV#_#a", "-" },
{"iS#_#a", "-" },
{"iCRD#a", "-" },
{"iCSY#a", "-" },
{"iCROT#", "-" },
{"WCAX#a", "-" },
{"WCSN#a", "-" },
{"iCNA#a", "-" },
{"*", "+" }};
if (*status > 0)
return(*status);
npat = sizeof(patterns)/sizeof(patterns[0][0])/2;
ffghsp(infptr, &nkeys, &nmore, status);
for (nrec = firstkey; nrec <= nkeys; nrec++) {
outrec[0] = '\0';
ffgrec(infptr, nrec, rec, status);
fits_translate_pixkeyword(rec, outrec, patterns, npat,
naxis, colnum,
&pat_num, &iret, &jret, &nret, &mret, &lret, status);
if (outrec[0]) {
ffprec(outfptr, outrec, status);
}
rec[8] = 0; outrec[8] = 0;
}
return(*status);
}
int fits_translate_pixkeyword(
char *inrec,
char *outrec,
char *patterns[][2],
int npat,
int naxis,
int *colnum,
int *pat_num,
int *i,
int *j,
int *n,
int *m,
int *l,
int *status)
{
int i1 = 0, j1 = 0, val;
int fac, nval = 0, mval = 0, lval = 0;
char a = ' ';
char oldp;
char c, s;
int ip, ic, pat, pass = 0, firstfail;
char *spat;
if (*status > 0)
return(*status);
if ((inrec == 0) || (outrec == 0))
return (*status = NULL_INPUT_PTR);
*outrec = '\0';
if (*inrec == '\0') return 0;
oldp = '\0';
firstfail = 0;
for (pat=0; pat < npat; pat++) {
spat = patterns[pat][0];
i1 = 0; j1 = 0; a = ' ';
pass = 0;
if (spat[0] == '*') {
pass = 1;
break;
}
if (firstfail && spat[0] == oldp) continue;
oldp = spat[0];
for (ip=0, ic=0, firstfail=1;
(spat[ip]) && (ic < 8);
ip++, ic++, firstfail=0) {
c = inrec[ic];
s = spat[ip];
if (s == 'i') {
if (isdigit(c)) { i1 = c - '0'; pass = 1;}
} else if (s == 'j') {
if (isdigit(c)) { j1 = c - '0'; pass = 1;}
} else if ((s == 'n')||(s == 'm')||(s == 'l')||(s == '#')) {
val = 0;
pass = 0;
if (isdigit(c)) {
pass = 1;
while (ic<8 && isdigit(c)) {
val = val*10 + (c - '0');
ic++; c = inrec[ic];
}
ic--; c = inrec[ic];
if (s == 'n' || s == 'm') {
if ( val >= 1 && val <= 999) {
if (val == colnum[0])
val = 1;
else if (val == colnum[1])
val = 2;
else if (val == colnum[2])
val = 3;
else if (val == colnum[3])
val = 4;
else {
pass = 0;
val = 0;
}
if (s == 'n')
nval = val;
else
mval = val;
} else {
pass = 0;
}
} else if (s == 'l') {
lval = val;
}
}
} else if (s == 'a') {
if (isupper(c) || c == ' ') { a = c; pass = 1;}
} else if (s == '?') {
pass = 1;
} else if (c == s) {
pass = 1;
} else {
pass = 0;
}
if (!pass) break;
}
if (pass && (ic >= 8 || inrec[ic] == ' ')) break;
}
if (i) { *i = i1; }
if (j) { *j = j1; }
if (n) { *n = nval; }
if (m) { *m = mval; }
if (l) { *l = lval; }
if (pat_num) { *pat_num = pat; }
spat = patterns[pat][1];
if (pass == 0 || spat[0] == '\0' || spat[0] == '-') return 0;
strcpy(outrec, inrec);
if (spat[0] == '+') return 0;
for (ip=0, ic=0; spat[ip]; ip++, ic++) {
s = spat[ip];
if (s == 'i') {
outrec[ic] = (i1+'0');
} else if (s == 'j') {
outrec[ic] = (j1+'0');
} else if (s == 'n' && nval > 0) {
for (fac = 1; (nval/fac) > 0; fac *= 10);
fac /= 10;
while(fac > 0) {
outrec[ic] = ((nval/fac) % 10) + '0';
fac /= 10;
ic ++;
}
ic--;
} else if (s == 'm' && mval > 0) {
for (fac = 1; (mval/fac) > 0; fac *= 10);
fac /= 10;
while(fac > 0) {
outrec[ic] = ((mval/fac) % 10) + '0';
fac /= 10;
ic ++;
}
ic--;
} else if (s == 'l' && lval >= 0) {
for (fac = 1; (lval/fac) > 0; fac *= 10);
fac /= 10;
while(fac > 0) {
outrec[ic] = ((lval/fac) % 10) + '0';
fac /= 10;
ic ++;
}
ic --;
} else if (s == 'a') {
outrec[ic] = a;
} else {
outrec[ic] = s;
}
}
for ( ; ic<8; ic++) { outrec[ic] = ' '; }
return(*status);
}
int ffasfm(char *tform,
int *dtcode,
long *twidth,
int *decimals,
int *status)
{
int ii, datacode;
long longval, width;
float fwidth;
char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG];
if (*status > 0)
return(*status);
if (dtcode)
*dtcode = 0;
if (twidth)
*twidth = 0;
if (decimals)
*decimals = 0;
ii = 0;
while (tform[ii] != 0 && tform[ii] == ' ')
ii++;
if (strlen(&tform[ii]) > FLEN_VALUE-1)
{
ffpmsg("Error: ASCII table TFORM code is too long (ffasfm)");
return(*status = BAD_TFORM);
}
strcpy(temp, &tform[ii]);
ffupch(temp);
form = temp;
if (form[0] == 0)
{
ffpmsg("Error: ASCII table TFORM code is blank");
return(*status = BAD_TFORM);
}
if (form[0] == 'A')
datacode = TSTRING;
else if (form[0] == 'I')
datacode = TLONG;
else if (form[0] == 'F')
datacode = TFLOAT;
else if (form[0] == 'E')
datacode = TFLOAT;
else if (form[0] == 'D')
datacode = TDOUBLE;
else
{
snprintf(message, FLEN_ERRMSG,
"Illegal ASCII table TFORMn datatype: \'%s\'", tform);
ffpmsg(message);
return(*status = BAD_TFORM_DTYPE);
}
if (dtcode)
*dtcode = datacode;
form++;
if (datacode == TSTRING || datacode == TLONG)
{
if (ffc2ii(form, &width, status) <= 0)
{
if (width <= 0)
{
width = 0;
*status = BAD_TFORM;
}
else
{
if (width <= 4 && datacode == TLONG)
datacode = TSHORT;
}
}
}
else
{
if (ffc2rr(form, &fwidth, status) <= 0)
{
if (fwidth <= 0.)
*status = BAD_TFORM;
else
{
width = (long) fwidth;
if (width > 7 && *temp == 'F')
datacode = TDOUBLE;
if (width < 10)
form = form + 1;
else
form = form + 2;
if (form[0] == '.')
{
form++;
if (ffc2ii(form, &longval, status) <= 0)
{
if (decimals)
*decimals = longval;
if (longval >= width)
*status = BAD_TFORM;
if (longval > 6 && *temp == 'E')
datacode = TDOUBLE;
}
}
}
}
}
if (*status > 0)
{
*status = BAD_TFORM;
snprintf(message,FLEN_ERRMSG,"Illegal ASCII table TFORMn code: \'%s\'", tform);
ffpmsg(message);
}
if (dtcode)
*dtcode = datacode;
if (twidth)
*twidth = width;
return(*status);
}
int ffbnfm(char *tform,
int *dtcode,
long *trepeat,
long *twidth,
int *status)
{
size_t ii, nchar;
int datacode, variable, iread;
long width, repeat;
char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG];
if (*status > 0)
return(*status);
if (dtcode)
*dtcode = 0;
if (trepeat)
*trepeat = 0;
if (twidth)
*twidth = 0;
nchar = strlen(tform);
for (ii = 0; ii < nchar; ii++)
{
if (tform[ii] != ' ')
break;
}
if (ii == nchar)
{
ffpmsg("Error: binary table TFORM code is blank (ffbnfm).");
return(*status = BAD_TFORM);
}
if (nchar-ii > FLEN_VALUE-1)
{
ffpmsg("Error: binary table TFORM code is too long (ffbnfm).");
return (*status = BAD_TFORM);
}
strcpy(temp, &tform[ii]);
ffupch(temp);
form = temp;
ii = 0;
while(isdigit((int) form[ii]))
ii++;
if (ii == 0)
repeat = 1;
else
{
if (sscanf(form,"%ld", &repeat) != 1)
{
ffpmsg("Error: Bad repeat format in TFORM (ffbnfm).");
return(*status = BAD_TFORM);
}
}
form = form + ii;
if (form[0] == 'P' || form[0] == 'Q')
{
variable = 1;
form++;
}
else
variable = 0;
if (form[0] == 'U')
{
datacode = TUSHORT;
width = 2;
}
else if (form[0] == 'I')
{
datacode = TSHORT;
width = 2;
}
else if (form[0] == 'V')
{
datacode = TULONG;
width = 4;
}
else if (form[0] == 'W')
{
datacode = TULONGLONG;
width = 8;
}
else if (form[0] == 'J')
{
datacode = TLONG;
width = 4;
}
else if (form[0] == 'K')
{
datacode = TLONGLONG;
width = 8;
}
else if (form[0] == 'E')
{
datacode = TFLOAT;
width = 4;
}
else if (form[0] == 'D')
{
datacode = TDOUBLE;
width = 8;
}
else if (form[0] == 'A')
{
datacode = TSTRING;
iread = 0;
if (form[1] != 0)
{
if (form[1] == '(' )
form++;
iread = sscanf(&form[1],"%ld", &width);
}
if (iread != 1 || (!variable && (width > repeat)) )
width = repeat;
}
else if (form[0] == 'L')
{
datacode = TLOGICAL;
width = 1;
}
else if (form[0] == 'X')
{
datacode = TBIT;
width = 1;
}
else if (form[0] == 'B')
{
datacode = TBYTE;
width = 1;
}
else if (form[0] == 'S')
{
datacode = TSBYTE;
width = 1;
}
else if (form[0] == 'C')
{
datacode = TCOMPLEX;
width = 8;
}
else if (form[0] == 'M')
{
datacode = TDBLCOMPLEX;
width = 16;
}
else
{
snprintf(message, FLEN_ERRMSG,
"Illegal binary table TFORMn datatype: \'%s\' ", tform);
ffpmsg(message);
return(*status = BAD_TFORM_DTYPE);
}
if (variable)
datacode = datacode * (-1);
if (dtcode)
*dtcode = datacode;
if (trepeat)
*trepeat = repeat;
if (twidth)
*twidth = width;
return(*status);
}
int ffbnfmll(char *tform,
int *dtcode,
LONGLONG *trepeat,
long *twidth,
int *status)
{
size_t ii, nchar;
int datacode, variable, iread;
long width;
LONGLONG repeat;
char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG];
double drepeat;
if (*status > 0)
return(*status);
if (dtcode)
*dtcode = 0;
if (trepeat)
*trepeat = 0;
if (twidth)
*twidth = 0;
nchar = strlen(tform);
for (ii = 0; ii < nchar; ii++)
{
if (tform[ii] != ' ')
break;
}
if (ii == nchar)
{
ffpmsg("Error: binary table TFORM code is blank (ffbnfmll).");
return(*status = BAD_TFORM);
}
if (strlen(&tform[ii]) > FLEN_VALUE-1)
{
ffpmsg("Error: binary table TFORM code is too long (ffbnfmll).");
return(*status = BAD_TFORM);
}
strcpy(temp, &tform[ii]);
ffupch(temp);
form = temp;
ii = 0;
while(isdigit((int) form[ii]))
ii++;
if (ii == 0)
repeat = 1;
else {
sscanf(form,"%lf", &drepeat);
repeat = (LONGLONG) (drepeat + 0.1);
}
form = form + ii;
if (form[0] == 'P' || form[0] == 'Q')
{
variable = 1;
form++;
}
else
variable = 0;
if (form[0] == 'U')
{
datacode = TUSHORT;
width = 2;
}
else if (form[0] == 'I')
{
datacode = TSHORT;
width = 2;
}
else if (form[0] == 'V')
{
datacode = TULONG;
width = 4;
}
else if (form[0] == 'W')
{
datacode = TULONGLONG;
width = 8;
}
else if (form[0] == 'J')
{
datacode = TLONG;
width = 4;
}
else if (form[0] == 'K')
{
datacode = TLONGLONG;
width = 8;
}
else if (form[0] == 'E')
{
datacode = TFLOAT;
width = 4;
}
else if (form[0] == 'D')
{
datacode = TDOUBLE;
width = 8;
}
else if (form[0] == 'A')
{
datacode = TSTRING;
iread = 0;
if (form[1] != 0)
{
if (form[1] == '(' )
form++;
iread = sscanf(&form[1],"%ld", &width);
}
if (iread != 1 || (!variable && (width > repeat)) )
width = (long) repeat;
}
else if (form[0] == 'L')
{
datacode = TLOGICAL;
width = 1;
}
else if (form[0] == 'X')
{
datacode = TBIT;
width = 1;
}
else if (form[0] == 'B')
{
datacode = TBYTE;
width = 1;
}
else if (form[0] == 'S')
{
datacode = TSBYTE;
width = 1;
}
else if (form[0] == 'C')
{
datacode = TCOMPLEX;
width = 8;
}
else if (form[0] == 'M')
{
datacode = TDBLCOMPLEX;
width = 16;
}
else
{
snprintf(message, FLEN_ERRMSG,
"Illegal binary table TFORMn datatype: \'%s\' ", tform);
ffpmsg(message);
return(*status = BAD_TFORM_DTYPE);
}
if (variable)
datacode = datacode * (-1);
if (dtcode)
*dtcode = datacode;
if (trepeat)
*trepeat = repeat;
if (twidth)
*twidth = width;
return(*status);
}
void ffcfmt(char *tform,
char *cform)
{
int ii;
cform[0] = '\0';
ii = 0;
while (tform[ii] != 0 && tform[ii] == ' ')
ii++;
if (tform[ii] == 0)
return;
cform[0] = '%';
strcpy(&cform[1], &tform[ii + 1]);
if (tform[ii] == 'A')
strcat(cform, "s");
else if (tform[ii] == 'I')
strcat(cform, ".0f");
if (tform[ii] == 'F')
strcat(cform, "f");
if (tform[ii] == 'E')
strcat(cform, "E");
if (tform[ii] == 'D')
strcat(cform, "E");
return;
}
void ffcdsp(char *tform,
char *cform)
{
int ii;
cform[0] = '\0';
ii = 0;
while (tform[ii] != 0 && tform[ii] == ' ')
ii++;
if (tform[ii] == 0)
{
cform[0] = '\0';
return;
}
if (strchr(tform+ii, '%'))
{
cform[0] = '\0';
return;
}
cform[0] = '%';
strcpy(&cform[1], &tform[ii + 1]);
if (tform[ii] == 'A' || tform[ii] == 'a')
strcat(cform, "s");
else if (tform[ii] == 'I' || tform[ii] == 'i')
strcat(cform, "d");
else if (tform[ii] == 'O' || tform[ii] == 'o')
strcat(cform, "o");
else if (tform[ii] == 'Z' || tform[ii] == 'z')
strcat(cform, "X");
else if (tform[ii] == 'F' || tform[ii] == 'f')
strcat(cform, "f");
else if (tform[ii] == 'E' || tform[ii] == 'e')
strcat(cform, "E");
else if (tform[ii] == 'D' || tform[ii] == 'd')
strcat(cform, "E");
else if (tform[ii] == 'G' || tform[ii] == 'g')
strcat(cform, "G");
else
cform[0] = '\0';
return;
}
int ffgcno( fitsfile *fptr,
int casesen,
char *templt,
int *colnum,
int *status)
{
char colname[FLEN_VALUE];
ffgcnn(fptr, casesen, templt, colname, colnum, status);
return(*status);
}
int ffgcnn( fitsfile *fptr,
int casesen,
char *templt,
char *colname,
int *colnum,
int *status)
{
char errmsg[FLEN_ERRMSG];
int tstatus, ii, founde, foundw, match, exact, unique;
long ivalue;
tcolumn *colptr;
if (*status <= 0)
{
(fptr->Fptr)->startcol = 0;
tstatus = 0;
}
else if (*status == COL_NOT_UNIQUE)
{
tstatus = COL_NOT_UNIQUE;
*status = 0;
}
else
return(*status);
colname[0] = 0;
*colnum = 0;
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr += ((fptr->Fptr)->startcol);
founde = FALSE;
foundw = FALSE;
unique = FALSE;
for (ii = (fptr->Fptr)->startcol; ii < (fptr->Fptr)->tfield; ii++, colptr++)
{
ffcmps(templt, colptr->ttype, casesen, &match, &exact);
if (match)
{
if (founde && exact)
{
(fptr->Fptr)->startcol = *colnum;
return(*status = COL_NOT_UNIQUE);
}
else if (founde)
{
}
else if (exact)
{
strcpy(colname, colptr->ttype);
*colnum = ii + 1;
founde = TRUE;
}
else if (foundw)
{
unique = FALSE;
}
else
{
strcpy(colname, colptr->ttype);
*colnum = ii + 1;
(fptr->Fptr)->startcol = *colnum;
foundw = TRUE;
unique = TRUE;
}
}
}
if (founde)
{
if (tstatus == COL_NOT_UNIQUE)
*status = COL_NOT_UNIQUE;
}
else if (foundw)
{
if (!unique || tstatus == COL_NOT_UNIQUE)
*status = COL_NOT_UNIQUE;
}
else
{
ffc2ii(templt, &ivalue, &tstatus);
if (tstatus == 0 && ivalue <= (fptr->Fptr)->tfield && ivalue > 0)
{
*colnum = ivalue;
colptr = (fptr->Fptr)->tableptr;
colptr += (ivalue - 1);
strcpy(colname, colptr->ttype);
}
else
{
*status = COL_NOT_FOUND;
if (tstatus != COL_NOT_UNIQUE)
{
snprintf(errmsg, FLEN_ERRMSG, "ffgcnn could not find column: %.45s", templt);
ffpmsg(errmsg);
}
}
}
(fptr->Fptr)->startcol = *colnum;
return(*status);
}
void ffcmps(char *templt,
char *colname,
int casesen,
int *match,
int *exact)
{
int ii, found, t1, s1, wildsearch = 0, tsave = 0, ssave = 0;
char temp[FLEN_VALUE], col[FLEN_VALUE];
*match = FALSE;
*exact = TRUE;
strncpy(temp, templt, FLEN_VALUE);
strncpy(col, colname, FLEN_VALUE);
temp[FLEN_VALUE - 1] = '\0';
col[FLEN_VALUE - 1] = '\0';
for (ii = strlen(temp) - 1; ii >= 0 && temp[ii] == ' '; ii--)
temp[ii] = '\0';
for (ii = strlen(col) - 1; ii >= 0 && col[ii] == ' '; ii--)
col[ii] = '\0';
if (!casesen)
{
ffupch(temp);
ffupch(col);
}
if (!FSTRCMP(temp, col) )
{
*match = TRUE;
return;
}
*exact = FALSE;
t1 = 0;
s1 = 0;
while(1)
{
if (temp[t1] == '\0' && col[s1] == '\0')
{
*match = TRUE;
return;
}
else if (temp[t1] == '\0')
{
if (wildsearch)
{
t1 = tsave;
s1 = ssave + 1;
}
else
{
return;
}
}
else if (col[s1] == '\0')
{
if (temp[t1] == '*' && temp[t1 + 1] == '\0')
{
*match = TRUE;
}
return;
}
if (temp[t1] == col[s1] || (temp[t1] == '?') )
{
s1++;
t1++;
}
else if (temp[t1] == '#' && isdigit((int) col[s1]) )
{
s1++;
t1++;
while (isdigit((int) col[s1]) )
s1++;
}
else if (temp[t1] == '*')
{
wildsearch = 1;
tsave = t1;
ssave = s1;
t1++;
if (temp[t1] == '\0' || temp[t1] == ' ')
{
*match = TRUE;
return;
}
found = FALSE;
while (col[s1] && !found)
{
if (temp[t1] == col[s1])
{
t1++;
s1++;
found = TRUE;
}
else
s1++;
}
if (!found)
{
return;
}
}
else
{
if (wildsearch)
{
t1 = tsave;
s1 = ssave + 1;
}
else
{
return;
}
}
}
}
int ffgtcl( fitsfile *fptr,
int colnum,
int *typecode,
long *repeat,
long *width,
int *status)
{
LONGLONG trepeat, twidth;
ffgtclll(fptr, colnum, typecode, &trepeat, &twidth, status);
if (*status > 0)
return(*status);
if (repeat)
*repeat= (long) trepeat;
if (width)
*width = (long) twidth;
return(*status);
}
int ffgtclll( fitsfile *fptr,
int colnum,
int *typecode,
LONGLONG *repeat,
LONGLONG *width,
int *status)
{
tcolumn *colptr;
int hdutype, decims;
long tmpwidth;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
return(*status = BAD_COL_NUM);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (ffghdt(fptr, &hdutype, status) > 0)
return(*status);
if (hdutype == ASCII_TBL)
{
ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status);
*width = tmpwidth;
if (repeat)
*repeat = 1;
}
else
{
if (typecode)
*typecode = colptr->tdatatype;
if (width)
*width = colptr->twidth;
if (repeat)
*repeat = colptr->trepeat;
}
return(*status);
}
int ffeqty( fitsfile *fptr,
int colnum,
int *typecode,
long *repeat,
long *width,
int *status)
{
LONGLONG trepeat, twidth;
ffeqtyll(fptr, colnum, typecode, &trepeat, &twidth, status);
if (repeat)
*repeat= (long) trepeat;
if (width)
*width = (long) twidth;
return(*status);
}
int ffeqtyll( fitsfile *fptr,
int colnum,
int *typecode,
LONGLONG *repeat,
LONGLONG *width,
int *status)
{
tcolumn *colptr;
int hdutype, decims, tcode, effcode;
double tscale, tzero, min_val, max_val;
long lngscale, lngzero = 0, tmpwidth;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
return(*status = BAD_COL_NUM);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (ffghdt(fptr, &hdutype, status) > 0)
return(*status);
if (hdutype == ASCII_TBL)
{
ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status);
if (width)
*width = tmpwidth;
if (repeat)
*repeat = 1;
}
else
{
if (typecode)
*typecode = colptr->tdatatype;
if (width)
*width = colptr->twidth;
if (repeat)
*repeat = colptr->trepeat;
}
if (!typecode)
return(*status);
tscale = colptr->tscale;
tzero = colptr->tzero;
if (tscale == 1.0 && tzero == 0.0)
return(*status);
tcode = abs(*typecode);
switch (tcode)
{
case TBYTE:
min_val = 0.;
max_val = 255.0;
break;
case TSHORT:
min_val = -32768.0;
max_val = 32767.0;
break;
case TLONG:
min_val = -2147483648.0;
max_val = 2147483647.0;
break;
case TLONGLONG:
min_val = -9.2233720368547755808E18;
max_val = 9.2233720368547755807E18;
break;
default:
return(*status);
}
if (tscale >= 0.) {
min_val = tzero + tscale * min_val;
max_val = tzero + tscale * max_val;
} else {
max_val = tzero + tscale * min_val;
min_val = tzero + tscale * max_val;
}
if (tzero < 2147483648.)
lngzero = (long) tzero;
lngscale = (long) tscale;
if ((tzero != 2147483648.) &&
(tzero != 9223372036854775808.) &&
(lngzero != tzero || lngscale != tscale)) {
if (tcode == TBYTE || tcode == TSHORT)
effcode = TFLOAT;
else
effcode = TDOUBLE;
} else if ((min_val == -128.) && (max_val == 127.)) {
effcode = TSBYTE;
} else if ((min_val >= -32768.0) && (max_val <= 32767.0)) {
effcode = TSHORT;
} else if ((min_val >= 0.0) && (max_val <= 65535.0)) {
effcode = TUSHORT;
} else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) {
effcode = TLONG;
} else if ((min_val >= 0.0) && (max_val < 4294967296.0)) {
effcode = TULONG;
} else if ((min_val >= -9.2233720368547755808E18) && (max_val <= 9.2233720368547755807E18)) {
effcode = TLONGLONG;
} else if ((min_val >= 0.0) && (max_val <= 1.8446744073709551616E19)) {
effcode = TULONGLONG;
} else {
effcode = TDOUBLE;
}
if (*typecode < 0)
*typecode = -effcode;
else
*typecode = effcode;
return(*status);
}
int ffgncl( fitsfile *fptr,
int *ncols,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
return(*status = NOT_TABLE);
*ncols = (fptr->Fptr)->tfield;
return(*status);
}
int ffgnrw( fitsfile *fptr,
long *nrows,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
return(*status = NOT_TABLE);
*nrows = (long) (fptr->Fptr)->numrows;
return(*status);
}
int ffgnrwll( fitsfile *fptr,
LONGLONG *nrows,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
return(*status = NOT_TABLE);
*nrows = (fptr->Fptr)->numrows;
return(*status);
}
int ffgacl( fitsfile *fptr,
int colnum,
char *ttype,
long *tbcol,
char *tunit,
char *tform,
double *tscal,
double *tzero,
char *tnull,
char *tdisp,
int *status)
{
char name[FLEN_KEYWORD], comm[FLEN_COMMENT];
tcolumn *colptr;
int tstatus;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
return(*status = BAD_COL_NUM);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum -1);
if (ttype)
strcpy(ttype, colptr->ttype);
if (tbcol)
*tbcol = (long) ((colptr->tbcol) + 1);
if (tform)
strcpy(tform, colptr->tform);
if (tscal)
*tscal = colptr->tscale;
if (tzero)
*tzero = colptr->tzero;
if (tnull)
strcpy(tnull, colptr->strnull);
if (tunit)
{
ffkeyn("TUNIT", colnum, name, status);
tstatus = 0;
*tunit = '\0';
ffgkys(fptr, name, tunit, comm, &tstatus);
}
if (tdisp)
{
ffkeyn("TDISP", colnum, name, status);
tstatus = 0;
*tdisp = '\0';
ffgkys(fptr, name, tdisp, comm, &tstatus);
}
return(*status);
}
int ffgbcl( fitsfile *fptr,
int colnum,
char *ttype,
char *tunit,
char *dtype,
long *repeat,
double *tscal,
double *tzero,
long *tnull,
char *tdisp,
int *status)
{
LONGLONG trepeat, ttnull;
if (*status > 0)
return(*status);
ffgbclll(fptr, colnum, ttype, tunit, dtype, &trepeat, tscal, tzero,
&ttnull, tdisp, status);
if (repeat)
*repeat = (long) trepeat;
if (tnull)
*tnull = (long) ttnull;
return(*status);
}
int ffgbclll( fitsfile *fptr,
int colnum,
char *ttype,
char *tunit,
char *dtype,
LONGLONG *repeat,
double *tscal,
double *tzero,
LONGLONG *tnull,
char *tdisp,
int *status)
{
char name[FLEN_KEYWORD], comm[FLEN_COMMENT];
tcolumn *colptr;
int tstatus;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
return(*status = BAD_COL_NUM);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum -1);
if (ttype)
strcpy(ttype, colptr->ttype);
if (dtype)
{
if (colptr->tdatatype < 0)
strcpy(dtype, "P");
else
dtype[0] = 0;
if (abs(colptr->tdatatype) == TBIT)
strcat(dtype, "X");
else if (abs(colptr->tdatatype) == TBYTE)
strcat(dtype, "B");
else if (abs(colptr->tdatatype) == TLOGICAL)
strcat(dtype, "L");
else if (abs(colptr->tdatatype) == TSTRING)
strcat(dtype, "A");
else if (abs(colptr->tdatatype) == TSHORT)
strcat(dtype, "I");
else if (abs(colptr->tdatatype) == TLONG)
strcat(dtype, "J");
else if (abs(colptr->tdatatype) == TLONGLONG)
strcat(dtype, "K");
else if (abs(colptr->tdatatype) == TFLOAT)
strcat(dtype, "E");
else if (abs(colptr->tdatatype) == TDOUBLE)
strcat(dtype, "D");
else if (abs(colptr->tdatatype) == TCOMPLEX)
strcat(dtype, "C");
else if (abs(colptr->tdatatype) == TDBLCOMPLEX)
strcat(dtype, "M");
}
if (repeat)
*repeat = colptr->trepeat;
if (tscal)
*tscal = colptr->tscale;
if (tzero)
*tzero = colptr->tzero;
if (tnull)
*tnull = colptr->tnull;
if (tunit)
{
ffkeyn("TUNIT", colnum, name, status);
tstatus = 0;
*tunit = '\0';
ffgkys(fptr, name, tunit, comm, &tstatus);
}
if (tdisp)
{
ffkeyn("TDISP", colnum, name, status);
tstatus = 0;
*tdisp = '\0';
ffgkys(fptr, name, tdisp, comm, &tstatus);
}
return(*status);
}
int ffghdn(fitsfile *fptr,
int *chdunum)
{
*chdunum = (fptr->HDUposition) + 1;
return(*chdunum);
}
int ffghadll(fitsfile *fptr,
LONGLONG *headstart,
LONGLONG *datastart,
LONGLONG *dataend,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0)
return(*status);
}
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
{
if (ffrdef(fptr, status) > 0)
return(*status);
}
if (headstart)
*headstart = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu];
if (datastart)
*datastart = (fptr->Fptr)->datastart;
if (dataend)
*dataend = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1];
return(*status);
}
int ffghof(fitsfile *fptr,
OFF_T *headstart,
OFF_T *datastart,
OFF_T *dataend,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0)
return(*status);
}
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
{
if (ffrdef(fptr, status) > 0)
return(*status);
}
if (headstart)
*headstart = (OFF_T) (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu];
if (datastart)
*datastart = (OFF_T) (fptr->Fptr)->datastart;
if (dataend)
*dataend = (OFF_T) (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1];
return(*status);
}
int ffghad(fitsfile *fptr,
long *headstart,
long *datastart,
long *dataend,
int *status)
{
LONGLONG shead, sdata, edata;
if (*status > 0)
return(*status);
ffghadll(fptr, &shead, &sdata, &edata, status);
if (headstart)
{
if (shead > LONG_MAX)
*status = NUM_OVERFLOW;
else
*headstart = (long) shead;
}
if (datastart)
{
if (sdata > LONG_MAX)
*status = NUM_OVERFLOW;
else
*datastart = (long) sdata;
}
if (dataend)
{
if (edata > LONG_MAX)
*status = NUM_OVERFLOW;
else
*dataend = (long) edata;
}
return(*status);
}
int ffrhdu(fitsfile *fptr,
int *hdutype,
int *status)
{
int ii, tstatus;
char card[FLEN_CARD];
char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT];
char xname[FLEN_VALUE], *xtension, urltype[20];
if (*status > 0)
return(*status);
if (ffgrec(fptr, 1, card, status) > 0 )
{
ffpmsg("Cannot read first keyword in header (ffrhdu).");
return(*status);
}
strncpy(name,card,8);
name[8] = '\0';
for (ii=7; ii >= 0; ii--)
{
if (name[ii] == ' ')
name[ii] = '\0';
else
break;
}
if (ffpsvc(card, value, comm, status) > 0)
{
ffpmsg("Cannot read value of first keyword in header (ffrhdu):");
ffpmsg(card);
return(*status);
}
if (!strcmp(name, "SIMPLE"))
{
ffpinit(fptr, status);
if (hdutype != NULL)
*hdutype = 0;
}
else if (!strcmp(name, "XTENSION"))
{
if (ffc2s(value, xname, status) > 0)
{
ffpmsg("Bad value string for XTENSION keyword:");
ffpmsg(value);
return(*status);
}
xtension = xname;
while (*xtension == ' ')
xtension++;
if (!strcmp(xtension, "TABLE"))
{
ffainit(fptr, status);
if (hdutype != NULL)
*hdutype = 1;
}
else if (!strcmp(xtension, "BINTABLE") ||
!strcmp(xtension, "A3DTABLE") ||
!strcmp(xtension, "3DTABLE") )
{
ffbinit(fptr, status);
if (hdutype != NULL)
*hdutype = 2;
}
else
{
tstatus = 0;
ffpinit(fptr, &tstatus);
if (tstatus == UNKNOWN_EXT && hdutype != NULL)
*hdutype = -1;
else
{
*status = tstatus;
if (hdutype != NULL)
*hdutype = 0;
}
}
}
else
{
if (card[0] == 0 ||
card[0] == 10)
{
*status = END_OF_FILE;
}
else
{
*status = UNKNOWN_REC;
ffpmsg
("Extension doesn't start with SIMPLE or XTENSION keyword. (ffrhdu)");
ffpmsg(card);
}
}
if ((fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] <
(fptr->Fptr)->logfilesize )
{
(fptr->Fptr)->lasthdu = 0;
}
else
{
(fptr->Fptr)->lasthdu = 1;
ffurlt(fptr, urltype, status);
if (!strcmp(urltype,"mem://") || !strcmp(urltype,"memkeep://"))
{
fftrun(fptr, (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1],
status);
}
}
return(*status);
}
int ffpinit(fitsfile *fptr,
int *status)
{
int groups, tstatus, simple, bitpix, naxis, extend, nspace;
int ttype = 0, bytlen = 0, ii, ntilebins;
long pcount, gcount;
LONGLONG naxes[999], npix, blank;
double bscale, bzero;
char comm[FLEN_COMMENT];
tcolumn *colptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
(fptr->Fptr)->hdutype = IMAGE_HDU;
(fptr->Fptr)->headend = (fptr->Fptr)->logfilesize;
groups = 0;
tstatus = *status;
ffgphd(fptr, 999, &simple, &bitpix, &naxis, naxes, &pcount, &gcount,
&extend, &bscale, &bzero, &blank, &nspace, status);
if (*status == NOT_IMAGE)
*status = tstatus;
else if (*status > 0)
return(*status);
(fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1));
(fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1)
* 2880;
if (naxis > 0 && naxes[0] == 0)
{
tstatus = 0;
ffmaky(fptr, 2, status);
if (ffgkyl(fptr, "GROUPS", &groups, comm, &tstatus))
groups = 0;
}
if (bitpix == BYTE_IMG)
{
ttype=TBYTE;
bytlen=1;
}
else if (bitpix == SHORT_IMG)
{
ttype=TSHORT;
bytlen=2;
}
else if (bitpix == LONG_IMG)
{
ttype=TLONG;
bytlen=4;
}
else if (bitpix == LONGLONG_IMG)
{
ttype=TLONGLONG;
bytlen=8;
}
else if (bitpix == FLOAT_IMG)
{
ttype=TFLOAT;
bytlen=4;
}
else if (bitpix == DOUBLE_IMG)
{
ttype=TDOUBLE;
bytlen=8;
}
(fptr->Fptr)->imgdim = naxis;
if (naxis == 0)
{
npix = 0;
}
else
{
if (groups)
{
npix = 1;
}
else
{
npix = naxes[0];
}
(fptr->Fptr)->imgnaxis[0] = naxes[0];
for (ii=1; ii < naxis; ii++)
{
npix = npix*naxes[ii];
(fptr->Fptr)->imgnaxis[ii] = naxes[ii];
}
}
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] =
(fptr->Fptr)->datastart +
( ((LONGLONG) pcount + npix) * bytlen * gcount + 2879) / 2880 * 2880;
(fptr->Fptr)->heapstart = (npix + pcount) * bytlen * gcount;
(fptr->Fptr)->heapsize = 0;
(fptr->Fptr)->compressimg = 0;
if (naxis == 0)
{
(fptr->Fptr)->rowlength = 0;
(fptr->Fptr)->tfield = 0;
if ((fptr->Fptr)->tilerow) {
ntilebins =
(((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1;
for (ii = 0; ii < ntilebins; ii++) {
if ((fptr->Fptr)->tiledata[ii]) {
free((fptr->Fptr)->tiledata[ii]);
}
if ((fptr->Fptr)->tilenullarray[ii]) {
free((fptr->Fptr)->tilenullarray[ii]);
}
}
free((fptr->Fptr)->tileanynull);
free((fptr->Fptr)->tiletype);
free((fptr->Fptr)->tiledatasize);
free((fptr->Fptr)->tilenullarray);
free((fptr->Fptr)->tiledata);
free((fptr->Fptr)->tilerow);
(fptr->Fptr)->tileanynull = 0;
(fptr->Fptr)->tiletype = 0;
(fptr->Fptr)->tiledatasize = 0;
(fptr->Fptr)->tilenullarray = 0;
(fptr->Fptr)->tiledata = 0;
(fptr->Fptr)->tilerow = 0;
}
if ((fptr->Fptr)->tableptr)
free((fptr->Fptr)->tableptr);
(fptr->Fptr)->tableptr = 0;
(fptr->Fptr)->numrows = 0;
(fptr->Fptr)->origrows = 0;
}
else
{
(fptr->Fptr)->numrows = gcount;
(fptr->Fptr)->origrows = gcount;
(fptr->Fptr)->rowlength = (npix + pcount) * bytlen;
(fptr->Fptr)->tfield = 2;
if ((fptr->Fptr)->tilerow) {
ntilebins =
(((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1;
for (ii = 0; ii < ntilebins; ii++) {
if ((fptr->Fptr)->tiledata[ii]) {
free((fptr->Fptr)->tiledata[ii]);
}
if ((fptr->Fptr)->tilenullarray[ii]) {
free((fptr->Fptr)->tilenullarray[ii]);
}
}
free((fptr->Fptr)->tileanynull);
free((fptr->Fptr)->tiletype);
free((fptr->Fptr)->tiledatasize);
free((fptr->Fptr)->tilenullarray);
free((fptr->Fptr)->tiledata);
free((fptr->Fptr)->tilerow);
(fptr->Fptr)->tileanynull = 0;
(fptr->Fptr)->tiletype = 0;
(fptr->Fptr)->tiledatasize = 0;
(fptr->Fptr)->tilenullarray = 0;
(fptr->Fptr)->tiledata = 0;
(fptr->Fptr)->tilerow = 0;
}
if ((fptr->Fptr)->tableptr)
free((fptr->Fptr)->tableptr);
colptr = (tcolumn *) calloc(2, sizeof(tcolumn) ) ;
if (!colptr)
{
ffpmsg
("malloc failed to get memory for FITS array descriptors (ffpinit)");
(fptr->Fptr)->tableptr = 0;
return(*status = ARRAY_TOO_BIG);
}
(fptr->Fptr)->tableptr = colptr;
colptr->tbcol = 0;
colptr->tdatatype = ttype;
colptr->twidth = bytlen;
colptr->trepeat = (LONGLONG) pcount;
colptr->tscale = 1.;
colptr->tzero = 0.;
colptr->tnull = blank;
colptr++;
colptr->tbcol = pcount * bytlen;
colptr->tdatatype = ttype;
colptr->twidth = bytlen;
colptr->trepeat = npix;
colptr->tscale = bscale;
colptr->tzero = bzero;
colptr->tnull = blank;
}
(fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ];
return(*status);
}
int ffainit(fitsfile *fptr,
int *status)
{
int ii, nspace, ntilebins;
long tfield;
LONGLONG pcount, rowlen, nrows, tbcoln;
tcolumn *colptr = 0;
char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT];
char message[FLEN_ERRMSG], errmsg[FLEN_ERRMSG];
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
(fptr->Fptr)->hdutype = ASCII_TBL;
(fptr->Fptr)->headend = (fptr->Fptr)->logfilesize;
if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0)
return(*status);
if (pcount != 0)
{
ffpmsg("PCOUNT keyword not equal to 0 in ASCII table (ffainit).");
snprintf(errmsg, FLEN_ERRMSG," PCOUNT = %ld", (long) pcount);
ffpmsg(errmsg);
return(*status = BAD_PCOUNT);
}
(fptr->Fptr)->rowlength = rowlen;
(fptr->Fptr)->tfield = tfield;
if ((fptr->Fptr)->tilerow) {
ntilebins =
(((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1;
for (ii = 0; ii < ntilebins; ii++) {
if ((fptr->Fptr)->tiledata[ii]) {
free((fptr->Fptr)->tiledata[ii]);
}
if ((fptr->Fptr)->tilenullarray[ii]) {
free((fptr->Fptr)->tilenullarray[ii]);
}
}
free((fptr->Fptr)->tileanynull);
free((fptr->Fptr)->tiletype);
free((fptr->Fptr)->tiledatasize);
free((fptr->Fptr)->tilenullarray);
free((fptr->Fptr)->tiledata);
free((fptr->Fptr)->tilerow);
(fptr->Fptr)->tileanynull = 0;
(fptr->Fptr)->tiletype = 0;
(fptr->Fptr)->tiledatasize = 0;
(fptr->Fptr)->tilenullarray = 0;
(fptr->Fptr)->tiledata = 0;
(fptr->Fptr)->tilerow = 0;
}
if ((fptr->Fptr)->tableptr)
free((fptr->Fptr)->tableptr);
if (tfield > 0)
{
colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) );
if (!colptr)
{
ffpmsg
("malloc failed to get memory for FITS table descriptors (ffainit)");
(fptr->Fptr)->tableptr = 0;
return(*status = ARRAY_TOO_BIG);
}
}
(fptr->Fptr)->tableptr = colptr;
for (ii = 0; ii < tfield; ii++, colptr++)
{
colptr->ttype[0] = '\0';
colptr->tscale = 1.;
colptr->tzero = 0.;
colptr->strnull[0] = ASCII_NULL_UNDEFINED;
colptr->tbcol = -1;
colptr->tdatatype = -9999;
}
(fptr->Fptr)->numrows = nrows;
(fptr->Fptr)->origrows = nrows;
(fptr->Fptr)->heapstart = rowlen * nrows;
(fptr->Fptr)->heapsize = 0;
(fptr->Fptr)->compressimg = 0;
for (nspace = 0, ii = 8; 1; ii++)
{
ffgkyn(fptr, ii, name, value, comm, status);
if (*status == NO_QUOTE)
{
strcat(value, "'");
*status = 0;
}
else if (*status == BAD_KEYCHAR)
{
*status = 0;
}
if (*status == END_OF_FILE)
{
ffpmsg("END keyword not found in ASCII table header (ffainit).");
return(*status = NO_END);
}
else if (*status > 0)
return(*status);
else if (name[0] == 'T')
ffgtbp(fptr, name, value, status);
else if (!FSTRCMP(name, "END"))
break;
if (!name[0] && !value[0] && !comm[0])
nspace++;
else
nspace = 0;
}
colptr = (fptr->Fptr)->tableptr;
for (ii = 0; ii < tfield; ii++, colptr++)
{
tbcoln = colptr->tbcol;
if (colptr->tdatatype == -9999)
{
ffkeyn("TFORM", ii+1, name, status);
snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffainit).", name);
ffpmsg(message);
return(*status = NO_TFORM);
}
else if (tbcoln == -1)
{
ffkeyn("TBCOL", ii+1, name, status);
snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffainit).", name);
ffpmsg(message);
return(*status = NO_TBCOL);
}
else if ((fptr->Fptr)->rowlength != 0 &&
(tbcoln < 0 || tbcoln >= (fptr->Fptr)->rowlength ) )
{
ffkeyn("TBCOL", ii+1, name, status);
snprintf(message,FLEN_ERRMSG,"Value of %s keyword out of range: %ld (ffainit).",
name, (long) tbcoln);
ffpmsg(message);
return(*status = BAD_TBCOL);
}
else if ((fptr->Fptr)->rowlength != 0 &&
tbcoln + colptr->twidth > (fptr->Fptr)->rowlength )
{
snprintf(message,FLEN_ERRMSG,"Column %d is too wide to fit in table (ffainit)",
ii+1);
ffpmsg(message);
snprintf(message, FLEN_ERRMSG," TFORM = %s and NAXIS1 = %ld",
colptr->tform, (long) (fptr->Fptr)->rowlength);
ffpmsg(message);
return(*status = COL_TOO_WIDE);
}
}
(fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1));
(fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1)
* 2880;
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] =
(fptr->Fptr)->datastart +
( ((LONGLONG)rowlen * nrows + 2879) / 2880 * 2880 );
(fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ];
return(*status);
}
int ffbinit(fitsfile *fptr,
int *status)
{
int ii, nspace, ntilebins;
long tfield;
LONGLONG pcount, rowlen, nrows, totalwidth;
tcolumn *colptr = 0;
char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT];
char message[FLEN_ERRMSG];
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
(fptr->Fptr)->hdutype = BINARY_TBL;
(fptr->Fptr)->headend = (fptr->Fptr)->logfilesize;
if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0)
return(*status);
(fptr->Fptr)->rowlength = rowlen;
(fptr->Fptr)->tfield = tfield;
if ((fptr->Fptr)->tilerow) {
ntilebins =
(((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1;
for (ii = 0; ii < ntilebins; ii++) {
if ((fptr->Fptr)->tiledata[ii]) {
free((fptr->Fptr)->tiledata[ii]);
}
if ((fptr->Fptr)->tilenullarray[ii]) {
free((fptr->Fptr)->tilenullarray[ii]);
}
}
free((fptr->Fptr)->tileanynull);
free((fptr->Fptr)->tiletype);
free((fptr->Fptr)->tiledatasize);
free((fptr->Fptr)->tilenullarray);
free((fptr->Fptr)->tiledata);
free((fptr->Fptr)->tilerow);
(fptr->Fptr)->tileanynull = 0;
(fptr->Fptr)->tiletype = 0;
(fptr->Fptr)->tiledatasize = 0;
(fptr->Fptr)->tilenullarray = 0;
(fptr->Fptr)->tiledata = 0;
(fptr->Fptr)->tilerow = 0;
}
if ((fptr->Fptr)->tableptr)
free((fptr->Fptr)->tableptr);
if (tfield > 0)
{
colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) );
if (!colptr)
{
ffpmsg
("malloc failed to get memory for FITS table descriptors (ffbinit)");
(fptr->Fptr)->tableptr = 0;
return(*status = ARRAY_TOO_BIG);
}
}
(fptr->Fptr)->tableptr = colptr;
for (ii = 0; ii < tfield; ii++, colptr++)
{
colptr->ttype[0] = '\0';
colptr->tscale = 1.;
colptr->tzero = 0.;
colptr->tnull = NULL_UNDEFINED;
colptr->tdatatype = -9999;
colptr->trepeat = 1;
colptr->strnull[0] = '\0';
}
(fptr->Fptr)->numrows = nrows;
(fptr->Fptr)->origrows = nrows;
(fptr->Fptr)->heapstart = rowlen * nrows;
(fptr->Fptr)->heapsize = pcount;
(fptr->Fptr)->compressimg = 0;
for (nspace = 0, ii = 8; 1; ii++)
{
ffgkyn(fptr, ii, name, value, comm, status);
if (*status == NO_QUOTE)
{
strcat(value, "'");
*status = 0;
}
else if (*status == BAD_KEYCHAR)
{
*status = 0;
}
if (*status == END_OF_FILE)
{
ffpmsg("END keyword not found in binary table header (ffbinit).");
return(*status = NO_END);
}
else if (*status > 0)
return(*status);
else if (name[0] == 'T')
ffgtbp(fptr, name, value, status);
else if (!FSTRCMP(name, "ZIMAGE"))
{
if (value[0] == 'T')
(fptr->Fptr)->compressimg = 1;
}
else if (!FSTRCMP(name, "END"))
break;
if (!name[0] && !value[0] && !comm[0])
nspace++;
else
nspace = 0;
}
colptr = (fptr->Fptr)->tableptr;
for (ii = 0; ii < tfield; ii++, colptr++)
{
if (colptr->tdatatype == -9999)
{
ffkeyn("TFORM", ii+1, name, status);
snprintf(message,FLEN_ERRMSG,"Required %s keyword not found (ffbinit).", name);
ffpmsg(message);
return(*status = NO_TFORM);
}
}
(fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1));
(fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1)
* 2880;
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] =
(fptr->Fptr)->datastart +
( ((fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize + 2879) / 2880 * 2880 );
ffgtbc(fptr, &totalwidth, status);
if (totalwidth != rowlen)
{
snprintf(message,FLEN_ERRMSG,
"NAXIS1 = %ld is not equal to the sum of column widths: %ld",
(long) rowlen, (long) totalwidth);
ffpmsg(message);
*status = BAD_ROW_WIDTH;
}
(fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ];
if ( (fptr->Fptr)->compressimg == 1)
imcomp_get_compressed_image_par(fptr, status);
return(*status);
}
int ffgabc(int tfields,
char **tform,
int space,
long *rowlen,
long *tbcol,
int *status)
{
int ii, datacode, decims;
long width;
if (*status > 0)
return(*status);
*rowlen=0;
if (tfields <= 0)
return(*status);
tbcol[0] = 1;
for (ii = 0; ii < tfields; ii++)
{
tbcol[ii] = *rowlen + 1;
ffasfm(tform[ii], &datacode, &width, &decims, status);
*rowlen += (width + space);
}
*rowlen -= space;
return (*status);
}
int ffgtbc(fitsfile *fptr,
LONGLONG *totalwidth,
int *status)
{
int tfields, ii;
LONGLONG nbytes;
tcolumn *colptr;
char message[FLEN_ERRMSG], *cptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
tfields = (fptr->Fptr)->tfield;
colptr = (fptr->Fptr)->tableptr;
*totalwidth = 0;
for (ii = 0; ii < tfields; ii++, colptr++)
{
colptr->tbcol = *totalwidth;
if (colptr->tdatatype == TSTRING)
{
nbytes = colptr->trepeat;
}
else if (colptr->tdatatype == TBIT)
{
nbytes = ( colptr->trepeat + 7) / 8;
}
else if (colptr->tdatatype > 0)
{
nbytes = colptr->trepeat * (colptr->tdatatype / 10);
}
else {
cptr = colptr->tform;
while (isdigit(*cptr)) cptr++;
if (*cptr == 'P')
nbytes = colptr->trepeat * 8;
else if (*cptr == 'Q')
nbytes = colptr->trepeat * 16;
else {
snprintf(message,FLEN_ERRMSG,
"unknown binary table column type: %s", colptr->tform);
ffpmsg(message);
*status = BAD_TFORM;
return(*status);
}
}
*totalwidth = *totalwidth + nbytes;
}
return(*status);
}
int ffgtbp(fitsfile *fptr,
char *name,
char *value,
int *status)
{
int tstatus, datacode, decimals;
long width, repeat, nfield, ivalue;
LONGLONG jjvalue;
double dvalue;
char tvalue[FLEN_VALUE], *loc;
char message[FLEN_ERRMSG];
tcolumn *colptr;
if (*status > 0)
return(*status);
tstatus = 0;
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
if(!FSTRNCMP(name + 1, "TYPE", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if (ffc2s(value, tvalue, &tstatus) > 0)
return(*status);
strcpy(colptr->ttype, tvalue);
}
else if(!FSTRNCMP(name + 1, "FORM", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if (ffc2s(value, tvalue, &tstatus) > 0)
return(*status);
strncpy(colptr->tform, tvalue, 9);
colptr->tform[9] = '\0';
if ((fptr->Fptr)->hdutype == ASCII_TBL)
{
if (ffasfm(tvalue, &datacode, &width, &decimals, status) > 0)
return(*status);
colptr->tdatatype = TSTRING;
colptr->trepeat = 1;
colptr->twidth = width;
}
else
{
if (ffbnfm(tvalue, &datacode, &repeat, &width, status) > 0)
return(*status);
colptr->tdatatype = datacode;
colptr->trepeat = (LONGLONG) repeat;
if (datacode == TSTRING) {
if (colptr->twidth == 0 || colptr->twidth > repeat)
colptr->twidth = width;
} else {
colptr->twidth = width;
}
}
}
else if(!FSTRNCMP(name + 1, "BCOL", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if ((fptr->Fptr)->hdutype == BINARY_TBL)
return(*status);
if (ffc2ii(value, &ivalue, status) > 0)
{
snprintf(message, FLEN_ERRMSG,
"Error reading value of %s as an integer: %s", name, value);
ffpmsg(message);
return(*status);
}
colptr->tbcol = ivalue - 1;
}
else if(!FSTRNCMP(name + 1, "SCAL", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if (ffc2dd(value, &dvalue, &tstatus) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Error reading value of %s as a double: %s", name, value);
ffpmsg(message);
return(*status);
}
colptr->tscale = dvalue;
}
else if(!FSTRNCMP(name + 1, "ZERO", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if (ffc2dd(value, &dvalue, &tstatus) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Error reading value of %s as a double: %s", name, value);
ffpmsg(message);
return(*status);
}
colptr->tzero = dvalue;
}
else if(!FSTRNCMP(name + 1, "NULL", 4) )
{
if( ffc2ii(name + 5, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if ((fptr->Fptr)->hdutype == ASCII_TBL)
{
if (ffc2s(value, tvalue, &tstatus) > 0)
return(*status);
strncpy(colptr->strnull, tvalue, 17);
colptr->strnull[17] = '\0';
}
else
{
if (ffc2jj(value, &jjvalue, &tstatus) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Error reading value of %s as an integer: %s", name, value);
ffpmsg(message);
return(*status);
}
colptr->tnull = jjvalue;
}
}
else if(!FSTRNCMP(name + 1, "DIM", 3) )
{
if ((fptr->Fptr)->hdutype == ASCII_TBL)
return(*status);
if( ffc2ii(name + 4, &nfield, &tstatus) > 0)
return(*status);
if (nfield < 1 || nfield > (fptr->Fptr)->tfield )
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr = colptr + nfield - 1;
if (colptr->tdatatype != -9999 && colptr->tdatatype != TSTRING)
return(*status);
loc = strchr(value, '(' );
if (!loc)
return(*status);
loc++;
width = strtol(loc, &loc, 10);
if (colptr->trepeat != 1 && colptr->trepeat < width)
return(*status);
colptr->twidth = width;
}
else if (!FSTRNCMP(name + 1, "HEAP", 4) )
{
if ((fptr->Fptr)->hdutype == ASCII_TBL)
return(*status);
if (ffc2jj(value, &jjvalue, &tstatus) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Error reading value of %s as an integer: %s", name, value);
ffpmsg(message);
return(*status);
}
(fptr->Fptr)->heapstart = jjvalue;
return(*status);
}
return(*status);
}
int ffgcprll( fitsfile *fptr,
int colnum,
LONGLONG firstrow,
LONGLONG firstelem,
LONGLONG nelem,
int writemode,
double *scale,
double *zero,
char *tform,
long *twidth,
int *tcode,
int *maxelem,
LONGLONG *startpos,
LONGLONG *elemnum,
long *incre,
LONGLONG *repeat,
LONGLONG *rowlen,
int *hdutype,
LONGLONG *tnull,
char *snull,
int *status)
{
int nulpos, rangecheck = 1, tstatus = 0;
LONGLONG datastart, endpos;
long nblock;
LONGLONG heapoffset, lrepeat, endrow, nrows, tbcol;
char message[FLEN_ERRMSG];
tcolumn *colptr;
if (fptr->HDUposition != (fptr->Fptr)->curhdu) {
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
} else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) {
if ( ffrdef(fptr, status) > 0)
return(*status);
} else if (writemode > 0) {
if (STREAM_DRIVER <= 0 || STREAM_DRIVER > 40) {
urltype2driver("stream://", &STREAM_DRIVER);
}
if ((fptr->Fptr)->driver == STREAM_DRIVER) {
if ((fptr->Fptr)->ENDpos !=
maxvalue((fptr->Fptr)->headend , (fptr->Fptr)->datastart -2880)) {
ffwend(fptr, status);
}
}
}
if (firstrow < 1)
{
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
snprintf(message,FLEN_ERRMSG, "Image group number is less than 1: %.0f",
(double) firstrow);
ffpmsg(message);
return(*status = BAD_ROW_NUM);
}
else
{
snprintf(message, FLEN_ERRMSG,"Starting row number is less than 1: %.0f",
(double) firstrow);
ffpmsg(message);
return(*status = BAD_ROW_NUM);
}
}
else if ((fptr->Fptr)->hdutype != ASCII_TBL && firstelem < 1)
{
snprintf(message, FLEN_ERRMSG,"Starting element number less than 1: %ld",
(long) firstelem);
ffpmsg(message);
return(*status = BAD_ELEM_NUM);
}
else if (nelem < 0)
{
snprintf(message, FLEN_ERRMSG,"Tried to read or write less than 0 elements: %.0f",
(double) nelem);
ffpmsg(message);
return(*status = NEG_BYTES);
}
else if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
{
snprintf(message, FLEN_ERRMSG,"Specified column number is out of range: %d",
colnum);
ffpmsg(message);
snprintf(message, FLEN_ERRMSG," There are %d columns in this table.",
(fptr->Fptr)->tfield );
ffpmsg(message);
return(*status = BAD_COL_NUM);
}
*hdutype = (fptr->Fptr)->hdutype;
*rowlen = (fptr->Fptr)->rowlength;
datastart = (fptr->Fptr)->datastart;
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
*scale = colptr->tscale;
*zero = colptr->tzero;
*tnull = colptr->tnull;
tbcol = colptr->tbcol;
*twidth = colptr->twidth;
*incre = colptr->twidth;
*tcode = colptr->tdatatype;
*repeat = colptr->trepeat;
strcpy(tform, colptr->tform);
strcpy(snull, colptr->strnull);
if (*hdutype == ASCII_TBL && snull[0] == '\0')
{
strcpy(snull, " ");
nulpos = minvalue(17, *twidth);
snull[nulpos] = '\0';
}
if (writemode == -1)
{
writemode = 0;
rangecheck = 0;
}
if (abs(*tcode) == TBIT)
{
*tcode = *tcode / TBIT * TBYTE;
*repeat = (*repeat + 7) / 8;
}
if (*hdutype == BINARY_TBL && *tcode == TSTRING) {
*repeat = *repeat / *twidth;
}
else if (*hdutype == BINARY_TBL && *tcode == -TSTRING) {
*incre = 1;
*twidth = (long) nelem;
}
if (*hdutype == ASCII_TBL)
*elemnum = 0;
else
*elemnum = firstelem - 1;
if (abs(*tcode) >= TCOMPLEX)
{
if (*tcode > 0)
*tcode = (*tcode + 1) / 2;
else
*tcode = (*tcode - 1) / 2;
*repeat = *repeat * 2;
*twidth = *twidth / 2;
*incre = *incre / 2;
}
if (abs(*tcode) == TFLOAT)
*maxelem = DBUFFSIZE / sizeof(float);
else if (abs(*tcode) == TDOUBLE)
*maxelem = DBUFFSIZE / sizeof(double);
else if (abs(*tcode) == TSTRING)
{
*maxelem = (DBUFFSIZE - 1)/ *twidth;
if (*maxelem == 0) {
snprintf(message,FLEN_ERRMSG,
"ASCII string column is too wide: %ld; max supported width is %d",
*twidth, DBUFFSIZE - 1);
ffpmsg(message);
return(*status = COL_TOO_WIDE);
}
}
else
*maxelem = DBUFFSIZE / *twidth;
*startpos = datastart + ((LONGLONG)(firstrow - 1) * *rowlen) + tbcol;
if (*hdutype == IMAGE_HDU && writemode)
{
if (*repeat < *elemnum + nelem)
*repeat = *elemnum + nelem;
}
else if (*tcode > 0)
{
if (*elemnum >= *repeat)
{
snprintf(message,FLEN_ERRMSG,
"First element to write is too large: %ld; max allowed value is %ld",
(long) ((*elemnum) + 1), (long) *repeat);
ffpmsg(message);
return(*status = BAD_ELEM_NUM);
}
endrow = ((*elemnum + nelem - 1) / *repeat) + firstrow;
if (writemode)
{
if ((endrow > (fptr->Fptr)->numrows) && (nelem > 0) )
{
if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0)
{
nrows = endrow - ((fptr->Fptr)->numrows);
if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Failed to add space for %.0f new rows in table.",
(double) nrows);
ffpmsg(message);
return(*status);
}
}
else
{
(fptr->Fptr)->heapstart +=
((LONGLONG)(endrow - (fptr->Fptr)->numrows) *
(fptr->Fptr)->rowlength );
(fptr->Fptr)->numrows = endrow;
}
}
}
else
{
if ( endrow > (fptr->Fptr)->numrows && rangecheck)
{
if (*hdutype == IMAGE_HDU)
{
if (firstrow > (fptr->Fptr)->numrows)
{
snprintf(message, FLEN_ERRMSG,
"Attempted to read from group %ld of the HDU,", (long) firstrow);
ffpmsg(message);
snprintf(message, FLEN_ERRMSG,
"however the HDU only contains %ld group(s).",
(long) ((fptr->Fptr)->numrows) );
ffpmsg(message);
}
else
{
ffpmsg("Attempt to read past end of array:");
snprintf(message, FLEN_ERRMSG,
" Image has %ld elements;", (long) *repeat);
ffpmsg(message);
snprintf(message, FLEN_ERRMSG,
" Tried to read %ld elements starting at element %ld.",
(long) nelem, (long) firstelem);
ffpmsg(message);
}
}
else
{
ffpmsg("Attempt to read past end of table:");
snprintf(message, FLEN_ERRMSG,
" Table has %.0f rows with %.0f elements per row;",
(double) ((fptr->Fptr)->numrows), (double) *repeat);
ffpmsg(message);
snprintf(message, FLEN_ERRMSG,
" Tried to read %.0f elements starting at row %.0f, element %.0f.",
(double) nelem, (double) firstrow, (double) ((*elemnum) + 1));
ffpmsg(message);
}
return(*status = BAD_ROW_NUM);
}
}
if (*repeat == 1 && nelem > 1 && writemode != 2)
{
if (*rowlen <= LONG_MAX) {
*incre = (long) *rowlen;
*repeat = nelem;
}
}
}
else
{
*tcode *= (-1);
if (writemode)
{
*repeat = nelem + *elemnum;
if ( firstrow <= (fptr->Fptr)->numrows )
{
ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, &tstatus);
if (!tstatus)
{
if (colptr->tdatatype <= -TCOMPLEX)
lrepeat = lrepeat * 2;
else if (colptr->tdatatype == -TBIT)
lrepeat = (lrepeat + 7) / 8;
if (lrepeat >= *repeat)
{
*startpos = datastart + heapoffset + (fptr->Fptr)->heapstart;
if (colptr->tdatatype <= -TCOMPLEX)
{
ffpdes(fptr, colnum, firstrow, *repeat / 2,
heapoffset, status);
}
else
{
ffpdes(fptr, colnum, firstrow, *repeat,
heapoffset, status);
}
return(*status);
}
}
}
if ( firstrow > (fptr->Fptr)->numrows)
{
nrows = firstrow - ((fptr->Fptr)->numrows);
if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Failed to add space for %.0f new rows in table.",
(double) nrows);
ffpmsg(message);
return(*status);
}
}
*startpos = datastart + (fptr->Fptr)->heapstart +
(fptr->Fptr)->heapsize;
if (colptr->tdatatype <= -TCOMPLEX)
{
ffpdes(fptr, colnum, firstrow, *repeat / 2,
(fptr->Fptr)->heapsize, status);
}
else
{
ffpdes(fptr, colnum, firstrow, *repeat, (fptr->Fptr)->heapsize,
status);
}
if ( !((fptr->Fptr)->lasthdu) )
{
endpos = datastart + (fptr->Fptr)->heapstart +
(fptr->Fptr)->heapsize + ( *repeat * (*incre));
if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1])
{
nblock = (long) (((endpos - 1 -
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] )
/ 2880) + 1);
if (ffiblk(fptr, nblock, 1, status) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Failed to extend the size of the variable length heap by %ld blocks.",
nblock);
ffpmsg(message);
return(*status);
}
}
}
(fptr->Fptr)->heapsize += ( *repeat * (*incre));
}
else
{
if ( firstrow > (fptr->Fptr)->numrows)
{
ffpmsg("Attempt to read past end of table");
snprintf(message,FLEN_ERRMSG,
" Table has %.0f rows and tried to read row %.0f.",
(double) ((fptr->Fptr)->numrows), (double) firstrow);
ffpmsg(message);
return(*status = BAD_ROW_NUM);
}
ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, status);
*repeat = lrepeat;
if (colptr->tdatatype <= -TCOMPLEX)
*repeat = *repeat * 2;
else if (colptr->tdatatype == -TBIT)
*repeat = (*repeat + 7) / 8;
if (*elemnum >= *repeat)
{
snprintf(message,FLEN_ERRMSG,
"Starting element to read in variable length column is too large: %ld",
(long) firstelem);
ffpmsg(message);
snprintf(message,FLEN_ERRMSG,
" This row only contains %ld elements", (long) *repeat);
ffpmsg(message);
return(*status = BAD_ELEM_NUM);
}
*startpos = datastart + heapoffset + (fptr->Fptr)->heapstart;
}
}
return(*status);
}
int fftheap(fitsfile *fptr,
LONGLONG *heapsz,
LONGLONG *unused,
LONGLONG *overlap,
int *valid,
int *status)
{
int jj, typecode, pixsize;
long ii, kk, theapsz, nbytes;
LONGLONG repeat, offset, tunused = 0, toverlap = 0;
char *buffer, message[FLEN_ERRMSG];
if (*status > 0)
return(*status);
if ( fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ( ffrdef(fptr, status) > 0)
return(*status);
if (valid) *valid = TRUE;
if (heapsz) *heapsz = (fptr->Fptr)->heapsize;
if (unused) *unused = 0;
if (overlap) *overlap = 0;
if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 )
return(*status);
if ((fptr->Fptr)->heapsize > LONG_MAX) {
ffpmsg("Heap is too big to test ( > 2**31 bytes). (fftheap)");
return(*status = MEMORY_ALLOCATION);
}
theapsz = (long) (fptr->Fptr)->heapsize;
buffer = calloc(1, theapsz);
if (!buffer )
{
snprintf(message,FLEN_ERRMSG,"Failed to allocate buffer to test the heap");
ffpmsg(message);
return(*status = MEMORY_ALLOCATION);
}
for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++)
{
ffgtcl(fptr, jj, &typecode, NULL, NULL, status);
if (typecode > 0)
continue;
pixsize = -typecode / 10;
for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++)
{
ffgdesll(fptr, jj, ii, &repeat, &offset, status);
if (typecode == -TBIT)
nbytes = (long) (repeat + 7) / 8;
else
nbytes = (long) repeat * pixsize;
if (offset < 0 || offset + nbytes > theapsz)
{
if (valid) *valid = FALSE;
snprintf(message,FLEN_ERRMSG,
"Descriptor in row %ld, column %d has invalid heap address",
ii, jj);
ffpmsg(message);
}
else
{
for (kk = 0; kk < nbytes; kk++)
buffer[kk + offset]++;
}
}
}
for (kk = 0; kk < theapsz; kk++)
{
if (buffer[kk] == 0)
tunused++;
else if (buffer[kk] > 1)
toverlap++;
}
if (heapsz) *heapsz = theapsz;
if (unused) *unused = tunused;
if (overlap) *overlap = toverlap;
free(buffer);
return(*status);
}
int ffcmph(fitsfile *fptr,
int *status)
{
fitsfile *tptr;
int jj, typecode, pixsize, valid;
long ii, buffsize = 10000, nblock, nbytes;
LONGLONG unused, overlap;
LONGLONG repeat, offset;
char *buffer, *tbuff, comm[FLEN_COMMENT];
char message[FLEN_ERRMSG];
LONGLONG pcount;
LONGLONG readheapstart, writeheapstart, endpos, t1heapsize, t2heapsize;
if (*status > 0)
return(*status);
fftheap(fptr, NULL, &unused, &overlap, &valid, status);
if (!valid)
return(*status = BAD_HEAP_PTR);
if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 ||
(unused == 0 && overlap == 0) || *status > 0 )
return(*status);
if (ffinit( &tptr, "mem://tempheapfile", status) )
{
snprintf(message,FLEN_ERRMSG,"Failed to create temporary file for the heap");
ffpmsg(message);
return(*status);
}
if ( ffcopy(fptr, tptr, 0, status) )
{
snprintf(message,FLEN_ERRMSG,"Failed to create copy of the heap");
ffpmsg(message);
ffclos(tptr, status);
return(*status);
}
buffer = (char *) malloc(buffsize);
if (!buffer)
{
snprintf(message,FLEN_ERRMSG,"Failed to allocate buffer to copy the heap");
ffpmsg(message);
ffclos(tptr, status);
return(*status = MEMORY_ALLOCATION);
}
readheapstart = (tptr->Fptr)->datastart + (tptr->Fptr)->heapstart;
writeheapstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart;
t1heapsize = (fptr->Fptr)->heapsize;
(fptr->Fptr)->heapsize = 0;
for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++)
{
ffgtcl(tptr, jj, &typecode, NULL, NULL, status);
if (typecode > 0)
continue;
pixsize = -typecode / 10;
for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++)
{
ffgdesll(tptr, jj, ii, &repeat, &offset, status);
if (typecode == -TBIT)
nbytes = (long) (repeat + 7) / 8;
else
nbytes = (long) repeat * pixsize;
if (nbytes > buffsize)
{
tbuff = realloc(buffer, nbytes);
if (tbuff)
{
buffer = tbuff;
buffsize = nbytes;
}
else
*status = MEMORY_ALLOCATION;
}
if ( !((fptr->Fptr)->lasthdu) )
{
endpos = writeheapstart + (fptr->Fptr)->heapsize + nbytes;
if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1])
{
nblock = (long) (((endpos - 1 -
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] )
/ 2880) + 1);
if (ffiblk(fptr, nblock, 1, status) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Failed to extend the size of the variable length heap by %ld blocks.",
nblock);
ffpmsg(message);
}
}
}
ffmbyt(tptr, readheapstart + offset, REPORT_EOF, status);
ffgbyt(tptr, nbytes, buffer, status);
ffmbyt(fptr, writeheapstart + (fptr->Fptr)->heapsize,
IGNORE_EOF, status);
ffpbyt(fptr, nbytes, buffer, status);
ffpdes(fptr, jj, ii, repeat,
(fptr->Fptr)->heapsize, status);
(fptr->Fptr)->heapsize += nbytes;
if (*status > 0)
{
free(buffer);
ffclos(tptr, status);
return(*status);
}
}
}
free(buffer);
ffclos(tptr, status);
nblock = (long) (( (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] -
(writeheapstart + (fptr->Fptr)->heapsize) ) / 2880);
if (nblock > 0)
{
t2heapsize = (fptr->Fptr)->heapsize;
(fptr->Fptr)->heapsize = t1heapsize;
ffdblk(fptr, nblock, status);
(fptr->Fptr)->heapsize = t2heapsize;
}
ffmaky(fptr, 2, status);
ffgkyjj(fptr, "PCOUNT", &pcount, comm, status);
if ((fptr->Fptr)->heapsize != pcount)
{
ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status);
}
ffrdef(fptr, status);
return(*status);
}
int ffgdes(fitsfile *fptr,
int colnum,
LONGLONG rownum,
long *length,
long *heapaddr,
int *status)
{
LONGLONG lengthjj, heapaddrjj;
if (ffgdesll(fptr, colnum, rownum, &lengthjj, &heapaddrjj, status) > 0)
return(*status);
if (length) {
if (lengthjj > LONG_MAX)
*status = NUM_OVERFLOW;
else
*length = (long) lengthjj;
}
if (heapaddr) {
if (heapaddrjj > LONG_MAX)
*status = NUM_OVERFLOW;
else
*heapaddr = (long) heapaddrjj;
}
return(*status);
}
int ffgdesll(fitsfile *fptr,
int colnum,
LONGLONG rownum,
LONGLONG *length,
LONGLONG *heapaddr,
int *status)
{
LONGLONG bytepos;
unsigned int descript4[2] = {0,0};
LONGLONG descript8[2] = {0,0};
tcolumn *colptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (colptr->tdatatype >= 0) {
*status = NOT_VARI_LEN;
return(*status);
}
bytepos = (fptr->Fptr)->datastart +
((fptr->Fptr)->rowlength * (rownum - 1)) +
colptr->tbcol;
if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P')
{
if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0)
{
if (length)
*length = (LONGLONG) descript4[0];
if (heapaddr)
*heapaddr = (LONGLONG) descript4[1];
}
}
else
{
if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0)
{
if (length)
*length = descript8[0];
if (heapaddr)
*heapaddr = descript8[1];
}
}
return(*status);
}
int ffgdess(fitsfile *fptr,
int colnum,
LONGLONG firstrow,
LONGLONG nrows,
long *length,
long *heapaddr,
int *status)
{
LONGLONG rowsize, bytepos;
long ii;
INT32BIT descript4[2] = {0,0};
LONGLONG descript8[2] = {0,0};
tcolumn *colptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (colptr->tdatatype >= 0) {
*status = NOT_VARI_LEN;
return(*status);
}
rowsize = (fptr->Fptr)->rowlength;
bytepos = (fptr->Fptr)->datastart +
(rowsize * (firstrow - 1)) +
colptr->tbcol;
if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P')
{
for (ii = 0; ii < nrows; ii++)
{
if (ffgi4b(fptr, bytepos, 2, 4, descript4, status) <= 0)
{
if (length) {
*length = (long) descript4[0];
length++;
}
if (heapaddr) {
*heapaddr = (long) descript4[1];
heapaddr++;
}
bytepos += rowsize;
}
else
return(*status);
}
}
else
{
for (ii = 0; ii < nrows; ii++)
{
if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0)
{
if (length) {
if (descript8[0] > LONG_MAX)*status = NUM_OVERFLOW;
*length = (long) descript8[0];
length++;
}
if (heapaddr) {
if (descript8[1] > LONG_MAX)*status = NUM_OVERFLOW;
*heapaddr = (long) descript8[1];
heapaddr++;
}
bytepos += rowsize;
}
else
return(*status);
}
}
return(*status);
}
int ffgdessll(fitsfile *fptr,
int colnum,
LONGLONG firstrow,
LONGLONG nrows,
LONGLONG *length,
LONGLONG *heapaddr,
int *status)
{
LONGLONG rowsize, bytepos;
long ii;
unsigned int descript4[2] = {0,0};
LONGLONG descript8[2] = {0,0};
tcolumn *colptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (colptr->tdatatype >= 0) {
*status = NOT_VARI_LEN;
return(*status);
}
rowsize = (fptr->Fptr)->rowlength;
bytepos = (fptr->Fptr)->datastart +
(rowsize * (firstrow - 1)) +
colptr->tbcol;
if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P')
{
for (ii = 0; ii < nrows; ii++)
{
if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0)
{
if (length) {
*length = (LONGLONG) descript4[0];
length++;
}
if (heapaddr) {
*heapaddr = (LONGLONG) descript4[1];
heapaddr++;
}
bytepos += rowsize;
}
else
return(*status);
}
}
else
{
for (ii = 0; ii < nrows; ii++)
{
if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0)
{
if (length) {
*length = descript8[0];
length++;
}
if (heapaddr) {
*heapaddr = descript8[1];
heapaddr++;
}
bytepos += rowsize;
}
else
return(*status);
}
}
return(*status);
}
int ffpdes(fitsfile *fptr,
int colnum,
LONGLONG rownum,
LONGLONG length,
LONGLONG heapaddr,
int *status)
{
LONGLONG bytepos;
unsigned int descript4[2];
LONGLONG descript8[2];
tcolumn *colptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
colptr = (fptr->Fptr)->tableptr;
colptr += (colnum - 1);
if (colptr->tdatatype >= 0)
*status = NOT_VARI_LEN;
bytepos = (fptr->Fptr)->datastart +
((fptr->Fptr)->rowlength * (rownum - 1)) +
colptr->tbcol;
ffmbyt(fptr, bytepos, IGNORE_EOF, status);
if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P')
{
if (length > UINT_MAX || length < 0 ||
heapaddr > UINT_MAX || heapaddr < 0) {
ffpmsg("P variable length column descriptor is out of range");
*status = NUM_OVERFLOW;
return(*status);
}
descript4[0] = (unsigned int) length;
descript4[1] = (unsigned int) heapaddr;
ffpi4b(fptr, 2, 4, (INT32BIT *) descript4, status);
}
else
{
descript8[0] = length;
descript8[1] = heapaddr;
ffpi8b(fptr, 2, 8, (long *) descript8, status);
}
return(*status);
}
int ffchdu(fitsfile *fptr,
int *status)
{
char message[FLEN_ERRMSG];
int ii, stdriver, ntilebins;
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
}
else if ((fptr->Fptr)->writemode == 1)
{
urltype2driver("stream://", &stdriver);
if (((fptr->Fptr)->driver != stdriver))
ffrdef(fptr, status);
if ((fptr->Fptr)->heapsize > 0) {
ffuptf(fptr, status);
}
ffpdfl(fptr, status);
}
if ((fptr->Fptr)->open_count == 1)
{
if ((fptr->Fptr)->tableptr)
{
free((fptr->Fptr)->tableptr);
(fptr->Fptr)->tableptr = NULL;
if ((fptr->Fptr)->tilerow) {
ntilebins =
(((fptr->Fptr)->znaxis[0] - 1) / ((fptr->Fptr)->tilesize[0])) + 1;
for (ii = 0; ii < ntilebins; ii++) {
if ((fptr->Fptr)->tiledata[ii]) {
free((fptr->Fptr)->tiledata[ii]);
}
if ((fptr->Fptr)->tilenullarray[ii]) {
free((fptr->Fptr)->tilenullarray[ii]);
}
}
free((fptr->Fptr)->tileanynull);
free((fptr->Fptr)->tiletype);
free((fptr->Fptr)->tiledatasize);
free((fptr->Fptr)->tilenullarray);
free((fptr->Fptr)->tiledata);
free((fptr->Fptr)->tilerow);
(fptr->Fptr)->tileanynull = 0;
(fptr->Fptr)->tiletype = 0;
(fptr->Fptr)->tiledatasize = 0;
(fptr->Fptr)->tilenullarray = 0;
(fptr->Fptr)->tiledata = 0;
(fptr->Fptr)->tilerow = 0;
}
}
}
if (*status > 0 && *status != NO_CLOSE_ERROR)
{
snprintf(message,FLEN_ERRMSG,
"Error while closing HDU number %d (ffchdu).", (fptr->Fptr)->curhdu);
ffpmsg(message);
}
return(*status);
}
int ffuptf(fitsfile *fptr,
int *status)
{
int ii, lenform=0;
long tflds;
LONGLONG length, addr, maxlen, naxis2, jj;
char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD];
char tform[FLEN_VALUE], newform[FLEN_VALUE], lenval[40];
char card[FLEN_CARD];
char message[FLEN_ERRMSG];
char *tmp;
ffmaky(fptr, 2, status);
ffgkyjj(fptr, "NAXIS2", &naxis2, comment, status);
ffgkyj(fptr, "TFIELDS", &tflds, comment, status);
for (ii = 1; ii <= tflds; ii++)
{
ffkeyn("TFORM", ii, keyname, status);
if (ffgkys(fptr, keyname, tform, comment, status) > 0)
{
snprintf(message,FLEN_ERRMSG,
"Error while updating variable length vector TFORMn values (ffuptf).");
ffpmsg(message);
return(*status);
}
if (tform[0] == 'P' || tform[1] == 'P' || tform[0] == 'Q' || tform[1] == 'Q')
{
maxlen = 0;
for (jj=1; jj <= naxis2; jj++)
{
ffgdesll(fptr, ii, jj, &length, &addr, status);
if (length > maxlen)
maxlen = length;
}
strcpy(newform, "'");
tmp = strchr(tform, '(');
if (tmp) *tmp = 0;
lenform = strlen(tform);
snprintf(lenval,40, "(%.0f)", (double) maxlen);
if (lenform+strlen(lenval)+2 > FLEN_VALUE-1)
{
ffpmsg("Error assembling TFORMn string (ffuptf).");
return(*status = BAD_TFORM);
}
strcat(newform, tform);
strcat(newform,lenval);
while(strlen(newform) < 9)
strcat(newform," ");
strcat(newform,"'" );
ffmkky(keyname, newform, comment, card, status);
ffmkey(fptr, card, status);
}
}
return(*status);
}
int ffrdef(fitsfile *fptr,
int *status)
{
int dummy, tstatus = 0;
LONGLONG naxis2;
LONGLONG pcount;
char card[FLEN_CARD], comm[FLEN_COMMENT], valstring[FLEN_VALUE];
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
}
else if ((fptr->Fptr)->writemode == 1)
{
if ((fptr->Fptr)->datastart != DATA_UNDEFINED)
{
if ((fptr->Fptr)->hdutype != IMAGE_HDU)
{
ffmaky(fptr, 2, status);
if (ffgkyjj(fptr, "NAXIS2", &naxis2, comm, &tstatus) > 0)
{
naxis2 = (fptr->Fptr)->numrows;
}
if ((fptr->Fptr)->numrows > naxis2
&& (fptr->Fptr)->origrows == naxis2)
{
snprintf(valstring,FLEN_VALUE, "%.0f", (double) ((fptr->Fptr)->numrows));
ffmkky("NAXIS2", valstring, comm, card, status);
ffmkey(fptr, card, status);
}
}
if ((fptr->Fptr)->heapsize > 0)
{
ffmaky(fptr, 2, status);
ffgkyjj(fptr, "PCOUNT", &pcount, comm, status);
if ((fptr->Fptr)->heapsize != pcount)
{
ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status);
}
}
}
if (ffwend(fptr, status) <= 0)
{
ffrhdu(fptr, &dummy, status);
}
}
return(*status);
}
int ffhdef(fitsfile *fptr,
int morekeys,
int *status)
{
LONGLONG delta;
if (*status > 0 || morekeys < 1)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
}
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
{
ffrdef(fptr, status);
delta = (((fptr->Fptr)->headend + (morekeys * 80)) / 2880 + 1)
* 2880 - (fptr->Fptr)->datastart;
(fptr->Fptr)->datastart += delta;
(fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] += delta;
}
return(*status);
}
int ffwend(fitsfile *fptr,
int *status)
{
int ii, tstatus;
LONGLONG endpos;
long nspace;
char blankkey[FLEN_CARD], endkey[FLEN_CARD], keyrec[FLEN_CARD] = "";
if (*status > 0)
return(*status);
endpos = (fptr->Fptr)->headend;
if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
(fptr->Fptr)->datastart = ( endpos / 2880 + 1 ) * 2880;
nspace = (long) (( (fptr->Fptr)->datastart - endpos ) / 80);
strcpy(blankkey, " ");
strcat(blankkey, " ");
strcpy(endkey, "END ");
strcat(endkey, " ");
tstatus=0;
ffmbyt(fptr, endpos, REPORT_EOF, &tstatus);
for (ii=0; ii < nspace; ii++)
{
ffgbyt(fptr, 80, keyrec, &tstatus);
if (tstatus) break;
if (strncmp(keyrec, blankkey, 80) && strncmp(keyrec, endkey, 80))
break;
}
if (ii == nspace && !tstatus)
{
endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) );
ffmbyt(fptr, endpos, REPORT_EOF, &tstatus);
ffgbyt(fptr, 80, keyrec, &tstatus);
if ( !strncmp(keyrec, endkey, 80) && !tstatus) {
(fptr->Fptr)->ENDpos = endpos;
return(*status);
}
}
endpos = (fptr->Fptr)->headend;
ffmbyt(fptr, endpos, IGNORE_EOF, status);
for (ii=0; ii < nspace; ii++)
ffpbyt(fptr, 80, blankkey, status);
endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) );
ffmbyt(fptr, endpos, REPORT_EOF, status);
ffpbyt(fptr, 80, endkey, status);
(fptr->Fptr)->ENDpos = endpos;
if (*status > 0)
ffpmsg("Error while writing END card (ffwend).");
return(*status);
}
int ffpdfl(fitsfile *fptr,
int *status)
{
char chfill, fill[2880];
LONGLONG fillstart;
int nfill, tstatus, ii;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
return(*status);
if ((fptr->Fptr)->heapstart == 0)
return(*status);
fillstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart +
(fptr->Fptr)->heapsize;
nfill = (long) ((fillstart + 2879) / 2880 * 2880 - fillstart);
if ((fptr->Fptr)->hdutype == ASCII_TBL)
chfill = 32;
else
chfill = 0;
tstatus = 0;
if (!nfill)
{
fillstart--;
nfill = 1;
ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus);
ffgbyt(fptr, nfill, fill, &tstatus);
if (tstatus == 0)
return(*status);
}
else
{
ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus);
ffgbyt(fptr, nfill, fill, &tstatus);
if (tstatus == 0)
{
for (ii = 0; ii < nfill; ii++)
{
if (fill[ii] != chfill)
break;
}
if (ii == nfill)
return(*status);
}
}
memset(fill, chfill, nfill);
ffmbyt(fptr, fillstart, IGNORE_EOF, status);
ffpbyt(fptr, nfill, fill, status);
if (*status > 0)
ffpmsg("Error writing Data Unit fill bytes (ffpdfl).");
return(*status);
}
int ffchfl( fitsfile *fptr, int *status)
{
int nblank,i,gotend;
LONGLONG endpos;
char rec[FLEN_CARD];
char *blanks=" ";
if( *status > 0 ) return (*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
endpos=(fptr->Fptr)->headend;
nblank=(long) (((fptr->Fptr)->datastart-endpos)/80);
ffmbyt(fptr,endpos,TRUE,status);
gotend=FALSE;
for(i=0;i<nblank;i++) {
ffgbyt(fptr,80,rec,status);
if( !strncmp(rec, "END ", 8) ) {
if( gotend ) {
*status=BAD_HEADER_FILL;
ffpmsg("Warning: Header fill area contains duplicate END card:");
}
gotend=TRUE;
if( strncmp( rec+8, blanks+8, 72) ) {
*status=END_JUNK;
ffpmsg(
"Warning: END keyword contains extraneous non-blank characters:");
}
} else if( gotend ) {
if( strncmp( rec, blanks, 80 ) ) {
*status=BAD_HEADER_FILL;
ffpmsg(
"Warning: Header fill area contains extraneous non-blank characters:");
}
}
if( *status > 0 ) {
rec[FLEN_CARD - 1] = '\0';
ffpmsg(rec);
return( *status );
}
}
return( *status );
}
int ffcdfl( fitsfile *fptr, int *status)
{
int nfill,i;
LONGLONG filpos;
char chfill,chbuff[2880];
if( *status > 0 ) return( *status );
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
if( (fptr->Fptr)->heapstart==0 ) return( *status );
filpos = (fptr->Fptr)->datastart
+ (fptr->Fptr)->heapstart
+ (fptr->Fptr)->heapsize;
nfill = (long) ((filpos + 2879) / 2880 * 2880 - filpos);
if( nfill == 0 ) return( *status );
ffmbyt(fptr, filpos, FALSE, status);
if( ffgbyt(fptr, nfill, chbuff, status) > 0)
{
ffpmsg("Error reading data unit fill bytes (ffcdfl).");
return( *status );
}
if( (fptr->Fptr)->hdutype==ASCII_TBL )
chfill = 32;
else
chfill = 0;
for(i=0;i<nfill;i++) {
if( chbuff[i] != chfill ) {
*status=BAD_DATA_FILL;
if( (fptr->Fptr)->hdutype==ASCII_TBL )
ffpmsg("Warning: remaining bytes following ASCII table data are not filled with blanks.");
else
ffpmsg("Warning: remaining bytes following data are not filled with zeros.");
return( *status );
}
}
return( *status );
}
int ffcrhd(fitsfile *fptr,
int *status)
{
int tstatus = 0;
LONGLONG bytepos, *ptr;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
if ((fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] )
return(*status);
while (ffmrhd(fptr, 1, 0, &tstatus) == 0);
if ((fptr->Fptr)->maxhdu == (fptr->Fptr)->MAXHDU)
{
ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart,
((fptr->Fptr)->MAXHDU + 1001) * sizeof(LONGLONG) );
if (ptr == NULL)
return (*status = MEMORY_ALLOCATION);
else {
(fptr->Fptr)->MAXHDU = (fptr->Fptr)->MAXHDU + 1000;
(fptr->Fptr)->headstart = ptr;
}
}
if (ffchdu(fptr, status) <= 0)
{
bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1];
ffmbyt(fptr, bytepos, IGNORE_EOF, status);
(fptr->Fptr)->maxhdu++;
(fptr->Fptr)->curhdu = (fptr->Fptr)->maxhdu;
fptr->HDUposition = (fptr->Fptr)->maxhdu;
(fptr->Fptr)->nextkey = bytepos;
(fptr->Fptr)->headend = bytepos;
(fptr->Fptr)->datastart = DATA_UNDEFINED;
(fptr->Fptr)->dither_seed = (fptr->Fptr)->request_dither_seed;
}
return(*status);
}
int ffdblk(fitsfile *fptr,
long nblocks,
int *status)
{
char buffer[2880];
int tstatus, ii;
LONGLONG readpos, writepos;
if (*status > 0 || nblocks <= 0)
return(*status);
tstatus = 0;
readpos = (fptr->Fptr)->datastart +
(fptr->Fptr)->heapstart +
(fptr->Fptr)->heapsize;
readpos = ((readpos + 2879) / 2880) * 2880;
writepos = readpos - ((LONGLONG)nblocks * 2880);
while ( !ffmbyt(fptr, readpos, REPORT_EOF, &tstatus) &&
!ffgbyt(fptr, 2880L, buffer, &tstatus) )
{
ffmbyt(fptr, writepos, REPORT_EOF, status);
ffpbyt(fptr, 2880L, buffer, status);
if (*status > 0)
{
ffpmsg("Error deleting FITS blocks (ffdblk)");
return(*status);
}
readpos += 2880;
writepos += 2880;
}
memset(buffer, 0, 2880);
ffmbyt(fptr, writepos, REPORT_EOF, status);
for (ii = 0; ii < nblocks; ii++)
ffpbyt(fptr, 2880L, buffer, status);
ffmbyt(fptr, writepos - 1, REPORT_EOF, status);
fftrun(fptr, writepos, status);
for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++)
(fptr->Fptr)->headstart[ii + 1] -= ((LONGLONG)nblocks * 2880);
return(*status);
}
int ffghdt(fitsfile *fptr,
int *exttype,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition == 0 && (fptr->Fptr)->headend == 0) {
*exttype = IMAGE_HDU;
}
else {
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
}
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
{
if ( ffrdef(fptr, status) > 0)
return(*status);
}
*exttype = (fptr->Fptr)->hdutype;
if ((fptr->Fptr)->compressimg)
*exttype = IMAGE_HDU;
}
return(*status);
}
int fits_is_reentrant(void)
{
#ifdef _REENTRANT
return(1);
#else
return(0);
#endif
}
int fits_is_compressed_image(fitsfile *fptr,
int *status)
{
if (*status > 0)
return(0);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
{
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
}
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
{
if ( ffrdef(fptr, status) > 0)
return(*status);
}
if ((fptr->Fptr)->compressimg)
return(1);
return(0);
}
int ffgipr(fitsfile *infptr,
int maxaxis,
int *bitpix,
int *naxis,
long *naxes,
int *status)
{
if (*status > 0)
return(*status);
if (bitpix)
fits_get_img_type(infptr, bitpix, status);
if (naxis)
fits_get_img_dim(infptr, naxis, status);
if (naxes)
fits_get_img_size(infptr, maxaxis, naxes, status);
return(*status);
}
int ffgiprll(fitsfile *infptr,
int maxaxis,
int *bitpix,
int *naxis,
LONGLONG *naxes,
int *status)
{
if (*status > 0)
return(*status);
if (bitpix)
fits_get_img_type(infptr, bitpix, status);
if (naxis)
fits_get_img_dim(infptr, naxis, status);
if (naxes)
fits_get_img_sizell(infptr, maxaxis, naxes, status);
return(*status);
}
int ffgidt( fitsfile *fptr,
int *imgtype,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
ffmaky(fptr, 1, status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status);
}
else if ((fptr->Fptr)->compressimg)
{
ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status);
}
else
{
*status = NOT_IMAGE;
}
return(*status);
}
int ffgiet( fitsfile *fptr,
int *imgtype,
int *status)
{
int tstatus;
long lngscale, lngzero = 0;
double bscale, bzero, min_val, max_val;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
ffmaky(fptr, 2, status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status);
}
else if ((fptr->Fptr)->compressimg)
{
ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status);
}
else
{
*status = NOT_IMAGE;
return(*status);
}
tstatus = 0;
ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus);
if (tstatus)
bscale = 1.0;
tstatus = 0;
ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus);
if (tstatus)
bzero = 0.0;
if (bscale == 1.0 && bzero == 0.0)
return(*status);
switch (*imgtype)
{
case BYTE_IMG:
min_val = 0.;
max_val = 255.0;
break;
case SHORT_IMG:
min_val = -32768.0;
max_val = 32767.0;
break;
case LONG_IMG:
min_val = -2147483648.0;
max_val = 2147483647.0;
break;
default:
return(*status);
}
if (bscale >= 0.) {
min_val = bzero + bscale * min_val;
max_val = bzero + bscale * max_val;
} else {
max_val = bzero + bscale * min_val;
min_val = bzero + bscale * max_val;
}
if (bzero < 2147483648.)
lngzero = (long) bzero;
lngscale = (long) bscale;
if ((bzero != 2147483648.) &&
(lngzero != bzero || lngscale != bscale)) {
if (*imgtype == BYTE_IMG || *imgtype == SHORT_IMG)
*imgtype = FLOAT_IMG;
else
*imgtype = DOUBLE_IMG;
} else if ((min_val == -128.) && (max_val == 127.)) {
*imgtype = SBYTE_IMG;
} else if ((min_val >= -32768.0) && (max_val <= 32767.0)) {
*imgtype = SHORT_IMG;
} else if ((min_val >= 0.0) && (max_val <= 65535.0)) {
*imgtype = USHORT_IMG;
} else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) {
*imgtype = LONG_IMG;
} else if ((min_val >= 0.0) && (max_val < 4294967296.0)) {
*imgtype = ULONG_IMG;
} else {
*imgtype = DOUBLE_IMG;
}
return(*status);
}
int ffgidm( fitsfile *fptr,
int *naxis ,
int *status)
{
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
*naxis = (fptr->Fptr)->imgdim;
}
else if ((fptr->Fptr)->compressimg)
{
*naxis = (fptr->Fptr)->zndim;
}
else
{
*status = NOT_IMAGE;
}
return(*status);
}
int ffgisz( fitsfile *fptr,
int nlen,
long *naxes,
int *status)
{
int ii, naxis;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
naxis = minvalue((fptr->Fptr)->imgdim, nlen);
for (ii = 0; ii < naxis; ii++)
{
naxes[ii] = (long) (fptr->Fptr)->imgnaxis[ii];
}
}
else if ((fptr->Fptr)->compressimg)
{
naxis = minvalue( (fptr->Fptr)->zndim, nlen);
for (ii = 0; ii < naxis; ii++)
{
naxes[ii] = (long) (fptr->Fptr)->znaxis[ii];
}
}
else
{
*status = NOT_IMAGE;
}
return(*status);
}
int ffgiszll( fitsfile *fptr,
int nlen,
LONGLONG *naxes,
int *status)
{
int ii, naxis;
if (*status > 0)
return(*status);
if (fptr->HDUposition != (fptr->Fptr)->curhdu)
ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
if ( ffrdef(fptr, status) > 0)
return(*status);
if ((fptr->Fptr)->hdutype == IMAGE_HDU)
{
naxis = minvalue((fptr->Fptr)->imgdim, nlen);
for (ii = 0; ii < naxis; ii++)
{
naxes[ii] = (fptr->Fptr)->imgnaxis[ii];
}
}
else if ((fptr->Fptr)->compressimg)
{
naxis = minvalue( (fptr->Fptr)->zndim, nlen);
for (ii = 0; ii < naxis; ii++)
{
naxes[ii] = (fptr->Fptr)->znaxis[ii];
}
}
else
{
*status = NOT_IMAGE;
}
return(*status);
}
int ffmahd(fitsfile *fptr,
int hdunum,
int *exttype,
int *status)
{
int moveto, tstatus;
char message[FLEN_ERRMSG];
LONGLONG *ptr;
if (*status > 0)
return(*status);
else if (hdunum < 1 )
return(*status = BAD_HDU_NUM);
else if (hdunum >= (fptr->Fptr)->MAXHDU )
{
ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart,
(hdunum + 1001) * sizeof(LONGLONG) );
if (ptr == NULL)
return (*status = MEMORY_ALLOCATION);
else {
(fptr->Fptr)->MAXHDU = hdunum + 1000;
(fptr->Fptr)->headstart = ptr;
}
}
fptr->HDUposition = (fptr->Fptr)->curhdu;
while( ((fptr->Fptr)->curhdu) + 1 != hdunum)
{
moveto = minvalue(hdunum - 1, ((fptr->Fptr)->maxhdu) + 1);
if ((fptr->Fptr)->headstart[moveto] < (fptr->Fptr)->logfilesize )
{
if (ffchdu(fptr, status) <= 0)
{
if (ffgext(fptr, moveto, exttype, status) > 0)
{
tstatus = 0;
ffrhdu(fptr, exttype, &tstatus);
}
}
}
else
*status = END_OF_FILE;
if (*status > 0)
{
if (*status != END_OF_FILE)
{
snprintf(message,FLEN_ERRMSG,
"Failed to move to HDU number %d (ffmahd).", hdunum);
ffpmsg(message);
}
return(*status);
}
}
if (exttype != NULL)
ffghdt(fptr, exttype, status);
return(*status);
}
int ffmrhd(fitsfile *fptr,
int hdumov,
int *exttype,
int *status)
{
int extnum;
if (*status > 0)
return(*status);
extnum = fptr->HDUposition + 1 + hdumov;
ffmahd(fptr, extnum, exttype, status);
return(*status);
}
int ffmnhd(fitsfile *fptr,
int exttype,
char *hduname,
int hduver,
int *status)
{
char extname[FLEN_VALUE];
int ii, hdutype, alttype, extnum, tstatus, match, exact;
int slen, putback = 0, chopped = 0;
long extver;
if (*status > 0)
return(*status);
extnum = fptr->HDUposition + 1;
if ((fptr->Fptr)->only_one) {
slen = strlen(hduname);
if (hduname[slen - 1] != '#')
putback = 1;
}
for (ii=1; 1; ii++)
{
tstatus = 0;
if (ffmahd(fptr, ii, &hdutype, &tstatus))
{
ffmahd(fptr, extnum, 0, status);
return(*status = BAD_HDU_NUM);
}
alttype = -1;
if (fits_is_compressed_image(fptr, status))
alttype = BINARY_TBL;
if (exttype == ANY_HDU || hdutype == exttype || hdutype == alttype)
{
ffmaky(fptr, 2, status);
if (ffgkys(fptr, "EXTNAME", extname, 0, &tstatus) <= 0)
{
if (putback) {
chopped = 0;
slen = strlen(extname);
if (extname[slen - 1] == '#') {
extname[slen - 1] = '\0';
chopped = 1;
}
}
ffcmps(hduname, extname, CASEINSEN, &match, &exact);
}
if (tstatus || !exact)
{
tstatus = 0;
if (ffgkys(fptr, "HDUNAME", extname, 0, &tstatus) <= 0)
{
if (putback) {
chopped = 0;
slen = strlen(extname);
if (extname[slen - 1] == '#') {
extname[slen - 1] = '\0';
chopped = 1;
}
}
ffcmps(hduname, extname, CASEINSEN, &match, &exact);
}
}
if (!tstatus && exact)
{
if (hduver)
{
if (ffgkyj(fptr, "EXTVER", &extver, 0, &tstatus) > 0)
extver = 1;
if ( (int) extver == hduver)
{
if (chopped) {
(fptr->Fptr)->only_one = 0;
}
return(*status);
}
}
else
{
if (chopped) {
(fptr->Fptr)->only_one = 0;
}
return(*status);
}
}
}
}
}
int ffthdu(fitsfile *fptr,
int *nhdu,
int *status)
{
int ii, extnum, tstatus;
if (*status > 0)
return(*status);
extnum = fptr->HDUposition + 1;
*nhdu = extnum - 1;
if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
return(*status);
tstatus = 0;
for (ii=extnum; ffmahd(fptr, ii, 0, &tstatus) <= 0; ii++)
{
*nhdu = ii;
}
ffmahd(fptr, extnum, 0, status);
return(*status);
}
int ffgext(fitsfile *fptr,
int hdunum,
int *exttype,
int *status)
{
int xcurhdu, xmaxhdu;
LONGLONG xheadend;
if (*status > 0)
return(*status);
if (ffmbyt(fptr, (fptr->Fptr)->headstart[hdunum], REPORT_EOF, status) <= 0)
{
xcurhdu = (fptr->Fptr)->curhdu;
xmaxhdu = (fptr->Fptr)->maxhdu;
xheadend = (fptr->Fptr)->headend;
(fptr->Fptr)->curhdu = hdunum;
fptr->HDUposition = hdunum;
(fptr->Fptr)->maxhdu = maxvalue((fptr->Fptr)->maxhdu, hdunum);
(fptr->Fptr)->headend = (fptr->Fptr)->logfilesize;
if (ffrhdu(fptr, exttype, status) > 0)
{
(fptr->Fptr)->curhdu = xcurhdu;
fptr->HDUposition = xcurhdu;
(fptr->Fptr)->maxhdu = xmaxhdu;
(fptr->Fptr)->headend = xheadend;
}
}
return(*status);
}
int ffiblk(fitsfile *fptr,
long nblock,
int headdata,
int *status)
{
int tstatus, savehdu, typhdu;
LONGLONG insertpt, jpoint;
long ii, nshift;
char charfill;
char buff1[2880], buff2[2880];
char *inbuff, *outbuff, *tmpbuff;
char card[FLEN_CARD];
if (*status > 0 || nblock <= 0)
return(*status);
tstatus = *status;
if (headdata == 0 || (fptr->Fptr)->hdutype == ASCII_TBL)
charfill = 32;
else
charfill = 0;
if (headdata == 0)
insertpt = (fptr->Fptr)->datastart;
else if (headdata == -1)
{
insertpt = 0;
strcpy(card, "XTENSION= 'IMAGE ' / IMAGE extension");
}
else
{
insertpt = (fptr->Fptr)->datastart +
(fptr->Fptr)->heapstart +
(fptr->Fptr)->heapsize;
insertpt = ((insertpt + 2879) / 2880) * 2880;
}
inbuff = buff1;
outbuff = buff2;
memset(outbuff, charfill, 2880);
if (nblock == 1)
{
if (headdata == -1)
ffmrec(fptr, 1, card, status);
ffmbyt(fptr, insertpt, REPORT_EOF, status);
ffgbyt(fptr, 2880, inbuff, status);
while (*status <= 0)
{
ffmbyt(fptr, insertpt, REPORT_EOF, status);
ffpbyt(fptr, 2880, outbuff, status);
if (*status > 0)
return(*status);
tmpbuff = inbuff;
inbuff = outbuff;
outbuff = tmpbuff;
insertpt += 2880;
ffmbyt(fptr, insertpt, REPORT_EOF, status);
ffgbyt(fptr, 2880, inbuff, status);
}
*status = tstatus;
ffmbyt(fptr, insertpt, IGNORE_EOF, status);
ffpbyt(fptr, 2880, outbuff, status);
}
else
{
savehdu = (fptr->Fptr)->curhdu;
tstatus = *status;
while(*status <= 0)
ffmrhd(fptr, 1, &typhdu, status);
if (*status == END_OF_FILE)
{
*status = tstatus;
}
ffmahd(fptr, savehdu + 1, &typhdu, status);
if (headdata == -1)
ffmrec(fptr, 1, card, status);
nshift = (long) (((fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - insertpt)
/ 2880);
jpoint = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - 2880;
for (ii = 0; ii < nshift; ii++)
{
if (ffmbyt(fptr, jpoint, REPORT_EOF, status) > 0)
return(*status);
ffgbyt(fptr, 2880, inbuff,status);
ffmbyt(fptr, jpoint + ((LONGLONG) nblock * 2880), IGNORE_EOF, status);
ffpbyt(fptr, 2880, inbuff, status);
jpoint -= 2880;
}
ffmbyt(fptr, insertpt, IGNORE_EOF, status);
for (ii = 0; ii < nblock; ii++)
ffpbyt(fptr, 2880, outbuff, status);
}
if (headdata == 0)
(fptr->Fptr)->datastart += ((LONGLONG) nblock * 2880);
for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++)
(fptr->Fptr)->headstart[ii + 1] += ((LONGLONG) nblock * 2880);
return(*status);
}
int ffgkcl(char *tcard)
{
char card[20], *card1, *card5;
card[0] = '\0';
strncat(card, tcard, 8);
strcat(card, " ");
ffupch(card);
card1 = card + 1;
card5 = card + 5;
if (*card == 'Z')
{
if (FSTRNCMP (card1, "IMAGE ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "CMPTYPE", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "NAME", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_CMPRS_KEY);
}
else if (FSTRNCMP (card1, "VAL", 3) == 0)
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_CMPRS_KEY);
}
else if (FSTRNCMP (card1, "TILE", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_CMPRS_KEY);
}
else if (FSTRNCMP (card1, "BITPIX ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "NAXIS", 5) == 0)
{
if ( ( *(card + 6) >= '0' && *(card + 6) <= '9' )
|| (*(card + 6) == ' ') )
return (TYP_CMPRS_KEY);
}
else if (FSTRNCMP (card1, "SCALE ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "ZERO ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "BLANK ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "SIMPLE ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "TENSION", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "EXTEND ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "BLOCKED", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "PCOUNT ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "GCOUNT ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "QUANTIZ", 7) == 0)
return (TYP_CMPRS_KEY);
else if (FSTRNCMP (card1, "DITHER0", 7) == 0)
return (TYP_CMPRS_KEY);
}
else if (*card == ' ')
{
return (TYP_COMM_KEY);
}
else if (*card == 'B')
{
if (FSTRNCMP (card1, "ITPIX ", 7) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (card1, "LOCKED ", 7) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (card1, "LANK ", 7) == 0)
return (TYP_NULL_KEY);
if (FSTRNCMP (card1, "SCALE ", 7) == 0)
return (TYP_SCAL_KEY);
if (FSTRNCMP (card1, "ZERO ", 7) == 0)
return (TYP_SCAL_KEY);
if (FSTRNCMP (card1, "UNIT ", 7) == 0)
return (TYP_UNIT_KEY);
}
else if (*card == 'C')
{
if (FSTRNCMP (card1, "OMMENT",6) == 0)
{
if (FSTRNCMP (tcard, "COMMENT and Astrophysics', volume 376, page 3",
47) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (tcard, "COMMENT FITS (Flexible Image Transport System",
47) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (tcard, "COMMENT Astrophysics Supplement Series v44/p3",
47) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (tcard, "COMMENT Contact the NASA Science Office of St",
47) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (tcard, "COMMENT FITS Definition document #100 and oth",
47) == 0)
return (TYP_STRUC_KEY);
if (*(card + 7) == ' ')
return (TYP_COMM_KEY);
else
return (TYP_USER_KEY);
}
if (FSTRNCMP (card1, "HECKSUM", 7) == 0)
return (TYP_CKSUM_KEY);
if (FSTRNCMP (card1, "ONTINUE", 7) == 0)
return (TYP_CONT_KEY);
if (FSTRNCMP (card1, "TYPE",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "UNIT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "RVAL",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "RPIX",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "ROTA",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "RDER",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "SYER",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "DELT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (*card1 == 'D')
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
}
else if (*card == 'D')
{
if (FSTRNCMP (card1, "ATASUM ", 7) == 0)
return (TYP_CKSUM_KEY);
if (FSTRNCMP (card1, "ATAMIN ", 7) == 0)
return (TYP_RANG_KEY);
if (FSTRNCMP (card1, "ATAMAX ", 7) == 0)
return (TYP_RANG_KEY);
if (FSTRNCMP (card1, "ATE-OBS", 7) == 0)
return (TYP_REFSYS_KEY); }
else if (*card == 'E')
{
if (FSTRNCMP (card1, "XTEND ", 7) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (card1, "ND ", 7) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (card1, "XTNAME ", 7) == 0)
{
if (FSTRNCMP(tcard, "EXTNAME = 'COMPRESSED_IMAGE'", 28) == 0)
return (TYP_CMPRS_KEY);
else
return (TYP_HDUID_KEY);
}
if (FSTRNCMP (card1, "XTVER ", 7) == 0)
return (TYP_HDUID_KEY);
if (FSTRNCMP (card1, "XTLEVEL", 7) == 0)
return (TYP_HDUID_KEY);
if (FSTRNCMP (card1, "QUINOX", 6) == 0)
return (TYP_REFSYS_KEY);
if (FSTRNCMP (card1, "QUI",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_REFSYS_KEY);
}
if (FSTRNCMP (card1, "POCH ", 7) == 0)
return (TYP_REFSYS_KEY);
}
else if (*card == 'G')
{
if (FSTRNCMP (card1, "COUNT ", 7) == 0)
return (TYP_STRUC_KEY);
if (FSTRNCMP (card1, "ROUPS ", 7) == 0)
return (TYP_STRUC_KEY);
}
else if (*card == 'H')
{
if (FSTRNCMP (card1, "DUNAME ", 7) == 0)
return (TYP_HDUID_KEY);
if (FSTRNCMP (card1, "DUVER ", 7) == 0)
return (TYP_HDUID_KEY);
if (FSTRNCMP (card1, "DULEVEL", 7) == 0)
return (TYP_HDUID_KEY);
if (FSTRNCMP (card1, "ISTORY",6) == 0)
{
if (*(card + 7) == ' ')
return (TYP_COMM_KEY);
else
return (TYP_USER_KEY);
}
}
else if (*card == 'L')
{
if (FSTRNCMP (card1, "ONPOLE",6) == 0)
return (TYP_WCS_KEY);
if (FSTRNCMP (card1, "ATPOLE",6) == 0)
return (TYP_WCS_KEY);
if (FSTRNCMP (card1, "ONP",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "ATP",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
}
else if (*card == 'M')
{
if (FSTRNCMP (card1, "JD-OBS ", 7) == 0)
return (TYP_REFSYS_KEY);
if (FSTRNCMP (card1, "JDOB",4) == 0)
{
if (*(card+5) >= '0' && *(card+5) <= '9')
return (TYP_REFSYS_KEY);
}
}
else if (*card == 'N')
{
if (FSTRNCMP (card1, "AXIS", 4) == 0)
{
if ((*card5 >= '0' && *card5 <= '9')
|| (*card5 == ' '))
return (TYP_STRUC_KEY);
}
}
else if (*card == 'P')
{
if (FSTRNCMP (card1, "COUNT ", 7) == 0)
return (TYP_STRUC_KEY);
if (*card1 == 'C')
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (*card1 == 'V')
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (*card1 == 'S')
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
}
else if (*card == 'R')
{
if (FSTRNCMP (card1, "ADECSYS", 7) == 0)
return (TYP_REFSYS_KEY);
if (FSTRNCMP (card1, "ADESYS", 6) == 0)
return (TYP_REFSYS_KEY);
if (FSTRNCMP (card1, "ADE",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_REFSYS_KEY);
}
}
else if (*card == 'S')
{
if (FSTRNCMP (card1, "IMPLE ", 7) == 0)
return (TYP_STRUC_KEY);
}
else if (*card == 'T')
{
if (FSTRNCMP (card1, "TYPE", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_STRUC_KEY);
}
else if (FSTRNCMP (card1, "FORM", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_STRUC_KEY);
}
else if (FSTRNCMP (card1, "BCOL", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_STRUC_KEY);
}
else if (FSTRNCMP (card1, "FIELDS ", 7) == 0)
return (TYP_STRUC_KEY);
else if (FSTRNCMP (card1, "HEAP ", 7) == 0)
return (TYP_STRUC_KEY);
else if (FSTRNCMP (card1, "NULL", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_NULL_KEY);
}
else if (FSTRNCMP (card1, "DIM", 3) == 0)
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_DIM_KEY);
}
else if (FSTRNCMP (card1, "UNIT", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_UNIT_KEY);
}
else if (FSTRNCMP (card1, "DISP", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_DISP_KEY);
}
else if (FSTRNCMP (card1, "SCAL", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_SCAL_KEY);
}
else if (FSTRNCMP (card1, "ZERO", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_SCAL_KEY);
}
else if (FSTRNCMP (card1, "LMIN", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_RANG_KEY);
}
else if (FSTRNCMP (card1, "LMAX", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_RANG_KEY);
}
else if (FSTRNCMP (card1, "DMIN", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_RANG_KEY);
}
else if (FSTRNCMP (card1, "DMAX", 4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_RANG_KEY);
}
else if (FSTRNCMP (card1, "CTYP",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CTY",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CUNI",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CUN",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRVL",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRV",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRPX",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRP",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CROT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CDLT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CDE",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRD",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CSY",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "WCS",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "C",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "P",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "V",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "S",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
}
else if (*card == 'X')
{
if (FSTRNCMP (card1, "TENSION", 7) == 0)
return (TYP_STRUC_KEY);
}
else if (*card == 'W')
{
if (FSTRNCMP (card1, "CSAXES", 6) == 0)
return (TYP_WCS_KEY);
if (FSTRNCMP (card1, "CSNAME", 6) == 0)
return (TYP_WCS_KEY);
if (FSTRNCMP (card1, "CAX", 3) == 0)
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CSN", 3) == 0)
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_WCS_KEY);
}
}
else if (*card >= '0' && *card <= '9')
{
if (*card1 == 'C')
{
if (FSTRNCMP (card1, "CTYP",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CTY",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CUNI",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CUN",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRVL",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRV",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRPX",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRP",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CROT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CDLT",4) == 0)
{
if (*card5 >= '0' && *card5 <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CDE",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CRD",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "CSY",3) == 0)
{
if (*(card+4) >= '0' && *(card+4) <= '9')
return (TYP_WCS_KEY);
}
}
else if (FSTRNCMP (card1, "V",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (FSTRNCMP (card1, "S",1) == 0)
{
if (*(card + 2) >= '0' && *(card + 2) <= '9')
return (TYP_WCS_KEY);
}
else if (*card1 >= '0' && *card1 <= '9')
{
if ( (*(card + 2) == 'P') && (*(card + 3) == 'C') )
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_WCS_KEY);
}
else if ( (*(card + 2) == 'C') && (*(card + 3) == 'D') )
{
if (*(card + 4) >= '0' && *(card + 4) <= '9')
return (TYP_WCS_KEY);
}
}
}
return (TYP_USER_KEY);
}
int ffdtyp(const char *cval,
char *dtype,
int *status)
{
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
else if (cval[0] == '\'')
*dtype = 'C';
else if (cval[0] == 'T' || cval[0] == 'F')
*dtype = 'L';
else if (cval[0] == '(')
*dtype = 'X';
else if (strchr(cval,'.'))
*dtype = 'F';
else if (strchr(cval,'E') || strchr(cval,'D') )
*dtype = 'F';
else
*dtype = 'I';
return(*status);
}
int ffinttyp(char *cval,
int *dtype,
int *negative,
int *status)
{
int ii, len;
char *p;
if (*status > 0)
return(*status);
*dtype = 0;
*negative = 0;
p = cval;
if (*p == '+') {
p++;
} else if (*p == '-') {
p++;
*negative = 1;
}
if (*p == '0') {
while (*p == '0') p++;
if (*p == 0) {
*dtype = TSBYTE;
return(*status);
}
}
len = strlen(p);
for (ii = 0; ii < len; ii++) {
if (!isdigit(*(p+ii))) {
*status = BAD_INTKEY;
return(*status);
}
}
if (len == 0) {
*status = VALUE_UNDEFINED;
} else if (len < 3) {
*dtype = TSBYTE;
} else if (len == 4) {
*dtype = TSHORT;
} else if (len > 5 && len < 10) {
*dtype = TINT;
} else if (len > 10 && len < 19) {
*dtype = TLONGLONG;
} else if (len > 20) {
*status = BAD_INTKEY;
} else {
if (!(*negative)) {
if (len == 3) {
if (strcmp(p,"127") <= 0 ) {
*dtype = TSBYTE;
} else if (strcmp(p,"255") <= 0 ) {
*dtype = TBYTE;
} else {
*dtype = TSHORT;
}
} else if (len == 5) {
if (strcmp(p,"32767") <= 0 ) {
*dtype = TSHORT;
} else if (strcmp(p,"65535") <= 0 ) {
*dtype = TUSHORT;
} else {
*dtype = TINT;
}
} else if (len == 10) {
if (strcmp(p,"2147483647") <= 0 ) {
*dtype = TINT;
} else if (strcmp(p,"4294967295") <= 0 ) {
*dtype = TUINT;
} else {
*dtype = TLONGLONG;
}
} else if (len == 19) {
if (strcmp(p,"9223372036854775807") <= 0 ) {
*dtype = TLONGLONG;
} else {
*dtype = TULONGLONG;
}
} else if (len == 20) {
if (strcmp(p,"18446744073709551615") <= 0 ) {
*dtype = TULONGLONG;
} else {
*status = BAD_INTKEY;
}
}
} else {
if (len == 3) {
if (strcmp(p,"128") <= 0 ) {
*dtype = TSBYTE;
} else {
*dtype = TSHORT;
}
} else if (len == 5) {
if (strcmp(p,"32768") <= 0 ) {
*dtype = TSHORT;
} else {
*dtype = TINT;
}
} else if (len == 10) {
if (strcmp(p,"2147483648") <= 0 ) {
*dtype = TINT;
} else {
*dtype = TLONGLONG;
}
} else if (len == 19) {
if (strcmp(p,"9223372036854775808") <= 0 ) {
*dtype = TLONGLONG;
} else {
*status = BAD_INTKEY;
}
}
}
}
return(*status);
}
int ffc2x(const char *cval,
char *dtype,
long *ival,
int *lval,
char *sval,
double *dval,
int *status)
{
ffdtyp(cval, dtype, status);
if (*dtype == 'I')
ffc2ii(cval, ival, status);
else if (*dtype == 'F')
ffc2dd(cval, dval, status);
else if (*dtype == 'L')
ffc2ll(cval, lval, status);
else
ffc2s(cval, sval, status);
return(*status);
}
int ffc2xx(const char *cval,
char *dtype,
LONGLONG *ival,
int *lval,
char *sval,
double *dval,
int *status)
{
ffdtyp(cval, dtype, status);
if (*dtype == 'I')
ffc2jj(cval, ival, status);
else if (*dtype == 'F')
ffc2dd(cval, dval, status);
else if (*dtype == 'L')
ffc2ll(cval, lval, status);
else
ffc2s(cval, sval, status);
return(*status);
}
int ffc2uxx(const char *cval,
char *dtype,
ULONGLONG *ival,
int *lval,
char *sval,
double *dval,
int *status)
{
ffdtyp(cval, dtype, status);
if (*dtype == 'I')
ffc2ujj(cval, ival, status);
else if (*dtype == 'F')
ffc2dd(cval, dval, status);
else if (*dtype == 'L')
ffc2ll(cval, lval, status);
else
ffc2s(cval, sval, status);
return(*status);
}
int ffc2i(const char *cval,
long *ival,
int *status)
{
char dtype, sval[81], msg[81];
int lval;
double dval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffc2x(cval, &dtype, ival, &lval, sval, &dval, status);
if (dtype == 'X' )
{
*status = BAD_INTKEY;
}
else if (dtype == 'C')
{
if (ffc2dd(sval, &dval, status) <= 0)
{
if (dval > (double) LONG_MAX || dval < (double) LONG_MIN)
*status = NUM_OVERFLOW;
else
*ival = (long) dval;
}
}
else if (dtype == 'F')
{
if (dval > (double) LONG_MAX || dval < (double) LONG_MIN)
*status = NUM_OVERFLOW;
else
*ival = (long) dval;
}
else if (dtype == 'L')
{
*ival = (long) lval;
}
if (*status > 0)
{
*ival = 0;
strcpy(msg,"Error in ffc2i evaluating string as an integer: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
return(*status);
}
int ffc2j(const char *cval,
LONGLONG *ival,
int *status)
{
char dtype, sval[81], msg[81];
int lval;
double dval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffc2xx(cval, &dtype, ival, &lval, sval, &dval, status);
if (dtype == 'X' )
{
*status = BAD_INTKEY;
}
else if (dtype == 'C')
{
if (ffc2dd(sval, &dval, status) <= 0)
{
if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN)
*status = NUM_OVERFLOW;
else
*ival = (LONGLONG) dval;
}
}
else if (dtype == 'F')
{
if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN)
*status = NUM_OVERFLOW;
else
*ival = (LONGLONG) dval;
}
else if (dtype == 'L')
{
*ival = (LONGLONG) lval;
}
if (*status > 0)
{
*ival = 0;
strcpy(msg,"Error in ffc2j evaluating string as a long integer: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
return(*status);
}
int ffc2uj(const char *cval,
ULONGLONG *ival,
int *status)
{
char dtype, sval[81], msg[81];
int lval;
double dval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffc2uxx(cval, &dtype, ival, &lval, sval, &dval, status);
if (dtype == 'X' )
{
*status = BAD_INTKEY;
}
else if (dtype == 'C')
{
if (ffc2dd(sval, &dval, status) <= 0)
{
if (dval > (double) DULONGLONG_MAX || dval < -0.49)
*status = NUM_OVERFLOW;
else
*ival = (ULONGLONG) dval;
}
}
else if (dtype == 'F')
{
if (dval > (double) DULONGLONG_MAX || dval < -0.49)
*status = NUM_OVERFLOW;
else
*ival = (ULONGLONG) dval;
}
else if (dtype == 'L')
{
*ival = (ULONGLONG) lval;
}
if (*status > 0)
{
*ival = 0;
strcpy(msg,"Error in ffc2j evaluating string as a long integer: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
return(*status);
}
int ffc2l(const char *cval,
int *lval,
int *status)
{
char dtype, sval[81], msg[81];
long ival;
double dval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffc2x(cval, &dtype, &ival, lval, sval, &dval, status);
if (dtype == 'C' || dtype == 'X' )
*status = BAD_LOGICALKEY;
if (*status > 0)
{
*lval = 0;
strcpy(msg,"Error in ffc2l evaluating string as a logical: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
if (dtype == 'I')
{
if (ival)
*lval = 1;
else
*lval = 0;
}
else if (dtype == 'F')
{
if (dval)
*lval = 1;
else
*lval = 0;
}
return(*status);
}
int ffc2r(const char *cval,
float *fval,
int *status)
{
char dtype, sval[81], msg[81];
int lval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffdtyp(cval, &dtype, status);
if (dtype == 'I' || dtype == 'F')
ffc2rr(cval, fval, status);
else if (dtype == 'L')
{
ffc2ll(cval, &lval, status);
*fval = (float) lval;
}
else if (dtype == 'C')
{
ffc2s(cval, sval, status);
ffc2rr(sval, fval, status);
}
else
*status = BAD_FLOATKEY;
if (*status > 0)
{
*fval = 0.;
strcpy(msg,"Error in ffc2r evaluating string as a float: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
return(*status);
}
int ffc2d(const char *cval,
double *dval,
int *status)
{
char dtype, sval[81], msg[81];
int lval;
if (*status > 0)
return(*status);
if (cval[0] == '\0')
return(*status = VALUE_UNDEFINED);
ffdtyp(cval, &dtype, status);
if (dtype == 'I' || dtype == 'F')
ffc2dd(cval, dval, status);
else if (dtype == 'L')
{
ffc2ll(cval, &lval, status);
*dval = (double) lval;
}
else if (dtype == 'C')
{
ffc2s(cval, sval, status);
ffc2dd(sval, dval, status);
}
else
*status = BAD_DOUBLEKEY;
if (*status > 0)
{
*dval = 0.;
strcpy(msg,"Error in ffc2d evaluating string as a double: ");
strncat(msg,cval,30);
ffpmsg(msg);
return(*status);
}
return(*status);
}
int ffc2ii(const char *cval,
long *ival,
int *status)
{
char *loc, msg[81];
if (*status > 0)
return(*status);
errno = 0;
*ival = 0;
*ival = strtol(cval, &loc, 10);
if (*loc != '\0' && *loc != ' ' )
*status = BAD_C2I;
if (errno == ERANGE)
{
strcpy(msg,"Range Error in ffc2ii converting string to long int: ");
strncat(msg,cval,25);
ffpmsg(msg);
*status = NUM_OVERFLOW;
errno = 0;
}
return(*status);
}
int ffc2jj(const char *cval,
LONGLONG *ival,
int *status)
{
char *loc, msg[81];
if (*status > 0)
return(*status);
errno = 0;
*ival = 0;
#if defined(_MSC_VER)
*ival = _atoi64(cval);
loc = (char *) cval;
while (*loc == ' ') loc++;
if (*loc == '-') loc++;
if (*loc == '+') loc++;
while (isdigit(*loc)) loc++;
#elif (USE_LL_SUFFIX == 1)
*ival = strtoll(cval, &loc, 10);
#else
*ival = strtol(cval, &loc, 10);
#endif
if (*loc != '\0' && *loc != ' ' )
*status = BAD_C2I;
if (errno == ERANGE)
{
strcpy(msg,"Range Error in ffc2jj converting string to longlong int: ");
strncat(msg,cval,23);
ffpmsg(msg);
*status = NUM_OVERFLOW;
errno = 0;
}
return(*status);
}
int ffc2ujj(const char *cval,
ULONGLONG *ival,
int *status)
{
char *loc, msg[81];
if (*status > 0)
return(*status);
errno = 0;
*ival = 0;
#if defined(_MSC_VER)
*ival = _atoi64(cval);
loc = (char *) cval;
while (*loc == ' ') loc++;
if (*loc == '-') loc++;
if (*loc == '+') loc++;
while (isdigit(*loc)) loc++;
#elif (USE_LL_SUFFIX == 1)
*ival = strtoull(cval, &loc, 10);
#else
*ival = strtoul(cval, &loc, 10);
#endif
if (*loc != '\0' && *loc != ' ' )
*status = BAD_C2I;
if (errno == ERANGE)
{
strcpy(msg,"Range Error in ffc2ujj converting string to unsigned longlong int: ");
strncat(msg,cval,25);
ffpmsg(msg);
*status = NUM_OVERFLOW;
errno = 0;
}
return(*status);
}
int ffc2ll(const char *cval,
int *lval,
int *status)
{
if (*status > 0)
return(*status);
if (cval[0] == 'T')
*lval = 1;
else
*lval = 0;
return(*status);
}
int ffc2s(const char *instr,
char *outstr,
int *status)
{
int jj;
size_t len, ii;
if (*status > 0)
return(*status);
if (instr[0] != '\'')
{
if (instr[0] == '\0') {
outstr[0] = '\0';
return(*status = VALUE_UNDEFINED);
} else {
strcpy(outstr, instr);
return(*status);
}
}
len = strlen(instr);
for (ii=1, jj=0; ii < len; ii++, jj++)
{
if (instr[ii] == '\'')
{
if (instr[ii+1] == '\'')
ii++;
else
break;
}
outstr[jj] = instr[ii];
}
outstr[jj] = '\0';
if (ii == len)
{
ffpmsg("This string value has no closing quote (ffc2s):");
ffpmsg(instr);
return(*status = 205);
}
for (jj--; jj >= 0; jj--)
{
if (outstr[jj] == ' ')
outstr[jj] = 0;
else
break;
}
return(*status);
}
int ffc2rr(const char *cval,
float *fval,
int *status)
{
char *loc, msg[81], tval[73];
struct lconv *lcc = 0;
static char decimalpt = 0;
short *sptr, iret;
if (*status > 0)
return(*status);
if (!decimalpt) {
lcc = localeconv();
decimalpt = *(lcc->decimal_point);
}
errno = 0;
*fval = 0.;
if (strchr(cval, 'D') || decimalpt == ',') {
if (strlen(cval) > 72)
{
strcpy(msg,"Error: Invalid string to float in ffc2rr");
ffpmsg(msg);
return (*status=BAD_C2F);
}
strcpy(tval, cval);
if ((loc = strchr(tval, 'D'))) *loc = 'E';
if (decimalpt == ',') {
if ((loc = strchr(tval, '.'))) *loc = ',';
}
*fval = (float) strtod(tval, &loc);
} else {
*fval = (float) strtod(cval, &loc);
}
if (*loc != '\0' && *loc != ' ' )
{
strcpy(msg,"Error in ffc2rr converting string to float: ");
strncat(msg,cval,30);
ffpmsg(msg);
*status = BAD_C2F;
}
sptr = (short *) fval;
#if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS
sptr++;
#endif
iret = fnan(*sptr);
if (errno == ERANGE || (iret == 1) )
{
strcpy(msg,"Error in ffc2rr converting string to float: ");
strncat(msg,cval,30);
ffpmsg(msg);
*fval = 0.;
*status = NUM_OVERFLOW;
errno = 0;
}
return(*status);
}
int ffc2dd(const char *cval,
double *dval,
int *status)
{
char *loc, msg[81], tval[73];
struct lconv *lcc = 0;
static char decimalpt = 0;
short *sptr, iret;
if (*status > 0)
return(*status);
if (!decimalpt) {
lcc = localeconv();
decimalpt = *(lcc->decimal_point);
}
errno = 0;
*dval = 0.;
if (strchr(cval, 'D') || decimalpt == ',') {
if (strlen(cval) > 72)
{
strcpy(msg,"Error: Invalid string to double in ffc2dd");
ffpmsg(msg);
return (*status=BAD_C2D);
}
strcpy(tval, cval);
if ((loc = strchr(tval, 'D'))) *loc = 'E';
if (decimalpt == ',') {
if ((loc = strchr(tval, '.'))) *loc = ',';
}
*dval = strtod(tval, &loc);
} else {
*dval = strtod(cval, &loc);
}
if (*loc != '\0' && *loc != ' ' )
{
strcpy(msg,"Error in ffc2dd converting string to double: ");
strncat(msg,cval,30);
ffpmsg(msg);
*status = BAD_C2D;
}
sptr = (short *) dval;
#if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS
sptr += 3;
#endif
iret = dnan(*sptr);
if (errno == ERANGE || (iret == 1) )
{
strcpy(msg,"Error in ffc2dd converting string to double: ");
strncat(msg,cval,30);
ffpmsg(msg);
*dval = 0.;
*status = NUM_OVERFLOW;
errno = 0;
}
return(*status);
}
int fits_strcasecmp(const char *s1, const char *s2)
{
char c1, c2;
for (;;) {
c1 = toupper( *s1 );
c2 = toupper( *s2 );
if (c1 < c2) return(-1);
if (c1 > c2) return(1);
if (c1 == 0) return(0);
s1++;
s2++;
}
}
int fits_strncasecmp(const char *s1, const char *s2, size_t n)
{
char c1, c2;
for (; n-- ;) {
c1 = toupper( *s1 );
c2 = toupper( *s2 );
if (c1 < c2) return(-1);
if (c1 > c2) return(1);
if (c1 == 0) return(0);
s1++;
s2++;
}
return(0);
}