 /*
  * Khoros: $Id$
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id$";
#endif

 /*
  * $Log$
  */ 

/*
 *---------------------------------------------------------------------
 *            Copyright 1990 University of New Mexico
 * 
 * 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"
#include "spectrum.h"

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>  		     	Output Utilities
 >>>>
 >>>>			write_data()
 >>>>			output_image_and_cmap()
 >>>>			output_cmap_only()
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/



/********************************************************
*
*  Routine Name: write_data
*
*       Purpose: writes out the image & map data
*	  Input: filename to write to
*	 Output: none
*    Written by: Danielle
*
********************************************************/
int write_data(filename)
char *filename;
{
	char *fullpath, temp[MaxLength];
	struct xvimage *out_image;
	float *floatptr;
	int   i, j, extra_columns = 0;
	legend_list *legend_ptr;
	FILE *file;
	unsigned long img_col_size, img_row_size, data_storage_type,
		      num_of_images, num_data_bands, map_rowsize, map_colsize,
		      map_scheme, map_storage_type, location_type,
		      location_dim;
		      

	/* expand filename */
        if (!(fullpath = vfullpath(filename, NULL, NULL)))
        {
           sprintf(temp, "Unable to expand '%s' in order to write image.",
                   filename);
           xvf_error_wait(temp, "write_data", NULL);
           return(false);
        }

	        /* see if legend file already exists/prompt to over-write*/
        if (file = fopen(fullpath, "r"))
        {
           sprintf(temp, "Over-write file '%s'?", fullpath);
           if (!(xvf_warn_wait(temp, "write_data", "Yes", "No")))
           {
               fclose(file);
               return(false);
           }
           fclose(file);
        }
	
	img_col_size = spc_image->col_size;
	img_row_size = spc_image->row_size;
	data_storage_type = VFF_TYP_1_BYTE;
	num_of_images = spc_image->num_of_images;
	num_data_bands = spc_image->num_data_bands;

	map_rowsize = spc_map_colnum;

	extra_columns += 2;  /* 2 extra columns for Count and Class columns */
	if (spc_map_contents & SpcCovarMatrix) 
	     extra_columns += spc_matrix_size;
	else if (spc_map_contents & SpcCovarDiag) 
	     extra_columns += spc_diag_size;

	map_rowsize += extra_columns;
	map_colsize = spc_map_rownum; 
	map_scheme = VFF_MS_ONEPERBAND;
	map_storage_type = VFF_MAPTYP_FLOAT;
	location_type = spc_image->location_type;
	location_dim = spc_image->location_dim;


	out_image = createimage(img_col_size, img_row_size, data_storage_type, 
		    num_of_images, num_data_bands, spc_image->comment, 
		    map_rowsize, map_colsize, map_scheme, map_storage_type, 
		    location_type, location_dim);
 

	out_image->imagedata = spc_image->imagedata;

	out_image->maps = (char *)malloc(map_rowsize*map_colsize*sizeof(float));

	floatptr = (float *) out_image->maps;

	/* always enter map data */
	for (i = 0; i < spc_map_colnum; i++)
	{
	   for (j = 0; j < spc_map_rownum; j++)
	   {
		*floatptr = spc_map[i][j];
		floatptr++;
           }
        }

	/* always enter count column */
	for (j = 0; j < spc_map_rownum; j++)
	{
	    *floatptr = spc_count[j];
	    floatptr++;
	}

	/* always enter class info (if any) */
	if (spc_legend_lookup == NULL)
	   spc_map_contents = spc_map_contents & (!SpcClass);

	else
	{
	   for (j = 0; j < spc_map_rownum; j++)
	   {
	       legend_ptr = spc_legend_lookup[j];
	       if (legend_ptr != NULL)
	           *floatptr = legend_ptr->class;
	       else *floatptr = -1;
	       floatptr++;
	   }
	}

	/* enter covariance matrix if maps came in with one */
	if (spc_map_contents & SpcCovarMatrix)
        {
	    for ( i = 0; i < spc_matrix_size; i++ )
	    {
		for (j = 0; j < spc_map_rownum; j++)
                {
                    *floatptr = spc_covar_matrix[i][j];
                     floatptr++;
                }
	    }
	}
	/* enter covariance diagonal if maps came in with one */
	else if (spc_map_contents & SpcCovarDiag)
        {
	    for ( i = 0; i < spc_diag_size; i++ )
	    {
		for (j = 0; j < spc_map_rownum; j++)
                {
                    *floatptr = spc_covar_diag[i][j];
                     floatptr++;
                }
	    }
	}

	out_image->ispare2 = spc_map_colnum;
	out_image->ispare1 = spc_map_contents | SpcCount;
	(void) writeimage(filename, out_image);

	/* 
	 * DON'T use freeimage() because we DON'T want to 
         * free the image data or the map data ! 
         */
	free((char *) out_image->maps);
	free(out_image);
	return(true);

}

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

output_image_and_cmap(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/MAX_PIXELS + 0.5;
               maps[i + MAX_PIXELS]     = colors[i].green/MAX_PIXELS + 0.5;
               maps[i + MAX_PIXELS * 2] = colors[i].blue/MAX_PIXELS + 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, NULL, 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, "Image with currently displayed colormap output to file %s.", filename);
        xvf_error_wait(temp, "output_image", NULL);

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



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

output_cmap_only(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/MAX_PIXELS + 0.5;
               maps[i + MAX_PIXELS]     = colors[i].green/MAX_PIXELS + 0.5;
               maps[i + MAX_PIXELS * 2] = colors[i].blue/MAX_PIXELS + 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, NULL, 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 colormap only output to file %s.", filename);
        xvf_error_wait(temp, "output_image", NULL);

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

