/****************************************************************************/
/*                                                                          */
/*  VolVis is a volume visualization system for investigating, manipulating */
/*  and rendering geometric and volumetric data.                            */
/*                                                                          */
/*  Copyright (C) 1993 by the Research Foundation of the State University   */
/*                            of New York                                   */
/*                                                                          */
/*  This program is free software; you can redistribute it and/or modify    */
/*  it under the terms of the GNU General Public License as published by    */
/*  the Free Software Foundation; either version 1, or (at your option)     */
/*  any later version.                                                      */
/*                                                                          */
/*  This program is distributed in the hope that it will be useful,         */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of          */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
/*  GNU General Public License for more details.                            */
/*                                                                          */
/*  You should have received a copy of the GNU General Public License       */
/*  along with this program; if not, write to the Free Software             */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
/*                                                                          */
/*  For information on VolVis, contact us at:                               */
/*                                                                          */
/*                volvis@cs.sunysb.edu                         (email)      */
/*                                                                          */
/*                Lisa Sobierajski & Ricardo Avila             (US Mail)    */
/*                Department of Computer Science                            */
/*                State University of New York at Stony Brook               */
/*                Stony Brook, New York  11794-4400                         */
/*                                                                          */
/****************************************************************************/



/*
 *                      File: X_ivi_frame.c
 *                    Author: Sean Francisco Smith
 *                      Date: 09/22/92
 *               Description: Image control routines for VolVis
 *      Modification History:
 *
 *              Who?            When?           Why?
 *      --------------------------------------------------------------------
 *
 */
#include	"OL_vv_ui.h"
#include	"C_volvis.h"

extern 	C_ImageTable	image_table;

/*
 *        Procedure Name: display_image
 *          Return Value:
 *       Input Variables: display, depth 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables: 
 *           Description: Repaint procedure for test_canvas
 */
#ifdef C_MOTIF
ivi_display_image( image_num, depth)
int	image_num,
	depth;
{
#endif
#ifdef C_OL
ivi_display_image( image_num, depth, display, gc, xid)
int	image_num;
int	depth;
Display		*display;
GC		gc;
XID		xid;
{
#endif
	unsigned char	*red_img_pointer,
			*green_img_pointer,
			*blue_img_pointer;

	int		red_lock,
			green_lock,
			blue_lock;

	int		height_index,
			width_index; 

	int		image_height,
			image_width;

	char		*pixel_data;
	XColor		pixel_color;
	XImage		*x_image;
	C_Image		*image;

#ifdef C_MOTIF
	GC		gc;
	Display		display;

	display = C_GetDisplay(image_table.image_entry[image_num]->ui_win),
	gc= XCreateGC( 	display,
			C_GetWindow(image_table.image_entry[image_num]->ui_win),
			NULL,
			NULL);
#endif
	image = image_table.image_entry[image_num]->image;

        red_img_pointer = image->red;
        green_img_pointer = image->green;
        blue_img_pointer = image->blue;

        /* get dimensions */
        image_height = image->height;
        image_width = image->width;

	/* Make space for pixels based on amount of data needed */
	if (depth == 24)
        	pixel_data = (char *) malloc(image_width*image_height*
                                sizeof(unsigned long));

	if (depth == 8)
		pixel_data = (char *) malloc(image_width*image_height*
				sizeof( unsigned long));

	if (pixel_data == NULL)
	{
		printf(" Unable to allocate pixel_data \n");
	}

        if (depth ==24)
        {
           x_image = XCreateImage( display,
                                DefaultVisual( display,
                                DefaultScreen( display)),
                                depth,
                                ZPixmap,
                                0,
                                pixel_data,
                                image_width,
                                image_height,
                                32,
                                image_width*sizeof(unsigned long));

           for (height_index = 0;height_index < image_height ;height_index++)
           {
               for(width_index = 0; width_index < image_width ;width_index++)
               {
                   pixel_color.pixel = *(red_img_pointer++) |
                                        ((*( green_img_pointer++))<<8) |                                                ((*( blue_img_pointer++))<<16);

                   XPutPixel(      x_image,
                                   width_index,
                                   height_index,
                                   pixel_color.pixel);
               }
           }
        }
	if (depth == 8)  
        {
		printf(" Depth is 8 \n");
           x_image = XCreateImage( display,
                                DefaultVisual(display,
                                DefaultScreen( display )),
                                depth,
                                ZPixmap,
                                0,
                                pixel_data,
                                image_width,
                                image_height,
                                32,
                                image_width*sizeof(unsigned long));

           for (height_index = 0; height_index < image_height; height_index++)
           {
               for( width_index = 0; width_index < image_width; width_index++)
               {
                   red_lock = *(red_img_pointer++);
                   green_lock = *(green_img_pointer++);
                   blue_lock = *(blue_img_pointer++);
 
                   /* Tweak formula as desired for hardware */
 
                    pixel_color.pixel = ((red_lock & 0xe0) 
                                        | ((green_lock & 0xe0)>>3)
                                        | ((blue_lock & 0xc0) >> 5));

                   /* figure how to get pixel index */
                   XPutPixel(      x_image,
                                   width_index,
                                   height_index,
                                   pixel_color.pixel);
               }
           }
        }

	XPutImage(	display,
#ifdef	C_MOTIF
			C_GetWindow(image_table.image_entry[image_num]->ui_win),
#endif
#ifdef	C_OL
			xid,
#endif
			gc,
			x_image,
			0,0,0,0,
			image_width,
			image_height );

	XFreeGC( display, gc);
	free( pixel_data ); 
	XDestroyImage( x_image );
}



/*
 *        Procedure Name: match_visual_info
 *          Return Value: match_num
 *       Input Variables:  display, screen_num
 *      Output Variables:
 *      Update Variables: colormap
 *      Global Variables:
 *           Description:gets depth and create colormap info for Object Control
 *                              Modify.
 */
int	match_visual_info( display, screen_num )
Display		*display;
int		screen_num;
{
	int	match_num;

	XVisualInfo	visual_template,
			*visualList;

	/* Test for Visual type needed */
        visual_template.class = TrueColor;
        visual_template.screen = screen_num;
        visual_template.depth = 24;
        visualList = XGetVisualInfo( display,
                               VisualScreenMask|VisualDepthMask|VisualClassMask,
                               &visual_template, &match_num);
	return (match_num);
}

/*
 *        Procedure Name: make_color_map
 *          Return Value:
 *       Input Variables: display, colors. screen_num
 *      Output Variables:
 *      Update Variables: colormap
 *      Global Variables:
 *           Description: makes color map. If colormap is already initialized
 *			then it returns automatically, and does NOT allocate
 *			a new colormap. If it is not, then the colors are
 *                      allocated.        
 */
void make_color_map( display, colors, screen_num)
Display 	*display;
XColor		*colors;
int		screen_num;
{
	int 	index,          /* index to color array */
                index_red,      /* counter for for loop */
                index_green,    /* "    "       "       */
                index_blue,     /* "    "       "       */
                add_red,        /* amount to add to red index*/
                add_green,      /* "    "       "   green "  */
                add_blue;       /*      "       "   blue  "  */

	if (image_table.colormap)
	{
		return;
	}
	else
	{
		image_table.colormap = XCreateColormap( 	display,
                           		RootWindow( display, screen_num),
                           		DefaultVisual(display, screen_num),
                           		AllocAll);

        	/* match colormap to window */
        	XSetWindowColormap( 	display,
        		                RootWindow(display, screen_num),
               		         	image_table.colormap);
        	/* test for colormap- it has succeeded */
 
        	index = 0;
        	for (index_red = 0; index_red < 256; index_red+= 32)
        	{
        		add_red = (index_red/32)*4;
               		for( index_green = 0;index_green < 256; index_green+=32)                        {
                		add_green = (index_green/32)*4;
                        	for(index_blue=0;index_blue<256;index_blue+=64)
                        	{
                        		add_blue = (index_blue/64)* 16;
                                	colors[index].flags = 0xff;
                                	colors[index].red = 
						(index_red + add_red)*256;
                                	colors[index].green=
						(index_green+add_green)*256;
                                	colors[index].blue = 
						(index_blue+add_blue)*256;
                                	colors[index].pixel = index;
                                	XStoreColor( display, 
						image_table.colormap, colors[index]);
                                	index++;
				}
                       	}
          	}
      	}
}
