+ /* 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;
+ if (attributes && (attributes->valuemask & XpmColorClosure))
+ closure = attributes->color_closure;
+ else
+ closure = NULL;
+
+ 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 hastable
+ */
+ 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 */
+ 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
+ dc,
+#endif
+ data, width, height, ncolors, cpp, colorTable, hashtable,
+ image, image_pixels, shapeimage, shape_pixels)
+#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 */