 /*
  * Khoros: $Id: lvggauss.c,v 1.2 1991/12/18 09:24:12 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: lvggauss.c,v 1.2 1991/12/18 09:24:12 dkhoros Exp $";
#endif

 /*
  * $Log: lvggauss.c,v $
 * Revision 1.2  1991/12/18  09:24:12  dkhoros
 * HellPatch3
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * 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: lvggauss.c
 >>>>
 >>>>      Program Name: vggauss
 >>>>
 >>>> Date Last Updated: Tue Dec 10 15:19:56 1991 
 >>>>
 >>>>          Routines: lvggauss - the library call for vggauss
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#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);
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvggauss - library call for vggauss
*
* Purpose:
*    
*    Creates a Gaussian (noise) image.
*    
*    

* Input:
*    
*    image          pointer to VIFF structure containing image data to
*                   be processed.
*    
*    rows           number of rows in image
*    
*    cols           number of columns in image
*    
*    bands          number of data bands in image
*    
*    mean           mean of Gaussian data
*    
*    variance       variance of Gaussian data
*    
*    type           data type of  resulting  image.   Must  be  either
*                   VFF_TYP_FLOAT or VFF_TYP_COMPLEX
*    
*    doadd          flag to indicate if data is to  be  added  to  the
*                   input  image.   If  this flag is set, then add the
*                   noise to the data that currently sits in image.
*    
*    

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

*
* Written By: Ramiro Jordan, Jeremy Worley
*    
*    Jeremy Worley   June 4, 1990  library now calls ggauss in vmath.a
*    
*    Jeremy Worley   June 5, 1990  single band bug in call to  create-
*                                  data fixed
*    
*    Jeremy Worley   Februaru 1, 1991
*                                  modified to accept  optional  input
*                                  image
*    
*    

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


/* -library_def */
int
lvggauss(image,rows,cols,bands,mean,var,type,doadd)
  struct xvimage **image;
  int            rows,cols,bands,type,doadd;
  float          mean,var;
/* -library_def_end */

/* -library_code */
{
    char *program="lvggauss";
    char *comment="Gaussian image created by lvggauss.";

    int     length,                     /* length of the image */
            i,j,b;                      /* counters */

    float   *fptr,                      /* pointer to data area*/
            *rptr=NULL,*iptr=NULL;      /* temporary space for complex */

    struct xvimage *kern, *createimage();

/* Immediately check arguments to ensure that they are within bounds */
    if(rows < 1 || cols < 1 || bands < 1){
       fprintf(stderr,"%s:  Image dimensions out of bounds.\n",program);
       return(0);
    }else if(var<=0.0){
       fprintf(stderr,"%s:  Variance out of bounds.\n",program);
       return(0);
    }else if(type!=VFF_TYP_FLOAT && type!=VFF_TYP_COMPLEX){
       fprintf(stderr,"%s:  Illegal image data type.\n",program);
       return(0);
    }

    if(doadd){
       rows = (*image)->col_size;
       cols = (*image)->row_size;
       bands = (*image)->num_data_bands;
       type = (*image)->data_storage_type;
    }

    kern = createimage((unsigned long) rows,    /* number of rows */
                        (unsigned long) cols,   /* number of columns */
                        (unsigned long)         /* data_storage_type */
                        type,
                        (unsigned long) 1,      /* num_of_images */ 
                        (unsigned long)bands,   /* num_data_bands */ 
                        comment,                /* 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)
                        VFF_LOC_IMPLICIT,       /* location_type */
                        (unsigned long) 0);     /* location_dim */

    if (kern == NULL) {
       (void)fprintf(stderr,"%s: Unable to allocate new image!\n",program);
       *image = NULL;
       RETURN(0);
    }

    length = kern->row_size * kern->col_size;

    fptr = (float *) kern->imagedata;

/*
** 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 noise sequence 
*/

   for(b=0;b<bands;b++){
       if(type==VFF_TYP_COMPLEX){
          if((ggauss(rptr,rows,cols,mean,var))==0){
             (void)fprintf(stderr,"%s:  Call to ggauss failed miserably.\n",
                                program);
             RETURN(0); 
          }
          if((ggauss(iptr,rows,cols,mean,var))==0){
             (void)fprintf(stderr,"%s:  Call to ggauss failed miserably.\n",
                                program);
             RETURN(0);
          }
          for(i=0,j=0;i<length;i++,j+=2){
             fptr[j] = rptr[i];
             fptr[j+1] = iptr[i]; 
          }
       }else{
          if((ggauss(fptr,rows,cols,mean,var))==0){
             (void)fprintf(stderr,"%s:  Call to ggauss failed miserably.\n",
                                program);
             RETURN(0);
          }
          fptr += length;
       }
    }          
 
    if(doadd){
      if(!lvadd(*image,kern,NULL,0)){
         fprintf(stderr,"%s:  Unable to add images.\n",program);
         return(0);
      }
    }else{
      *image = kern;
    }

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