1
/*===========================================================================
2
Copyright (C) 1994-2009 European Southern Observatory (ESO)
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; either version 2 of
7
the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public
15
License along with this program; if not, write to the Free
16
Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
19
Correspondence concerning ESO-MIDAS should be addressed as follows:
20
Internet e-mail: midas@eso.org
21
Postal address: European Southern Observatory
22
Data Management Division
23
Karl-Schwarzschild-Strasse 2
24
D 85748 Garching bei Muenchen
26
===========================================================================*/
28
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
.AUTHOR P.Grosbol ESO/IPG
32
.KEYWORDS FITS data matrix, decode, read
33
.COMMENT read the prime data matrix of FITS file
34
.VERSION 1.0 1988-Dec-10 : Creation, PJG
35
.VERSION 1.1 1989-Oct-08 : Save Group parm. in table, PJG
36
.VERSION 1.2 1989-Oct-24 : Check of data to store, PJG
37
.VERSION 1.3 1990-Feb-04 : Change call-seq. for cv-routine, PJG
38
.VERSION 1.4 1991-Feb-14 : Correct pointer error, PJG
39
.VERSION 2.0 1991-Feb-24 : Change call-seq. structures, PJG
40
.VERSION 2.1 1991-Mar-23 : Compute min/max if not given, PJG
41
.VERSION 2.2 1993-Sep-23 : Check overflow in cut values, PJG
42
.VERSION 2.3 1993-Dec-02 : Update to new SC + prototypes, PJG
43
.VERSION 2.4 1994-May-09 : Cast variable for ANSI-C, PJG
44
.VERSION 2.5 1994-Jun-28 : Include UI2 as bitpix=-16, PJG
45
.VERSION 2.6 1994-Sep-07 : Add explicit cast for unsigned, PJG
46
.VERSION 2.7 1997-Jan-08 : Only warning on wrong record size, PJG
49
---------------------------------------------------------------------*/
51
#include <stdio.h> /* computer specific constants */
53
#include <computer.h> /* computer specific constants */
54
#include <fitsfmt.h> /* general data definitions */
55
#include <fitsdef.h> /* basic FITS definitions */
56
#include <fitsextvals.h>
57
#include <midas_def.h> /* MIDAS definitions */
59
#define MXFB 2880 /* max. size of scaling buffer */
66
int fitsrdmNUL(int mfd , BFDEF * bfdef , int size , int mfdt , char fmt,
69
int fitsrdmNUL(mfd,bfdef,size,mfdt,fmt,Midas_flag)
70
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
71
.PURPOSE Read prime data matrix in FITS
72
.ALGORITHM this version does the NULL check of data
73
.RETURN error code - 0: OK, -1: error
74
---------------------------------------------------------------------*/
75
int mfd; /* IN: MIDAS file descriptor */
76
BFDEF *bfdef; /* IN: pointer to FITS header parm's */
77
int size; /* IN: size of data matrix (bytes) */
78
int mfdt; /* IN: MIDAS file desc. Groups table */
79
char fmt; /* IN: data format Original/Float */
80
int Midas_flag; /* IN: = 0, `usual' mode
81
= 1, `internal FITS access' */
85
register int bf, k, ireg;
86
unsigned char uc, *pb;
88
unsigned short u, *pu;
89
int fpf, dno, gno, pno, npix, n, fmm;
90
int dn, pn, ndata, dfmt, nb, pcnt, dsf, unit[4];
91
int felem, i, *pi, mnvi, mxvi;
93
register double fac, zero, *pd, mnvd, mxvd;
117
pno = bfdef->pcount; pcnt = 0; /* initiate counters */
121
dfmt = bfdef->bitpix;
122
nb = (dfmt<0) ? -dfmt/8 : dfmt/8;
123
ndata = size/(nb*bfdef->gcount) - pno; dno = ndata;
124
fac = bfdef->bscale; zero = bfdef->bzero;
125
if ((fac > 0.999999) && (fac < 1.00001))
126
ifac = 1; /* no need to multiply with 1.0 */
130
fmm = ((bfdef->mflag != 3) && (0<size));
131
fpf = (bfdef->sflag || dfmt!=-32) ;
132
dsf = ((bfdef->sflag && dfmt!=-64) || fmt=='F') ? -32 : dfmt;
135
{ /* read all data in prime matrix */
136
if ((n=dread(&p.c,FITSLR)) != FITSLR) /* read next data record */
139
SCTPUT("Warning: incomplete FITS record read!");
145
SCTPUT("Error: unexpected EOF");
150
case 16 : size /= 2; break;
152
case -32 : size /= 4; break;
153
case -64 : size /= 8; break;
155
(void) sprintf(tbuf,"%d data values still missing",size);
157
if (0<=mfd) SCFCLO(mfd); mfd = -1;
158
(void) SCKWRI("OUTPUTI",&size,16,1,&unit); /* save value */
165
n = size; /* last loop */
169
size -= n; /* decrement remaining bytes */
172
{ /* convert to local data format */
173
case 8 : npix = n; break;
175
case 16 : npix = n/2;
176
if (!same_comp_i2) cvi2(p.s,npix,0); break;
177
case 32 : npix = n/4;
178
if (!same_comp_i4) cvi4(p.i,npix,0); break;
179
case -32 : npix = n/4; cvr4(p.f,npix,0); break;
180
case -64 : npix = n/8; cvr8(p.d,npix,0); break;
184
{ /* scale all values if needed */
186
{ /* decode groups parameters */
187
pn = (pno<npix) ? pno : npix;
188
pno -= pn; npix -= pn;
193
case 8 : d = pp->pscal * (*(p.b++)) + pp->pzero;
196
case 16 : d = pp->pscal * (*(p.s++)) + pp->pzero;
198
case 32 : d = pp->pscal * (*(p.i++)) + pp->pzero;
200
case -32 : d = pp->pscal * (*(p.f++)) + pp->pzero;
202
case -64 : d = pp->pscal * (*(p.d++)) + pp->pzero;
206
if (0<=mfdt) TCEWRD(mfdt,gno+1,pcnt,&d);
210
if (!pno && 0<dno && npix)
211
{ /* decode data values */
212
dn = (dno<npix) ? dno : npix;
213
dno -= dn; npix -= dn;
216
{ /* we scale the data */
220
pf = buf.f; uc = bfdef->blank;
225
for (k=0; k<dn; k++, pf++, p.b++)
230
*pf = fac*((int)(*p.b)) + zero;
235
for (k=0; k<dn; k++, pf++, p.b++)
240
*pf = (int)(*p.b) + zero;
249
*pf++ = fac*((int)(*p.b++)) + zero;
253
for (k=0; k<dn; k++) *pf++ = (int)(*p.b++) + zero;
259
pf = buf.f; s = bfdef->blank;
264
for (k=0; k<dn; k++, pf++, p.s++)
269
*pf = fac*(*p.s) + zero;
274
for (k=0; k<dn; k++, pf++, p.s++)
288
*pf++ = fac*(*p.s++) + zero;
292
for (k=0; k<dn; k++) *pf++ = (*p.s++) + zero;
298
pf = buf.f; i = bfdef->blank;
303
for (k=0; k<dn; k++, pf++, p.i++)
308
*pf = fac*(*p.i) + zero;
313
for (k=0; k<dn; k++, pf++, p.i++)
326
for (k=0; k<dn; k++) *pf++ = fac*(*p.i++) + zero;
330
for (k=0; k<dn; k++) *pf++ = (*p.i++) + zero;
338
for (k=0; k<dn; k++) *pf++ = fac * (*p.f++) + zero;
342
for (k=0; k<dn; k++) *pf++ = (*p.f++) + zero;
349
for (k=0; k<dn; k++) *pd++ = fac * (*p.d++) + zero;
353
for (k=0; k<dn; k++) *pd++ = (*p.d++) + zero;
360
if (dfmt!=-64) /* store data in MIDAS file */
361
MyPut(-32,felem,dn,(char *) buf.f);
363
MyPut(dfmt,felem,dn,(char *) buf.d);
367
if (dfmt!=-64) /* store data in MIDAS file */
368
SCFPUT(mfd,felem,dn,(char *) buf.f);
370
SCFPUT(mfd,felem,dn,(char *) buf.d);
375
{ /* we convert data to float */
379
pf = buf.f; uc = bfdef->blank;
382
for (k=0; k<dn; k++, pf++, p.b++)
392
for (k=0; k<dn; k++) *pf++ = *p.b++;
397
pf = buf.f; s = bfdef->blank;
400
for (k=0; k<dn; k++, pf++, p.s++)
410
for (k=0; k<dn; k++) *pf++ = *p.s++;
415
pf = buf.f; i = bfdef->blank;
418
for (k=0; k<dn; k++, pf++, p.i++)
428
for (k=0; k<dn; k++) *pf++ = *p.i++;
433
MyPut(dfmt,felem,dn,(char *) p.f);
435
SCFPUT(mfd,felem,dn,(char *) p.f);
440
for (k=0; k<dn; k++, pf++, p.d++)
442
if (isNULLDOUBLE(*p.d))
451
if (dfmt!=-32) /* store data in MIDAS file */
452
MyPut(-32,felem,dn,(char *) buf.f);
456
if (dfmt!=-32) /* store data in MIDAS file */
457
SCFPUT(mfd,felem,dn,(char *) buf.f);
462
{ /* just check for NULLs */
468
pb = p.b; uc = bfdef->blank;
469
for (k=0; k<dn; k++, pb++) if (*pb==uc) *pb = 0xFF;
472
MyPut(dfmt,felem,dn,(char *) p.b);
474
SCFPUT(mfd,felem,dn,(char *) p.b);
478
pu = p.u; u = bfdef->blank; ps = p.s;
481
for (k=0; k<dn; k++, pu++, ps++)
491
for (k=0; k<dn; k++) *pu++ = *ps++ + 32768;
494
MyPut(dfmt,felem,dn,(char *) p.u);
496
SCFPUT(mfd,felem,dn,(char *) p.u);
502
ps = p.s; s = bfdef->blank;
503
for (k=0; k<dn; k++, ps++)
504
if (*ps==s) toNULLSHORT(*ps);
507
MyPut(dfmt,felem,dn,(char *) p.s);
509
SCFPUT(mfd,felem,dn,(char *) p.s);
515
pi = p.i; i = bfdef->blank;
516
for (k=0; k<dn; k++, pi++)
517
if (*pi==i) toNULLINT(*pi);
520
MyPut(dfmt,felem,dn,(char *) p.i);
522
SCFPUT(mfd,felem,dn,(char *) p.i);
527
MyPut(dfmt,felem,dn,(char *) p.f);
529
SCFPUT(mfd,felem,dn,(char *) p.f);
534
MyPut(dfmt,felem,dn,(char *) p.d);
536
SCFPUT(mfd,felem,dn,(char *) p.d);
543
/* for all 3 cases, find data min/max values if not known
544
this means another pass over the data */
552
if (felem==1) mnvi = mxvi = *pb;
567
if (felem==1) mnvi = mxvi = *pu;
571
if (!isNULLSHORT(ireg))
582
if (felem==1) mnvi = mxvi = *ps;
586
if (!isNULLSHORT(ireg))
597
if (felem==1) mnvi = mxvi = *pi;
601
if (!isNULLINT(ireg))
611
pf = (fpf) ? buf.f : p.f - dn;
612
if (felem==1) mnvd = mxvd = *pf;
615
dreg = (double) *pf++;
616
if (!isNULLFLOAT(dreg))
626
pd = (bfdef->sflag) ? buf.d : p.d - dn;
627
if (felem==1) mnvd = mxvd = *pd;
631
if (!isNULLDOUBLE(dreg))
647
pno = bfdef->pcount; pcnt = 0;
653
} while (npix && gno<bfdef->gcount);
658
{ /* save computed min/max values */
660
{ /* handle also UI2 here */
661
cuts[0] = (float)mnvi; cuts[1] = (float)mxvi;
667
else if (mnvd<MINFLOAT)
671
else if (mxvd<MINFLOAT)
673
cuts[0] = (float)mnvd; cuts[1] = (float)mxvd;
675
SCDWRR(mfd,"LHCUTS",cuts,3,2,unit);
682
if (0<=mfd) SCFCLO(mfd); /* close data files */
683
if (0<=mfdt) { TCSINI(mfdt); TCTCLO(mfdt); }
694
int fitsrdmUI2NUL(int mfd , BFDEF * bfdef , int size , int mfdt , char fmt,
697
int fitsrdmUI2NUL(mfd,bfdef,size,mfdt,fmt,Midas_flag)
698
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
699
.PURPOSE Read prime unsinged short int data matrix in FITS
700
.RETURN error code - 0: OK, -1: error
701
---------------------------------------------------------------------*/
702
int mfd; /* IN: MIDAS file descriptor */
703
BFDEF *bfdef; /* IN: pointer to FITS header parm's */
704
int size; /* IN: size of data matrix (bytes) */
705
int mfdt; /* IN: MIDAS file desc. Groups table */
706
char fmt; /* IN: data format Original/Float */
707
int Midas_flag; /* IN: = 0, `usual' mode
708
= 1, `internal FITS access' */
712
register int bf, k, ireg;
714
unsigned short u, *pu;
715
int dno, gno, pno, npix, n, fmm;
716
int dn, pn, ndata, dfmt, pcnt, dsf, unit[4];
717
int ifac, felem, mnvi, mxvi;
722
register double dreg, fac, zero, mnvd, mxvd;
744
/* we only come here, if bfdef->bitpix = 16 (or -16) */
748
pno = bfdef->pcount; pcnt = 0; /* initiate counters */
752
dfmt = bfdef->bitpix;
753
/* was: nb = (dfmt<0) ? -dfmt/8 : dfmt/8;
754
ndata = size/(nb*bfdef->gcount) - pno; dno = ndata; */
755
/* now: since nb = 2 */
756
ndata = size/(2*bfdef->gcount) - pno; dno = ndata;
757
fac = bfdef->bscale; zero = bfdef->bzero;
758
if ((fac > 0.999999) && (fac < 1.00001))
759
ifac = 1; /* no need to multiply with 1.0 */
763
fmm = ((bfdef->mflag != 3) && (0<size));
764
dsf = (bfdef->sflag || fmt=='F') ? -32 : dfmt;
767
printf("UI2: dfmt = %d, bf = %d, fmm = %d, dsf = %d, pno = %d\n",
768
dfmt,bf,fmm,dsf,pno);
773
{ /* read all data in prime matrix */
774
if ((n=dread(&p.c,FITSLR)) != FITSLR) /* read next data record */
777
SCTPUT("Warning: incomplete FITS record read!");
783
SCTPUT("Error: unexpected EOF");
785
(void) sprintf(tbuf,"%d data values still missing",size);
787
if (0<=mfd) SCFCLO(mfd); mfd = -1;
788
(void) SCKWRI("OUTPUTI",&size,16,1,&unit); /* save value */
793
if (size<n) n = size;
794
size -= n; /* decrement remaining bytes */
796
if (!same_comp_i2) cvi2(p.s,npix,0);
799
{ /* scale all values if needed */
801
{ /* decode groups parameters */
802
pn = (pno<npix) ? pno : npix;
803
pno -= pn; npix -= pn;
806
d = pp->pscal * (*(p.s++)) + pp->pzero;
808
if (0<=mfdt) TCEWRD(mfdt,gno+1,pcnt,&d);
812
if (!pno && 0<dno && npix)
813
{ /* decode data values */
814
dn = (dno<npix) ? dno : npix;
815
dno -= dn; npix -= dn;
817
/* option = scale the data (unsigned int and int are equal) */
818
/* format for minmax is float */
822
pf = buf.f; s = bfdef->blank, ps = p.s;
825
if (felem==1) mnvd = mxvd = (fac*(*ps)) + zero;
828
for (k=0; k<dn; k++, pf++, ps++)
834
*pf = (fac * (*ps)) + zero;
849
*pf = fac*(*ps++) + zero;
850
dreg = (double) *pf++;
861
*pf = (*ps++) + zero;
862
dreg = (double) *pf++;
877
for (k=0; k<dn; k++, pf++, ps++)
882
*pf = fac*(*ps) + zero;
887
for (k=0; k<dn; k++, pf++, ps++)
901
*pf++ = fac*(*ps++) + zero;
905
for (k=0; k<dn; k++) *pf++ = (*ps++) + zero;
911
MyPut(-32,felem,dn,(char *) buf.f);
913
SCFPUT(mfd,felem,dn,(char *) buf.f);
916
/* option = convert data to float (unsingend int and int are equal) */
917
/* format for minmax is float */
921
pf = buf.f; s = bfdef->blank, ps = p.s;
924
if (felem==1) mnvd = mxvd = (float) *ps;
927
for (k=0; k<dn; k++, pf++, ps++)
947
dreg = (double) *pf++;
959
for (k=0; k<dn; k++, pf++, ps++)
969
for (k=0; k<dn; k++) *pf++ = (float) *ps++;
974
MyPut(-32,felem,dn,(char *) buf.f);
976
SCFPUT(mfd,felem,dn,(char *) buf.f);
979
/* option = take data as is (unsigned int and int are different) */
980
/* format for minmax is same as original format */
986
pu = p.u; u = bfdef->blank; ps = p.s;
988
{ /* here dsf = dfmt */
989
if (felem==1) mnvi = mxvi = *ps + 32768;
992
for (k=0; k<dn; k++, pu++)
1010
for (k=0; k<dn; k++)
1026
for (k=0; k<dn; k++, pu++, ps++)
1036
for (k=0; k<dn; k++) *pu++ = *ps++ + 32768;
1039
if (Midas_flag != 0)
1040
MyPut(dfmt,felem,dn,(char *) p.u);
1042
SCFPUT(mfd,felem,dn,(char *) p.u);
1044
else /* dfmt = 16 */
1046
ps = p.s; s = bfdef->blank;
1048
{ /* here dsf = dfmt */
1049
if (felem==1) mnvi = mxvi = *ps;
1052
for (k=0; k<dn; k++, ps++)
1068
for (k=0; k<dn; k++)
1082
for (k=0; k<dn; k++, ps++)
1084
if (*ps == s) toNULLSHORT(*ps);
1089
if (Midas_flag != 0)
1090
MyPut(dfmt,felem,dn,(char *) p.s);
1092
SCFPUT(mfd,felem,dn,(char *) p.s);
1100
pno = bfdef->pcount; pcnt = 0;
1106
} while (npix && gno<bfdef->gcount);
1111
{ /* save computed min/max values */
1113
{ /* handle also UI2 here */
1114
cuts[0] = (float)mnvi; cuts[1] = (float)mxvi;
1120
else if (mnvd<MINFLOAT)
1124
else if (mxvd<MINFLOAT)
1126
cuts[0] = (float)mnvd; cuts[1] = (float)mxvd;
1128
SCDWRR(mfd,"LHCUTS",cuts,3,2,unit);
1133
if (Midas_flag == 0)
1135
if (0<=mfd) SCFCLO(mfd); /* close data files */
1136
if (0<=mfdt) { TCSINI(mfdt); TCTCLO(mfdt); }
1137
mfd = -1; mfdt = -1;