home *** CD-ROM | disk | FTP | other *** search
/ vis-ftp.cs.umass.edu / vis-ftp.cs.umass.edu.tar / vis-ftp.cs.umass.edu / pub / Software / universal_plane_file_format / read_write_plane.c < prev    next >
C/C++ Source or Header  |  1991-03-06  |  24KB  |  748 lines

  1. /* -*-c-mode-*- */
  2. /*------------------------------------------------------
  3.  *  READ_WRITE_PLANE.C - Generic C code to read and write LLVS planes
  4.  *  Robert Heller Created on Mon Jul 10 09:46:28 1989
  5.  *  Last mod - 
  6.  *--------------------------------------------------------
  7.  *  Contents:
  8.  *--------------------------------------------------------
  9.  * (c) Copyright 1989 by The University of Massachusetts
  10.  *------------------------------------------------------*/
  11.  
  12. #include <stdio.h>        /* standard I/O defs */
  13. #include <math.h>        /* math defs */
  14. #include <ctype.h>        /* character defs */
  15.  
  16. #include <llvs_per_plane.h>    /* llvs per_plane defs */
  17. #include <llvs_plane.h>        /* llvs plane file defs */
  18.  
  19.  /*
  20.   * read_plane(plane,plane_info,associations,filename) - read in a plane file.
  21.   * plane is a pointer to a pointer to a PLANE object, plane_info is a pointer
  22.   * to a pointer to a PLANE_INFO object, associations is a pointer to a pointer
  23.   * to char, and filename is a filename.
  24.   * plane, plane_info, and associations are set to malloc'ed space, so should
  25.   * be addresses of cloberable pointers (i.e. addresses of variables or 
  26.   * structure fields, etc.).
  27.   */
  28.  
  29.  
  30. char *malloc(), *calloc();
  31.  
  32. read_plane(plane,plane_info,associations,filename)
  33. PLANE **plane;
  34. PLANE_INFO **plane_info;
  35. char **associations;
  36. char *filename;
  37. {
  38.     /* plane file header record structure */
  39.     static LLVS_PLANE_FILE_HEADER header;
  40.     /* plane size header record structure */
  41.     static LLVS_PLANE_SIZE_HEADER size_header;
  42.     int plsize;            /* # bytes in plane */
  43.     FILE *plfile;        /* plane file */
  44.     llvs_ubyte *data_pointer; /* pointer to data buffer */
  45.     int rbytes, bytesleft;    /* I/O byte counters */
  46.     int need_swap, need_cvt_float; /* flags to indicate if conversions needed */
  47.  
  48.     /* open file.  abort if open failure */
  49.     plfile = fopen(filename,"r");
  50.     if (plfile == NULL) return(-1);
  51.     /* read header record */
  52.     if (fread(&header,32,1,plfile) != 1) return(-1);
  53. #ifdef DECSTATION
  54.     if (header.ptype == 32) {
  55.         rewind(plfile);
  56.     return(read_plane_vms_var(plane,plane_info,associations,plfile));
  57.     }
  58. #endif
  59.     need_swap = header.bsex != LLVS_NATIVE_BYTE_SEX;
  60.     need_cvt_float = header.floatfmt != LLVS_NATIVE_FLOATFMT;
  61.  
  62.     if (need_swap) swap_longs(&header.pl_level,7);
  63.     if (header.ptype == LLVS_PLF_FLOAT && need_cvt_float) 
  64.     cvt_floats(&header.background,1,header.floatfmt,LLVS_NATIVE_FLOATFMT);
  65.     /* computer plane size */
  66.     plsize = header.data_length - 12;
  67.     /* allocate plane info struct */
  68.     *plane_info = (PLANE_INFO *) malloc(sizeof(PLANE_INFO));
  69.     if (*plane_info == NULL) return(-1);
  70.     /* fill in plane info slots */
  71.     (*plane_info)->datatype = header.ptype;
  72.     (*plane_info)->level = header.pl_level;
  73.     (*plane_info)->row_location = header.row_location;
  74.     (*plane_info)->column_location = header.col_location;
  75.     (*plane_info)->background.fixnum = header.background.iback;
  76.     /* allocate plane it self */
  77.     *plane = (PLANE *) malloc(plsize);
  78.     if (*plane == NULL) return(-1);
  79.     /* allocate space for association list */
  80.     *associations = calloc(header.alist_length+1,sizeof(char));
  81.     if (*associations == NULL) return(-1);
  82.     /* read in association list */
  83.     data_pointer = (llvs_ubyte *) *associations;    /* start of buffer */
  84.     bytesleft = header.alist_length; /* number of bytes to read */
  85.     while (bytesleft > 0) {
  86.     rbytes = bytesleft;
  87.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  88.     if (fread(data_pointer,rbytes,1,plfile) != 1) return(-1);
  89.     data_pointer += rbytes;
  90.     bytesleft -= rbytes;
  91.     }
  92.     /* read size header */
  93.     if (fread(&size_header,12,1,plfile) != 1) return(-1);
  94.     if (need_swap) swap_longs(&size_header,3);
  95.     /* fill in addition slots in plane info */
  96.     (*plane_info)->row_dimension = size_header.row_dimension;
  97.     (*plane_info)->column_dimension = size_header.col_dimension;
  98.     /* read in plane */
  99.     data_pointer = (unsigned char *) (*plane)->plane_base;
  100.     bytesleft = plsize;
  101.     while (bytesleft > 0) {
  102.     rbytes = bytesleft;
  103.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  104.     if (fread(data_pointer,rbytes,1,plfile) != 1) return(-1);
  105.     if (need_swap && header.ptype == LLVS_PLF_SHORT) 
  106.         swap_words(data_pointer,rbytes >> 1);
  107.     if (need_swap && (header.ptype == LLVS_PLF_INT || 
  108.               header.ptype == LLVS_PLF_FLOAT))
  109.         swap_longs(data_pointer,rbytes >> 2);
  110.     if (need_cvt_float && header.ptype == LLVS_PLF_FLOAT)
  111.         cvt_floats(data_pointer,rbytes >> 2,header.floatfmt,LLVS_NATIVE_FLOATFMT);
  112.     data_pointer += rbytes;
  113.     bytesleft -= rbytes;
  114.     }
  115.     /* close file */
  116.     fclose(plfile);
  117.     return(header.multi_plane_flag);
  118.     }
  119.  
  120. #ifdef DECSTATION
  121.  
  122. read_plane_vms_var(plane,plane_info,associations,plfile)
  123. PLANE **plane;
  124. PLANE_INFO **plane_info;
  125. char **associations;
  126. FILE *plfile;
  127. {
  128.     /* plane file header record structure */
  129.     static LLVS_PLANE_FILE_HEADER header;
  130.     /* plane size header record structure */
  131.     static LLVS_PLANE_SIZE_HEADER size_header;
  132.     static unsigned short int rsize;
  133.     int plsize;            /* # bytes in plane */
  134.     llvs_ubyte *data_pointer; /* pointer to data buffer */
  135.     int rbytes, bytesleft;    /* I/O byte counters */
  136.     int need_swap, need_cvt_float; /* flags to indicate if conversions needed */
  137.  
  138.     /* read header record */
  139.     if (fread(&rsize,2,1,plfile) != 1) return(-1);
  140.     if (fread(&header,32,1,plfile) != 1) return(-1);
  141.     need_swap = header.bsex != LLVS_NATIVE_BYTE_SEX;
  142.     need_cvt_float = header.floatfmt != LLVS_NATIVE_FLOATFMT;
  143.  
  144.     if (need_swap) swap_longs(&header.pl_level,7);
  145.     if (header.ptype == LLVS_PLF_FLOAT && need_cvt_float) 
  146.     cvt_floats(&header.background,1,header.floatfmt,LLVS_NATIVE_FLOATFMT);
  147.     /* computer plane size */
  148.     plsize = header.data_length - 12;
  149.     /* allocate plane info struct */
  150.     *plane_info = (PLANE_INFO *) malloc(sizeof(PLANE_INFO));
  151.     if (*plane_info == NULL) return(-1);
  152.     /* fill in plane info slots */
  153.     (*plane_info)->datatype = header.ptype;
  154.     (*plane_info)->level = header.pl_level;
  155.     (*plane_info)->row_location = header.row_location;
  156.     (*plane_info)->column_location = header.col_location;
  157.     (*plane_info)->background.fixnum = header.background.iback;
  158.     /* allocate plane it self */
  159.     *plane = (PLANE *) malloc(plsize);
  160.     if (*plane == NULL) return(-1);
  161.     /* allocate space for association list */
  162.     *associations = calloc(header.alist_length+1,sizeof(char));
  163.     if (*associations == NULL) return(-1);
  164.     /* read in association list */
  165.     data_pointer = (llvs_ubyte *) *associations;    /* start of buffer */
  166.     bytesleft = header.alist_length; /* number of bytes to read */
  167.     while (bytesleft > 0) {
  168.     rbytes = bytesleft;
  169.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  170.     if (fread(&rsize,2,1,plfile) != 1) return(-1);
  171.     if (fread(data_pointer,rbytes,1,plfile) != 1) return(-1);
  172.     data_pointer += rbytes;
  173.     bytesleft -= rbytes;
  174.     }
  175.     /* gobble extra byte */
  176.     if ((header.alist_length & 01) == 1) fread(&rsize,1,1,plfile);
  177.     /* read size header */
  178.     if (fread(&rsize,2,1,plfile) != 1) return(-1);
  179.     if (fread(&size_header,12,1,plfile) != 1) return(-1);
  180.     if (need_swap) swap_longs(&size_header,3);
  181.     /* fill in addition slots in plane info */
  182.     (*plane_info)->row_dimension = size_header.row_dimension;
  183.     (*plane_info)->column_dimension = size_header.col_dimension;
  184.     /* read in plane */
  185.     data_pointer = (unsigned char *) (*plane)->plane_base;
  186.     bytesleft = plsize;
  187.     while (bytesleft > 0) {
  188.     rbytes = bytesleft;
  189.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  190.     if (fread(&rsize,2,1,plfile) != 1) return(-1);
  191.     if (fread(data_pointer,rbytes,1,plfile) != 1) return(-1);
  192.     if (need_swap && header.ptype == LLVS_PLF_SHORT) 
  193.         swap_words(data_pointer,rbytes >> 1);
  194.     if (need_swap && (header.ptype == LLVS_PLF_INT || 
  195.               header.ptype == LLVS_PLF_FLOAT))
  196.         swap_longs(data_pointer,rbytes >> 2);
  197.     if (need_cvt_float && header.ptype == LLVS_PLF_FLOAT)
  198.         cvt_floats(data_pointer,rbytes >> 2,header.floatfmt,LLVS_NATIVE_FLOATFMT);
  199.     data_pointer += rbytes;
  200.     bytesleft -= rbytes;
  201.     }
  202.     /* close file */
  203.     fclose(plfile);
  204.     return(header.multi_plane_flag);
  205.     }
  206.  
  207.   /*
  208.    * write_plane(plane,plane_info,associations,filename) - write out a plane.
  209.    */
  210.  
  211. #endif
  212.  
  213.   /*
  214.    * write_plane(plane,plane_info,associations,filename) - write out a plane.
  215.    */
  216.  
  217. write_plane(plane,plane_info,associations,filename)
  218. PLANE *plane;
  219. PLANE_INFO *plane_info;
  220. char *associations;
  221. char *filename;
  222. {
  223.     static LLVS_PLANE_FILE_HEADER header;
  224.     /* plane size header record structure */
  225.     static LLVS_PLANE_SIZE_HEADER size_header;
  226.     int plsize;            /* # bytes in plane */
  227.     FILE *plfile;        /* plane file */
  228.     unsigned char *data_pointer; /* pointer to data buffer */
  229.     int rbytes, bytesleft;    /* I/O byte counters */
  230.  
  231.     /* open file.  abort if open failure */
  232. #ifdef VMS
  233.     plfile = fopen(filename,"w", "rfm=var");
  234. #else
  235.     plfile = fopen(filename,"w");
  236. #endif
  237.     if (plfile == NULL) return(-1);
  238.     /* fill in plane file header record */
  239.     header.ptype = plane_info->datatype;
  240.     header.bsex = LLVS_NATIVE_BYTE_SEX;
  241.     header.floatfmt = LLVS_NATIVE_FLOATFMT;
  242.     header.reserved = 0;
  243.     header.pl_level = plane_info->level;
  244.     header.row_location = plane_info->row_location;
  245.     header.col_location = plane_info->column_location;
  246.     header.background.iback = plane_info->background.fixnum;
  247.     header.data_length = plane_size(plane_info) + 12;
  248.     if (associations == NULL) associations = "NIL";
  249.     header.alist_length = strlen(associations);
  250.     header.multi_plane_flag = 0;
  251.  
  252.     /* write header record */
  253.     if (fwrite(&header,32,1,plfile) != 1) return(-1);
  254.     /* compute plane size (for use later) */
  255.     plsize = header.data_length - 12;
  256.     /* get pointer to associaions list */
  257.     data_pointer = (llvs_ubyte *) associations;
  258.     /* and length */
  259.     bytesleft = header.alist_length;
  260.     /* write out associations list */
  261.     while (bytesleft > 0) {
  262.     rbytes = bytesleft;
  263.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  264.     if (fwrite(data_pointer,rbytes,1,plfile) != 1) return(-1);
  265.     data_pointer += rbytes;
  266.     bytesleft -= rbytes;
  267.     }
  268.     /* fill in size header */
  269.     size_header.datatype_again = header.ptype;
  270.     size_header.row_dimension = plane_info->row_dimension;
  271.     size_header.col_dimension = plane_info->column_dimension;
  272.  
  273.     /* write out size header */
  274.     if (fwrite(&size_header,12,1,plfile) != 1) return(-1);
  275.     /* get pointer & size of plane data */
  276.     data_pointer = (unsigned char *) plane->plane_base;
  277.     bytesleft = plsize;
  278.     /* write plane data */
  279.     while (bytesleft > 0) {
  280.     rbytes = bytesleft;
  281.     if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
  282.     if (fwrite(data_pointer,rbytes,1,plfile) != 1) return(-1);
  283.     data_pointer += rbytes;
  284.     bytesleft -= rbytes;
  285.     }
  286.     /* close file */
  287.     fclose(plfile);
  288.     return(0);
  289.     }
  290.  
  291.  /* compute plane size from plane info */
  292.  
  293. plane_size(plinfo)
  294. PLANE_INFO *plinfo;
  295. {
  296.     int elements;        /* element count */
  297.  
  298.     elements = plinfo->row_dimension * plinfo->column_dimension;
  299.     switch (plinfo->datatype) {
  300.     case LLVS_BIT: return( (elements + 7) / 8);
  301.     case LLVS_BYTE:
  302.         return( elements * sizeof(unsigned char));
  303.     case LLVS_SHORT: 
  304.         return( elements * sizeof(short int));
  305.     case LLVS_INT: 
  306.         return( elements * sizeof(long int));
  307.     case LLVS_FLOAT: 
  308.         return( elements * sizeof(float));
  309.     }
  310.     }
  311.  
  312. swap_longs(array,element_count)
  313. llvs_integer array[];
  314. int element_count;
  315. {
  316.     union {
  317.     llvs_ubyte bytes[4];
  318.     llvs_integer longword;
  319.     } a,b;
  320.     register int i;
  321.  
  322.     for (i = 0; i < element_count; i++) {
  323.     a.longword = array[i];
  324.     b.bytes[0] = a.bytes[3];
  325.     b.bytes[1] = a.bytes[2];
  326.     b.bytes[2] = a.bytes[1];
  327.     b.bytes[3] = a.bytes[0];
  328.     array[i] = b.longword;
  329.     }
  330.     }
  331.  
  332. swap_words(array,element_count)
  333. llvs_half_integer array[];
  334. int element_count;
  335. {
  336.     union {
  337.     llvs_ubyte bytes[2];
  338.     llvs_half_integer word;
  339.     } a,b;
  340.     register int i;
  341.  
  342.     for (i = 0; i < element_count; i++) {
  343.     a.word = array[i];
  344.     b.bytes[0] = a.bytes[1];
  345.     b.bytes[1] = a.bytes[0];
  346.     array[i] = b.word;
  347.     }
  348.     }
  349.  
  350. cvt_floats(array,element_count,current_format,desired_format)
  351. llvs_integer array[];
  352. int element_count,desired_format;
  353. {
  354.     static llvs_integer old,new;
  355.     register int i;
  356.     void vax_to_ieee(), ieee_to_vax();
  357.  
  358.     for (i = 0; i < element_count; i++) {
  359.     old = array[i];
  360.     new = 0;
  361. /*
  362.     if (LLVS_NATIVE_BYTE_SEX == LLVS_LOW_BYTE_FIRST && 
  363.          current_format == LLVS_IEEE_SINGLE_FLOAT) swap_longs(&old,1);
  364. */
  365.     switch (current_format) {
  366.         case LLVS_DEC_SINGLE_FLOAT:
  367.         switch (desired_format) {
  368.             case LLVS_DEC_SINGLE_FLOAT: new = old; break;
  369.             case LLVS_IEEE_SINGLE_FLOAT: vax_to_ieee(&old,&new); break;
  370.             }
  371.         break;
  372.         case LLVS_IEEE_SINGLE_FLOAT:
  373.         switch (desired_format) {
  374.             case LLVS_DEC_SINGLE_FLOAT: ieee_to_vax(&old,&new); break;
  375.             case LLVS_IEEE_SINGLE_FLOAT: new = old; break;
  376.             }
  377.         break;
  378.         }
  379.     if (LLVS_NATIVE_BYTE_SEX == LLVS_LOW_BYTE_FIRST &&
  380.         desired_format == LLVS_IEEE_SINGLE_FLOAT) swap_longs(&new,1);
  381.     array[i] = new;
  382.     }
  383.     }
  384.  
  385. /*****************************************************************
  386.  fjm -- 11/6/87 -- Function IEEE_VAX_S(Value)
  387.  
  388.  This function takes an IEEE format MC68881 Single precision floating
  389.  point number and returns the VAX F_floating form of the number if it
  390.  is in range.
  391.  
  392.  Note: The smallest vax floating point number is 4 times smaller than
  393.        the smallest ieee floating point number in normallized form.
  394.        The largest vax floating point number is .5 times as large as
  395.        the largest ieee floating point number.
  396.  
  397.        Actual ranges:
  398.  
  399.                Vax                     IEEE
  400.                ---                     ----
  401.  
  402.        max     1.7014119x10**38        3.4028243x10**38
  403.  
  404.        min     0.29387365x10**-38      1.175495x10**-38 (normalized)
  405.                                        1.4013x10**-45   (de-normalized)
  406.  
  407.  Let E = the exponent part of the real (in signed magnitude form), and
  408.  let M = the mantisa, and S = the sign.
  409.  
  410.  The vax represents floating point numbers as:
  411.  
  412.        S bit -- bit 15
  413.        E     -- bits 7-14, 8 bit, excess 128 exponent.
  414.        M     -- bits 6(MSB)-0 and bits 31-16(LSB) unsigned fraction.
  415.        Numbers are stored in a normalized form with a hidden 1 bit
  416.        representing a 0.1 is immediately to the left of the MSB of M. Note
  417.        that the radix point of the fraction is to the left of the hidden
  418.        bit in this form.
  419.  
  420.        IF E .ge. 1 then
  421.                value = (-1)**S x 2**(E-128) x 0.1M
  422.        IF S .eq. 0 .and. E .eq. 0 then
  423.                value = 0 (unsigned)
  424.        IF S .eq. 1 .and. E .eq. 0 then
  425.                illegal value, signalled on attempted operation.
  426.  
  427.  The IEEE representation is as follows:
  428.  
  429.        S bit -- bit 31
  430.        E     -- bits 23-30, 8 bit, excess 127 binary exponent.
  431.        M     -- bits 22(MSB) - 0(LSB) unsigned fraction.
  432.        Numbers are stored in either normalized or de-normalized form. In
  433.        normalized form (the usual representation) a hidden 1 bit representing
  434.        a 1.0 is immediatly to the left of the MSB of M. In denormalized form,
  435.        the hidden bit is 0. See below. Note that in IEEE form, the radix point
  436.        of the fraction is to the right of the hidden bit.
  437.  
  438.        IF E .ge. 1 .and. E .le. 254 then
  439.                actual value = (-1)**S x 2**(E-127) x 1.M
  440.        IF E .eq. 0 .and. M .eq. 0 then
  441.                value = signed zero (S bit is preserved)
  442.        IF E .eq. 255 .and. M .ne. 0 then
  443.                not a number (NAN). M can have any bit pattern, and the
  444.                result of any operation on a NAN with the MSB of F set
  445.                on an IEEE implementation results in a signal. The
  446.                interpretation on any value associated with a NAN is left
  447.                to the application.
  448.        IF E .eq. 255 .and. M .eq. 0 then
  449.                value = Plus or minus infinity, depending on S.
  450.        IF E .eq. 0 .and. M .ne. 0 then
  451.                denormalized number, used to represent numbers less 
  452.                than can be represented in normalized form. The hidden bit
  453.                is assumed to a zero.
  454.                value = (-1)**S x 2**(E-126) x 0.M
  455.  
  456.  Note that the vax and ieee forms differ by a bias of 1 in their stored
  457.  exponent form, and that they also differ implicitly by a power of 2 due to
  458.  the difference in normalization scalling (ieee = 1.M, vax = 0.1M).
  459.  Thus the conversion for the exponent is Evax = Eieee + 2. Further, the vax
  460.  can represent smaller numbers in normallized form than can the 68881, so
  461.  this routine converts the de-normalized numbers that are representable
  462.  on the vax. Thus, all ieee normalized numbers with exponents less than 254
  463.  are convertable to vax representations. Further, Some of the de-normalized
  464.  numbers are convertable. Loss of range (overflow) occurs on the high end.
  465.  The actual conversion outline follows:
  466.  
  467.  Normallized numbers:
  468.  
  469.        numbers in the magnitude of:
  470.                1.175495 x 10**-38 to 1.7014119 x 10**38
  471.        are converted exactly, with no loss of precision.
  472.  
  473.        numbers with a magnitude greater than 1.7014119 x 10**38
  474.        are converted to a vax reserved operand with sign of 1 and
  475.        exponent and mantissa of zero. This is the equivalent of
  476.        the result of a floating overflow on a 780 class machine.
  477.  
  478.  De-normalized numbers:
  479.  
  480.        numbers in the magnitude of:
  481.                0.29387365 x 10**-38 to 1.175494 x 10**-38
  482.        are converted. Note that while the conversion is exact,
  483.        the vax has 1 to 2 bits more precision in this range than is
  484.        represenatble in the ieee form. The extra 1 or 2 bits are assigned
  485.        zeros in the conversion.
  486.  
  487.        numbers less than 0.29387365 x10**-38 are mapped on to vax zero
  488.        with S=0, E=0, and M=0.
  489.  
  490.  Zeros:
  491.  
  492.        both positive and minus zero in the ieee implementation are
  493.        mapped on to vax zero with S=0, M=0, and E=0.
  494.  
  495.  Infinities:
  496.  
  497.        Infinities have no dual in the vax architecture, as such, the
  498.        value mapped is a vax reserved operand, with S=1, E=0, and M=0.
  499.        This is the equivalent of a floating overflow result on the
  500.        780 class machines.
  501.  
  502.  Not Numbers (NAN's):
  503.  
  504.        These are mapped onto vax operands by setting the sign bit,
  505.        clearing the exponent, and preserving the mantissa. Note that
  506.        this conversion losses the original sign bit. The ieee representation
  507.        has twice as many NAN's as the vax, so half are lost.
  508.  
  509.  
  510.         integer*4 function IEEE_VAX_S(value) ! really of type bit vector.
  511.  
  512.         implicit        none
  513.  
  514.         integer*4       value
  515.  
  516.         integer*4       S
  517.         integer*4       E
  518.         integer*4       M
  519.  Fetch the fields from IEEE format:
  520.  
  521.        31 30          23 22                           0
  522.       +--+--------------+------------------------------+
  523.       | S| Exponent     |MSB   Mantissa             LSB|
  524.       +--+--------------+------------------------------+
  525.  
  526.         S = lib$extzv(31,1,value)
  527.         E = lib$extzv(23,8,value)
  528.         M = lib$extzv(0,23,value)
  529.  
  530.  Note: The following code is optimized to deal with the two most likely
  531.        casses first: namely, normal values and zeros.
  532.  
  533.  
  534.  Zeros and de-normalized numbers:
  535.  
  536.         if ( E .eq. 0 ) then
  537.  
  538.  Zeros:
  539.           if( M .eq. 0 ) then
  540.             S = 0
  541.  
  542.  de-normalized number:
  543.  
  544.           else ! M .ne. 0
  545.  
  546.           number is representable if  bit 21 or 22 is set.
  547.           shift the mantisa the right number of bits and strip the
  548.           high order set bit which becomes the hidden bit on the vax.
  549.           Numbers outside the representable range are set to zero.
  550.  
  551.             if ( ( M .and. '400000'x) .ne. 0 ) then
  552.               M = (M .or. '3FFFFF'x) * 2
  553.               E = 2
  554.  
  555.             else if ( ( M .and. '200000'x) .ne. 0 ) then
  556.               M = (M .or. '1FFFFF'x) * 4
  557.               E = 1
  558.             else
  559.               S = 0
  560.               E = 0
  561.               M = 0
  562.               end if
  563.             end if
  564.  
  565.  Normal value:
  566.  
  567.         else if ( E .lt. 254 ) then
  568.           E = E + 2
  569.  
  570.  
  571.  un-representable (overflow)
  572.  
  573.         else if ( E .eq. 254 ) then
  574.  
  575.  
  576.           S = 1
  577.           E = 0
  578.           M = 0
  579.  
  580.  Infinities and NAN's
  581.  
  582.         else ! E .eq. 255
  583.           S = 1
  584.           E = 0
  585.  
  586.           end if
  587.  
  588.  Store the numbers in vax format.
  589.  
  590.        31                   16 15 14       7 6           0
  591.       +-----------------------+--+----------+-------------+
  592.       |    Mantissa        LSB| S| Exponent |MSB Mantissa |
  593.       +-----------------------+--+----------+-------------+
  594.  
  595.  
  596.  
  597.         call lib$insv(S,15,1,ieee_vax_s)
  598.         call lib$insv(E, 7,8,ieee_vax_s)
  599.         call lib$insv(lib$extzv(16,7,M),0,7,ieee_vax_s)
  600.         call lib$insv(lib$extzv(0,16,M),16,16,ieee_vax_s)
  601.  
  602.         return
  603.         end
  604.  
  605.     Frank J. Manion
  606.                                         The Fox Chase Cancer Center
  607.   Phone: (215) 728-3660                 7701 Burholme Avenue
  608.                                         Philadelphia, PA  19111
  609.                                         USA
  610. *******************************************************************/
  611.  
  612. void ieee_to_vax(ip,cp)
  613. int *ip;
  614. unsigned char *cp;
  615. {
  616. int s, e, m;
  617. unsigned int i;
  618.  
  619. /* Fetch the fields from IEEE format:
  620.  
  621.       31  30          23 22                           0
  622.       +--+--------------+------------------------------+
  623.       | S| Exponent     |MSB   Mantissa             LSB|
  624.       +--+--------------+------------------------------+
  625. */
  626.  
  627.   i = *ip;
  628. #if LLVS_NATIVE_BYTE_SEX == LLVS_LOW_BYTE_FIRST
  629.   swap_longs(cp,1);
  630. #endif
  631.   s = 1 & (i >> 31);
  632.   e = 0x0ff & (i >> 23);
  633.   m = 0x7fffff & i;
  634.  
  635. /*
  636.  Note: The following code is optimized to deal with the two most likely
  637.        casses first: namely, normal values and zeros.
  638. */
  639.  
  640.  
  641.   if (e == 0) { /* Zeros and de-normalized numbers: */
  642.     if (m == 0) s = 0;
  643.     else {
  644.       /*
  645.           number is representable if  bit 21 or 22 is set.
  646.           shift the mantisa the right number of bits and strip the
  647.           high order set bit which becomes the hidden bit on the vax.
  648.           Numbers outside the representable range are set to zero.
  649.       */
  650.       if (m & 0x400000) {
  651.         m = (m | 0x3FFFFF) << 1;
  652.         e = 2;
  653.         }
  654.       else if (m & 0x200000) {
  655.         m = (m | 0x1FFFFF) << 2;
  656.         e = 1;
  657.         }
  658.       else {
  659.         s = 0;
  660.         e = 0;
  661.         m = 0;
  662.         }
  663.       }
  664.     }
  665.   else if (e < 254) e += 2; /*  Normal value: */
  666.   else if (e == 254) { /* un-representable (overflow) */
  667.     s = 1;
  668.     e = 0;
  669.     m = 0;
  670.     }
  671.   else { /* E .eq. 255 - Infinities and NAN's */
  672.     s = 1;
  673.     e = 0;
  674.     }
  675.  
  676. /*
  677.   Store the numbers in vax format.
  678.  
  679.        31                   16 15 14       7 6           0
  680.       +-----------------------+--+----------+-------------+
  681.       |    Mantissa        LSB| S| Exponent |MSB Mantissa |
  682.       +-----------------------+--+----------+-------------+
  683. */
  684.  
  685.   *cp++ = (m >> 16) | ((1 & e) << 7);
  686.   *cp++ = (s << 7) | (e >> 1);
  687.   *cp++ = 0xff & m;
  688.   *cp++ = 0xff & (m >> 8);
  689. }
  690.  
  691. void vax_to_ieee(cp,ip)
  692. unsigned char *cp;
  693. unsigned int *ip;
  694. {
  695. int s, e, m;
  696. unsigned int i;
  697.  
  698. /* Fetch the fields from VAX format:
  699.  
  700.        31                   16 15 14       7 6           0
  701.       +-----------------------+--+----------+-------------+
  702.       |    Mantissa        LSB| S| Exponent |MSB Mantissa |
  703.       +-----------------------+--+----------+-------------+
  704. */
  705.  
  706. #if LLVS_NATIVE_BYTE_SEX == LLVS_HIGH_BYTE_FIRST
  707.   swap_longs(cp,1);
  708. #endif
  709.   s = *(cp + 1) >> 7;
  710.   e = ((0x7f & *(cp + 1)) <<  1) | (*(cp + 0) >> 7);
  711.   m = ((0x7f & *(cp + 0)) << 16) | (*(cp + 3) << 8) | *(cp + 2);
  712.  
  713.  
  714. /*
  715.  Note: The following code is optimized to deal with the two most likely
  716.        casses first: namely, normal values and zeros.
  717. */
  718.  
  719.  
  720.   if (e > 1) e -= 2; /*  Normal value: */
  721.   else if (e == 0) { /* Zeros and de-normalized numbers: */
  722.     if (s == 0) m = 0;
  723.     else { /* NAN & Infinity */
  724.       m = 0;
  725.       e = 255;
  726.       }
  727.     }
  728.   else { /* un-representable (overflow) */
  729.     s = 0;
  730.     e = 0;
  731.     m = 0;
  732.     }
  733. /*
  734.   Store the numbers in IEEE format.
  735.  
  736.        31 30          23 22                           0
  737.       +--+--------------+------------------------------+
  738.       | S| Exponent     |MSB   Mantissa             LSB|
  739.       +--+--------------+------------------------------+
  740. */
  741.  
  742.   *ip = (s << 31) | (e << 23) | m;
  743.  
  744. #if LLVS_NATIVE_BYTE_SEX == LLVS_LOW_BYTE_FIRST
  745.   swap_longs(ip,1);
  746. #endif
  747. }
  748.