 /*
  * Khoros: $Id: run_file.c,v 1.4 1992/03/20 22:39:26 dkhoros Exp $
  */

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

 /*
  * $Log: run_file.c,v $
 * Revision 1.4  1992/03/20  22:39:26  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 "editimage.h"


/********************************************************
*
*  Routine Name:  run_file
*
*       Purpose:  drives the pane 'file'
*
*         Input:  form - pointer to the form tree 
*		  file_info  - information structure for pane 'file'
*        Output:  action of the application program
*
*     Called By:  run_function()
*
*   Automatically Generated By:  conductor
*
********************************************************/


run_file(form, file_info)

xvf_form *form;
files_subform_file *file_info;
{
	char *fullpath, temp[MaxLength];

	_xvf_get_file(form, file_info);

	/*
	 * user clicked on 'live' string selection 'input_path'
	 */
	if (file_info->input_path_selected)
	{
	    if (global_indir != NULL)
	        free(global_indir);

            global_indir = xvf_strcpy(file_info->input_path);
            XVF_FILE_DIR = file_info->input_path;
	    fullpath = vfullpath(file_info->input_path, NULL, NULL);
            sprintf(temp, "Global input path now set to %s.", fullpath);
            xvf_error_wait(temp, "run_file", NULL);
	}

	/*
	 * user clicked on 'live' string selection 'output_path'
	 */
	else if (file_info->output_path_selected)
	{
	    if (global_outdir != NULL)
                free(global_outdir);

            global_outdir = xvf_strcpy(file_info->output_path);
	    fullpath = vfullpath(file_info->output_path, NULL, NULL);
            sprintf(temp, "Global output path now set to %s.", fullpath);
            xvf_error_wait(temp, "run_file", NULL);
	}

	/*
	 * user clicked on 'live' input file selection 'image'
	 */
	else if (file_info->image_selected)
	    input_new_image(file_info->image);


	/*
	 * user clicked on 'live' input file selection 'overlay'
	 */
	else if (file_info->overlay_selected)
	    input_new_overlay(file_info->overlay);


	/*
	 * protection mechanism 
	 */
	else if (xvdisplay->image == NULL)
	{
	    xvf_error_wait("Please display an image before attempting to do this operation", "run_file", NULL);
	    return;
	}

	/*
	 * user clicked on 'live' input file selection 'colormap'
	 */
	else if (file_info->colormap_selected)
	    input_new_colormap(file_info->colormap);

	/*
	 * user clicked on 'live' input file selection 'shape'
	 */
	else if (file_info->shape_selected)
	    input_new_shape(file_info->shape);

	/*
	 * user clicked on 'live' input file selection 'clip'
	 */
	else if (file_info->clip_selected)
	    input_new_clip(file_info->clip);

	/*
	 * user clicked on 'live' output file selection 'outfile'
	 */
	else if (file_info->outfile_selected)
	    output_image(file_info->outfile);

	/*
	 * user clicked on 'live' output file selection 'outmap'
	 */
	else if (file_info->outmap_selected)
	    output_colormap(file_info->outmap);
}



/********************************************************
*
*  Routine Name:  input_new_image
*
*       Purpose:  brings in a new image to be displayed when the
*		  user clicks on the live "input file" selection
*
*         Input:  filename - name of the new input image file
*        Output:  displays the new image
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

input_new_image(infile)

char *infile;
{
	char   *filename, temp[MaxLength];
	struct xvimage *image, *readimage();

	/* 
	 * make sure they've provided a filename 
         */
	if (infile == NULL)
        {
             xvf_error_wait("Error! No filename specified.", 
			    "input_new_image", NULL);
                 return;
        }
	filename = vfullpath(infile, global_indir, NULL);

	/*
         *  read in the new image
         */
        if (!(image = readimage(filename)))
        {
           /* error in readimage */
	   sprintf(temp, "readimage failed! Unable to read image from file %s.", filename);
           xvf_error_wait(temp, "run_file", NULL);
           free(filename);
	   return;
        }
	
	/*
	 *  update with the new image
	 */
	if (update_image(image) == False)
	{
	   free(filename);
	   return;
	}

	if (update_id != 0)
	{
	    xvf_delete_detect(update_id);
	    update_id = 0;
	}

	if (update_time != 0)
	{
	    update_id = xvf_detect_file(filename, update_time, 
					update_file, NULL);
	}
	free(filename);
}



/********************************************************
*
*  Routine Name:  input_new_colormap
*
*       Purpose:  brings in a new image to have its colormap used when the
*		  user clicks on the live "input colormap" selection
*
*         Input:  filename - name of the image file with the new colormap
*        Output:  displays the old image with the new colormap
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

input_new_colormap(infile)

char *infile;
{
	int    num;
	char   *filename, temp[MaxLength];
	struct xvimage *image, *readimage();

	/* 
	 * make sure they've provided a filename 
         */
	if (infile == NULL)
        {
           xvf_error_wait("Error!  No filename specified.","input_new_colormap",
			 NULL);
           return;
        }
	filename = vfullpath(infile, global_indir, NULL);

	/*
         *  read in the new image
         */
        if (!(image = readimage(filename)))
        {
           /* error in readimage */
           sprintf(temp, "readimage failed! Unable to read image from file %s.",
		   filename);
           xvf_error_wait(temp, "input_new_colormap", NULL);
           free(filename);
	   return;
        }

        if (image->map_storage_type != VFF_MAPTYP_1_BYTE &&
	    image->map_storage_type != VFF_MAPTYP_NONE)
        {
           xvf_error_wait("Error! Input image colormap type must be of type None (VFF_MAPTYP_NONE) or Byte (VFF_MAPTYP_1_BYTE)\n.", "input_new_colormap", NULL);
           free(filename); freeimage(image);
           return;
        }
	transfer_colormap(image, xvdisplay->image);

	/*
	 *  update with the new image
	 */
	xvd_load_xcolors(xvdisplay);
	num = (xvdisplay->pixelmax - xvdisplay->pixelmin) + 1;
	store_colors(xvdisplay->xcolors, xvdisplay->pixelmin, num);

	/*
	 * Cleanup
	 */
	free(filename);
	freeimage(image);
}



/********************************************************
*
*  Routine Name:  input_new_shape
*
*       Purpose:  brings in a bit image to be used as a shape mask when the
*		  user clicks on the live "input shape mask" selection
*
*         Input:  filename - name of the image file to be used as a shape mask
*        Output:  displays the old image masked by the new shape image
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

input_new_shape(infile)

char *infile;
{
	char   *filename, temp[MaxLength];
	struct xvimage *shape, *readimage();

	/* 
	 * if they put in a NULL filename, 
	 * delete any existing shape masks
         */
	if (infile == NULL)
        {
	    xvdisplay->shape = NULL;
	    xvd_update_shape(xvdisplay, NULL);
            return;
        }
	filename = vfullpath(infile, global_indir, NULL);

	/*
         *  read in the new image
         */
        if (!(shape = readimage(filename)))
        {
           /* error in readimage */
	   sprintf(temp, "readimage failed! Unable to read shape image from \
file %s.", filename);
           xvf_error_wait(temp, "input_new_shape", NULL);
           free(filename);
	   return;
        }
	xvd_update_shape(xvdisplay, shape);

	/*
	 * Cleanup
	 */
        free(filename);
}



/********************************************************
*
*  Routine Name:  input_new_clip
*
*       Purpose:  brings in a bit image to be used as a clip mask when the
*		  user clicks on the live "input clip mask" selection
*
*         Input:  filename - name of the image file to be used as a clip mask
*        Output:  displays the old image masked by the new clip image
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

input_new_clip(infile)
char *infile;
{
	char *filename, temp[MaxLength];
	struct xvimage *clip, *readimage();

	/* 
	 * if they put in a NULL filename, 
	 * delete any existing clip masks
         */
	if (infile == NULL)
        {
	    if (xvdisplay->clip != NULL)
	       freeimage(xvdisplay->clip);

	    xvdisplay->clip = NULL;
	    xvd_update_clip(xvdisplay, NULL);
            return;
        }
	filename = vfullpath(infile, global_indir, NULL);

	/*
         *  read in the new clip image
         */
        if (!(clip = readimage(filename)))
        {
           /* error in readimage */
           sprintf(temp, "readimage failed! Unable to read clip image from \
file %s.", filename);
           xvf_error_wait(temp, "run_file", NULL);
           free(filename);
	   return;
        }
	xvd_update_clip(xvdisplay, clip);

	/*
	 * Cleanup
	 */
        free(filename);
}



/********************************************************
*
*  Routine Name:  input_new_overlay
*
*       Purpose:  brings in a new image to be overlaid onto the 
*		  currently displayed image  when the
*		  user clicks on the live "input file" selection
*
*         Input:  filename - name of the new input overlay file
*        Output:  displays the new image
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/


input_new_overlay(infile)

char *infile;
{
	char   *filename, temp[MaxLength];
	struct xvimage *readimage(), **xvd_seperate_images();


	/* 
	 * if they put in a NULL filename, 
	 * delete any existing overlays
         */
	if (infile == NULL)
        {
	    free_overlays();
	    xvd_update_overlay(xvdisplay, NULL);
            return;
        }
	filename = vfullpath(infile, global_indir, NULL);

	/*
         *  read in the new overlays
         */
	if (overlays != NULL)
	{
	   free_overlays();
	   xvd_update_overlay(xvdisplay, NULL);
	}

        if (!(overlays = readimage(filename)))
        {
           /* error in readimage */
           sprintf(temp, "readimage failed! Unable to read image from file \
%s.", filename);
           xvf_error_wait(temp, "input_new_overlay", NULL);
           free(filename);
	   return;
        }

	if (overlays != NULL)
        {
           if (!(ovband = xvd_seperate_images(overlays, &num_ovbands)))
           {
              xvf_error_wait("leditimage", "lvbandsprt failed for seperating \
out overlay bands!\n", NULL);
              overlays = NULL;
              ovband   = NULL;
           }
	   else
	   {
	      ovactive = (int *) XtCalloc(1, sizeof(int) * num_ovbands);
	   }
        }
	change_overlays();

	/*
	 *  Cleanup
	 */
	free(filename);
}



/********************************************************
*
*  Routine Name:  output_image
*
*       Purpose:  outputs the image that is currently displayed when the
*		  user clicks on the live "output file" selection
*
*         Input:  filename - name of the output image file
*        Output:  outputs the new image
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

output_image(outfile)

char *outfile;
{
	int      i;
        unsigned char *maps;
	struct   xvimage *image;
	XColor	 colors[MAX_PIXELS];
	char     *filename, temp[MaxLength];
        XColor   *xcolors  = xvdisplay->xcolors;


	/*
	 *  Get the current colors in the colormap.
	 */
	for (i = 0; i < ncolors; i++)
	{
	   colors[i].pixel = xcolors[i].pixel;
	   if (xvdisplay->histogram[i] > 0)
	      colors[i].flags = DoRed | DoGreen | DoBlue;
	   else
	      colors[i].flags = 0;
	}
	XQueryColors(display, xvdisplay->colormap, colors, ncolors);

        maps  = (unsigned char *) XtMalloc(3 * MAX_PIXELS);
        image = (struct xvimage *) XtMalloc(sizeof(struct xvimage));
        bcopy(xvdisplay->image, image, sizeof(struct xvimage));
        image->maps = (char *) maps;

        for (i = 0; i < MAX_PIXELS; i++)
        {
            if (xvdisplay->histogram[i] > 0)
            {
               maps[i]			= colors[i].red/256 + 0.5;
               maps[i + MAX_PIXELS]     = colors[i].green/256 + 0.5;
               maps[i + MAX_PIXELS * 2] = colors[i].blue/256 + 0.5;
            }
            else
            {
               maps[i] =
               maps[i + MAX_PIXELS] =
               maps[i + MAX_PIXELS * 2] = i;
            }
        }
        image->map_row_size      = 3;
        image->map_col_size      = MAX_PIXELS;
        image->map_scheme        = VFF_MS_SHARED;
        image->map_storage_type  = VFF_MAPTYP_1_BYTE;
        image->color_space_model = VFF_CM_genericRGB;

	filename = vfullpath(outfile, global_outdir, NULL);
        if (!writeimage(filename, image))
        {
           sprintf(temp, "writeimage failed! Unable to write image to file %s.", filename);
           xvf_error_wait(temp, "file_output", NULL);
           free(filename); free(image); free(maps);
           return;
        }
        sprintf(temp, "Currently displayed image output to file %s.", filename);
        xvf_error_wait(temp, "output_image", NULL);

	/*
	 *  Cleanup
	 */
        free(filename);
	free(image);
	free(maps);
}



/********************************************************
*
*  Routine Name:  output_colormap
*
*       Purpose:  outputs the image colormap that is currently displayed
*		  when the user clicks on the live "output file" selection
*
*         Input:  filename - name of the output image file
*        Output:  outputs the new image's colormap
*
*     Called By:  run_file()
*
*    Written By:  Danielle Argiro & Mark Young
*
********************************************************/

output_colormap(outfile)

char *outfile;
{
	int      i;
        unsigned char *maps;
	struct   xvimage *image;
	XColor	 colors[MAX_PIXELS];
	char     *filename, temp[MaxLength];
        XColor   *xcolors  = xvdisplay->xcolors;


	/*
	 *  Get the current colors in the colormap.
	 */
	for (i = 0; i < ncolors; i++)
	{
	   colors[i].pixel = xcolors[i].pixel;
	   if (xvdisplay->histogram[i] > 0)
	      colors[i].flags = DoRed | DoGreen | DoBlue;
	   else
	      colors[i].flags = 0;
	}
	XQueryColors(display, xvdisplay->colormap, colors, ncolors);

        maps  = (unsigned char *) XtMalloc(3 * MAX_PIXELS);
        image = (struct xvimage *) XtMalloc(sizeof(struct xvimage));
        bcopy(xvdisplay->image, image, sizeof(struct xvimage));
        image->maps = (char *) maps;

        for (i = 0; i < MAX_PIXELS; i++)
        {
            if (xvdisplay->histogram[i] > 0)
            {
               maps[i]			= colors[i].red/256 + 0.5;
               maps[i + MAX_PIXELS]     = colors[i].green/256 + 0.5;
               maps[i + MAX_PIXELS * 2] = colors[i].blue/256 + 0.5;
            }
            else
            {
               maps[i] =
               maps[i + MAX_PIXELS] =
               maps[i + MAX_PIXELS * 2] = i;
            }
        }
        image->map_row_size      = 3;
        image->map_col_size      = MAX_PIXELS;
        image->map_scheme        = VFF_MS_SHARED;
        image->map_storage_type  = VFF_MAPTYP_1_BYTE;
        image->color_space_model = VFF_CM_genericRGB;
	image->imagedata	 = NULL;
	image->row_size		 =
	image->col_size		 = 0;

	filename = vfullpath(outfile, global_outdir, NULL);
        if (!writeimage(filename, image))
        {
           sprintf(temp, "writeimage failed! Unable to write image to file %s.", filename);
           xvf_error_wait(temp, "file_output", NULL);
           free(filename); free(image); free(maps);
           return;
        }
        sprintf(temp, "Currently displayed image output to file %s.", filename);
        xvf_error_wait(temp, "output_image", NULL);

	/*
	 *  Cleanup
	 */
        free(filename);
	free(image);
	free(maps);
}
