 /*
  * Khoros: $Id: ldinsert.c,v 1.2 1992/03/20 23:27:40 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: ldinsert.c,v 1.2 1992/03/20 23:27:40 dkhoros Exp $";
#endif

 /*
  * $Log: ldinsert.c,v $
 * Revision 1.2  1992/03/20  23:27:40  dkhoros
 * VirtualPatch5
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * 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: ldinsert.c
 >>>>
 >>>>      Program Name: dinsert
 >>>>
 >>>> Date Last Updated: Sat Feb 15 16:34:55 1992 
 >>>>
 >>>>          Routines: ldinsert - the library call for dinsert
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


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


/****************************************************************
*
* Routine Name: ldinsert - library call for dinsert
*
* Purpose:
*    
*    Inserts 1-D format file into another 1-D file.
*    
*    

* Input:
*    
*    *img1          (struct xvimage) -  pointer  to  the  input/output
*                   xvimage structure
*    
*    *img2          (struct xvimage) - pointer to  the  input  xvimage
*                   structure to be inserted
*    
*    *s_img         (struct xvimage) - pointer to the starting  insert
*                   value input image (int)
*    
*    s_img_flg      (int) - flag set to 1  if  starting  insert  value
*                   image was specified.
*    
*    start          (int) - constant starting insert value
*    
*    append_flg     (int) - flag set to 1 if img2 vectors  are  to  be
*                   appended to end of img1 vectors.
*    
*    process_dir    (int) - data processing direction. 0 = vector, 1 =
*                   band.
*    
*    

* Output:
*    
*    *img1          (struct xvimage) -  pointer  to  the  input/output
*                   xvimage structure
*    
*    

*
* Written By: Donna Koechner
*    
*    Thu Jun  7 20:47:20 MDT 1990 Donna  Koechner  -  updated  to
*    ghostwriter
*    Audit Done  04-OCT-90  Donna Koechner
*    
*    

****************************************************************/


/* -library_def */
int
ldinsert(img1, img2, s_img, s_img_flg, start, append_flg, process_dir)

struct xvimage  *img1,          /* input/output image */
                *img2,          /* image to be inserted into img1 */
                *s_img;         /* starting point file for inserting */
int             s_img_flg,      /* flag for starting point file */
                start,          /* insert point */
                append_flg,     /* flag set to one if appending to end */
                process_dir;    /* direction of processing 0=vect, 1= band */
/* -library_def_end */

/* -library_code */
{ 

  int           arith,                  /* scale factor: real=1, cmplx=2 */
                num_vects1,             /* number of vectors in img1 */
                num_vects2,             /* number of vectors in img2 */
                dim1,                   /* dimension of vectors in img1 */
                dim2,                   /* dimension of vectors in img2 */
                insert_val,             /* local start insert variable */
                i, j, m,                /* loop variables */
                *s_array;               /* start array from s_img */
                
  float         **data1,                /* input data array */
                **data2,                /* input data array */
                **out_data;             /* inserted data array */

  char          **dload_vector();

  if( ! (propertype("ldinsert",img1,VFF_TYP_FLOAT,FALSE)) && 
      ! (propertype("ldinsert",img1,VFF_TYP_COMPLEX,FALSE)) ) { 
      fprintf(stderr,"ldinsert: data storage type must be float or complex.\n");
      return(0); 
  }

  if( ! matchtype("ldinsert",img1,img2,FALSE)) {
      fprintf(stderr,"ldinsert: data storage types of both files must be ");
      fprintf(stderr," the same.\n");
      return(0); 
  }

  if( ! (proper_loc_type("ldinsert",img1,VFF_LOC_IMPLICIT,FALSE)) ||
      ! (match_loc_type("ldinsert",img1,img2,FALSE)) ) {
      fprintf(stderr,"ldinsert: file location type must be implicit\n");
      return(0); 
  }


 /*
  * Set up arithmetic type
  */
  arith = 1;
  if (img1->data_storage_type == VFF_TYP_COMPLEX)
  {
    arith = 2;
  }

 /*
  * Call dload_vector for input image (img1)
  */
  if ( ( data1 = (float **)dload_vector(img1, &num_vects1, &dim1, 
                 process_dir)) == NULL)
  {
    (void)fprintf(stderr,"ldinsert: dload_vector for img1 failed\n");
    return(0);
  }

 /*
  * Call dload_vector for input image to insert (img2)
  */
  if ( ( data2 = (float **)dload_vector(img2, &num_vects2, &dim2, 
                 process_dir)) == NULL)
  {
    (void)fprintf(stderr,"ldinsert: dload_vector for img2 failed\n");
    return(0);
  }

 /* 
  * Return error is images do not have same number of vectors or if
  * dimension is not greater than zero.
  */
  if ( num_vects1 != num_vects2 ) 
  {
    (void)fprintf(stderr,"ldinsert: number of vectors in input files do");
    (void)fprintf(stderr,"not agree!\nfile 1 -> %d, file 2 -> %d\n",
                          num_vects1, num_vects2);
    return(0);
  }

  if ( (dim1 < 1) || (dim2 < 1) )
  {
    (void)fprintf(stderr,"ldinsert: an input file has zero dimension!\n");
    return(0);
  }

 /*
  * IF start image was passed in, deal with it.
  */
  if (s_img_flg)
  {
   /*
    * make sure start insert value image is proper type.
    */
    if(!(propertype("ldinsert", s_img, VFF_TYP_4_BYTE, FALSE)) )
    {
      (void)fprintf(stderr,"ldinsert: start value file must be of type int.\n");
      return(0);
    }

   /*
    * verify that starting value file has same number of points as there
    * are vectors in the input file
    */
    if(num_vects1 != (s_img->row_size*s_img->col_size*s_img->num_data_bands) )
    {
      (void)fprintf(stderr,"ldinsert: start value image is wrong size (%d)\n",
                    (s_img->row_size*s_img->col_size*s_img->num_data_bands) );
      (void)fprintf(stderr,"number of vectors in input files is %d\n",
                    num_vects1);
      return(0);
    }

   /*
    * Assign the image data to the shift array.
    */
    s_array = (int *)s_img->imagedata;
  }

 /*
  * Allocate array of vectors for combined data.
  */
  if ( (out_data = (float **) (malloc ((unsigned int) num_vects1 *
        sizeof(float))) ) == NULL)
  {
    (void) fprintf(stderr,"ldinsert: Cannot allocate for output array.\n");
    return(0);
  }
  for (i=0; i<num_vects1; i++)
  {
    if ((out_data[i] = (float *) (malloc ((unsigned int) ((dim1 + dim2) * 
         arith * sizeof(float) )))) == NULL)
    {
      (void)fprintf(stderr,"ldshift: Cannot alloc for output array.\n");
      return(0);
    }
  }

 /*
  * Append Code
  */

  if (append_flg)
  {
    for (i=0; i<num_vects1; i++)
    {
      for (j=0; j<dim1*arith; j++)
      {
        out_data[i][j] = data1[i][j];
      }
      for (j=0,m=(dim1*arith); j<(dim2*arith); j++,m++)
      {
        out_data[i][m] = data2[i][j];
      }
    }
  }  /* end of append code */


 /*
  * Insert Code
  */

  else  
  {
   /*
    * If insert value image flag is not set, assign start value 
    * and check bounds.
    */
    if ( ! s_img_flg )
    {
      insert_val = start;
      if ( insert_val > dim1 )
      {
        (void)fprintf(stderr,"ldinsert: insert_val out of range.");
        (void)fprintf(stderr,"  insert_val = %d, dimension of img1 = %d.\n",
                      insert_val, dim1);
        return(0);
      }
    }
 
    for ( i=0; i<num_vects1; i++)
    {
      if (s_img_flg)
      {
        insert_val = s_array[i]; 
        if( insert_val > dim1 )
        {
          (void)fprintf(stderr,"ldinsert: vector %d insert_val out of range.\n",
                        i);
          (void)fprintf(stderr,"insert_val = %d, dimension = %d.\n",
                        insert_val, dim1);
          return(0);
        }
      }

      m = 0;
      for ( j=0; j<(insert_val*arith); j++)
      {
        out_data[i][m] = data1[i][j];
        m++;
      }
      for ( j=0; j<(dim2*arith); j++)
      {
        out_data[i][m] = data2[i][j];
        m++;
      }
      for ( j=(insert_val*arith); j<(dim1*arith); j++)
      {
        out_data[i][m] = data1[i][j];
        m++;
      }

    }  /* end of loop through vectors */
  }  /* end of insert code */
  

 /*
  * Unload the combined vector array back into img1.
  */
  if (!(dunload_vector((char**)out_data, img1, img1->data_storage_type, 
                       num_vects1, (dim1+dim2), process_dir)) )
  {
    (void)fprintf(stderr,"ldinsert: dunload_vector failed!\n");
    return(0);
  }

  for (i=0; i<num_vects1; i++)
  {
    free((char*)out_data[i]);
  }
  free((char**)out_data);
  return(1);

}  /* end of ldinsert */
/* -library_code_end */
