home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / hdf / unix / hdf3_2r2.lha / HDF3.2r2 / bkwdtest / transarray.c < prev   
Encoding:
C/C++ Source or Header  |  1992-10-29  |  7.2 KB  |  194 lines

  1. /*-----------------------------------------------------------------------------
  2.  * File:  transarray.c
  3.  *
  4.  * Purpose:
  5.  *    General purpose utility routines
  6.  *
  7.  * Invokes:
  8.  *
  9.  * Public functions:
  10.  *    transar - transpose the array and reverse the dimension sizes
  11.  *
  12.  * Lower level functions:
  13.  *
  14.  * Private functions:
  15.  *
  16.  * Remarks:
  17.  *
  18.  *--------------------------------------------------------------------------*/
  19.  
  20.  
  21. /*----------------------------------------------------------------------------
  22.  * Name:    transar
  23.  * Purpose: Transpose in memory a data array and reverse its dimension
  24.  *          sizes accordingly. 
  25.  *          It can be used by C programs to transpose
  26.  *          SDS's which were written by Fortran programs using HDF library
  27.  *          previous to HDF3.2r1 (or HDF3.2beta3)
  28.  * Inputs:  rankp: pointer to the rank of the data array
  29.  *          indims: dimension sizes of input (source) data array
  30.  *          outdims: dimension sizes of output (destination) data array
  31.  *          numtypep: pointer to the number type of the data 
  32.  *          indata: source data array
  33.  *          outdata: destination data array --transposation of indata
  34.  *          isfortranp: pointer to the indicator of the caller, *(isfortranp)=0 if
  35.  *                      the caller is a C program 
  36.  * Returns: 0 on success, -1 on failure 
  37.  * Outputs: the transposed array and reversed dimension sizes
  38.  * Users:   a general utility function. can be used by C programs to transpose SDS's 
  39.  *          which were written by Fortran programs using HDF library
  40.  *          previous to HDF3.2r1 (or HDF3.2beta3)
  41.  * Invokes: 
  42.  * Method:  reverse dimensions. transpose the data array. 
  43.  * Remarks: HDF C programs may call DFKNTsize(numbertype | DFNT_NATIVE) to get 
  44.  *          the memory size of the number type. The Fortran interface of 
  45.  *          DFKNTsize needs to be written. 
  46.  *          
  47.  **********************************************************************/
  48.  
  49.  
  50. #ifdef PROTOTYPE
  51. int transar(int *rankp, int *indims, int *outdims,
  52.           int *eltsizep, char *indata, char *outdata, int *isfortranp)
  53. #else
  54. int transar(rankp, indims, outdims, eltsizep, indata, outdata,isfortranp)
  55.  
  56.     int     *rankp;    /* number of dimensions of the data array  */
  57.     int     *indims,    /* array containing the coordinates of the input */
  58.                         /* data array  */
  59.             *outdims,    /* array to store the dimensions of the output */
  60.                         /* data array  */
  61.             *eltsizep;   /* size(number of bytes) of the element */
  62.     char    *indata,    /* the input data array */
  63.             *outdata;   /* the transposed data array -- output data array  */
  64.     int     *isfortranp; /* 1--called from Fortran program, 0--from C prog. */
  65.  
  66. #endif /* PROTOTYPE */
  67.  
  68. {
  69.     int
  70.         done,           /* true if we are at the end of the slice */
  71.         i, j,           /* temporary loop index */
  72.         temp,        /* used for reverse of the  dims   */
  73.         rank,           /* rank of the array               */
  74.         NTsize,         /* size of the data                */
  75.         leastsig,        /* rank-1  */
  76. /*        localNTsize,   */
  77.                          /* size of this NT as it occurs in this machine */
  78.         outstride,      /* byte distance,in outdata,of two adjacent elements */
  79.             /* in indata[]           */
  80.         *offset,        /* array for accessing the next element in data[] */
  81.         *outoffset,     /* array for accessing the next element in outdata[] */
  82.         *dims,          /* dimsizes used in transposition   */
  83.         *dimsleft;      /* array for tracking the current position in data[] */
  84. /*        isnative,       */
  85. /*        machinetype;    */
  86.                         /* assigned DF_MT.  used for debugging */
  87. /*    uint8               */
  88. /*        platnumsubclass, */
  89.                         /* class of this NT for this platform */
  90.      unsigned char
  91.         *outdatap,      /* ptr into outdata[] at starting offset */
  92.                            /* of current block  */
  93.         *outdp,        /* ptr into outdata[] at an element of the current row */
  94.         *datap,         /* ptr into data[] at starting offset */
  95.                             /* of current block */
  96.         *dp;            /* ptr into data[] at an element of the current row */
  97.     char *FUNC="transarray";
  98.  
  99.  
  100.     if (!indata || !outdata ) {
  101.         exit(-1); 
  102.     }
  103.  
  104. /*    isnative = DFNT_NATIVE;
  105.     machinetype = DF_MT;
  106.     platnumsubclass = DFKgetPNSC(numtype, DF_MT);
  107.     localNTsize = DFKNTsize(numtype | isnative);
  108. */
  109.     rank = *rankp;
  110.     NTsize = *eltsizep;
  111.     /* reverse dimensions first  */
  112.     for (i=0; i<rank; i++)    {
  113.         outdims[i] = indims[rank-i-1];
  114.     }
  115.     if (*isfortranp == 1) dims=outdims;  /* use outdims, slowest dim first, to make */
  116.                                         /* the dims consistant with the data in C order */
  117.     else dims=indims;
  118.     /*
  119.      * To transpose the data we must work on a row by row
  120.      * basis and cannot collapse dimensions.
  121.      */
  122.     
  123.     leastsig = rank-1;        /* which is least sig dim */
  124.  
  125.     /* allocate buffers */
  126.     offset = (long int*) malloc(3 * rank * sizeof(long int));
  127.     if (!offset) {
  128.         exit(-1);
  129.     } 
  130.     outoffset = offset + rank;
  131.     dimsleft = outoffset + rank;
  132.  
  133.         /* compute initial position in the data */
  134.     for (i=leastsig; i>=0; i--)
  135.         dimsleft[i] = dims[i];
  136.  
  137.         /* compute offsets for the source array */
  138.     offset[leastsig] = 1*NTsize;
  139.     for (i = leastsig; i>0; i--)
  140.         offset[i-1] = offset[i] * dims[i];
  141.     
  142.         /* compute offsets for the destination array */
  143.     outoffset[0] = 1*NTsize;
  144.     for (i=0; i<leastsig; i++)
  145.         outoffset[i+1] = outoffset[i] * outdims[leastsig - i];
  146.     outstride = outoffset[leastsig];
  147.     datap = (unsigned char *)indata;
  148.     outdatap = (unsigned char *)outdata;
  149.     done = 0;
  150.         /* -- now read in the data */
  151.     do {
  152.             /* move to the next row in source array */
  153.             /* scatter out the elements of one row */
  154. #ifdef UNICOS
  155. #pragma ivdep
  156. #endif
  157.         for (dp=datap, outdp = outdatap, i=0; i<dims[leastsig]; i++) {
  158.              for (j=0; j<NTsize; j++)
  159.                         *(outdp +j) = *(dp +j);
  160.              dp += NTsize;
  161.              outdp += outstride;
  162.         }
  163.  
  164.             /*
  165.              * Find starting place of the next row/block.
  166.              * Note that all moves are relative:
  167.              *   this preserves the starting offsets of each dimension
  168.              */
  169.         for (i=leastsig-1; i>=0; i--) {
  170.             if (--dimsleft[i] > 0) {
  171.                     /* move to next element in the current dimension */
  172.                 datap += offset[i];
  173.                 outdatap += outoffset[i];
  174.                 break;
  175.             } else {
  176.                 dimsleft[i] = dims[i];
  177.                    /*
  178.                      * Note that we are still positioned at the beginning of
  179.                      * the last element in the current dimension
  180.                      */
  181.                     /* move back to the beginning of dimension i */
  182.                 datap -= offset[i] * (dims[i]-1);
  183.                     /* move back to beginning outdata position of dimension i */
  184.                 outdatap -= outoffset[i] * (outdims[i]-1);
  185.                 if (i==0) done = 1;
  186.             }
  187.         }
  188.     } while (!done && leastsig > 0);
  189.  
  190.     free((char *)offset);
  191.     return(0);
  192. }   /* end transarray */
  193.  
  194.