 /*
  * Khoros: $Id: lviff2mat.c,v 1.4 1992/03/20 23:36:13 dkhoros Exp $
  */

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

 /*
  * $Log: lviff2mat.c,v $
 * Revision 1.4  1992/03/20  23:36:13  dkhoros
 * VirtualPatch5
 *
  */

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

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: lviff2mat.c
 >>>>
 >>>>      Program Name: viff2mat
 >>>>
 >>>> Date Last Updated: Thu Mar 19 17:42:00 1992 
 >>>>
 >>>>          Routines: lviff2mat - the library call for viff2mat
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


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


/****************************************************************
*
* Routine Name: lviff2mat - library call for viff2mat
*
* Purpose:
*    
*    viff2mat - outputs a matrix in desired form.
*    
*    

* Input:
*    
*    fname          specify ouput file
*    
*    image          input matrix image to operate on.
*    
*    style          input the control string for style of output.   In
*                   normal  C  style format control string for printf.
*                   ex:  %-5.2f   specifies  left  justified  floating
*                   point number with a total
*                               size of 5 spaces with 2 for the  frac-
*                   tional  part.   Note: Does not include hexidecimal
*                   or octal output format.
*    
*    numcols        the number of columns per line.
*    
*    delimiter      the type of  element  delimiter.   0->  space  1->
*                   comma
*    
*    bracket        determines the type of bracket used in the matrix.
*                   0-> "[  ]" 1-> "<  >"
*    
*    

* Output:
*    
*    errnum         errnum returns an error number which specifies the
*                   reason  for  failure.   1->  Output  file name not
*                   specified.  2-> Matrix parameter  is  empty.   3->
*                   Rows  or  Cols value is invalid.  4-> Style string
*                   not specified.  5-> Number of  Cols  specification
*                   invalid.  6-> Invalid element delimiter specified.
*                   7-> Invalid bracket  type  specified.   8->  Can't
*                   open output file.
*    
*    Return Value:  1 on success, 0 on failure.
*    
*    

*
* Written By: Matthew Lawrence,Jeremy Worley
*    
*    Jeremy Worley 16 Aug 1991 08:30 MDT
*              Changed an expression that caused the multiband  images
*              to get translated incorrectly.
*    
*    Jeremy Worley 19 Mar 1992 17:40 MST
*              Added/changed necessary code  to  deal  with  transport
*              capabilities  in  vgparm.  Also fixed a bug wherein the
*              kfile was closed after each matrix was output.
*    
*    

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


/* -library_def */
int lviff2mat(filename,image,style,numcols,delimiter,bracket,errnum)
    char *filename,*style;
    struct xvimage *image;
    int numcols,delimiter,bracket,*errnum; 
/* -library_def_end */

/* -library_code */
{
    char *program = "lviff2mat";
    int i,bands,rows,cols,type;
    double *kern;
    kfile *kfptr;

  bands = (int)image->num_data_bands;
  rows = (int)image->col_size;
  cols = (int)image->row_size;

/*
** cast all of the data up to double or double complex
*/

   if(image->data_storage_type==VFF_TYP_COMPLEX || image->data_storage_type==
        VFF_TYP_DCOMPLEX){
      if(!lvcast(&image,(int)1,(int)VFF_TYP_DCOMPLEX)){
         fprintf(stderr,"%s:  Failure to cast up to double complex.\n",program);
         return(0);
      }
      type = 1;
   }else{
      if(!lvcast(&image,(int)1,(int)VFF_TYP_DOUBLE)){
         fprintf(stderr,"%s:  Failure to cast up to double.\n",program);
         return(0);
      }
      type = 0;
   }

   kfptr = kfopen(filename,"w");

   kern = (double *)(image->imagedata);

   for(i=0;i<bands;i++){
       if(bands>1)kfprintf(kfptr,"# Band %d\n",i);
       if(!llviff2mat(kfptr,kern,rows,cols,type,style,numcols,delimiter,
           bracket,errnum)){
           return(0);
       }
       kern += (type+1)*rows*cols;
   }

   kfclose(kfptr);
   return(1);
}

/***********************************************************************
*
*  Routine Name: 
*
*          Date:
*        
*       Purpose:  
*
*         Input: 
*
*        Output: 
*
*    Written By:  
*
* Modifications:
*
***********************************************************************/

int llviff2mat(kfptr,matrix,rows,cols,type,style,numcols,delimiter,bracket,
    errnum)
    double *matrix;
    char *style;
    int rows,cols,type,numcols,delimiter,bracket,*errnum;
    kfile *kfptr;
/* -library_def_end */

/* -library_code */
  {
  int r,       /* Row loop counter. */
      c,       /* Col loop counter. */
      idx,     /* The index into the matrix. */
      colcount; /* Counts the number of cols printed. */
  char *style2;
/*
** perform some error checking
*/

   if(errnum==NULL)
      {
      (void)fprintf(stderr,"Error in call to lviff2mat: errnum = NULL\n");
      return(0);
      }

   if(matrix==NULL)
      {
      *errnum = 2;  /* No matrix to output. */
      return(0);
      }

   if(rows<=0 || cols<=0)
      {
      *errnum = 3;  /* Rows or Cols value invalid. */
      return(0);
      }

   if(style==NULL)
      {
        if((style2 = (char *)kmalloc(3*sizeof(char)))==NULL){
           fprintf(stderr,"%s:  can't malloc, dude!\n");
           return(0);
        }
        style2 = "%.12e";
        if(type)numcols = 2;
        else numcols = 4;
      }
   else
      {
        if((style2 = (char *)kmalloc((strlen(style)+1)*sizeof(char)))==NULL){
           fprintf(stderr,"%s:  can't malloc, dude!\n");
           return(0);
        }
        strcpy(style2,style);
      }

   if(numcols<=0)
      {
      *errnum = 5;  /* Invalid number of columns to print per line. */
      return(0);
      }

   if((delimiter < 0) || (delimiter > 1))
      {
      *errnum = 6; /* Invalid delimiter specified. */
      return(0);
      }

   if((bracket < 0) || (bracket > 1))
      {
      *errnum = 7;  /* Invalid bracket specified. */
      return(0);
      }

/*
** loop through all components and output each element of the matrix
*/

   if(bracket == 0)
      (void)kfprintf(kfptr,"[\n");
   else
      (void)kfprintf(kfptr,"<\n");

   for(r=0;r<rows;r++)
      {
      colcount = 0;
      for(c=0;c<cols;c++)
         {
         if(type)  /* Is data complex. */
            {
            idx = 2*(r*cols+c);
            (void)kfprintf(kfptr,"(");
            (void)kfprintf(kfptr,style2,matrix[idx]);
            (void)kfprintf(kfptr,",");
            (void)kfprintf(kfptr,style2,matrix[idx+1]);
            (void)kfprintf(kfptr,")");
            if(c != cols-1) /* If last element, no delimiter. */
               {
               if(delimiter == 0)
                  (void)kfprintf(kfptr,"  ");
               else
                  (void)kfprintf(kfptr,",");
               }
            }
         else     /* Data is not complex. */
            {
            (void)kfprintf(kfptr,style2,matrix[r*cols + c]);
            if(c != cols-1) /* If last element, no delimiter. */
               { 
               if(delimiter == 0)
                  (void)kfprintf(kfptr," ");
               else
                  (void)kfprintf(kfptr,",");
               }
            }
         colcount++;
         if ((c == cols-1) && (r != rows-1)) /* If last line, no ";" */
            (void)kfprintf(kfptr,";");
         if(colcount==numcols)
            {
            colcount = 0;
            if(c != cols-1)
              (void)kfprintf(kfptr,"\n");
            }
         }    
      (void)kfprintf(kfptr,"\n");
      }

   if(bracket == 0)
      (void)kfprintf(kfptr,"]\n\n");
   else
      (void)kfprintf(kfptr,">\n\n");

/*
** normal exit: no error
*/

   *errnum = 0;
   return(1);
   }
/* -library_code_end */
