 /*
  * Khoros: $Id: dloadvect.c,v 1.1 1991/05/10 15:41:35 khoros Exp $
  */

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

 /*
  * $Log: dloadvect.c,v $
 * Revision 1.1  1991/05/10  15:41:35  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.
 *---------------------------------------------------------------------
 */

/*
#
# FILE NAME:	dloadvector.c
# 
# AUTHORS: 	Donna Koechner
#
# 
# DATE:		2/9/90
# 
# DESCRIPTION:	Utility for loading an image to a vector array.
#	
# MODIFICATIONS: Mon Feb 25 1991 - added double and double complex
#		 capabilities - Donna Koechner
#			
*/

#include "unmcopyright.h"	 
#include "vinclude.h"	 	

/**************************************************************
*
* MODULE NAME: 	dload_vector
*
*     PURPOSE:	dload_vector is a dsp utility which takes a multiband 
*		data file and rearanges the data so that the it is stored 
*             	as a list of vectors.
*
*		dload_vector should be called at the beginning of each 
*		dsp1 routine to convert data to vector format.  It formats 
*		the data according to the process direction (DSP_VECTOR,
*		DSP_BAND) passed in.  
*		A **char vector data array is returned, and the values for
*		the num_vects and dimension are set.  Dimension refers
*		to the number of points in each vector.  If the data
*		is complex, dimension is the number of complex PAIRS
*		per vector.
*
*		Dload_vector checks that number of image data bands is 
*		at least 1.  If data processing is in DSP_VECTOR direction,
*		Calls load_vector.  If data processing is in DSP_BAND 
*		direction, assigns data to 2 dimensional vector array.
*			
*		DSP_VECTOR Processing Direction:
*              	Each pixel in a multiband image can be thought of
*              	as a vector looking down all the bands. Thus, each
*              	pixel is a vector with dimension = number of data bands.
*		This format is obtained if the parameter, process_dir,
*		passed to dload_vector is DSP_VECTOR (0).
*		Memory is allocated for the vector array by load_vector.
*
*      	        When process_dir = DSP_VECTOR, dload_vector will scan the 
*		image row by row making a linear 
*      	        2-dimensional array, where the first array index
*      	        points to a vector (which corresponds to some pixel),
*      	        the second array index contains the values for that
*      	        pixel looking down the bands on the image.
*		Memory is allocated for the vector array in dload_vector.
*
*		DSP_BAND Processing Direction:
*		If process_dir is DSP_BAND (1), the calling routine requires
*		that each data band be represented as a vector.  Therefore
*		dload_vector will return a 2-dimensional array where
*		each band is a vector of dimension rows*cols.  
*
*		Data type can be of any type except BIT.
*
*       INPUT:  struct xvimage *image - a pointer to the image to
*                                      vectorize.
*
*		int - process_dir - a flag set to DSP_VECTOR (0) the data 
*				    is to be vectorized down the bands, and
*				    set to DSP_BAND (1) if each band is to 
*				    be returned as a vector.
*
*      OUTPUT: 	returns a pointer to a 2-d array containing the
*               vectorized data.
*
*              	int - num_vects - the total number of vectors loaded into
*                                 the array
*
*              	int - dimension - the dimension of each vector.
*
*
* CALLED FROM: 		main
*
* ROUTINES CALLED:	load_vector()
*
**************************************************************/

/*ADD_SRC*/


char **dload_vector(image, num_vects, dimension, process_dir)

struct xvimage	*image;
int 		*num_vects, *dimension, process_dir;

{
  int   border,			/* image border (set to zero for now) */
	i,j,indx;

  short *sptr, **sdata;		/* short pointer and vector array */
  int   *iptr, **idata;		/* int pointer and vector array */
  float	*fptr, **fdata;		/* float pointer and vector array */
  double *dptr, **ddata;	/* double pointer and vector array */

  char	*cptr, **data,		/* byte pointer and vector array */
	**load_vector();

  char  *prog = "dload_vector: ";


 /*
  * If image has less than one band, there is an error in the input.
  */
  
  if (image->num_data_bands < 1)
  {
    (void) fprintf(stderr,"dload_vector:  invalid number of data bands ");
    (void) fprintf(stderr,"(%d) in input image\n", image->num_data_bands);
    return(0);
  }

 /*
  * If process direction is down vectors, or the input file has
  * only one data band, call load_vector routine 
  * to rearrange data.  If the data is complex, 
  * load_vector returns dimension which is 2 times the number of bands.
  */

  if ( (process_dir == DSP_VECTOR) && (image->num_data_bands != 1) )
  {
    border = 0;
    data = load_vector(image, border, num_vects, dimension);
    if (data == NULL)
    {
      (void)fprintf(stderr,"load_vector failed!\n");
      return(0);
    }
  }

  else   /* processing across bands, or only one band present */
  {
   /*
    * Assign num_vects and dimension values 
    */
    *num_vects = image->num_data_bands;
    *dimension = image->col_size * image->row_size;

    switch(image->data_storage_type) 
    {
      case VFF_TYP_BIT:
           (void)fprintf(stderr,"%sCannot work on BIT data type\n",prog);
           return(0);

      case VFF_TYP_1_BYTE:
           /*
            * allocate the data array 
            */
            if((data = (char **) (malloc((unsigned int) *num_vects * 
                       sizeof(char *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: byte malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((data[i] = (char *) (malloc((unsigned int) *dimension *
                             sizeof(char) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: byte malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            cptr = (char *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<*dimension; j++)
              {
                data[i][j] = cptr[indx];
	        indx++;
              }
            }
	    break;

      case VFF_TYP_2_BYTE:
           /*
            * allocate the data array 
            */
            if((sdata = (short **) (malloc((unsigned int) *num_vects * 
                        sizeof(short *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: short malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((sdata[i] = (short *) (malloc((unsigned int) *dimension *
                              sizeof(short) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: short malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            sptr = (short *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<*dimension; j++)
              {
                sdata[i][j] = sptr[indx];
	        indx++;
              }
            }
            data = (char **) sdata;
	    break;

      case VFF_TYP_4_BYTE:
           /*
            * allocate the data array 
            */
            if((idata = (int **) (malloc((unsigned int) *num_vects * 
                        sizeof(int *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: int malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((idata[i] = (int *) (malloc((unsigned int) *dimension *
                              sizeof(int) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: int malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            iptr = (int *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<*dimension; j++)
              {
                idata[i][j] = iptr[indx];
	        indx++;
              }
            }
            data = (char **) idata;
	    break;

      case VFF_TYP_FLOAT:
           /*
            * allocate the data array 
            */
            if((fdata = (float **) (malloc((unsigned int) *num_vects * 
                        sizeof(float *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: float malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((fdata[i] = (float *) (malloc((unsigned int) *dimension *
                              sizeof(float) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: float malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            fptr = (float *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<*dimension; j++)
              {
                fdata[i][j] = fptr[indx];
	        indx++;
              }
            }
            data = (char **) fdata;
	    break;

      case VFF_TYP_COMPLEX:
           /*
            * allocate the data array 
            */
            if((fdata = (float **) (malloc((unsigned int) *num_vects * 
                        sizeof(float *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: complex malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((fdata[i] = (float *) (malloc((unsigned int) *dimension *
                              2 * sizeof(float) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: complex malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            fptr = (float *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<(*dimension*2); j++)
              {
                fdata[i][j] = fptr[indx];
	        indx++;
              }
            }
            data = (char **) fdata;
	    break;

      case VFF_TYP_DOUBLE:
           /*
            * allocate the data array 
            */
            if((ddata = (double **) (malloc((unsigned int) *num_vects * 
                        sizeof(double *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: double malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((ddata[i] = (double *) (malloc((unsigned int) *dimension *
                              sizeof(double) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: double malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            dptr = (double *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<*dimension; j++)
              {
                ddata[i][j] = dptr[indx];
	        indx++;
              }
            }
            data = (char **) ddata;
	    break;

      case VFF_TYP_DCOMPLEX:
           /*
            * allocate the data array 
            */
            if((ddata = (double **) (malloc((unsigned int) *num_vects * 
                        sizeof(double *) ))) == NULL)
            {
              (void)fprintf(stderr,"dload_vector: dcomplex malloc failed\n");
              return(0);
            }
            for(i=0; i<*num_vects; i++)
            {
              if ((ddata[i] = (double *) (malloc((unsigned int) *dimension *
                              2 * sizeof(double) ))) == NULL)
              {
                (void)fprintf(stderr,"dload_vector: dcomplex malloc failed\n");
                return(0);
              }
            }

           /*
            * Assign image data address to ptr.
            */
            dptr = (double *) image->imagedata;
        
           /*
            * Assign ptr to output data 
            */
            indx = 0;
            for (i=0; i<*num_vects; i++)
            {
              for (j=0; j<(*dimension*2); j++)
              {
                ddata[i][j] = dptr[indx];
	        indx++;
              }
            }
            data = (char **) ddata;
	    break;

      default:
	   (void)fprintf(stderr,"%sInvalid image data storage type\n",prog);
	   (void)fprintf(stderr,"Can only convert type BYTE, SHORT, INTEGER,");
	   (void)fprintf(stderr,"Float\nand Complex\n");
	   return(0);

    }  /* end of case statement */

  }
  return(data);
}
