#include <xpm.h>

#ifndef _XtIntrinsic_h
# include <xpmP.h>
#else
# define TRANSPARENT_COLOR "None" /* this must be a string! */
# define NKEYS 5
#endif

unsigned char *ReadXpm3Pixmap(view,fp, filename, w, h, colrs, bg)
Widget view;
FILE *fp;
char *filename;
int *w, *h;
XColor *colrs;
int *bg;
{
	XpmAttributes attributes;
	XpmInfo info;
	XpmImage image;
	int ErrorStatus;
	XColor tmpcolr;
	int i, size;
	char *colorName;
	unsigned char *pix_data;
	unsigned char *bptr;
	unsigned int *pixels;
        /*extern Widget view;*/

	attributes.valuemask = XpmReturnPixels | XpmColorTable;

	ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info);
	if (ErrorStatus != XpmSuccess)
	{
	        *w = 0;
	        *h = 0;
		return(NULL);
	}

	*w = (int)image.width;
	*h = (int)image.height;
	size = (*w) * (*h);

	for (i=0; i<image.ncolors; i++)
	{
		colorName = image.colorTable[i].c_color;
		/*
		fprintf(stderr,
			"colorstring=<%s> string=<%s> c_color=<%s>\n",
			image.colorTable[i].symbolic,
			image.colorTable[i].string,
			image.colorTable[i].c_color
			);
		*/
		if (strcmp(colorName, TRANSPARENT_COLOR) == 0)
		{
			unsigned long bg_pixel;

			/* First, go fetch the background pixel. */
			XtVaGetValues (view, XtNbackground, &bg_pixel, NULL);

			/* Now, load up tmpcolr. */
			tmpcolr.pixel = bg_pixel;

			/* Now query for the full color info. */
			XQueryColor (XtDisplay (view), 
				DefaultColormap (XtDisplay (view),
				DefaultScreen (XtDisplay (view))),
			       &tmpcolr);
			*bg = i;
		}
		else
		{
		  Display *dsp = XtDisplay(view);
			XParseColor(dsp,
				DefaultColormap(dsp, DefaultScreen(dsp)),
				colorName, &tmpcolr);
		}
		colrs[i].red = tmpcolr.red;
		colrs[i].green = tmpcolr.green;
		colrs[i].blue = tmpcolr.blue;
		colrs[i].pixel = i;
		colrs[i].flags = DoRed|DoGreen|DoBlue;
	}
	for (i=image.ncolors; i<256; i++)
	{
		colrs[i].red = 0;
		colrs[i].green = 0;
		colrs[i].blue = 0;
		colrs[i].pixel = i;
		colrs[i].flags = DoRed|DoGreen|DoBlue;
	}

	pixels = image.data;
	pix_data = (unsigned char *)malloc(size);
        if (pix_data == NULL)
        {
                fprintf(stderr, "Not enough memory for data.\n");
		XpmFreeXpmImage(&image);
		XpmFreeXpmInfo(&info);
                return((unsigned char *)NULL);
        }
	bptr = pix_data;
        for (i=0; i<size; i++)
        {
		int pix;
 
		pix = (int)*pixels;
                if (pix > (256 - 1))
                        pix = 0;
		*bptr++ = (unsigned char)pix;
                pixels++;
        }
	XpmFreeXpmImage(&image);
	XpmFreeXpmInfo(&info);

        return(pix_data);
}

#ifdef MOSAIC
#ifndef _XtIntrinsic_h
#include <xpmP.h>
#else
typedef struct {
    unsigned int type;
    union {
        FILE *file;
        char **data;
    }     stream;
    char *cptr;
    unsigned int line;
    int CommentLength;
    char Comment[BUFSIZ];
    char *Bcmt, *Ecmt, Bos, Eos;
    int format;                 /* 1 if XPM1, 0 otherwise */
}      xpmData;
#endif

unsigned char *ProcessXpm3Data(wid, xpmdata, w, h, colrs, bg)
Widget wid;
char **xpmdata;
int *w, *h;
XColor *colrs;
int *bg;
{
	xpmData mdata;
	XpmAttributes attributes;
	int ErrorStatus;
	XColor tmpcolr;
	int i, size;
	char *colorName;
	unsigned char *pix_data;
	unsigned char *bptr;
	unsigned int *pixels;
	XpmImage image;
	XpmInfo info;

	attributes.valuemask = XpmReturnPixels | XpmColorTable;

	xpmOpenArray(xpmdata, &mdata);
	xpmInitXpmImage(&image);
	xpmInitXpmInfo(&info);

	ErrorStatus = xpmParseData(&mdata, &image, &info);
	if (ErrorStatus != XpmSuccess)
	{
	        *w = 0;
	        *h = 0;
		XpmFreeXpmImage(&image);
		XpmFreeXpmInfo(&info);
		xpmDataClose(&mdata);
		return(NULL);
	}

	*w = (int)image.width;
	*h = (int)image.height;
	size = (*w) * (*h);

	for (i=0; i<image.ncolors; i++)
	{
		colorName = image.colorTable[i].c_color;
		if (strcmp(colorName, TRANSPARENT_COLOR) == 0)
		{
			unsigned long bg_pixel;

			/* First, go fetch the pixel. */
			XtVaGetValues (wid, XtNbackground, &bg_pixel, NULL);

			/* Now, load up tmpcolr. */
			tmpcolr.pixel = bg_pixel;

			/* Now query for the full color info. */
			XQueryColor (XtDisplay (wid), 
				DefaultColormap (XtDisplay (wid),
				DefaultScreen (XtDisplay (wid))),
			       &tmpcolr);
			*bg = i;
		}
		else
		{
			XParseColor(XtDisplay (wid),
				DefaultColormap(XtDisplay (wid),
				DefaultScreen(XtDisplay (wid))),
				colorName, &tmpcolr);
		}
		colrs[i].red = tmpcolr.red;
		colrs[i].green = tmpcolr.green;
		colrs[i].blue = tmpcolr.blue;
		colrs[i].pixel = i;
		colrs[i].flags = DoRed|DoGreen|DoBlue;
	}
	for (i=image.ncolors; i<256; i++)
	{
		colrs[i].red = 0;
		colrs[i].green = 0;
		colrs[i].blue = 0;
		colrs[i].pixel = i;
		colrs[i].flags = DoRed|DoGreen|DoBlue;
	}

	pixels = image.data;
	pix_data = (unsigned char *)malloc(size);
        if (pix_data == NULL)
        {
                fprintf(stderr, "Not enough memory for data.\n");
		XpmFreeXpmImage(&image);
		XpmFreeXpmInfo(&info);
		xpmDataClose(&mdata);
                return((unsigned char *)NULL);
        }
	bptr = pix_data;
        for (i=0; i<size; i++)
        {
		int pix;

		pix = (int)*pixels;
                if (pix > (256 - 1))
                        pix = 0;
		*bptr++ = (unsigned char)pix;
                pixels++;
        }

	XpmFreeXpmImage(&image);
	XpmFreeXpmInfo(&info);
	xpmDataClose(&mdata);

#ifdef TIMING
X_GETTIMEOFDAY(&Tv);
fprintf(stderr, "ReadXpm3Pixmap exit (%d.%d)\n", Tv.tv_sec, Tv.tv_usec);
#endif
        return(pix_data);
}

#endif

