 /*
  * Khoros: $Id: lmtrans.c,v 1.4 1992/03/20 23:47:23 dkhoros Exp $
  */

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

 /*
  * $Log: lmtrans.c,v $
 * Revision 1.4  1992/03/20  23:47:23  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: lmtrans.c
 >>>>
 >>>>      Program Name: mtrans
 >>>>
 >>>> Date Last Updated: Thu Mar  5 08:55:54 1992 
 >>>>
 >>>>          Routines: lmtrans - the library call for mtrans
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
static int ltrans();
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lmtrans - library call for mtrans
*
* Purpose:
*    
*    mtrans - transposes a matrix.
*    
*    

* Input:
*    
*    image          an image containg one or more  matrices  (one  per
*                   band).
*    
*    conjugate      1-> make conjugate 0-> dont make conjugate
*    
*    

* Output:
*    
*    image          double or  double  complex  image  containing  the
*                   transposes of the input image's matrices.
*    
*    Return Value:  1 on success, 0 on failure.
*    
*    

*
* Written By: Matthew Lawrence, Jeremy Worley
*    
*    Jeremy Worley 27 Jan 1992 09:58 MST
*              Changed declaration of ltrans() from int to static  int
*              in lmtrans().
*    
*    Jeremy Worley 05 Mar 1992 08:54 MST
*              Made the declaration of lvcast() explicit in lmtrans().
*    
*    

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


/* -library_def */
int lmtrans(image,conjugate)
   struct xvimage *image;
   int conjugate;
/* -library_def_end */

/* -library_code */
{
  int i,rows,cols,trows,tcols,bands,type;
  double *mat,*kern;
  char *program = "lmtrans";

  int lvcast();
 
  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;
   }

  if((mat = (double *)malloc(2*rows*cols*sizeof(double)))==NULL){
     fprintf(stderr,"%s:  Failure to allocate necessary data.\n",program);
     return(0);
  }

/*
** process all of the data
*/

   kern = (double *)(image->imagedata);
   for(i=0;i<bands;i++){
      if(!ltrans(mat,&trows,&tcols,kern,rows,cols,type,conjugate)){
         fprintf(stderr,"%s:  Failed call to static routine.\n",program);
         free((char *)mat);
         return(0);
      }

      bcopy(mat,kern,(type+1)*rows*cols*sizeof(double));
      kern += (type+1)*rows*cols;
   }

   image->row_size = tcols;
   image->col_size = trows;

   return(1);
}
/***********************************************************************
*
*  Routine Name: static ltrans
*
*          Date:
*        
*       Purpose:  
*
*         Input: 
*
*        Output: 
*
*    Written By:  Matthew Lawrence
*
* Modifications:
*
***********************************************************************/

static int ltrans(tm,trows,tcols,matrix,rows,cols,type,conjugate)
    double *matrix, *tm;
    int rows,cols,*trows,*tcols,type,conjugate;
{
        char *program = "lmtrans";
        int tmpos,cpos,mpos,rpos,toggle;

        if(rows==0 || cols==0)
           {
           (void)fprintf(stderr,"%s: zero dimension matrices not allowed\n",
              program);
           return(0);
           }

        if(tm==NULL || trows==NULL || tcols==NULL || matrix==NULL)
           {
           (void)fprintf(stderr,"%s: Null input/output paramter not allowed\n",
              program);
           return(0);
           }

        if (type < 0 || conjugate < 0 || type > 1 || conjugate > 1)
           {
           (void)fprintf(stderr,"%s: Illegal type or conjugate parameter specified\n",program);
           return(0);
           }
        tmpos = 0;
        for(cpos = 0; cpos < cols; cpos++)
           { 
           if(type == 0)
              mpos = cpos;
           else
              mpos = cpos*2;
           for(rpos = 0; rpos < rows; rpos++)
              {
              if(type == 0)
                 {
                 *(tm+tmpos) = *(matrix+mpos);
                 tmpos++;
                 }
              else
                 {
                 *(tm+tmpos) = *(matrix+mpos);
                 *(tm+tmpos+1) = *(matrix+mpos+1);
                 tmpos = tmpos+2; 
                 }
              if(type == 0)
                 mpos = mpos+cols;
              else
                 mpos = mpos+cols*2;
              }
           }
           
        *trows = cols;
        *tcols = rows; 

        if(type == 1 && conjugate == 1)
           {
           toggle = 0;
           for(tmpos = 0; tmpos < rows*cols*2; tmpos++)
              {
              if(toggle == 1)
                 {
                 *(tm+tmpos) = *(tm+tmpos)*-1.0;
                 toggle = 0;
                 }
              else
                 toggle = 1;
              }
           }

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