 /*
  * Khoros: $Id: input.c,v 1.6 1992/03/20 22:46:07 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: input.c,v 1.6 1992/03/20 22:46:07 dkhoros Exp $";
#endif

 /*
  * $Log: input.c,v $
 * Revision 1.6  1992/03/20  22:46:07  dkhoros
 * VirtualPatch5
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, 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 too 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 1990 by UNM */
#include "xprism.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: input.c
   >>>>               
   >>>>   description: input file utility routines
   >>>>              
   >>>>      routines:
   >>>>			get_file_type
   >>>>			get_file_dps
   >>>>			get_file_raw
   >>>>			get_file_points
   >>>>			get_image
   >>>>			get_input_file
   >>>>			check_ascii
   >>>>			check_raw
   >>>>			check_other_type
   >>>>			assign_data
   >>>>			get_file_function
   >>>>              
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

/***********************************************************************
*
*  Routine Name: get_file_type
*
*          Date:
*        
*       Purpose: returns the file type given a file name 
*
*         Input: char *filename - filename to check
*
*        Output: file type
*
*    Written By:  
*
* Modifications:
*                Scott Wilson Fri Aug 30 04:29:30 MDT 1991
*                   Added cache stuff.
*                Mark Young Sun Nov 10 15:51:57 MST 1991
*                   Deleted cache stuff.
*
***********************************************************************/
int get_file_type(filename)
char *filename;
{
	int    fd, file_type, fslot, check_file_type();
        char   buf[512];


	if (filename == NULL)
	   return(ERROR);
	else if ((fd = kopen(filename, O_RDONLY, 0666)) == -1)
	   return(ERROR);

	/*
	 *  Check to see if the file is a valid file.
	 */
	file_type = check_file_type(fd);

	/*
	 *  If not an image file then see if we can recognize the file
	 *  as an ascii or floating point plot file.  Otherwise if file_type
	 *  returns ERROR then the file is either incomplete or is not
	 *  of the version/release.
	 */
	if (file_type == NOT_XVIFF) 
	   file_type = check_other_type(fd);

	(void) kclose(fd);
	return(file_type);
}



int check_other_type(fd)

int	fd;
{
	char    buffer[1024];
	int	file_type;
	int	size=0;


	/*
	 *  Rewind the file just in case "check_file_type" didn't.  If
	 *  file is standard in, then lseek will fail and "block_read"
	 *  will read from block_buffer before reading the rest of the
	 *  bytes from stdin.
	 */
	(void) klseek(fd, 0L, 0);

	if ((size = block_read(fd, buffer, 1024)) <= 0)
	{
	   return(ERROR);
	}

	file_type = check_ascii(buffer, size);
	if (file_type == ASCII_FUN || file_type == ASCII_DATA)
	   return(file_type);
	else if (file_type == ASCII_COMMENT)
	   return(UNKNOWN);
	else if ((file_type = check_raw(buffer, size)) != NULL) 
	   return(file_type);

	return(UNKNOWN);
}


#define ISDIGIT(x) (isdigit(x) || isspace(x) || (x == 'e') || (x == 'E') \
	|| (x == 'd') || (x == 'D') || (x == '-') || (x == '+') || (x == '.') )

#define COMMENT(x) ((x == '#') || (x == '/'))


int check_ascii(buffer, size)

char	*buffer;
int	size;
{
   	int	i = 0, ctrl = 0;
   	short	func = FALSE;
   	short	ascii_data = FALSE;
   	short	ascii_comment = FALSE;
   	short	end_comment = FALSE;

        /* 
	 * first lets see if it has got lots of control characters in in.
	 * it so, then 99% sure it is a raw file and not an ascii file.
         */

	while (i < size )
	{
	 if (iscntrl(buffer[i]) && ! isspace(buffer[i]))
	    ctrl++;
	 i++;
	}

	if (ctrl > 10)
	  return(NULL);
	  
	i = 0;
	while (i < size )
	{
	   if (isalnum(buffer[i]) && ! isspace(buffer[i]) 
		&& ! iscntrl(buffer[i]))
	   {
	      if (COMMENT(buffer[i]))
	      {
		if (buffer[i] == '/')
		{
		  if (buffer[i+1] == '*')
		  {
	            ascii_comment = True;
		    end_comment = False;
		    i += 2;
		    while (i < size && ! end_comment)
		    {
		      if (buffer[i] == '*')
		      {
		        if (buffer[i+1] == '/')
			{
			  end_comment = True;
			  i++;
			}
		      }
		      i++;
		    }
		  }
	        }
		else /* its at # */
		{
	           ascii_comment = True;
		   while ((buffer[i] != '\n') && (i < size))
		     i++;
		}
	      }
	      else if (! ISDIGIT(buffer[i]))
	      {
	           if ((strncmp(&buffer[i], "f(x)",4) == 0))
		      func = True;
	           else if((strncmp(&buffer[i], "f(x,y)",6) == 0))
		      func = True;
	           else if ((strncmp(&buffer[i],"f(x ,y)",7)== 0))
		      func = True;
	           else if ((strncmp(&buffer[i],"f(x , y)",8)==0))
		      func = True;
	           else if ((strncmp(&buffer[i],"f(x, y)",7)== 0))
		      func = True;
	      }
	      else
		  ascii_data = True;
	   }
	   i++;
	}

	if (func == True)
	   return(ASCII_FUN);
	else if (ascii_data == True) 
	   return(ASCII_DATA);
	else if (ascii_comment == True)
	   return(ASCII_COMMENT);
	else 
	   return(NULL);
}

int check_raw(buffer, size)

char	*buffer;
int	size;
{
	return(RAW_DATA);
}



/************************************************************
*
*  MODULE NAME: get_file_dps
*
*      PURPOSE: Gets data points from an ascii data file 
*               specified by the user.  Input file should
*               have the following form for 2D:
*      
*               3        { number of data points }
*               4.5 5.7
*               3.1 9    { data points in doubles }
*               10  2.7
*
*               A similar form is used for 3D only with the 
*               additional Z value (points are in triples)
*
*
*        INPUT: 1) dimen -- 2D or 3D
*
*               2) filename -- name of the ascii file to read
*
*
*       OUTPUT: values for all fields of plot structure
*
*    CALLED BY: 
*
*   WRITTEN BY:  Danielle Argiro and Mark Young
*
*
*************************************************************/


XPlot *get_file_dps(dimen, filename, data_format, num_rows)

int          dimen, data_format, num_rows;
char         *filename;

{
	FILE   *fid;
	int    i, j, k, l, m, points, new_num_rows = 0, done = 0;
        static int col_size = -1;
        float	*data, *read_ascii(), temp;
	XPlot	*plot;
	char    *mesg, tmp[512], tmp1[512];
	char   *prompts[3];
	char   *answers[1];

	/* various plot structure fields that need
	 to be given values at this time    */

	if (!(plot = (XPlot *) calloc(1,(unsigned) sizeof(XPlot))))
	{
	   mesg = xvf_strcpy("Unable to allocate memory for plot structure.");
	   xvf_error_wait(mesg, "get_file_dps", NULL);
	   free(mesg);
	   return(NULL);
	}

	plot->input_type = ASCII_DATA;
	plot->data_type  = VFF_TYP_FLOAT;
	plot->data_format  = data_format;
	plot->filename = VStrcpy(filename);
	plot->machine_type_index = -1;
	plot->band = -1;
	plot->cmplx = -1;

        /* make some initializations */
	plot->begin_point.x = 0.0;
	plot->begin_point.y = 0.0;
	plot->end_point.x = 0.0;
	plot->end_point.y = 0.0;
	plot->step_size.x = 1.0;
	plot->step_size.y = 1.0;

	/* attempt to open the file */
	if ((fid = fopen(filename, "r")) == NULL)
	{
	   (void) sprintf(tmp, "File %s not found\n",filename);
	   xvf_error_wait(tmp, "get_file_dps", NULL);
	   return(NULL);
	}

	/* initializations */

        data = read_ascii(fid, &points);
 	(void) fclose(fid);
        if (data == NULL)
        {
	   (void) sprintf(tmp, "File %s is empty \n",filename);
	   xvf_error_wait(tmp, "get_file_dps", NULL);
	   return(NULL);
        }
	switch (data_format)
        {
          case XY_PAIRS:
              plot->size = points/2;
              break;
          case Y_ONLY:
          case Z_ONLY:
              plot->size = points;
              break;
          case XYZ_TRIPLES:
 	      plot->size = points/3;
              break;
          default:
	       mesg = VStrcpy("Error data format specified");
	       xvf_error_wait(mesg, "get_file_dps", NULL);
	       free(mesg);
	       free(data);
	       return(NULL);
               break;
        }

	if (plot->size <= 1)
	{
	   mesg = xvf_strcpy("You must plot more than one point!");
	   xvf_error_wait(mesg, "get_file_dps", NULL);
	   free(mesg); 
	   free(data); 
	   return(NULL);
	}

	if (!(plot->points = (Coord *) malloc(plot->size * sizeof(Coord))))
	{
	   mesg = xvf_strcpy("Unable to allocate memory for points.");
	   xvf_error_wait(mesg, "get_file_dps", NULL);
	   free(mesg);
	   free(data);
	   return(NULL);
	}


         /* set the row_size = number columns */
        if (num_rows > 0)
	{
           plot->row_size = plot->size/num_rows;
	   col_size = num_rows;
	}
        else if (col_size == num_rows)
	{
           plot->row_size = 1;
	   col_size = plot->size;
	}
	else
	{
           plot->row_size = plot->size/col_size;
	}

	if (PLOT_TYPE_3D(dimen) && num_rows == -1)
	{
           while (! done)
           {
	      sprintf(tmp,"CHANGE NUMBER OF ROWS OF DATA\nTotal \
Points = %d\nCurrent Number of Rows = %d\nCurrent Number of Columns = %d", 
	       plot->size, col_size, plot->row_size);

	      sprintf(tmp1,"Input New Number Of Rows For Data");
	      prompts[0] = xvf_strcpy(tmp1);
	      answers[0] = (char *) calloc(1, MaxLength * sizeof(char));
              sprintf(answers[0], "%d", col_size);
    
	      /* prompt user for their own row and col info  */
	      xvf_query_wait(tmp, prompts, "OK",answers,1, 10);
	      new_num_rows = atoi(answers[0]);

	      if(new_num_rows <= 0 || new_num_rows > plot->size )
	      {
	         mesg = xvf_strcpy("Invalid row size entered,  reseting");
	         xvf_error_wait(mesg, "get_file_dps", NULL);
	         free(mesg);
	      }
	      else
              {
	         plot->row_size = plot->size/new_num_rows;
	         col_size = new_num_rows;
 	         done = True;
              }
           }
    	}

	/* read in data points */
        if (data_format == XY_PAIRS || data_format == XYZ_TRIPLES)
        {
            k = 0;
	    for (i = 0; i < plot->size; i++)  
	    {
	       plot->points[i].x = data[k++];
	       plot->points[i].y = data[k++];

	       if (PLOT_TYPE_3D(dimen))
	           plot->points[i].z = data[k++];
            }
         }
         else if (data_format == Y_ONLY && PLOT_TYPE_2D(dimen))
         {
	    for (i = 0; i < plot->size; i++)  
	    {
	       plot->points[i].x = i;
	       plot->points[i].y = data[i];
            }
         }
         else if (data_format == Z_ONLY && PLOT_TYPE_3D(dimen))
         {
            plot->WCmin.x  = 0;
            plot->WCmax.x  = 0;
    
            plot->WCmax.x = plot->row_size -1;
            plot->WCmax.y = col_size - 1;

	    l = 0;
            for (i = 0; i < col_size; i++)
            {
               for (j = 0; j < plot->row_size; j++)
               {
                   plot->points[l].x = j;
                   plot->points[l].y = i;
                   l++;
               }
            }
            for (i = 0; i < plot->size; i++) 
	       plot->points[i].z = data[i];

            if (col_size != 1)
            {
               for (i = 0; i < col_size/2; i++)
               {
                  l = i * plot->row_size;
                  m = (col_size -i -1) * plot->row_size;
   
                  for (j = 0; j < plot->row_size; j++)
                  {
                      temp = data[l];
                      plot->points[l].z = data[m];
                      plot->points[m].z = temp;
                      l++; m++;
	          }
               }
            }
         }

	find_min_max(plot, dimen);
	free(data);
	return(plot);
}

/************************************************************
*
*  MODULE NAME: get_file_raw
*
*      PURPOSE: Gets data points from a raw input file
*               specified by the user.
*
*        INPUT: 1) dimen -- 2D or 3D
*
*               2) filename -- name of the ascii file to read
*		3) source_machine - the machine type the data is in
*		4) data_type - byte, short, int, float
*		5) data_format - xy, xyz, y only, z only
*
*
*       OUTPUT: values for all fields of plot structure
*
*    CALLED BY: 
*
*   WRITTEN : Tom Sauer
*
*
*************************************************************/


XPlot *get_file_raw(dimen, filename, source_machine, data_type, 
		     data_format, num_rows)

int          dimen, data_format, source_machine, data_type;
int	     num_rows;
char         *filename;

{
	int     fd;
	int     i, j, k, l, m, points, new_num_rows = 0, done = 0;
	static  int col_size = -1;
        int 	offset = 0;
        float	*data, temp;
	XPlot	*plot;
	char    *mesg, tmp[512], tmp1[512];
	char    *prompts[3];
	char    *answers[1];

	/* various plot structure fields that need
	 to be given values at this time    */

	if (!(plot = (XPlot *) calloc(1,(unsigned) sizeof(XPlot))))
	{
	   mesg = xvf_strcpy("Unable to allocate memory for plot structure.");
	   xvf_error_wait(mesg, "get_file_raw", NULL);
	   free(mesg);
	   return(NULL);
	}

	plot->input_type = RAW_DATA;
	plot->data_type  = VFF_TYP_FLOAT;
	plot->data_format  = data_format;
	plot->filename = VStrcpy(filename);

        /* make some initializations */
	plot->begin_point.x = 0.0;
	plot->begin_point.y = 0.0;
	plot->end_point.x = 0.0;
	plot->end_point.y = 0.0;
	plot->step_size.x = 1.0;
	plot->step_size.y = 1.0;
	plot->machine_type_index = source_machine;
	plot->band = -1;
	plot->cmplx = -1;

	if ((fd = kopen(filename, O_RDONLY, 0666)) == -1)
	{
	   (void) sprintf(tmp, "Cannot open file %s",filename);
	   xvf_error_wait(tmp, "get_file_raw", NULL);
	   return(NULL);
	}

	/* initializations */

        data = read_raw(fd, offset, &points, data_type, 
			 machine_defs[source_machine].order);

 	(void) kclose(fd);
        if (data == NULL)
        {
	   (void) sprintf(tmp, "File %s is empty \n",filename);
	   xvf_error_wait(tmp, "get_file_raw", NULL);
	   return(NULL);
        }

	switch (data_format)
        {
          case XY_PAIRS:
              plot->size = points/2;
              break;
          case Y_ONLY:
          case Z_ONLY:
              plot->size = points;
              break;
          case XYZ_TRIPLES:
 	      plot->size = points/3;
              break;
          default:
	       mesg = VStrcpy("Error data format specified");
	       xvf_error_wait(mesg, "get_file_raw", NULL);
	       free(mesg);
	       free(data);
	       return(NULL);
               break;
        }

	if (plot->size <= 1)
	{
	   mesg = xvf_strcpy("You must plot more than one point!");
	   xvf_error_wait(mesg, "get_file_raw", NULL);
	   free(mesg); 
	   free(data);
	   return(NULL);
	}

	if (!(plot->points = (Coord *) malloc(plot->size * sizeof(Coord))))
	{
	   mesg = xvf_strcpy("Unable to allocate memory for points.");
	   xvf_error_wait(mesg, "get_file_raw", NULL);
	   free(mesg);
	   free(data);
	   return(NULL);
	}

         /* set the row_size = number columns */
        if (num_rows > 0)
	{
           plot->row_size = plot->size/num_rows;
	   col_size = num_rows;
	}
        else if (col_size == num_rows)
	{
           plot->row_size = 1;
	   col_size = plot->size;
	}
	else
        {
           plot->row_size = plot->size/col_size;
        }

	if (PLOT_TYPE_3D(dimen) && num_rows == -1)
	{
           while (! done)
           {
	      sprintf(tmp,"CHANGE NUMBER OF ROWS OF DATA\nTotal \
Points = %d\nCurrent Number of Rows = %d\nCurrent Number of Columns = %d", 
	 plot->size, col_size, plot->row_size);
    
	      sprintf(tmp1,"Input New Number Of Rows For Data");
	      prompts[0] = xvf_strcpy(tmp1);
	      answers[0] = (char *) calloc(1, MaxLength * sizeof(char));
	      sprintf(answers[0], "%d", col_size);
   
              /* prompt user for their own row and col info  */
              xvf_query_wait(tmp, prompts, "OK",answers,1, 10);
              new_num_rows = atoi(answers[0]);

              if(new_num_rows <= 0 || new_num_rows > plot->size )
              {
                 mesg = xvf_strcpy("Invalid row size entered,  reseting");
                 xvf_error_wait(mesg, "get_file_dps", NULL);
                 free(mesg);
	      }
	      else
              {
	         plot->row_size = plot->size/new_num_rows;
	         col_size = new_num_rows;
 	         done = True;
              }
           }
         }

	/* read in data points */
        if (data_format == XY_PAIRS || data_format == XYZ_TRIPLES)
        {
            k = 0;
	    for (i = 0; i < plot->size; i++)  
	    {
	       plot->points[i].x = data[k++];
	       plot->points[i].y = data[k++];

	       if (PLOT_TYPE_3D(dimen))
	           plot->points[i].z = data[k++];
            }
         }
         else if (data_format == Y_ONLY && PLOT_TYPE_2D(dimen))
         {
	    for (i = 0; i < plot->size; i++)  
	    {
	       plot->points[i].x = i;
	       plot->points[i].y = data[i];
            }
         }
         else if (data_format == Z_ONLY && PLOT_TYPE_3D(dimen))
         {
            plot->WCmin.x  = 0;
            plot->WCmax.x  = 0;

            plot->WCmax.x = plot->row_size -1;
            plot->WCmax.y = col_size - 1;

	    l = 0;
            for (i = 0; i < col_size; i++)
            {
               for (j = 0; j < plot->row_size; j++)
               {
                   plot->points[l].x = j;
                   plot->points[l].y = i;
                   l++;
               }
            }
            for (i = 0; i < plot->size; i++)
              plot->points[i].z = data[i];

            if (col_size != 1)
            {
               for (i = 0; i < col_size/2; i++)
               {
                  l = i * plot->row_size;
                  m = (col_size -i -1) * plot->row_size;
   
                  for (j = 0; j < plot->row_size; j++)
                  {
                      temp = data[l];
                      plot->points[l].z = data[m];
                      plot->points[m].z = temp;
                      l++; m++;
	          }
               }
            }
         }
        
	find_min_max(plot, dimen);
	free(data);
	return(plot);
}


/************************************************************
*
*  MODULE NAME: get_image
*
*      PURPOSE: Gets input for the xprism plotting routines
*               from the image file specified by the
*               user. The file MUST be in Khoros image file 
*               format, and should have been created  by 
*               the "writeimage()" routine. The file will be 
*               non-ascii, stored in binary. For complete 
*               description of the image file format, see
*               viff.h. 
*
*
*        INPUT: 1) dimen    -- 2D or 3D
*               2) plot     -- pointer to plot structure
*               3) filename -- name of file containing Khoros Image
*
*       OUTPUT: Values for all fields of the plot structure
*               passed by "plot" pointer
*
*    CALLED BY:
*
*   WRITTEN BY: Danielle Argiro, Mark Young, Tait Cyrus, Scott Wilson,
*		Mike Lang and Ramiro Jordan
*
*
*************************************************************/



XPlot *get_image(dimen, filename, whichband, complex_type) 

int	dimen;          /* 2-D or 3-D */
char	*filename;
int	whichband, complex_type;
{
	struct xvimage *image;       /* pointer to image to be created */
	struct xvimage *readimage();
        XPlot  *plot;

	float	ftemp, *fptr;
	int     i, j, l, m, com_type;
        int     band, band_num, current, band_size, loc_size;
	int     dsize, dcount, msize, mcount, lsize, lcount;
	char	*data;
        char    **bandnames, temp[MaxLength];
	XawListReturnStruct *band_list_return;
	char *prompt;
	char *label;

        plot = (XPlot *) calloc(1,sizeof(XPlot));

	image = readimage(filename);  /* read in the image information */
	if (image == NULL)
	{
	   return(NULL);
	}

	/* inconsistent image types */
	if (image->data_storage_type == VFF_TYP_BIT)
	{
	    xvf_error_wait("Cannot plot single bits at this time", 
			   "get_image", NULL);
	    freeimage(image);
	    return(NULL);
	}

	if (image->data_storage_type == VFF_TYP_DCOMPLEX)
	{
	    xvf_error_wait(
		"Cannot plot images with a data storage type of DOUBLE COMPLEX", 
                "get_image", NULL);
	    freeimage(image);
	    return(NULL);
	}

	/* cannot plot an image with 0 columns */
	if (image->col_size == 0)
	{
	   (void) sprintf(temp, "Cannot plot image %s with col_size = 0", 
			  filename);
	   xvf_error_wait(temp, "get_image", NULL);
	   freeimage(image);
	   return(NULL);
	}

	/* cannot plot an image with 0 rows */
	if (image->row_size == 0)
	{
	   (void) sprintf(temp, "Cannot plot image %s with row_size = 0", 
			  filename);
	   xvf_error_wait(temp, "get_image", NULL);
	   freeimage(image);
	   return(NULL);
	}
	
	band = 0;
	if (whichband > 0)
	  band = whichband;


	/* 
         * ask the user which band to display if whichband is set to -1,
	 * otherwise the band number was set on the command line.
	 */

	if ((image->num_data_bands > 1) && (whichband == -1))
	{
	   prompt = xvf_strcpy("Pick Band To Be Plotted");
	   label = xvf_strcpy("Image Bands");
           band_num = image->num_data_bands;
           bandnames = (char **) malloc(sizeof(char *) * band_num);
   
           for (i = 0; i < band_num; i++)
           {
               (void) sprintf(temp," image band %1d", i);
               bandnames[i] = xvf_strcpy(temp);
           }

	   /*
	    *  Prompt the user for which band they want using a list widget
	    */
	   band_list_return = xvf_run_list_wait(bandnames, band_num, 1, prompt,
                                                label, &current, False);
	   for (i = 0; i < band_num; i++)
	      free(bandnames[i]);
	   free(bandnames);
	   free(prompt);
	   free(label);

	   if (band_list_return == NULL) 
		return(NULL);

	   band = band_list_return->list_index;
   
	}

	if (band >= image->num_data_bands)
	{
           (void) sprintf(temp, "The band number specified to plot is greater than the number of bands in the image\n");
           xvf_error_wait(temp, "get_image", NULL);
	   freeimage(image);
           return(NULL);
	}

	com_type = complex_type;
	if (image->data_storage_type == VFF_TYP_COMPLEX)
	{
	   if (complex_type == 0)
	   {
	      prompt = xvf_strcpy("Choose Plot Type");
	      label = xvf_strcpy("Complex Plot Type");
              bandnames = (char **) malloc(sizeof(char *) * 4);
      
              bandnames[0] = xvf_strcpy("Real");
              bandnames[1] = xvf_strcpy("Imaginary");
              bandnames[2] = xvf_strcpy("Magnitude");
              bandnames[3] = xvf_strcpy("Phase");
   
	      /*
	       *  Prompt the user for which band they want using a list widget
	       */

	      com_type = 1;
	      band_list_return = xvf_run_list_wait(bandnames, 4, 1, prompt,
                                                   label, &current, False);
   
	      for (i = 0; i < 4; i++)
	         free(bandnames[i]);
	      free(bandnames);
	      free(prompt);
	      free(label);

	      if (band_list_return == NULL) 
		return(NULL);

	      com_type = band_list_return->list_index + 1;
	   }

	   if (! lvctor(image, com_type))
	   {
		(void) sprintf(temp, "Cannot convert the COMPLEX image data to the desired REAL data type");
                xvf_error_wait(temp, "get_image", NULL);
                freeimage(image);
                return(NULL);
	   }
	}

	plot->band = band;
	plot->cmplx = com_type;

	imagesize(image,&dsize, &dcount, &msize, &mcount,&lsize, &lcount);
	band_size = dsize/image->num_data_bands;

	if (image->location_dim != 0)
	  loc_size = lsize/image->location_dim;
   
	if (image->location_type == VFF_LOC_IMPLICIT)
	    plot->input_type =  XVIFF_IMPL;
	else if (image->location_type == VFF_LOC_EXPLICIT)
	    plot->input_type =  XVIFF_EXP;
 
	plot->data_type   = image->data_storage_type;  /* data type          */
	plot->data_format   = NO_FORMAT;  /* data type          */
	plot->filename = VStrcpy(filename);
	plot->machine_type_index = -1;

        /* make some initializations */
	plot->begin_point.x = 0.0;
	plot->begin_point.y = 0.0;
	plot->end_point.x = 0.0;
	plot->end_point.y = 0.0;
	plot->step_size.x = 1.0;
	plot->step_size.y = 1.00;

	if (PLOT_TYPE_2D(dimen)) 
	{ 
	   plot->WCmin.x = 0;  /* arrays begin at 0 */

	   if (image->col_size == 1) /* y nonexistent - plotting x and z */
	   {
		plot->WCmax.x = image->row_size;
		plot->size = image->row_size;
		plot->row_size = 1;
	   }
	   else if (image->row_size == 1) /* x nonexistent - plotting y and z */
	   {
	      plot->WCmax.x = image->col_size;
	      plot->size = image->col_size;
	      plot->row_size = 1;
	   }
	   else /* plotting x and y end to end */
	   {
	      plot->size = image->row_size * image->col_size;
              plot->WCmax.x = image->row_size * image->col_size;
              plot->row_size = image->row_size;
           }
	   
	   /* dynamically allocate point array */
	   plot->points = (Coord *)malloc((unsigned)(sizeof(Coord)*plot->size));

	   /* read in image data, converting on the fly */
	   if (image->location_type == VFF_LOC_EXPLICIT)
	   {
	      data = (char *) image->location;
	      assign_data(plot->points, data, plot->size, XAXIS, VFF_TYP_FLOAT);

	      data = (char *) &(image->imagedata[band * band_size]);
	      assign_data(plot->points, data, plot->size,YAXIS,plot->data_type);
	   }
	   else
	   {
	      for (i = 0; i < plot->size; i++)
		  plot->points[i].x = i;

	      data = (char *) &(image->imagedata[band * band_size]);
	      assign_data(plot->points, data, plot->size,YAXIS,plot->data_type);
	   }
	}
	else   /* info to be plotted from image is 3-D  */
	{
	   plot->WCmin.x  = 0;  /* arrays begin at 0 */
	   plot->WCmin.y  = 0;

	   plot->WCmax.x = image->row_size -1;
	   plot->WCmax.y = image->col_size -1;
	
	   plot->row_size = image->row_size;
	   plot->size = image->col_size * image->row_size;
	
	   /* dynamically allocate arrays */
	   plot->points = (Coord *) malloc((unsigned)(sizeof(Coord)*plot->size));
	   if (image->location_type == VFF_LOC_EXPLICIT)
	   {
	      data = (char *) image->location;
	      assign_data(plot->points, data, plot->size, XAXIS, VFF_TYP_FLOAT);

	      fptr = &(image->location[image->row_size * image->col_size]);
	      data = (char *) fptr;
	      assign_data(plot->points, data, plot->size, YAXIS, VFF_TYP_FLOAT);

	      data = (char *) &(image->imagedata[band * band_size]);
	      assign_data(plot->points, data, plot->size,ZAXIS,plot->data_type);
	   }
	   else
	   {
              l = 0;

              data = (char *) &(image->imagedata[band * band_size]);
              assign_data(plot->points, data, plot->size,ZAXIS,plot->data_type);

              for (i = 0; i < image->col_size; i++)
              {
                 for (j = 0; j < image->row_size; j++)
                 {
                     plot->points[l].x = j;
                     plot->points[l].y = i;
                     l++;
                 }
              }

              for (i = 0; i < image->col_size/2; i++)
              {
                 l = i * image->row_size;
                 m = (image->col_size -i -1) * image->row_size;

                 for (j = 0; j < image->row_size; j++)
                 {
                     ftemp = plot->points[l].z;
                     plot->points[l].z = plot->points[m].z;
                     plot->points[m].z = ftemp;
                     l++; m++;
                 }
              }
	   }
	}
        freeimage(image);
	find_min_max(plot, dimen);

	return(plot);
}


assign_data(points, data, size, axis, data_type)

Coord	*points;
char	*data;
int	axis;
long	size, data_type;
{
	int	i;
	char	*mesg;

	register int	       *iptr;
	register short	       *sptr;
	register float	       *fptr;
	register double	       *dptr;
	register unsigned char *cptr;

	if (axis == XAXIS)
	{
	   switch (data_type)
	   {
	     case VFF_TYP_1_BYTE:
	          cptr = (unsigned char *) data;
	          for (i = 0; i < size; i++)
		      points[i].x = *cptr++;
	          break;

	     case VFF_TYP_2_BYTE:
	          sptr = (short *) data;
	          for (i = 0; i < size; i++)
		      points[i].x = *sptr++;
	          break;

	      case VFF_TYP_4_BYTE:
	          iptr = (int *) data;
	          for (i = 0; i < size; i++)
		      points[i].x = *iptr++;
	          break;

	     case VFF_TYP_FLOAT:
	          fptr = (float *) data;
	          for (i = 0; i < size; i++)
		      points[i].x = *fptr++;
	          break;

	     case VFF_TYP_DOUBLE:
	          dptr = (double *) data;
	          for (i = 0; i < size; i++)
		      points[i].x = *dptr++;
	          break;

	      default:
	          mesg = xvf_strcpy("Cannot process. Unknown image type");
	          xvf_error_wait(mesg, "assign_data", NULL);
	          free(mesg);
                  return;
	   }
	}
	else if (axis == YAXIS)
	{
	   switch (data_type)
	   {
	     case VFF_TYP_1_BYTE:
	          cptr = (unsigned char *) data;
	          for (i = 0; i < size; i++)
		      points[i].y = *cptr++;
	          break;

	     case VFF_TYP_2_BYTE:
	          sptr = (short *) data;
	          for (i = 0; i < size; i++)
		      points[i].y = *sptr++;
	          break;

	      case VFF_TYP_4_BYTE:
	          iptr = (int *) data;
	          for (i = 0; i < size; i++)
		      points[i].y = *iptr++;
	          break;

	     case VFF_TYP_FLOAT:
	          fptr = (float *) data;
	          for (i = 0; i < size; i++)
		      points[i].y = *fptr++;
	          break;

	     case VFF_TYP_DOUBLE:
	          dptr = (double *) data;
	          for (i = 0; i < size; i++)
		      points[i].y = *dptr++;
	          break;

	      default:
	          mesg = xvf_strcpy("Cannot process. Unknown image type");
	          xvf_error_wait(mesg, "assign_data", NULL);
	          free(mesg);
                  return;
	   }
	}
	else if (axis == ZAXIS)
	{
	   switch (data_type)
	   {
	     case VFF_TYP_1_BYTE:
	          cptr = (unsigned char *) data;
	          for (i = 0; i < size; i++)
		      points[i].z = *cptr++;
	          break;

	     case VFF_TYP_2_BYTE:
	          sptr = (short *) data;
	          for (i = 0; i < size; i++)
		      points[i].z = *sptr++;
	          break;

	      case VFF_TYP_4_BYTE:
	          iptr = (int *) data;
	          for (i = 0; i < size; i++)
		      points[i].z = *iptr++;
	          break;

	     case VFF_TYP_FLOAT:
	          fptr = (float *) data;
	          for (i = 0; i < size; i++)
		      points[i].z = *fptr++;
	          break;

	     case VFF_TYP_DOUBLE:
	          dptr = (double *) data;
	          for (i = 0; i < size; i++)
		      points[i].z = *dptr++;
	          break;

	      default:
	          mesg = xvf_strcpy("Cannot process. Unknown image type");
	          xvf_error_wait(mesg, "assign_data", NULL);
	          free(mesg);
                  return;
	   }
	}
}



/************************************************************
*
*  MODULE NAME: get_input_file
*
*
*      PURPOSE: Reads in an input file to xprism2 - determines
*		what type of file it is (image: implicit or explicit,
*		or ascii: with data points or function)
*
*	INPUT:  form - pointer to the form tree
*		input_info - pointer to the Input Pane information structure
*
*       OUTPUT: plot
*
*    CALLED BY: main
*
*   WRITTEN BY: Danielle Argiro and Mark Young
*
*
*************************************************************/

XPlot *get_input_file(input_file, plot_type, data_format, machine_type, 
		      data_type, num_rows, whichband, complex_type)
char    *input_file;
int	plot_type, num_rows, whichband, complex_type;
int	data_format, machine_type, data_type;

{
    FILE  *fid;
    XPlot *plot, *get_function();
    int   filetype, get_file_type();
    char  *mesg, *filestring;
    char  temp[512], xrange[512], yrange[512], file_func[512], error[1024];
    

    if (gwin != NULL)
    {
        if (gwin->plotnum > 19)
        {
	  mesg = xvf_strcpy("Sorry... we only allow 20 plots in the workspace");
	    xvf_error_wait(mesg, "get_input_file", NULL);
       	    free(mesg);
	    return(NULL);
        }
    }

      /* 
       * determine what type of file we are working with
       */

    if (input_file == NULL)
    {
        mesg = xvf_strcpy("File selected but no file specified!\n");
        xvf_error_wait(mesg, "get_input_file", NULL);
        free(mesg);
        return(NULL);
    }

    filestring = vfullpath (input_file, global_indir, NULL);
    filetype = get_file_type(filestring);

    switch (filetype) {

	 
	 /* some kind of error in input */
	    case ERROR:
		 sprintf(temp, "file '%s' not found", filestring);
		 mesg = xvf_strcpy(temp);
		 xvf_error_wait(mesg, "get_input_file", NULL);
       		 free(mesg); return(NULL);
	         break;

	 /* input file type unknown */
	    case UNKNOWN:
	  	 xvf_error_wait(
			"Error in input- unknown type of file specified",
			"get_input_file", NULL);
		 return(NULL);
	         break;


	 /* input image file (XVIFF) */
	    case XVIFF:
                 plot = get_image(plot_type, filestring, 
				  whichband, complex_type);
                 if (plot == NULL) return(NULL); 
		 break;
		     
	 /* function appears in specified ascii file */
	    case ASCII_FUN:

		 if ((fid = fopen(filestring, "r")) == NULL) 
	         {
		     sprintf(temp, "File %s not found\n",filestring);
		     mesg = xvf_strcpy(temp);
	  	     xvf_error_wait(mesg, "get_input_file", NULL);
		     free(mesg);
       		     return(NULL);
		 }

		 file_func[0] = '\0';
		 xrange[0] = '\0';
		 yrange[0] = '\0';
		 get_file_function(fid, file_func, xrange, yrange, plot_type);
		 fclose(fid);

		 if (PLOT_TYPE_2D(plot_type))
		 {
		    if (VStrlen(file_func) != 0 && VStrlen(xrange) != 0)
                     plot = get_function(plot_type, file_func, xrange, 
					  NULL, error);
		    else
		    {
	              xvf_error_wait(
			  "An invalid function has been specified in the input \
file\n\nPlease check the function and comments." , "get_input_file", NULL);
		      return(NULL);
		    }
		 }
		 else
		 {
		    if (file_func != NULL && xrange != NULL && yrange != NULL)
                       plot = get_function(plot_type, file_func, 
					   xrange, yrange, error);
		    else
		    {
	              xvf_error_wait(
			  "An invalid function has been specified in the input \
file\n\nPlease check the function and comments." , "get_input_file", NULL);
		      return(NULL);
		    }
		 }

		 if (plot == NULL) 
		 {
	            xvf_error_wait(error, "get_input_file", NULL);
		    return(NULL);
		 }

	         plot->input_type = ASCII_FUN;
		 break;


	/* set of data points appears in specified ascii file */
	   case ASCII_DATA:
		plot = get_file_dps(plot_type, filestring, 
				    data_format, num_rows);
                if (plot == NULL) return(NULL);
	           plot->input_type = ASCII_DATA;
		break;

	   case RAW_DATA:
		plot = get_file_raw(plot_type, filestring, machine_type,
				    data_type, data_format, num_rows);
                if (plot == NULL) return(NULL);
	           plot->input_type = RAW_DATA;
		break;

	   default: 
		 mesg = xvf_strcpy("Hitting default filetype: unknown type of file specified\n");
		 xvf_error_wait(mesg, "get_input_file", NULL);
                 free(mesg);
                 return(NULL);
                 break;

	   }  /* end switch (filetype) */

      plot->plot_type = plot_type;
      find_min_max(plot, plot_type);
      return(plot);


} /* end get_input_file */
/************************************************************
*
*  MODULE NAME: get_file_points
*
*
*      PURPOSE: Reads in an input file and determines the number of
*		data points in the file.
*
*	INPUT: input_file - input file to count points in
*		data_format - the data format, XY_PAIRS, Y_ONLY,
*				Z_ONLY, XYZ_TRIPLES
*		data_type - the data type used only for raw files
*			    VFF_TYP_1_BYTE, VFF_TYP_2_BYTE, VFF_TYP_4_BYTE,
*			    VFF_TYP_FLOAT
*
*       OUTPUT: number of data points, 
*		If there are 0 points in the file a 0 uis returned
*		If an error occurs a -1 is returned
*
*    CALLED BY: who ever needs it.
*
*   WRITTEN BY: Tom Sauer
*
*
*************************************************************/

int get_file_points(plot_type, input_file, data_format, data_type, num_points_x,
		    num_points_y)
char    *input_file;
int	data_format, data_type, *num_points_x, *num_points_y;

{
    FILE  *fid;
    int   filetype, get_file_type(), points;
    int   fd;
    float *data, *read_ascii();
    float beg, end;
    char  *filestring;
    char  xrange[512], yrange[512], file_func[512], error[512];
    struct xvimage *image;
    struct stat buf;

    *num_points_x = 0; 
    *num_points_y = 0;
    /* determine what type of file we are working with */
    if (input_file == NULL)
    {
        return(-1);
    }

    filestring = vfullpath (input_file, global_indir, NULL);
    filetype = get_file_type(filestring);

    switch (filetype) {

	 
	 /* some kind of error in input */
	    case ERROR:
		 free(filestring);
		 return(-1);
	         break;

	 /* input file type unknown */
	    case UNKNOWN:
		 free(filestring);
		 return(-1);
	         break;


	 /* input image file (XVIFF) */
	    case XVIFF:
                 image = readimage(filestring);
                 if (image == NULL)
                 {
                        free(filestring);
                        return(-1);
                 }
		 *num_points_x = image->row_size * image->col_size;
		 free(image);
		 break;
		     
	 /* function appears in specified ascii file */
	    case ASCII_FUN:
		if ((fid = fopen(filestring, "r")) == NULL)
	   		return(-1);

		 file_func[0] = '\0';
		 xrange[0] = '\0';
		 yrange[0] = '\0';
		 get_file_function(fid, file_func, xrange, yrange, plot_type);
		 fclose(fid);

		 if (PLOT_TYPE_2D(plot_type))
		 {
		    if (! get_range(xrange, &beg, &end, num_points_x, error))
			return(-1);
	         }
                 else
		 {
		    if (! get_range(xrange, &beg, &end, num_points_x, error))
			return(-1);
		    if (! get_range(yrange, &beg, &end, num_points_y, error))
			return(-1);
		 }
		 /* add stuff for 3D here */
		 break;


	/* set of data points appears in specified ascii file */
	   case ASCII_DATA:
		/* attempt to open the file */
		if ((fid = fopen(filestring, "r")) == NULL)
		{
		        free(filestring);
	   		return(-1);
		}

		/* initializations */

        	data = read_ascii(fid, &points);
 		(void) fclose(fid);
        	if (data == NULL)
	   		*num_points_x = 0;
		switch (data_format)
        	{
          	   case XY_PAIRS:
              		*num_points_x = points/2;
              		break;
          	   case Y_ONLY:
          	   case Z_ONLY:
              		*num_points_x = points;
              		break;
          	   case XYZ_TRIPLES:
 	      		*num_points_x = points/3;
              		break;
          	   default:
	       		free(data);
		        free(filestring);
	       		return(-1);
               		break;
        	}
		break;

	   case RAW_DATA:
		if (stat(filestring, &buf) == -1)
		{
		        free(filestring);
			return(-1);
		}

		switch(data_type)
		{
		   case VFF_TYP_1_BYTE:
			points = buf.st_size;
			break;
		   case VFF_TYP_2_BYTE:
			points = buf.st_size/2;
			break;
		   case VFF_TYP_4_BYTE:
		   case VFF_TYP_FLOAT:
			points = buf.st_size/4;
			break;
		   default:
		        free(filestring);
			return(-1);
			break;
		}

		switch (data_format)
        	{
          	   case XY_PAIRS:
              		*num_points_x = points/2;
              		break;
          	   case Y_ONLY:
          	   case Z_ONLY:
              		*num_points_x = points;
              		break;
          	   case XYZ_TRIPLES:
 	      		*num_points_x = points/3;
              		break;
          	   default:
		        free(filestring);
	       		return(-1);
               		break;
		}
		break;

	   default: 
		 free(filestring);
		 return(-1);
                 break;

	   }  /* end switch (filetype) */

      free(filestring);
      return(1);


} /* end get_file_points */


/************************************************************
*
*  MODULE NAME: get_file_function
*
*
*      PURPOSE: Reads in an input file and weed through the comments
*		to find the function and ranges
*		This routine was not written to be robust, but to
*		allow folks to have comments in the function files.
*		Eventually the xvparser should do this work.
*
*	INPUT:  fid - the open ascii file
*		file_func - a NULL pointer for the function
*		xrange - a NULL pointer for the xrange
*		yrange - a NULL pointer for the yrange
*		plot_type - either 2D or 3D
*
*       OUTPUT: file_func - a pointer to the function
*               xrange - a pointer to the xrange
*               yrange - a pointer to the yrange
*
*   WRITTEN BY: Tom Sauer
*
*
*************************************************************/

get_file_function(fid, file_func, xrange, yrange, plot_type)

FILE    *fid;
char    *file_func, *xrange, *yrange;
int	plot_type;

{
    char  data[512];
    int found_func, found_xintv, found_yintv, comment, done, len, i;
    

	found_func = False;
	found_xintv = False;
	found_yintv = False;
	comment = False;
	while(! feof(fid))
	{
	   (void) fgets(data, 512, fid);
	   len = VStrlen(data);
	   i = 0;
	   done = False;
	   while (! done && i < len)
	   {
	     if (comment == True)
	     {
		if (data[i] == '*' && data[i+1] == '/')
		{
		  comment = False;
		  i++;
		}
	     }
	     else if(data[i] == '#' && ! comment)
	     {
	       done = True;
	     }
	     else if (data[i] == '/' && data[i+1] == '*')
	     {
		comment = True;
		i++;
	     }
	     else if (! comment && PLOT_TYPE_2D(plot_type))
	     {
	           if ((strncmp(&data[i], "f(x)",4) == 0) && ! found_func)
	           {
		      strcpy(file_func, &data[i]);
		      done = True;
		      found_func = True;
		   }
		   else if ((strncmp(&data[i], "x =",3) == 0) && ! found_xintv)
		   {
                           strcpy(xrange, &data[i]);
                           done = True;
                           found_xintv = True;
		   }
		   else if ((strncmp(&data[i], "x=",2) == 0) && ! found_xintv)
                   {
                              strcpy(xrange,&data[i]);
                              done = True;
                              found_xintv = True;
		   }
	     }
	     else if (! comment && PLOT_TYPE_3D(plot_type))
	     {
	           if ((strncmp(&data[i], "f(x,y)",6) == 0) && ! found_func)
	           {
		      strcpy(file_func, &data[i]);
		      done = True;
		      found_func = True;
		   }
	           else if ((strncmp(&data[i],"f(x ,y)",7)== 0) && ! found_func)
	           {
		      strcpy(file_func, &data[i]);
		      done = True;
		      found_func = True;
		   }
	           else if ((strncmp(&data[i],"f(x , y)",8)==0) && ! found_func)
	           {
		      strcpy(file_func, &data[i]);
		      done = True;
		      found_func = True;
		   }
	           else if ((strncmp(&data[i],"f(x, y)",7)== 0) && ! found_func)
	           {
		      strcpy(file_func, &data[i]);
		      done = True;
		      found_func = True;
		   }
		   else if ((strncmp(&data[i], "x =",3) == 0) && ! found_xintv)
		   {
                      strcpy(xrange, &data[i]);
                      done = True;
                      found_xintv = True;
		   }
		   else if ((strncmp(&data[i], "x=",2) == 0) && ! found_xintv)
                   {
                      strcpy(xrange,&data[i]);
                      done = True;
                      found_xintv = True;
		   }
		   else if ((strncmp(&data[i], "y =",3) == 0) && ! found_yintv)
		   {
                      strcpy(yrange, &data[i]);
                      done = True;
                      found_yintv = True;
		   }
		   else if ((strncmp(&data[i], "y=",2) == 0) && ! found_yintv)
                   {
                      strcpy(yrange,&data[i]);
                      done = True;
                      found_yintv = True;
		   }
	     }
	     i++;
	   }
       }
}

