/*===========================================================================
  Copyright (C) 1994-2009 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENT      fitsrdm.c
.LAUGUAGE   C
.AUTHOR     P.Grosbol   ESO/IPG
.KEYWORDS   FITS data matrix, decode, read
.COMMENT    read the prime data matrix of FITS file
.VERSION    1.0  1988-Dec-10 : Creation,   PJG 
.VERSION    1.1  1989-Oct-08 : Save Group parm. in table,   PJG 
.VERSION    1.2  1989-Oct-24 : Check of data to store,   PJG 
.VERSION    1.3  1990-Feb-04 : Change call-seq. for cv-routine, PJG 
.VERSION    1.4  1991-Feb-14 : Correct pointer error, PJG
.VERSION    2.0  1991-Feb-24 : Change call-seq. structures, PJG 
.VERSION    2.1  1991-Mar-23 : Compute min/max if not given, PJG
.VERSION    2.2  1993-Sep-23 : Check overflow in cut values, PJG
.VERSION    2.3  1993-Dec-02 : Update to new SC + prototypes, PJG
.VERSION    2.4  1994-May-09 : Cast variable for ANSI-C, PJG
.VERSION    2.5  1994-Jun-28 : Include UI2 as bitpix=-16, PJG
.VERSION    2.6  1994-Sep-07 : Add explicit cast for unsigned, PJG
.VERSION    2.7  1997-Jan-08 : Only warning on wrong record size, PJG

 090706		last modif
---------------------------------------------------------------------*/

#include   <stdio.h>            /* computer specific constants    */

#include   <computer.h>            /* computer specific constants    */
#include   <fitsfmt.h>             /* general data definitions       */
#include   <fitsdef.h>             /* basic FITS definitions         */
#include   <fitsextvals.h>
#include   <midas_def.h>           /* MIDAS definitions              */

#define    MXFB              2880  /* max. size of scaling buffer    */

/*

*/

#ifdef __STDC__
int fitsrdmNUL(int mfd , BFDEF * bfdef , int size , int mfdt , char fmt,
            int Midas_flag)
#else
int fitsrdmNUL(mfd,bfdef,size,mfdt,fmt,Midas_flag)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE	Read prime data matrix in FITS
.ALGORITHM	this version does the NULL check of data
.RETURN		error code - 0: OK, -1: error
---------------------------------------------------------------------*/
int       mfd;                 /* IN: MIDAS file descriptor          */
BFDEF     *bfdef;              /* IN: pointer to FITS header parm's  */
int       size;                /* IN: size of data matrix (bytes)    */
int       mfdt;                /* IN: MIDAS file desc. Groups table  */
char      fmt;                 /* IN: data format Original/Float     */
int       Midas_flag;	       /* IN: = 0, `usual' mode
                                      = 1, `internal FITS access'  */

#endif
{
register int   bf, k, ireg;
unsigned char  uc, *pb;
short          s, *ps;
unsigned short u, *pu;
int            fpf, dno, gno, pno, npix, n, fmm;
int            dn, pn, ndata, dfmt, nb, pcnt, dsf, unit[4];
int            felem, i, *pi, mnvi, mxvi;
float          *pf, cuts[2];
register double      fac, zero, *pd, mnvd, mxvd;
double         d, dreg;
PDEF           *pp;
union { 
	float    f[2*MXFB];
	double     d[MXFB];
      } buf;
union { 
	unsigned char   *b;
	char            *c;
	short           *s;
	unsigned short  *u;
	int             *i;
	float           *f;
	double          *d;
      } p;


int    ifac;


mnvi = mxvi = 0;
mnvd = mxvd = 0.0;

pno = bfdef->pcount; pcnt = 0;             /* initiate counters     */
pp = bfdef->parm;
npix = gno = 0;
bf = bfdef->bflag;
dfmt = bfdef->bitpix;
nb = (dfmt<0) ? -dfmt/8 : dfmt/8;
ndata = size/(nb*bfdef->gcount) - pno; dno = ndata;
fac = bfdef->bscale; zero = bfdef->bzero;
if ((fac > 0.999999) && (fac < 1.00001))
   ifac = 1;				/* no need to multiply with 1.0 */
else
   ifac = 0;
felem = 1;
fmm = ((bfdef->mflag != 3) && (0<size));
fpf = (bfdef->sflag || dfmt!=-32) ;
dsf = ((bfdef->sflag && dfmt!=-64) || fmt=='F') ? -32 : dfmt;

while (0<size) 
   {                 /* read all data in prime matrix  */
   if ((n=dread(&p.c,FITSLR)) != FITSLR) 	/* read next data record  */
      {			
      if (size<=n) 
	 SCTPUT("Warning: incomplete FITS record read!");
      else 
         {
         int   unit;
         char  tbuf[80];

	 SCTPUT("Error: unexpected EOF");
         switch (dfmt)
            {
            case   8 : break;
            case -16 :
            case  16 : size /= 2; break;
            case  32 : 
            case -32 : size /= 4; break;
            case -64 : size /= 8; break;
            }
	 (void) sprintf(tbuf,"%d data values still missing",size);
         SCTPUT(tbuf);
	 if (0<=mfd) SCFCLO(mfd); mfd = -1;
         (void) SCKWRI("OUTPUTI",&size,16,1,&unit);	/* save value */
	 return NOFITS;
         }
      }

   if (size<=n) 
      {
      n = size;			/* last loop */
      size = 0;
      }
   else
      size -= n;		/* decrement remaining bytes      */

   switch (dfmt) 
      {                /* convert to local data format   */
      case   8 : npix = n; break;
      case -16 :
      case  16 : npix = n/2; 
                 if (!same_comp_i2) cvi2(p.s,npix,0); break;
      case  32 : npix = n/4; 
                 if (!same_comp_i4) cvi4(p.i,npix,0); break;
      case -32 : npix = n/4; cvr4(p.f,npix,0); break;
      case -64 : npix = n/8; cvr8(p.d,npix,0); break;
      }

   do 
      {				/* scale all values if needed     */
      if (0<pno) 
         {			/* decode groups parameters       */
	 pn = (pno<npix) ? pno : npix;
	 pno -= pn; npix -= pn;
	 while (pn--) 
            {
	    switch (dfmt) 
               {
	       case   8 : d = pp->pscal * (*(p.b++)) + pp->pzero;
			  break;
               case -16 :
	       case  16 : d = pp->pscal * (*(p.s++)) + pp->pzero;
			  break;
	       case  32 : d = pp->pscal * (*(p.i++)) + pp->pzero;
			  break;
	       case -32 : d = pp->pscal * (*(p.f++)) + pp->pzero;
			  break;
	       case -64 : d = pp->pscal * (*(p.d++)) + pp->pzero;
			  break;
               }
	    pcnt++; pp++;
            if (0<=mfdt) TCEWRD(mfdt,gno+1,pcnt,&d);
	    }
         }

      if (!pno && 0<dno && npix) 
         {				/* decode data values            */
	 dn = (dno<npix) ? dno : npix;
	 dno -= dn; npix -= dn;

         if (bfdef->sflag) 
            {				/* we scale the data */
	    switch (dfmt) 
               {
	       case   8 : 
                  pf = buf.f; uc = bfdef->blank;
                  if (bf)
                     {
                     if (ifac == 0)
                        {
			for (k=0; k<dn; k++, pf++, p.b++) 
                           {
                           if (*p.b==uc) 
                              toNULLFLOAT(*pf);
                           else
			      *pf = fac*((int)(*p.b)) + zero;
                           }
                        }
                     else		/* fac = 1.0 */
                        {
			for (k=0; k<dn; k++, pf++, p.b++) 
                           {
                           if (*p.b==uc) 
                              toNULLFLOAT(*pf);
                           else
			      *pf = (int)(*p.b) + zero;
                           }
                        }
                     }
                  else
                     {
                     if (ifac == 0)
                        {
			for (k=0; k<dn; k++)
                            *pf++ = fac*((int)(*p.b++)) + zero;
                        }
		     else		/* fac = 1.0 */
			{
			for (k=0; k<dn; k++) *pf++ = (int)(*p.b++) + zero;
			}
                     }
	          break;
	       case -16 :
	       case  16 :
                  pf = buf.f; s = bfdef->blank;
                  if (bf)
                     {
                     if (ifac == 0)
                        {
                        for (k=0; k<dn; k++, pf++, p.s++) 
                           {
                           if (*p.s==s) 
                              toNULLFLOAT(*pf);
                           else
                              *pf = fac*(*p.s) + zero;
                           }
                        }
		     else
                        {
                        for (k=0; k<dn; k++, pf++, p.s++) 
                           {
                           if (*p.s==s) 
                              toNULLFLOAT(*pf);
                           else
                              *pf = *p.s + zero;
                           }
                        }
                     }
                  else
                     {
                     if (ifac == 0)
                        {
                        for (k=0; k<dn; k++)
                           *pf++ = fac*(*p.s++) + zero;
                        }
		     else
                        {
                        for (k=0; k<dn; k++) *pf++ = (*p.s++) + zero;
                        }
                     }

	          break;
       	       case  32 : 
                  pf = buf.f; i = bfdef->blank;
                  if (bf)
                     {
                     if (ifac == 0)
                        {
                        for (k=0; k<dn; k++, pf++, p.i++) 
                           {
                           if (*p.i==i) 
                              toNULLFLOAT(*pf);
                           else
                              *pf = fac*(*p.i) + zero;
                           }
			}
		     else
                        {
                        for (k=0; k<dn; k++, pf++, p.i++)
                           {
                           if (*p.i==i)
                              toNULLFLOAT(*pf);
                           else
                              *pf = (*p.i) + zero;
                           }
                        }
                     }
                  else
                     {
                     if (ifac == 0)
                        {
                        for (k=0; k<dn; k++) *pf++ = fac*(*p.i++) + zero;
                        }
                     else
                        {
                        for (k=0; k<dn; k++) *pf++ = (*p.i++) + zero;
                        }
                     }
	          break;
	       case -32 : 
                  pf = buf.f;
                  if (ifac == 0)
                     {
		     for (k=0; k<dn; k++) *pf++ = fac * (*p.f++) + zero;
		     }
		  else
                     {
		     for (k=0; k<dn; k++) *pf++ = (*p.f++) + zero;
		     }
	          break;
	       case -64 :
                  pd = buf.d;
                  if (ifac == 0)
                     {
		     for (k=0; k<dn; k++) *pd++ = fac * (*p.d++) + zero;
		     }
		  else
                     {
		     for (k=0; k<dn; k++) *pd++ = (*p.d++) + zero;
		     }
	          break;
	       }		/* end switch */

            if (Midas_flag != 0)
               {
	       if (dfmt!=-64)             /* store data in MIDAS file */
	          MyPut(-32,felem,dn,(char *) buf.f);
	       else  
                  MyPut(dfmt,felem,dn,(char *) buf.d);
               }
            else
               {
	       if (dfmt!=-64)             /* store data in MIDAS file */
	          SCFPUT(mfd,felem,dn,(char *) buf.f);
	       else
                  SCFPUT(mfd,felem,dn,(char *) buf.d);
               }
	    }

         else if (fmt=='F') 
            { 				/* we convert data to float */
	    switch (dfmt) 
               {
	       case   8 : 
                  pf = buf.f; uc = bfdef->blank;
                  if (bf)
                     {
                     for (k=0; k<dn; k++, pf++, p.b++)
                        {
                        if (*p.b==uc)
                           toNULLFLOAT(*pf);
                        else
                           *pf = *p.b;
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++) *pf++ = *p.b++;
                     }
	          break;
	       case -16 :
	       case  16 :
                  pf = buf.f; s = bfdef->blank;
                  if (bf)
                     {
                     for (k=0; k<dn; k++, pf++, p.s++)
                        {
                        if (*p.s==s)
                           toNULLFLOAT(*pf);
                        else
                           *pf = *p.s;
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++) *pf++ = *p.s++;
                     }

	          break;
	       case  32 :
                  pf = buf.f; i = bfdef->blank;
                  if (bf)
                     {
                     for (k=0; k<dn; k++, pf++, p.i++)
                        {
                        if (*p.i==i)
                           toNULLFLOAT(*pf);
                        else
                           *pf = *p.i;
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++) *pf++ = *p.i++;
                     }
	          break;
	       case -32 : 
                  if (Midas_flag != 0)
                     MyPut(dfmt,felem,dn,(char *) p.f);
                  else
                     SCFPUT(mfd,felem,dn,(char *) p.f);
		  p.f += dn;
                  break;
	       case -64 :
                  pf = buf.f;
		  for (k=0; k<dn; k++, pf++, p.d++) 
                     {
                     if (isNULLDOUBLE(*p.d)) 
                        toNULLFLOAT(*pf);
                     else 
                        *pf = *p.d;
                     }
                  break;
	       }			/* end switch */
            if (Midas_flag != 0)
               {
	       if (dfmt!=-32)             /* store data in MIDAS file */
	          MyPut(-32,felem,dn,(char *) buf.f);
               }
            else
               {
	       if (dfmt!=-32)             /* store data in MIDAS file */
	          SCFPUT(mfd,felem,dn,(char *) buf.f);
               }
	    }

         else 
            {				/* just check for NULLs */
	    switch (dfmt)
               {
	       case   8 : 
                  if (bf) 
                     { 
		     pb = p.b; uc = bfdef->blank;
		     for (k=0; k<dn; k++, pb++) if (*pb==uc) *pb = 0xFF;
		     }
                  if (Midas_flag != 0)
		     MyPut(dfmt,felem,dn,(char *) p.b);
                  else
		     SCFPUT(mfd,felem,dn,(char *) p.b);
		  p.b += dn;
                  break;
	       case -16 : 
                  pu = p.u; u = bfdef->blank; ps = p.s;
                  if (bf)
                     {
		     for (k=0; k<dn; k++, pu++, ps++) 
                        {
			if (*ps==u) 
                           toNULLSHORT(*pu);
                        else
			   *pu = *ps + 32768;
                        }
		     }
                  else
                     {
		     for (k=0; k<dn; k++) *pu++ = *ps++ + 32768;
		     }
                  if (Midas_flag != 0)
		     MyPut(dfmt,felem,dn,(char *) p.u);
                  else
		     SCFPUT(mfd,felem,dn,(char *) p.u);
		  p.u += dn;
                  break;
	       case  16 :
                  if (bf) 
                     {
		     ps = p.s; s = bfdef->blank;
		     for (k=0; k<dn; k++, ps++)
		        if (*ps==s) toNULLSHORT(*ps);
		     }
                  if (Midas_flag != 0)
                     MyPut(dfmt,felem,dn,(char *) p.s);
                  else
		     SCFPUT(mfd,felem,dn,(char *) p.s);
		  p.s += dn;
                  break;
	       case  32 : 
                  if (bf) 
                     {
		     pi = p.i; i = bfdef->blank;
		     for (k=0; k<dn; k++, pi++)
		        if (*pi==i) toNULLINT(*pi);
		     }
                  if (Midas_flag != 0)
                     MyPut(dfmt,felem,dn,(char *) p.i);
                  else
                     SCFPUT(mfd,felem,dn,(char *) p.i);
		  p.i += dn;
                  break;
	       case -32 : 
                  if (Midas_flag != 0)
                     MyPut(dfmt,felem,dn,(char *) p.f);
                  else
                     SCFPUT(mfd,felem,dn,(char *) p.f);
		  p.f += dn;
                  break;
	       case -64 : 
                  if (Midas_flag != 0)
                     MyPut(dfmt,felem,dn,(char *) p.d);
                  else
                     SCFPUT(mfd,felem,dn,(char *) p.d);
		  p.d += dn;
                  break;
	       }		/* end switch */
	    }


         /* for all 3 cases, find data min/max values if not known 
	    this means another pass over the data */

         if (fmm) 
            {    
	    switch (dsf) 
               {
	       case   8 :
                  pb = p.b - dn;
                  if (felem==1) mnvi = mxvi = *pb;
		  for (k=0; k<dn; k++)
                     {
                     ireg = (int) *pb++;
		     if (ireg != 0xFF) 
                        {
			if (ireg<mnvi) 
                              mnvi = ireg;
			else if (mxvi<ireg) 
                              mxvi = ireg;
			}
                     }
                  break;
	       case -16 : 
                  pu = p.u - dn;
                  if (felem==1) mnvi = mxvi = *pu;
		  for (k=0; k<dn; k++)
                     {
                     ireg = (int) *pu++;
		     if (!isNULLSHORT(ireg)) 
                        {
			if (ireg < mnvi)
                                  mnvi = ireg;
			else if (mxvi<ireg)
                                  mxvi = ireg;
			}
		     }
                  break;
	       case  16 : 
                  ps = p.s - dn;
                  if (felem==1) mnvi = mxvi = *ps;
		  for (k=0; k<dn; k++)
		     {
                     ireg = (int) *ps++;
		     if (!isNULLSHORT(ireg)) 
                        {
			if (ireg<mnvi) 
                           mnvi = ireg;
			else if (mxvi<ireg) 
			   mxvi = ireg;
			}
		     }
                  break;
	       case  32 : 
                  pi = p.i - dn;
                  if (felem==1) mnvi = mxvi = *pi;
		  for (k=0; k<dn; k++)
		     {
                     ireg = (int) *pi++;
		     if (!isNULLINT(ireg)) 
			{
			if (ireg<mnvi) 
			   mnvi = ireg;
			else if (mxvi<ireg) 
			   mxvi = ireg;
			}
		     }
                  break;
	       case -32 : 
                  pf = (fpf) ? buf.f : p.f - dn;
                  if (felem==1) mnvd = mxvd = *pf;
		  for (k=0; k<dn; k++)
		     {
		     dreg = (double) *pf++;
		     if (!isNULLFLOAT(dreg)) 
			{
			if (dreg<mnvd) 
			   mnvd = dreg;
			else if (mxvd<dreg) 
			   mxvd = dreg;
			}
	             }
                  break;
	       case -64 : 
                  pd = (bfdef->sflag) ? buf.d : p.d - dn;
                  if (felem==1) mnvd = mxvd = *pd;
		  for (k=0; k<dn; k++)
		     {
		     dreg = *pd++;
		     if (!isNULLDOUBLE(dreg))
			{
			if (dreg<mnvd) 
			   mnvd = dreg;
			else if (mxvd<dreg) 
			   mxvd = dreg;
			}
		     }
                  break;
	       }		/* end switch */
	    }

         felem += dn;
         if (!dno) 
            {
            gno++;
            pno = bfdef->pcount; pcnt = 0;
            pp = bfdef->parm;
            dno = ndata;
            }
         }

      } while (npix && gno<bfdef->gcount);

   }

if (fmm) 
   {                         /* save computed min/max values  */
   if (dsf > -32) 
      {				/* handle also UI2 here */
      cuts[0] = (float)mnvi; cuts[1] = (float)mxvi;
      }
   else 
      {
      if (MAXFLOAT<mnvd) 
         mnvd = MAXFLOAT;
      else if (mnvd<MINFLOAT) 
         mnvd = MINFLOAT;
      if (MAXFLOAT<mxvd) 
         mxvd = MAXFLOAT;
      else if (mxvd<MINFLOAT) 
         mxvd = MINFLOAT;
      cuts[0] = (float)mnvd; cuts[1] = (float)mxvd;
      }
    SCDWRR(mfd,"LHCUTS",cuts,3,2,unit);

   }


if (Midas_flag == 0)
   {
   if (0<=mfd) SCFCLO(mfd);                       /* close data files  */
   if (0<=mfdt) { TCSINI(mfdt); TCTCLO(mfdt); }
   mfd = -1; mfdt = -1;
   }

return 0;
}
/*

*/

#ifdef __STDC__
int fitsrdmUI2NUL(int mfd , BFDEF * bfdef , int size , int mfdt , char fmt,
            int Midas_flag)
#else
int fitsrdmUI2NUL(mfd,bfdef,size,mfdt,fmt,Midas_flag)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       Read prime unsinged short int data matrix in FITS
.RETURN        error code - 0: OK, -1: error
---------------------------------------------------------------------*/
int       mfd;                 /* IN: MIDAS file descriptor          */
BFDEF     *bfdef;              /* IN: pointer to FITS header parm's  */
int       size;                /* IN: size of data matrix (bytes)    */
int       mfdt;                /* IN: MIDAS file desc. Groups table  */
char      fmt;                 /* IN: data format Original/Float     */
int       Midas_flag;	       /* IN: = 0, `usual' mode
                                      = 1, `internal FITS access'  */

#endif
{
register int   bf, k, ireg;
short          s, *ps;
unsigned short u, *pu;
int            dno, gno, pno, npix, n, fmm;
int            dn, pn, ndata, dfmt, pcnt, dsf, unit[4];
int            ifac, felem, mnvi, mxvi;
 
float          *pf, cuts[2];
 
double         d;
register double     dreg, fac, zero, mnvd, mxvd;
 
PDEF           *pp;
union { 
	float    f[2*MXFB];
	double     d[MXFB];
      } buf;
union { 
	unsigned char   *b;
	char            *c;
	short           *s;
	unsigned short  *u;
	int             *i;
	float           *f;
	double          *d;
      } p;






/* we only come here, if bfdef->bitpix = 16 (or -16) */

mnvi = mxvi = 0;
mnvd = mxvd = 0.0;
pno = bfdef->pcount; pcnt = 0;             /* initiate counters     */
pp = bfdef->parm;
gno = 0;
bf = bfdef->bflag;
dfmt = bfdef->bitpix;
/* was: nb = (dfmt<0) ? -dfmt/8 : dfmt/8;
ndata = size/(nb*bfdef->gcount) - pno; dno = ndata; */
/* now: since nb = 2 */
ndata = size/(2*bfdef->gcount) - pno; dno = ndata;
fac = bfdef->bscale; zero = bfdef->bzero;
if ((fac > 0.999999) && (fac < 1.00001))
   ifac = 1;				/* no need to multiply with 1.0 */
else
   ifac = 0;
felem = 1;
fmm = ((bfdef->mflag != 3) && (0<size));
dsf = (bfdef->sflag || fmt=='F') ? -32 : dfmt;

/*
printf("UI2: dfmt = %d, bf = %d, fmm = %d, dsf = %d, pno = %d\n",
dfmt,bf,fmm,dsf,pno);
*/


while (0<size) 
   {                 /* read all data in prime matrix  */
   if ((n=dread(&p.c,FITSLR)) != FITSLR) 	/* read next data record  */
      {			
      if (size<=n) 
	 SCTPUT("Warning: incomplete FITS record read!");
      else 
         {
         int   unit;
         char  tbuf[80];

	 SCTPUT("Error: unexpected EOF");
         size /= 2; 
	 (void) sprintf(tbuf,"%d data values still missing",size);
         SCTPUT(tbuf);
	 if (0<=mfd) SCFCLO(mfd); mfd = -1;
         (void) SCKWRI("OUTPUTI",&size,16,1,&unit);	/* save value */
	 return NOFITS;
         }
      }

   if (size<n) n = size;
   size -= n;                     /* decrement remaining bytes      */
   npix = n/2; 
   if (!same_comp_i2) cvi2(p.s,npix,0); 

   do 
      {				/* scale all values if needed     */
      if (0<pno) 
         {			/* decode groups parameters       */
	 pn = (pno<npix) ? pno : npix;
	 pno -= pn; npix -= pn;
	 while (pn--) 
            {
	    d = pp->pscal * (*(p.s++)) + pp->pzero;
	    pcnt++; pp++;
            if (0<=mfdt) TCEWRD(mfdt,gno+1,pcnt,&d);
	    }
         }

      if (!pno && 0<dno && npix) 
         {				/* decode data values            */
	 dn = (dno<npix) ? dno : npix;
	 dno -= dn; npix -= dn;

         /* option = scale the data (unsigned int and int are equal) */
         /* format for minmax is float */

         if (bfdef->sflag) 
            {		
            pf = buf.f; s = bfdef->blank, ps = p.s;
            if (fmm)
               {			/* dsf = -32 */
               if (felem==1) mnvd = mxvd = (fac*(*ps)) + zero;
               if (bf)
                  { 
                  for (k=0; k<dn; k++, pf++, ps++)
                     {
                     if (*ps == s) 
                        toNULLFLOAT(*pf);
                     else
                        {
                        *pf = (fac * (*ps)) + zero;
                        dreg = (double) *pf;
                        if (dreg<mnvd)
                           mnvd = dreg;
                        else if (mxvd<dreg)
                           mxvd = dreg;
                        }
                     }
                  }
               else
                  {
                  if (ifac == 0)
                     {
                     for (k=0; k<dn; k++)
                        {
                        *pf = fac*(*ps++) + zero;
                        dreg = (double) *pf++;
                        if (dreg<mnvd)
                           mnvd = dreg;
                        else if (mxvd<dreg)
                           mxvd = dreg;
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++)
                        {
                        *pf = (*ps++) + zero;
                        dreg = (double) *pf++;
                        if (dreg<mnvd)
                           mnvd = dreg;
                        else if (mxvd<dreg)
                           mxvd = dreg;
                        }
                     }
                  }
               }
            else
               {
               if (bf)
                  {
                  if (ifac == 0)
                     {
                     for (k=0; k<dn; k++, pf++, ps++) 
                        {
                        if (*ps==s) 
                           toNULLFLOAT(*pf);
                        else
                           *pf = fac*(*ps) + zero;
                        }
                     }
	          else
                     {
                     for (k=0; k<dn; k++, pf++, ps++) 
                        {
                        if (*ps==s) 
                           toNULLFLOAT(*pf);
                        else
                           *pf = *ps + zero;
                        }
                     }
                  }
               else
                  {
                  if (ifac == 0)
                     {
                     for (k=0; k<dn; k++)
                           *pf++ = fac*(*ps++) + zero;
                     }
	          else
                     {
                     for (k=0; k<dn; k++) *pf++ = (*ps++) + zero;
                     }
                  }
               }

            if (Midas_flag != 0)
	       MyPut(-32,felem,dn,(char *) buf.f);
            else
	       SCFPUT(mfd,felem,dn,(char *) buf.f);
	    }

         /* option = convert data to float (unsingend int and int are equal) */
         /* format for minmax is float */

         else if (fmt=='F') 
            { 	
            pf = buf.f; s = bfdef->blank, ps = p.s;
            if (fmm)
               {                        /* dsf = -32 */
               if (felem==1) mnvd = mxvd = (float) *ps;
               if (bf)
                  {
                  for (k=0; k<dn; k++, pf++, ps++)
                     {
                     if (*ps == s)
                        toNULLFLOAT(*pf);
                     else
                        {
                        *pf = (float) *ps;
                        dreg = (double) *pf;
                        if (dreg<mnvd)
                           mnvd = dreg;
                        else if (mxvd<dreg)
                           mxvd = dreg;
                        }
                     }
                  }
               else
                  {
                  for (k=0; k<dn; k++) 
                     {
                     *pf = (float) *ps++;
                     dreg = (double) *pf++;
                     if (dreg<mnvd)
                        mnvd = dreg;
                     else if (mxvd<dreg)
                        mxvd = dreg;
                     }
                  }
               }
            else
               {
               if (bf)
                  {
                  for (k=0; k<dn; k++, pf++, ps++)
                     {
                     if (*ps==s)
                        toNULLFLOAT(*pf);
                     else
                        *pf = (float) *ps;
                     }
                  }
               else
                  {
                  for (k=0; k<dn; k++) *pf++ = (float) *ps++;
                  }
               }

            if (Midas_flag != 0)
	       MyPut(-32,felem,dn,(char *) buf.f);
	    else
               SCFPUT(mfd,felem,dn,(char *) buf.f);
	    }

         /* option = take data as is (unsigned int and int are different) */
         /* format for minmax is same as original format */

         else 
            {		
	    if (dfmt == (-16))
               {
               pu = p.u; u = bfdef->blank; ps = p.s;
               if (fmm)
                  {				/* here dsf = dfmt */
                  if (felem==1) mnvi = mxvi = *ps + 32768;
                  if (bf)
                     {
                     for (k=0; k<dn; k++, pu++)
                        {
                        ireg = (int) *ps++;
                        if (ireg == u)
                           toNULLSHORT(*pu);
                        else
                           {
                           ireg += 32768;
                           if (ireg < mnvi)
                              mnvi = ireg;
                           else if (mxvi<ireg)
                              mxvi = ireg;
                           *pu = ireg;
                           }
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++) 
                        {
                        ireg = (int) *ps++;
                        ireg += 32768;
                        if (ireg < mnvi)
                           mnvi = ireg;
                        else if (mxvi<ireg)
                           mxvi = ireg;
                        *pu++ = ireg;
                        }
                     }
                  }
               else
                  {
                  if (bf)
                     {
	             for (k=0; k<dn; k++, pu++, ps++) 
                        {
	                if (*ps == u) 
                           toNULLSHORT(*pu);
                        else
	                   *pu = *ps + 32768;
                        }
	             }
                  else
                     {
	             for (k=0; k<dn; k++) *pu++ = *ps++ + 32768;
	             }
                  }
               if (Midas_flag != 0)
	          MyPut(dfmt,felem,dn,(char *) p.u);
               else
	          SCFPUT(mfd,felem,dn,(char *) p.u);
	       }
            else		/* dfmt = 16 */
               {
	       ps = p.s; s = bfdef->blank;
               if (fmm)
                  {                          /* here dsf = dfmt */
                  if (felem==1) mnvi = mxvi = *ps;
                  if (bf)
                     {
                     for (k=0; k<dn; k++, ps++)
                        {
                        ireg = (int) *ps;
	                if (ireg == s) 
                           toNULLSHORT(*ps);
                        else
                           {
                           if (ireg<mnvi)
                              mnvi = ireg;
                           else if (mxvi<ireg)
                              mxvi = ireg;
                           }
                        }
                     }
                  else
                     {
                     for (k=0; k<dn; k++)
                        {
                        ireg = (int) *ps++;
                        if (ireg<mnvi)
                           mnvi = ireg;
                        else if (mxvi<ireg)
                           mxvi = ireg;
                        }
                     }
                  }
               else
                  {
                  if (bf) 
                     {
	             for (k=0; k<dn; k++, ps++)
                        {
	                if (*ps == s) toNULLSHORT(*ps);
                        }
	             }
                  }

               if (Midas_flag != 0)
                  MyPut(dfmt,felem,dn,(char *) p.s);
               else
                  SCFPUT(mfd,felem,dn,(char *) p.s);
	       }
	    }

         felem += dn;
         if (!dno) 
            {
            gno++;
            pno = bfdef->pcount; pcnt = 0;
            pp = bfdef->parm;
            dno = ndata;
            }
         }

      } while (npix && gno<bfdef->gcount);
   }


if (fmm) 
   {                         /* save computed min/max values  */
   if (dsf > -32) 
      {				/* handle also UI2 here */
      cuts[0] = (float)mnvi; cuts[1] = (float)mxvi;
      }
   else 
      {
      if (MAXFLOAT<mnvd) 
         mnvd = MAXFLOAT;
      else if (mnvd<MINFLOAT) 
         mnvd = MINFLOAT;
      if (MAXFLOAT<mxvd) 
         mxvd = MAXFLOAT;
      else if (mxvd<MINFLOAT) 
         mxvd = MINFLOAT;
      cuts[0] = (float)mnvd; cuts[1] = (float)mxvd;
      }
    SCDWRR(mfd,"LHCUTS",cuts,3,2,unit);

   }


if (Midas_flag == 0)
   {
   if (0<=mfd) SCFCLO(mfd);                       /* close data files  */
   if (0<=mfdt) { TCSINI(mfdt); TCTCLO(mfdt); }
   mfd = -1; mfdt = -1;
   }

return 0;
}


