 /*
  * Khoros: $Id: utils.c,v 1.1 1991/05/10 15:43:29 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: utils.c,v 1.1 1991/05/10 15:43:29 khoros Exp $";
#endif

 /*
  * $Log: utils.c,v $
 * Revision 1.1  1991/05/10  15:43:29  khoros
 * Initial revision
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.

 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "vinclude.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: utils.c 				      <<<<
   >>>>                                                       <<<<
   >>>>   description: loads and unloads viff data 
   >>>>        
   >>>>      routines: load_viff_data()
   >>>>              
   >>>> modifications:	 
   >>>>       Fixed bug with interleaved multiple data bands.  
   >>>>	      The index was not being computed correctly.
   >>>>          (Donna Koechner & Mark Young  1/10/90)
   >>>>
   >>>>		Fixed bug with non-interleaved complex data.  The
   >>>>	        starting point was not being doubled for complex 
   >>>>		data.
   >>>>		(Donna Koechner & Mark Young  1/31/90)
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/*********************************************************************
*
*	load_viff_data
*
*	Load data either real or complex into viff format.
*
*	nrows, ncols		totaling number of points (sets) per band
*				not including the row & col increment factor.
*
*	data			array containing data points
*
*	bands			array that will contain the data bands.
*
*	location		array that will contain the location data
*				bands.
*	numbands		number of bands in the file
*
*	dimension		number of location bands in the file
*
*	interleave		whether data is interleaved or not
*					x1 y1 z1
*					x2 y2 z2
*					  .vs.
*				         x1 x2
*				         y1 y2
*				         z1 z2
*
*	start			starting point offset to be read for
*				band.
*
*	row_skip, col_skip	number of points to skip along the row and
*				column.  This is done after getting each
*				set of points.  Since the user is expected 
*				to use start offset if they don't wish to
*				start at the first point of each band.
*
*	complex			type of data, either real or complex
*
*********************************************************************/


load_viff_data(data, bands, location, nrows, ncols, numbands, dimension,
	       interleave, start, row_skip, col_skip, complex)

float	*data, *bands, *location;
int	nrows, ncols, numbands, dimension, interleave, start,
	row_skip, col_skip, complex;
{
   int    i, j, k, l, m, n, b, point_per_vector, index, bandsize;



   /* read non-interleaved data points */
   if (!interleave)		
   {
      /*
       *  Since the data is not interleaved that means that
       *  each band of data is specified before the next
       *  band starts.  ie)
       *
       *	x1 x2 x3 x4 x5 ....
       *	y1 y2 y3 y4 y5 ....
       *	z1 z2 z3 z4zy5 ....
       *	     etc.
       *
       *  The data is organized as dimension (location) band data
       *  is specified first then the data (image) band comes after.
       */

      /*  location data */
      k = l = b = 0;
      bandsize = nrows*ncols;
      for (i = 0; i < dimension; i++)
      {
	  /*
	   *  Offset the start of the data array according to the
	   *  data band offset (start) specified by the user.
	   */
          for (m = 0; m < nrows; m += row_skip) 
	  {
	     l = start*b + m*ncols + b*bandsize;
             for (n = 0; n < ncols; n += col_skip) 
	     {
	        location[k++] = data[l];
	        l += col_skip;
	     }
	  }

	  /*
	   *  Increment to the next band.  This way we skip to the
	   *  next band of data loaded in "data".
	   */
	  b++;
      }

      /*  band data */
      k = 0;
      for (i = 0; i < numbands; i++) 
      {
	  /*
	   *  Offset the start of the data array according to the
	   *  data band offset (start) specified by the user.
	   */
          for (m = 0; m < nrows; m += row_skip) 
	  {
	     if (complex == 1)
	        l = start*b + m*ncols*2 + b*bandsize;
	     else
	        l = start*b + m*ncols + b*bandsize;

             for (n = 0; n < ncols; n += col_skip) 
	     {
     	        if (complex == 1)            /* data is complex */
	        {
	           bands[k++] = data[l];
	           bands[k++] = data[l+1];

	           /*  skip factor */
	           l += col_skip*2;
	        }
	        else
	        {
	           bands[k++] = data[l];

	           /*  skip factor */
	           l += col_skip;
	        }
	     }
	  }

	  /*
	   *  Increment to the next band.  This way we skip to the
	   *  next band of data loaded in "data".  If the data is
	   *  complex then we need to skip twice the bandsize, since
	   *  for each point there is two numbers (real,imaginary).
	   */
	  if (complex)
	     b += 2;
	  else
	     b++;
      }
   }
   else   /* read interleaved data points */
   {
      /*
       *  Since the data is interleaved that means that
       *  each set of points (from each band) is specified
       *  before the next set starts.  ie)
       *
       *	x1 y1 z1 w1
       *	x2 y2 z2 w2
       *	x3 y3 z3 w3
       *	x4 y4 z4 w4
       *	x5 y5 z5 w5
       *	   etc.
       *
       *  The data is organized as dimension (location) band points
       *  is specified first then the data (image) band points comes after.
       */
      if (complex == 1)            /* data is complex */
	 point_per_vector = (dimension + numbands * 2);
      else
	 point_per_vector = (dimension + numbands);

      /*
       *  Offset the start of the data array according to the
       *  data band offset (start) specified by the user.
       */
      bandsize = (1 + (nrows -1)/row_skip) * (1 + (ncols -1)/col_skip);

      k = i = 0;
      for (m = 0; m < nrows; m += row_skip) 
      {
	 l = (start + m * ncols) * point_per_vector;
         for (n = 0; n < ncols; n += col_skip) 
	 {
	    /*  location data */
            for (j = 0; j < dimension; j++) 
	    {
	       index = j * bandsize + k;
	       location[index] = data[l++];
	    }
	    k++;

	    /*  band data */
            for (j = 0; j < numbands; j++) 
	    {
     	       if (complex == 1)            /* data is complex */
	       {
	          index = j * bandsize * 2 + i;
	          bands[index]    = data[l++];
	          bands[index +1] = data[l++];
	       }
	       else
	       {
	          index = j * bandsize + i;
	          bands[index] = data[l++];
	       }
	    }

	    if (complex == 1)
	       i += 2;
	    else
	       i++;

	    /*  skip factor */
	    l += (col_skip -1) * point_per_vector;
        }
     }
   }
}
