From c9179017c7e70703b7cac46c2df8b950506319e0 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Fri, 6 Nov 2009 06:10:10 +0000
Subject: Added libXpm-3.5.8

---
 libXpm/src/Attrib.c    |  308 ++++++
 libXpm/src/CrBufFrI.c  |  451 +++++++++
 libXpm/src/CrBufFrP.c  |   77 ++
 libXpm/src/CrDatFrI.c  |  404 ++++++++
 libXpm/src/CrDatFrP.c  |   77 ++
 libXpm/src/CrIFrBuf.c  |  117 +++
 libXpm/src/CrIFrDat.c  |  122 +++
 libXpm/src/CrIFrP.c    |   58 ++
 libXpm/src/CrPFrBuf.c  |   78 ++
 libXpm/src/CrPFrDat.c  |   81 ++
 libXpm/src/CrPFrI.c    |   62 ++
 libXpm/src/Image.c     |   62 ++
 libXpm/src/Info.c      |  125 +++
 libXpm/src/Makefile.am |   46 +
 libXpm/src/Makefile.in |  654 +++++++++++++
 libXpm/src/RdFToBuf.c  |  124 +++
 libXpm/src/RdFToDat.c  |   68 ++
 libXpm/src/RdFToI.c    |  274 ++++++
 libXpm/src/RdFToP.c    |   77 ++
 libXpm/src/WrFFrBuf.c  |   60 ++
 libXpm/src/WrFFrDat.c  |   62 ++
 libXpm/src/WrFFrI.c    |  364 +++++++
 libXpm/src/WrFFrP.c    |   77 ++
 libXpm/src/XpmI.h      |  333 +++++++
 libXpm/src/amigax.c    |  385 ++++++++
 libXpm/src/amigax.h    |  151 +++
 libXpm/src/create.c    | 2519 ++++++++++++++++++++++++++++++++++++++++++++++++
 libXpm/src/data.c      |  480 +++++++++
 libXpm/src/hashtab.c   |  239 +++++
 libXpm/src/misc.c      |  124 +++
 libXpm/src/parse.c     |  807 ++++++++++++++++
 libXpm/src/rgb.c       |  287 ++++++
 libXpm/src/rgbtab.h    |  292 ++++++
 libXpm/src/scan.c      | 1025 ++++++++++++++++++++
 libXpm/src/simx.c      |  293 ++++++
 libXpm/src/simx.h      |  154 +++
 36 files changed, 10917 insertions(+)
 create mode 100644 libXpm/src/Attrib.c
 create mode 100644 libXpm/src/CrBufFrI.c
 create mode 100644 libXpm/src/CrBufFrP.c
 create mode 100644 libXpm/src/CrDatFrI.c
 create mode 100644 libXpm/src/CrDatFrP.c
 create mode 100644 libXpm/src/CrIFrBuf.c
 create mode 100644 libXpm/src/CrIFrDat.c
 create mode 100644 libXpm/src/CrIFrP.c
 create mode 100644 libXpm/src/CrPFrBuf.c
 create mode 100644 libXpm/src/CrPFrDat.c
 create mode 100644 libXpm/src/CrPFrI.c
 create mode 100644 libXpm/src/Image.c
 create mode 100644 libXpm/src/Info.c
 create mode 100644 libXpm/src/Makefile.am
 create mode 100644 libXpm/src/Makefile.in
 create mode 100644 libXpm/src/RdFToBuf.c
 create mode 100644 libXpm/src/RdFToDat.c
 create mode 100644 libXpm/src/RdFToI.c
 create mode 100644 libXpm/src/RdFToP.c
 create mode 100644 libXpm/src/WrFFrBuf.c
 create mode 100644 libXpm/src/WrFFrDat.c
 create mode 100644 libXpm/src/WrFFrI.c
 create mode 100644 libXpm/src/WrFFrP.c
 create mode 100644 libXpm/src/XpmI.h
 create mode 100644 libXpm/src/amigax.c
 create mode 100644 libXpm/src/amigax.h
 create mode 100644 libXpm/src/create.c
 create mode 100644 libXpm/src/data.c
 create mode 100644 libXpm/src/hashtab.c
 create mode 100644 libXpm/src/misc.c
 create mode 100644 libXpm/src/parse.c
 create mode 100644 libXpm/src/rgb.c
 create mode 100644 libXpm/src/rgbtab.h
 create mode 100644 libXpm/src/scan.c
 create mode 100644 libXpm/src/simx.c
 create mode 100644 libXpm/src/simx.h

(limited to 'libXpm/src')

diff --git a/libXpm/src/Attrib.c b/libXpm/src/Attrib.c
new file mode 100644
index 000000000..cb304df1f
--- /dev/null
+++ b/libXpm/src/Attrib.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* Attrib.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions related to the XpmAttributes structure                           *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/* 3.2 backward compatibility code */
+LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
+				 XpmColor ***oldct));
+
+LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors));
+
+/*
+ * Create a colortable compatible with the old style colortable
+ */
+static int
+CreateOldColorTable(
+    XpmColor	  *ct,
+    unsigned int   ncolors,
+    XpmColor	***oldct)
+{
+    XpmColor **colorTable, **color;
+    unsigned int a;
+
+    if (ncolors >= UINT_MAX / sizeof(XpmColor *)) 
+	return XpmNoMemory;
+
+    colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
+    if (!colorTable) {
+	*oldct = NULL;
+	return (XpmNoMemory);
+    }
+    for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
+	*color = ct;
+    *oldct = colorTable;
+    return (XpmSuccess);
+}
+
+static void
+FreeOldColorTable(
+    XpmColor	**colorTable,
+    unsigned int  ncolors)
+{
+    unsigned int a, b;
+    XpmColor **color;
+    char **sptr;
+
+    if (colorTable) {
+	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+	    for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
+		if (*sptr)
+		    XpmFree(*sptr);
+	}
+	XpmFree(*colorTable);
+	XpmFree(colorTable);
+    }
+}
+
+/* end 3.2 bc */
+
+/*
+ * Free the computed color table
+ */
+void
+xpmFreeColorTable(
+    XpmColor	*colorTable,
+    int		 ncolors)
+{
+    int a, b;
+    XpmColor *color;
+    char **sptr;
+
+    if (colorTable) {
+	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+	    for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
+		if (*sptr)
+		    XpmFree(*sptr);
+	}
+	XpmFree(colorTable);
+    }
+}
+
+/*
+ * Free array of extensions
+ */
+void
+XpmFreeExtensions(
+    XpmExtension	*extensions,
+    int			 nextensions)
+{
+    unsigned int i, j, nlines;
+    XpmExtension *ext;
+    char **sptr;
+
+    if (extensions  && nextensions > 0) {
+	for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
+	    if (ext->name)
+		XpmFree(ext->name);
+	    nlines = ext->nlines;
+	    for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
+		if (sptr && *sptr)
+		    XpmFree(*sptr);
+	    if (ext->lines)
+		XpmFree(ext->lines);
+	}
+	XpmFree(extensions);
+    }
+}
+
+/*
+ * Return the XpmAttributes structure size
+ */
+
+int
+XpmAttributesSize(void)
+{
+    return sizeof(XpmAttributes);
+}
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitAttributes(XpmAttributes *attributes)
+{
+    if (attributes) {
+	attributes->pixels = NULL;
+	attributes->npixels = 0;
+	attributes->colorTable = NULL;
+	attributes->ncolors = 0;
+/* 3.2 backward compatibility code */
+	attributes->hints_cmt = NULL;
+	attributes->colors_cmt = NULL;
+	attributes->pixels_cmt = NULL;
+/* end 3.2 bc */
+	if (attributes->valuemask & XpmReturnExtensions) {
+	    attributes->extensions = NULL;
+	    attributes->nextensions = 0;
+	}
+	if (attributes->valuemask & XpmReturnAllocPixels) {
+	    attributes->alloc_pixels = NULL;
+	    attributes->nalloc_pixels = 0;
+	}
+    }
+}
+
+/*
+ * Fill in the XpmAttributes with the XpmImage and the XpmInfo
+ */
+void
+xpmSetAttributes(
+    XpmAttributes	*attributes,
+    XpmImage		*image,
+    XpmInfo		*info)
+{
+    if (attributes->valuemask & XpmReturnColorTable) {
+	attributes->colorTable = image->colorTable;
+	attributes->ncolors = image->ncolors;
+
+	/* avoid deletion of copied data */
+	image->ncolors = 0;
+	image->colorTable = NULL;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes->valuemask & XpmReturnInfos) {
+	int ErrorStatus;
+
+	ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
+					  (XpmColor ***)
+					  &attributes->colorTable);
+
+	/* if error just say we can't return requested data */
+	if (ErrorStatus != XpmSuccess) {
+	    attributes->valuemask &= ~XpmReturnInfos;
+	    if (!(attributes->valuemask & XpmReturnPixels)) {
+		XpmFree(attributes->pixels);
+		attributes->pixels = NULL;
+		attributes->npixels = 0;
+	    }
+	    attributes->ncolors = 0;
+	} else {
+	    attributes->ncolors = image->ncolors;
+	    attributes->hints_cmt = info->hints_cmt;
+	    attributes->colors_cmt = info->colors_cmt;
+	    attributes->pixels_cmt = info->pixels_cmt;
+
+	    /* avoid deletion of copied data */
+	    image->ncolors = 0;
+	    image->colorTable = NULL;
+	    info->hints_cmt = NULL;
+	    info->colors_cmt = NULL;
+	    info->pixels_cmt = NULL;
+	}
+    }
+/* end 3.2 bc */
+    if (attributes->valuemask & XpmReturnExtensions) {
+	attributes->extensions = info->extensions;
+	attributes->nextensions = info->nextensions;
+
+	/* avoid deletion of copied data */
+	info->extensions = NULL;
+	info->nextensions = 0;
+    }
+    if (info->valuemask & XpmHotspot) {
+	attributes->valuemask |= XpmHotspot;
+	attributes->x_hotspot = info->x_hotspot;
+	attributes->y_hotspot = info->y_hotspot;
+    }
+    attributes->valuemask |= XpmCharsPerPixel;
+    attributes->cpp = image->cpp;
+    attributes->valuemask |= XpmSize;
+    attributes->width = image->width;
+    attributes->height = image->height;
+}
+
+/*
+ * Free the XpmAttributes structure members
+ * but the structure itself
+ */
+void
+XpmFreeAttributes(XpmAttributes *attributes)
+{
+    if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
+	XpmFree(attributes->pixels);
+	attributes->pixels = NULL;
+	attributes->npixels = 0;
+    }
+    if (attributes->valuemask & XpmReturnColorTable) {
+	xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
+	attributes->colorTable = NULL;
+	attributes->ncolors = 0;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes->valuemask & XpmInfos) {
+	if (attributes->colorTable) {
+	    FreeOldColorTable((XpmColor **) attributes->colorTable,
+			      attributes->ncolors);
+	    attributes->colorTable = NULL;
+	    attributes->ncolors = 0;
+	}
+	if (attributes->hints_cmt) {
+	    XpmFree(attributes->hints_cmt);
+	    attributes->hints_cmt = NULL;
+	}
+	if (attributes->colors_cmt) {
+	    XpmFree(attributes->colors_cmt);
+	    attributes->colors_cmt = NULL;
+	}
+	if (attributes->pixels_cmt) {
+	    XpmFree(attributes->pixels_cmt);
+	    attributes->pixels_cmt = NULL;
+	}
+	if (attributes->pixels) {
+	    XpmFree(attributes->pixels);
+	    attributes->pixels = NULL;
+	    attributes->npixels = 0;
+	}
+    }
+/* end 3.2 bc */
+    if (attributes->valuemask & XpmReturnExtensions
+	&& attributes->nextensions) {
+	XpmFreeExtensions(attributes->extensions, attributes->nextensions);
+	attributes->extensions = NULL;
+	attributes->nextensions = 0;
+    }
+    if (attributes->valuemask & XpmReturnAllocPixels
+	&& attributes->nalloc_pixels) {
+	XpmFree(attributes->alloc_pixels);
+	attributes->alloc_pixels = NULL;
+	attributes->nalloc_pixels = 0;
+    }
+    attributes->valuemask = 0;
+}
diff --git a/libXpm/src/CrBufFrI.c b/libXpm/src/CrBufFrI.c
new file mode 100644
index 000000000..a53b1177b
--- /dev/null
+++ b/libXpm/src/CrBufFrI.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrBufFrI.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan an image and possibly its mask and create an XPM buffer               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+/* $XFree86$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
+			 unsigned int *used_size, XpmColor *colors,
+			 unsigned int ncolors, unsigned int cpp));
+
+LFUNC(WritePixels, void, (char *dataptr, unsigned int data_size,
+			  unsigned int *used_size,
+			  unsigned int width, unsigned int height,
+			  unsigned int cpp, unsigned int *pixels,
+			  XpmColor *colors));
+
+LFUNC(WriteExtensions, void, (char *dataptr, unsigned int data_size,
+			      unsigned int *used_size,
+			      XpmExtension *ext, unsigned int num));
+
+LFUNC(ExtensionsSize, unsigned int, (XpmExtension *ext, unsigned int num));
+LFUNC(CommentsSize, int, (XpmInfo *info));
+
+int
+XpmCreateBufferFromImage(
+    Display		 *display,
+    char		**buffer_return,
+    XImage		 *image,
+    XImage		 *shapeimage,
+    XpmAttributes	 *attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* initialize return value */
+    if (buffer_return)
+	*buffer_return = NULL;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+					     &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /* create the buffer from the XpmImage */
+    if (attributes) {
+	xpmSetInfo(&info, attributes);
+	ErrorStatus =
+	    XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
+    } else
+	ErrorStatus =
+	    XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto error; \
+}while(0)
+
+int
+XpmCreateBufferFromXpmImage(
+    char	**buffer_return,
+    XpmImage	 *image,
+    XpmInfo	 *info)
+{
+    /* calculation variables */
+    int ErrorStatus;
+    char buf[BUFSIZ];
+    unsigned int cmts, extensions, ext_size = 0;
+    unsigned int l, cmt_size = 0;
+    char *ptr = NULL, *p;
+    unsigned int ptr_size, used_size, tmp;
+
+    *buffer_return = NULL;
+
+    cmts = info && (info->valuemask & XpmComments);
+    extensions = info && (info->valuemask & XpmExtensions)
+	&& info->nextensions;
+
+    /* compute the extensions and comments size */
+    if (extensions)
+	ext_size = ExtensionsSize(info->extensions, info->nextensions);
+    if (cmts)
+	cmt_size = CommentsSize(info);
+
+    /* write the header line */
+#ifndef VOID_SPRINTF
+    used_size =
+#endif
+    sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
+#ifdef VOID_SPRINTF
+    used_size = strlen(buf);
+#endif
+    ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */
+    if(ptr_size <= used_size ||
+       ptr_size <= ext_size  ||
+       ptr_size <= cmt_size)
+    {
+        return XpmNoMemory;
+    }
+    ptr = (char *) XpmMalloc(ptr_size);
+    if (!ptr)
+	return XpmNoMemory;
+    strcpy(ptr, buf);
+
+    /* write the values line */
+    if (cmts && info->hints_cmt) {
+#ifndef VOID_SPRINTF
+	used_size +=
+#endif
+	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt);
+#ifdef VOID_SPRINTF
+	used_size += strlen(info->hints_cmt) + 5;
+#endif
+    }
+#ifndef VOID_SPRINTF
+    l =
+#endif
+    sprintf(buf, "\"%d %d %d %d", image->width, image->height,
+	    image->ncolors, image->cpp);
+#ifdef VOID_SPRINTF
+    l = strlen(buf);
+#endif
+
+    if (info && (info->valuemask & XpmHotspot)) {
+#ifndef VOID_SPRINTF
+	l +=
+#endif
+	snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot);
+#ifdef VOID_SPRINTF
+	l = strlen(buf);
+#endif
+    }
+    if (extensions) {
+#ifndef VOID_SPRINTF
+	l +=
+#endif
+	sprintf(buf + l, " XPMEXT");
+#ifdef VOID_SPRINTF
+	l = strlen(buf);
+#endif
+    }
+#ifndef VOID_SPRINTF
+    l +=
+#endif
+    sprintf(buf + l, "\",\n");
+#ifdef VOID_SPRINTF
+    l = strlen(buf);
+#endif
+    ptr_size += l;
+    if(ptr_size <= l)
+        RETURN(XpmNoMemory);
+    p = (char *) XpmRealloc(ptr, ptr_size);
+    if (!p)
+	RETURN(XpmNoMemory);
+    ptr = p;
+    strcpy(ptr + used_size, buf);
+    used_size += l;
+
+    /* write colors */
+    if (cmts && info->colors_cmt) {
+#ifndef VOID_SPRINTF
+	used_size +=
+#endif
+	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt);
+#ifdef VOID_SPRINTF
+	used_size += strlen(info->colors_cmt) + 5;
+#endif
+    }
+    ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
+			      image->colorTable, image->ncolors, image->cpp);
+ 
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+
+    /*
+     * now we know the exact size we need, realloc the data
+     * 4 = 1 (for '"') + 3 (for '",\n')
+     * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
+     */
+     if(image->width  > UINT_MAX / image->cpp ||
+       (tmp = image->width * image->cpp + 4) <= 4 ||
+        image->height > UINT_MAX / tmp ||
+       (tmp = image->height * tmp + 1) <= 1 ||
+       (ptr_size += tmp) <= tmp)
+	RETURN(XpmNoMemory);
+
+    p = (char *) XpmRealloc(ptr, ptr_size);
+    if (!p)
+	RETURN(XpmNoMemory);
+    ptr = p;
+
+    /* print pixels */
+    if (cmts && info->pixels_cmt) {
+#ifndef VOID_SPRINTF
+	used_size +=
+#endif
+	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt);
+#ifdef VOID_SPRINTF
+	used_size += strlen(info->pixels_cmt) + 5;
+#endif
+    }
+    WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height,
+		image->cpp, image->data, image->colorTable);
+
+    /* print extensions */
+    if (extensions)
+	WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size,
+			info->extensions, info->nextensions);
+
+    /* close the array */
+    strcpy(ptr + used_size, "};\n");
+
+    *buffer_return = ptr;
+
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (ptr)
+	XpmFree(ptr);
+    return (ErrorStatus);
+}
+
+
+static int
+WriteColors(
+    char		**dataptr,
+    unsigned int	 *data_size,
+    unsigned int	 *used_size,
+    XpmColor		 *colors,
+    unsigned int	  ncolors,
+    unsigned int	  cpp)
+{
+    char buf[BUFSIZ] = {0};
+    unsigned int a, key, l;
+    char *s, *s2;
+    char **defaults;
+
+    *buf = '"';
+    for (a = 0; a < ncolors; a++, colors++) {
+
+	defaults = (char **) colors;
+	s = buf + 1;
+	if(cpp > (sizeof(buf) - (s-buf)))
+		return(XpmNoMemory);
+	strncpy(s, *defaults++, cpp);
+	s += cpp;
+
+	for (key = 1; key <= NKEYS; key++, defaults++) {
+	    if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+		s +=
+#endif
+		/* assume C99 compliance */
+		snprintf(s, sizeof(buf) - (s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+		s += strlen(s);
+#endif
+		/* now let's check if s points out-of-bounds */
+		if((s-buf) > sizeof(buf))
+			return(XpmNoMemory);
+	    }
+	}
+	if(sizeof(buf) - (s-buf) < 4)
+		return(XpmNoMemory);
+	strcpy(s, "\",\n");
+	l = s + 3 - buf;
+	if( *data_size                   >= UINT_MAX-l ||
+	    *data_size + l               <= *used_size ||
+	   (*data_size + l - *used_size) <= sizeof(buf))
+		return(XpmNoMemory);
+	s = (char *) XpmRealloc(*dataptr, *data_size + l);
+	if (!s)
+	    return (XpmNoMemory);
+	*data_size += l;
+	strcpy(s + *used_size, buf);
+	*used_size += l;
+	*dataptr = s;
+    }
+    return (XpmSuccess);
+}
+
+static void
+WritePixels(
+    char		*dataptr,
+    unsigned int	 data_size,
+    unsigned int	*used_size,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	 cpp,
+    unsigned int	*pixels,
+    XpmColor		*colors)
+{
+    char *s = dataptr;
+    unsigned int x, y, h;
+
+    if(height <= 1)
+    	return;
+
+    h = height - 1;
+    for (y = 0; y < h; y++) {
+	*s++ = '"';
+	for (x = 0; x < width; x++, pixels++) {
+	    if(cpp >= (data_size - (s-dataptr)))
+		return;
+	    strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? :-\ */
+	    s += cpp;
+	}
+	if((data_size - (s-dataptr)) < 4)
+		return;
+	strcpy(s, "\",\n");
+	s += 3;
+    }
+    /* duplicate some code to avoid a test in the loop */
+    *s++ = '"';
+    for (x = 0; x < width; x++, pixels++) {
+	if(cpp >= (data_size - (s-dataptr)))
+	    return;
+	strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? */
+	s += cpp;
+    }
+    *s++ = '"';
+    *used_size += s - dataptr;
+}
+
+static unsigned int
+ExtensionsSize(
+    XpmExtension	*ext,
+    unsigned int	 num)
+{
+    unsigned int x, y, a, size;
+    char **line;
+
+    size = 0;
+    if(num == 0)
+    	return(0); /* ok? */
+    for (x = 0; x < num; x++, ext++) {
+	/* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
+	size += strlen(ext->name) + 11;
+	a = ext->nlines; /* how can we trust ext->nlines to be not out-of-bounds? */
+	for (y = 0, line = ext->lines; y < a; y++, line++)
+	    /* 4 = 3 (for ',\n"') + 1 (for '"') */
+	    size += strlen(*line) + 4;
+    }
+    /* 13 is for ',\n"XPMENDEXT"' */
+    if(size > UINT_MAX - 13) /* unlikely */
+    	return(0);
+    return size + 13;
+}
+
+static void
+WriteExtensions(
+    char		*dataptr,
+    unsigned int	 data_size,
+    unsigned int	*used_size,
+    XpmExtension	*ext,
+    unsigned int	 num)
+{
+    unsigned int x, y, a;
+    char **line;
+    char *s = dataptr;
+
+    for (x = 0; x < num; x++, ext++) {
+#ifndef VOID_SPRINTF
+	s +=
+#endif
+	snprintf(s, data_size - (s-dataptr), ",\n\"XPMEXT %s\"", ext->name);
+#ifdef VOID_SPRINTF
+	s += strlen(ext->name) + 11;
+#endif
+	a = ext->nlines;
+	for (y = 0, line = ext->lines; y < a; y++, line++) {
+#ifndef VOID_SPRINTF
+	    s +=
+#endif
+	    snprintf(s, data_size - (s-dataptr), ",\n\"%s\"", *line);
+#ifdef VOID_SPRINTF
+	    s += strlen(*line) + 4;
+#endif
+	}
+    }
+    strncpy(s, ",\n\"XPMENDEXT\"", data_size - (s-dataptr)-1);
+    *used_size += s - dataptr + 13;
+}
+
+static int
+CommentsSize(XpmInfo *info)
+{
+    int size = 0;
+
+    /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
+    /* wrap possible but *very* unlikely */
+    if (info->hints_cmt)
+	size += 5 + strlen(info->hints_cmt);
+
+    if (info->colors_cmt)
+	size += 5 + strlen(info->colors_cmt);
+
+    if (info->pixels_cmt)
+	size += 5 + strlen(info->pixels_cmt);
+
+    return size;
+}
diff --git a/libXpm/src/CrBufFrP.c b/libXpm/src/CrBufFrP.c
new file mode 100644
index 000000000..de3e7764c
--- /dev/null
+++ b/libXpm/src/CrBufFrP.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrBufFrP.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan a pixmap and possibly its mask and create an XPM buffer               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreateBufferFromPixmap(
+    Display		 *display,
+    char		**buffer_return,
+    Pixmap		  pixmap,
+    Pixmap		  shapemask,
+    XpmAttributes	 *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+	width = attributes->width;
+	height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+	xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+	xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+				 &width, &height);
+
+    /* create the buffer */
+    ErrorStatus = XpmCreateBufferFromImage(display, buffer_return, ximage,
+					   shapeimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/CrDatFrI.c b/libXpm/src/CrDatFrI.c
new file mode 100644
index 000000000..aa1d893b7
--- /dev/null
+++ b/libXpm/src/CrDatFrI.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrDataFI.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan an image and possibly its mask and create an XPM array                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86$ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
+			  XpmColor *colors, unsigned int ncolors,
+			  unsigned int cpp));
+
+LFUNC(CreatePixels, void, (char **dataptr, unsigned int data_size,
+			   unsigned int width,
+			   unsigned int height, unsigned int cpp,
+			   unsigned int *pixels, XpmColor *colors));
+
+LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
+			      unsigned int *ext_size,
+			      unsigned int *ext_nlines));
+
+LFUNC(CreateExtensions, void, (char **dataptr, unsigned int data_size,
+			       unsigned int offset,
+			       XpmExtension *ext, unsigned int num,
+			       unsigned int ext_nlines));
+
+int
+XpmCreateDataFromImage(
+    Display		  *display,
+    char		***data_return,
+    XImage		  *image,
+    XImage		  *shapeimage,
+    XpmAttributes	  *attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* initialize return value */
+    if (data_return)
+	*data_return = NULL;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+					     &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /* create the data from the XpmImage */
+    if (attributes) {
+	xpmSetInfo(&info, attributes);
+	ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
+    } else
+	ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto exit; \
+} while(0)
+
+int
+XpmCreateDataFromXpmImage(
+    char	***data_return,
+    XpmImage	  *image,
+    XpmInfo	  *info)
+{
+    /* calculation variables */
+    int ErrorStatus;
+    char buf[BUFSIZ];
+    char **header = NULL, **data, **sptr, **sptr2, *s;
+    unsigned int header_size, header_nlines;
+    unsigned int data_size, data_nlines;
+    unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
+    unsigned int offset, l, n;
+
+    *data_return = NULL;
+
+    extensions = info && (info->valuemask & XpmExtensions)
+	&& info->nextensions;
+
+    /* compute the number of extensions lines and size */
+    if (extensions)
+	CountExtensions(info->extensions, info->nextensions,
+			&ext_size, &ext_nlines);
+
+    /*
+     * alloc a temporary array of char pointer for the header section which
+     * is the hints line + the color table lines
+     */
+    header_nlines = 1 + image->ncolors; /* this may wrap and/or become 0 */
+
+    /* 2nd check superfluous if we do not need header_nlines any further */
+    if(header_nlines <= image->ncolors ||
+       header_nlines >= UINT_MAX / sizeof(char *))
+    	return(XpmNoMemory);
+
+    header_size = sizeof(char *) * header_nlines;
+    if (header_size >= UINT_MAX / sizeof(char *))
+	return (XpmNoMemory);
+    header = (char **) XpmCalloc(header_size, sizeof(char *)); /* can we trust image->ncolors */
+    if (!header)
+	return (XpmNoMemory);
+
+    /* print the hints line */
+    s = buf;
+#ifndef VOID_SPRINTF
+    s +=
+#endif
+    sprintf(s, "%d %d %d %d", image->width, image->height,
+	    image->ncolors, image->cpp);
+#ifdef VOID_SPRINTF
+    s += strlen(s);
+#endif
+
+    if (info && (info->valuemask & XpmHotspot)) {
+#ifndef VOID_SPRINTF
+	s +=
+#endif
+	sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
+#ifdef VOID_SPRINTF
+	s += strlen(s);
+#endif
+    }
+    if (extensions) {
+	strcpy(s, " XPMEXT");
+	s += 7;
+    }
+    l = s - buf + 1;
+    *header = (char *) XpmMalloc(l);
+    if (!*header)
+	RETURN(XpmNoMemory);
+    header_size += l;
+    strcpy(*header, buf);
+
+    /* print colors */
+    ErrorStatus = CreateColors(header + 1, &header_size,
+			       image->colorTable, image->ncolors, image->cpp);
+
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+
+    /* now we know the size needed, alloc the data and copy the header lines */
+    offset = image->width * image->cpp + 1;
+
+    if(offset <= image->width || offset <= image->cpp)
+	RETURN(XpmNoMemory);
+
+    if( (image->height + ext_nlines) >= UINT_MAX / sizeof(char *))
+	RETURN(XpmNoMemory);
+    data_size = (image->height + ext_nlines) * sizeof(char *);
+
+    if (image->height > UINT_MAX / offset ||
+        image->height * offset > UINT_MAX - data_size)
+	RETURN(XpmNoMemory);
+    data_size += image->height * offset;
+
+    if( (header_size + ext_size) >= (UINT_MAX - data_size) )
+	RETURN(XpmNoMemory);
+    data_size += header_size + ext_size;
+
+    data = (char **) XpmMalloc(data_size);
+    if (!data)
+	RETURN(XpmNoMemory);
+
+    data_nlines = header_nlines + image->height + ext_nlines;
+    *data = (char *) (data + data_nlines);
+
+    /* can header have less elements then n suggests? */
+    n = image->ncolors;
+    for (l = 0, sptr = data, sptr2 = header; l <= n && sptr && sptr2; l++, sptr++, sptr2++) {
+	strcpy(*sptr, *sptr2);
+	*(sptr + 1) = *sptr + strlen(*sptr2) + 1;
+    }
+
+    /* print pixels */
+    data[header_nlines] = (char *) data + header_size
+	+ (image->height + ext_nlines) * sizeof(char *);
+
+    CreatePixels(data + header_nlines, data_size-header_nlines, image->width, image->height,
+		 image->cpp, image->data, image->colorTable);
+
+    /* print extensions */
+    if (extensions)
+	CreateExtensions(data + header_nlines + image->height - 1,
+			 data_size - header_nlines - image->height + 1, offset,
+			 info->extensions, info->nextensions,
+			 ext_nlines);
+
+    *data_return = data;
+    ErrorStatus = XpmSuccess;
+
+/* exit point, free only locally allocated variables */
+exit:
+    if (header) {
+	for (l = 0; l < header_nlines; l++)
+	    if (header[l])
+		XpmFree(header[l]);
+		XpmFree(header);
+    }
+    return(ErrorStatus);
+}
+
+static int
+CreateColors(
+    char		**dataptr,
+    unsigned int	 *data_size,
+    XpmColor		 *colors,
+    unsigned int	  ncolors,
+    unsigned int	  cpp)
+{
+    char buf[BUFSIZ];
+    unsigned int a, key, l;
+    char *s, *s2;
+    char **defaults;
+
+    /* can ncolors be trusted here? */
+    for (a = 0; a < ncolors; a++, colors++, dataptr++) {
+
+	defaults = (char **) colors;
+	if(sizeof(buf) <= cpp)
+	    return(XpmNoMemory);
+	strncpy(buf, *defaults++, cpp);
+	s = buf + cpp;
+
+	if(sizeof(buf) <= (s-buf))
+		return XpmNoMemory;
+
+	for (key = 1; key <= NKEYS; key++, defaults++) {
+	    if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+		s +=
+#endif
+		/* assume C99 compliance */
+			snprintf(s, sizeof(buf)-(s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+		s += strlen(s);
+#endif
+		/* does s point out-of-bounds? */
+		if(sizeof(buf) < (s-buf))
+			return XpmNoMemory;
+	    }
+	}
+	/* what about using strdup()? */
+	l = s - buf + 1;
+	s = (char *) XpmMalloc(l);
+	if (!s)
+	    return (XpmNoMemory);
+	*data_size += l;
+	*dataptr = strcpy(s, buf);
+    }
+    return (XpmSuccess);
+}
+
+static void
+CreatePixels(
+    char		**dataptr,
+    unsigned int	  data_size,
+    unsigned int	  width,
+    unsigned int	  height,
+    unsigned int	  cpp,
+    unsigned int	 *pixels,
+    XpmColor		 *colors)
+{
+    char *s;
+    unsigned int x, y, h, offset;
+
+    if(height <= 1)
+    	return;
+
+    h = height - 1;
+
+    offset = width * cpp + 1;
+
+    if(offset <= width || offset <= cpp)
+    	return;
+
+    /* why trust h? */
+    for (y = 0; y < h; y++, dataptr++) {
+	s = *dataptr;
+	/* why trust width? */
+	for (x = 0; x < width; x++, pixels++) {
+	    if(cpp > (data_size - (s - *dataptr)))
+	    	return;
+	    strncpy(s, colors[*pixels].string, cpp); /* why trust pixel? */
+	    s += cpp;
+	}
+	*s = '\0';
+	if(offset > data_size)
+		return;
+	*(dataptr + 1) = *dataptr + offset;
+    }
+    /* duplicate some code to avoid a test in the loop */
+    s = *dataptr;
+    /* why trust width? */
+    for (x = 0; x < width; x++, pixels++) {
+	if(cpp > data_size - (s - *dataptr))
+	    	return;
+	strncpy(s, colors[*pixels].string, cpp); /* why should we trust *pixel? */
+	s += cpp;
+    }
+    *s = '\0';
+}
+
+static void
+CountExtensions(
+    XpmExtension	*ext,
+    unsigned int	 num,
+    unsigned int	*ext_size,
+    unsigned int	*ext_nlines)
+{
+    unsigned int x, y, a, size, nlines;
+    char **line;
+
+    size = 0;
+    nlines = 0;
+    for (x = 0; x < num; x++, ext++) {
+	/* 1 for the name */
+	nlines += ext->nlines + 1;
+	/* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
+	size += strlen(ext->name) + 8;
+	a = ext->nlines;
+	for (y = 0, line = ext->lines; y < a; y++, line++)
+	    size += strlen(*line) + 1;
+    }
+    /* 10 and 1 are for the ending "XPMENDEXT" */
+    *ext_size = size + 10;
+    *ext_nlines = nlines + 1;
+}
+
+static void
+CreateExtensions(
+    char		**dataptr,
+    unsigned int	  data_size,
+    unsigned int	  offset,
+    XpmExtension	 *ext,
+    unsigned int	  num,
+    unsigned int	  ext_nlines)
+{
+    unsigned int x, y, a, b;
+    char **line;
+
+    *(dataptr + 1) = *dataptr + offset;
+    dataptr++;
+    a = 0;
+    for (x = 0; x < num; x++, ext++) {
+	snprintf(*dataptr, data_size, "XPMEXT %s", ext->name);
+	a++;
+	if (a < ext_nlines)
+	    *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
+	dataptr++;
+	b = ext->nlines; /* can we trust these values? */
+	for (y = 0, line = ext->lines; y < b; y++, line++) {
+	    strcpy(*dataptr, *line);
+	    a++;
+	    if (a < ext_nlines)
+		*(dataptr + 1) = *dataptr + strlen(*line) + 1;
+	    dataptr++;
+	}
+    }
+    strcpy(*dataptr, "XPMENDEXT");
+}
diff --git a/libXpm/src/CrDatFrP.c b/libXpm/src/CrDatFrP.c
new file mode 100644
index 000000000..0e17fee14
--- /dev/null
+++ b/libXpm/src/CrDatFrP.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrDataFP.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan a pixmap and possibly its mask and create an XPM array                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreateDataFromPixmap(
+    Display		  *display,
+    char		***data_return,
+    Pixmap		   pixmap,
+    Pixmap		   shapemask,
+    XpmAttributes	  *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+	width = attributes->width;
+	height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+	xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+	xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+				 &width, &height);
+
+    /* create the data */
+    ErrorStatus = XpmCreateDataFromImage(display, data_return, ximage,
+					 shapeimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/CrIFrBuf.c b/libXpm/src/CrIFrBuf.c
new file mode 100644
index 000000000..b6b12cad1
--- /dev/null
+++ b/libXpm/src/CrIFrBuf.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrBuf.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm buffer (file in memory) and create the image and possibly its *
+*  mask                                                                       *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(OpenBuffer, void, (char *buffer, xpmData *mdata));
+
+int
+XpmCreateImageFromBuffer(
+    Display		 *display,
+    char		 *buffer,
+    XImage		**image_return,
+    XImage		**shapeimage_return,
+    XpmAttributes	 *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open buffer to read */
+    OpenBuffer(buffer, &mdata);
+
+    /* create the XImage from the XpmData */
+    if (attributes) {
+	xpmInitAttributes(attributes);
+	xpmSetInfoMask(&info, attributes);
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, &info, attributes);
+    } else
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, NULL, attributes);
+    if (attributes) {
+	if (ErrorStatus >= 0)		/* no fatal error */
+	    xpmSetAttributes(attributes, &image, &info);
+	XpmFreeXpmInfo(&info);
+    }
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmCreateXpmImageFromBuffer(
+    char	*buffer,
+    XpmImage	*image,
+    XpmInfo	*info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open buffer to read */
+    OpenBuffer(buffer, &mdata);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    return (ErrorStatus);
+}
+
+/*
+ * open the given buffer to be read or written as an xpmData which is returned
+ */
+static void
+OpenBuffer(
+    char	*buffer,
+    xpmData	*mdata)
+{
+    mdata->type = XPMBUFFER;
+    mdata->cptr = buffer;
+    mdata->CommentLength = 0;
+}
diff --git a/libXpm/src/CrIFrDat.c b/libXpm/src/CrIFrDat.c
new file mode 100644
index 000000000..9ef155721
--- /dev/null
+++ b/libXpm/src/CrIFrDat.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and create the image and possibly its mask              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(OpenArray, void, (char **data, xpmData *mdata));
+
+int
+XpmCreateImageFromData(
+    Display		 *display,
+    char		**data,
+    XImage		**image_return,
+    XImage		**shapeimage_return,
+    XpmAttributes	 *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open data */
+    OpenArray(data, &mdata);
+
+    /* create an XpmImage from the file */
+    if (attributes) {
+	xpmInitAttributes(attributes);
+	xpmSetInfoMask(&info, attributes);
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, &info, attributes);
+    } else
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, NULL, attributes);
+    if (attributes) {
+	if (ErrorStatus >= 0)		/* no fatal error */
+	    xpmSetAttributes(attributes, &image, &info);
+	XpmFreeXpmInfo(&info);
+    }
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmCreateXpmImageFromData(
+    char	**data,
+    XpmImage	 *image,
+    XpmInfo	 *info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open data */
+    OpenArray(data, &mdata);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    return (ErrorStatus);
+}
+
+/*
+ * open the given array to be read or written as an xpmData which is returned
+ */
+static void
+OpenArray(
+    char	**data,
+    xpmData	 *mdata)
+{
+    mdata->type = XPMARRAY;
+    mdata->stream.data = data;
+    mdata->cptr = *data;
+    mdata->line = 0;
+    mdata->CommentLength = 0;
+    mdata->Bcmt = mdata->Ecmt = NULL;
+    mdata->Bos = mdata->Eos = '\0';
+    mdata->format = 0;			/* this can only be Xpm 2 or 3 */
+}
diff --git a/libXpm/src/CrIFrP.c b/libXpm/src/CrIFrP.c
new file mode 100644
index 000000000..79c4c49c5
--- /dev/null
+++ b/libXpm/src/CrIFrP.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Create the XImage related to the given Pixmap.                             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+void
+xpmCreateImageFromPixmap(
+    Display		 *display,
+    Pixmap		  pixmap,
+    XImage		**ximage_return,
+    unsigned int	 *width,
+    unsigned int	 *height)
+{
+    unsigned int dum;
+    int dummy;
+    Window win;
+
+    if (*width == 0 && *height == 0)
+	XGetGeometry(display, pixmap, &win, &dummy, &dummy,
+		     width, height, &dum, &dum);
+
+    *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height,
+			       AllPlanes, ZPixmap);
+}
diff --git a/libXpm/src/CrPFrBuf.c b/libXpm/src/CrPFrBuf.c
new file mode 100644
index 000000000..2c28a4137
--- /dev/null
+++ b/libXpm/src/CrPFrBuf.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrBuf.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm buffer and create the pixmap and possibly its mask            *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromBuffer(
+    Display		*display,
+    Drawable		 d,
+    char		*buffer,
+    Pixmap		*pixmap_return,
+    Pixmap		*shapemask_return,
+    XpmAttributes	*attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+	*pixmap_return = 0;
+    if (shapemask_return)
+	*shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmCreateImageFromBuffer(display, buffer,
+					   (pixmap_return ? &ximage : NULL),
+					   (shapemask_return ?
+					    &shapeimage : NULL),
+					   attributes);
+
+    if (ErrorStatus < 0)		/* fatal error */
+	return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+	xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+	XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+	xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+	XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/CrPFrDat.c b/libXpm/src/CrPFrDat.c
new file mode 100644
index 000000000..b65771d19
--- /dev/null
+++ b/libXpm/src/CrPFrDat.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and create the pixmap and possibly its mask             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromData(
+    Display		 *display,
+    Drawable		  d,
+    char		**data,
+    Pixmap		 *pixmap_return,
+    Pixmap		 *shapemask_return,
+    XpmAttributes	 *attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+	*pixmap_return = 0;
+    if (shapemask_return)
+	*shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmCreateImageFromData(display, data,
+					 (pixmap_return ? &ximage : NULL),
+					 (shapemask_return ?
+					  &shapeimage : NULL),
+					 attributes);
+
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    if (ErrorStatus < 0)		/* fatal error */
+	return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+	xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+	XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+	xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+	XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/CrPFrI.c b/libXpm/src/CrPFrI.c
new file mode 100644
index 000000000..8f6f4aa46
--- /dev/null
+++ b/libXpm/src/CrPFrI.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Create the Pixmap related to the given XImage.                             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+void
+xpmCreatePixmapFromImage(
+    Display	*display,
+    Drawable	 d,
+    XImage	*ximage,
+    Pixmap	*pixmap_return)
+{
+    GC gc;
+    XGCValues values;
+
+    *pixmap_return = XCreatePixmap(display, d, ximage->width,
+				   ximage->height, ximage->depth);
+    /* set fg and bg in case we have an XYBitmap */
+    values.foreground = 1;
+    values.background = 0;
+    gc = XCreateGC(display, *pixmap_return,
+		   GCForeground | GCBackground, &values);
+
+    XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0,
+	      ximage->width, ximage->height);
+
+    XFreeGC(display, gc);
+}
diff --git a/libXpm/src/Image.c b/libXpm/src/Image.c
new file mode 100644
index 000000000..e0223cc2a
--- /dev/null
+++ b/libXpm/src/Image.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  Image.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions to init and free the XpmImage structure.                         *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmImage(XpmImage *image)
+{
+    image->ncolors = 0;
+    image->colorTable = NULL;
+    image->data = NULL;
+}
+
+/*
+ * Free the XpmImage data which have been allocated
+ */
+void
+XpmFreeXpmImage(XpmImage *image)
+{
+    if (image->colorTable)
+	xpmFreeColorTable(image->colorTable, image->ncolors);
+    if (image->data)
+	XpmFree(image->data);
+    image->data = NULL;
+}
diff --git a/libXpm/src/Info.c b/libXpm/src/Info.c
new file mode 100644
index 000000000..e975a6dce
--- /dev/null
+++ b/libXpm/src/Info.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  Info.c:                                                                    *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions related to the XpmInfo structure.                                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmInfo(XpmInfo *info)
+{
+    if (info) {
+	info->hints_cmt = NULL;
+	info->colors_cmt = NULL;
+	info->pixels_cmt = NULL;
+	info->extensions = NULL;
+	info->nextensions = 0;
+    }
+}
+
+/*
+ * Free the XpmInfo data which have been allocated
+ */
+void
+XpmFreeXpmInfo(XpmInfo *info)
+{
+    if (info) {
+	if (info->valuemask & XpmComments) {
+	    if (info->hints_cmt) {
+		XpmFree(info->hints_cmt);
+		info->hints_cmt = NULL;
+	    }
+	    if (info->colors_cmt) {
+		XpmFree(info->colors_cmt);
+		info->colors_cmt = NULL;
+	    }
+	    if (info->pixels_cmt) {
+		XpmFree(info->pixels_cmt);
+		info->pixels_cmt = NULL;
+	    }
+	}
+	if (info->valuemask & XpmReturnExtensions && info->nextensions) {
+	    XpmFreeExtensions(info->extensions, info->nextensions);
+	    info->extensions = NULL;
+	    info->nextensions = 0;
+	}
+	info->valuemask = 0;
+    }
+}
+
+/*
+ * Set the XpmInfo valuemask to retrieve required info
+ */
+void
+xpmSetInfoMask(
+    XpmInfo		*info,
+    XpmAttributes	*attributes)
+{
+    info->valuemask = 0;
+    if (attributes->valuemask & XpmReturnInfos)
+	info->valuemask |= XpmReturnComments;
+    if (attributes->valuemask & XpmReturnExtensions)
+	info->valuemask |= XpmReturnExtensions;
+}
+
+/*
+ * Fill in the XpmInfo with the XpmAttributes
+ */
+void
+xpmSetInfo(
+    XpmInfo		*info,
+    XpmAttributes	*attributes)
+{
+    info->valuemask = 0;
+    if (attributes->valuemask & XpmInfos) {
+	info->valuemask |= XpmComments | XpmColorTable;
+	info->hints_cmt = attributes->hints_cmt;
+	info->colors_cmt = attributes->colors_cmt;
+	info->pixels_cmt = attributes->pixels_cmt;
+    }
+    if (attributes->valuemask & XpmExtensions) {
+	info->valuemask |= XpmExtensions;
+	info->extensions = attributes->extensions;
+	info->nextensions = attributes->nextensions;
+    }
+    if (attributes->valuemask & XpmHotspot) {
+	info->valuemask |= XpmHotspot;
+	info->x_hotspot = attributes->x_hotspot;
+	info->y_hotspot = attributes->y_hotspot;
+    }
+}
diff --git a/libXpm/src/Makefile.am b/libXpm/src/Makefile.am
new file mode 100644
index 000000000..0c8652a8f
--- /dev/null
+++ b/libXpm/src/Makefile.am
@@ -0,0 +1,46 @@
+# Daniel Stone disowns all copyright on this file.
+
+lib_LTLIBRARIES=libXpm.la
+
+AM_CPPFLAGS = -I. -I$(top_srcdir)/include/X11/
+AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS)
+
+libXpm_la_LDFLAGS = -version-number 4:11:0 -no-undefined
+libXpm_la_LIBADD =  $(XPM_LIBS)
+
+libXpm_la_SOURCES =					\
+	Attrib.c					\
+	CrBufFrI.c					\
+	CrBufFrP.c					\
+	CrDatFrI.c					\
+	CrDatFrP.c					\
+	CrIFrBuf.c					\
+	CrIFrDat.c					\
+	CrIFrP.c					\
+	CrPFrBuf.c					\
+	CrPFrDat.c					\
+	CrPFrI.c					\
+	Image.c						\
+	Info.c						\
+	RdFToBuf.c					\
+	RdFToDat.c					\
+	RdFToI.c					\
+	RdFToP.c					\
+	WrFFrBuf.c					\
+	WrFFrDat.c					\
+	WrFFrI.c					\
+	WrFFrP.c					\
+	XpmI.h						\
+	create.c					\
+	data.c						\
+	hashtab.c					\
+	misc.c						\
+	parse.c						\
+	rgb.c						\
+	rgbtab.h					\
+	scan.c
+
+libXpmincludedir = $(includedir)/X11
+libXpminclude_HEADERS = $(top_srcdir)/include/X11/xpm.h
+
+EXTRA_DIST = amigax.c amigax.h simx.c simx.h
diff --git a/libXpm/src/Makefile.in b/libXpm/src/Makefile.in
new file mode 100644
index 000000000..885c6ae8d
--- /dev/null
+++ b/libXpm/src/Makefile.in
@@ -0,0 +1,654 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Daniel Stone disowns all copyright on this file.
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src
+DIST_COMMON = $(libXpminclude_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" \
+	"$(DESTDIR)$(libXpmincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libXpm_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libXpm_la_OBJECTS = Attrib.lo CrBufFrI.lo CrBufFrP.lo CrDatFrI.lo \
+	CrDatFrP.lo CrIFrBuf.lo CrIFrDat.lo CrIFrP.lo CrPFrBuf.lo \
+	CrPFrDat.lo CrPFrI.lo Image.lo Info.lo RdFToBuf.lo RdFToDat.lo \
+	RdFToI.lo RdFToP.lo WrFFrBuf.lo WrFFrDat.lo WrFFrI.lo \
+	WrFFrP.lo create.lo data.lo hashtab.lo misc.lo parse.lo rgb.lo \
+	scan.lo
+libXpm_la_OBJECTS = $(am_libXpm_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libXpm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libXpm_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo "  CC    " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo "  CCLD  " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo "  GEN   " $@;
+SOURCES = $(libXpm_la_SOURCES)
+DIST_SOURCES = $(libXpm_la_SOURCES)
+HEADERS = $(libXpminclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SXPM_CFLAGS = @SXPM_CFLAGS@
+SXPM_LIBS = @SXPM_LIBS@
+VERSION = @VERSION@
+XPM_CFLAGS = @XPM_CFLAGS@
+XPM_LIBS = @XPM_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+lib_LTLIBRARIES = libXpm.la
+AM_CPPFLAGS = -I. -I$(top_srcdir)/include/X11/
+AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS)
+libXpm_la_LDFLAGS = -version-number 4:11:0 -no-undefined
+libXpm_la_LIBADD = $(XPM_LIBS)
+libXpm_la_SOURCES = \
+	Attrib.c					\
+	CrBufFrI.c					\
+	CrBufFrP.c					\
+	CrDatFrI.c					\
+	CrDatFrP.c					\
+	CrIFrBuf.c					\
+	CrIFrDat.c					\
+	CrIFrP.c					\
+	CrPFrBuf.c					\
+	CrPFrDat.c					\
+	CrPFrI.c					\
+	Image.c						\
+	Info.c						\
+	RdFToBuf.c					\
+	RdFToDat.c					\
+	RdFToI.c					\
+	RdFToP.c					\
+	WrFFrBuf.c					\
+	WrFFrDat.c					\
+	WrFFrI.c					\
+	WrFFrP.c					\
+	XpmI.h						\
+	create.c					\
+	data.c						\
+	hashtab.c					\
+	misc.c						\
+	parse.c						\
+	rgb.c						\
+	rgbtab.h					\
+	scan.c
+
+libXpmincludedir = $(includedir)/X11
+libXpminclude_HEADERS = $(top_srcdir)/include/X11/xpm.h
+EXTRA_DIST = amigax.c amigax.h simx.c simx.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libXpm.la: $(libXpm_la_OBJECTS) $(libXpm_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libXpm_la_LINK) -rpath $(libdir) $(libXpm_la_OBJECTS) $(libXpm_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Attrib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrBufFrI.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrBufFrP.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrDatFrI.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrDatFrP.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrIFrBuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrIFrDat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrIFrP.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrPFrBuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrPFrDat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CrPFrI.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Image.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RdFToBuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RdFToDat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RdFToI.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RdFToP.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WrFFrBuf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WrFFrDat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WrFFrI.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WrFFrP.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/create.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtab.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rgb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-libXpmincludeHEADERS: $(libXpminclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(libXpmincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libXpmincludedir)"
+	@list='$(libXpminclude_HEADERS)'; test -n "$(libXpmincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libXpmincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(libXpmincludedir)" || exit $$?; \
+	done
+
+uninstall-libXpmincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libXpminclude_HEADERS)'; test -n "$(libXpmincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(libXpmincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(libXpmincludedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libXpmincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libXpmincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES uninstall-libXpmincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libLTLIBRARIES clean-libtool ctags distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-libLTLIBRARIES install-libXpmincludeHEADERS \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-libLTLIBRARIES \
+	uninstall-libXpmincludeHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXpm/src/RdFToBuf.c b/libXpm/src/RdFToBuf.c
new file mode 100644
index 000000000..b719960af
--- /dev/null
+++ b/libXpm/src/RdFToBuf.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* RdFToBuf.c:                                                                 *
+*                                                                             *
+*  XPM library                                                                *
+*  Copy a file to a malloc'ed buffer, provided as a convenience.              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <sys/stat.h>
+#if !defined(FOR_MSW) && !defined(WIN32)
+#include <unistd.h>
+#endif
+#ifndef VAX11C
+#include <fcntl.h>
+#endif
+#if defined(FOR_MSW) || defined(WIN32)
+#include <io.h>
+#define stat _stat
+#define fstat _fstat
+#define fdopen _fdopen
+#define O_RDONLY _O_RDONLY
+#endif
+
+int
+XpmReadFileToBuffer(
+    char	 *filename,
+    char	**buffer_return)
+{
+    int fd, fcheck;
+    off_t len;
+    char *ptr;
+    struct stat stats;
+    FILE *fp;
+
+    *buffer_return = NULL;
+
+#ifndef VAX11C
+    fd = open(filename, O_RDONLY);
+#else
+    fd = open(filename, O_RDONLY, NULL);
+#endif
+    if (fd < 0)
+	return XpmOpenFailed;
+
+    if (fstat(fd, &stats)) {
+	close(fd);
+	return XpmOpenFailed;
+    }
+    fp = fdopen(fd, "r");
+    if (!fp) {
+	close(fd);
+	return XpmOpenFailed;
+    }
+    len = stats.st_size;
+    ptr = (char *) XpmMalloc(len + 1);
+    if (!ptr) {
+	fclose(fp);
+	return XpmNoMemory;
+    }
+    fcheck = fread(ptr, 1, len, fp);
+    fclose(fp);
+#ifdef VMS
+    /* VMS often stores text files in a variable-length record format,
+       where there are two bytes of size followed by the record.  fread	
+       converts this so it looks like a record followed by a newline.	
+       Unfortunately, the size reported by fstat() (and fseek/ftell)	
+       counts the two bytes for the record terminator, while fread()	
+       counts only one.  So, fread() sees fewer bytes in the file (size	
+       minus # of records) and thus when asked to read the amount	
+       returned by stat(), it fails.
+       The best solution, suggested by DEC, seems to consider the length
+       returned from fstat() as an upper bound and call fread() with
+       a record length of 1. Then don't check the return value.
+       We'll check for 0 for gross error that's all.
+    */
+    len = fcheck;
+    if (fcheck == 0) {
+#else
+    if (fcheck != len) {
+#endif
+	XpmFree(ptr);
+	return XpmOpenFailed;
+    }
+    ptr[len] = '\0';
+    *buffer_return = ptr;
+    return XpmSuccess;
+}
diff --git a/libXpm/src/RdFToDat.c b/libXpm/src/RdFToDat.c
new file mode 100644
index 000000000..87f7f1ec8
--- /dev/null
+++ b/libXpm/src/RdFToDat.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToDat.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create an array of strings corresponding to it.      *
+*                                                                             *
+*  Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com              *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmReadFileToData(
+    char	  *filename,
+    char	***data_return)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+
+    info.valuemask = XpmReturnComments | XpmReturnExtensions;
+
+    /*
+     * initialize return value
+     */
+    if (data_return)
+	*data_return = NULL;
+
+    ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    ErrorStatus =
+	XpmCreateDataFromXpmImage(data_return, &image, &info);
+
+    XpmFreeXpmImage(&image);
+    XpmFreeXpmInfo(&info);
+
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/RdFToI.c b/libXpm/src/RdFToI.c
new file mode 100644
index 000000000..bc05fe624
--- /dev/null
+++ b/libXpm/src/RdFToI.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create the image and possibly its mask               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86$ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#ifndef NO_ZPIPE
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#else
+#ifdef FOR_MSW
+#include <fcntl.h>
+#endif
+#endif
+
+LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
+LFUNC(xpmDataClose, void, (xpmData *mdata));
+
+FUNC(xpmPipeThrough, FILE*, (int fd,
+			     const char *cmd,
+			     const char *arg1,
+			     const char *mode));
+
+#ifndef CXPMPROG
+int
+XpmReadFileToImage(
+    Display		 *display,
+    char		 *filename,
+    XImage		**image_return,
+    XImage		**shapeimage_return,
+    XpmAttributes	 *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open file to read */
+    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
+	return (ErrorStatus);
+
+    /* create the XImage from the XpmData */
+    if (attributes) {
+	xpmInitAttributes(attributes);
+	xpmSetInfoMask(&info, attributes);
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, &info, attributes);
+    } else
+	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+					    image_return, shapeimage_return,
+					    &image, NULL, attributes);
+    if (attributes) {
+	if (ErrorStatus >= 0)		/* no fatal error */
+	    xpmSetAttributes(attributes, &image, &info);
+	XpmFreeXpmInfo(&info);
+    }
+
+    xpmDataClose(&mdata);
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmReadFileToXpmImage(
+    char	*filename,
+    XpmImage	*image,
+    XpmInfo	*info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open file to read */
+    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
+	return (ErrorStatus);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    xpmDataClose(&mdata);
+
+    return (ErrorStatus);
+}
+#endif /* CXPMPROG */
+
+#ifndef NO_ZPIPE
+/* Do not depend on errno after read_through */
+FILE*
+xpmPipeThrough(
+    int		 fd,
+    const char	*cmd,
+    const char	*arg1,
+    const char	*mode)
+{
+    FILE* fp;
+    int status, fds[2], in = 0, out = 1;
+    pid_t pid;
+    if ( 'w' == *mode )
+	out = 0, in = 1;
+    if ( pipe(fds) < 0 )
+	return NULL;
+    pid = fork();
+    if ( pid < 0 )
+	goto fail1;
+    if ( 0 == pid )
+    {
+	close(fds[in]);
+	if ( dup2(fds[out], out) < 0 )
+	    goto err;
+	close(fds[out]);
+	if ( dup2(fd, in) < 0 )
+	    goto err;
+	close(fd);
+	pid = fork();
+	if ( pid < 0 )
+	    goto err;
+	if ( 0 == pid )
+	{
+	    execlp(cmd, cmd, arg1, (char *)NULL);
+	    perror(cmd);
+	    goto err;
+	}
+	_exit(0);
+    err:
+	_exit(1);
+    }
+    close(fds[out]);
+    /* calling process: wait for first child */
+    while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
+	;
+    if ( WIFSIGNALED(status) ||
+	 (WIFEXITED(status) && WEXITSTATUS(status) != 0) )
+	goto fail2;
+    fp = fdopen(fds[in], mode);
+    if ( !fp )
+	goto fail2;
+    close(fd); /* still open in 2nd child */
+    return fp;
+fail1:
+    close(fds[out]);
+fail2:
+    close(fds[in]);
+    return NULL;
+}
+#endif
+
+/*
+ * open the given file to be read as an xpmData which is returned.
+ */
+static int
+OpenReadFile(
+    char	*filename,
+    xpmData	*mdata)
+{
+    if (!filename) {
+	mdata->stream.file = (stdin);
+	mdata->type = XPMFILE;
+    } else {
+	int fd = open(filename, O_RDONLY);
+#if defined(NO_ZPIPE)
+	if ( fd < 0 )
+	    return XpmOpenFailed;
+#else
+	const char* ext = NULL;
+	if ( fd >= 0 )
+	    ext = strrchr(filename, '.');
+#ifdef STAT_ZFILE /* searching for z-files if the given name not found */
+	else
+	{
+	    size_t len = strlen(filename);
+	    char *compressfile = (char *) XpmMalloc(len + 4);
+	    if ( !compressfile )
+		return (XpmNoMemory);
+	    strcpy(compressfile, filename);
+	    strcpy(compressfile + len, ext = ".Z");
+	    fd = open(compressfile, O_RDONLY);
+	    if ( fd < 0 )
+	    {
+		strcpy(compressfile + len, ext = ".gz");
+		fd = open(compressfile, O_RDONLY);
+		if ( fd < 0 )
+		{
+		    XpmFree(compressfile);
+		    return XpmOpenFailed;
+		}
+	    }
+	    XpmFree(compressfile);
+	}
+#endif
+	if ( ext && !strcmp(ext, ".Z") )
+	{
+	    mdata->type = XPMPIPE;
+	    mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
+	}
+	else if ( ext && !strcmp(ext, ".gz") )
+	{
+	    mdata->type = XPMPIPE;
+	    mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
+	}
+	else
+#endif /* z-files */
+	{
+	    mdata->type = XPMFILE;
+	    mdata->stream.file = fdopen(fd, "r");
+	}
+	if (!mdata->stream.file)
+	{
+	    close(fd);
+	    return (XpmOpenFailed);
+	}
+    }
+    mdata->CommentLength = 0;
+#ifdef CXPMPROG
+    mdata->lineNum = 0;
+    mdata->charNum = 0;
+#endif
+    return (XpmSuccess);
+}
+
+/*
+ * close the file related to the xpmData if any
+ */
+static void
+xpmDataClose(xpmData *mdata)
+{
+    if (mdata->stream.file != (stdin))
+	fclose(mdata->stream.file);
+}
diff --git a/libXpm/src/RdFToP.c b/libXpm/src/RdFToP.c
new file mode 100644
index 000000000..baceddae9
--- /dev/null
+++ b/libXpm/src/RdFToP.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create the pixmap and possibly its mask              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmReadFileToPixmap(
+    Display		*display,
+    Drawable		 d,
+    char		*filename,
+    Pixmap		*pixmap_return,
+    Pixmap		*shapemask_return,
+    XpmAttributes	*attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+	*pixmap_return = 0;
+    if (shapemask_return)
+	*shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmReadFileToImage(display, filename,
+				     (pixmap_return ? &ximage : NULL),
+				     (shapemask_return ? &shapeimage : NULL),
+				     attributes);
+
+    if (ErrorStatus < 0)		/* fatal error */
+	return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+	xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+	XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+	xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+	XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/WrFFrBuf.c b/libXpm/src/WrFFrBuf.c
new file mode 100644
index 000000000..bd1c45b91
--- /dev/null
+++ b/libXpm/src/WrFFrBuf.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* WrFFrBuf.c:                                                                 *
+*                                                                             *
+*  XPM library                                                                *
+*  Write a memory buffer to a file, provided as a convenience.                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromBuffer(
+    char	*filename,
+    char	*buffer)
+{
+    int fcheck, len;
+    FILE *fp = fopen(filename, "w");
+
+    if (!fp)
+	return XpmOpenFailed;
+
+    len = strlen(buffer);
+    fcheck = fwrite(buffer, len, 1, fp);
+    fclose(fp);
+    if (fcheck != 1)
+	return XpmOpenFailed; /* maybe use a better return value */
+
+    return XpmSuccess;
+}
diff --git a/libXpm/src/WrFFrDat.c b/libXpm/src/WrFFrDat.c
new file mode 100644
index 000000000..dc738b9a0
--- /dev/null
+++ b/libXpm/src/WrFFrDat.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and write a file that corresponds to it.                *
+*                                                                             *
+*  Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com              *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromData(
+    char	 *filename,
+    char	**data)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+
+    info.valuemask = XpmReturnComments | XpmReturnExtensions;
+
+    ErrorStatus = XpmCreateXpmImageFromData(data, &image, &info);
+
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    ErrorStatus = XpmWriteFileFromXpmImage(filename, &image, &info);
+
+    XpmFreeXpmImage(&image);
+    XpmFreeXpmInfo(&info);
+
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/WrFFrI.c b/libXpm/src/WrFFrI.c
new file mode 100644
index 000000000..3eeaf2a1d
--- /dev/null
+++ b/libXpm/src/WrFFrI.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Write an image and possibly its mask to an XPM file                        *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86$ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#ifndef NO_ZPIPE
+#include "sys/wait.h"
+#include "sys/types.h"
+#include "fcntl.h"
+#include "unistd.h"
+#include "errno.h"
+#endif
+
+/* MS Windows define a function called WriteFile @#%#&!!! */
+LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name,
+			  XpmInfo *info));
+
+LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
+
+LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
+			 unsigned int cpp, unsigned int *pixels,
+			 XpmColor *colors));
+
+LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
+			      unsigned int num));
+
+LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
+LFUNC(xpmDataClose, void, (xpmData *mdata));
+
+int
+XpmWriteFileFromImage(
+    Display		*display,
+    char		*filename,
+    XImage		*image,
+    XImage		*shapeimage,
+    XpmAttributes	*attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+					     &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /* write the file from the XpmImage */
+    if (attributes) {
+	xpmSetInfo(&info, attributes);
+	ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
+    } else
+	ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+int
+XpmWriteFileFromXpmImage(
+    char	*filename,
+    XpmImage	*image,
+    XpmInfo	*info)
+{
+    xpmData mdata;
+    char *name, *dot, *s, new_name[BUFSIZ] = {0};
+    int ErrorStatus;
+
+    /* open file to write */
+    if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
+	return (ErrorStatus);
+
+    /* figure out a name */
+    if (filename) {
+#ifdef VMS
+	name = filename;
+#else
+	if (!(name = strrchr(filename, '/'))
+#ifdef AMIGA
+	    && !(name = strrchr(filename, ':'))
+#endif
+     )
+	    name = filename;
+	else
+	    name++;
+#endif
+	/* let's try to make a valid C syntax name */
+	if (strchr(name, '.')) {
+	    strncpy(new_name, name, sizeof(new_name));
+	    new_name[sizeof(new_name)-1] = '\0';
+	    /* change '.' to '_' */
+	    name = s = new_name;
+	    while ((dot = strchr(s, '.'))) {
+		*dot = '_';
+		s = dot;
+	    }
+	}
+	if (strchr(name, '-')) {
+	    if (name != new_name) {
+		strncpy(new_name, name, sizeof(new_name));
+		new_name[sizeof(new_name)-1] = '\0';
+		name = new_name;
+	    }
+	    /* change '-' to '_' */
+	    s = name;
+	    while ((dot = strchr(s, '-'))) {
+		*dot = '_';
+		s = dot;
+	    }
+	}
+    } else
+	name = "image_name";
+
+    /* write the XpmData from the XpmImage */
+    if (ErrorStatus == XpmSuccess)
+	ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
+
+    xpmDataClose(&mdata);
+
+    return (ErrorStatus);
+}
+
+static int
+xpmWriteFile(
+    FILE	*file,
+    XpmImage	*image,
+    char	*name,
+    XpmInfo	*info)
+{
+    /* calculation variables */
+    unsigned int cmts, extensions;
+    int ErrorStatus;
+
+    cmts = info && (info->valuemask & XpmComments);
+    extensions = info && (info->valuemask & XpmExtensions)
+	&& info->nextensions;
+
+    /* print the header line */
+    fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
+
+    /* print the hints line */
+    if (cmts && info->hints_cmt)
+	fprintf(file, "/*%s*/\n", info->hints_cmt);
+
+    fprintf(file, "\"%d %d %d %d", image->width, image->height,
+	    image->ncolors, image->cpp);
+
+    if (info && (info->valuemask & XpmHotspot))
+	fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
+
+    if (extensions)
+	fprintf(file, " XPMEXT");
+
+    fprintf(file, "\",\n");
+
+    /* print colors */
+    if (cmts && info->colors_cmt)
+	fprintf(file, "/*%s*/\n", info->colors_cmt);
+
+    WriteColors(file, image->colorTable, image->ncolors);
+
+    /* print pixels */
+    if (cmts && info->pixels_cmt)
+	fprintf(file, "/*%s*/\n", info->pixels_cmt);
+
+    ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
+			      image->data, image->colorTable);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /* print extensions */
+    if (extensions)
+	WriteExtensions(file, info->extensions, info->nextensions);
+
+    /* close the array */
+    fprintf(file, "};\n");
+
+    return (XpmSuccess);
+}
+
+static void
+WriteColors(
+    FILE		*file,
+    XpmColor		*colors,
+    unsigned int	 ncolors)
+{
+    unsigned int a, key;
+    char *s;
+    char **defaults;
+
+    for (a = 0; a < ncolors; a++, colors++) {
+
+	defaults = (char **) colors;
+	fprintf(file, "\"%s", *defaults++);
+
+	for (key = 1; key <= NKEYS; key++, defaults++) {
+	    if ((s = *defaults))
+		fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
+	}
+	fprintf(file, "\",\n");
+    }
+}
+
+
+static int
+WritePixels(
+    FILE		*file,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	 cpp,
+    unsigned int	*pixels,
+    XpmColor		*colors)
+{
+    char *s, *p, *buf;
+    unsigned int x, y, h;
+
+    h = height - 1;
+    if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) 
+	return XpmNoMemory;    
+    p = buf = (char *) XpmMalloc(width * cpp + 3);
+    if (!buf)
+	return (XpmNoMemory);
+    *buf = '"';
+    p++;
+    for (y = 0; y < h; y++) {
+	s = p;
+	for (x = 0; x < width; x++, pixels++) {
+	    strncpy(s, colors[*pixels].string, cpp);
+	    s += cpp;
+	}
+	*s++ = '"';
+	*s = '\0';
+	fprintf(file, "%s,\n", buf);
+    }
+    /* duplicate some code to avoid a test in the loop */
+    s = p;
+    for (x = 0; x < width; x++, pixels++) {
+	strncpy(s, colors[*pixels].string, cpp);
+	s += cpp;
+    }
+    *s++ = '"';
+    *s = '\0';
+    fprintf(file, "%s", buf);
+
+    XpmFree(buf);
+    return (XpmSuccess);
+}
+
+static void
+WriteExtensions(
+    FILE		*file,
+    XpmExtension	*ext,
+    unsigned int	 num)
+{
+    unsigned int x, y, n;
+    char **line;
+
+    for (x = 0; x < num; x++, ext++) {
+	fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
+	n = ext->nlines;
+	for (y = 0, line = ext->lines; y < n; y++, line++)
+	    fprintf(file, ",\n\"%s\"", *line);
+    }
+    fprintf(file, ",\n\"XPMENDEXT\"");
+}
+
+
+#ifndef NO_ZPIPE
+FUNC(xpmPipeThrough, FILE*, (int fd,
+			     const char* cmd,
+			     const char* arg1,
+			     const char* mode));
+#endif
+
+/*
+ * open the given file to be written as an xpmData which is returned
+ */
+static int
+OpenWriteFile(
+    char	*filename,
+    xpmData	*mdata)
+{
+    if (!filename) {
+	mdata->stream.file = (stdout);
+	mdata->type = XPMFILE;
+    } else {
+#ifndef NO_ZPIPE
+	size_t len;
+#endif
+	int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+	if ( fd < 0 )
+	    return(XpmOpenFailed);
+#ifndef NO_ZPIPE
+	len = strlen(filename);
+	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
+	    mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
+	    mdata->type = XPMPIPE;
+	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
+	    mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
+	    mdata->type = XPMPIPE;
+	} else
+#endif
+	{
+	    mdata->stream.file = fdopen(fd, "w");
+	    mdata->type = XPMFILE;
+	}
+	if (!mdata->stream.file)
+	    return (XpmOpenFailed);
+    }
+    return (XpmSuccess);
+}
+
+/*
+ * close the file related to the xpmData if any
+ */
+static void
+xpmDataClose(xpmData *mdata)
+{
+    if (mdata->stream.file != (stdout))
+	fclose(mdata->stream.file);
+}
+
diff --git a/libXpm/src/WrFFrP.c b/libXpm/src/WrFFrP.c
new file mode 100644
index 000000000..497ba56d7
--- /dev/null
+++ b/libXpm/src/WrFFrP.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Write a pixmap and possibly its mask to an XPM file                        *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromPixmap(
+    Display		*display,
+    char		*filename,
+    Pixmap		 pixmap,
+    Pixmap		 shapemask,
+    XpmAttributes	*attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+	width = attributes->width;
+	height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+	xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+	xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+				 &width, &height);
+
+    /* write to the file */
+    ErrorStatus = XpmWriteFileFromImage(display, filename, ximage, shapeimage,
+					attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/libXpm/src/XpmI.h b/libXpm/src/XpmI.h
new file mode 100644
index 000000000..e9f28cc74
--- /dev/null
+++ b/libXpm/src/XpmI.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+/* $XFree86: xc/extras/Xpm/lib/XpmI.h,v 1.7 2001/11/01 23:35:25 dawes Exp $ */
+
+/*****************************************************************************\
+* XpmI.h:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Internal Include file                                                      *
+*                                                                             *
+*  ** Everything defined here is subject to changes any time. **              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+#ifndef XPMI_h
+#define XPMI_h
+
+#include "xpm.h"
+
+/*
+ * lets try to solve include files
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+/* stdio.h doesn't declare popen on a Sequent DYNIX OS */
+#ifdef sequent
+extern FILE *popen();
+#endif
+
+#ifdef FOR_MSW
+#include "simx.h"
+#else
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xmd.h>
+#endif
+
+#ifdef VMS
+#include <unixio.h>
+#include <file.h>
+#endif
+
+/* The following should help people wanting to use their own memory allocation
+ * functions. To avoid the overhead of a function call when the standard
+ * functions are used these are all macros, even the XpmFree function which
+ * needs to be a real function for the outside world though.
+ * So if change these be sure to change the XpmFree function in misc.c
+ * accordingly.
+ */
+#define XpmFree(ptr) free(ptr)
+
+#ifndef FOR_MSW
+#define XpmMalloc(size) malloc((size))
+#define XpmRealloc(ptr, size) realloc((ptr), (size))
+#define XpmCalloc(nelem, elsize) calloc((nelem), (elsize))
+#else
+/* checks for mallocs bigger than 64K */
+#define XpmMalloc(size) boundCheckingMalloc((long)(size))/* in simx.[ch] */
+#define XpmRealloc(ptr, size) boundCheckingRealloc((ptr),(long)(size))
+#define XpmCalloc(nelem, elsize) \
+		boundCheckingCalloc((long)(nelem),(long) (elsize))
+#endif
+
+#if defined(SCO) || defined(__USLC__)
+#include <stdint.h>	/* For SIZE_MAX */
+#endif
+#include <limits.h>
+#ifndef SIZE_MAX
+# ifdef ULONG_MAX
+#  define SIZE_MAX ULONG_MAX
+# else 
+#  define SIZE_MAX UINT_MAX
+# endif
+#endif
+
+#define XPMMAXCMTLEN BUFSIZ
+typedef struct {
+    unsigned int type;
+    union {
+	FILE *file;
+	char **data;
+    }     stream;
+    char *cptr;
+    unsigned int line;
+    int CommentLength;
+    char Comment[XPMMAXCMTLEN];
+    char *Bcmt, *Ecmt, Bos, Eos;
+    int format;			/* 1 if XPM1, 0 otherwise */
+#ifdef CXPMPROG
+    int lineNum;
+    int charNum;
+#endif
+}      xpmData;
+
+#define XPMARRAY 0
+#define XPMFILE  1
+#define XPMPIPE  2
+#define XPMBUFFER 3
+
+#define EOL '\n'
+#define TAB '\t'
+#define SPC ' '
+
+typedef struct {
+    char *type;			/* key word */
+    char *Bcmt;			/* string beginning comments */
+    char *Ecmt;			/* string ending comments */
+    char Bos;			/* character beginning strings */
+    char Eos;			/* character ending strings */
+    char *Strs;			/* strings separator */
+    char *Dec;			/* data declaration string */
+    char *Boa;			/* string beginning assignment */
+    char *Eoa;			/* string ending assignment */
+}      xpmDataType;
+
+extern xpmDataType xpmDataTypes[];
+
+/*
+ * rgb values and ascii names (from rgb text file) rgb values,
+ * range of 0 -> 65535 color mnemonic of rgb value
+ */
+typedef struct {
+    int r, g, b;
+    char *name;
+}      xpmRgbName;
+
+/* Maximum number of rgb mnemonics allowed in rgb text file. */
+#define MAX_RGBNAMES 1024
+
+extern char *xpmColorKeys[];
+
+#define TRANSPARENT_COLOR "None"	/* this must be a string! */
+
+/* number of xpmColorKeys */
+#define NKEYS 5
+
+/* XPM internal routines */
+
+FUNC(xpmParseData, int, (xpmData *data, XpmImage *image, XpmInfo *info));
+FUNC(xpmParseDataAndCreate, int, (Display *display, xpmData *data,
+				  XImage **image_return,
+				  XImage **shapeimage_return,
+				  XpmImage *image, XpmInfo *info,
+				  XpmAttributes *attributes));
+
+FUNC(xpmFreeColorTable, void, (XpmColor *colorTable, int ncolors));
+
+FUNC(xpmInitAttributes, void, (XpmAttributes *attributes));
+
+FUNC(xpmInitXpmImage, void, (XpmImage *image));
+
+FUNC(xpmInitXpmInfo, void, (XpmInfo *info));
+
+FUNC(xpmSetInfoMask, void, (XpmInfo *info, XpmAttributes *attributes));
+FUNC(xpmSetInfo, void, (XpmInfo *info, XpmAttributes *attributes));
+FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image,
+			      XpmInfo *info));
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d,
+				      XImage *ximage, Pixmap *pixmap_return));
+
+FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap,
+				      XImage **ximage_return,
+				      unsigned int *width,
+				      unsigned int *height));
+#endif
+
+/* structures and functions related to hastable code */
+
+typedef struct _xpmHashAtom {
+    char *name;
+    void *data;
+}      *xpmHashAtom;
+
+typedef struct {
+    unsigned int size;
+    unsigned int limit;
+    unsigned int used;
+    xpmHashAtom *atomTable;
+}      xpmHashTable;
+
+FUNC(xpmHashTableInit, int, (xpmHashTable *table));
+FUNC(xpmHashTableFree, void, (xpmHashTable *table));
+FUNC(xpmHashSlot, xpmHashAtom *, (xpmHashTable *table, char *s));
+FUNC(xpmHashIntern, int, (xpmHashTable *table, char *tag, void *data));
+
+#define HashAtomData(i) ((void *)(long)i)
+#define HashColorIndex(slot) ((unsigned long)((*slot)->data))
+#define USE_HASHTABLE (cpp > 2 && ncolors > 4)
+
+/* I/O utility */
+
+FUNC(xpmNextString, int, (xpmData *mdata));
+FUNC(xpmNextUI, int, (xpmData *mdata, unsigned int *ui_return));
+FUNC(xpmGetString, int, (xpmData *mdata, char **sptr, unsigned int *l));
+
+#define xpmGetC(mdata) \
+	((!mdata->type || mdata->type == XPMBUFFER) ? \
+	 (*mdata->cptr++) : (getc(mdata->stream.file)))
+
+FUNC(xpmNextWord, unsigned int,
+     (xpmData *mdata, char *buf, unsigned int buflen));
+FUNC(xpmGetCmt, int, (xpmData *mdata, char **cmt));
+FUNC(xpmParseHeader, int, (xpmData *mdata));
+FUNC(xpmParseValues, int, (xpmData *data, unsigned int *width,
+			   unsigned int *height, unsigned int *ncolors,
+			   unsigned int *cpp, unsigned int *x_hotspot,
+			   unsigned int *y_hotspot, unsigned int *hotspot,
+			   unsigned int *extensions));
+
+FUNC(xpmParseColors, int, (xpmData *data, unsigned int ncolors,
+			   unsigned int cpp, XpmColor **colorTablePtr,
+			   xpmHashTable *hashtable));
+
+FUNC(xpmParseExtensions, int, (xpmData *data, XpmExtension **extensions,
+			       unsigned int *nextensions));
+
+/* RGB utility */
+
+FUNC(xpmReadRgbNames, int, (char *rgb_fname, xpmRgbName *rgbn));
+FUNC(xpmGetRgbName, char *, (xpmRgbName *rgbn, int rgbn_max,
+			     int red, int green, int blue));
+FUNC(xpmFreeRgbNames, void, (xpmRgbName *rgbn, int rgbn_max));
+#ifdef FOR_MSW
+FUNC(xpmGetRGBfromName,int, (char *name, int *r, int *g, int *b));
+#endif
+
+#ifndef AMIGA
+FUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp,
+				      register XImage *img));
+FUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp,
+				     register XImage *img));
+
+/*
+ * Macros
+ *
+ * The XYNORMALIZE macro determines whether XY format data requires
+ * normalization and calls a routine to do so if needed. The logic in
+ * this module is designed for LSBFirst byte and bit order, so
+ * normalization is done as required to present the data in this order.
+ *
+ * The ZNORMALIZE macro performs byte and nibble order normalization if
+ * required for Z format data.
+ *
+ * The XYINDEX macro computes the index to the starting byte (char) boundary
+ * for a bitmap_unit containing a pixel with coordinates x and y for image
+ * data in XY format.
+ *
+ * The ZINDEX* macros compute the index to the starting byte (char) boundary
+ * for a pixel with coordinates x and y for image data in ZPixmap format.
+ *
+ */
+
+#define XYNORMALIZE(bp, img) \
+    if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
+	xpm_xynormalizeimagebits((unsigned char *)(bp), img)
+
+#define ZNORMALIZE(bp, img) \
+    if (img->byte_order == MSBFirst) \
+	xpm_znormalizeimagebits((unsigned char *)(bp), img)
+
+#define XYINDEX(x, y, img) \
+    ((y) * img->bytes_per_line) + \
+    (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
+
+#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
+    (((x) * img->bits_per_pixel) >> 3)
+
+#define ZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2)
+
+#define ZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1)
+
+#define ZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x)
+
+#define ZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3)
+#endif /* not AMIGA */
+
+#ifdef __STDC__
+#define Const const
+#else
+#define Const /**/
+#endif
+
+#ifdef NEED_STRDUP
+FUNC(xpmstrdup, char *, (char *s1));
+#else
+#undef xpmstrdup
+#define xpmstrdup strdup
+#endif
+
+#ifdef NEED_STRCASECMP                   
+FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
+#else
+#undef xpmstrcasecmp
+#define xpmstrcasecmp strcasecmp
+#endif
+
+FUNC(xpmatoui, unsigned int,
+     (char *p, unsigned int l, unsigned int *ui_return));
+
+#endif
diff --git a/libXpm/src/amigax.c b/libXpm/src/amigax.c
new file mode 100644
index 000000000..eb3bc3a4c
--- /dev/null
+++ b/libXpm/src/amigax.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 19896 Lorens Younes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Lorens Younes shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Lorens Younes.
+ */
+
+/*****************************************************************************\
+* amigax.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Emulates some Xlib functionality for Amiga.                                *
+*                                                                             *
+*  Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95                      *
+*  Revised 4/96                                                               *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include "amigax.h"
+
+#include <graphics/gfxbase.h>
+#include <intuition/screens.h>
+
+#include <proto/exec.h>
+
+
+static struct RastPort *
+AllocRastPort (unsigned int, unsigned int, unsigned int);
+static void
+FreeRastPort (struct RastPort *, unsigned int,unsigned int);
+
+
+static struct RastPort *
+AllocRastPort (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    struct RastPort  *rp;
+    
+    rp = XpmMalloc (sizeof (*rp));
+    if (rp != NULL)
+    {
+	InitRastPort (rp);
+	if (GfxBase->LibNode.lib_Version >= 39)
+	{
+	    rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL);
+	    if (rp->BitMap == NULL)
+	    {
+		FreeRastPort (rp, width, height);
+		return NULL;
+	    }
+	}
+	else
+	{
+	    unsigned int   i;
+	    
+	    rp->BitMap = XpmMalloc (sizeof (*rp->BitMap));
+	    if (rp->BitMap == NULL)
+	    {
+		FreeRastPort (rp, width, height);
+		return NULL;
+	    }
+	    
+	    InitBitMap (rp->BitMap, depth, width, height);
+	    for (i = 0; i < depth; ++i)
+		rp->BitMap->Planes[i] = NULL;
+	    for (i = 0; i < depth; ++i)
+	    {
+		rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height);
+		if (rp->BitMap->Planes[i] == NULL)
+		{
+		    FreeRastPort (rp, width, height);
+		    return NULL;
+		}
+	    }
+	}
+    }
+    
+    return rp;
+}
+
+
+static void
+FreeRastPort (
+    struct RastPort  *rp,
+    unsigned int      width,
+    unsigned int      height)
+{
+    if (rp != NULL)
+    {
+	if (rp->BitMap != NULL)
+	{
+	    WaitBlit ();
+	    if (GfxBase->LibNode.lib_Version >= 39)
+		FreeBitMap (rp->BitMap);
+	    else
+	    {
+		unsigned int   i;
+		
+		for (i = 0; i < rp->BitMap->Depth; ++i)
+		{
+		    if (rp->BitMap->Planes[i] != NULL)
+			FreeRaster (rp->BitMap->Planes[i], width, height);
+		}
+		XpmFree (rp->BitMap);
+	    }
+	}
+	XpmFree (rp);
+    }
+}
+
+
+XImage *
+AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    XImage  *img;
+    
+    img = XpmMalloc (sizeof (*img));
+    if (img != NULL)
+    {
+	img->width = width;
+	img->height = height;
+	img->rp = AllocRastPort (img->width, img->height, depth);
+	if (img->rp == NULL)
+	{
+	    FreeXImage (img);
+	    return NULL;
+	}
+    }
+    
+    return img;
+}
+
+
+int
+FreeXImage (
+    XImage  *ximage)
+{
+    if (ximage != NULL)
+    {
+	FreeRastPort (ximage->rp, ximage->width, ximage->height);
+	XpmFree (ximage);
+    }
+    
+    return Success;
+}
+
+
+int
+XPutPixel (
+    XImage         *ximage,
+    int             x,
+    int             y,
+    unsigned long   pixel)
+{
+    SetAPen (ximage->rp, pixel);
+    WritePixel (ximage->rp, x, y);
+    
+    return Success;
+}
+
+
+Status
+AllocBestPen (
+    Colormap        colormap,
+    XColor         *screen_in_out,
+    unsigned long   precision,
+    Bool            fail_if_bad)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+	unsigned long   r, g, b;
+	
+	r = screen_in_out->red * 0x00010001;
+	g = screen_in_out->green * 0x00010001;
+	b = screen_in_out->blue * 0x00010001;
+	screen_in_out->pixel = ObtainBestPen (colormap, r, g, b,
+					      OBP_Precision, precision,
+					      OBP_FailIfBad, fail_if_bad,
+					      TAG_DONE);
+	if (screen_in_out->pixel == -1)
+	    return False;
+	
+	QueryColor (colormap, screen_in_out);
+    }
+    else
+    {
+	XColor   nearest, trial;
+	long     nearest_delta, trial_delta;
+	int      num_cells, i;
+	
+	num_cells = colormap->Count;
+	nearest.pixel = 0;
+	QueryColor (colormap, &nearest);
+	nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8))
+			  * ((screen_in_out->red >> 8) - (nearest.red >> 8)))
+			 +
+			 (((screen_in_out->green >> 8) - (nearest.green >> 8))
+			  * ((screen_in_out->green >> 8) - (nearest.green >> 8)))
+			 +
+			 (((screen_in_out->blue >> 8) - (nearest.blue >> 8))
+			  * ((screen_in_out->blue >> 8) - (nearest.blue >> 8))));
+	for (i = 1; i < num_cells; i++)
+	{
+	/* precision and fail_if_bad is ignored under pre V39 */
+	    trial.pixel = i;
+	    QueryColor (colormap, &trial);
+	    trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8))
+			    * ((screen_in_out->red >> 8) - (trial.red >> 8)))
+			   +
+			   (((screen_in_out->green >> 8) - (trial.green >> 8))
+			    * ((screen_in_out->green >> 8) - (trial.green >> 8)))
+			   +
+			   (((screen_in_out->blue >> 8) - (trial.blue >> 8))
+			    * ((screen_in_out->blue >> 8) - (trial.blue >> 8))));
+	    if (trial_delta < nearest_delta)
+	    {
+		nearest = trial;
+		nearest_delta = trial_delta;
+	    }
+	}
+	screen_in_out->pixel = nearest.pixel;
+	screen_in_out->red = nearest.red;
+	screen_in_out->green = nearest.green;
+	screen_in_out->blue = nearest.blue;
+    }
+    
+    return True;
+}
+
+
+int
+FreePens (
+    Colormap        colormap,
+    unsigned long  *pixels,
+    int             npixels)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+	int   i;
+	
+	for (i = 0; i < npixels; i++)
+	    ReleasePen (colormap, pixels[i]);
+    }
+    
+    return Success;
+}
+
+
+Status
+ParseColor (
+    char    *spec,
+    XColor  *exact_def_return)
+{
+    int spec_length;
+    
+    if (spec == 0)
+	return False;
+    
+    spec_length = strlen(spec);
+    if (spec[0] == '#')
+    {
+	int hexlen;
+	char hexstr[10];
+	
+	hexlen = (spec_length - 1) / 3;
+	if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1)
+	    return False;
+	
+	hexstr[hexlen] = '\0';
+	strncpy (hexstr, spec + 1, hexlen);
+	exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+	strncpy (hexstr, spec + 1 + hexlen, hexlen);
+	exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+	strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen);
+	exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+	
+	return True;
+    }
+    else
+    {
+	FILE  *rgbf;
+	int    items, red, green, blue;
+	char   line[512], name[512];
+	Bool   success = False;
+	
+	rgbf = fopen ("LIBS:rgb.txt", "r");
+	if (rgbf == NULL)
+	    return False;
+	
+	while (fgets(line, sizeof (line), rgbf) && !success)
+	{
+	    items = sscanf (line, "%d %d %d %[^\n]\n",
+			    &red, &green, &blue, name);
+	    if (items != 4)
+		continue;
+	    
+	    if (red < 0 || red > 0xFF
+		|| green < 0 || green > 0xFF
+		|| blue < 0 || blue > 0xFF)
+	    {
+		continue;
+	    }
+	    
+	    if (0 == xpmstrcasecmp (spec, name))
+	    {
+		exact_def_return->red = red * 0x0101;
+		exact_def_return->green = green * 0x0101;
+		exact_def_return->blue = blue * 0x0101;
+		success = True;
+	    }
+	}
+	fclose (rgbf);
+	
+	return success;
+    }
+}
+
+
+int
+QueryColor (
+    Colormap   colormap,
+    XColor    *def_in_out)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+	unsigned long   rgb[3];
+	
+	GetRGB32 (colormap, def_in_out->pixel, 1, rgb);
+	def_in_out->red = rgb[0] >> 16;
+	def_in_out->green = rgb[1] >> 16;
+	def_in_out->blue = rgb[2] >> 16;
+    }
+    else
+    {
+	unsigned short   rgb;
+	
+	rgb = GetRGB4 (colormap, def_in_out->pixel);
+	def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111;
+	def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111;
+	def_in_out->blue = (rgb & 0xF) * 0x1111;
+    }
+    
+    return Success;
+}
+
+
+int
+QueryColors (
+    Colormap   colormap,
+    XColor    *defs_in_out,
+    int        ncolors)
+{
+    int   i;
+    
+    for (i = 0; i < ncolors; i++)
+	QueryColor (colormap, &defs_in_out[i]);
+    
+    return Success;
+}
diff --git a/libXpm/src/amigax.h b/libXpm/src/amigax.h
new file mode 100644
index 000000000..213ed7619
--- /dev/null
+++ b/libXpm/src/amigax.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 1996 Lorens Younes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Lorens Younes shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Lorens Younes.
+ */
+
+/*****************************************************************************\
+* amigax.h:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Emulates some Xlib functionality for Amiga.                                *
+*                                                                             *
+*  Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95                      *
+*  Revised 4/96                                                               *
+\*****************************************************************************/
+
+#ifndef AMIGA_X
+#define AMIGA_X
+
+
+#include <intuition/screens.h>
+
+#include <proto/exec.h>
+#include <proto/graphics.h>
+
+
+#define Success   0
+
+/* really never used */
+#define ZPixmap   2
+
+#define Bool     int
+#define Status   int
+#define True     1
+#define False    0
+
+typedef struct ColorMap  *Colormap;
+
+typedef void  *Visual;
+
+typedef struct {
+    int               width, height;
+    struct RastPort  *rp;
+}   XImage;
+
+typedef struct {
+    unsigned long    pixel;
+    unsigned short   red, green, blue;
+}   XColor;
+
+typedef struct Screen   Display;
+
+
+#define XGrabServer(dpy)     (Forbid ())
+#define XUngrabServer(dpy)   (Permit ())
+
+#define XDefaultScreen(dpy)          (0)
+#define XDefaultVisual(dpy, scr)     (NULL)
+#define XDefaultColormap(dpy, scr)   (dpy->ViewPort.ColorMap)
+#define XDefaultDepth(dpy, scr)      (dpy->RastPort.BitMap->Depth)
+
+#define XCreateImage(dpy, vi, depth, format, offset, data, width, height, pad, bpl) \
+	(AllocXImage (width, height, depth))
+#define XDestroyImage(img)   (FreeXImage (img))
+
+#define XAllocColor(dpy, cm, xc) \
+	(AllocBestPen (cm, xc, PRECISION_EXACT, True))
+#define XFreeColors(dpy, cm, pixels, npixels, planes) \
+	(FreePens (cm, pixels, npixels))
+#define XParseColor(dpy, cm, spec, exact_def_return) \
+	(ParseColor (spec, exact_def_return))
+#define XQueryColor(dpy, cm, def_in_out) \
+	(QueryColor(cm, def_in_out))
+#define XQueryColors(dpy, cm, defs_in_out, ncolors) \
+	(QueryColors(cm, defs_in_out, ncolors))
+
+
+XImage *
+AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth);
+
+
+int
+FreeXImage (
+    XImage  *ximage);
+
+
+int
+XPutPixel (
+    XImage         *ximage,
+    int             x,
+    int             y,
+    unsigned long   pixel);
+
+
+Status
+AllocBestPen (
+    Colormap        colormap,
+    XColor         *screen_in_out,
+    unsigned long   precision,
+    Bool            fail_if_bad);
+
+
+int
+FreePens (
+    Colormap        colormap,
+    unsigned long  *pixels,
+    int             npixels);
+
+
+Status
+ParseColor (
+    char      *spec,
+    XColor    *exact_def_return);
+
+
+int
+QueryColor (
+    Colormap   colormap,
+    XColor    *def_in_out);
+
+
+int
+QueryColors (
+    Colormap   colormap,
+    XColor    *defs_in_out,
+    int        ncolors);
+
+
+#endif /* AMIGA_X */
diff --git a/libXpm/src/create.c b/libXpm/src/create.c
new file mode 100644
index 000000000..acae3218c
--- /dev/null
+++ b/libXpm/src/create.c
@@ -0,0 +1,2519 @@
+/* $XdotOrg: lib/Xpm/src/create.c,v 1.6 2005/05/19 15:02:48 sandmann Exp $ */
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* create.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Create an X image and possibly its related shape mask                      *
+*  from the given XpmImage.                                                   *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/create.c,v 1.4 2003/05/27 22:26:20 tsi Exp $ */
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+
+LFUNC(xpmVisualType, int, (Visual *visual));
+
+LFUNC(AllocColor, int, (Display *display, Colormap colormap,
+			char *colorname, XColor *xcolor, void *closure));
+LFUNC(FreeColors, int, (Display *display, Colormap colormap,
+			Pixel *pixels, int n, void *closure));
+
+#ifndef FOR_MSW
+LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
+			   Visual *visual, XColor *col,
+			   Pixel *image_pixel, Pixel *mask_pixel,
+			   Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+			   XpmAttributes *attributes, XColor *cols, int ncols,
+			   XpmAllocColorFunc allocColor, void *closure));
+#else
+/* let the window system take care of close colors */
+#endif
+
+LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
+		      char *colorname, unsigned int color_index,
+		      Pixel *image_pixel, Pixel *mask_pixel,
+		      unsigned int *mask_pixel_index,
+		      Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+		      Pixel *used_pixels, unsigned int *nused_pixels,
+		      XpmAttributes *attributes, XColor *cols, int ncols,
+		      XpmAllocColorFunc allocColor, void *closure));
+
+LFUNC(CreateXImage, int, (Display *display, Visual *visual,
+			  unsigned int depth, int format, unsigned int width,
+                          unsigned int height, XImage **image_return));
+
+LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
+                          XpmColor *colors, unsigned int ncolors,
+                          Pixel *image_pixels, Pixel *mask_pixels,
+                          unsigned int *mask_pixel_index,
+                          Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+                          Pixel *used_pixels, unsigned int *nused_pixels));
+
+#ifndef FOR_MSW
+LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width,
+			       unsigned int height, unsigned int ncolors,
+			       unsigned int cpp, XpmColor *colorTable,
+			       xpmHashTable *hashtable,
+			       XImage *image, Pixel *image_pixels,
+			       XImage *mask, Pixel *mask_pixels));
+#else  /* FOR_MSW */
+LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width,
+			       unsigned int height, unsigned int ncolors,
+			       unsigned int cpp, XpmColor *colorTable,
+			       xpmHashTable *hashtable,
+			       XImage *image, Pixel *image_pixels,
+			       XImage *mask, Pixel *mask_pixels));
+#endif
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/* XImage pixel routines */
+LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
+			     unsigned int height, unsigned int *pixelindex,
+			     Pixel *pixels));
+
+LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
+			       unsigned int height, unsigned int *pixelindex,
+			       Pixel *pixels));
+
+LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
+			       unsigned int height, unsigned int *pixelindex,
+			       Pixel *pixels));
+
+LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
+			      unsigned int height, unsigned int *pixelindex,
+			      Pixel *pixels));
+
+LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
+			      unsigned int height, unsigned int *pixelindex,
+			      Pixel *pixels));
+
+LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel));
+#if !defined(WORD64) && !defined(LONG64)
+LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
+#endif
+LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+
+# else /* AMIGA */
+LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width,
+			      unsigned int height, unsigned int *pixelindex,
+			      Pixel *pixels));
+# endif/* AMIGA */
+#else  /* FOR_MSW */
+/* FOR_MSW pixel routine */
+LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,
+				unsigned int width, unsigned int height,
+				unsigned int *pixelindex, Pixel *pixels));
+#endif /* FOR_MSW */
+
+#ifdef NEED_STRCASECMP
+FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
+
+/*
+ * in case strcasecmp is not provided by the system here is one
+ * which does the trick
+ */
+int
+xpmstrcasecmp(
+    register char	*s1,
+    register char	*s2)
+{
+    register int c1, c2;
+
+    while (*s1 && *s2) {
+	c1 = tolower(*s1);
+	c2 = tolower(*s2);
+	if (c1 != c2)
+	    return (c1 - c2);
+	s1++;
+	s2++;
+    }
+    return (int) (*s1 - *s2);
+}
+
+#endif
+
+/*
+ * return the default color key related to the given visual
+ */
+static int
+xpmVisualType(Visual *visual)
+{
+#ifndef FOR_MSW
+# ifndef AMIGA
+    switch (visual->class) {
+    case StaticGray:
+    case GrayScale:
+	switch (visual->map_entries) {
+	case 2:
+	    return (XPM_MONO);
+	case 4:
+	    return (XPM_GRAY4);
+	default:
+	    return (XPM_GRAY);
+	}
+    default:
+	return (XPM_COLOR);
+    }
+# else
+    /* set the key explicitly in the XpmAttributes to override this */
+    return (XPM_COLOR);
+# endif
+#else
+    /* there should be a similar switch for MSW */
+    return (XPM_COLOR);
+#endif
+}
+
+
+typedef struct {
+    int cols_index;
+    long closeness;
+}      CloseColor;
+
+static int
+closeness_cmp(Const void *a, Const void *b)
+{
+    CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b;
+
+    /* cast to int as qsort requires */
+    return (int) (x->closeness - y->closeness);
+}
+
+
+/* default AllocColor function:
+ *   call XParseColor if colorname is given, return negative value if failure
+ *   call XAllocColor and return 0 if failure, positive otherwise
+ */
+static int
+AllocColor(
+    Display	*display,
+    Colormap	 colormap,
+    char	*colorname,
+    XColor	*xcolor,
+    void	*closure)		/* not used */
+{
+    int status;
+    if (colorname)
+	if (!XParseColor(display, colormap, colorname, xcolor))
+	    return -1;
+    status = XAllocColor(display, colormap, xcolor);
+    return status != 0 ? 1 : 0;
+}
+
+
+#ifndef FOR_MSW
+/*
+ * set a close color in case the exact one can't be set
+ * return 0 if success, 1 otherwise.
+ */
+
+static int
+SetCloseColor(
+    Display		*display,
+    Colormap		 colormap,
+    Visual		*visual,
+    XColor		*col,
+    Pixel		*image_pixel,
+    Pixel		*mask_pixel,
+    Pixel		*alloc_pixels,
+    unsigned int	*nalloc_pixels,
+    XpmAttributes	*attributes,
+    XColor		*cols,
+    int			 ncols,
+    XpmAllocColorFunc	 allocColor,
+    void		*closure)
+{
+
+    /*
+     * Allocation failed, so try close colors. To get here the visual must
+     * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
+     * What about sharing systems like QDSS?). Beware: we have to treat
+     * DirectColor differently.
+     */
+
+
+    long int red_closeness, green_closeness, blue_closeness;
+    int n;
+    Bool alloc_color;
+
+    if (attributes && (attributes->valuemask & XpmCloseness))
+	red_closeness = green_closeness = blue_closeness =
+	    attributes->closeness;
+    else {
+	red_closeness = attributes->red_closeness;
+	green_closeness = attributes->green_closeness;
+	blue_closeness = attributes->blue_closeness;
+    }
+    if (attributes && (attributes->valuemask & XpmAllocCloseColors))
+	alloc_color = attributes->alloc_close_colors;
+    else
+	alloc_color = True;
+
+    /*
+     * We sort the colormap by closeness and try to allocate the color
+     * closest to the target. If the allocation of this close color fails,
+     * which almost never happens, then one of two scenarios is possible.
+     * Either the colormap must have changed (since the last close color
+     * allocation or possibly while we were sorting the colormap), or the
+     * color is allocated as Read/Write by some other client. (Note: X
+     * _should_ allow clients to check if a particular color is Read/Write,
+     * but it doesn't! :-( ). We cannot determine which of these scenarios
+     * occurred, so we try the next closest color, and so on, until no more
+     * colors are within closeness of the target. If we knew that the
+     * colormap had changed, we could skip this sequence.
+     * 
+     * If _none_ of the colors within closeness of the target can be allocated,
+     * then we can finally be pretty sure that the colormap has actually
+     * changed. In this case we try to allocate the original color (again),
+     * then try the closecolor stuff (again)...
+     * 
+     * In theory it would be possible for an infinite loop to occur if another
+     * process kept changing the colormap every time we sorted it, so we set
+     * a maximum on the number of iterations. After this many tries, we use
+     * XGrabServer() to ensure that the colormap remains unchanged.
+     * 
+     * This approach gives particularly bad worst case performance - as many as
+     * <MaximumIterations> colormap reads and sorts may be needed, and as
+     * many as <MaximumIterations> * <ColormapSize> attempted allocations
+     * may fail. On an 8-bit system, this means as many as 3 colormap reads,
+     * 3 sorts and 768 failed allocations per execution of this code!
+     * Luckily, my experiments show that in general use in a typical 8-bit
+     * color environment only about 1 in every 10000 allocations fails to
+     * succeed in the fastest possible time. So virtually every time what
+     * actually happens is a single sort followed by a successful allocate.
+     * The very first allocation also costs a colormap read, but no further
+     * reads are usually necessary.
+     */
+
+#define ITERATIONS 2			/* more than one is almost never
+					 * necessary */
+
+    for (n = 0; n <= ITERATIONS; ++n) {
+	CloseColor *closenesses =
+	    (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
+	int i, c;
+
+	for (i = 0; i < ncols; ++i) {	/* build & sort closenesses table */
+#define COLOR_FACTOR       3
+#define BRIGHTNESS_FACTOR  1
+
+	    closenesses[i].cols_index = i;
+	    closenesses[i].closeness =
+		COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red)
+				+ abs((long) col->green - (long) cols[i].green)
+				+ abs((long) col->blue - (long) cols[i].blue))
+		+ BRIGHTNESS_FACTOR * abs(((long) col->red +
+					   (long) col->green +
+					   (long) col->blue)
+					   - ((long) cols[i].red +
+					      (long) cols[i].green +
+					      (long) cols[i].blue));
+	}
+	qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
+
+	i = 0;
+	c = closenesses[i].cols_index;
+	while ((long) cols[c].red >= (long) col->red - red_closeness &&
+	       (long) cols[c].red <= (long) col->red + red_closeness &&
+	       (long) cols[c].green >= (long) col->green - green_closeness &&
+	       (long) cols[c].green <= (long) col->green + green_closeness &&
+	       (long) cols[c].blue >= (long) col->blue - blue_closeness &&
+	       (long) cols[c].blue <= (long) col->blue + blue_closeness) {
+	    if (alloc_color) {
+		if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){
+		    if (n == ITERATIONS)
+			XUngrabServer(display);
+		    XpmFree(closenesses);
+		    *image_pixel = cols[c].pixel;
+		    *mask_pixel = 1;
+		    alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
+		    return (0);
+		} else {
+		    ++i;
+		    if (i == ncols)
+			break;
+		    c = closenesses[i].cols_index;
+		}
+	    } else {
+		if (n == ITERATIONS)
+		    XUngrabServer(display);
+		XpmFree(closenesses);
+		*image_pixel = cols[c].pixel;
+		*mask_pixel = 1;
+		return (0);
+	    }
+	}
+
+	/* Couldn't allocate _any_ of the close colors! */
+
+	if (n == ITERATIONS)
+	    XUngrabServer(display);
+	XpmFree(closenesses);
+
+	if (i == 0 || i == ncols)	/* no color close enough or cannot */
+	    return (1);			/* alloc any color (full of r/w's) */
+
+	if ((*allocColor)(display, colormap, NULL, col, closure)) {
+	    *image_pixel = col->pixel;
+	    *mask_pixel = 1;
+	    alloc_pixels[(*nalloc_pixels)++] = col->pixel;
+	    return (0);
+	} else {			/* colormap has probably changed, so
+					 * re-read... */
+	    if (n == ITERATIONS - 1)
+		XGrabServer(display);
+
+#if 0
+	    if (visual->class == DirectColor) {
+		/* TODO */
+	    } else
+#endif
+		XQueryColors(display, colormap, cols, ncols);
+	}
+    }
+    return (1);
+}
+
+#define USE_CLOSECOLOR attributes && \
+(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
+ || ((attributes->valuemask & XpmRGBCloseness) && \
+     (attributes->red_closeness != 0 \
+      || attributes->green_closeness != 0 \
+      || attributes->blue_closeness != 0)))
+
+#else
+    /* FOR_MSW part */
+    /* nothing to do here, the window system does it */
+#endif
+
+/*
+ * set the color pixel related to the given colorname,
+ * return 0 if success, 1 otherwise.
+ */
+
+static int
+SetColor(
+    Display		*display,
+    Colormap		 colormap,
+    Visual		*visual,
+    char		*colorname,
+    unsigned int	 color_index,
+    Pixel		*image_pixel,
+    Pixel		*mask_pixel,
+    unsigned int	*mask_pixel_index,
+    Pixel		*alloc_pixels,
+    unsigned int	*nalloc_pixels,
+    Pixel		*used_pixels,
+    unsigned int	*nused_pixels,
+    XpmAttributes	*attributes,
+    XColor		*cols,
+    int			 ncols,
+    XpmAllocColorFunc	 allocColor,
+    void		*closure)
+{
+    XColor xcolor;
+    int status;
+
+    if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
+	status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
+	if (status < 0)		/* parse color failed */
+	    return (1);
+
+	if (status == 0) {
+#ifndef FOR_MSW
+	    if (USE_CLOSECOLOR)
+		return (SetCloseColor(display, colormap, visual, &xcolor,
+				      image_pixel, mask_pixel,
+				      alloc_pixels, nalloc_pixels,
+				      attributes, cols, ncols,
+				      allocColor, closure));
+	    else
+#endif /* ndef FOR_MSW */
+		return (1);
+	} else
+	    alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
+	*image_pixel = xcolor.pixel;
+#ifndef FOR_MSW
+	*mask_pixel = 1;
+#else
+	*mask_pixel = RGB(0,0,0);
+#endif
+	used_pixels[(*nused_pixels)++] = xcolor.pixel;
+    } else {
+	*image_pixel = 0;
+#ifndef FOR_MSW
+	*mask_pixel = 0;
+#else
+  	*mask_pixel = RGB(255,255,255);
+#endif
+	/* store the color table index */
+	*mask_pixel_index = color_index;
+    }
+    return (0);
+}
+
+
+static int
+CreateColors(
+    Display		*display,
+    XpmAttributes	*attributes,
+    XpmColor		*colors,
+    unsigned int	 ncolors,
+    Pixel		*image_pixels,
+    Pixel		*mask_pixels,
+    unsigned int	*mask_pixel_index,
+    Pixel		*alloc_pixels,
+    unsigned int	*nalloc_pixels,
+    Pixel		*used_pixels,
+    unsigned int	*nused_pixels)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    XpmColorSymbol *colorsymbols = NULL;
+    unsigned int numsymbols;
+    XpmAllocColorFunc allocColor;
+    void *closure;
+
+    char *colorname;
+    unsigned int color, key;
+    Bool pixel_defined;
+    XpmColorSymbol *symbol = NULL;
+    char **defaults;
+    int ErrorStatus = XpmSuccess;
+    char *s;
+    int default_index;
+
+    XColor *cols = NULL;
+    unsigned int ncols = 0;
+
+    /*
+     * retrieve information from the XpmAttributes
+     */
+    if (attributes && attributes->valuemask & XpmColorSymbols) {
+	colorsymbols = attributes->colorsymbols;
+	numsymbols = attributes->numsymbols;
+    } else
+	numsymbols = 0;
+
+    if (attributes && attributes->valuemask & XpmVisual)
+	visual = attributes->visual;
+    else
+	visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+	colormap = attributes->colormap;
+    else
+	colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColorKey))
+	key = attributes->color_key;
+    else
+	key = xpmVisualType(visual);
+
+    if (attributes && (attributes->valuemask & XpmAllocColor))
+	allocColor = attributes->alloc_color;
+    else
+	allocColor = AllocColor;
+    if (attributes && (attributes->valuemask & XpmColorClosure))
+	closure = attributes->color_closure;
+    else
+	closure = NULL;
+
+#ifndef FOR_MSW
+    if (USE_CLOSECOLOR) {
+	/* originally from SetCloseColor */
+#if 0
+	if (visual->class == DirectColor) {
+
+	    /*
+	     * TODO: Implement close colors for DirectColor visuals. This is
+	     * difficult situation. Chances are that we will never get here,
+	     * because any machine that supports DirectColor will probably
+	     * also support TrueColor (and probably PseudoColor). Also,
+	     * DirectColor colormaps can be very large, so looking for close
+	     * colors may be too slow.
+	     */
+	} else {
+#endif
+	    unsigned int i;
+
+#ifndef AMIGA
+	    ncols = visual->map_entries;
+#else
+	    ncols = colormap->Count;
+#endif
+	    cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
+	    for (i = 0; i < ncols; ++i)
+		cols[i].pixel = i;
+	    XQueryColors(display, colormap, cols, ncols);
+#if 0
+	}
+#endif
+    }
+#endif /* ndef FOR_MSW */
+
+    switch (key) {
+    case XPM_MONO:
+	default_index = 2;
+	break;
+    case XPM_GRAY4:
+	default_index = 3;
+	break;
+    case XPM_GRAY:
+	default_index = 4;
+	break;
+    case XPM_COLOR:
+    default:
+	default_index = 5;
+	break;
+    }
+
+    for (color = 0; color < ncolors; color++, colors++,
+					 image_pixels++, mask_pixels++) {
+	colorname = NULL;
+	pixel_defined = False;
+	defaults = (char **) colors;
+
+	/*
+	 * look for a defined symbol
+	 */
+	if (numsymbols) {
+
+	    unsigned int n;
+
+	    s = defaults[1];
+	    for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
+		if (symbol->name && s && !strcmp(symbol->name, s))
+		    /* override name */
+		    break;
+		if (!symbol->name && symbol->value) {	/* override value */
+		    int def_index = default_index;
+
+		    while (defaults[def_index] == NULL)	/* find defined
+							 * colorname */
+			--def_index;
+		    if (def_index < 2) {/* nothing towards mono, so try
+					 * towards color */
+			def_index = default_index + 1;
+			while (def_index <= 5 && defaults[def_index] == NULL)
+			    ++def_index;
+		    }
+		    if (def_index >= 2 && defaults[def_index] != NULL &&
+			!xpmstrcasecmp(symbol->value, defaults[def_index]))
+			break;
+		}
+	    }
+	    if (n != numsymbols) {
+		if (symbol->name && symbol->value)
+		    colorname = symbol->value;
+		else
+		    pixel_defined = True;
+	    }
+	}
+	if (!pixel_defined) {		/* pixel not given as symbol value */
+
+	    unsigned int k;
+
+	    if (colorname) {		/* colorname given as symbol value */
+		if (!SetColor(display, colormap, visual, colorname, color,
+			      image_pixels, mask_pixels, mask_pixel_index,
+			      alloc_pixels, nalloc_pixels, used_pixels,
+			      nused_pixels, attributes, cols, ncols,
+			      allocColor, closure))
+		    pixel_defined = True;
+		else
+		    ErrorStatus = XpmColorError;
+	    }
+	    k = key;
+	    while (!pixel_defined && k > 1) {
+		if (defaults[k]) {
+		    if (!SetColor(display, colormap, visual, defaults[k],
+				  color, image_pixels, mask_pixels,
+				  mask_pixel_index, alloc_pixels,
+				  nalloc_pixels, used_pixels, nused_pixels,
+				  attributes, cols, ncols,
+				  allocColor, closure)) {
+			pixel_defined = True;
+			break;
+		    } else
+			ErrorStatus = XpmColorError;
+		}
+		k--;
+	    }
+	    k = key + 1;
+	    while (!pixel_defined && k < NKEYS + 1) {
+		if (defaults[k]) {
+		    if (!SetColor(display, colormap, visual, defaults[k],
+				  color, image_pixels, mask_pixels,
+				  mask_pixel_index, alloc_pixels,
+				  nalloc_pixels, used_pixels, nused_pixels,
+				  attributes, cols, ncols,
+				  allocColor, closure)) {
+			pixel_defined = True;
+			break;
+		    } else
+			ErrorStatus = XpmColorError;
+		}
+		k++;
+	    }
+	    if (!pixel_defined) {
+		if (cols)
+		    XpmFree(cols);
+		return (XpmColorFailed);
+	    }
+	} else {
+	    /* simply use the given pixel */
+	    *image_pixels = symbol->pixel;
+	    /* the following makes the mask to be built even if none
+	       is given a particular pixel */
+	    if (symbol->value
+		&& !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
+		*mask_pixels = 0;
+		*mask_pixel_index = color;
+	    } else
+		*mask_pixels = 1;
+	    used_pixels[(*nused_pixels)++] = *image_pixels;
+	}
+    }
+    if (cols)
+	XpmFree(cols);
+    return (ErrorStatus);
+}
+
+
+/* default FreeColors function, simply call XFreeColors */
+static int
+FreeColors(
+    Display	*display,
+    Colormap	 colormap,
+    Pixel	*pixels,
+    int		 n,
+    void	*closure)		/* not used */
+{
+    return XFreeColors(display, colormap, pixels, n, 0);
+}
+
+
+/* function call in case of error */
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto error; \
+} while(0)
+
+int
+XpmCreateImageFromXpmImage(
+    Display		 *display,
+    XpmImage		 *image,
+    XImage		**image_return,
+    XImage		**shapeimage_return,
+    XpmAttributes	 *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    unsigned int depth;
+    int bitmap_format;
+    XpmFreeColorsFunc freeColors;
+
+    /* variables to return */
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int mask_pixel_index = XpmUndefPixel;
+    int ErrorStatus;
+
+    /* calculation variables */
+    Pixel *image_pixels = NULL;
+    Pixel *mask_pixels = NULL;
+    Pixel *alloc_pixels = NULL;
+    Pixel *used_pixels = NULL;
+    unsigned int nalloc_pixels = 0;
+    unsigned int nused_pixels = 0;
+
+    /* initialize return values */
+    if (image_return)
+	*image_return = NULL;
+    if (shapeimage_return)
+	*shapeimage_return = NULL;
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmVisual))
+	visual = attributes->visual;
+    else
+	visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+	colormap = attributes->colormap;
+    else
+	colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmDepth))
+	depth = attributes->depth;
+    else
+	depth = XDefaultDepth(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmBitmapFormat))
+	bitmap_format = attributes->bitmap_format;
+    else
+	bitmap_format = ZPixmap;
+
+    if (attributes && (attributes->valuemask & XpmFreeColors))
+	freeColors = attributes->free_colors;
+    else
+	freeColors = FreeColors;
+
+    ErrorStatus = XpmSuccess;
+
+    if (image->ncolors >= UINT_MAX / sizeof(Pixel)) 
+	return (XpmNoMemory);
+
+    /* malloc pixels index tables */
+    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!image_pixels)
+	return (XpmNoMemory);
+
+    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!mask_pixels)
+	RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!alloc_pixels)
+	RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!used_pixels)
+	RETURN(XpmNoMemory);
+
+    /* get pixel colors, store them in index tables */
+    ErrorStatus = CreateColors(display, attributes, image->colorTable,
+			       image->ncolors, image_pixels, mask_pixels,
+			       &mask_pixel_index, alloc_pixels, &nalloc_pixels,
+			       used_pixels, &nused_pixels);
+
+    if (ErrorStatus != XpmSuccess
+	&& (ErrorStatus < 0 || (attributes
+				&& (attributes->valuemask & XpmExactColors)
+				&& attributes->exactColors)))
+	RETURN(ErrorStatus);
+
+    /* create the ximage */
+    if (image_return) {
+	ErrorStatus = CreateXImage(display, visual, depth,
+				   (depth == 1 ? bitmap_format : ZPixmap),
+				   image->width, image->height, &ximage);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+
+	/*
+	 * set the ximage data using optimized functions for ZPixmap
+	 */
+
+	if (ximage->bits_per_pixel == 8)
+	    PutImagePixels8(ximage, image->width, image->height,
+			    image->data, image_pixels);
+	else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
+		 (ximage->byte_order == ximage->bitmap_bit_order))
+	    PutImagePixels1(ximage, image->width, image->height,
+			    image->data, image_pixels);
+	else if (ximage->bits_per_pixel == 16)
+	    PutImagePixels16(ximage, image->width, image->height,
+			     image->data, image_pixels);
+	else if (ximage->bits_per_pixel == 32)
+	    PutImagePixels32(ximage, image->width, image->height,
+			     image->data, image_pixels);
+	else
+	    PutImagePixels(ximage, image->width, image->height,
+			   image->data, image_pixels);
+# else /* AMIGA */
+	APutImagePixels(ximage, image->width, image->height,
+			image->data, image_pixels);
+# endif
+#else  /* FOR_MSW */
+	MSWPutImagePixels(display, ximage, image->width, image->height,
+			  image->data, image_pixels);
+#endif
+    }
+    /* create the shape mask image */
+    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
+	ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
+				   image->width, image->height, &shapeimage);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+	PutImagePixels1(shapeimage, image->width, image->height,
+			image->data, mask_pixels);
+# else /* AMIGA */
+	APutImagePixels(shapeimage, image->width, image->height,
+			image->data, mask_pixels);
+# endif
+#else  /* FOR_MSW */
+	MSWPutImagePixels(display, shapeimage, image->width, image->height,
+			  image->data, mask_pixels);
+#endif
+
+    }
+    XpmFree(image_pixels);
+    XpmFree(mask_pixels);
+
+    /* if requested return used pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnPixels ||
+/* 3.2 backward compatibility code */
+	attributes->valuemask & XpmReturnInfos)) {
+/* end 3.2 bc */
+	attributes->pixels = used_pixels;
+	attributes->npixels = nused_pixels;
+	attributes->mask_pixel = mask_pixel_index;
+    } else
+	XpmFree(used_pixels);
+
+    /* if requested return alloc'ed pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
+	attributes->alloc_pixels = alloc_pixels;
+	attributes->nalloc_pixels = nalloc_pixels;
+    } else
+	XpmFree(alloc_pixels);
+
+    /* return created images */
+    if (image_return)
+	*image_return = ximage;
+    if (shapeimage_return)
+	*shapeimage_return = shapeimage;
+
+    return (ErrorStatus);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+    if (image_pixels)
+	XpmFree(image_pixels);
+    if (mask_pixels)
+	XpmFree(mask_pixels);
+    if (nalloc_pixels)
+	(*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
+    if (alloc_pixels)
+	XpmFree(alloc_pixels);
+    if (used_pixels)
+	XpmFree(used_pixels);
+
+    return (ErrorStatus);
+}
+
+
+/*
+ * Create an XImage with its data
+ */
+static int
+CreateXImage(
+    Display	 *display,
+    Visual	 *visual,
+    unsigned int  depth,
+    int		  format,
+    unsigned int  width,
+    unsigned int  height,
+    XImage	**image_return)
+{
+    int bitmap_pad;
+
+    /* first get bitmap_pad */
+    if (depth > 16)
+	bitmap_pad = 32;
+    else if (depth > 8)
+	bitmap_pad = 16;
+    else
+	bitmap_pad = 8;
+
+    /* then create the XImage with data = NULL and bytes_per_line = 0 */
+    *image_return = XCreateImage(display, visual, depth, format, 0, 0,
+				 width, height, bitmap_pad, 0);
+    if (!*image_return)
+	return (XpmNoMemory);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
+	XDestroyImage(*image_return);
+	return XpmNoMemory;
+    }
+    /* now that bytes_per_line must have been set properly alloc data */
+    if((*image_return)->bytes_per_line == 0 ||  height == 0)
+    	return XpmNoMemory;
+    (*image_return)->data =
+	(char *) XpmMalloc((*image_return)->bytes_per_line * height);
+
+    if (!(*image_return)->data) {
+	XDestroyImage(*image_return);
+	*image_return = NULL;
+	return (XpmNoMemory);
+    }
+#else
+    /* under FOR_MSW and AMIGA XCreateImage has done it all */
+#endif
+    return (XpmSuccess);
+}
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/*
+ * The functions below are written from X11R5 MIT's code (XImUtil.c)
+ *
+ * The idea is to have faster functions than the standard XPutPixel function
+ * to build the image data. Indeed we can speed up things by suppressing tests
+ * performed for each pixel. We do the same tests but at the image level.
+ * We also assume that we use only ZPixmap images with null offsets.
+ */
+
+LFUNC(_putbits, void, (register char *src, int dstoffset,
+		       register int numbits, register char *dst));
+
+LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
+
+static unsigned char Const _reverse_byte[0x100] = {
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static int
+_XReverse_Bytes(
+    register unsigned char	*bpt,
+    register unsigned int	 nb)
+{
+    do {
+	*bpt = _reverse_byte[*bpt];
+	bpt++;
+    } while (--nb > 0); /* is nb user-controled? */
+    return 0;
+}
+
+
+void
+xpm_xynormalizeimagebits(
+    register unsigned char	*bp,
+    register XImage		*img)
+{
+    register unsigned char c;
+
+    if (img->byte_order != img->bitmap_bit_order) {
+	switch (img->bitmap_unit) {
+
+	case 16:
+	    c = *bp;
+	    *bp = *(bp + 1);
+	    *(bp + 1) = c;
+	    break;
+
+	case 32:
+	    c = *(bp + 3);
+	    *(bp + 3) = *bp;
+	    *bp = c;
+	    c = *(bp + 2);
+	    *(bp + 2) = *(bp + 1);
+	    *(bp + 1) = c;
+	    break;
+	}
+    }
+    if (img->bitmap_bit_order == MSBFirst)
+	_XReverse_Bytes(bp, img->bitmap_unit >> 3);
+}
+
+void
+xpm_znormalizeimagebits(
+    register unsigned char	*bp,
+    register XImage		*img)
+{
+    register unsigned char c;
+
+    switch (img->bits_per_pixel) {
+
+    case 2:
+	_XReverse_Bytes(bp, 1);
+	break;
+
+    case 4:
+	*bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
+	break;
+
+    case 16:
+	c = *bp;
+	*bp = *(bp + 1);
+	*(bp + 1) = c;
+	break;
+
+    case 24:
+	c = *(bp + 2);
+	*(bp + 2) = *bp;
+	*bp = c;
+	break;
+
+    case 32:
+	c = *(bp + 3);
+	*(bp + 3) = *bp;
+	*bp = c;
+	c = *(bp + 2);
+	*(bp + 2) = *(bp + 1);
+	*(bp + 1) = c;
+	break;
+    }
+}
+
+static unsigned char Const _lomask[0x09] = {
+0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+static unsigned char Const _himask[0x09] = {
+0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+
+static void
+_putbits(
+    register char	*src,		/* address of source bit string */
+    int			 dstoffset,	/* bit offset into destination;
+					 * range is 0-31 */
+    register int	 numbits,	/* number of bits to copy to
+					 * destination */
+    register char	*dst)		/* address of destination bit string */
+{
+    register unsigned char chlo, chhi;
+    int hibits;
+
+    dst = dst + (dstoffset >> 3);
+    dstoffset = dstoffset & 7;
+    hibits = 8 - dstoffset;
+    chlo = *dst & _lomask[dstoffset];
+    for (;;) {
+	chhi = (*src << dstoffset) & _himask[dstoffset];
+	if (numbits <= hibits) {
+	    chhi = chhi & _lomask[dstoffset + numbits];
+	    *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
+	    break;
+	}
+	*dst = chhi | chlo;
+	dst++;
+	numbits = numbits - hibits;
+	chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
+	src++;
+	if (numbits <= dstoffset) {
+	    chlo = chlo & _lomask[numbits];
+	    *dst = (*dst & _himask[numbits]) | chlo;
+	    break;
+	}
+	numbits = numbits - dstoffset;
+    }
+}
+
+/*
+ * Default method to write pixels into a Z image data structure.
+ * The algorithm used is:
+ *
+ *	copy the destination bitmap_unit or Zpixel to temp
+ *	normalize temp if needed
+ *	copy the pixel bits into the temp
+ *	renormalize temp if needed
+ *	copy the temp back into the destination image data
+ */
+
+static void
+PutImagePixels(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    register char *src;
+    register char *dst;
+    register unsigned int *iptr;
+    register unsigned int x, y;
+    register char *data;
+    Pixel pixel, px;
+    int nbytes, depth, ibu, ibpp, i;
+
+    data = image->data;
+    iptr = pixelindex;
+    depth = image->depth;
+    if (depth == 1) {
+	ibu = image->bitmap_unit;
+	for (y = 0; y < height; y++) /* how can we trust height */
+	    for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
+		pixel = pixels[*iptr];
+		for (i = 0, px = pixel; i < sizeof(unsigned long);
+		     i++, px >>= 8)
+		    ((unsigned char *) &pixel)[i] = px;
+		src = &data[XYINDEX(x, y, image)];
+		dst = (char *) &px;
+		px = 0;
+		nbytes = ibu >> 3;
+		for (i = nbytes; --i >= 0;)
+		    *dst++ = *src++;
+		XYNORMALIZE(&px, image);
+		_putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
+		XYNORMALIZE(&px, image);
+		src = (char *) &px;
+		dst = &data[XYINDEX(x, y, image)];
+		for (i = nbytes; --i >= 0;)
+		    *dst++ = *src++;
+	    }
+    } else {
+	ibpp = image->bits_per_pixel;
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		pixel = pixels[*iptr];
+		if (depth == 4)
+		    pixel &= 0xf;
+		for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
+		     px >>= 8)
+		    ((unsigned char *) &pixel)[i] = px;
+		src = &data[ZINDEX(x, y, image)];
+		dst = (char *) &px;
+		px = 0;
+		nbytes = (ibpp + 7) >> 3;
+		for (i = nbytes; --i >= 0;)
+		    *dst++ = *src++;
+		ZNORMALIZE(&px, image);
+		_putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
+		ZNORMALIZE(&px, image);
+		src = (char *) &px;
+		dst = &data[ZINDEX(x, y, image)];
+		for (i = nbytes; --i >= 0;)
+		    *dst++ = *src++;
+	    }
+    }
+}
+
+/*
+ * write pixels into a 32-bits Z image data structure
+ */
+
+#if !defined(WORD64) && !defined(LONG64)
+/* this item is static but deterministic so let it slide; doesn't
+ * hurt re-entrancy of this library. Note if it is actually const then would
+ * be OK under rules of ANSI-C but probably not C++ which may not
+ * want to allocate space for it.
+ */
+static unsigned long byteorderpixel = MSBFirst << 24;
+
+#endif
+
+/*
+   WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
+   3.2e code - by default you get the speeded-up version.
+*/
+
+static void
+PutImagePixels32(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int y;
+    Pixel pixel;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+    unsigned char *addr;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		*((unsigned long *) addr) = pixels[*iptr];
+	    }
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		pixel = pixels[*iptr];
+		addr[0] = pixel >> 24;
+		addr[1] = pixel >> 16;
+		addr[2] = pixel >> 8;
+		addr[3] = pixel;
+	    }
+    else
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		pixel = pixels[*iptr];
+		addr[0] = pixel;
+		addr[1] = pixel >> 8;
+		addr[2] = pixel >> 16;
+		addr[3] = pixel >> 24;
+	    }
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    unsigned int bpl = image->bytes_per_line;
+    unsigned char *data_ptr, *max_data;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+	for (y = 0; y < height; y++) {
+	    data_ptr = data;
+	    max_data = data_ptr + (width << 2);
+
+	    while (data_ptr < max_data) {
+		*((unsigned long *) data_ptr) = pixels[*(iptr++)];
+		data_ptr += (1 << 2);
+	    }
+	    data += bpl;
+	}
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++) {
+	    data_ptr = data;
+	    max_data = data_ptr + (width << 2);
+
+	    while (data_ptr < max_data) {
+		pixel = pixels[*(iptr++)];
+
+		*data_ptr++ = pixel >> 24;
+		*data_ptr++ = pixel >> 16;
+		*data_ptr++ = pixel >> 8;
+		*data_ptr++ = pixel;
+
+	    }
+	    data += bpl;
+	}
+    else
+	for (y = 0; y < height; y++) {
+	    data_ptr = data;
+	    max_data = data_ptr + (width << 2);
+
+	    while (data_ptr < max_data) {
+		pixel = pixels[*(iptr++)];
+
+		*data_ptr++ = pixel;
+		*data_ptr++ = pixel >> 8;
+		*data_ptr++ = pixel >> 16;
+		*data_ptr++ = pixel >> 24;
+	    }
+	    data += bpl;
+	}
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 16-bits Z image data structure
+ */
+
+static void
+PutImagePixels16(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+    unsigned char *addr;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX16(x, y, image)];
+		addr[0] = pixels[*iptr] >> 8;
+		addr[1] = pixels[*iptr];
+	    }
+    else
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX16(x, y, image)];
+		addr[0] = pixels[*iptr];
+		addr[1] = pixels[*iptr] >> 8;
+	    }
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    Pixel pixel;
+
+    unsigned int bpl = image->bytes_per_line;
+    unsigned char *data_ptr, *max_data;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++) {
+	    data_ptr = data;
+	    max_data = data_ptr + (width << 1);
+
+	    while (data_ptr < max_data) {
+		pixel = pixels[*(iptr++)];
+
+		data_ptr[0] = pixel >> 8;
+		data_ptr[1] = pixel;
+
+		data_ptr += (1 << 1);
+	    }
+	    data += bpl;
+	}
+    else
+	for (y = 0; y < height; y++) {
+	    data_ptr = data;
+	    max_data = data_ptr + (width << 1);
+
+	    while (data_ptr < max_data) {
+		pixel = pixels[*(iptr++)];
+
+		data_ptr[0] = pixel;
+		data_ptr[1] = pixel >> 8;
+
+		data_ptr += (1 << 1);
+	    }
+	    data += bpl;
+	}
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 8-bits Z image data structure
+ */
+
+static void
+PutImagePixels8(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    char *data;
+    unsigned int *iptr;
+    unsigned int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+
+    data = image->data;
+    iptr = pixelindex;
+    for (y = 0; y < height; y++)
+	for (x = 0; x < width; x++, iptr++)
+	    data[ZINDEX8(x, y, image)] = pixels[*iptr];
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    unsigned int bpl = image->bytes_per_line;
+    char *data_ptr, *max_data;
+
+    data = image->data;
+    iptr = pixelindex;
+
+    for (y = 0; y < height; y++) {
+	data_ptr = data;
+	max_data = data_ptr + width;
+
+	while (data_ptr < max_data)
+	    *(data_ptr++) = pixels[*(iptr++)];
+
+	data += bpl;
+    }
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 1-bit depth image data structure and **offset null**
+ */
+
+static void
+PutImagePixels1(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    if (image->byte_order != image->bitmap_bit_order)
+	PutImagePixels(image, width, height, pixelindex, pixels);
+    else {
+	unsigned int *iptr;
+	unsigned int y;
+	char *data;
+
+#ifdef WITHOUT_SPEEDUPS
+
+	unsigned int x;
+
+	data = image->data;
+	iptr = pixelindex;
+	if (image->bitmap_bit_order == MSBFirst)
+	    for (y = 0; y < height; y++)
+		for (x = 0; x < width; x++, iptr++) {
+		    if (pixels[*iptr] & 1)
+			data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
+		    else
+			data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
+		}
+	else
+	    for (y = 0; y < height; y++)
+		for (x = 0; x < width; x++, iptr++) {
+		    if (pixels[*iptr] & 1)
+			data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
+		    else
+			data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
+		}
+
+#else  /* WITHOUT_SPEEDUPS */
+
+	char value;
+	char *data_ptr, *max_data;
+	int bpl = image->bytes_per_line;
+	int diff, count;
+
+	data = image->data;
+	iptr = pixelindex;
+
+	diff = width & 7;
+	width >>= 3;
+
+	if (image->bitmap_bit_order == MSBFirst)
+	    for (y = 0; y < height; y++) {
+		data_ptr = data;
+		max_data = data_ptr + width;
+		while (data_ptr < max_data) {
+		    value = 0;
+
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+		    value = (value << 1) | (pixels[*(iptr++)] & 1);
+
+		    *(data_ptr++) = value;
+		}
+		if (diff) {
+		    value = 0;
+		    for (count = 0; count < diff; count++) {
+			if (pixels[*(iptr++)] & 1)
+			    value |= (0x80 >> count);
+		    }
+		    *(data_ptr) = value;
+		}
+		data += bpl;
+	    }
+	else
+	    for (y = 0; y < height; y++) {
+		data_ptr = data;
+		max_data = data_ptr + width;
+		while (data_ptr < max_data) {
+		    value = 0;
+		    iptr += 8;
+
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+		    value = (value << 1) | (pixels[*(--iptr)] & 1);
+
+		    iptr += 8;
+		    *(data_ptr++) = value;
+		}
+		if (diff) {
+		    value = 0;
+		    for (count = 0; count < diff; count++) {
+			if (pixels[*(iptr++)] & 1)
+			    value |= (1 << count);
+		    }
+		    *(data_ptr) = value;
+		}
+		data += bpl;
+	    }
+
+#endif /* WITHOUT_SPEEDUPS */
+    }
+}
+
+int
+XpmCreatePixmapFromXpmImage(
+    Display		*display,
+    Drawable		 d,
+    XpmImage		*image,
+    Pixmap		*pixmap_return,
+    Pixmap		*shapemask_return,
+    XpmAttributes	*attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+	*pixmap_return = 0;
+    if (shapemask_return)
+	*shapemask_return = 0;
+
+    /* create the ximages */
+    ErrorStatus = XpmCreateImageFromXpmImage(display, image,
+					     (pixmap_return ? &ximage : NULL),
+					     (shapemask_return ?
+					      &shapeimage : NULL),
+					     attributes);
+    if (ErrorStatus < 0)
+	return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+	xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+	XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+	xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+	XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
+
+# else /* AMIGA */
+
+static void
+APutImagePixels (
+    XImage        *image,
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int  *pixelindex,
+    Pixel         *pixels)
+{
+    unsigned int   *data = pixelindex;
+    unsigned int    x, y;
+    unsigned char  *array;
+    XImage         *tmp_img;
+    BOOL            success = FALSE;
+    
+    array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array));
+    if (array != NULL)
+    {
+	tmp_img = AllocXImage ((((width+15)>>4)<<4), 1,
+			       image->rp->BitMap->Depth);
+	if (tmp_img != NULL)
+	{
+	    for (y = 0; y < height; ++y)
+	    {
+		for (x = 0; x < width; ++x)
+		    array[x] = pixels[*(data++)];
+		WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp);
+	    }
+	    FreeXImage (tmp_img);
+	    success = TRUE;
+	}
+	XpmFree (array);
+    }
+    
+    if (!success)
+    {
+	for (y = 0; y < height; ++y)
+	    for (x = 0; x < width; ++x)
+		XPutPixel (image, x, y, pixels[*(data++)]);
+    }
+}
+
+# endif/* AMIGA */
+#else  /* FOR_MSW part follows */
+static void
+MSWPutImagePixels(
+    Display		*dc,
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	*pixelindex,
+    Pixel		*pixels)
+{
+    unsigned int *data = pixelindex;
+    unsigned int x, y;
+    HBITMAP obm;
+
+    obm = SelectObject(*dc, image->bitmap);
+    for (y = 0; y < height; y++) {
+	for (x = 0; x < width; x++) {
+	    SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
+	}
+    }
+    SelectObject(*dc, obm);
+}
+
+#endif /* FOR_MSW */
+
+
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+
+static int
+PutPixel1(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    register char *src;
+    register char *dst;
+    register int i;
+    Pixel px;
+    int nbytes;
+
+    if(x < 0 || y < 0)
+    	return 0;
+
+    for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
+	((unsigned char *)&pixel)[i] = px;
+    src = &ximage->data[XYINDEX(x, y, ximage)];
+    dst = (char *)&px;
+    px = 0;
+    nbytes = ximage->bitmap_unit >> 3;
+    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
+    XYNORMALIZE(&px, ximage);
+    i = ((x + ximage->xoffset) % ximage->bitmap_unit);
+    _putbits ((char *)&pixel, i, 1, (char *)&px);
+    XYNORMALIZE(&px, ximage);
+    src = (char *) &px;
+    dst = &ximage->data[XYINDEX(x, y, ximage)];
+    for (i = nbytes; --i >= 0; )
+	*dst++ = *src++;
+
+    return 1;
+}
+
+static int
+PutPixel(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    register char *src;
+    register char *dst;
+    register int i;
+    Pixel px;
+    unsigned int nbytes, ibpp;
+
+    if(x < 0 || y < 0)
+    	return 0;
+
+    ibpp = ximage->bits_per_pixel;
+    if (ximage->depth == 4)
+	pixel &= 0xf;
+    for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
+	((unsigned char *) &pixel)[i] = px;
+    src = &ximage->data[ZINDEX(x, y, ximage)];
+    dst = (char *) &px;
+    px = 0;
+    nbytes = (ibpp + 7) >> 3;
+    for (i = nbytes; --i >= 0;)
+	*dst++ = *src++;
+    ZNORMALIZE(&px, ximage);
+    _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
+    ZNORMALIZE(&px, ximage);
+    src = (char *) &px;
+    dst = &ximage->data[ZINDEX(x, y, ximage)];
+    for (i = nbytes; --i >= 0;)
+	*dst++ = *src++;
+
+    return 1;
+}
+
+#if !defined(WORD64) && !defined(LONG64)
+static int
+PutPixel32(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+    	return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    *((unsigned long *)addr) = pixel;
+    return 1;
+}
+#endif
+
+static int
+PutPixel32MSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+    	return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    addr[0] = pixel >> 24;
+    addr[1] = pixel >> 16;
+    addr[2] = pixel >> 8;
+    addr[3] = pixel;
+    return 1;
+}
+
+static int
+PutPixel32LSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+    	return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    addr[3] = pixel >> 24;
+    addr[2] = pixel >> 16;
+    addr[1] = pixel >> 8;
+    addr[0] = pixel;
+    return 1;
+}
+
+static int
+PutPixel16MSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    unsigned char *addr;
+    
+    if(x < 0 || y < 0)
+    	return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+    addr[0] = pixel >> 8;
+    addr[1] = pixel;
+    return 1;
+}
+
+static int
+PutPixel16LSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    unsigned char *addr;
+    
+    if(x < 0 || y < 0)
+    	return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+    addr[1] = pixel >> 8;
+    addr[0] = pixel;
+    return 1;
+}
+
+static int
+PutPixel8(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    if(x < 0 || y < 0)
+    	return 0;
+
+    ximage->data[ZINDEX8(x, y, ximage)] = pixel;
+    return 1;
+}
+
+static int
+PutPixel1MSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    if(x < 0 || y < 0)
+    	return 0;
+
+    if (pixel & 1)
+	ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
+    else
+	ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
+    return 1;
+}
+
+static int
+PutPixel1LSB(
+    register XImage	*ximage,
+    int			 x,
+    int			 y,
+    unsigned long	 pixel)
+{
+    if(x < 0 || y < 0)
+    	return 0;
+
+    if (pixel & 1)
+	ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
+    else
+	ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
+    return 1;
+}
+
+#endif /* not FOR_MSW && not AMIGA */
+
+/*
+ * This function parses an Xpm file or data and directly create an XImage
+ */
+int
+xpmParseDataAndCreate(
+    Display		 *display,
+    xpmData		 *data,
+    XImage		**image_return,
+    XImage		**shapeimage_return,
+    XpmImage		 *image,
+    XpmInfo		 *info,
+    XpmAttributes	 *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    unsigned int depth;
+    int bitmap_format;
+    XpmFreeColorsFunc freeColors;
+
+    /* variables to return */
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int mask_pixel_index = XpmUndefPixel;
+
+    /* calculation variables */
+    Pixel *image_pixels = NULL;
+    Pixel *mask_pixels = NULL;
+    Pixel *alloc_pixels = NULL;
+    Pixel *used_pixels = NULL;
+    unsigned int nalloc_pixels = 0;
+    unsigned int nused_pixels = 0;
+    unsigned int width, height, ncolors, cpp;
+    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
+    XpmColor *colorTable = NULL;
+    char *hints_cmt = NULL;
+    char *colors_cmt = NULL;
+    char *pixels_cmt = NULL;
+
+    unsigned int cmts;
+    int ErrorStatus;
+    xpmHashTable hashtable;
+
+
+    /* initialize return values */
+    if (image_return)
+	*image_return = NULL;
+    if (shapeimage_return)
+	*shapeimage_return = NULL;
+
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmVisual))
+	visual = attributes->visual;
+    else
+	visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+	colormap = attributes->colormap;
+    else
+	colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmDepth))
+	depth = attributes->depth;
+    else
+	depth = XDefaultDepth(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmBitmapFormat))
+	bitmap_format = attributes->bitmap_format;
+    else
+	bitmap_format = ZPixmap;
+
+    if (attributes && (attributes->valuemask & XpmFreeColors))
+	freeColors = attributes->free_colors;
+    else
+	freeColors = FreeColors;
+
+    cmts = info && (info->valuemask & XpmReturnComments);
+
+    /*
+     * parse the header
+     */
+    ErrorStatus = xpmParseHeader(data);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /*
+     * read values
+     */
+    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
+				 &x_hotspot, &y_hotspot, &hotspot,
+				 &extensions);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /*
+     * store the hints comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &hints_cmt);
+
+    /*
+     * init the hashtable
+     */
+    if (USE_HASHTABLE) {
+	ErrorStatus = xpmHashTableInit(&hashtable);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+    }
+
+    /*
+     * read colors
+     */
+    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+
+    /*
+     * store the colors comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &colors_cmt);
+
+    /* malloc pixels index tables */
+    if (ncolors >= UINT_MAX / sizeof(Pixel)) 
+	RETURN(XpmNoMemory);
+
+    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!image_pixels)
+	RETURN(XpmNoMemory);
+
+    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!mask_pixels)
+	RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!alloc_pixels)
+	RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!used_pixels)
+	RETURN(XpmNoMemory);
+
+    /* get pixel colors, store them in index tables */
+    ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
+			       image_pixels, mask_pixels, &mask_pixel_index,
+			       alloc_pixels, &nalloc_pixels, used_pixels,
+			       &nused_pixels);
+
+    if (ErrorStatus != XpmSuccess
+	&& (ErrorStatus < 0 || (attributes
+				&& (attributes->valuemask & XpmExactColors)
+				&& attributes->exactColors)))
+	RETURN(ErrorStatus);
+
+    /* now create the ximage */
+    if (image_return) {
+	ErrorStatus = CreateXImage(display, visual, depth,
+				   (depth == 1 ? bitmap_format : ZPixmap),
+				   width, height, &ximage);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+
+	/*
+	 * set the XImage pointer function, to be used with XPutPixel,
+	 * to an internal optimized function
+	 */
+
+	if (ximage->bits_per_pixel == 8)
+	    ximage->f.put_pixel = PutPixel8;
+	else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
+		 (ximage->byte_order == ximage->bitmap_bit_order))
+	    if (ximage->bitmap_bit_order == MSBFirst)
+		ximage->f.put_pixel = PutPixel1MSB;
+	    else
+		ximage->f.put_pixel = PutPixel1LSB;
+	else if (ximage->bits_per_pixel == 16)
+	    if (ximage->bitmap_bit_order == MSBFirst)
+		ximage->f.put_pixel = PutPixel16MSB;
+	    else
+		ximage->f.put_pixel = PutPixel16LSB;
+	else if (ximage->bits_per_pixel == 32)
+#if !defined(WORD64) && !defined(LONG64)
+	    if (*((char *)&byteorderpixel) == ximage->byte_order)
+		ximage->f.put_pixel = PutPixel32;
+	    else
+#endif
+		if (ximage->bitmap_bit_order == MSBFirst)
+		    ximage->f.put_pixel = PutPixel32MSB;
+		else
+		    ximage->f.put_pixel = PutPixel32LSB;
+	else if ((ximage->bits_per_pixel | ximage->depth) == 1)
+	    ximage->f.put_pixel = PutPixel1;
+	else
+	    ximage->f.put_pixel = PutPixel;
+#endif /* not FOR_MSW && not AMIGA */
+    }
+
+    /* create the shape mask image */
+    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
+	ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
+				   width, height, &shapeimage);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+	if (shapeimage->bitmap_bit_order == MSBFirst)
+	    shapeimage->f.put_pixel = PutPixel1MSB;
+	else
+	    shapeimage->f.put_pixel = PutPixel1LSB;
+#endif
+    }
+
+    /*
+     * read pixels and put them in the XImage
+     */
+    ErrorStatus = ParseAndPutPixels(
+#ifdef FOR_MSW
+				    display,
+#endif
+				    data, width, height, ncolors, cpp,
+				    colorTable, &hashtable,
+				    ximage, image_pixels,
+				    shapeimage, mask_pixels);
+    XpmFree(image_pixels);
+    image_pixels = NULL;
+    XpmFree(mask_pixels);
+    mask_pixels = NULL;
+
+    /*
+     * free the hastable
+     */
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+    else if (USE_HASHTABLE)
+	xpmHashTableFree(&hashtable);
+
+    /*
+     * store the pixels comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &pixels_cmt);
+
+    /*
+     * parse extensions
+     */
+    if (info && (info->valuemask & XpmReturnExtensions)) {
+	if (extensions) {
+	    ErrorStatus = xpmParseExtensions(data, &info->extensions,
+					     &info->nextensions);
+	    if (ErrorStatus != XpmSuccess)
+		RETURN(ErrorStatus);
+	} else {
+	    info->extensions = NULL;
+	    info->nextensions = 0;
+	}
+    }
+    /*
+     * store found informations in the XpmImage structure
+     */
+    image->width = width;
+    image->height = height;
+    image->cpp = cpp;
+    image->ncolors = ncolors;
+    image->colorTable = colorTable;
+    image->data = NULL;
+
+    if (info) {
+	if (cmts) {
+	    info->hints_cmt = hints_cmt;
+	    info->colors_cmt = colors_cmt;
+	    info->pixels_cmt = pixels_cmt;
+	}
+	if (hotspot) {
+	    info->x_hotspot = x_hotspot;
+	    info->y_hotspot = y_hotspot;
+	    info->valuemask |= XpmHotspot;
+	}
+    }
+    /* if requested return used pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnPixels ||
+/* 3.2 backward compatibility code */
+	attributes->valuemask & XpmReturnInfos)) {
+/* end 3.2 bc */
+	attributes->pixels = used_pixels;
+	attributes->npixels = nused_pixels;
+	attributes->mask_pixel = mask_pixel_index;
+    } else
+	XpmFree(used_pixels);
+
+    /* if requested return alloc'ed pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
+	attributes->alloc_pixels = alloc_pixels;
+	attributes->nalloc_pixels = nalloc_pixels;
+    } else
+	XpmFree(alloc_pixels);
+
+    /* return created images */
+    if (image_return)
+	*image_return = ximage;
+    if (shapeimage_return)
+	*shapeimage_return = shapeimage;
+
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (USE_HASHTABLE)
+	xpmHashTableFree(&hashtable);
+    if (colorTable)
+	xpmFreeColorTable(colorTable, ncolors);
+    if (hints_cmt)
+	XpmFree(hints_cmt);
+    if (colors_cmt)
+	XpmFree(colors_cmt);
+    if (pixels_cmt)
+	XpmFree(pixels_cmt);
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+    if (image_pixels)
+	XpmFree(image_pixels);
+    if (mask_pixels)
+	XpmFree(mask_pixels);
+    if (nalloc_pixels)
+	(*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
+    if (alloc_pixels)
+	XpmFree(alloc_pixels);
+    if (used_pixels)
+	XpmFree(used_pixels);
+
+    return (ErrorStatus);
+}
+
+static int
+ParseAndPutPixels(
+#ifdef FOR_MSW
+    Display		*dc,
+#endif
+    xpmData		*data,
+    unsigned int	 width,
+    unsigned int	 height,
+    unsigned int	 ncolors,
+    unsigned int	 cpp,
+    XpmColor		*colorTable,
+    xpmHashTable	*hashtable,
+    XImage		*image,
+    Pixel		*image_pixels,
+    XImage		*shapeimage,
+    Pixel		*shape_pixels)
+{
+    unsigned int a, x, y;
+
+    switch (cpp) {
+
+    case (1):				/* Optimize for single character
+					 * colors */
+	{
+	    unsigned short colidx[256];
+#ifdef FOR_MSW
+	    HDC shapedc;
+	    HBITMAP obm, sobm;
+
+	    if ( shapeimage ) {
+		shapedc = CreateCompatibleDC(*dc);
+		sobm = SelectObject(shapedc, shapeimage->bitmap);
+	    } else {
+	        shapedc = NULL;
+	    }
+	    obm = SelectObject(*dc, image->bitmap);
+#endif
+	    if (ncolors > 256)
+		return (XpmFileInvalid);
+
+	    bzero((char *)colidx, 256 * sizeof(short));
+	    for (a = 0; a < ncolors; a++)
+		colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
+
+	    for (y = 0; y < height; y++) {
+		xpmNextString(data);
+		for (x = 0; x < width; x++) {
+		    int c = xpmGetC(data);
+
+		    if (c > 0 && c < 256 && colidx[c] != 0) {
+#ifndef FOR_MSW
+			XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
+			if (shapeimage)
+			    XPutPixel(shapeimage, x, y,
+				      shape_pixels[colidx[c] - 1]);
+#else
+			SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
+			if (shapedc) {
+			    SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
+			}
+#endif
+		    } else
+			return (XpmFileInvalid);
+		}
+	    }
+#ifdef FOR_MSW
+	    if ( shapedc ) {
+	        SelectObject(shapedc, sobm);
+		DeleteDC(shapedc);
+	    }
+	    SelectObject(*dc, obm);
+#endif
+	}
+	break;
+
+    case (2):				/* Optimize for double character
+					 * colors */
+	{
+
+/* free all allocated pointers at all exits */
+#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
+if (cidx[f]) XpmFree(cidx[f]);}
+
+	    /* array of pointers malloced by need */
+	    unsigned short *cidx[256];
+	    unsigned int char1;
+
+	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+	    for (a = 0; a < ncolors; a++) {
+		char1 = (unsigned char) colorTable[a].string[0];
+		if (cidx[char1] == NULL) { /* get new memory */
+		    cidx[char1] = (unsigned short *)
+			XpmCalloc(256, sizeof(unsigned short));
+		    if (cidx[char1] == NULL) { /* new block failed */
+			FREE_CIDX;
+			return (XpmNoMemory);
+		    }
+		}
+		cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
+	    }
+
+	    for (y = 0; y < height; y++) {
+		xpmNextString(data);
+		for (x = 0; x < width; x++) {
+		    int cc1 = xpmGetC(data);
+		    if (cc1 > 0 && cc1 < 256) {
+			int cc2 = xpmGetC(data);
+			if (cc2 > 0 && cc2 < 256 &&
+			    cidx[cc1] && cidx[cc1][cc2] != 0) {
+#ifndef FOR_MSW
+			    XPutPixel(image, x, y,
+				      image_pixels[cidx[cc1][cc2] - 1]);
+			    if (shapeimage)
+				XPutPixel(shapeimage, x, y,
+					  shape_pixels[cidx[cc1][cc2] - 1]);
+#else
+			SelectObject(*dc, image->bitmap);
+			SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
+			if (shapeimage) {
+			    SelectObject(*dc, shapeimage->bitmap);
+			    SetPixel(*dc, x, y,
+				     shape_pixels[cidx[cc1][cc2] - 1]);
+			}
+#endif
+			} else {
+			    FREE_CIDX;
+			    return (XpmFileInvalid);
+			}
+		    } else {
+			FREE_CIDX;
+			return (XpmFileInvalid);
+		    }
+		}
+	    }
+	    FREE_CIDX;
+	}
+	break;
+
+    default:				/* Non-optimized case of long color
+					 * names */
+	{
+	    char *s;
+	    char buf[BUFSIZ];
+
+	    if (cpp >= sizeof(buf))
+		return (XpmFileInvalid);
+
+	    buf[cpp] = '\0';
+	    if (USE_HASHTABLE) {
+		xpmHashAtom *slot;
+
+		for (y = 0; y < height; y++) {
+		    xpmNextString(data);
+		    for (x = 0; x < width; x++) {
+			for (a = 0, s = buf; a < cpp; a++, s++)
+			    *s = xpmGetC(data);
+			slot = xpmHashSlot(hashtable, buf);
+			if (!*slot)	/* no color matches */
+			    return (XpmFileInvalid);
+#ifndef FOR_MSW
+			XPutPixel(image, x, y,
+				  image_pixels[HashColorIndex(slot)]);
+			if (shapeimage)
+			    XPutPixel(shapeimage, x, y,
+				      shape_pixels[HashColorIndex(slot)]);
+#else
+			SelectObject(*dc, image->bitmap);
+			SetPixel(*dc, x, y,
+				 image_pixels[HashColorIndex(slot)]);
+			if (shapeimage) {
+			    SelectObject(*dc, shapeimage->bitmap);
+			    SetPixel(*dc, x, y,
+				     shape_pixels[HashColorIndex(slot)]);
+			}
+#endif
+		    }
+		}
+	    } else {
+		for (y = 0; y < height; y++) {
+		    xpmNextString(data);
+		    for (x = 0; x < width; x++) {
+			for (a = 0, s = buf; a < cpp; a++, s++)
+			    *s = xpmGetC(data);
+			for (a = 0; a < ncolors; a++)
+			    if (!strcmp(colorTable[a].string, buf))
+				break;
+			if (a == ncolors)	/* no color matches */
+			    return (XpmFileInvalid);
+#ifndef FOR_MSW
+			XPutPixel(image, x, y, image_pixels[a]);
+			if (shapeimage)
+			    XPutPixel(shapeimage, x, y, shape_pixels[a]);
+#else
+			SelectObject(*dc, image->bitmap);
+			SetPixel(*dc, x, y, image_pixels[a]);
+			if (shapeimage) {
+			    SelectObject(*dc, shapeimage->bitmap);
+			    SetPixel(*dc, x, y, shape_pixels[a]);
+			}
+#endif
+		    }
+		}
+	    }
+	}
+	break;
+    }
+    return (XpmSuccess);
+}
diff --git a/libXpm/src/data.c b/libXpm/src/data.c
new file mode 100644
index 000000000..94caa61bf
--- /dev/null
+++ b/libXpm/src/data.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* data.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  IO utilities                                                               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/data.c,v 1.3 2001/10/28 03:32:10 tsi Exp $ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifndef CXPMPROG
+#if 0
+/* Official version number */
+static char *RCS_Version = "$XpmVersion: 3.4k $";
+
+/* Internal version number */
+static char *RCS_Id = "Id: xpm.shar,v 3.71 1998/03/19 19:47:14 lehors Exp $";
+#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#endif
+#include <ctype.h>
+
+#ifndef CXPMPROG
+#define Getc(data, file) getc(file)
+#define Ungetc(data, c, file) ungetc(c, file)
+#endif
+
+static int
+ParseComment(xpmData *data)
+{
+    if (data->type == XPMBUFFER) {
+	register char c;
+	register unsigned int n = 0;
+	unsigned int notend;
+	char *s, *s2;
+
+	s = data->Comment;
+	*s = data->Bcmt[0];
+
+	/* skip the string beginning comment */
+	s2 = data->Bcmt;
+	do {
+	    c = *data->cptr++;
+	    *++s = c;
+	    n++;
+	    s2++;
+	} while (c == *s2 && *s2 != '\0' && c);
+
+	if (*s2 != '\0') {
+	    /* this wasn't the beginning of a comment */
+	    data->cptr -= n;
+	    return 0;
+	}
+	/* store comment */
+	data->Comment[0] = *s;
+	s = data->Comment;
+	notend = 1;
+	n = 0;
+	while (notend) {
+	    s2 = data->Ecmt;
+	    while (*s != *s2 && c) {
+		c = *data->cptr++;
+		if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+		    s = data->Comment;
+		    n = 0;
+		}
+		*++s = c;
+		n++;
+	    }
+	    data->CommentLength = n;
+	    do {
+		c = *data->cptr++;
+		if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+		    s = data->Comment;
+		    n = 0;
+		}
+		*++s = c;
+		n++;
+		s2++;
+	    } while (c == *s2 && *s2 != '\0' && c);
+	    if (*s2 == '\0') {
+		/* this is the end of the comment */
+		notend = 0;
+		data->cptr--;
+	    }
+	}
+	return 0;
+    } else {
+	FILE *file = data->stream.file;
+	register int c;
+	register unsigned int n = 0, a;
+	unsigned int notend;
+	char *s, *s2;
+
+	s = data->Comment;
+	*s = data->Bcmt[0];
+
+	/* skip the string beginning comment */
+	s2 = data->Bcmt;
+	do {
+	    c = Getc(data, file);
+	    *++s = c;
+	    n++;
+	    s2++;
+	} while (c == *s2 && *s2 != '\0' && c != EOF);
+
+	if (*s2 != '\0') {
+	    /* this wasn't the beginning of a comment */
+	    /* put characters back in the order that we got them */
+	    for (a = n; a > 0; a--, s--)
+		Ungetc(data, *s, file);
+	    return 0;
+	}
+	/* store comment */
+	data->Comment[0] = *s;
+	s = data->Comment;
+	notend = 1;
+	n = 0;
+	while (notend) {
+	    s2 = data->Ecmt;
+	    while (*s != *s2 && c != EOF) {
+		c = Getc(data, file);
+		if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+		    s = data->Comment;
+		    n = 0;
+		}
+		*++s = c;
+		n++;
+	    }
+	    data->CommentLength = n;
+	    do {
+		c = Getc(data, file);
+		if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+		    s = data->Comment;
+		    n = 0;
+		}
+		*++s = c;
+		n++;
+		s2++;
+	    } while (c == *s2 && *s2 != '\0' && c != EOF);
+	    if (*s2 == '\0') {
+		/* this is the end of the comment */
+		notend = 0;
+		Ungetc(data, *s, file);
+	    }
+	}
+	return 0;
+    }
+}
+
+/*
+ * skip to the end of the current string and the beginning of the next one
+ */
+int
+xpmNextString(xpmData *data)
+{
+    if (!data->type)
+	data->cptr = (data->stream.data)[++data->line];
+    else if (data->type == XPMBUFFER) {
+	register char c;
+
+	/* get to the end of the current string */
+	if (data->Eos)
+	    while ((c = *data->cptr++) && c != data->Eos);
+
+	/*
+	 * then get to the beginning of the next string looking for possible
+	 * comment
+	 */
+	if (data->Bos) {
+	    while ((c = *data->cptr++) && c != data->Bos)
+		if (data->Bcmt && c == data->Bcmt[0])
+		    ParseComment(data);
+	} else if (data->Bcmt) {	/* XPM2 natural */
+	    while ((c = *data->cptr++) == data->Bcmt[0])
+		ParseComment(data);
+	    data->cptr--;
+	}
+    } else {
+	register int c;
+	FILE *file = data->stream.file;
+
+	/* get to the end of the current string */
+	if (data->Eos)
+	    while ((c = Getc(data, file)) != data->Eos && c != EOF);
+
+	/*
+	 * then get to the beginning of the next string looking for possible
+	 * comment
+	 */
+	if (data->Bos) {
+	    while ((c = Getc(data, file)) != data->Bos && c != EOF)
+		if (data->Bcmt && c == data->Bcmt[0])
+		    ParseComment(data);
+
+	} else if (data->Bcmt) {	/* XPM2 natural */
+	    while ((c = Getc(data, file)) == data->Bcmt[0])
+		ParseComment(data);
+	    Ungetc(data, c, file);
+	}
+    }
+    return 0;
+}
+
+
+/*
+ * skip whitespace and return the following word
+ */
+unsigned int
+xpmNextWord(
+    xpmData		*data,
+    char		*buf,
+    unsigned int	 buflen)
+{
+    register unsigned int n = 0;
+    int c;
+
+    if (!data->type || data->type == XPMBUFFER) {
+	while (isspace(c = *data->cptr) && c != data->Eos)
+	    data->cptr++;
+	do {
+	    c = *data->cptr++;
+	    *buf++ = c;
+	    n++;
+	} while (!isspace(c) && c != data->Eos && n < buflen);
+	n--;
+	data->cptr--;
+    } else {
+	FILE *file = data->stream.file;
+
+	while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos);
+	while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) {
+	    *buf++ = c;
+	    n++;
+	    c = Getc(data, file);
+	}
+	Ungetc(data, c, file);
+    }
+    return (n); /* this returns bytes read + 1 */
+}
+
+/*
+ * skip whitespace and compute the following unsigned int,
+ * returns 1 if one is found and 0 if not
+ */
+int
+xpmNextUI(
+    xpmData		*data,
+    unsigned int	*ui_return)
+{
+    char buf[BUFSIZ];
+    int l;
+
+    l = xpmNextWord(data, buf, BUFSIZ);
+    return xpmatoui(buf, l, ui_return);
+}
+
+/*
+ * return end of string - WARNING: malloc!
+ */
+int
+xpmGetString(
+    xpmData		 *data,
+    char		**sptr,
+    unsigned int	 *l)
+{
+    unsigned int i, n = 0;
+    int c;
+    char *p = NULL, *q, buf[BUFSIZ];
+
+    if (!data->type || data->type == XPMBUFFER) {
+	if (data->cptr) {
+	    char *start = data->cptr;
+	    while ((c = *data->cptr) && c != data->Eos)
+		data->cptr++;
+	    n = data->cptr - start + 1;
+	    p = (char *) XpmMalloc(n);
+	    if (!p)
+		return (XpmNoMemory);
+	    strncpy(p, start, n);
+	    if (data->type)		/* XPMBUFFER */
+		p[n - 1] = '\0';
+	}
+    } else {
+	FILE *file = data->stream.file;
+
+	if ((c = Getc(data, file)) == EOF)
+	    return (XpmFileInvalid);
+
+	i = 0;
+	q = buf;
+	p = (char *) XpmMalloc(1);
+	while (c != data->Eos && c != EOF) {
+	    if (i == BUFSIZ) {
+		/* get to the end of the buffer */
+		/* malloc needed memory */
+		q = (char *) XpmRealloc(p, n + i);
+		if (!q) {
+		    XpmFree(p);
+		    return (XpmNoMemory);
+		}
+		p = q;
+		q += n;
+		/* and copy what we already have */
+		strncpy(q, buf, i);
+		n += i;
+		i = 0;
+		q = buf;
+	    }
+	    *q++ = c;
+	    i++;
+	    c = Getc(data, file);
+	}
+	if (c == EOF) {
+	    XpmFree(p);
+	    return (XpmFileInvalid);
+	}
+	if (n + i != 0) {
+	    /* malloc needed memory */
+	    q = (char *) XpmRealloc(p, n + i + 1);
+	    if (!q) {
+		XpmFree(p);
+		return (XpmNoMemory);
+	    }
+	    p = q;
+	    q += n;
+	    /* and copy the buffer */
+	    strncpy(q, buf, i);
+	    n += i;
+	    p[n++] = '\0';
+	} else {
+	    *p = '\0';
+	    n = 1;
+	}
+	Ungetc(data, c, file);
+    }
+    *sptr = p;
+    *l = n;
+    return (XpmSuccess);
+}
+
+/*
+ * get the current comment line
+ */
+int
+xpmGetCmt(
+    xpmData	 *data,
+    char	**cmt)
+{
+    if (!data->type)
+	*cmt = NULL;
+    else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) {
+	if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL)
+		return XpmNoMemory;
+	strncpy(*cmt, data->Comment, data->CommentLength);
+	(*cmt)[data->CommentLength] = '\0';
+	data->CommentLength = 0;
+    } else
+	*cmt = NULL;
+    return 0;
+}
+
+xpmDataType xpmDataTypes[] =
+{
+    {"", "!", "\n", '\0', '\n', "", "", "", ""},	/* Natural type */
+    {"C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n"},
+    {"Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n"},
+    {NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL}
+};
+
+/*
+ * parse xpm header
+ */
+int
+xpmParseHeader(xpmData *data)
+{
+    char buf[BUFSIZ+1] = {0};
+    int l, n = 0;
+
+    if (data->type) {
+	data->Bos = '\0';
+	data->Eos = '\n';
+	data->Bcmt = data->Ecmt = NULL;
+	l = xpmNextWord(data, buf, BUFSIZ);
+	if (l == 7 && !strncmp("#define", buf, 7)) {
+	    /* this maybe an XPM 1 file */
+	    char *ptr;
+
+	    l = xpmNextWord(data, buf, BUFSIZ);
+	    if (!l)
+		return (XpmFileInvalid);
+	    buf[l] = '\0';
+	    ptr = strrchr(buf, '_');
+	    if (!ptr || strncmp("_format", ptr, l - (ptr - buf)))
+		return XpmFileInvalid;
+	    /* this is definitely an XPM 1 file */
+	    data->format = 1;
+	    n = 1;			/* handle XPM1 as mainly XPM2 C */
+	} else {
+
+	    /*
+	     * skip the first word, get the second one, and see if this is
+	     * XPM 2 or 3
+	     */
+	    l = xpmNextWord(data, buf, BUFSIZ);
+	    if ((l == 3 && !strncmp("XPM", buf, 3)) ||
+		(l == 4 && !strncmp("XPM2", buf, 4))) {
+		if (l == 3)
+		    n = 1;		/* handle XPM as XPM2 C */
+		else {
+		    /* get the type key word */
+		    l = xpmNextWord(data, buf, BUFSIZ);
+
+		    /*
+		     * get infos about this type
+		     */
+		    while (xpmDataTypes[n].type
+			   && strncmp(xpmDataTypes[n].type, buf, l))
+			n++;
+		}
+		data->format = 0;
+	    } else
+		/* nope this is not an XPM file */
+		return XpmFileInvalid;
+	}
+	if (xpmDataTypes[n].type) {
+	    if (n == 0) {		/* natural type */
+		data->Bcmt = xpmDataTypes[n].Bcmt;
+		data->Ecmt = xpmDataTypes[n].Ecmt;
+		xpmNextString(data);	/* skip the end of the headerline */
+		data->Bos = xpmDataTypes[n].Bos;
+		data->Eos = xpmDataTypes[n].Eos;
+	    } else {
+		data->Bcmt = xpmDataTypes[n].Bcmt;
+		data->Ecmt = xpmDataTypes[n].Ecmt;
+		if (!data->format) {	/* XPM 2 or 3 */
+		    data->Bos = xpmDataTypes[n].Bos;
+		    data->Eos = '\0';
+		    /* get to the beginning of the first string */
+		    xpmNextString(data);
+		    data->Eos = xpmDataTypes[n].Eos;
+		} else			/* XPM 1 skip end of line */
+		    xpmNextString(data);
+	    }
+	} else
+	    /* we don't know about that type of XPM file... */
+	    return XpmFileInvalid;
+    }
+    return XpmSuccess;
+}
diff --git a/libXpm/src/hashtab.c b/libXpm/src/hashtab.c
new file mode 100644
index 000000000..49e6e4831
--- /dev/null
+++ b/libXpm/src/hashtab.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* hashtab.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+*  this originaly comes from Colas Nahaboo as a part of Wool                  *
+*                                                                             *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(AtomMake, xpmHashAtom, (char *name, void *data));
+LFUNC(HashTableGrows, int, (xpmHashTable * table));
+
+static xpmHashAtom
+AtomMake(				/* makes an atom */
+    char	*name,			/* WARNING: is just pointed to */
+    void	*data)
+{
+    xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom));
+
+    if (object) {
+	object->name = name;
+	object->data = data;
+    }
+    return object;
+}
+
+/************************\
+* 			 *
+*  hash table routines 	 *
+* 			 *
+\************************/
+
+/*
+ * Hash function definition:
+ * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char,
+ *				 hash2 = temporary for hashcode.
+ * INITIAL_TABLE_SIZE in slots
+ * HASH_TABLE_GROWS how hash table grows.
+ */
+
+/* Mock lisp function */
+#define HASH_FUNCTION 	  hash = (hash << 5) - hash + *hp++;
+/* #define INITIAL_HASH_SIZE 2017 */
+#define INITIAL_HASH_SIZE 256		/* should be enough for colors */
+#define HASH_TABLE_GROWS  size = size * 2;
+
+/* aho-sethi-ullman's HPJ (sizes should be primes)*/
+#ifdef notdef
+#define HASH_FUNCTION	hash <<= 4; hash += *hp++; \
+    if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2;
+#define INITIAL_HASH_SIZE 4095		/* should be 2^n - 1 */
+#define HASH_TABLE_GROWS  size = size << 1 + 1;
+#endif
+
+/* GNU emacs function */
+/*
+#define HASH_FUNCTION 	  hash = (hash << 3) + (hash >> 28) + *hp++;
+#define INITIAL_HASH_SIZE 2017
+#define HASH_TABLE_GROWS  size = size * 2;
+*/
+
+/* end of hash functions */
+
+/*
+ * The hash table is used to store atoms via their NAME:
+ *
+ * NAME --hash--> ATOM |--name--> "foo"
+ *		       |--data--> any value which has to be stored
+ *
+ */
+
+/*
+ * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name
+ * (slot points to NULL if it is not defined)
+ *
+ */
+
+xpmHashAtom *
+xpmHashSlot(
+    xpmHashTable	*table,
+    char		*s)
+{
+    xpmHashAtom *atomTable = table->atomTable;
+    unsigned int hash;
+    xpmHashAtom *p;
+    char *hp = s;
+    char *ns;
+
+    hash = 0;
+    while (*hp) {			/* computes hash function */
+	HASH_FUNCTION
+    }
+    p = atomTable + hash % table->size;
+    while (*p) {
+	ns = (*p)->name;
+	if (ns[0] == s[0] && strcmp(ns, s) == 0)
+	    break;
+	p--;
+	if (p < atomTable)
+	    p = atomTable + table->size - 1;
+    }
+    return p;
+}
+
+static int
+HashTableGrows(xpmHashTable *table)
+{
+    xpmHashAtom *atomTable = table->atomTable;
+    unsigned int size = table->size;
+    xpmHashAtom *t, *p;
+    int i;
+    unsigned int oldSize = size;
+
+    t = atomTable;
+    HASH_TABLE_GROWS
+	table->size = size;
+    table->limit = size / 3;
+    if (size >= UINT_MAX / sizeof(*atomTable)) 
+	return (XpmNoMemory);
+    atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
+    if (!atomTable)
+	return (XpmNoMemory);
+    table->atomTable = atomTable;
+    for (p = atomTable + size; p > atomTable;)
+	*--p = NULL;
+    for (i = 0, p = t; i < oldSize; i++, p++)
+	if (*p) {
+	    xpmHashAtom *ps = xpmHashSlot(table, (*p)->name);
+
+	    *ps = *p;
+	}
+    XpmFree(t);
+    return (XpmSuccess);
+}
+
+/*
+ * xpmHashIntern(table, name, data)
+ * an xpmHashAtom is created if name doesn't exist, with the given data.
+ */
+
+int
+xpmHashIntern(
+    xpmHashTable	*table,
+    char		*tag,
+    void		*data)
+{
+    xpmHashAtom *slot;
+
+    if (!*(slot = xpmHashSlot(table, tag))) {
+	/* undefined, make a new atom with the given data */
+	if (!(*slot = AtomMake(tag, data)))
+	    return (XpmNoMemory);
+	if (table->used >= table->limit) {
+	    int ErrorStatus;
+
+	    if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess)
+		return (ErrorStatus);
+	    table->used++;
+	    return (XpmSuccess);
+	}
+	table->used++;
+    }
+    return (XpmSuccess);
+}
+
+/*
+ *  must be called before allocating any atom
+ */
+
+int
+xpmHashTableInit(xpmHashTable *table)
+{
+    xpmHashAtom *p;
+    xpmHashAtom *atomTable;
+
+    table->size = INITIAL_HASH_SIZE;
+    table->limit = table->size / 3;
+    table->used = 0;
+    table->atomTable = NULL;
+    if (table->size >= UINT_MAX / sizeof(*atomTable))
+	return (XpmNoMemory);
+    atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
+    if (!atomTable)
+	return (XpmNoMemory);
+    for (p = atomTable + table->size; p > atomTable;)
+	*--p = NULL;
+    table->atomTable = atomTable;
+    return (XpmSuccess);
+}
+
+/*
+ *   frees a hashtable and all the stored atoms
+ */
+
+void
+xpmHashTableFree(xpmHashTable *table)
+{
+    xpmHashAtom *p;
+    xpmHashAtom *atomTable = table->atomTable;
+
+    if (!atomTable)
+	return;
+    for (p = atomTable + table->size; p > atomTable;)
+	if (*--p)
+	    XpmFree(*p);
+    XpmFree(atomTable);
+    table->atomTable = NULL;
+}
diff --git a/libXpm/src/misc.c b/libXpm/src/misc.c
new file mode 100644
index 000000000..e5bc0f6b6
--- /dev/null
+++ b/libXpm/src/misc.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* misc.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Miscellaneous utilities                                                    *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#ifdef NEED_STRDUP
+/*
+ * in case strdup is not provided by the system here is one
+ * which does the trick
+ */
+char *
+xpmstrdup(char *s1)
+{
+    char *s2;
+    size_t l = strlen(s1) + 1;
+
+    if (s2 = (char *) XpmMalloc(l))
+	strcpy(s2, s1);
+    return s2;
+}
+
+#endif
+
+unsigned int
+xpmatoui(
+    register char	*p,
+    unsigned int	 l,
+    unsigned int	*ui_return)
+{
+    register unsigned int n, i;
+
+    n = 0;
+    for (i = 0; i < l; i++)
+	if (*p >= '0' && *p <= '9')
+	    n = n * 10 + *p++ - '0';
+	else
+	    break;
+
+    if (i != 0 && i == l) {
+	*ui_return = n;
+	return 1;
+    } else
+	return 0;
+}
+
+/*
+ * Function returning a character string related to an error code.
+ */
+char *
+XpmGetErrorString(int errcode)
+{
+    switch (errcode) {
+    case XpmColorError:
+	return ("XpmColorError");
+    case XpmSuccess:
+	return ("XpmSuccess");
+    case XpmOpenFailed:
+	return ("XpmOpenFailed");
+    case XpmFileInvalid:
+	return ("XpmFileInvalid");
+    case XpmNoMemory:
+	return ("XpmNoMemory");
+    case XpmColorFailed:
+	return ("XpmColorFailed");
+    default:
+	return ("Invalid XpmError");
+    }
+}
+
+/*
+ * The following function provides a way to figure out if the linked library is
+ * newer or older than the one with which a program has been first compiled.
+ */
+int
+XpmLibraryVersion(void)
+{
+    return XpmIncludeVersion;
+}
+
+
+/* The following should help people wanting to use their own functions */
+#ifdef XpmFree
+#undef XpmFree
+#endif
+
+void
+XpmFree(void *ptr)
+{
+    free(ptr);
+}
diff --git a/libXpm/src/parse.c b/libXpm/src/parse.c
new file mode 100644
index 000000000..b1838661b
--- /dev/null
+++ b/libXpm/src/parse.c
@@ -0,0 +1,807 @@
+/* $XdotOrg: lib/Xpm/src/parse.c,v 1.6 2005/07/16 21:11:25 alanc Exp $ */
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+/* $XFree86: xc/extras/Xpm/lib/parse.c,v 1.2 2000/09/26 15:56:43 tsi Exp $ */
+
+/*****************************************************************************\
+* parse.c:                                                                    *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file or array and store the found informations                *
+*  in the given XpmImage structure.                                           *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86$ */
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+#include <string.h>
+
+#if defined(HAS_STRLCAT) || defined(HAVE_STRLCAT)
+# define STRLCAT(dst, src, dstsize) do { \
+  	if (strlcat(dst, src, dstsize) >= (dstsize)) \
+	    return (XpmFileInvalid); } while(0)
+# define STRLCPY(dst, src, dstsize) do { \
+  	if (strlcpy(dst, src, dstsize) >= (dstsize)) \
+	    return (XpmFileInvalid); } while(0)
+#else
+# define STRLCAT(dst, src, dstsize) do { \
+	if ((strlen(dst) + strlen(src)) < (dstsize)) \
+ 	    strcat(dst, src); \
+	else return (XpmFileInvalid); } while(0)
+# define STRLCPY(dst, src, dstsize) do { \
+	if (strlen(src) < (dstsize)) \
+ 	    strcpy(dst, src); \
+	else return (XpmFileInvalid); } while(0)
+#endif
+
+LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,
+			 unsigned int height, unsigned int ncolors,
+			 unsigned int cpp, XpmColor *colorTable,
+			 xpmHashTable *hashtable, unsigned int **pixels));
+
+char *xpmColorKeys[] = {
+    "s",				/* key #1: symbol */
+    "m",				/* key #2: mono visual */
+    "g4",				/* key #3: 4 grays visual */
+    "g",				/* key #4: gray visual */
+    "c",				/* key #5: color visual */
+};
+
+int
+xpmParseValues(
+    xpmData		*data,
+    unsigned int	*width,
+    unsigned int	*height,
+    unsigned int	*ncolors,
+    unsigned int	*cpp,
+    unsigned int	*x_hotspot,
+    unsigned int	*y_hotspot,
+    unsigned int	*hotspot,
+    unsigned int	*extensions)
+{
+    unsigned int l;
+    char buf[BUFSIZ + 1];
+
+    if (!data->format) {		/* XPM 2 or 3 */
+
+	/*
+	 * read values: width, height, ncolors, chars_per_pixel
+	 */
+	if (!(xpmNextUI(data, width) && xpmNextUI(data, height)
+	      && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp)))
+	    return (XpmFileInvalid);
+
+	/*
+	 * read optional information (hotspot and/or XPMEXT) if any
+	 */
+	l = xpmNextWord(data, buf, BUFSIZ);
+	if (l) {
+	    *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
+	    if (*extensions)
+		*hotspot = (xpmNextUI(data, x_hotspot)
+			    && xpmNextUI(data, y_hotspot));
+	    else {
+		*hotspot = (xpmatoui(buf, l, x_hotspot)
+			    && xpmNextUI(data, y_hotspot));
+		l = xpmNextWord(data, buf, BUFSIZ);
+		*extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
+	    }
+	}
+    } else {
+
+	/*
+	 * XPM 1 file read values: width, height, ncolors, chars_per_pixel
+	 */
+	int i;
+	char *ptr;
+	Bool got_one, saw_width = False, saw_height = False;
+	Bool saw_ncolors = False, saw_chars_per_pixel = False;
+
+	for (i = 0; i < 4; i++) {
+	    l = xpmNextWord(data, buf, BUFSIZ);
+	    if (l != 7 || strncmp("#define", buf, 7))
+		return (XpmFileInvalid);
+	    l = xpmNextWord(data, buf, BUFSIZ);
+	    if (!l)
+		return (XpmFileInvalid);
+	    buf[l] = '\0';
+	    ptr = buf;
+	    got_one = False;
+	    while (!got_one) {
+		ptr = strchr(ptr, '_');
+		if (!ptr)
+		    return (XpmFileInvalid);
+		switch (l - (ptr - buf)) {
+		case 6:
+		    if (saw_width || strncmp("_width", ptr, 6)
+			|| !xpmNextUI(data, width))
+			return (XpmFileInvalid);
+		    else
+			saw_width = True;
+		    got_one = True;
+		    break;
+		case 7:
+		    if (saw_height || strncmp("_height", ptr, 7)
+			|| !xpmNextUI(data, height))
+			return (XpmFileInvalid);
+		    else
+			saw_height = True;
+		    got_one = True;
+		    break;
+		case 8:
+		    if (saw_ncolors || strncmp("_ncolors", ptr, 8)
+			|| !xpmNextUI(data, ncolors))
+			return (XpmFileInvalid);
+		    else
+			saw_ncolors = True;
+		    got_one = True;
+		    break;
+		case 16:
+		    if (saw_chars_per_pixel
+			|| strncmp("_chars_per_pixel", ptr, 16)
+			|| !xpmNextUI(data, cpp))
+			return (XpmFileInvalid);
+		    else
+			saw_chars_per_pixel = True;
+		    got_one = True;
+		    break;
+		default:
+		    ptr++;
+		}
+	    }
+	    /* skip the end of line */
+	    xpmNextString(data);
+	}
+	if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel)
+	  return (XpmFileInvalid);
+
+	*hotspot = 0;
+	*extensions = 0;
+    }
+    return (XpmSuccess);
+}
+
+int
+xpmParseColors(
+    xpmData		 *data,
+    unsigned int	  ncolors,
+    unsigned int	  cpp,
+    XpmColor		**colorTablePtr,
+    xpmHashTable	 *hashtable)
+{
+    unsigned int key = 0, l, a, b, len;
+    unsigned int curkey;		/* current color key */
+    unsigned int lastwaskey;		/* key read */
+    char buf[BUFSIZ+1];
+    char curbuf[BUFSIZ];		/* current buffer */
+    char **sptr, *s;
+    XpmColor *color;
+    XpmColor *colorTable;
+    char **defaults;
+    int ErrorStatus;
+
+    if (ncolors >= UINT_MAX / sizeof(XpmColor))
+	return (XpmNoMemory);
+    colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
+    if (!colorTable)
+	return (XpmNoMemory);
+
+    if (!data->format) {		/* XPM 2 or 3 */
+	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+	    xpmNextString(data);	/* skip the line */
+
+	    /*
+	     * read pixel value
+	     */
+	    if (cpp >= UINT_MAX - 1) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    color->string = (char *) XpmMalloc(cpp + 1);
+	    if (!color->string) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    for (b = 0, s = color->string; b < cpp; b++, s++)
+		*s = xpmGetC(data);
+	    *s = '\0';
+
+	    /*
+	     * store the string in the hashtable with its color index number
+	     */
+	    if (USE_HASHTABLE) {
+		ErrorStatus =
+		    xpmHashIntern(hashtable, color->string, HashAtomData(a));
+		if (ErrorStatus != XpmSuccess) {
+		    xpmFreeColorTable(colorTable, ncolors);
+		    return (ErrorStatus);
+		}
+	    }
+
+	    /*
+	     * read color keys and values
+	     */
+	    defaults = (char **) color;
+	    curkey = 0;
+	    lastwaskey = 0;
+	    *curbuf = '\0';		/* init curbuf */
+	    while ((l = xpmNextWord(data, buf, BUFSIZ))) {
+		if (!lastwaskey) {
+		    for (key = 0, sptr = xpmColorKeys; key < NKEYS; key++,
+			 sptr++)
+			if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l)))
+			    break;
+		}
+		if (!lastwaskey && key < NKEYS) {	/* open new key */
+		    if (curkey) {	/* flush string */
+			len = strlen(curbuf) + 1;
+			s = (char *) XpmMalloc(len);
+			if (!s) {
+			    xpmFreeColorTable(colorTable, ncolors);
+			    return (XpmNoMemory);
+			}
+			defaults[curkey] = s;
+			memcpy(s, curbuf, len);
+		    }
+		    curkey = key + 1;	/* set new key  */
+		    *curbuf = '\0';	/* reset curbuf */
+		    lastwaskey = 1;
+		} else {
+		    if (!curkey) {	/* key without value */
+			xpmFreeColorTable(colorTable, ncolors);
+			return (XpmFileInvalid);
+		    }
+		    if (!lastwaskey)
+			STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
+		    buf[l] = '\0';
+		    STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */
+		    lastwaskey = 0;
+		}
+	    }
+	    if (!curkey) {		/* key without value */
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmFileInvalid);
+	    }
+	    len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */
+	    s = defaults[curkey] = (char *) XpmMalloc(len);
+	    if (!s) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    memcpy(s, curbuf, len);
+	}
+    } else {				/* XPM 1 */
+	/* get to the beginning of the first string */
+	data->Bos = '"';
+	data->Eos = '\0';
+	xpmNextString(data);
+	data->Eos = '"';
+	for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+
+	    /*
+	     * read pixel value
+	     */
+	    if (cpp >= UINT_MAX - 1) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    color->string = (char *) XpmMalloc(cpp + 1);
+	    if (!color->string) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    for (b = 0, s = color->string; b < cpp; b++, s++)
+		*s = xpmGetC(data);
+	    *s = '\0';
+
+	    /*
+	     * store the string in the hashtable with its color index number
+	     */
+	    if (USE_HASHTABLE) {
+		ErrorStatus =
+		    xpmHashIntern(hashtable, color->string, HashAtomData(a));
+		if (ErrorStatus != XpmSuccess) {
+		    xpmFreeColorTable(colorTable, ncolors);
+		    return (ErrorStatus);
+		}
+	    }
+
+	    /*
+	     * read color values
+	     */
+	    xpmNextString(data);	/* get to the next string */
+	    *curbuf = '\0';		/* init curbuf */
+	    while ((l = xpmNextWord(data, buf, BUFSIZ))) {
+		if (*curbuf != '\0')
+		    STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
+		buf[l] = '\0';
+		STRLCAT(curbuf, buf, sizeof(curbuf));	/* append buf */
+	    }
+	    len = strlen(curbuf) + 1;
+	    s = (char *) XpmMalloc(len);
+	    if (!s) {
+		xpmFreeColorTable(colorTable, ncolors);
+		return (XpmNoMemory);
+	    }
+	    memcpy(s, curbuf, len);
+	    color->c_color = s;
+	    *curbuf = '\0';		/* reset curbuf */
+	    if (a < ncolors - 1)	/* can we trust ncolors -> leave data's bounds */
+		xpmNextString(data);	/* get to the next string */
+	}
+    }
+    *colorTablePtr = colorTable;
+    return (XpmSuccess);
+}
+
+static int
+ParsePixels(
+    xpmData		 *data,
+    unsigned int	  width,
+    unsigned int	  height,
+    unsigned int	  ncolors,
+    unsigned int	  cpp,
+    XpmColor		 *colorTable,
+    xpmHashTable	 *hashtable,
+    unsigned int	**pixels)
+{
+    unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */
+    unsigned int a, x, y;
+
+    if ((height > 0 && width >= UINT_MAX / height) ||
+	width * height >= UINT_MAX / sizeof(unsigned int)) 
+	return XpmNoMemory;
+#ifndef FOR_MSW
+    iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
+#else
+
+    /*
+     * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!!
+     * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary
+     */
+    iptr2 = (unsigned int *)
+	XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height);
+#endif
+    if (!iptr2)
+	return (XpmNoMemory);
+
+    iptr = iptr2;
+
+    switch (cpp) {
+
+    case (1):				/* Optimize for single character
+					 * colors */
+	{
+	    unsigned short colidx[256];
+
+	    if (ncolors > 256) {
+		XpmFree(iptr2); /* found by Egbert Eich */
+		return (XpmFileInvalid);
+	    }
+
+	    bzero((char *)colidx, 256 * sizeof(short));
+	    for (a = 0; a < ncolors; a++)
+		colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
+
+	    for (y = 0; y < height; y++) {
+		xpmNextString(data);
+		for (x = 0; x < width; x++, iptr++) {
+		    int c = xpmGetC(data);
+
+		    if (c > 0 && c < 256 && colidx[c] != 0)
+			*iptr = colidx[c] - 1;
+		    else {
+			XpmFree(iptr2);
+			return (XpmFileInvalid);
+		    }
+		}
+	    }
+	}
+	break;
+
+    case (2):				/* Optimize for double character
+					 * colors */
+	{
+
+/* free all allocated pointers at all exits */
+#define FREE_CIDX \
+do \
+{ \
+	int f; for (f = 0; f < 256; f++) \
+	if (cidx[f]) XpmFree(cidx[f]); \
+} while(0)
+
+	    /* array of pointers malloced by need */
+	    unsigned short *cidx[256];
+	    unsigned int char1;
+
+	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+	    for (a = 0; a < ncolors; a++) {
+		char1 = (unsigned char) colorTable[a].string[0];
+		if (cidx[char1] == NULL) { /* get new memory */
+		    cidx[char1] = (unsigned short *)
+			XpmCalloc(256, sizeof(unsigned short));
+		    if (cidx[char1] == NULL) { /* new block failed */
+			FREE_CIDX;
+			XpmFree(iptr2);
+			return (XpmNoMemory);
+		    }
+		}
+		cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
+	    }
+
+	    for (y = 0; y < height; y++) {
+		xpmNextString(data);
+		for (x = 0; x < width; x++, iptr++) {
+		    int cc1 = xpmGetC(data);
+		    if (cc1 > 0 && cc1 < 256) {
+			int cc2 = xpmGetC(data);
+			if (cc2 > 0 && cc2 < 256 &&
+			    cidx[cc1] && cidx[cc1][cc2] != 0)
+			    *iptr = cidx[cc1][cc2] - 1;
+			else {
+			    FREE_CIDX;
+			    XpmFree(iptr2);
+			    return (XpmFileInvalid);
+			}
+		    } else {
+			FREE_CIDX;
+			XpmFree(iptr2);
+			return (XpmFileInvalid);
+		    }
+		}
+	    }
+	    FREE_CIDX;
+	}
+	break;
+
+    default:				/* Non-optimized case of long color
+					 * names */
+	{
+	    char *s;
+	    char buf[BUFSIZ];
+
+	    if (cpp >= sizeof(buf)) {
+		XpmFree(iptr2); /* found by Egbert Eich */
+		return (XpmFileInvalid);
+	    }
+
+	    buf[cpp] = '\0';
+	    if (USE_HASHTABLE) {
+		xpmHashAtom *slot;
+
+		for (y = 0; y < height; y++) {
+		    xpmNextString(data);
+		    for (x = 0; x < width; x++, iptr++) {
+			for (a = 0, s = buf; a < cpp; a++, s++)
+			    *s = xpmGetC(data); /* int assigned to char, not a problem here */
+			slot = xpmHashSlot(hashtable, buf);
+			if (!*slot) {	/* no color matches */
+			    XpmFree(iptr2);
+			    return (XpmFileInvalid);
+			}
+			*iptr = HashColorIndex(slot);
+		    }
+		}
+	    } else {
+		for (y = 0; y < height; y++) {
+		    xpmNextString(data);
+		    for (x = 0; x < width; x++, iptr++) {
+			for (a = 0, s = buf; a < cpp; a++, s++)
+			    *s = xpmGetC(data); /* int assigned to char, not a problem here */
+			for (a = 0; a < ncolors; a++)
+			    if (!strcmp(colorTable[a].string, buf))
+				break;
+			if (a == ncolors) {	/* no color matches */
+			    XpmFree(iptr2);
+			    return (XpmFileInvalid);
+			}
+			*iptr = a;
+		    }
+		}
+	    }
+	}
+	break;
+    }
+    *pixels = iptr2;
+    return (XpmSuccess);
+}
+
+int
+xpmParseExtensions(
+    xpmData		 *data,
+    XpmExtension	**extensions,
+    unsigned int	 *nextensions)
+{
+    XpmExtension *exts = NULL, *ext;
+    unsigned int num = 0;
+    unsigned int nlines, a, l, notstart, notend = 0;
+    int status;
+    char *string, *s, *s2, **sp;
+
+    xpmNextString(data);
+    exts = (XpmExtension *) XpmMalloc(sizeof(XpmExtension));
+    /* get the whole string */
+    status = xpmGetString(data, &string, &l);
+    if (status != XpmSuccess) {
+	XpmFree(exts);
+	return (status);
+    }
+    /* look for the key word XPMEXT, skip lines before this */
+    while ((notstart = strncmp("XPMEXT", string, 6))
+	   && (notend = strncmp("XPMENDEXT", string, 9))) {
+	XpmFree(string);
+	xpmNextString(data);
+	status = xpmGetString(data, &string, &l);
+	if (status != XpmSuccess) {
+	    XpmFree(exts);
+	    return (status);
+	}
+    }
+    if (!notstart)
+	notend = strncmp("XPMENDEXT", string, 9);
+    while (!notstart && notend) {
+	/* there starts an extension */
+	ext = (XpmExtension *)
+	    XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */
+	if (!ext) {
+	    XpmFree(string);
+	    XpmFreeExtensions(exts, num);
+	    return (XpmNoMemory);
+	}
+	exts = ext;
+	ext += num;
+	/* skip whitespace and store its name */
+	s2 = s = string + 6;
+	while (isspace(*s2))
+	    s2++;
+	a = s2 - s;
+	ext->name = (char *) XpmMalloc(l - a - 6);
+	if (!ext->name) {
+	    XpmFree(string);
+	    ext->lines = NULL;
+	    ext->nlines = 0;
+	    XpmFreeExtensions(exts, num + 1);
+	    return (XpmNoMemory);
+	}
+	strncpy(ext->name, s + a, l - a - 6);
+	XpmFree(string);
+	/* now store the related lines */
+	xpmNextString(data);
+	status = xpmGetString(data, &string, &l);
+	if (status != XpmSuccess) {
+	    ext->lines = NULL;
+	    ext->nlines = 0;
+	    XpmFreeExtensions(exts, num + 1);
+	    return (status);
+	}
+	ext->lines = (char **) XpmMalloc(sizeof(char *));
+	nlines = 0;
+	while ((notstart = strncmp("XPMEXT", string, 6))
+	       && (notend = strncmp("XPMENDEXT", string, 9))) {
+	    sp = (char **)
+		XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); /* can we iterate enough for a wrapping? */
+	    if (!sp) {
+		XpmFree(string);
+		ext->nlines = nlines;
+		XpmFreeExtensions(exts, num + 1);
+		return (XpmNoMemory);
+	    }
+	    ext->lines = sp;
+	    ext->lines[nlines] = string;
+	    nlines++;
+	    xpmNextString(data);
+	    status = xpmGetString(data, &string, &l);
+	    if (status != XpmSuccess) {
+		ext->nlines = nlines;
+		XpmFreeExtensions(exts, num + 1);
+		return (status);
+	    }
+	}
+	if (!nlines) {
+	    XpmFree(ext->lines);
+	    ext->lines = NULL;
+	}
+	ext->nlines = nlines;
+	num++;
+    }
+    if (!num) {
+	XpmFree(string);
+	XpmFree(exts);
+	exts = NULL;
+    } else if (!notend)
+	XpmFree(string);
+    *nextensions = num;
+    *extensions = exts;
+    return (XpmSuccess);
+}
+
+
+/* function call in case of error */
+#undef RETURN
+#define RETURN(status) \
+do { \
+      goto error; \
+} while(0)
+
+/*
+ * This function parses an Xpm file or data and store the found informations
+ * in an an XpmImage structure which is returned.
+ */
+int
+xpmParseData(
+    xpmData	*data,
+    XpmImage	*image,
+    XpmInfo	*info)
+{
+    /* variables to return */
+    unsigned int width, height, ncolors, cpp;
+    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
+    XpmColor *colorTable = NULL;
+    unsigned int *pixelindex = NULL;
+    char *hints_cmt = NULL;
+    char *colors_cmt = NULL;
+    char *pixels_cmt = NULL;
+
+    unsigned int cmts;
+    int ErrorStatus;
+    xpmHashTable hashtable;
+
+    cmts = info && (info->valuemask & XpmReturnComments);
+
+    /*
+     * parse the header
+     */
+    ErrorStatus = xpmParseHeader(data);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /*
+     * read values
+     */
+    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
+				 &x_hotspot, &y_hotspot, &hotspot,
+				 &extensions);
+    if (ErrorStatus != XpmSuccess)
+	return (ErrorStatus);
+
+    /*
+     * store the hints comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &hints_cmt);
+
+    /*
+     * init the hashtable
+     */
+    if (USE_HASHTABLE) {
+	ErrorStatus = xpmHashTableInit(&hashtable);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+    }
+
+    /*
+     * read colors
+     */
+    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
+    if (ErrorStatus != XpmSuccess) {
+	if (USE_HASHTABLE)
+	    xpmHashTableFree(&hashtable);
+	RETURN(ErrorStatus);
+    }
+
+    /*
+     * store the colors comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &colors_cmt);
+
+    /*
+     * read pixels and index them on color number
+     */
+    ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable,
+			      &hashtable, &pixelindex);
+
+    /*
+     * free the hastable
+     */
+    if (USE_HASHTABLE)
+	xpmHashTableFree(&hashtable);
+
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+
+    /*
+     * store the pixels comment line
+     */
+    if (cmts)
+	xpmGetCmt(data, &pixels_cmt);
+
+    /*
+     * parse extensions
+     */
+    if (info && (info->valuemask & XpmReturnExtensions)) {
+	if (extensions) {
+	    ErrorStatus = xpmParseExtensions(data, &info->extensions,
+					     &info->nextensions);
+	    if (ErrorStatus != XpmSuccess)
+		RETURN(ErrorStatus);
+	} else {
+	    info->extensions = NULL;
+	    info->nextensions = 0;
+	}
+    }
+
+    /*
+     * store found informations in the XpmImage structure
+     */
+    image->width = width;
+    image->height = height;
+    image->cpp = cpp;
+    image->ncolors = ncolors;
+    image->colorTable = colorTable;
+    image->data = pixelindex;
+
+    if (info) {
+	if (cmts) {
+	    info->hints_cmt = hints_cmt;
+	    info->colors_cmt = colors_cmt;
+	    info->pixels_cmt = pixels_cmt;
+	}
+	if (hotspot) {
+	    info->x_hotspot = x_hotspot;
+	    info->y_hotspot = y_hotspot;
+	    info->valuemask |= XpmHotspot;
+	}
+    }
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (colorTable)
+	xpmFreeColorTable(colorTable, ncolors);
+    if (pixelindex)
+	XpmFree(pixelindex);
+    if (hints_cmt)
+	XpmFree(hints_cmt);
+    if (colors_cmt)
+	XpmFree(colors_cmt);
+    if (pixels_cmt)
+	XpmFree(pixels_cmt);
+
+    return(ErrorStatus);
+}
diff --git a/libXpm/src/rgb.c b/libXpm/src/rgb.c
new file mode 100644
index 000000000..848ae1f11
--- /dev/null
+++ b/libXpm/src/rgb.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* rgb.c:                                                                      *
+*                                                                             *
+*  XPM library                                                                *
+*  Rgb file utilities                                                         *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * Part of this code has been taken from the ppmtoxpm.c file written by Mark
+ * W. Snitily but has been modified for my special need
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+
+#ifndef FOR_MSW				/* normal part first, MSW part at
+					 * the end, (huge ifdef!) */
+/*
+ * Read a rgb text file.  It stores the rgb values (0->65535)
+ * and the rgb mnemonics (malloc'ed) into the "rgbn" array.  Returns the
+ * number of entries stored.
+ */
+int
+xpmReadRgbNames(
+    char	*rgb_fname,
+    xpmRgbName	 rgbn[])
+{
+    FILE *rgbf;
+    int n, items, red, green, blue;
+    char line[512], name[512], *rgbname, *s1, *s2;
+    xpmRgbName *rgb;
+
+    /* Open the rgb text file.  Abort if error. */
+    if ((rgbf = fopen(rgb_fname, "r")) == NULL)
+	return 0;
+
+    /* Loop reading each line in the file. */
+    n = 0;
+    rgb = rgbn; 
+    /* Quit if rgb text file has too many entries. */
+    while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
+
+	/* Skip silently if line is bad. */
+	items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
+	if (items != 4)
+	    continue;
+
+	/*
+	 * Make sure rgb values are within 0->255 range. Skip silently if
+	 * bad.
+	 */
+	if (red < 0 || red > 0xFF ||
+	    green < 0 || green > 0xFF ||
+	    blue < 0 || blue > 0xFF)
+	    continue;
+
+	/* Allocate memory for ascii name. If error give up here. */
+	if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
+	    break;
+
+	/* Copy string to ascii name and lowercase it. */
+	for (s1 = name, s2 = rgbname; *s1; s1++)
+	    *s2++ = tolower(*s1);
+	*s2 = '\0';
+
+	/* Save the rgb values and ascii name in the array. */
+	rgb->r = red * 257;		/* 65535/255 = 257 */
+	rgb->g = green * 257;
+	rgb->b = blue * 257;
+	rgb->name = rgbname;
+	rgb++;
+	n++;
+    }
+
+    fclose(rgbf);
+
+    /* Return the number of read rgb names. */
+    return n < 0 ? 0 : n;
+}
+
+/*
+ * Return the color name corresponding to the given rgb values
+ */
+char *
+xpmGetRgbName(
+    xpmRgbName	rgbn[],		/* rgb mnemonics from rgb text file */
+    int		rgbn_max,	/* number of rgb mnemonics in table */
+    int		red,		/* rgb values */
+    int		green,
+    int		blue)
+{
+    int i;
+    xpmRgbName *rgb;
+
+    /*
+     * Just perform a dumb linear search over the rgb values of the color
+     * mnemonics.  One could speed things up by sorting the rgb values and
+     * using a binary search, or building a hash table, etc...
+     */
+    for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+	if (red == rgb->r && green == rgb->g && blue == rgb->b)
+	    return rgb->name;
+
+    /* if not found return NULL */
+    return NULL;
+}
+
+/*
+ * Free the strings which have been malloc'ed in xpmReadRgbNames
+ */
+void
+xpmFreeRgbNames(
+    xpmRgbName	rgbn[],
+    int		rgbn_max)
+{
+    int i;
+    xpmRgbName *rgb;
+
+    for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+	XpmFree(rgb->name);
+}
+
+#else					/* here comes the MSW part, the
+					 * second part of the  huge ifdef */
+
+#include "rgbtab.h"			/* hard coded rgb.txt table */
+
+int
+xpmReadRgbNames(
+    char	*rgb_fname,
+    xpmRgbName	 rgbn[])
+{
+    /*
+     * check for consistency???
+     * table has to be sorted for calls on strcasecmp
+     */
+    return (numTheRGBRecords);
+}
+
+/*
+ * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
+ * which has something like #0303 for one color
+ */
+char *
+xpmGetRgbName(
+    xpmRgbName rgbn[],		/* rgb mnemonics from rgb text file
+				 * not used */
+    int		rgbn_max,	/* not used */
+    int		red, 		/* rgb values */
+    int		green,
+    int		blue)
+
+{
+    int i;
+    unsigned long rgbVal;
+
+    i = 0;
+    while (i < numTheRGBRecords) {
+	rgbVal = theRGBRecords[i].rgb;
+	if (GetRValue(rgbVal) == red &&
+	    GetGValue(rgbVal) == green &&
+	    GetBValue(rgbVal) == blue)
+	    return (theRGBRecords[i].name);
+	i++;
+    }
+    return (NULL);
+}
+
+/* used in XParseColor in simx.c */
+int
+xpmGetRGBfromName(
+    char	*inname,
+    int		*r,
+    int		*g,
+    int		*b)
+{
+    int left, right, middle;
+    int cmp;
+    unsigned long rgbVal;
+    char *name;
+    char *grey, *p;
+
+    name = xpmstrdup(inname);
+
+    /*
+     * the table in rgbtab.c has no names with spaces, and no grey, but a
+     * lot of gray
+     */
+    /* so first extract ' ' */
+    while (p = strchr(name, ' ')) {
+	while (*(p)) {			/* till eof of string */
+	    *p = *(p + 1);		/* copy to the left */
+	    p++;
+	}
+    }
+    /* fold to lower case */
+    p = name;
+    while (*p) {
+	*p = tolower(*p);
+	p++;
+    }
+
+    /*
+     * substitute Grey with Gray, else rgbtab.h would have more than 100
+     * 'duplicate' entries
+     */
+    if (grey = strstr(name, "grey"))
+	grey[2] = 'a';
+
+    /* binary search */
+    left = 0;
+    right = numTheRGBRecords - 1;
+    do {
+	middle = (left + right) / 2;
+	cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
+	if (cmp == 0) {
+	    rgbVal = theRGBRecords[middle].rgb;
+	    *r = GetRValue(rgbVal);
+	    *g = GetGValue(rgbVal);
+	    *b = GetBValue(rgbVal);
+	    free(name);
+	    return (1);
+	} else if (cmp < 0) {
+	    right = middle - 1;
+	} else {			/* > 0 */
+	    left = middle + 1;
+	}
+    } while (left <= right);
+
+    /*
+     * I don't like to run in a ColorInvalid error and to see no pixmap at
+     * all, so simply return a red pixel. Should be wrapped in an #ifdef
+     * HeDu
+     */
+
+    *r = 255;
+    *g = 0;
+    *b = 0;				/* red error pixel */
+
+    free(name);
+    return (1);
+}
+
+void
+xpmFreeRgbNames(
+    xpmRgbName	rgbn[],
+    int		rgbn_max)
+{
+    /* nothing to do */
+}
+
+#endif					/* MSW part */
diff --git a/libXpm/src/rgbtab.h b/libXpm/src/rgbtab.h
new file mode 100644
index 000000000..3b7518491
--- /dev/null
+++ b/libXpm/src/rgbtab.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* rgbtab.h                                                                    *
+*                                                                             *
+* A hard coded rgb.txt. To keep it short I removed all colornames with        *
+* trailing numbers, Blue3 etc, except the GrayXX. Sorry Grey-lovers I prefer  *
+* Gray ;-). But Grey is recognized on lookups, only on save Gray will be      *
+* used, maybe you want to do some substitue there too.                        *
+*                                                                             *
+* To save memory the RGBs are coded in one long value, as done by the RGB     *
+* macro.                                                                      *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+
+typedef struct {
+    char *name;
+    COLORREF rgb;			/* it's unsigned long */
+}      rgbRecord;
+
+/*
+#define myRGB(r,g,b) \
+	((unsigned long)r<<16|(unsigned long)g<<8|(unsigned long)b)
+*/
+#define myRGB(r,g,b)	RGB(r,g,b)	/* MSW has this macro */
+
+
+static rgbRecord theRGBRecords[] =
+{
+    {"AliceBlue", myRGB(240, 248, 255)},
+    {"AntiqueWhite", myRGB(250, 235, 215)},
+    {"Aquamarine", myRGB(50, 191, 193)},
+    {"Azure", myRGB(240, 255, 255)},
+    {"Beige", myRGB(245, 245, 220)},
+    {"Bisque", myRGB(255, 228, 196)},
+    {"Black", myRGB(0, 0, 0)},
+    {"BlanchedAlmond", myRGB(255, 235, 205)},
+    {"Blue", myRGB(0, 0, 255)},
+    {"BlueViolet", myRGB(138, 43, 226)},
+    {"Brown", myRGB(165, 42, 42)},
+    {"burlywood", myRGB(222, 184, 135)},
+    {"CadetBlue", myRGB(95, 146, 158)},
+    {"chartreuse", myRGB(127, 255, 0)},
+    {"chocolate", myRGB(210, 105, 30)},
+    {"Coral", myRGB(255, 114, 86)},
+    {"CornflowerBlue", myRGB(34, 34, 152)},
+    {"cornsilk", myRGB(255, 248, 220)},
+    {"Cyan", myRGB(0, 255, 255)},
+    {"DarkGoldenrod", myRGB(184, 134, 11)},
+    {"DarkGreen", myRGB(0, 86, 45)},
+    {"DarkKhaki", myRGB(189, 183, 107)},
+    {"DarkOliveGreen", myRGB(85, 86, 47)},
+    {"DarkOrange", myRGB(255, 140, 0)},
+    {"DarkOrchid", myRGB(139, 32, 139)},
+    {"DarkSalmon", myRGB(233, 150, 122)},
+    {"DarkSeaGreen", myRGB(143, 188, 143)},
+    {"DarkSlateBlue", myRGB(56, 75, 102)},
+    {"DarkSlateGray", myRGB(47, 79, 79)},
+    {"DarkTurquoise", myRGB(0, 166, 166)},
+    {"DarkViolet", myRGB(148, 0, 211)},
+    {"DeepPink", myRGB(255, 20, 147)},
+    {"DeepSkyBlue", myRGB(0, 191, 255)},
+    {"DimGray", myRGB(84, 84, 84)},
+    {"DodgerBlue", myRGB(30, 144, 255)},
+    {"Firebrick", myRGB(142, 35, 35)},
+    {"FloralWhite", myRGB(255, 250, 240)},
+    {"ForestGreen", myRGB(80, 159, 105)},
+    {"gainsboro", myRGB(220, 220, 220)},
+    {"GhostWhite", myRGB(248, 248, 255)},
+    {"Gold", myRGB(218, 170, 0)},
+    {"Goldenrod", myRGB(239, 223, 132)},
+    {"Gray", myRGB(126, 126, 126)},
+    {"Gray0", myRGB(0, 0, 0)},
+    {"Gray1", myRGB(3, 3, 3)},
+    {"Gray10", myRGB(26, 26, 26)},
+    {"Gray100", myRGB(255, 255, 255)},
+    {"Gray11", myRGB(28, 28, 28)},
+    {"Gray12", myRGB(31, 31, 31)},
+    {"Gray13", myRGB(33, 33, 33)},
+    {"Gray14", myRGB(36, 36, 36)},
+    {"Gray15", myRGB(38, 38, 38)},
+    {"Gray16", myRGB(41, 41, 41)},
+    {"Gray17", myRGB(43, 43, 43)},
+    {"Gray18", myRGB(46, 46, 46)},
+    {"Gray19", myRGB(48, 48, 48)},
+    {"Gray2", myRGB(5, 5, 5)},
+    {"Gray20", myRGB(51, 51, 51)},
+    {"Gray21", myRGB(54, 54, 54)},
+    {"Gray22", myRGB(56, 56, 56)},
+    {"Gray23", myRGB(59, 59, 59)},
+    {"Gray24", myRGB(61, 61, 61)},
+    {"Gray25", myRGB(64, 64, 64)},
+    {"Gray26", myRGB(66, 66, 66)},
+    {"Gray27", myRGB(69, 69, 69)},
+    {"Gray28", myRGB(71, 71, 71)},
+    {"Gray29", myRGB(74, 74, 74)},
+    {"Gray3", myRGB(8, 8, 8)},
+    {"Gray30", myRGB(77, 77, 77)},
+    {"Gray31", myRGB(79, 79, 79)},
+    {"Gray32", myRGB(82, 82, 82)},
+    {"Gray33", myRGB(84, 84, 84)},
+    {"Gray34", myRGB(87, 87, 87)},
+    {"Gray35", myRGB(89, 89, 89)},
+    {"Gray36", myRGB(92, 92, 92)},
+    {"Gray37", myRGB(94, 94, 94)},
+    {"Gray38", myRGB(97, 97, 97)},
+    {"Gray39", myRGB(99, 99, 99)},
+    {"Gray4", myRGB(10, 10, 10)},
+    {"Gray40", myRGB(102, 102, 102)},
+    {"Gray41", myRGB(105, 105, 105)},
+    {"Gray42", myRGB(107, 107, 107)},
+    {"Gray43", myRGB(110, 110, 110)},
+    {"Gray44", myRGB(112, 112, 112)},
+    {"Gray45", myRGB(115, 115, 115)},
+    {"Gray46", myRGB(117, 117, 117)},
+    {"Gray47", myRGB(120, 120, 120)},
+    {"Gray48", myRGB(122, 122, 122)},
+    {"Gray49", myRGB(125, 125, 125)},
+    {"Gray5", myRGB(13, 13, 13)},
+    {"Gray50", myRGB(127, 127, 127)},
+    {"Gray51", myRGB(130, 130, 130)},
+    {"Gray52", myRGB(133, 133, 133)},
+    {"Gray53", myRGB(135, 135, 135)},
+    {"Gray54", myRGB(138, 138, 138)},
+    {"Gray55", myRGB(140, 140, 140)},
+    {"Gray56", myRGB(143, 143, 143)},
+    {"Gray57", myRGB(145, 145, 145)},
+    {"Gray58", myRGB(148, 148, 148)},
+    {"Gray59", myRGB(150, 150, 150)},
+    {"Gray6", myRGB(15, 15, 15)},
+    {"Gray60", myRGB(153, 153, 153)},
+    {"Gray61", myRGB(156, 156, 156)},
+    {"Gray62", myRGB(158, 158, 158)},
+    {"Gray63", myRGB(161, 161, 161)},
+    {"Gray64", myRGB(163, 163, 163)},
+    {"Gray65", myRGB(166, 166, 166)},
+    {"Gray66", myRGB(168, 168, 168)},
+    {"Gray67", myRGB(171, 171, 171)},
+    {"Gray68", myRGB(173, 173, 173)},
+    {"Gray69", myRGB(176, 176, 176)},
+    {"Gray7", myRGB(18, 18, 18)},
+    {"Gray70", myRGB(179, 179, 179)},
+    {"Gray71", myRGB(181, 181, 181)},
+    {"Gray72", myRGB(184, 184, 184)},
+    {"Gray73", myRGB(186, 186, 186)},
+    {"Gray74", myRGB(189, 189, 189)},
+    {"Gray75", myRGB(191, 191, 191)},
+    {"Gray76", myRGB(194, 194, 194)},
+    {"Gray77", myRGB(196, 196, 196)},
+    {"Gray78", myRGB(199, 199, 199)},
+    {"Gray79", myRGB(201, 201, 201)},
+    {"Gray8", myRGB(20, 20, 20)},
+    {"Gray80", myRGB(204, 204, 204)},
+    {"Gray81", myRGB(207, 207, 207)},
+    {"Gray82", myRGB(209, 209, 209)},
+    {"Gray83", myRGB(212, 212, 212)},
+    {"Gray84", myRGB(214, 214, 214)},
+    {"Gray85", myRGB(217, 217, 217)},
+    {"Gray86", myRGB(219, 219, 219)},
+    {"Gray87", myRGB(222, 222, 222)},
+    {"Gray88", myRGB(224, 224, 224)},
+    {"Gray89", myRGB(227, 227, 227)},
+    {"Gray9", myRGB(23, 23, 23)},
+    {"Gray90", myRGB(229, 229, 229)},
+    {"Gray91", myRGB(232, 232, 232)},
+    {"Gray92", myRGB(235, 235, 235)},
+    {"Gray93", myRGB(237, 237, 237)},
+    {"Gray94", myRGB(240, 240, 240)},
+    {"Gray95", myRGB(242, 242, 242)},
+    {"Gray96", myRGB(245, 245, 245)},
+    {"Gray97", myRGB(247, 247, 247)},
+    {"Gray98", myRGB(250, 250, 250)},
+    {"Gray99", myRGB(252, 252, 252)},
+    {"Green", myRGB(0, 255, 0)},
+    {"GreenYellow", myRGB(173, 255, 47)},
+    {"honeydew", myRGB(240, 255, 240)},
+    {"HotPink", myRGB(255, 105, 180)},
+    {"IndianRed", myRGB(107, 57, 57)},
+    {"ivory", myRGB(255, 255, 240)},
+    {"Khaki", myRGB(179, 179, 126)},
+    {"lavender", myRGB(230, 230, 250)},
+    {"LavenderBlush", myRGB(255, 240, 245)},
+    {"LawnGreen", myRGB(124, 252, 0)},
+    {"LemonChiffon", myRGB(255, 250, 205)},
+    {"LightBlue", myRGB(176, 226, 255)},
+    {"LightCoral", myRGB(240, 128, 128)},
+    {"LightCyan", myRGB(224, 255, 255)},
+    {"LightGoldenrod", myRGB(238, 221, 130)},
+    {"LightGoldenrodYellow", myRGB(250, 250, 210)},
+    {"LightGray", myRGB(168, 168, 168)},
+    {"LightPink", myRGB(255, 182, 193)},
+    {"LightSalmon", myRGB(255, 160, 122)},
+    {"LightSeaGreen", myRGB(32, 178, 170)},
+    {"LightSkyBlue", myRGB(135, 206, 250)},
+    {"LightSlateBlue", myRGB(132, 112, 255)},
+    {"LightSlateGray", myRGB(119, 136, 153)},
+    {"LightSteelBlue", myRGB(124, 152, 211)},
+    {"LightYellow", myRGB(255, 255, 224)},
+    {"LimeGreen", myRGB(0, 175, 20)},
+    {"linen", myRGB(250, 240, 230)},
+    {"Magenta", myRGB(255, 0, 255)},
+    {"Maroon", myRGB(143, 0, 82)},
+    {"MediumAquamarine", myRGB(0, 147, 143)},
+    {"MediumBlue", myRGB(50, 50, 204)},
+    {"MediumForestGreen", myRGB(50, 129, 75)},
+    {"MediumGoldenrod", myRGB(209, 193, 102)},
+    {"MediumOrchid", myRGB(189, 82, 189)},
+    {"MediumPurple", myRGB(147, 112, 219)},
+    {"MediumSeaGreen", myRGB(52, 119, 102)},
+    {"MediumSlateBlue", myRGB(106, 106, 141)},
+    {"MediumSpringGreen", myRGB(35, 142, 35)},
+    {"MediumTurquoise", myRGB(0, 210, 210)},
+    {"MediumVioletRed", myRGB(213, 32, 121)},
+    {"MidnightBlue", myRGB(47, 47, 100)},
+    {"MintCream", myRGB(245, 255, 250)},
+    {"MistyRose", myRGB(255, 228, 225)},
+    {"moccasin", myRGB(255, 228, 181)},
+    {"NavajoWhite", myRGB(255, 222, 173)},
+    {"Navy", myRGB(35, 35, 117)},
+    {"NavyBlue", myRGB(35, 35, 117)},
+    {"OldLace", myRGB(253, 245, 230)},
+    {"OliveDrab", myRGB(107, 142, 35)},
+    {"Orange", myRGB(255, 135, 0)},
+    {"OrangeRed", myRGB(255, 69, 0)},
+    {"Orchid", myRGB(239, 132, 239)},
+    {"PaleGoldenrod", myRGB(238, 232, 170)},
+    {"PaleGreen", myRGB(115, 222, 120)},
+    {"PaleTurquoise", myRGB(175, 238, 238)},
+    {"PaleVioletRed", myRGB(219, 112, 147)},
+    {"PapayaWhip", myRGB(255, 239, 213)},
+    {"PeachPuff", myRGB(255, 218, 185)},
+    {"peru", myRGB(205, 133, 63)},
+    {"Pink", myRGB(255, 181, 197)},
+    {"Plum", myRGB(197, 72, 155)},
+    {"PowderBlue", myRGB(176, 224, 230)},
+    {"purple", myRGB(160, 32, 240)},
+    {"Red", myRGB(255, 0, 0)},
+    {"RosyBrown", myRGB(188, 143, 143)},
+    {"RoyalBlue", myRGB(65, 105, 225)},
+    {"SaddleBrown", myRGB(139, 69, 19)},
+    {"Salmon", myRGB(233, 150, 122)},
+    {"SandyBrown", myRGB(244, 164, 96)},
+    {"SeaGreen", myRGB(82, 149, 132)},
+    {"seashell", myRGB(255, 245, 238)},
+    {"Sienna", myRGB(150, 82, 45)},
+    {"SkyBlue", myRGB(114, 159, 255)},
+    {"SlateBlue", myRGB(126, 136, 171)},
+    {"SlateGray", myRGB(112, 128, 144)},
+    {"snow", myRGB(255, 250, 250)},
+    {"SpringGreen", myRGB(65, 172, 65)},
+    {"SteelBlue", myRGB(84, 112, 170)},
+    {"Tan", myRGB(222, 184, 135)},
+    {"Thistle", myRGB(216, 191, 216)},
+    {"tomato", myRGB(255, 99, 71)},
+    {"Transparent", myRGB(0, 0, 1)},
+    {"Turquoise", myRGB(25, 204, 223)},
+    {"Violet", myRGB(156, 62, 206)},
+    {"VioletRed", myRGB(243, 62, 150)},
+    {"Wheat", myRGB(245, 222, 179)},
+    {"White", myRGB(255, 255, 255)},
+    {"WhiteSmoke", myRGB(245, 245, 245)},
+    {"Yellow", myRGB(255, 255, 0)},
+    {"YellowGreen", myRGB(50, 216, 56)},
+    NULL
+};
+
+static int numTheRGBRecords = 234;
diff --git a/libXpm/src/scan.c b/libXpm/src/scan.c
new file mode 100644
index 000000000..eab1c434c
--- /dev/null
+++ b/libXpm/src/scan.c
@@ -0,0 +1,1025 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* scan.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Scanning utility for XPM file format                                       *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/scan.c,v 1.2 2001/10/28 03:32:11 tsi Exp $ */
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#define MAXPRINTABLE 92			/* number of printable ascii chars
+					 * minus \ and " for string compat
+					 * and ? to avoid ANSI trigraphs. */
+
+static char *printable =
+" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
+ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
+
+/*
+ * printable begin with a space, so in most case, due to my algorithm, when
+ * the number of different colors is less than MAXPRINTABLE, it will give a
+ * char follow by "nothing" (a space) in the readable xpm file
+ */
+
+
+typedef struct {
+    Pixel *pixels;
+    unsigned int *pixelindex;
+    unsigned int size;
+    unsigned int ncolors;
+    unsigned int mask_pixel;		/* whether there is or not */
+}      PixelsMap;
+
+LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
+			unsigned int *index_return));
+
+LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
+			    unsigned int *index_return));
+
+typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap,
+			    unsigned int *index_return);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
+			    unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
+			      unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
+			      unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
+			     unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
+			     unsigned int height, PixelsMap *pmap,
+			     storeFuncPtr storeFunc));
+# else /* AMIGA */
+LFUNC(AGetImagePixels, int, (XImage *image, unsigned int width,
+			     unsigned int height, PixelsMap *pmap,
+			     storeFuncPtr storeFunc));
+# endif/* AMIGA */
+#else  /* ndef FOR_MSW */
+LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
+			       unsigned int height, PixelsMap *pmap,
+			       storeFuncPtr storeFunc));
+#endif
+LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
+				  XpmAttributes *attributes));
+
+LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, 
+			     unsigned int ncolors, 
+			     Pixel *pixels, unsigned int mask,
+			     unsigned int cpp, XpmAttributes *attributes));
+
+/*
+ * This function stores the given pixel in the given arrays which are grown
+ * if not large enough.
+ */
+static int
+storePixel(
+    Pixel		 pixel,
+    PixelsMap		*pmap,
+    unsigned int	*index_return)
+{
+    unsigned int i;
+    Pixel *p;
+    unsigned int ncolors;
+
+    if (*index_return) {		/* this is a transparent pixel! */
+	*index_return = 0;
+	return 0;
+    }
+    ncolors = pmap->ncolors;
+    p = pmap->pixels + pmap->mask_pixel;
+    for (i = pmap->mask_pixel; i < ncolors; i++, p++)
+	if (*p == pixel)
+	    break;
+    if (i == ncolors) {
+	if (ncolors >= pmap->size) {
+	    pmap->size *= 2;
+	    p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
+	    if (!p)
+		return (1);
+	    pmap->pixels = p;
+
+	}
+	(pmap->pixels)[ncolors] = pixel;
+	pmap->ncolors++;
+    }
+    *index_return = i;
+    return 0;
+}
+
+static int
+storeMaskPixel(
+    Pixel		 pixel,
+    PixelsMap		*pmap,
+    unsigned int	*index_return)
+{
+    if (!pixel) {
+	if (!pmap->ncolors) {
+	    pmap->ncolors = 1;
+	    (pmap->pixels)[0] = 0;
+	    pmap->mask_pixel = 1;
+	}
+	*index_return = 1;
+    } else
+	*index_return = 0;
+    return 0;
+}
+
+/* function call in case of error */
+#undef RETURN
+#define RETURN(status) \
+do { \
+      ErrorStatus = status; \
+      goto error; \
+} while(0)
+
+/*
+ * This function scans the given image and stores the found informations in
+ * the given XpmImage structure.
+ */
+int
+XpmCreateXpmImageFromImage(
+    Display		*display,
+    XImage		*image,
+    XImage		*shapeimage,
+    XpmImage		*xpmimage,
+    XpmAttributes	*attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    unsigned int cpp;
+
+    /* variables to return */
+    PixelsMap pmap;
+    XpmColor *colorTable = NULL;
+    int ErrorStatus = 0;
+
+    /* calculation variables */
+    unsigned int width = 0;
+    unsigned int height = 0;
+    unsigned int cppm;			/* minimum chars per pixel */
+    unsigned int c;
+
+    /* initialize pmap */
+    pmap.pixels = NULL;
+    pmap.pixelindex = NULL;
+    pmap.size = 256;			/* should be enough most of the time */
+    pmap.ncolors = 0;
+    pmap.mask_pixel = 0;
+
+    /*
+     * get geometry
+     */
+    if (image) {
+	width = image->width;
+	height = image->height;
+    } else if (shapeimage) {
+	width = shapeimage->width;
+	height = shapeimage->height;
+    }
+
+    /*
+     * retrieve information from the XpmAttributes
+     */
+    if (attributes && (attributes->valuemask & XpmCharsPerPixel
+/* 3.2 backward compatibility code */
+		       || attributes->valuemask & XpmInfos))
+/* end 3.2 bc */
+	cpp = attributes->cpp;
+    else
+	cpp = 0;
+
+    if ((height > 0 && width >= UINT_MAX / height) ||
+	width * height >= UINT_MAX / sizeof(unsigned int))
+	RETURN(XpmNoMemory);
+    pmap.pixelindex =
+	(unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
+    if (!pmap.pixelindex)
+	RETURN(XpmNoMemory);
+
+    if (pmap.size >= UINT_MAX / sizeof(Pixel)) 
+	RETURN(XpmNoMemory);
+
+    pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
+    if (!pmap.pixels)
+	RETURN(XpmNoMemory);
+
+    /*
+     * scan shape mask if any
+     */
+    if (shapeimage) {
+#ifndef FOR_MSW
+# ifndef AMIGA
+	ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
+				      storeMaskPixel);
+# else
+	ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap,
+				      storeMaskPixel);
+# endif
+#else
+	ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
+					&pmap, storeMaskPixel);
+#endif
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+    }
+
+    /*
+     * scan the image data
+     * 
+     * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
+     * functions, otherwise use slower but sure general one.
+     * 
+     */
+
+    if (image) {
+#ifndef FOR_MSW
+# ifndef AMIGA
+	if (((image->bits_per_pixel | image->depth) == 1)  &&
+	    (image->byte_order == image->bitmap_bit_order))
+	    ErrorStatus = GetImagePixels1(image, width, height, &pmap,
+					  storePixel);
+	else if (image->format == ZPixmap) {
+	    if (image->bits_per_pixel == 8)
+		ErrorStatus = GetImagePixels8(image, width, height, &pmap);
+	    else if (image->bits_per_pixel == 16)
+		ErrorStatus = GetImagePixels16(image, width, height, &pmap);
+	    else if (image->bits_per_pixel == 32)
+		ErrorStatus = GetImagePixels32(image, width, height, &pmap);
+	} else
+	    ErrorStatus = GetImagePixels(image, width, height, &pmap);
+# else
+	ErrorStatus = AGetImagePixels(image, width, height, &pmap,
+				      storePixel);
+# endif
+#else
+	ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap,
+					storePixel);
+#endif
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+    }
+
+    /*
+     * get rgb values and a string of char, and possibly a name for each
+     * color
+     */
+    if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor))
+	RETURN(XpmNoMemory);
+    colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
+    if (!colorTable)
+	RETURN(XpmNoMemory);
+
+    /* compute the minimal cpp */
+    for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
+	c *= MAXPRINTABLE;
+    if (cpp < cppm)
+	cpp = cppm;
+
+    if (pmap.mask_pixel) {
+	ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
+	if (ErrorStatus != XpmSuccess)
+	    RETURN(ErrorStatus);
+    }
+
+    ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors,
+				  pmap.pixels, pmap.mask_pixel, cpp,
+				  attributes);
+    if (ErrorStatus != XpmSuccess)
+	RETURN(ErrorStatus);
+
+    /*
+     * store found informations in the XpmImage structure
+     */
+    xpmimage->width = width;
+    xpmimage->height = height;
+    xpmimage->cpp = cpp;
+    xpmimage->ncolors = pmap.ncolors;
+    xpmimage->colorTable = colorTable;
+    xpmimage->data = pmap.pixelindex;
+
+    XpmFree(pmap.pixels);
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (pmap.pixelindex)
+	XpmFree(pmap.pixelindex);
+    if (pmap.pixels)
+	XpmFree(pmap.pixels);
+    if (colorTable)
+	xpmFreeColorTable(colorTable, pmap.ncolors);
+
+    return (ErrorStatus);
+}
+
+static int
+ScanTransparentColor(
+    XpmColor		*color,
+    unsigned int	 cpp,
+    XpmAttributes	*attributes)
+{
+    char *s;
+    unsigned int a, b, c;
+
+    /* first get a character string */
+    a = 0;
+    if (cpp >= UINT_MAX - 1)
+	return (XpmNoMemory);
+    if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
+	return (XpmNoMemory);
+    *s++ = printable[c = a % MAXPRINTABLE];
+    for (b = 1; b < cpp; b++, s++)
+	*s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
+    *s = '\0';
+
+    /* then retreive related info from the attributes if any */
+    if (attributes && (attributes->valuemask & XpmColorTable
+/* 3.2 backward compatibility code */
+		       || attributes->valuemask & XpmInfos)
+/* end 3.2 bc */
+	&& attributes->mask_pixel != XpmUndefPixel) {
+
+	unsigned int key;
+	char **defaults = (char **) color;
+	char **mask_defaults;
+
+/* 3.2 backward compatibility code */
+	if (attributes->valuemask & XpmColorTable)
+/* end 3.2 bc */
+	    mask_defaults = (char **) (
+		attributes->colorTable + attributes->mask_pixel);
+/* 3.2 backward compatibility code */
+	else
+	    mask_defaults = (char **)
+		((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
+/* end 3.2 bc */
+	for (key = 1; key <= NKEYS; key++) {
+	    if ((s = mask_defaults[key])) {
+		defaults[key] = (char *) xpmstrdup(s);
+		if (!defaults[key])
+		    return (XpmNoMemory);
+	    }
+	}
+    } else {
+	color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR);
+	if (!color->c_color)
+	    return (XpmNoMemory);
+    }
+    return (XpmSuccess);
+}
+
+static int
+ScanOtherColors(
+    Display		*display,
+    XpmColor		*colors,
+    unsigned int	 ncolors,
+    Pixel		*pixels,
+    unsigned int	 mask,
+    unsigned int	 cpp,
+    XpmAttributes	*attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Colormap colormap;
+    char *rgb_fname;
+
+#ifndef FOR_MSW
+    xpmRgbName rgbn[MAX_RGBNAMES];
+#else
+    xpmRgbName *rgbn = NULL; 
+#endif    
+    int rgbn_max = 0;
+    unsigned int i, j, c, i2;
+    XpmColor *color;
+    XColor *xcolors = NULL, *xcolor;
+    char *colorname, *s;
+    XpmColor *colorTable = NULL, **oldColorTable = NULL;
+    unsigned int ancolors = 0;
+    Pixel *apixels = NULL;
+    unsigned int mask_pixel = 0;
+    Bool found;
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmColormap))
+	colormap = attributes->colormap;
+    else
+	colormap = XDefaultColormap(display, XDefaultScreen(display));
+    if (attributes && (attributes->valuemask & XpmRgbFilename))
+	rgb_fname = attributes->rgb_fname;
+    else
+	rgb_fname = NULL;
+
+    /* start from the right element */
+    if (mask) {
+	colors++;
+	ncolors--;
+	pixels++;
+    }
+
+    /* first get character strings and rgb values */
+    if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1)
+	return (XpmNoMemory);
+    xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
+    if (!xcolors)
+	return (XpmNoMemory);
+
+    for (i = 0, i2 = mask, color = colors, xcolor = xcolors;
+	 i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
+
+	if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
+	    XpmFree(xcolors);
+	    return (XpmNoMemory);
+	}
+	*s++ = printable[c = i2 % MAXPRINTABLE];
+	for (j = 1; j < cpp; j++, s++)
+	    *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
+	*s = '\0';
+
+	xcolor->pixel = *pixels;
+    }
+    XQueryColors(display, colormap, xcolors, ncolors);
+
+#ifndef FOR_MSW
+    /* read the rgb file if any was specified */
+    if (rgb_fname)
+	rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
+#else
+    /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
+    rgbn_max = xpmReadRgbNames(NULL, NULL);
+#endif
+
+    if (attributes && attributes->valuemask & XpmColorTable) {
+	colorTable = attributes->colorTable;
+	ancolors = attributes->ncolors;
+	apixels = attributes->pixels;
+	mask_pixel = attributes->mask_pixel;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes && attributes->valuemask & XpmInfos) {
+	oldColorTable = (XpmColor **) attributes->colorTable;
+	ancolors = attributes->ncolors;
+	apixels = attributes->pixels;
+	mask_pixel = attributes->mask_pixel;
+    }
+/* end 3.2 bc */
+
+    for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
+						  i++, color++, xcolor++) {
+
+	/* look for related info from the attributes if any */
+	found = False;
+	if (ancolors) {
+	    unsigned int offset = 0;
+
+	    for (j = 0; j < ancolors; j++) {
+		if (j == mask_pixel) {
+		    offset = 1;
+		    continue;
+		}
+		if (apixels[j - offset] == xcolor->pixel)
+		    break;
+	    }
+	    if (j != ancolors) {
+		unsigned int key;
+		char **defaults = (char **) color;
+		char **adefaults;
+
+/* 3.2 backward compatibility code */
+		if (oldColorTable)
+		    adefaults = (char **) oldColorTable[j];
+		else
+/* end 3.2 bc */
+		    adefaults = (char **) (colorTable + j);
+
+		found = True;
+		for (key = 1; key <= NKEYS; key++) {
+		    if ((s = adefaults[key]))
+			defaults[key] = (char *) xpmstrdup(s);
+		}
+	    }
+	}
+	if (!found) {
+	    /* if nothing found look for a color name */
+	    colorname = NULL;
+	    if (rgbn_max)
+		colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
+					  xcolor->green, xcolor->blue);
+	    if (colorname)
+		color->c_color = (char *) xpmstrdup(colorname);
+	    else {
+		/* at last store the rgb value */
+		char buf[BUFSIZ];
+#ifndef FOR_MSW
+		sprintf(buf, "#%04X%04X%04X",
+			xcolor->red, xcolor->green, xcolor->blue);
+#else   
+		sprintf(buf, "#%02x%02x%02x",
+			xcolor->red, xcolor->green, xcolor->blue);
+#endif			
+		color->c_color = (char *) xpmstrdup(buf);
+	    }
+	    if (!color->c_color) {
+		XpmFree(xcolors);
+		xpmFreeRgbNames(rgbn, rgbn_max);
+		return (XpmNoMemory);
+	    }
+	}
+    }
+
+    XpmFree(xcolors);
+    xpmFreeRgbNames(rgbn, rgbn_max);
+    return (XpmSuccess);
+}
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/*
+ * The functions below are written from X11R5 MIT's code (XImUtil.c)
+ *
+ * The idea is to have faster functions than the standard XGetPixel function
+ * to scan the image data. Indeed we can speed up things by suppressing tests
+ * performed for each pixel. We do exactly the same tests but at the image
+ * level.
+ */
+
+static unsigned long Const low_bits_table[] = {
+    0x00000000, 0x00000001, 0x00000003, 0x00000007,
+    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+    0xffffffff
+};
+
+/*
+ * Default method to scan pixels of an image data structure.
+ * The algorithm used is:
+ *
+ *	copy the source bitmap_unit or Zpixel into temp
+ *	normalize temp if needed
+ *	extract the pixel bits into return value
+ *
+ */
+
+static int
+GetImagePixels(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    PixelsMap		*pmap)
+{
+    char *src;
+    char *dst;
+    unsigned int *iptr;
+    char *data;
+    unsigned int x, y;
+    int bits, depth, ibu, ibpp, offset, i;
+    unsigned long lbt;
+    Pixel pixel, px;
+
+    data = image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    ibpp = image->bits_per_pixel;
+    offset = image->xoffset;
+
+    if (image->bitmap_unit < 0)
+	    return (XpmNoMemory);
+
+    if ((image->bits_per_pixel | image->depth) == 1) {
+	ibu = image->bitmap_unit;
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		src = &data[XYINDEX(x, y, image)];
+		dst = (char *) &pixel;
+		pixel = 0;
+		for (i = ibu >> 3; --i >= 0;)
+		    *dst++ = *src++;
+		XYNORMALIZE(&pixel, image);
+		bits = (x + offset) % ibu;
+		pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
+		if (ibpp != depth)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    } else if (image->format == XYPixmap) {
+	int nbytes, bpl, j;
+	long plane = 0;
+	ibu = image->bitmap_unit;
+	nbytes = ibu >> 3;
+	bpl = image->bytes_per_line;
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		pixel = 0;
+		plane = 0;
+		for (i = depth; --i >= 0;) {
+		    src = &data[XYINDEX(x, y, image) + plane];
+		    dst = (char *) &px;
+		    px = 0;
+		    for (j = nbytes; --j >= 0;)
+			*dst++ = *src++;
+		    XYNORMALIZE(&px, image);
+		    bits = (x + offset) % ibu;
+		    pixel = (pixel << 1) |
+			    (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1);
+		    plane = plane + (bpl * height);
+		}
+		if (ibpp != depth)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    } else if (image->format == ZPixmap) {
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		src = &data[ZINDEX(x, y, image)];
+		dst = (char *) &px;
+		px = 0;
+		for (i = (ibpp + 7) >> 3; --i >= 0;)
+		    *dst++ = *src++;
+		ZNORMALIZE(&px, image);
+		pixel = 0;
+		for (i = sizeof(unsigned long); --i >= 0;)
+		    pixel = (pixel << 8) | ((unsigned char *) &px)[i];
+		if (ibpp == 4) {
+		    if (x & 1)
+			pixel >>= 4;
+		    else
+			pixel &= 0xf;
+		}
+		if (ibpp != depth)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    } else
+	return (XpmColorError); /* actually a bad image */
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 32-bits Z image data structure
+ */
+
+#if !defined(WORD64) && !defined(LONG64)
+static unsigned long byteorderpixel = MSBFirst << 24;
+#endif
+
+static int
+GetImagePixels32(
+    XImage		 *image,
+    unsigned int	 width,
+    unsigned int	 height,
+    PixelsMap		*pmap)
+{
+    unsigned char *addr;
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		pixel = *((unsigned long *) addr);
+		if (depth != 32)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		pixel = ((unsigned long) addr[0] << 24 |
+			 (unsigned long) addr[1] << 16 |
+			 (unsigned long) addr[2] << 8 |
+			 addr[3]);
+		if (depth != 32)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    else
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX32(x, y, image)];
+		pixel = (addr[0] |
+			 (unsigned long) addr[1] << 8 |
+			 (unsigned long) addr[2] << 16 |
+			 (unsigned long) addr[3] << 24);
+		if (depth != 32)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 16-bits Z image data structure
+ */
+
+static int
+GetImagePixels16(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    PixelsMap		*pmap)
+{
+    unsigned char *addr;
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    if (image->byte_order == MSBFirst)
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX16(x, y, image)];
+		pixel = addr[0] << 8 | addr[1];
+		if (depth != 16)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    else
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		addr = &data[ZINDEX16(x, y, image)];
+		pixel = addr[0] | addr[1] << 8;
+		if (depth != 16)
+		    pixel &= lbt;
+		if (storePixel(pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 8-bits Z image data structure
+ */
+
+static int
+GetImagePixels8(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    PixelsMap		*pmap)
+{
+    unsigned int *iptr;
+    unsigned char *data;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    for (y = 0; y < height; y++)
+	for (x = 0; x < width; x++, iptr++) {
+	    pixel = data[ZINDEX8(x, y, image)];
+	    if (depth != 8)
+		pixel &= lbt;
+	    if (storePixel(pixel, pmap, iptr))
+		return (XpmNoMemory);
+	}
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 1-bit depth Z image data structure
+ */
+
+static int
+GetImagePixels1(
+    XImage		*image,
+    unsigned int	 width,
+    unsigned int	 height,
+    PixelsMap		 *pmap,
+    storeFuncPtr	 storeFunc)
+{
+    unsigned int *iptr;
+    unsigned int x, y;
+    char *data;
+    Pixel pixel;
+    int xoff, yoff, offset, bpl;
+
+    data = image->data;
+    iptr = pmap->pixelindex;
+    offset = image->xoffset;
+    bpl = image->bytes_per_line;
+
+    if (image->bitmap_bit_order == MSBFirst)
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		xoff = x + offset;
+		yoff = y * bpl + (xoff >> 3);
+		xoff &= 7;
+		pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0;
+		if ((*storeFunc) (pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    else
+	for (y = 0; y < height; y++)
+	    for (x = 0; x < width; x++, iptr++) {
+		xoff = x + offset;
+		yoff = y * bpl + (xoff >> 3);
+		xoff &= 7;
+		pixel = (data[yoff] & (1 << xoff)) ? 1 : 0;
+		if ((*storeFunc) (pixel, pmap, iptr))
+		    return (XpmNoMemory);
+	    }
+    return (XpmSuccess);
+}
+
+# else /* AMIGA */
+
+#define CLEAN_UP(status) \
+do {\
+    if (pixels) XpmFree (pixels);\
+    if (tmp_img) FreeXImage (tmp_img);\
+    return (status);\
+} while(0)
+
+static int
+AGetImagePixels (
+    XImage        *image,
+    unsigned int   width,
+    unsigned int   height,
+    PixelsMap     *pmap,
+    int          (*storeFunc) (Pixel, PixelsMap *, unsigned int *))
+{
+    unsigned int   *iptr;
+    unsigned int    x, y;
+    unsigned char  *pixels;
+    XImage         *tmp_img;
+    
+    pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels));
+    if (pixels == NULL)
+	return XpmNoMemory;
+    
+    tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
+    if (tmp_img == NULL)
+	CLEAN_UP (XpmNoMemory);
+    
+    iptr = pmap->pixelindex;
+    for (y = 0; y < height; ++y)
+    {
+	ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp);
+	for (x = 0; x < width; ++x, ++iptr)
+	{
+	    if ((*storeFunc) (pixels[x], pmap, iptr))
+		CLEAN_UP (XpmNoMemory);
+	}
+    }
+    
+    CLEAN_UP (XpmSuccess);
+}
+
+#undef CLEAN_UP
+
+# endif/* AMIGA */
+#else  /* ndef FOR_MSW */
+static int
+MSWGetImagePixels(
+    Display	 *display,
+    XImage	 *image,
+    unsigned int  width,
+    unsigned int  height,
+    PixelsMap	 *pmap,
+    int		(*storeFunc) (Pixel, PixelsMap*, unsigned int *))
+{
+    unsigned int *iptr;
+    unsigned int x, y;
+    Pixel pixel;
+
+    iptr = pmap->pixelindex;
+
+    SelectObject(*display, image->bitmap);
+    for (y = 0; y < height; y++) {
+	for (x = 0; x < width; x++, iptr++) {
+	    pixel = GetPixel(*display, x, y);
+	    if ((*storeFunc) (pixel, pmap, iptr))
+		return (XpmNoMemory);
+	}
+    }
+    return (XpmSuccess);
+}
+
+#endif
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+int
+XpmCreateXpmImageFromPixmap(
+    Display		*display,
+    Pixmap		 pixmap,
+    Pixmap		 shapemask,
+    XpmImage		*xpmimage,
+    XpmAttributes	*attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+	width = attributes->width;
+	height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+	xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+	xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+				 &width, &height);
+
+    /* create the related XpmImage */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
+					     xpmimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+	XDestroyImage(ximage);
+    if (shapeimage)
+	XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
+
+# endif/* not AMIGA */
+#endif /* ndef FOR_MSW */
diff --git a/libXpm/src/simx.c b/libXpm/src/simx.c
new file mode 100644
index 000000000..97b3b5f03
--- /dev/null
+++ b/libXpm/src/simx.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* simx.c: 0.1a                                                                *
+*                                                                             *
+* This emulates some Xlib functionality for MSW. It's not a general solution, *
+* it is close related to XPM-lib. It is only intended to satisfy what is need *
+* there. Thus allowing to read XPM files under MS windows.                    *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+#ifdef FOR_MSW
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xpm.h"
+#include "xpmi.h"			/* for XpmMalloc */
+
+/*
+ * On DOS size_t is only 2 bytes, thus malloc(size_t s) can only malloc
+ * 64K. BUT an expression data=malloc(width*height) may result in an
+ * overflow. So this function takes a long as input, and returns NULL if the
+ * request is larger than 64K, is size_t is only 2 bytes.
+ *
+ * This requires casts like XpmMalloc( (long)width*(long(height)), else it
+ * might have no effect at all.
+ */
+
+void *
+boundCheckingMalloc(long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {	/* same size, just do it */
+	return (malloc((size_t) s));
+    } else {
+	if (sizeof(size_t) == 2) {
+	    if (s > 0xFFFF)
+		return (NULL);		/* to large, size_t with 2 bytes
+					 * only allows 16 bits */
+	    else
+		return (malloc((size_t) s));
+	} else {			/* it's not a long, not 2 bytes,
+					 * what is it ??? */
+	    return (malloc((size_t) s));
+	}
+    }
+}
+void *
+boundCheckingCalloc(long num, long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {	/* same size, just do it */
+	return (calloc((size_t) num, (size_t) s));
+    } else {
+	if (sizeof(size_t) == 2) {
+	    if (s > 0xFFFF || num * s > 0xFFFF)
+		return (NULL);		/* to large, size_t with 2 bytes
+					 * only allows 16 bits */
+	    else
+		return (calloc((size_t) num, (size_t) s));
+	} else {			/* it's not a long, not 2 bytes,
+					 * what is it ??? */
+	    return (calloc((size_t) num, (size_t) s));
+	}
+    }
+}
+void *
+boundCheckingRealloc(void *p, long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {	/* same size, just do it */
+	return (realloc(p, (size_t) s));
+    } else {
+	if (sizeof(size_t) == 2) {
+	    if (s > 0xFFFF)
+		return (NULL);		/* to large, size_t with 2 bytes
+					 * only allows 16 bits */
+	    else
+		return (realloc(p, (size_t) s));
+	} else {			/* it's not a long, not 2 bytes,
+					 * what is it ??? */
+	    return (realloc(p, (size_t) s));
+	}
+    }
+}
+
+/* static Visual theVisual = { 0 }; */
+Visual *
+XDefaultVisual(Display *display, Screen *screen)
+{
+    return (NULL);			/* struct could contain info about
+					 * MONO, GRAY, COLOR */
+}
+
+Screen *
+XDefaultScreen(Display *d)
+{
+    return (NULL);
+}
+
+/* I get only 1 plane but 8 bits per pixel,
+   so I think BITSPIXEL should be depth */
+int 
+XDefaultDepth(Display *display, Screen *screen)
+{
+    int d, b;
+
+    b = GetDeviceCaps(*display, BITSPIXEL);
+    d = GetDeviceCaps(*display, PLANES);
+    return (b);
+}
+
+Colormap *
+XDefaultColormap(Display *display, Screen *screen)
+{
+    return (NULL);
+}
+
+/* convert hex color names,
+   wrong digits (not a-f,A-F,0-9) are treated as zero */
+static int 
+hexCharToInt(c)
+{
+    int r;
+
+    if (c >= '0' && c <= '9')
+	r = c - '0';
+    else if (c >= 'a' && c <= 'f')
+	r = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'F')
+	r = c - 'A' + 10;
+    else
+	r = 0;
+
+    return (r);
+}
+
+static int 
+rgbFromHex(char *hex, int *r, int *g, int *b)
+{
+    int len;
+
+    if (hex == NULL || hex[0] != '#')
+	return (0);
+
+    len = strlen(hex);
+    if (len == 3 + 1) {
+	*r = hexCharToInt(hex[1]);
+	*g = hexCharToInt(hex[2]);
+	*b = hexCharToInt(hex[3]);
+    } else if (len == 6 + 1) {
+	*r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]);
+	*g = hexCharToInt(hex[3]) * 16 + hexCharToInt(hex[4]);
+	*b = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]);
+    } else if (len == 12 + 1) {
+	/* it's like c #32329999CCCC */
+	/* so for now only take two digits */
+	*r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]);
+	*g = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]);
+	*b = hexCharToInt(hex[9]) * 16 + hexCharToInt(hex[10]);
+    } else
+	return (0);
+
+    return (1);
+}
+
+/* Color related functions */
+int 
+XParseColor(Display *d, Colormap *cmap, char *name, XColor *color)
+{
+    int r, g, b;			/* only 8 bit values used */
+    int okay;
+
+/* TODO: use colormap via PALETTE */
+    /* parse name either in table or #RRGGBB #RGB */
+    if (name == NULL)
+	return (0);
+
+    if (name[0] == '#') {		/* a hex string */
+	okay = rgbFromHex(name, &r, &g, &b);
+    } else {
+	okay = xpmGetRGBfromName(name, &r, &g, &b);
+    }
+
+    if (okay) {
+	color->pixel = RGB(r, g, b);
+	color->red = (BYTE) r;
+	color->green = (BYTE) g;
+	color->blue = (BYTE) b;
+	return (1);
+    } else
+	return (0);			/* --> ColorError */
+}
+
+
+int 
+XAllocColor(Display *d, Colormap cmap, XColor *color)
+{
+/* colormap not used yet so color->pixel is the real COLORREF (RBG) and not an
+   index in some colormap as in X */
+    return (1);
+}
+void 
+XQueryColors(Display *display, Colormap *colormap,
+	     XColor *xcolors, int ncolors)
+{
+/* under X this fills the rgb values to given .pixel */
+/* since there no colormap use FOR_MSW (not yet!!), rgb is plain encoded */
+    XColor *xc = xcolors;
+    int i;
+
+    for (i = 0; i < ncolors; i++, xc++) {
+	xc->red = GetRValue(xc->pixel);
+	xc->green = GetGValue(xc->pixel);
+	xc->blue = GetBValue(xc->pixel);
+    }
+    return;
+}
+int 
+XFreeColors(Display *d, Colormap cmap,
+	    unsigned long pixels[], int npixels, unsigned long planes)
+{
+    /* no colormap yet */
+    return (0);				/* correct ??? */
+}
+
+/* XImage functions */
+XImage *
+XCreateImage(Display *d, Visual *v,
+	     int depth, int format,
+	     int x, int y, int width, int height,
+	     int pad, int foo)
+{
+    XImage *img = (XImage *) XpmMalloc(sizeof(XImage));
+
+    if (img) {
+	/*JW: This is what it should be, but the picture comes out
+	      just black!?  It appears to be doing monochrome reduction,
+	      but I've got no clue why.  Using CreateBitmap() is supposed
+	      to be slower, but otherwise ok
+	  if ( depth == GetDeviceCaps(*d, BITSPIXEL) ) {
+	    img->bitmap = CreateCompatibleBitmap(*d, width, height);
+        } else*/ {
+	    img->bitmap = CreateBitmap(width, height, 1 /* plane */ ,
+				       depth /* bits per pixel */ , NULL);
+	}
+	img->width = width;
+	img->height = height;
+	img->depth = depth;
+    }
+    return (img);
+
+}
+
+void 
+XImageFree(XImage *img)
+{
+    if (img) {
+	XpmFree(img);
+    }
+}
+void 
+XDestroyImage(XImage *img)
+{
+    if (img) {
+	DeleteObject(img->bitmap);	/* check return ??? */
+	XImageFree(img);
+    }
+}
+
+#endif
diff --git a/libXpm/src/simx.h b/libXpm/src/simx.h
new file mode 100644
index 000000000..7c4c4b9ec
--- /dev/null
+++ b/libXpm/src/simx.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* simx.h: 0.1a                                                                *
+*                                                                             *
+* This emulates some Xlib functionality for MSW. It's not a general solution, *
+* it is close related to XPM-lib. It is only intended to satisfy what is need *
+* there. Thus allowing to read XPM files under MS windows.                    *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+
+#ifndef _SIMX_H
+#define _SIMX_H
+
+#ifdef FOR_MSW
+
+#include "windows.h"			/* MS windows GDI types */
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#define NO_ZPIPE
+
+/*
+ * minimal portability layer between ansi and KR C
+ */
+/* this comes from xpm.h, and is here again, to avoid complicated
+    includes, since this is included from xpm.h */
+/* these defines get undefed at the end of this file */
+#if __STDC__ || defined(__cplusplus) || defined(c_plusplus)
+ /* ANSI || C++ */
+#define FUNC(f, t, p) extern t f p
+#define LFUNC(f, t, p) static t f p
+#else /* k&R */
+#define FUNC(f, t, p) extern t f()
+#define LFUNC(f, t, p) static t f()
+#endif
+
+
+FUNC(boundCheckingMalloc, void *, (long s));
+FUNC(boundCheckingCalloc, void *, (long num, long s));
+FUNC(boundCheckingRealloc, void *, (void *p, long s));
+
+/* define MSW types for X window types,
+   I don't know much about MSW, but the following defines do the job */
+
+typedef HDC Display;			/* this should be similar */
+typedef void *Screen;			/* not used */
+typedef void *Visual;			/* not used yet, is for GRAY, COLOR,
+					 * MONO */
+
+typedef void *Colormap;			/* should be COLORPALETTE, not done
+					 * yet */
+
+typedef COLORREF Pixel;
+
+#define PIXEL_ALREADY_TYPEDEFED		/* to let xpm.h know about it */
+
+typedef struct {
+    Pixel pixel;
+    BYTE red, green, blue;
+}      XColor;
+
+typedef struct {
+    HBITMAP bitmap;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+}      XImage;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+/* some replacements for X... functions */
+
+/* XDefaultXXX */
+    FUNC(XDefaultVisual, Visual *, (Display *display, Screen *screen));
+    FUNC(XDefaultScreen, Screen *, (Display *d));
+    FUNC(XDefaultColormap, Colormap *, (Display *display, Screen *screen));
+    FUNC(XDefaultDepth, int, (Display *d, Screen *s));
+
+/* color related */
+    FUNC(XParseColor, int, (Display *, Colormap *, char *, XColor *));
+    FUNC(XAllocColor, int, (Display *, Colormap, XColor *));
+    FUNC(XQueryColors, void, (Display *display, Colormap *colormap,
+			      XColor *xcolors, int ncolors));
+    FUNC(XFreeColors, int, (Display *d, Colormap cmap,
+			    unsigned long pixels[],
+			    int npixels, unsigned long planes));
+/* XImage */
+    FUNC(XCreateImage, XImage *, (Display *, Visual *, int depth, int format,
+				  int x, int y, int width, int height,
+				  int pad, int foo));
+
+/* free and destroy bitmap */
+    FUNC(XDestroyImage, void /* ? */ , (XImage *));
+/* free only, bitmap remains */
+    FUNC(XImageFree, void, (XImage *));
+#if defined(__cplusplus) || defined(c_plusplus)
+} /* end of extern "C" */
+#endif /* cplusplus */
+
+#define ZPixmap 1			/* not really used */
+#define XYBitmap 1			/* not really used */
+
+#ifndef True
+#define True 1
+#define False 0
+#endif
+#ifndef Bool
+typedef BOOL Bool;		/* take MSW bool */
+#endif
+/* make these local here, simx.c gets the same from xpm.h */
+#undef LFUNC
+#undef FUNC
+
+/* Some functions and constants that have non-standard names in the
+   MS library.  */
+#define bzero(addr,sz) memset(addr, 0, sz)
+#define close _close
+#define fdopen _fdopen
+#define index strchr
+#define open _open
+#define O_RDONLY _O_RDONLY
+#define rindex strrchr
+#define strdup _strdup
+
+
+#endif /* def FOR_MSW */
+
+#endif /* _SIMX_H */
-- 
cgit v1.2.3