 /*
  * Khoros: $Id: lvgsin.c,v 1.3 1992/03/20 23:05:51 dkhoros Exp $
  */

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

 /*
  * $Log: lvgsin.c,v $
 * Revision 1.3  1992/03/20  23:05:51  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: lvgsin.c
 >>>>
 >>>>      Program Name: vgsin
 >>>>
 >>>> Date Last Updated: Thu Mar  5 08:36:32 1992 
 >>>>
 >>>>          Routines: lvgsin - the library call for vgsin
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
/*
** RETURN simply frees up pointers before leaving
*/

#define RETURN(x) if(iptr!=NULL)free(iptr);if(rptr!=NULL)free(rptr);return(x);

#define TWOPI (double)6.28318530718
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvgsin - library call for vgsin
*
* Purpose:
*    
*    Creates a sinusoidal image.
*    
*    

* Input:
*    
*    image          pointer to VIFF structure containing image data to
*                   be processed.
*    
*    rows           rows is an integer that specifies  the  number  of
*                   rows in the resultant image.
*    
*    cols           cols is an integer that specifies  the  number  of
*                   columns in the resultant image.
*    
*    bands          bands is an integer that specifies the  number  of
*                   bands in the resultant image.
*    
*    amp            amp is an float that specifies the maximum  ampli-
*                   tude of the signal.
*    
*    fs             fs is a float that  specifies  the  sampling  fre-
*                   quency for signal generation.
*    
*    fx             fx is a float that specifies the frequency of  the
*                   signal in the X direction in radians/pixel.
*    
*    fy             fy is a float that specifies the frequency of  the
*                   signal in the Y direction. in radians/pixel
*    
*    px             px is a float that specifies the  phase  shift  in
*                   the X direction in radians.
*    
*    py             py is a float that specifies the  phase  shift  in
*                   the Y direction in radians.
*    
*    type           type is an int  that  specifies  the  output  data
*                   type.    It   must  be  one  of  VFF_TYP_FLOAT  or
*                   VFF_TYP_COMPLEX.
*    
*    

* Output:
*    
*    image          pointer to VIFF structure  containing  image  data
*                   after processing.
*    
*    Return Value:  1 on success, 0 on failure.
*    
*    

*
* Written By: Jeremy Worley, Marcelo Teran, Ramiro Jordan
*    
*    Scott Wilson 09 Jun 1990 11:31 MST
*              Major documentation fixed,  fixed  up  units  on  input
*              parameters  so  they  are consistent (i.e. all in radi-
*              ans), fixed .pane to  reflect  this,  changed  argument
*              names to be more descriptive (i.e.  "py" instead of "e"
*              for phase Y.
*    
*    Scott Wilson 21 Jan 1991 14:20 MST
*              Changed return(1) to RETURN(1) at end of routine - oth-
*              erwise have a memory leak.
*    
*    Scott Wilson 21 Jan 1991 14:25 MST
*              Found fs and fx switched in the call from  vgsin.   Put
*              'em right.
*    
*    Scott Wilson 21 Jan 1991 14:26 MST
*              Found fx and fy switched in call to  gsin().   Put  'em
*              right.
*    
*    Jeremy Worley 05 Mar 1992 08:35 MST
*              Many fprintfs in error conditions were called with  too
*              few arguments - fixed.
*    
*    

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


/* -library_def */
lvgsin(image,rows,columns,bands,amp,fs,fx,fy,px,py,type)
  struct xvimage **image;
  int            rows,columns,bands,type;
  float          amp,fx,fy,fs,px,py;
/* -library_def_end */

/* -library_code */
{
  struct xvimage *createimage();
  char   *comment="Sinusoidal signal courtesy of lvgsin";
  long int i,j,b,length;
  float *fimage,*iptr=NULL,*rptr=NULL;

  char *program="lvgsin";

/* Immediately check bounds on arguments. */
  if(rows<1 || columns<1 || bands<1){
     fprintf(stderr,"%s:  Image dimension out of bounds.\n",program);
     return(0);
  }else if(fs<=0.0){
     fprintf(stderr,"%s:  Sampling frequency out of bounds.\n",program);
     return(0);
  }else if(fx<0.0 || fy<0.0){
     fprintf(stderr,"%s:  Frequency out of bounds.\n",program);
     return(0);
  }else if(type!=VFF_TYP_FLOAT && type!=VFF_TYP_COMPLEX){
     fprintf(stderr,"%s:  Illegal image data type specified.\n",program);
     return(0);
  }

  *image = createimage(rows,columns,type,1,bands,comment,
                      (unsigned long)0, /* map_row_size */
                      (unsigned long)0, /* map_col_size */
                      (unsigned long)VFF_MS_NONE,
                      (unsigned long)VFF_MAPTYP_NONE,
                      (unsigned long)VFF_LOC_IMPLICIT,
                      (unsigned long)0);/* location dimension */

  if(*image==NULL){
     fprintf(stderr,"%s:  Unable to create allocate memory for image.\n",
             program);
     return(0);
  }

  fimage = (float *)(*image)->imagedata;

  length = (*image)->row_size * (*image)->col_size;

/*
** allocate temporary work space
*/

   if(type==VFF_TYP_COMPLEX){
      if((rptr = (float *)malloc(length*sizeof(float)))==NULL){
         (void)fprintf(stderr,"%s:  Failed memory allocation.\n",program);
         RETURN(0);
      }

      if((iptr = (float *)malloc(length*sizeof(float)))==NULL){
         (void)fprintf(stderr,"%s:  Failed memory allocation.\n",program);
         RETURN(0);
      }
   }

/*
** generate the sinusoid sequence
*/

  for(b=0;b<bands;b++){
     if(type==VFF_TYP_FLOAT){
        if(!gsin(fimage,rows,columns,fs,amp,fy,fx,px,py)){
           fprintf(stderr,"%s: [1]call to gsin failed.\n",program);
           RETURN(0);
        }
        fimage += length;
     }else{ /* then its complex */
        /* Do cosine part */
        if(!gsin(rptr,rows,columns,fs,amp,fy,fx,px-XV_PI_2,py-XV_PI_2)){
           fprintf(stderr,"%s: [2]call to gsin failed.\n",program);
           RETURN(0);
        }
        /* Do sine part */
        if(!gsin(iptr,rows,columns,fs,amp,fy,fx,px,py)){
           fprintf(stderr,"%s: [3]call to gsin failed miserably.\n",program);
           RETURN(0);
        }

/*
** sort of interleave the data back
*/

        for(i=0,j=0;i<length;i++,j+=2){
            fimage[j] = rptr[i];
            fimage[j+1] = iptr[i];
        } 
    } /* end of if() */
  } /* end of for loop */

  RETURN(1);
} /* end of lvgsin */
/* -library_code_end */
