 /*
  * Khoros: $Id: lraw2viff.c,v 1.3 1992/03/20 23:35:44 dkhoros Exp $
  */

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

 /*
  * $Log: lraw2viff.c,v $
 * Revision 1.3  1992/03/20  23:35:44  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: lraw2viff.c
 >>>>
 >>>>      Program Name: raw2viff
 >>>>
 >>>> Date Last Updated: Wed Nov 13 12:33:45 1991 
 >>>>
 >>>>          Routines: lraw2viff - the library call for raw2viff
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


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


/****************************************************************
*
* Routine Name: lraw2viff - library call for raw2viff
*
* Purpose:
*    
*    Transforms RAW data into the VIFF file format.
*    
*    

* Input:
*    
*         filename: filename of the INPUT RAW file
*    
*    image:the resulting viff image
*    
*    nrows:number of rows
*    
*    ncols:number of columns
*    
*    start:start offset for each band
*    
*    row_skip, col_skip:
*          number of points to be skipped along the column and rows.
*    
*    numbands:
*         number of bands in the file
*    
*    dimension:
*          number of locations bands default is  0  which  implies  an
*         implicit image
*    
*    interleave:
*         whether data is interleaved or not
*    
*    data_type:
*         a viff image type that will be used by lvconvert to  convert
*         the float file to the proper output type.
*    
*    mach_type:
*         The machine order of the  incoming  raw  data.  Valid  order
*         types are VFF_DEP_IEEE, VFF_DEP_NSORDER or VFF_DEP_DECORDER.
*    
*    

* Output:
*    
*         image: holds the result.
*    
*    

*
* Written By: Ramiro Jordan, Mike Lang, Mark Young, Tom Sauer
*    
*    Ghosted by Pascal ADAM  14-JUNE-90
*    
*    

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


/* -library_def */
int
lraw2viff(filename, image, nrows, ncols, offset, start, row_skip, col_skip,
          numbands, dimension, interleave, data_type, mach_type)

int     nrows, ncols, offset, start, row_skip, col_skip, numbands, dimension, 
        interleave, data_type, mach_type;
char    *filename;
struct  xvimage **image;

/* -library_def_end */

/* -library_code */
{
   float    *data, *new_read_raw();
   int      size, nr, nc, length, numsets, complex;
   struct   xvimage *img, *createimage();
   unsigned long data_storage_type, location_type;
   int file;
   int force_convert;   /* force a convert for complicated conversions */

   /*
    *  Do some error checking.  Make sure that the calling routine
    *  has given us some realistic values.
    */
   if ( numbands < 1 )
   {
         (void) fprintf(stderr, "Number of bands must be >= than 1" );
         return(0);
   }
   if (offset < 0)
   {
         (void)fprintf (stderr, "Header offset must be >= than 0" );
         return(0);
   }
   if (start < 0)
   {
         (void)fprintf (stderr, "Start offset must be >= than 0" );
         return(0);
   }
   if (row_skip < 1 || col_skip < 1)
   {
         (void) fprintf(stderr, "Row and column increment factors must be >= \
than 1" );
         return(0);
   }

   if ( (file = kopen(filename, O_RDONLY)) < 0)
   {
         (void) fprintf(stderr,"lvraw2viff: Unable to access input file %s",
                               filename);
         return(0);
   }

   /* 
    * The "convert_to_float" flag is set to false if there is no interleaving,
    * interleaving but number of bands equal one,
    *  no row skip, no column skip, no location data (dimension = 0).
    */

   if ( (interleave == FALSE || (interleave == TRUE && numbands == 1))
       && (row_skip <= 1) && (col_skip <= 1) && (dimension == 0) ) 
       force_convert = FALSE;
   else force_convert = TRUE;

   if (!(data = new_read_raw(file, offset, &length, data_type, mach_type, force_convert)))
   {
      kclose(file);
      return(0);
   }
   size = length;
   kclose(file);

   /*
    *  Check to see if the input file data is complex.  If so we need to
    *  know this since this will affect how we compute the size of the
    *  each band.
    */
   if (data_type == VFF_TYP_COMPLEX)
      complex = TRUE;
   else
      complex = FALSE;

   if (complex == 1)            /* complex image data */
      numsets = (dimension + numbands * 2);
   else

      numsets = (dimension + numbands);

   length /= numsets;
   if (length < 1)
   {
      (void) fprintf(stderr, "Not enough data found in raw data file!\n Need at\
 least %d data point, but found only %d data points\n", numsets, size);
      return(0);
   }

   /*  This makes use of setting rows or columns to zero ... if they are
       set to zero, then get the whole data set
   */

   if (nrows == 0)
   {
      nrows = 1;
   }
   if (ncols == 0)
   {
      ncols = length/nrows ;
   }

   /*
    *  Make sure that there is enough raw data in order to get the number
    *  of desired points (nrows*ncols).
    */
   size = nrows*ncols;

   if ((length - start) < size)
   {
         (void) fprintf(stderr, "\nOut of bounds! Number of requested rows and \
columns is greater than \nthe number of points per band found in the data file.\
\nNumber of points in the file per band is %d,\nnumber of expected points per \
band is %d.  (Num of rows = %d Num of cols = %d)\n\n", (length - start), size,
nrows, ncols);
         return(0);
   }

   if(dimension == 0)
   {
        location_type = VFF_LOC_IMPLICIT;
   }
   else
   {
        location_type = VFF_LOC_EXPLICIT;
   }
   if (complex)
      data_storage_type = VFF_TYP_COMPLEX;
   else
      data_storage_type = VFF_TYP_FLOAT;


   /* 
    *  Don't want to malloc space for data if there was not a forced
    *  convert to float in new_read_raw().
    */

   if (force_convert == FALSE) {
       nr = 0;
       nc = 0;
   }
   else {
       nr = (1 + (nrows -1)/row_skip);
       nc = (1 + (ncols -1)/col_skip);
   }

   img = createimage(   (unsigned long) nr,    /* number of rows */
                        (unsigned long) nc,    /* number of columns */
                        (unsigned long)
                        data_storage_type,             /* data_storage_type */
                        (unsigned long) 1,             /* num_of_images */
                        (unsigned long) numbands,      /* num_data_bands */
                        "created by lraw2viff",        /* comment */
                        (unsigned long) 0,              /* map_row_size */
                        (unsigned long) 0,              /* map_col_size */
                        (unsigned long)
                        VFF_MS_NONE,                    /* map_scheme */
                        (unsigned long)
                        VFF_MAPTYP_NONE,                /* map_storage_type */
                        (unsigned long)
                        location_type,                     /* location_type */
                        (unsigned long) dimension);     /* dimension */

   *image = img;

   if ( img == NULL ) {
       (void)fprintf(stderr,"lraw2viff: Unable to allocate new image!\n");
       return(0);
   }

   if (force_convert == FALSE) {   /*  Assign fields and point to data */
      img->row_size = (1 + (ncols -1)/col_skip);
      img->col_size = (1 + (nrows -1)/row_skip);
      img->imagedata = (char *) data;
      img->data_storage_type = data_type;
   }
   else {

      /*  massage data points into specified form */
      load_viff_data(data, (float *)img->imagedata, img->location, nrows, ncols,
                  numbands, dimension, interleave, start, row_skip, col_skip,
                  complex);

       if (data_type != data_storage_type)
       {
          (void) lvconvert(img, data_type, 0, 1, 0.0, 1.0,0);
       }
       free((char *) data);
   }
   return (TRUE);
}
/* -library_code_end */
