home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / compstol / cmpsttl1.lha / CompositeTool / v1.1.dist / HDF / dfkit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-08  |  8.1 KB  |  321 lines

  1. #include "df.h"
  2.  
  3. union fpx
  4. {
  5.      float f;
  6.      long  l;
  7. };
  8.  
  9. union float_uint_uchar {
  10.     float32 f;
  11.     unsigned int32 i;
  12.     unsigned char c[4];
  13. };
  14.  
  15. DFIstrncpy(dest, source, len)
  16. char *source, *dest;
  17. int len;
  18. {
  19.  
  20.     for(; (--len > 0) && (*dest++ = *source++););
  21.     if (!len) *dest = '\0';
  22. }
  23.  
  24.  
  25. int DFconvert(source, dest, ntype, sourcetype, desttype)
  26. char *source, *dest;
  27. int ntype, sourcetype, desttype;
  28. {
  29.     char tmp[4];        /* size of float32 */
  30.  
  31.     if (ntype==DFNT_FLOAT) {
  32.  
  33.     if (((sourcetype==DFNTF_IEEE) && ( desttype==DFNTF_PC)) ||
  34.         ((sourcetype==DFNTF_PC) && (desttype==DFNTF_IEEE))) {
  35.         dest[0]=source[3];
  36.         dest[1]=source[2];
  37.         dest[2]=source[1];
  38.         dest[3]=source[0];
  39.         return(0);
  40.     }
  41.  
  42.     /* if reversed IEEE convert first */
  43.     if (sourcetype==DFNTF_PC) {
  44.         tmp[0]=source[3];
  45.         tmp[1]=source[2];
  46.         tmp[2]=source[1];
  47.         tmp[3]=source[0];
  48.         source=tmp;
  49.         sourcetype=DFNTF_IEEE;
  50.     }
  51.  
  52.         if ((sourcetype==DFNTF_IEEE) && (desttype==DFNTF_CRAY)) {
  53.             if (DFCVieeeF2unicosF(source,(union fpx*) dest)<0) return(-1);
  54.         } else if ((sourcetype==DFNTF_CRAY) &&
  55.            ((desttype==DFNTF_IEEE) || (desttype==DFNTF_PC))) {
  56.             if (DFCVunicosF2ieeeF((union fpx*)source, dest)<0) return(-1);
  57.         } else if ((sourcetype==DFNTF_IEEE) && (desttype==DFNTF_VAX)) {
  58.             if (DFCVieeeF2vaxF((union float_uint_uchar *) source,
  59.                    (union float_uint_uchar *) dest)<0)
  60.         return(-1);
  61.         } else if ((sourcetype==DFNTF_VAX) &&
  62.            ((desttype==DFNTF_IEEE) || (desttype==DFNTF_PC))) {
  63.             if (DFCVvaxF2ieeeF((union float_uint_uchar*) source,
  64.                    (union float_uint_uchar*) dest)<0)
  65.         return(-1);
  66.         }
  67.  
  68.     /* if reversed IEEE convert */
  69.     if (desttype==DFNTF_PC) {
  70.         char t;
  71.         t=dest[3];
  72.         dest[3]=dest[0];
  73.         dest[0]=t;
  74.         t=dest[2];
  75.         dest[2]=dest[1];
  76.         dest[1]=t;
  77.     }
  78.     return(0);
  79.     }
  80.         /* default */
  81.     DFerror = DFE_BADCONV;
  82.     return(-1);
  83. }
  84.  
  85. char *DFIgetspace(qty)
  86. unsigned qty;
  87. {
  88.     char *p;
  89.  
  90.     p = malloc(qty);
  91.     if (p==NULL) {
  92.         DFerror = DFE_NOSPACE;
  93.         return(NULL);
  94.     }
  95.     return(p);
  96. }
  97.  
  98. char *DFIfreespace(ptr)
  99. char *ptr;
  100. {
  101.     if (ptr!=NULL) free(ptr);
  102.     return(NULL);
  103. }
  104.  
  105.  
  106. #ifdef UNICOS
  107.  
  108. #define MINEXP    0x3f81000000000000  /* min valid Cray masked exponent */
  109. #define MAXEXP    0x407e000000000000  /* max valid Cray masked exponent */
  110.  
  111. #define C_FMASK   0x00007fffff000000  /* Cray fraction mask (1st 23 bits)*/
  112. #define C_EMASK   0x7fff000000000000  /* Cray exponent mask */
  113. #define C_SMASK   0x8000000000000000  /* Cray sign mask */
  114. #define C_IMPLICIT 0x0000800000000000 /* Cray implicit bit */
  115.  
  116. #define I_FMASK   0x007fffff          /* IEEE fraction mask */
  117. #define I_EMASK   0x7f800000          /* IEEE exponent mask */
  118. #define I_SMASK   0x80000000          /* IEEE sign mask     */
  119.  
  120. #define IEEE_BIAS 0177
  121. #define CRAY_BIAS 040000
  122.  
  123. static long C2I_diff;
  124. static long I2C_diff;
  125.  
  126. #endif /*UNICOS*/
  127.  
  128.  
  129.     /*  convert from Cray2 floating point format to IEEE format */
  130. /* shut lint up */
  131. /* ARGSUSED */
  132. int DFCVunicosF2ieeeF(cray_fp, ieee_fp)
  133. union fpx *cray_fp;
  134. char *ieee_fp;
  135. {
  136.  
  137. #ifdef UNICOS
  138.     long tmp;
  139.  
  140.     if (cray_fp->l == 0) {
  141.         tmp = 0;
  142.     }
  143.          
  144.     else {
  145.         tmp = (C_EMASK & cray_fp->l);
  146.         if (tmp < MINEXP || tmp > MAXEXP) {
  147.             DFerror = DFE_BADFP;
  148.             return(-1);
  149.         }
  150.  
  151.         C2I_diff = (IEEE_BIAS - CRAY_BIAS - 1) << 48;
  152.         tmp = (( tmp + C2I_diff ) << 7)
  153.             | ( (cray_fp->l & C_FMASK) << 8 )
  154.             | ( (cray_fp->l & C_SMASK));
  155.     }
  156.     DFmovmem(&tmp, ieee_fp, 4);
  157.     return(0);
  158.  
  159. #else /*UNICOS*/
  160.     DFerror = DFE_BADCONV;
  161.     return(-1);
  162. #endif /*UNICOS*/
  163.  
  164. }
  165.  
  166.  
  167. /* Conversion from IEEE floating point format to Cray format */
  168.  
  169. /* shut lint up */
  170. /* ARGSUSED */
  171. int DFCVieeeF2unicosF(ieee_fp, cray_fp)
  172. union fpx *cray_fp;
  173. char *ieee_fp;
  174. {
  175.  
  176. #ifdef UNICOS
  177.     long tmp;
  178.  
  179.     tmp = 0;
  180.     DFmovmem(ieee_fp, ((char *) &tmp) + 4, 4);      /* right 4 bytes of tmp */
  181.  
  182.     if ( (cray_fp->l = tmp & I_EMASK) == 0) {
  183.         cray_fp->l = 0;
  184.         return(0);
  185.     }
  186.  
  187.     I2C_diff = (CRAY_BIAS - IEEE_BIAS + 1) << 23;
  188.     cray_fp->l += I2C_diff;
  189.     cray_fp->l = (cray_fp->l<< 25)  | ( (tmp & I_FMASK) << 24)
  190.        | ( (tmp & I_SMASK) << 32) | C_IMPLICIT;
  191.     return (0);
  192.  
  193. #else /*UNICOS*/
  194.     DFerror = DFE_BADCONV;
  195.     return(-1);
  196. #endif /*UNICOS*/
  197.  
  198. }
  199.  
  200.  
  201. DFIc2fstr(str, len)
  202. char* str;
  203. int len;
  204. {
  205.     int i;
  206.  
  207.     for(i=0; (str[i]); i++);
  208.     for(; i<len; i++) str[i] = ' ';
  209. }
  210.  
  211. char *DFIf2cstring(fstr, len)
  212. #ifdef UNICOS
  213.     _fcd fstr;
  214.     int len;
  215. {
  216.     char *cstr, *str;
  217.     int i;
  218.  
  219.     str = _fcdtocp(fstr);
  220.     cstr = DFIgetspace(len+1);
  221.     for(i=0;i<len && (cstr[i] = str[i]) != ' '; i++);
  222.     cstr[i] = '\0';
  223.     return cstr;
  224. }
  225. #else /*UNICOS*/
  226.     char *fstr;
  227.     int len;
  228. {
  229.     char *cstr;
  230.     int i;
  231.  
  232. #ifdef VMS
  233.     fstr = (char *) *((char **) &fstr[4]); /* deref descriptor */
  234.                 /* the VMS string descriptor: 4 bytes of
  235.                    string length, and then address of
  236.                    string */
  237. #endif /*VMS*/
  238.  
  239.     cstr = DFIgetspace((unsigned) len + 1);
  240.     for(i=0;(i<len)&&((cstr[i]=fstr[i]) != ' ');i++);
  241.     cstr[i] = '\0';
  242.     return cstr;
  243. }
  244. #endif /*UNICOS*/
  245.  
  246. int DFCVvaxF2ieeeF(in, out)
  247. union float_uint_uchar *in, *out;
  248. {
  249.     register unsigned char exp;
  250.  
  251.     exp = (in->c[1] << 1) | (in->c[0] >> 7);    /* extract exponent */
  252.     if (!exp && !in->c[1]) out->i = 0;          /* zero value */
  253.     else if (exp>2) {                           /* normal value */
  254.         out->c[0] = in->c[1] - 1;   /* actually subtracts 2 from exponent */
  255.                 /* copy mantissa, LSB of exponent */
  256.         out->c[1] = in->c[0];
  257.         out->c[2] = in->c[3];
  258.         out->c[3] = in->c[2];
  259.     }
  260.     else if (exp) {                             /* denormalized number */
  261.         register int shft;
  262.  
  263.         out->c[0] = in->c[1] & 0x80;            /* keep sign, zero exponent */
  264.         shft = 3 - exp;
  265.             /* shift original mant by 1 or 2 to get denormalized mant */
  266.             /* prefix mantissa with '1'b or '01'b as appropriate */
  267.         out->c[1] = ((in->c[0] & 0x7f) >> shft) | (0x10 << exp);
  268.         out->c[2] = (in->c[0] << (8-shft)) | (in->c[3] >> shft);
  269.         out->c[3] = (in->c[3] << (8-shft)) | (in->c[2] >> shft);
  270.     }
  271.     else {                                      /* sign=1 -> infinity or NaN */
  272.         out->c[0] = 0xff;                       /* set exp to 255 */
  273.                 /* copy mantissa */
  274.         out->c[1] = in->c[0] | 0x80;            /* LSB of exp = 1 */
  275.         out->c[2] = in->c[3];
  276.         out->c[3] = in->c[2];
  277.     }
  278.     return(0);
  279. }
  280.  
  281.  
  282. int DFCVieeeF2vaxF(in, out)
  283. union float_uint_uchar *in, *out;
  284. {
  285.     register unsigned char exp;
  286.  
  287.     exp = (in->c[0] << 1) | (in->c[1] >> 7);    /* extract exponent */
  288.     if (exp) {                                  /* non-zero exponent */
  289.             /* copy mantissa, last bit of exponent */
  290.         out->c[0] = in->c[1];
  291.         out->c[2] = in->c[3];
  292.         out->c[3] = in->c[2];
  293.         if (exp<254)                            /* normal value */
  294.             out->c[1] = in->c[0] + 1;           /* actually adds two to exp */
  295.         else {                                  /* infinity or NaN */
  296.             if (exp==254)                       /* unrepresentable - OFL */
  297.                 out->i = 0;                     /* set mant=0 for overflow */
  298.             out->c[0] &= 0x7f;                  /* set last bit of exp to 0 */
  299.             out->c[1] = 0x80;                   /* sign=1 exp=0 -> OFL or NaN */
  300.         }
  301.     }
  302.     else if (in->c[1] & 0x60) {                 /* denormalized value */
  303.         register int shft;
  304.     
  305.         shft = (in->c[1] & 0x40) ? 1 : 2;       /* shift needed to normalize */
  306.             /* shift mantissa */
  307.             /* note last bit of exp set to 1 implicitly */
  308.         out->c[0] = (in->c[1] << shft) & (in->c[2] >> (8-shft));
  309.         out->c[3] = (in->c[2] << shft) & (in->c[3] >> (8-shft));
  310.         out->c[2] = in->c[3] << shft;
  311.         out->c[1] = (in->c[0] & 0x80);          /* sign */
  312.         if (shft==1) {                          /* set exp to 2 */
  313.             out->c[1] |= 0x01;
  314.             out->c[0] &= 0x7f;                  /* set LSB of exp to 0 */
  315.         }
  316.     }
  317.     else out->i = 0;                            /* zero */
  318.  
  319.     return(0);
  320. }
  321.