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

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

 /*
  * $Log: lvect2row.c,v $
 * Revision 1.1  1991/05/10  15:41:54  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, 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 to 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 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: lvect2row.c
 >>>>
 >>>>      Program Name: vect2row
 >>>>
 >>>> Date Last Updated: Sun Apr 28 22:35:14 1991 
 >>>>
 >>>>          Routines: lvect2row - the library call for vect2row
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvect2row - library call for vect2row
*
* Purpose:
*    
*    reformats data stored in vector format to a single-band file
*    where  each  vector  is represented as a separate row in the
*    output file.
*    
*    
* Input:
*    
*    *image         pointer the input/output xvimage structure
*    
*    single_vect    integer flag which, if set to  1,  indicates  that
*                   only on vector is to be extracted
*    
*    row_offset     integer, if single_vect is set, this  defines  the
*                   row position of the targeted pixel
*    
*    col_offset     integer, if single_vect is set, this  defines  the
*                   column position of the targeted pixel
*    
*    
* Output:
*    
*    *image         pointer to the input/output (struct xvimage)
*    
*    
*
* Written By: Donna Koechner
*    
*    Tue May 22 21:10:52 MDT 1990 Donna Koechner - updated  to  ghost-
*    writer
*    Audit Done  05-OCT-90  Donna Koechner
*    Sun Feb 24 1991 Updated to work on all VFF  types  except  BIT  -
*    Donna Koechner
*    
*    
****************************************************************/


/* -library_def */
int 
lvect2row ( image, single_vect, row_offset, col_offset, process_dir )
struct xvimage  *image;
int             single_vect,    /* flag set to 1 if only 1 vector extracted */
                row_offset,     /* if single_vect = 1, pixel row index */
                col_offset,     /* if single_vect = 1, pixel col index */
                process_dir;    /* 0 = DSP_VECTOR, 1 = DSP_BAND */
/* -library_def_end */

/* -library_code */
{
  int           offset,         /* offset (floats) if single_vect = 1 */
                dimension,      /* dimension returned by dload_vector */
                num_vects,      /* number of vectors returned dload_vector */
                new_rows,       /* number of rows in output image */
                **long_v,       /* vector array returned by dload_vector */
                *long_tmp,
                ind, i, j;
  short         **short_v,      /* vector array returned by dload_vector */
                *short_tmp;

  char          **char_v,       /* vector array returned by dload_vector */
                *char_tmp;

  float         **float_v,      /* vector array returned by dload_vector */
                *float_tmp;

  double        **double_v,     /* vector array returned by dload_vector */
                *double_tmp;

  char          **dload_vector();
  char *program = "lvect2row";


  switch(image->data_storage_type) {

    case VFF_TYP_BIT:
         fprintf(stderr,"%s: Cannot operate on VFF_TYP_BIT data.", program);
         return(0);

    case VFF_TYP_1_BYTE:
         /* get data into vector format */
         char_v = (char **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(char_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         new_rows = num_vects;

        /* Reassign data in row format (char_tmp points to same memory
         * as image->imagedata) */
         char_tmp = image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             char_tmp[ind + j] = char_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension;
           new_rows = 1;
           /* allocate temporary array */
           if((char_tmp = (char *)(malloc((unsigned int) dimension * 
                sizeof(unsigned char)))) == NULL) {
             (void)fprintf(stderr,"lvect2row: cannot allocate char array\n");
             return(0);
           }
        
           bcopy(&image->imagedata[offset], char_tmp, dimension);
           free(image->imagedata);
           image->imagedata = (char *) char_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for (i=0; i<num_vects; i++) 
           free(char_v[i]);
         free(char_v);

         break;


    case VFF_TYP_2_BYTE:
         /* get data into vector format */
         short_v = (short **)(dload_vector(image, &num_vects, &dimension, 
                                          process_dir));
         if(short_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         new_rows = num_vects;

        /* Reassign data in row format (short_tmp points to same memory
         * as image->imagedata) */
         short_tmp = (short *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             short_tmp[ind + j] = short_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(short);
           new_rows = 1;
           /* allocate temporary array */
           if((short_tmp = (short *)(malloc((unsigned int) dimension * 
                sizeof(short)))) == NULL)
           {
             (void)fprintf(stderr,"lvect2row: cannot allocate short array\n");
             return(0);
           }

           bcopy(&image->imagedata[offset], short_tmp, dimension * 
                 sizeof(short));
           free(image->imagedata);
           image->imagedata = (char *) short_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for (i=0; i<num_vects; i++) 
           free(short_v[i]);
         free(short_v);

         break;


    case VFF_TYP_4_BYTE:
         /* get data into vector format */
         long_v = (int **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(long_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         new_rows = num_vects;

        /* Reassign data in row format (long_tmp points to same memory
         * as image->imagedata) */
         long_tmp = (int *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             long_tmp[ind + j] = long_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(int);
           new_rows = 1;
           /* allocate temporary array */
           if((long_tmp = (int *)(malloc((unsigned int) dimension * 
                  sizeof(int)))) == NULL) {
             (void)fprintf(stderr,"lvect2row: cannot allocate long array\n");
             return(0);
           }

           bcopy(&image->imagedata[offset], long_tmp, dimension * 
                 sizeof(int));
           free(image->imagedata);
           image->imagedata = (char *) long_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for (i=0; i<num_vects; i++) 
           free(long_v[i]);
         free(long_v);

         break;


    case VFF_TYP_FLOAT:
         /* get data into vector format */
         float_v = (float **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(float_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         new_rows = num_vects;

        /* Reassign data in row format (float_tmp points to same memory as
         * image->imagedata) */
         float_tmp = (float *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             float_tmp[ind + j] = float_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(float);
           new_rows = 1;
           if((float_tmp = (float *)(malloc((unsigned int) dimension *
                sizeof(float)))) == NULL){
             (void)fprintf(stderr,"lvect2row: cannot allocate float array\n");
             return(0);
           }
        
           bcopy(&image->imagedata[offset], float_tmp, 
                                dimension * sizeof(float));
           free(image->imagedata);
           image->imagedata = (char *) float_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for(i=0; i<num_vects; i++)
           free(float_v[i]);
         free(float_v);

         break;

    case VFF_TYP_COMPLEX:
         /* get data into vector format */
         float_v = (float **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(float_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         dimension *= 2;
         new_rows = num_vects;

        /* Reassign data in row format (float_tmp points to same memory as
         * image->imagedata) */
         float_tmp = (float *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             float_tmp[ind + j] = float_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(float);
           new_rows = 1;
           /* allocate temporary array */
           if((float_tmp = (float *)(malloc((unsigned int) dimension * 
                sizeof(float)))) == NULL)
           {
             (void)fprintf(stderr,"lvect2row: cannot allocate complex array\n");
             return(0);
           }

           bcopy(&image->imagedata[offset], float_tmp, 
                                dimension * sizeof(float));
           free(image->imagedata);
           image->imagedata = (char *) float_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for(i=0; i<num_vects; i++)
           free(float_v[i]);
         free(float_v);

         break;


    case VFF_TYP_DOUBLE:
         /* get data into vector format */
         double_v = (double **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(double_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         new_rows = num_vects;

        /* Reassign data in row format (double_tmp points to same memory as
         * image->imagedata) */
         double_tmp = (double *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             double_tmp[ind + j] = double_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(double);
           new_rows = 1;
           /* allocate temporary array */
           if((double_tmp = (double *)(malloc((unsigned int) dimension * 
                sizeof(double)))) == NULL)
           {
             (void)fprintf(stderr,"lvect2row: cannot allocate double array\n");
             return(0);
           }

           bcopy(&image->imagedata[offset], double_tmp, 
                                dimension * sizeof(double));
           free(image->imagedata);
           image->imagedata = (char *) double_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for(i=0; i<num_vects; i++)
           free(double_v[i]);
         free(double_v);

         break;


    case VFF_TYP_DCOMPLEX:
         /* get data into vector format */
         double_v = (double **)dload_vector(image, &num_vects, &dimension, 
                                          process_dir);
         if(double_v == NULL) {
           (void) fprintf(stderr,"lvect2row: dload_vector failed\n");
           return(0);
         }

         dimension *= 2;
         new_rows = num_vects;

        /* Reassign data in row format (double_tmp points to same memory as
         * image->imagedata) */
         double_tmp = (double *) image->imagedata;
         for (i=0; i<num_vects; i++) {
           ind = (i * dimension);
           for (j=0; j<dimension; j++) {
             double_tmp[ind + j] = double_v[i][j];
           }
         }

         if (single_vect) {
           offset = ((row_offset * image->row_size) + col_offset ) * dimension
                        * sizeof(double);
           new_rows = 1;
           /* allocate temporary array */
           if((double_tmp = (double *)(malloc((unsigned int) dimension * 
                sizeof(double)))) == NULL)
           {
             (void)fprintf(stderr,"lvect2row: cannot allocate dcomplex array\n");
             return(0);
           }

           bcopy(&image->imagedata[offset], double_tmp, 
                                dimension * sizeof(double));
           free(image->imagedata);
           image->imagedata = (char *) double_tmp;
         }

         /* free the vector array allocated in dload_vector */
         for(i=0; i<num_vects; i++)
           free(double_v[i]);
         free(double_v);

         break;

  } /* end of data_storage_type case statement */


 /* If entire image is stored, set map_subrow_size for inverse conversion. */
  if(single_vect) {
    image->startx = col_offset;
    image->starty = row_offset;
  }
  else
    image->subrow_size = image->row_size;

  image->col_size = new_rows;
  image->row_size = image->num_data_bands;
  image->num_data_bands = 1;
  

  return(TRUE);
}
/* -library_code_end */
