/* @(#)tz0.c 17.1.1.1 (ES0-DMD) 01/25/02 17:36:45 */ /*=========================================================================== Copyright (C) 1995 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 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding 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 ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME tz0.c .LANGUAGE C .AUTHOR J.D.Ponz IPG-ESO Garching, Francois Ochsenbein .CATEGORY table interface (Design 2.0) low level routines. .COMMENTS This module contains the lower level routines handling tables for NULL values. Note that the choice of NULL value for floating-point numbers is badly chosen as the maximal value for non-IEEE format, for compatibility with previous VAX definitions. The ~0 (i.e. all bits set) would have been a better choice, but... .VERSION 3.0 01-Jul-1990 Extracted from tz2 .VERSION 3.1 19-Dec-1990: toNULL set ALL values to NULL. .VERSION 3.2 27-Feb-1991: Added TBL_cv2 (Convert between data types) .VERSION 3.3 22-Sep-1992: treats correctly NULL values (i.e convex) ------------------------------------------------------------*/ #include /* General MIDAS Symbols */ #include /* Local computer definitions */ #include /* Table System parameters */ #include /* Include definition NINT */ /*======================================================================= * Test for a null value (may depend on the version...) *=======================================================================*/ int TBL_isNULL (dtype, x) /*+++++++ .PURPOSE Check a SINGLE value is null .RETURNS 1 (isNULL) / 0 (is NOT null) -------*/ int dtype; /* IN: Table specific datatype */ int *x; /* IN: Value to test */ { int isnull; switch(TBL_ElementType(dtype)) { case TBL_D_A1: isnull = *(char *)x == 0; break; case TBL_D_A2: isnull = *(short *)x == 0; break; case TBL_D_A4: isnull = *x == 0; break; case TBL_D_I1: isnull = isNULL1(x); break; case TBL_D_I2: isnull = isNULL2(x); break; case TBL_D_I4: isnull = isNULL4(x); break; case TBL_D_R4: isnull = isNULLF(x); break; case TBL_D_R8: isnull = isNULLD(x); break; default : isnull = 0; break; } return (isnull); } /*======================================================================= * Set a null value (may depend on the version...) *=======================================================================*/ int TBL_toNULL (dtype, x) /*+++++++ .PURPOSE Writes NULL values. .RETURNS Number of bytes modified. -------*/ int dtype; /* IN: Table specific datatype */ char *x; /* OUT: where to set the NULL value */ { int etype, esize, items, bytes; char *p; etype = TBL_ElementType(dtype); items = TBL_Items(dtype); esize = 1 << (etype & 3); /* Element Size */ bytes = esize * items; switch(etype) { case TBL_D_A1: case TBL_D_A2: case TBL_D_A4: oscfill(x, bytes, 0); break; case TBL_D_I1: oscfill(x, bytes, NULL1); break; case TBL_D_I2: for (p = x; --items >= 0; p += esize) toNULL2(p); break; case TBL_D_I4: for (p = x; --items >= 0; p += esize) toNULL4(p); break; case TBL_D_R4: for (p = x; --items >= 0; p += esize) toNULLF(p); break; case TBL_D_R8: for (p = x; --items >= 0; p += esize) toNULLD(p); break; } return (bytes); } /*=======================================================================*/ int TBL_cv2(x1, dtyp1, x2, dtyp2) /*+++++++ .PURPOSE Convert vector of datatype1 into datatype2 .RETURNS Status as number of overflows, i.e. number of values that are out of range .REMARKS Lengths are assumed to be identical (actually taken from dtyp1) -------*/ char *x1; /* IN: Input values to convert */ int dtyp1; /* IN: Table specific datatype of input array */ char *x2; /* OUT: Output values (converted) */ int dtyp2; /* IN: Table specific datatype of output array */ { int blen1, blen2, etyp1, etyp2, items, k, isnull, over; int aLong, *pLong; double aReal; etyp1 = TBL_ElementType(dtyp1); etyp2 = TBL_ElementType(dtyp2); blen1 = 1 << (etyp1 & 3); blen2 = 1 << (etyp2 & 3); items = dtyp1 & TBL_D_MASK; over = 0; /* Number of Overflows */ /* k set to 0=I4, 1=double */ for (; --items >= 0; x1 += blen1, x2 += blen2) { isnull = 0; switch(etyp1) { case TBL_D_A1: aLong = *(unsigned char *)x1; k = 0; isnull = 0; break; case TBL_D_A2: aLong = *(unsigned short *)x1; k = 0; isnull = 0; break; case TBL_D_A4: aReal = *(unsigned int *)x1; k = 1; isnull = 0; break; case TBL_D_I1: isnull = isNULL1(x1); k = 0; if (!isnull) aLong = *x1; break; case TBL_D_I2: isnull = isNULL2(x1); k = 0; if (!isnull) aLong = *(short *)x1; break; case TBL_D_I4: isnull = isNULL4(x1); k = 0; if (!isnull) aLong = *(int *)x1; break; case TBL_D_R4: isnull = isNULLF(x1); k = 1; if (!isnull) aReal = *(float *)x1; break; case TBL_D_R8: isnull = isNULLD(x1); k = 1; if (!isnull) aReal = *(double *)x1; break; } if (isnull) switch(etyp2) { case TBL_D_A1: *x2 = 0; break; case TBL_D_A2: *(short *)x2 = 0; break; case TBL_D_A4: *(int *)x2 = 0; break; case TBL_D_I1: toNULL1(x2); break; case TBL_D_I2: toNULL2(x2); break; case TBL_D_I4: toNULL4(x2); break; case TBL_D_R4: toNULLF(x2); break; case TBL_D_R8: toNULLD(x2); break; } else if (k) switch(etyp2) { /* From aReal */ case TBL_D_A1: if ((aReal < 0) || (aReal > 0xff)) *(char *)x2 = 0xff, over++; else *x2 = NINT(aReal); break; case TBL_D_A2: if ((aReal < 0) || (aReal > 0xffff)) *(short *)x2 = 0xffff, over++; else *(unsigned short*)x2 = NINT(aReal); break; case TBL_D_A4: if ((aReal < 0) || (aReal > (unsigned)0xffffffff)) *(int *)x2 = 0xffffffff; else *(unsigned int *)x2 = NINT(aReal); break; case TBL_D_I1: if ((aReal <= NULL1) || (aReal > 127)) toNULL1(x2), over++; else *x2 = NINT(aReal); break; case TBL_D_I2: if ((aReal < MINSHORT) || (aReal > MAXSHORT)) toNULL2(x2), over++; else *(short *)x2 = NINT(aReal); break; case TBL_D_I4: if ((aReal < -MAXINT) || (aReal > MAXINT)) toNULL4(x2), over++; else *(int *)x2 = NINT(aReal); break; case TBL_D_R4: if ((aReal < -MAXFLOAT)||(aReal > MAXFLOAT)) toNULLF(x2), over++; else *(float *)x2 = aReal; break; case TBL_D_R8: *(double*)x2 = aReal; break; } else switch(etyp2) { /* From aLong */ case TBL_D_A1: if ((aLong < 0) || (aLong > 0xff)) *(char *)x2 = 0xff, over++; else *x2 = aLong; break; case TBL_D_A2: if ((aLong < 0) || (aLong > 0xffff)) *(short *)x2 = 0xffff, over++; else *(unsigned short*)x2 = aLong; break; case TBL_D_A4: if (aLong < 0) *(int *)x2 = 0xffffffff; else *(unsigned int *)x2 = aLong; break; case TBL_D_I1: if ((aLong <= NULL1) || (aLong > 127)) toNULL1(x2), over++; else *x2 = aLong; break; case TBL_D_I2: if ((aLong < MINSHORT) || (aLong > MAXSHORT)) toNULL2(x2), over++; else *(short *)x2 = aLong; break; case TBL_D_I4: *(int *)x2 = aLong; break; case TBL_D_R4: *(float *)x2 = aLong; break; case TBL_D_R8: *(double*)x2 = aLong; break; } } return (over); } /*=======================================================================*/ /* This Routine is just here to allow a conversion from New Format (3D) to Old. Delete it afterwards... */ /*=======================================================================*/ int TBL_toMAX(dtype, x) /*+++++++ .PURPOSE Writes a SINGLE MAX value .RETURNS Number of bytes modified. -------*/ int dtype; /* IN: Table specific datatype */ char *x; /* OUT: where to set the MAX value */ { int bytes; /* Returned value */ int etype; /* Returned value */ etype = TBL_ElementType(dtype); bytes = 1 << (etype & 3); switch(etype) { case TBL_D_A1: *x = 0xff; break; case TBL_D_I1: *x = 127; break; case TBL_D_A2: *(short *)x = 0xffff; break; case TBL_D_I2: *(short *)x = 0x7fff; break; case TBL_D_A4: *(int *)x = 0xffffffff; break; case TBL_D_I4: *(int *)x = 0x7fffffff; break; case TBL_D_R8: *(double *)x = MAXDOUBLE; break; case TBL_D_R4: *(float *)x = MAXFLOAT; break; } return (bytes); }