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

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

 /*
  * $Log: loadvector.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: loadvector.c                           <<<<
   >>>>                                                       <<<<
   >>>>   description: utilities for loading and unloading    <<<<
   >>>>                 an image to a vector array            <<<<
   >>>>                                                       <<<<
   >>>>      routines: load_float_vector(),                   <<<<
   >>>>                load_complex_vector(), 		      <<<<
   >>>>                load_float_vector(),                   <<<<
   >>>>                load_complex_vector(),                 <<<<
   >>>>                load_int_vector(),                     <<<<
   >>>>                load_byte_vector(),                    <<<<
   >>>>                load_short_vector()                    <<<<
   >>>>                load_double_vector(),                  <<<<
   >>>>                load_dcomplex_vector(),                <<<<
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>    		Mon Feb 25 1991 - added double and    <<<<
   >>>>			double complex capabilities	      <<<<
   >>>>			Donna Koechner			      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include	<stdio.h>
#include "viff.h"	

/************************************************************
*
*  Routine Name:  load_vector()
*
*          Date:  Thu Apr  5 11:46:03 MDT 1990
*        
*       Purpose:  
*              takes a multiband image and rearanges the data so
*	       that the data is stored as a list of vectors.
*	       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 routine 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.
*
*              When a border is specified a row and coluwn on each
*	       side of the image is dropped.
*	       
*
*         Input: 
*               struct xvimage *image - a pointer to the image to
*		                       vectorize.
*		border - the border width to skip.
*
*
*        Output: 
*              returns a (char **) 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 by: 
*
*    Written By:  Tom Sauer
*
*************************************************************/

char **load_vector(image, border, num_vects, dimension)
struct xvimage *image;
int border;
int *num_vects, *dimension;

{
    char **output_vectors, **load_char_vector();
    float **float_vectors, **load_float_vector(), **load_complex_vector();
    double **double_vectors, **load_double_vector(), **load_dcomplex_vector();
    int **load_int_vector(), **int_vectors;
    short **load_short_vector(), **short_vectors;
    char *program = "load_vector";

    switch(image->data_storage_type) 
    {
       case VFF_TYP_BIT:
          fprintf(stderr, "%s: Can not work on BIT data storage type\n",program);
          fprintf(stderr, "Can only convert type Byte, Short, Integer, ");
          fprintf(stderr, "Float\nand Complex\n");
          return(NULL);
          break;

       case VFF_TYP_1_BYTE:
          output_vectors = load_char_vector(image,border,num_vects,dimension);
          if (output_vectors == NULL)
          {
             fprintf(stderr, "%s: load_char_vector failed\n", program);
             return(NULL);
          }
          break;

       case VFF_TYP_2_BYTE:
          short_vectors = load_short_vector(image,border,num_vects,dimension);
          if (short_vectors == NULL)
          {
             fprintf(stderr, "%s: load_short_vector failed\n", program);
             return(NULL);
          }
          output_vectors = (char **) short_vectors;
          break;

       case VFF_TYP_4_BYTE:
          int_vectors = load_int_vector(image,border,num_vects,dimension);
          if (int_vectors == NULL)
          {
             fprintf(stderr, "%s: load_int_vector failed\n", program);
             return(NULL);
          }
          output_vectors = (char **) int_vectors;
          break;

       case VFF_TYP_FLOAT:
          float_vectors = load_float_vector(image,border,num_vects,dimension);
          if (float_vectors == NULL)
          {
             fprintf(stderr, "%s: load_float_vector failed\n", program);
             return(NULL);
          }
          output_vectors = (char **) float_vectors;
          break;

       case VFF_TYP_COMPLEX:
          float_vectors = load_complex_vector(image,border,num_vects,dimension);
          if (float_vectors == NULL)
          {
             fprintf(stderr, "%s: load_complex_vector failed\n", program);
             return(NULL);
          }

          output_vectors = (char **) float_vectors;
          break;

       case VFF_TYP_DOUBLE:
          double_vectors = load_double_vector(image,border,num_vects,dimension);
          if (double_vectors == NULL)
          {
             fprintf(stderr, "%s: load_double_vector failed\n", program);
             return(NULL);
          }
          output_vectors = (char **) double_vectors;
          break;

       case VFF_TYP_DCOMPLEX:
          double_vectors = load_dcomplex_vector(image,border,num_vects,
			   dimension);
          if (double_vectors == NULL)
          {
             fprintf(stderr, "%s: load_dcomplex_vector failed\n", program);
             return(NULL);
          }

          output_vectors = (char **) double_vectors;
          break;

       default:
          fprintf(stderr, "%s: Invalid image Data Storage type\n", program);
          fprintf(stderr, "Can only convert type Byte, Short, Integer, ");
          fprintf(stderr, "Float\nand Complex\n");
          return(NULL);
          break;
      }

       return(output_vectors);
}


/************************************************************
*
*  Routine Name:   load_byte_vector()
*
*          Date:    Thu Apr  5 11:22:17 MDT 1990
*        
*       Purpose:     a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a char 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

char **load_char_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{


    char *program = "load_char_vector";
    char **output_vectors, *cptr;
    int m, i, j, k;
    int nr, nc;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;

    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));


              /* Allocate space for output_vectors image */

    output_vectors = (char **)malloc((unsigned int) *num_vects * sizeof (char *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
      /* vectorize the data, such that the border width is ignored */

    for (i = 0; i < *num_vects; i++) 
    {
       output_vectors[i] = (char *) malloc (*dimension * sizeof (char));
       if (output_vectors[i] == NULL) 
       {
          (void) fprintf (stderr,
               "%s: insufficient memory available\n",program);
           return (NULL);
       }
    }

    /* Assign image data address to ptr */

    cptr = (char *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       for (j = border; j < nc - border; j++) 
       {
	  for (k = 0; k < *dimension; k++) 
          {
	       output_vectors[m][k] = cptr[(i * nc + j) + (k * nc * nr)];
	  }
	  m++;
       }
    }
    return(output_vectors);
}

/************************************************************
*
*  Routine Name:   load_short_vector()
*
*          Date:    Thu Apr  5 11:22:17 MDT 1990
*        
*       Purpose:     a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a short 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

short **load_short_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{

    char *program = "load_short_vector";
    short **output_vectors, *sptr;
    int m, i, j, k;
    int nr, nc;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;

    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));


              /* Allocate space for output_vectors image */

    output_vectors = (short **)malloc((unsigned int) *num_vects * sizeof (short *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
      /* vectorize the data, such that the border width is ignored */

    for (i = 0; i < *num_vects; i++) 
    {
       output_vectors[i] = (short *) malloc (*dimension * sizeof (short));
       if (output_vectors[i] == NULL) 
       {
          (void) fprintf (stderr,
               "%s: insufficient memory available\n",program);
           return (NULL);
       }
    }

    /* Assign image data address to ptr */

    sptr = (short *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       for (j = border; j < nc - border; j++) 
       {
	  for (k = 0; k < *dimension; k++) 
          {
	       output_vectors[m][k] = sptr[(i * nc + j) + (k * nc * nr)];
	  }
	  m++;
       }
    }
    return(output_vectors);
}

/************************************************************
*
*  Routine Name:   load_int_vector()
*
*          Date:    Thu Apr  5 11:22:17 MDT 1990
*        
*       Purpose:     a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a int 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

int **load_int_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{

    char *program = "load_int_vector";
    int **output_vectors, *iptr;
    int m, i, j, k;
    int nr, nc;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;

    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));


              /* Allocate space for output_vectors image */

    output_vectors = (int **)malloc((unsigned int) *num_vects * sizeof (int *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
      /* vectorize the data, such that the border width is ignored */

    for (i = 0; i < *num_vects; i++) 
    {
       output_vectors[i] = (int *) malloc (*dimension * sizeof (int));
       if (output_vectors[i] == NULL) 
       {
          (void) fprintf (stderr,
               "%s: insufficient memory available\n",program);
           return (NULL);
       }
    }

    /* Assign image data address to ptr */

    iptr = (int *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       for (j = border; j < nc - border; j++) 
       {
	  for (k = 0; k < *dimension; k++) 
          {
	       output_vectors[m][k] = iptr[(i * nc + j) + (k * nc * nr)];
	  }
	  m++;
       }
    }
    return(output_vectors);
}

/************************************************************
*
*  Routine Name:   load_float_vector()
*
*          Date:    Thu Apr  5 11:22:17 MDT 1990
*        
*       Purpose:     a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a float 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

float **load_float_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{


    char *program = "load_float_vector";
    float **output_vectors, *fptr;
    int m, i, j, k;
    int nr, nc;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;

    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));


              /* Allocate space for output_vectors image */

    output_vectors = (float **)malloc((unsigned int) *num_vects * sizeof (float *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available for pointer array\n",program);
	return (NULL);
    }
      /* vectorize the data, such that the border width is ignored */

    for (i = 0; i < *num_vects; i++) 
    {
       output_vectors[i] = (float *) malloc (*dimension * sizeof (float));
       if (output_vectors[i] == NULL) 
       {
          (void) fprintf (stderr,
               "%s: insufficient memory available for additional output vector\n",program);
           return (NULL);
       }
    }

    /* Assign image data address to ptr */

    fptr = (float *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       for (j = border; j < nc - border; j++) 
       {
	  for (k = 0; k < *dimension; k++) 
          {
	       output_vectors[m][k] = fptr[(i * nc + j) + (k * nc * nr)];
	  }
	  m++;
       }
    }
    return(output_vectors);
}

/************************************************************
*
*  Routine Name:   load_complex_vector()
*
*          Date:    Thu Apr  5 11:22:17 MDT 1990
*        
*       Purpose:     takes a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a complex 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

float **load_complex_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{

    char *program = "load_complex_vector";
    float **output_vectors, *fptr;
    int m, i, j, k, p;
    int nr, nc, q;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;


    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));

              /* Allocate space for output_vectors image */

    output_vectors = (float **)malloc((unsigned int) *num_vects * sizeof (float *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
    for (i = 0; i < *num_vects; i++) 
    {
        output_vectors[i] = (float *)malloc(*dimension * 2 * sizeof (float));
        if (output_vectors[i] == NULL) 
        {
           (void) fprintf (stderr,
                  "%s: insufficient memory available\n", program);
	   return (NULL);
	}
    }

    /* Assign image data address to ptr */

    fptr = (float *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       q = border*2;
       for (j = border; j < nc - border; j++ ) 
       {
          p = 0;
          for (k = 0; k < *dimension; k++) 
          {
	    output_vectors[m][p] = fptr[(i * nc*2 + q)+(k * nc * nr*2)];
            p++;
            output_vectors[m][p] = fptr[(i * nc*2 + q+1)+(k * nc *nr*2)];
            p++;
          }
          q +=2;
          m++;
       }
    }
    return(output_vectors);
}


/************************************************************
*
*  Routine Name:   load_double_vector()
*
*          Date:    Mon Feb 25 12:43:24 MST 1991
*        
*       Purpose:     a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a double 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

double **load_double_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{


    char *program = "load_double_vector";
    double **output_vectors, *dptr;
    int m, i, j, k;
    int nr, nc;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;

    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));


              /* Allocate space for output_vectors image */

    output_vectors = (double **)malloc((unsigned int) *num_vects * sizeof (double *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
      /* vectorize the data, such that the border width is ignored */

    for (i = 0; i < *num_vects; i++) 
    {
       output_vectors[i] = (double *) malloc (*dimension * sizeof (double));
       if (output_vectors[i] == NULL) 
       {
          (void) fprintf (stderr,
               "%s: insufficient memory available\n",program);
           return (NULL);
       }
    }

    /* Assign image data address to ptr */

    dptr = (double *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       for (j = border; j < nc - border; j++) 
       {
	  for (k = 0; k < *dimension; k++) 
          {
	       output_vectors[m][k] = dptr[(i * nc + j) + (k * nc * nr)];
	  }
	  m++;
       }
    }
    return(output_vectors);
}

/************************************************************
*
*  Routine Name:   load_dcomplex_vector()
*
*          Date:    Mon Feb 25 13:12:32 MST 1991
*        
*       Purpose:     takes a multiband image and rearanges the data so
*              	     that the data is stored as a list of vectors.
*                    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 routine 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.
*
*                    When a border is specified a row and coluwn on each
*                    side of the image is dropped.
*
*         Input:     struct xvimage *image - a pointer to the image to
*                                      vectorize.
*               border - the border width to skip.
*
*        Output: returns a double complex 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 by: load_vector()
*
*    Written By:  Tom Sauer
*
*************************************************************/

double **load_dcomplex_vector(image, border, num_vects, dimension)

struct xvimage *image;
int border;
int *num_vects, *dimension;
{

    char *program = "load_dcomplex_vector";
    double **output_vectors, *dptr;
    int m, i, j, k, p;
    int nr, nc, q;

    *dimension = image->num_data_bands;
    nr = image->col_size;
    nc = image->row_size;


    if ((nr - (border*2) <= 0) || (nc  - (border*2) <= 0))
    {
       (void) fprintf (stderr,"%s: border size is too large\n",program);
       return (NULL);
    }

        /* calculate the total number of vectors */

    *num_vects = (image->row_size-(border*2)) * (image->col_size-(border*2));

              /* Allocate space for output_vectors image */

    output_vectors = (double **)malloc((unsigned int) *num_vects * sizeof (double *));
    if (output_vectors == NULL) 
    {
        (void) fprintf (stderr, "%s: insufficient memory available\n",program);
	return (NULL);
    }
    for (i = 0; i < *num_vects; i++) 
    {
        output_vectors[i] = (double *)malloc(*dimension * 2 * sizeof (double));
        if (output_vectors[i] == NULL) 
        {
           (void) fprintf (stderr,
                  "%s: insufficient memory available\n", program);
	   return (NULL);
	}
    }

    /* Assign image data address to ptr */

    dptr = (double *) image->imagedata;

          /* Assign ptr to output vectors minus the border */

    m = 0;
    for (i = border; i < nr - border; i++) 
    {
       q = border*2;
       for (j = border; j < nc - border; j++ ) 
       {
          p = 0;
          for (k = 0; k < *dimension; k++) 
          {
	    output_vectors[m][p] = dptr[(i * nc*2 + q)+(k * nc * nr*2)];
            p++;
            output_vectors[m][p] = dptr[(i * nc*2 + q+1)+(k * nc *nr*2)];
            p++;
          }
          q +=2;
          m++;
       }
    }
    return(output_vectors);
}
