Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright (C) 1989-95 GROUPE BULL
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a copy
      5  * of this software and associated documentation files (the "Software"), to
      6  * deal in the Software without restriction, including without limitation the
      7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      8  * sell copies of the Software, and to permit persons to whom the Software is
      9  * furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     17  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20  *
     21  * Except as contained in this notice, the name of GROUPE BULL shall not be
     22  * used in advertising or otherwise to promote the sale, use or other dealings
     23  * in this Software without prior written authorization from GROUPE BULL.
     24  */
     25 
     26 /*****************************************************************************\
     27 * create.c:                                                                   *
     28 *                                                                             *
     29 *  XPM library                                                                *
     30 *  Create an X image and possibly its related shape mask                      *
     31 *  from the given XpmImage.                                                   *
     32 *                                                                             *
     33 *  Developed by Arnaud Le Hors                                                *
     34 \*****************************************************************************/
     35 
     36 /* October 2004, source code review by Thomas Biege <thomas (at) suse.de> */
     37 
     38 #ifdef HAVE_CONFIG_H
     39 #include <config.h>
     40 #endif
     41 #include "XpmI.h"
     42 #include <ctype.h>
     43 
     44 #if defined(_MSC_VER)
     45 #define strcasecmp _stricmp
     46 #endif
     47 
     48 LFUNC(xpmVisualType, int, (Visual *visual));
     49 
     50 LFUNC(AllocColor, int, (Display *display, Colormap colormap,
     51 			char *colorname, XColor *xcolor, void *closure));
     52 LFUNC(FreeColors, int, (Display *display, Colormap colormap,
     53 			Pixel *pixels, int n, void *closure));
     54 
     55 LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
     56 			   Visual *visual, XColor *col,
     57 			   Pixel *image_pixel, Pixel *mask_pixel,
     58 			   Pixel *alloc_pixels, unsigned int *nalloc_pixels,
     59 			   XpmAttributes *attributes, XColor *cols, int ncols,
     60 			   XpmAllocColorFunc allocColor, void *closure));
     61 
     62 LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
     63 		      char *colorname, unsigned int color_index,
     64 		      Pixel *image_pixel, Pixel *mask_pixel,
     65 		      unsigned int *mask_pixel_index,
     66 		      Pixel *alloc_pixels, unsigned int *nalloc_pixels,
     67 		      Pixel *used_pixels, unsigned int *nused_pixels,
     68 		      XpmAttributes *attributes, XColor *cols, int ncols,
     69 		      XpmAllocColorFunc allocColor, void *closure));
     70 
     71 LFUNC(CreateXImage, int, (Display *display, Visual *visual,
     72 			  unsigned int depth, int format, unsigned int width,
     73                           unsigned int height, XImage **image_return));
     74 
     75 LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
     76                           XpmColor *colors, unsigned int ncolors,
     77                           Pixel *image_pixels, Pixel *mask_pixels,
     78                           unsigned int *mask_pixel_index,
     79                           Pixel *alloc_pixels, unsigned int *nalloc_pixels,
     80                           Pixel *used_pixels, unsigned int *nused_pixels));
     81 
     82 LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width,
     83 			       unsigned int height, unsigned int ncolors,
     84 			       unsigned int cpp, XpmColor *colorTable,
     85 			       xpmHashTable *hashtable,
     86 			       XImage *image, Pixel *image_pixels,
     87 			       XImage *mask, Pixel *mask_pixels));
     88 
     89 /* XImage pixel routines */
     90 LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
     91 			     unsigned int height, unsigned int *pixelindex,
     92 			     Pixel *pixels));
     93 
     94 LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
     95 			       unsigned int height, unsigned int *pixelindex,
     96 			       Pixel *pixels));
     97 
     98 LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
     99 			       unsigned int height, unsigned int *pixelindex,
    100 			       Pixel *pixels));
    101 
    102 LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
    103 			      unsigned int height, unsigned int *pixelindex,
    104 			      Pixel *pixels));
    105 
    106 LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
    107 			      unsigned int height, unsigned int *pixelindex,
    108 			      Pixel *pixels));
    109 
    110 LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel));
    111 LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel));
    112 #if !defined(WORD64) && !defined(LONG64)
    113 LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
    114 #endif
    115 LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    116 LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    117 LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    118 LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    119 LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel));
    120 LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    121 LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
    122 
    123 /*
    124  * return the default color key related to the given visual
    125  */
    126 static int
    127 xpmVisualType(Visual *visual)
    128 {
    129     switch (visual->class) {
    130     case StaticGray:
    131     case GrayScale:
    132 	switch (visual->map_entries) {
    133 	case 2:
    134 	    return (XPM_MONO);
    135 	case 4:
    136 	    return (XPM_GRAY4);
    137 	default:
    138 	    return (XPM_GRAY);
    139 	}
    140     default:
    141 	return (XPM_COLOR);
    142     }
    143 }
    144 
    145 
    146 typedef struct {
    147     int cols_index;
    148     long closeness;
    149 }      CloseColor;
    150 
    151 static int
    152 closeness_cmp(const void *a, const void *b)
    153 {
    154     const CloseColor *x = (const CloseColor *) a, *y = (const CloseColor *) b;
    155 
    156     /* cast to int as qsort requires */
    157     return (int) (x->closeness - y->closeness);
    158 }
    159 
    160 
    161 /* default AllocColor function:
    162  *   call XParseColor if colorname is given, return negative value if failure
    163  *   call XAllocColor and return 0 if failure, positive otherwise
    164  */
    165 static int
    166 AllocColor(
    167     Display	*display,
    168     Colormap	 colormap,
    169     char	*colorname,
    170     XColor	*xcolor,
    171     void	*closure)		/* not used */
    172 {
    173     int status;
    174     if (colorname)
    175 	if (!XParseColor(display, colormap, colorname, xcolor))
    176 	    return -1;
    177     status = XAllocColor(display, colormap, xcolor);
    178     return status != 0 ? 1 : 0;
    179 }
    180 
    181 
    182 /*
    183  * set a close color in case the exact one can't be set
    184  * return 0 if success, 1 otherwise.
    185  */
    186 
    187 static int
    188 SetCloseColor(
    189     Display		*display,
    190     Colormap		 colormap,
    191     Visual		*visual,
    192     XColor		*col,
    193     Pixel		*image_pixel,
    194     Pixel		*mask_pixel,
    195     Pixel		*alloc_pixels,
    196     unsigned int	*nalloc_pixels,
    197     XpmAttributes	*attributes,
    198     XColor		*cols,
    199     int			 ncols,
    200     XpmAllocColorFunc	 allocColor,
    201     void		*closure)
    202 {
    203 
    204     /*
    205      * Allocation failed, so try close colors. To get here the visual must
    206      * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
    207      * What about sharing systems like QDSS?). Beware: we have to treat
    208      * DirectColor differently.
    209      */
    210 
    211 
    212     long int red_closeness, green_closeness, blue_closeness;
    213     int n;
    214     Bool alloc_color;
    215 
    216     if (attributes && (attributes->valuemask & XpmCloseness))
    217 	red_closeness = green_closeness = blue_closeness =
    218 	    attributes->closeness;
    219     else {
    220 	red_closeness = attributes->red_closeness;
    221 	green_closeness = attributes->green_closeness;
    222 	blue_closeness = attributes->blue_closeness;
    223     }
    224     if (attributes && (attributes->valuemask & XpmAllocCloseColors))
    225 	alloc_color = attributes->alloc_close_colors;
    226     else
    227 	alloc_color = True;
    228 
    229     /*
    230      * We sort the colormap by closeness and try to allocate the color
    231      * closest to the target. If the allocation of this close color fails,
    232      * which almost never happens, then one of two scenarios is possible.
    233      * Either the colormap must have changed (since the last close color
    234      * allocation or possibly while we were sorting the colormap), or the
    235      * color is allocated as Read/Write by some other client. (Note: X
    236      * _should_ allow clients to check if a particular color is Read/Write,
    237      * but it doesn't! :-( ). We cannot determine which of these scenarios
    238      * occurred, so we try the next closest color, and so on, until no more
    239      * colors are within closeness of the target. If we knew that the
    240      * colormap had changed, we could skip this sequence.
    241      *
    242      * If _none_ of the colors within closeness of the target can be allocated,
    243      * then we can finally be pretty sure that the colormap has actually
    244      * changed. In this case we try to allocate the original color (again),
    245      * then try the closecolor stuff (again)...
    246      *
    247      * In theory it would be possible for an infinite loop to occur if another
    248      * process kept changing the colormap every time we sorted it, so we set
    249      * a maximum on the number of iterations. After this many tries, we use
    250      * XGrabServer() to ensure that the colormap remains unchanged.
    251      *
    252      * This approach gives particularly bad worst case performance - as many as
    253      * <MaximumIterations> colormap reads and sorts may be needed, and as
    254      * many as <MaximumIterations> * <ColormapSize> attempted allocations
    255      * may fail. On an 8-bit system, this means as many as 3 colormap reads,
    256      * 3 sorts and 768 failed allocations per execution of this code!
    257      * Luckily, my experiments show that in general use in a typical 8-bit
    258      * color environment only about 1 in every 10000 allocations fails to
    259      * succeed in the fastest possible time. So virtually every time what
    260      * actually happens is a single sort followed by a successful allocate.
    261      * The very first allocation also costs a colormap read, but no further
    262      * reads are usually necessary.
    263      */
    264 
    265 #define ITERATIONS 2			/* more than one is almost never
    266 					 * necessary */
    267 
    268     for (n = 0; n <= ITERATIONS; ++n) {
    269 	CloseColor *closenesses =
    270 	    (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
    271 	int i, c;
    272 
    273 	for (i = 0; i < ncols; ++i) {	/* build & sort closenesses table */
    274 #define COLOR_FACTOR       3
    275 #define BRIGHTNESS_FACTOR  1
    276 
    277 	    closenesses[i].cols_index = i;
    278 	    closenesses[i].closeness =
    279 		COLOR_FACTOR * (labs((long) col->red - (long) cols[i].red)
    280 				+ labs((long) col->green - (long) cols[i].green)
    281 				+ labs((long) col->blue - (long) cols[i].blue))
    282 		+ BRIGHTNESS_FACTOR * labs(((long) col->red +
    283 					   (long) col->green +
    284 					   (long) col->blue)
    285 					   - ((long) cols[i].red +
    286 					      (long) cols[i].green +
    287 					      (long) cols[i].blue));
    288 	}
    289 	qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
    290 
    291 	i = 0;
    292 	c = closenesses[i].cols_index;
    293 	while ((long) cols[c].red >= (long) col->red - red_closeness &&
    294 	       (long) cols[c].red <= (long) col->red + red_closeness &&
    295 	       (long) cols[c].green >= (long) col->green - green_closeness &&
    296 	       (long) cols[c].green <= (long) col->green + green_closeness &&
    297 	       (long) cols[c].blue >= (long) col->blue - blue_closeness &&
    298 	       (long) cols[c].blue <= (long) col->blue + blue_closeness) {
    299 	    if (alloc_color) {
    300 		if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){
    301 		    if (n == ITERATIONS)
    302 			XUngrabServer(display);
    303 		    XpmFree(closenesses);
    304 		    *image_pixel = cols[c].pixel;
    305 		    *mask_pixel = 1;
    306 		    alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
    307 		    return (0);
    308 		} else {
    309 		    ++i;
    310 		    if (i == ncols)
    311 			break;
    312 		    c = closenesses[i].cols_index;
    313 		}
    314 	    } else {
    315 		if (n == ITERATIONS)
    316 		    XUngrabServer(display);
    317 		XpmFree(closenesses);
    318 		*image_pixel = cols[c].pixel;
    319 		*mask_pixel = 1;
    320 		return (0);
    321 	    }
    322 	}
    323 
    324 	/* Couldn't allocate _any_ of the close colors! */
    325 
    326 	if (n == ITERATIONS)
    327 	    XUngrabServer(display);
    328 	XpmFree(closenesses);
    329 
    330 	if (i == 0 || i == ncols)	/* no color close enough or cannot */
    331 	    return (1);			/* alloc any color (full of r/w's) */
    332 
    333 	if ((*allocColor)(display, colormap, NULL, col, closure)) {
    334 	    *image_pixel = col->pixel;
    335 	    *mask_pixel = 1;
    336 	    alloc_pixels[(*nalloc_pixels)++] = col->pixel;
    337 	    return (0);
    338 	} else {			/* colormap has probably changed, so
    339 					 * re-read... */
    340 	    if (n == ITERATIONS - 1)
    341 		XGrabServer(display);
    342 
    343 #if 0
    344 	    if (visual->class == DirectColor) {
    345 		/* TODO */
    346 	    } else
    347 #endif
    348 		XQueryColors(display, colormap, cols, ncols);
    349 	}
    350     }
    351     return (1);
    352 }
    353 
    354 #define USE_CLOSECOLOR attributes && \
    355 (((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
    356  || ((attributes->valuemask & XpmRGBCloseness) && \
    357      (attributes->red_closeness != 0 \
    358       || attributes->green_closeness != 0 \
    359       || attributes->blue_closeness != 0)))
    360 
    361 
    362 /*
    363  * set the color pixel related to the given colorname,
    364  * return 0 if success, 1 otherwise.
    365  */
    366 
    367 static int
    368 SetColor(
    369     Display		*display,
    370     Colormap		 colormap,
    371     Visual		*visual,
    372     char		*colorname,
    373     unsigned int	 color_index,
    374     Pixel		*image_pixel,
    375     Pixel		*mask_pixel,
    376     unsigned int	*mask_pixel_index,
    377     Pixel		*alloc_pixels,
    378     unsigned int	*nalloc_pixels,
    379     Pixel		*used_pixels,
    380     unsigned int	*nused_pixels,
    381     XpmAttributes	*attributes,
    382     XColor		*cols,
    383     int			 ncols,
    384     XpmAllocColorFunc	 allocColor,
    385     void		*closure)
    386 {
    387     XColor xcolor;
    388     int status;
    389 
    390     if (strcasecmp(colorname, TRANSPARENT_COLOR)) {
    391 	status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
    392 	if (status < 0)		/* parse color failed */
    393 	    return (1);
    394 
    395 	if (status == 0) {
    396 	    if (USE_CLOSECOLOR)
    397 		return (SetCloseColor(display, colormap, visual, &xcolor,
    398 				      image_pixel, mask_pixel,
    399 				      alloc_pixels, nalloc_pixels,
    400 				      attributes, cols, ncols,
    401 				      allocColor, closure));
    402 	    else
    403 		return (1);
    404 	} else
    405 	    alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
    406 	*image_pixel = xcolor.pixel;
    407 	*mask_pixel = 1;
    408 	used_pixels[(*nused_pixels)++] = xcolor.pixel;
    409     } else {
    410 	*image_pixel = 0;
    411 	*mask_pixel = 0;
    412 	/* store the color table index */
    413 	*mask_pixel_index = color_index;
    414     }
    415     return (0);
    416 }
    417 
    418 
    419 static int
    420 CreateColors(
    421     Display		*display,
    422     XpmAttributes	*attributes,
    423     XpmColor		*colors,
    424     unsigned int	 ncolors,
    425     Pixel		*image_pixels,
    426     Pixel		*mask_pixels,
    427     unsigned int	*mask_pixel_index,
    428     Pixel		*alloc_pixels,
    429     unsigned int	*nalloc_pixels,
    430     Pixel		*used_pixels,
    431     unsigned int	*nused_pixels)
    432 {
    433     /* variables stored in the XpmAttributes structure */
    434     Visual *visual;
    435     Colormap colormap;
    436     XpmColorSymbol *colorsymbols = NULL;
    437     unsigned int numsymbols;
    438     XpmAllocColorFunc allocColor;
    439     void *closure;
    440 
    441     char *colorname;
    442     unsigned int color, key;
    443     Bool pixel_defined;
    444     XpmColorSymbol *symbol = NULL;
    445     char **defaults;
    446     int ErrorStatus = XpmSuccess;
    447     char *s;
    448     int default_index;
    449 
    450     XColor *cols = NULL;
    451     unsigned int ncols = 0;
    452 
    453     /*
    454      * retrieve information from the XpmAttributes
    455      */
    456     if (attributes && attributes->valuemask & XpmColorSymbols) {
    457 	colorsymbols = attributes->colorsymbols;
    458 	numsymbols = attributes->numsymbols;
    459     } else
    460 	numsymbols = 0;
    461 
    462     if (attributes && attributes->valuemask & XpmVisual)
    463 	visual = attributes->visual;
    464     else
    465 	visual = XDefaultVisual(display, XDefaultScreen(display));
    466 
    467     if (attributes && (attributes->valuemask & XpmColormap))
    468 	colormap = attributes->colormap;
    469     else
    470 	colormap = XDefaultColormap(display, XDefaultScreen(display));
    471 
    472     if (attributes && (attributes->valuemask & XpmColorKey))
    473 	key = attributes->color_key;
    474     else
    475 	key = xpmVisualType(visual);
    476 
    477     if (attributes && (attributes->valuemask & XpmAllocColor))
    478 	allocColor = attributes->alloc_color;
    479     else
    480 	allocColor = AllocColor;
    481     if (attributes && (attributes->valuemask & XpmColorClosure))
    482 	closure = attributes->color_closure;
    483     else
    484 	closure = NULL;
    485 
    486     if (USE_CLOSECOLOR) {
    487 	/* originally from SetCloseColor */
    488 #if 0
    489 	if (visual->class == DirectColor) {
    490 
    491 	    /*
    492 	     * TODO: Implement close colors for DirectColor visuals. This is
    493 	     * difficult situation. Chances are that we will never get here,
    494 	     * because any machine that supports DirectColor will probably
    495 	     * also support TrueColor (and probably PseudoColor). Also,
    496 	     * DirectColor colormaps can be very large, so looking for close
    497 	     * colors may be too slow.
    498 	     */
    499 	} else {
    500 #endif
    501 	    unsigned int i;
    502 
    503 	    ncols = visual->map_entries;
    504 	    cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
    505 	    for (i = 0; i < ncols; ++i)
    506 		cols[i].pixel = i;
    507 	    XQueryColors(display, colormap, cols, ncols);
    508 #if 0
    509 	}
    510 #endif
    511     }
    512 
    513     switch (key) {
    514     case XPM_MONO:
    515 	default_index = 2;
    516 	break;
    517     case XPM_GRAY4:
    518 	default_index = 3;
    519 	break;
    520     case XPM_GRAY:
    521 	default_index = 4;
    522 	break;
    523     case XPM_COLOR:
    524     default:
    525 	default_index = 5;
    526 	break;
    527     }
    528 
    529     for (color = 0; color < ncolors; color++, colors++,
    530 					 image_pixels++, mask_pixels++) {
    531 	colorname = NULL;
    532 	pixel_defined = False;
    533 	defaults = (char **) colors;
    534 
    535 	/*
    536 	 * look for a defined symbol
    537 	 */
    538 	if (numsymbols) {
    539 
    540 	    unsigned int n;
    541 
    542 	    s = defaults[1];
    543 	    for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
    544 		if (symbol->name && s && !strcmp(symbol->name, s))
    545 		    /* override name */
    546 		    break;
    547 		if (!symbol->name && symbol->value) {	/* override value */
    548 		    int def_index = default_index;
    549 
    550 		    while (defaults[def_index] == NULL)	/* find defined
    551 							 * colorname */
    552 			--def_index;
    553 		    if (def_index < 2) {/* nothing towards mono, so try
    554 					 * towards color */
    555 			def_index = default_index + 1;
    556 			while (def_index <= 5 && defaults[def_index] == NULL)
    557 			    ++def_index;
    558 		    }
    559 		    if (def_index >= 2 && def_index <= 5 &&
    560 			defaults[def_index] != NULL &&
    561 			!strcasecmp(symbol->value, defaults[def_index]))
    562 			break;
    563 		}
    564 	    }
    565 	    if (n != numsymbols) {
    566 		if (symbol->name && symbol->value)
    567 		    colorname = symbol->value;
    568 		else
    569 		    pixel_defined = True;
    570 	    }
    571 	}
    572 	if (!pixel_defined) {		/* pixel not given as symbol value */
    573 
    574 	    unsigned int k;
    575 
    576 	    if (colorname) {		/* colorname given as symbol value */
    577 		if (!SetColor(display, colormap, visual, colorname, color,
    578 			      image_pixels, mask_pixels, mask_pixel_index,
    579 			      alloc_pixels, nalloc_pixels, used_pixels,
    580 			      nused_pixels, attributes, cols, ncols,
    581 			      allocColor, closure))
    582 		    pixel_defined = True;
    583 		else
    584 		    ErrorStatus = XpmColorError;
    585 	    }
    586 	    k = key;
    587 	    while (!pixel_defined && k > 1) {
    588 		if (defaults[k]) {
    589 		    if (!SetColor(display, colormap, visual, defaults[k],
    590 				  color, image_pixels, mask_pixels,
    591 				  mask_pixel_index, alloc_pixels,
    592 				  nalloc_pixels, used_pixels, nused_pixels,
    593 				  attributes, cols, ncols,
    594 				  allocColor, closure)) {
    595 			pixel_defined = True;
    596 			break;
    597 		    } else
    598 			ErrorStatus = XpmColorError;
    599 		}
    600 		k--;
    601 	    }
    602 	    k = key + 1;
    603 	    while (!pixel_defined && k < NKEYS + 1) {
    604 		if (defaults[k]) {
    605 		    if (!SetColor(display, colormap, visual, defaults[k],
    606 				  color, image_pixels, mask_pixels,
    607 				  mask_pixel_index, alloc_pixels,
    608 				  nalloc_pixels, used_pixels, nused_pixels,
    609 				  attributes, cols, ncols,
    610 				  allocColor, closure)) {
    611 			pixel_defined = True;
    612 			break;
    613 		    } else
    614 			ErrorStatus = XpmColorError;
    615 		}
    616 		k++;
    617 	    }
    618 	    if (!pixel_defined) {
    619 		if (cols)
    620 		    XpmFree(cols);
    621 		return (XpmColorFailed);
    622 	    }
    623 	} else {
    624 	    /* simply use the given pixel */
    625 	    *image_pixels = symbol->pixel;
    626 	    /* the following makes the mask to be built even if none
    627 	       is given a particular pixel */
    628 	    if (symbol->value
    629 		&& !strcasecmp(symbol->value, TRANSPARENT_COLOR)) {
    630 		*mask_pixels = 0;
    631 		*mask_pixel_index = color;
    632 	    } else
    633 		*mask_pixels = 1;
    634 	    used_pixels[(*nused_pixels)++] = *image_pixels;
    635 	}
    636     }
    637     if (cols)
    638 	XpmFree(cols);
    639     return (ErrorStatus);
    640 }
    641 
    642 
    643 /* default FreeColors function, simply call XFreeColors */
    644 static int
    645 FreeColors(
    646     Display	*display,
    647     Colormap	 colormap,
    648     Pixel	*pixels,
    649     int		 n,
    650     void	*closure)		/* not used */
    651 {
    652     return XFreeColors(display, colormap, pixels, n, 0);
    653 }
    654 
    655 
    656 /* function call in case of error */
    657 
    658 #undef RETURN
    659 #define RETURN(status) \
    660 do \
    661 { \
    662       ErrorStatus = status; \
    663       goto error; \
    664 } while(0)
    665 
    666 int
    667 XpmCreateImageFromXpmImage(
    668     Display		 *display,
    669     XpmImage		 *image,
    670     XImage		**image_return,
    671     XImage		**shapeimage_return,
    672     XpmAttributes	 *attributes)
    673 {
    674     /* variables stored in the XpmAttributes structure */
    675     Visual *visual;
    676     Colormap colormap;
    677     unsigned int depth;
    678     int bitmap_format;
    679     XpmFreeColorsFunc freeColors;
    680 
    681     /* variables to return */
    682     XImage *ximage = NULL;
    683     XImage *shapeimage = NULL;
    684     unsigned int mask_pixel_index = XpmUndefPixel;
    685     int ErrorStatus;
    686 
    687     /* calculation variables */
    688     Pixel *image_pixels = NULL;
    689     Pixel *mask_pixels = NULL;
    690     Pixel *alloc_pixels = NULL;
    691     Pixel *used_pixels = NULL;
    692     unsigned int nalloc_pixels = 0;
    693     unsigned int nused_pixels = 0;
    694 
    695     /* initialize return values */
    696     if (image_return)
    697 	*image_return = NULL;
    698     if (shapeimage_return)
    699 	*shapeimage_return = NULL;
    700 
    701     /* retrieve information from the XpmAttributes */
    702     if (attributes && (attributes->valuemask & XpmVisual))
    703 	visual = attributes->visual;
    704     else
    705 	visual = XDefaultVisual(display, XDefaultScreen(display));
    706 
    707     if (attributes && (attributes->valuemask & XpmColormap))
    708 	colormap = attributes->colormap;
    709     else
    710 	colormap = XDefaultColormap(display, XDefaultScreen(display));
    711 
    712     if (attributes && (attributes->valuemask & XpmDepth))
    713 	depth = attributes->depth;
    714     else
    715 	depth = XDefaultDepth(display, XDefaultScreen(display));
    716 
    717     if (attributes && (attributes->valuemask & XpmBitmapFormat))
    718 	bitmap_format = attributes->bitmap_format;
    719     else
    720 	bitmap_format = ZPixmap;
    721 
    722     if (attributes && (attributes->valuemask & XpmFreeColors))
    723 	freeColors = attributes->free_colors;
    724     else
    725 	freeColors = FreeColors;
    726 
    727     ErrorStatus = XpmSuccess;
    728 
    729     if (image->ncolors >= UINT_MAX / sizeof(Pixel))
    730 	return (XpmNoMemory);
    731 
    732     /* malloc pixels index tables */
    733     image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
    734     if (!image_pixels)
    735 	return (XpmNoMemory);
    736 
    737     mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
    738     if (!mask_pixels)
    739 	RETURN(XpmNoMemory);
    740 
    741     /* maximum of allocated pixels will be the number of colors */
    742     alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
    743     if (!alloc_pixels)
    744 	RETURN(XpmNoMemory);
    745 
    746     /* maximum of allocated pixels will be the number of colors */
    747     used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
    748     if (!used_pixels)
    749 	RETURN(XpmNoMemory);
    750 
    751     /* get pixel colors, store them in index tables */
    752     ErrorStatus = CreateColors(display, attributes, image->colorTable,
    753 			       image->ncolors, image_pixels, mask_pixels,
    754 			       &mask_pixel_index, alloc_pixels, &nalloc_pixels,
    755 			       used_pixels, &nused_pixels);
    756 
    757     if (ErrorStatus != XpmSuccess
    758 	&& (ErrorStatus < 0 || (attributes
    759 				&& (attributes->valuemask & XpmExactColors)
    760 				&& attributes->exactColors)))
    761 	RETURN(ErrorStatus);
    762 
    763     /* create the ximage */
    764     if (image_return) {
    765 	ErrorStatus = CreateXImage(display, visual, depth,
    766 				   (depth == 1 ? bitmap_format : ZPixmap),
    767 				   image->width, image->height, &ximage);
    768 	if (ErrorStatus != XpmSuccess)
    769 	    RETURN(ErrorStatus);
    770 
    771 	/*
    772 	 * set the ximage data using optimized functions for ZPixmap
    773 	 */
    774 
    775 	if (ximage->bits_per_pixel == 8)
    776 	    PutImagePixels8(ximage, image->width, image->height,
    777 			    image->data, image_pixels);
    778 	else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
    779 		 (ximage->byte_order == ximage->bitmap_bit_order))
    780 	    PutImagePixels1(ximage, image->width, image->height,
    781 			    image->data, image_pixels);
    782 	else if (ximage->bits_per_pixel == 16)
    783 	    PutImagePixels16(ximage, image->width, image->height,
    784 			     image->data, image_pixels);
    785 	else if (ximage->bits_per_pixel == 32)
    786 	    PutImagePixels32(ximage, image->width, image->height,
    787 			     image->data, image_pixels);
    788 	else
    789 	    PutImagePixels(ximage, image->width, image->height,
    790 			   image->data, image_pixels);
    791     }
    792     /* create the shape mask image */
    793     if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
    794 	ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
    795 				   image->width, image->height, &shapeimage);
    796 	if (ErrorStatus != XpmSuccess)
    797 	    RETURN(ErrorStatus);
    798 
    799 	PutImagePixels1(shapeimage, image->width, image->height,
    800 			image->data, mask_pixels);
    801 
    802     }
    803     XpmFree(image_pixels);
    804     XpmFree(mask_pixels);
    805 
    806     /* if requested return used pixels in the XpmAttributes structure */
    807     if (attributes && (attributes->valuemask & XpmReturnPixels ||
    808 /* 3.2 backward compatibility code */
    809 	attributes->valuemask & XpmReturnInfos)) {
    810 /* end 3.2 bc */
    811 	attributes->pixels = used_pixels;
    812 	attributes->npixels = nused_pixels;
    813 	attributes->mask_pixel = mask_pixel_index;
    814     } else
    815 	XpmFree(used_pixels);
    816 
    817     /* if requested return alloc'ed pixels in the XpmAttributes structure */
    818     if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
    819 	attributes->alloc_pixels = alloc_pixels;
    820 	attributes->nalloc_pixels = nalloc_pixels;
    821     } else
    822 	XpmFree(alloc_pixels);
    823 
    824     /* return created images */
    825     if (image_return)
    826 	*image_return = ximage;
    827     if (shapeimage_return)
    828 	*shapeimage_return = shapeimage;
    829 
    830     return (ErrorStatus);
    831 
    832 /* exit point in case of error, free only locally allocated variables */
    833 error:
    834     if (ximage)
    835 	XDestroyImage(ximage);
    836     if (shapeimage)
    837 	XDestroyImage(shapeimage);
    838     if (image_pixels)
    839 	XpmFree(image_pixels);
    840     if (mask_pixels)
    841 	XpmFree(mask_pixels);
    842     if (nalloc_pixels)
    843 	(*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
    844     if (alloc_pixels)
    845 	XpmFree(alloc_pixels);
    846     if (used_pixels)
    847 	XpmFree(used_pixels);
    848 
    849     return (ErrorStatus);
    850 }
    851 
    852 
    853 /*
    854  * Create an XImage with its data
    855  */
    856 static int
    857 CreateXImage(
    858     Display	 *display,
    859     Visual	 *visual,
    860     unsigned int  depth,
    861     int		  format,
    862     unsigned int  width,
    863     unsigned int  height,
    864     XImage	**image_return)
    865 {
    866     int bitmap_pad;
    867 
    868     /* first get bitmap_pad */
    869     if (depth > 16)
    870 	bitmap_pad = 32;
    871     else if (depth > 8)
    872 	bitmap_pad = 16;
    873     else
    874 	bitmap_pad = 8;
    875 
    876     /* then create the XImage with data = NULL and bytes_per_line = 0 */
    877     *image_return = XCreateImage(display, visual, depth, format, 0, 0,
    878 				 width, height, bitmap_pad, 0);
    879     if (!*image_return)
    880 	return (XpmNoMemory);
    881 
    882     if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
    883 	XDestroyImage(*image_return);
    884 	*image_return = NULL;
    885 	return XpmNoMemory;
    886     }
    887     if (width != 0 && (*image_return)->bits_per_pixel >= INT_MAX / width) {
    888 	XDestroyImage(*image_return);
    889 	*image_return = NULL;
    890 	return XpmNoMemory;
    891     }
    892     /* now that bytes_per_line must have been set properly alloc data */
    893     if((*image_return)->bytes_per_line == 0 ||  height == 0) {
    894 	XDestroyImage(*image_return);
    895 	*image_return = NULL;
    896     	return XpmNoMemory;
    897     }
    898     (*image_return)->data =
    899 	(char *) XpmMalloc((*image_return)->bytes_per_line * height);
    900 
    901     if (!(*image_return)->data) {
    902 	XDestroyImage(*image_return);
    903 	*image_return = NULL;
    904 	return (XpmNoMemory);
    905     }
    906     return (XpmSuccess);
    907 }
    908 
    909 /*
    910  * The functions below are written from X11R5 MIT's code (XImUtil.c)
    911  *
    912  * The idea is to have faster functions than the standard XPutPixel function
    913  * to build the image data. Indeed we can speed up things by suppressing tests
    914  * performed for each pixel. We do the same tests but at the image level.
    915  * We also assume that we use only ZPixmap images with null offsets.
    916  */
    917 
    918 LFUNC(_putbits, void, (register char *src, int dstoffset,
    919 		       register int numbits, register char *dst));
    920 
    921 LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
    922 
    923 static unsigned char const _reverse_byte[0x100] = {
    924     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
    925     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
    926     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
    927     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
    928     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
    929     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
    930     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
    931     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
    932     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
    933     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
    934     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
    935     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
    936     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
    937     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
    938     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
    939     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
    940     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
    941     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
    942     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
    943     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
    944     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
    945     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
    946     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
    947     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
    948     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
    949     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
    950     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
    951     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
    952     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
    953     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
    954     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
    955     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
    956 };
    957 
    958 static int
    959 _XReverse_Bytes(
    960     register unsigned char	*bpt,
    961     register unsigned int	 nb)
    962 {
    963     do {
    964 	*bpt = _reverse_byte[*bpt];
    965 	bpt++;
    966     } while (--nb > 0); /* is nb user-controled? */
    967     return 0;
    968 }
    969 
    970 
    971 void
    972 xpm_xynormalizeimagebits(
    973     register unsigned char	*bp,
    974     register XImage		*img)
    975 {
    976     register unsigned char c;
    977 
    978     if (img->byte_order != img->bitmap_bit_order) {
    979 	switch (img->bitmap_unit) {
    980 
    981 	case 16:
    982 	    c = *bp;
    983 	    *bp = *(bp + 1);
    984 	    *(bp + 1) = c;
    985 	    break;
    986 
    987 	case 32:
    988 	    c = *(bp + 3);
    989 	    *(bp + 3) = *bp;
    990 	    *bp = c;
    991 	    c = *(bp + 2);
    992 	    *(bp + 2) = *(bp + 1);
    993 	    *(bp + 1) = c;
    994 	    break;
    995 	}
    996     }
    997     if (img->bitmap_bit_order == MSBFirst)
    998 	_XReverse_Bytes(bp, img->bitmap_unit >> 3);
    999 }
   1000 
   1001 void
   1002 xpm_znormalizeimagebits(
   1003     register unsigned char	*bp,
   1004     register XImage		*img)
   1005 {
   1006     register unsigned char c;
   1007 
   1008     switch (img->bits_per_pixel) {
   1009 
   1010     case 2:
   1011 	_XReverse_Bytes(bp, 1);
   1012 	break;
   1013 
   1014     case 4:
   1015 	*bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
   1016 	break;
   1017 
   1018     case 16:
   1019 	c = *bp;
   1020 	*bp = *(bp + 1);
   1021 	*(bp + 1) = c;
   1022 	break;
   1023 
   1024     case 24:
   1025 	c = *(bp + 2);
   1026 	*(bp + 2) = *bp;
   1027 	*bp = c;
   1028 	break;
   1029 
   1030     case 32:
   1031 	c = *(bp + 3);
   1032 	*(bp + 3) = *bp;
   1033 	*bp = c;
   1034 	c = *(bp + 2);
   1035 	*(bp + 2) = *(bp + 1);
   1036 	*(bp + 1) = c;
   1037 	break;
   1038     }
   1039 }
   1040 
   1041 static unsigned char const _lomask[0x09] = {
   1042 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
   1043 static unsigned char const _himask[0x09] = {
   1044 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
   1045 
   1046 static void
   1047 _putbits(
   1048     register char	*src,		/* address of source bit string */
   1049     int			 dstoffset,	/* bit offset into destination;
   1050 					 * range is 0-31 */
   1051     register int	 numbits,	/* number of bits to copy to
   1052 					 * destination */
   1053     register char	*dst)		/* address of destination bit string */
   1054 {
   1055     register unsigned char chlo, chhi;
   1056     int hibits;
   1057 
   1058     dst = dst + (dstoffset >> 3);
   1059     dstoffset = dstoffset & 7;
   1060     hibits = 8 - dstoffset;
   1061     chlo = *dst & _lomask[dstoffset];
   1062     for (;;) {
   1063 	chhi = (*src << dstoffset) & _himask[dstoffset];
   1064 	if (numbits <= hibits) {
   1065 	    chhi = chhi & _lomask[dstoffset + numbits];
   1066 	    *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
   1067 	    break;
   1068 	}
   1069 	*dst = chhi | chlo;
   1070 	dst++;
   1071 	numbits = numbits - hibits;
   1072 	chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
   1073 	src++;
   1074 	if (numbits <= dstoffset) {
   1075 	    chlo = chlo & _lomask[numbits];
   1076 	    *dst = (*dst & _himask[numbits]) | chlo;
   1077 	    break;
   1078 	}
   1079 	numbits = numbits - dstoffset;
   1080     }
   1081 }
   1082 
   1083 /*
   1084  * Default method to write pixels into a Z image data structure.
   1085  * The algorithm used is:
   1086  *
   1087  *	copy the destination bitmap_unit or Zpixel to temp
   1088  *	normalize temp if needed
   1089  *	copy the pixel bits into the temp
   1090  *	renormalize temp if needed
   1091  *	copy the temp back into the destination image data
   1092  */
   1093 
   1094 static void
   1095 PutImagePixels(
   1096     XImage		*image,
   1097     unsigned int	 width,
   1098     unsigned int	 height,
   1099     unsigned int	*pixelindex,
   1100     Pixel		*pixels)
   1101 {
   1102     register char *src;
   1103     register char *dst;
   1104     register unsigned int *iptr;
   1105     register unsigned int x, y;
   1106     register char *data;
   1107     Pixel pixel, px;
   1108     int nbytes, depth, ibu, ibpp, i;
   1109 
   1110     data = image->data;
   1111     iptr = pixelindex;
   1112     depth = image->depth;
   1113     if (depth == 1) {
   1114 	ibu = image->bitmap_unit;
   1115 	for (y = 0; y < height; y++) /* how can we trust height */
   1116 	    for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
   1117 		pixel = pixels[*iptr];
   1118 		for (i = 0, px = pixel; i < sizeof(unsigned long);
   1119 		     i++, px >>= 8)
   1120 		    ((unsigned char *) &pixel)[i] = px;
   1121 		src = &data[XYINDEX(x, y, image)];
   1122 		dst = (char *) &px;
   1123 		px = 0;
   1124 		nbytes = ibu >> 3;
   1125 		for (i = nbytes; --i >= 0;)
   1126 		    *dst++ = *src++;
   1127 		XYNORMALIZE(&px, image);
   1128 		_putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
   1129 		XYNORMALIZE(&px, image);
   1130 		src = (char *) &px;
   1131 		dst = &data[XYINDEX(x, y, image)];
   1132 		for (i = nbytes; --i >= 0;)
   1133 		    *dst++ = *src++;
   1134 	    }
   1135     } else {
   1136 	ibpp = image->bits_per_pixel;
   1137 	for (y = 0; y < height; y++)
   1138 	    for (x = 0; x < width; x++, iptr++) {
   1139 		pixel = pixels[*iptr];
   1140 		if (depth == 4)
   1141 		    pixel &= 0xf;
   1142 		for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
   1143 		     px >>= 8)
   1144 		    ((unsigned char *) &pixel)[i] = px;
   1145 		src = &data[ZINDEX(x, y, image)];
   1146 		dst = (char *) &px;
   1147 		px = 0;
   1148 		nbytes = (ibpp + 7) >> 3;
   1149 		for (i = nbytes; --i >= 0;)
   1150 		    *dst++ = *src++;
   1151 		ZNORMALIZE(&px, image);
   1152 		_putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
   1153 		ZNORMALIZE(&px, image);
   1154 		src = (char *) &px;
   1155 		dst = &data[ZINDEX(x, y, image)];
   1156 		for (i = nbytes; --i >= 0;)
   1157 		    *dst++ = *src++;
   1158 	    }
   1159     }
   1160 }
   1161 
   1162 /*
   1163  * write pixels into a 32-bits Z image data structure
   1164  */
   1165 
   1166 #if !defined(WORD64) && !defined(LONG64)
   1167 /* this item is static but deterministic so let it slide; doesn't
   1168  * hurt re-entrancy of this library. Note if it is actually const then would
   1169  * be OK under rules of ANSI-C but probably not C++ which may not
   1170  * want to allocate space for it.
   1171  */
   1172 static unsigned long byteorderpixel = MSBFirst << 24;
   1173 
   1174 #endif
   1175 
   1176 /*
   1177    WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
   1178    3.2e code - by default you get the speeded-up version.
   1179 */
   1180 
   1181 static void
   1182 PutImagePixels32(
   1183     XImage		*image,
   1184     unsigned int	 width,
   1185     unsigned int	 height,
   1186     unsigned int	*pixelindex,
   1187     Pixel		*pixels)
   1188 {
   1189     unsigned char *data;
   1190     unsigned int *iptr;
   1191     unsigned int y;
   1192     Pixel pixel;
   1193 
   1194 #ifdef WITHOUT_SPEEDUPS
   1195 
   1196     unsigned int x;
   1197     unsigned char *addr;
   1198 
   1199     data = (unsigned char *) image->data;
   1200     iptr = pixelindex;
   1201 #if !defined(WORD64) && !defined(LONG64)
   1202     if (*((char *) &byteorderpixel) == image->byte_order) {
   1203 	for (y = 0; y < height; y++)
   1204 	    for (x = 0; x < width; x++, iptr++) {
   1205 		addr = &data[ZINDEX32(x, y, image)];
   1206 		*((unsigned long *) addr) = pixels[*iptr];
   1207 	    }
   1208     } else
   1209 #endif
   1210     if (image->byte_order == MSBFirst)
   1211 	for (y = 0; y < height; y++)
   1212 	    for (x = 0; x < width; x++, iptr++) {
   1213 		addr = &data[ZINDEX32(x, y, image)];
   1214 		pixel = pixels[*iptr];
   1215 		addr[0] = pixel >> 24;
   1216 		addr[1] = pixel >> 16;
   1217 		addr[2] = pixel >> 8;
   1218 		addr[3] = pixel;
   1219 	    }
   1220     else
   1221 	for (y = 0; y < height; y++)
   1222 	    for (x = 0; x < width; x++, iptr++) {
   1223 		addr = &data[ZINDEX32(x, y, image)];
   1224 		pixel = pixels[*iptr];
   1225 		addr[0] = pixel;
   1226 		addr[1] = pixel >> 8;
   1227 		addr[2] = pixel >> 16;
   1228 		addr[3] = pixel >> 24;
   1229 	    }
   1230 
   1231 #else  /* WITHOUT_SPEEDUPS */
   1232 
   1233     unsigned int bpl = image->bytes_per_line;
   1234     unsigned char *data_ptr, *max_data;
   1235 
   1236     data = (unsigned char *) image->data;
   1237     iptr = pixelindex;
   1238 #if !defined(WORD64) && !defined(LONG64)
   1239     if (*((char *) &byteorderpixel) == image->byte_order) {
   1240 	for (y = 0; y < height; y++) {
   1241 	    data_ptr = data;
   1242 	    max_data = data_ptr + (width << 2);
   1243 
   1244 	    while (data_ptr < max_data) {
   1245 		*((unsigned long *) data_ptr) = pixels[*(iptr++)];
   1246 		data_ptr += (1 << 2);
   1247 	    }
   1248 	    data += bpl;
   1249 	}
   1250     } else
   1251 #endif
   1252     if (image->byte_order == MSBFirst)
   1253 	for (y = 0; y < height; y++) {
   1254 	    data_ptr = data;
   1255 	    max_data = data_ptr + (width << 2);
   1256 
   1257 	    while (data_ptr < max_data) {
   1258 		pixel = pixels[*(iptr++)];
   1259 
   1260 		*data_ptr++ = pixel >> 24;
   1261 		*data_ptr++ = pixel >> 16;
   1262 		*data_ptr++ = pixel >> 8;
   1263 		*data_ptr++ = pixel;
   1264 
   1265 	    }
   1266 	    data += bpl;
   1267 	}
   1268     else
   1269 	for (y = 0; y < height; y++) {
   1270 	    data_ptr = data;
   1271 	    max_data = data_ptr + (width << 2);
   1272 
   1273 	    while (data_ptr < max_data) {
   1274 		pixel = pixels[*(iptr++)];
   1275 
   1276 		*data_ptr++ = pixel;
   1277 		*data_ptr++ = pixel >> 8;
   1278 		*data_ptr++ = pixel >> 16;
   1279 		*data_ptr++ = pixel >> 24;
   1280 	    }
   1281 	    data += bpl;
   1282 	}
   1283 
   1284 #endif /* WITHOUT_SPEEDUPS */
   1285 }
   1286 
   1287 /*
   1288  * write pixels into a 16-bits Z image data structure
   1289  */
   1290 
   1291 static void
   1292 PutImagePixels16(
   1293     XImage		*image,
   1294     unsigned int	 width,
   1295     unsigned int	 height,
   1296     unsigned int	*pixelindex,
   1297     Pixel		*pixels)
   1298 {
   1299     unsigned char *data;
   1300     unsigned int *iptr;
   1301     unsigned int y;
   1302 
   1303 #ifdef WITHOUT_SPEEDUPS
   1304 
   1305     unsigned int x;
   1306     unsigned char *addr;
   1307 
   1308     data = (unsigned char *) image->data;
   1309     iptr = pixelindex;
   1310     if (image->byte_order == MSBFirst)
   1311 	for (y = 0; y < height; y++)
   1312 	    for (x = 0; x < width; x++, iptr++) {
   1313 		addr = &data[ZINDEX16(x, y, image)];
   1314 		addr[0] = pixels[*iptr] >> 8;
   1315 		addr[1] = pixels[*iptr];
   1316 	    }
   1317     else
   1318 	for (y = 0; y < height; y++)
   1319 	    for (x = 0; x < width; x++, iptr++) {
   1320 		addr = &data[ZINDEX16(x, y, image)];
   1321 		addr[0] = pixels[*iptr];
   1322 		addr[1] = pixels[*iptr] >> 8;
   1323 	    }
   1324 
   1325 #else  /* WITHOUT_SPEEDUPS */
   1326 
   1327     Pixel pixel;
   1328 
   1329     unsigned int bpl = image->bytes_per_line;
   1330     unsigned char *data_ptr, *max_data;
   1331 
   1332     data = (unsigned char *) image->data;
   1333     iptr = pixelindex;
   1334     if (image->byte_order == MSBFirst)
   1335 	for (y = 0; y < height; y++) {
   1336 	    data_ptr = data;
   1337 	    max_data = data_ptr + (width << 1);
   1338 
   1339 	    while (data_ptr < max_data) {
   1340 		pixel = pixels[*(iptr++)];
   1341 
   1342 		data_ptr[0] = pixel >> 8;
   1343 		data_ptr[1] = pixel;
   1344 
   1345 		data_ptr += (1 << 1);
   1346 	    }
   1347 	    data += bpl;
   1348 	}
   1349     else
   1350 	for (y = 0; y < height; y++) {
   1351 	    data_ptr = data;
   1352 	    max_data = data_ptr + (width << 1);
   1353 
   1354 	    while (data_ptr < max_data) {
   1355 		pixel = pixels[*(iptr++)];
   1356 
   1357 		data_ptr[0] = pixel;
   1358 		data_ptr[1] = pixel >> 8;
   1359 
   1360 		data_ptr += (1 << 1);
   1361 	    }
   1362 	    data += bpl;
   1363 	}
   1364 
   1365 #endif /* WITHOUT_SPEEDUPS */
   1366 }
   1367 
   1368 /*
   1369  * write pixels into a 8-bits Z image data structure
   1370  */
   1371 
   1372 static void
   1373 PutImagePixels8(
   1374     XImage		*image,
   1375     unsigned int	 width,
   1376     unsigned int	 height,
   1377     unsigned int	*pixelindex,
   1378     Pixel		*pixels)
   1379 {
   1380     char *data;
   1381     unsigned int *iptr;
   1382     unsigned int y;
   1383 
   1384 #ifdef WITHOUT_SPEEDUPS
   1385 
   1386     unsigned int x;
   1387 
   1388     data = image->data;
   1389     iptr = pixelindex;
   1390     for (y = 0; y < height; y++)
   1391 	for (x = 0; x < width; x++, iptr++)
   1392 	    data[ZINDEX8(x, y, image)] = pixels[*iptr];
   1393 
   1394 #else  /* WITHOUT_SPEEDUPS */
   1395 
   1396     unsigned int bpl = image->bytes_per_line;
   1397     char *data_ptr, *max_data;
   1398 
   1399     data = image->data;
   1400     iptr = pixelindex;
   1401 
   1402     for (y = 0; y < height; y++) {
   1403 	data_ptr = data;
   1404 	max_data = data_ptr + width;
   1405 
   1406 	while (data_ptr < max_data)
   1407 	    *(data_ptr++) = pixels[*(iptr++)];
   1408 
   1409 	data += bpl;
   1410     }
   1411 
   1412 #endif /* WITHOUT_SPEEDUPS */
   1413 }
   1414 
   1415 /*
   1416  * write pixels into a 1-bit depth image data structure and **offset null**
   1417  */
   1418 
   1419 static void
   1420 PutImagePixels1(
   1421     XImage		*image,
   1422     unsigned int	 width,
   1423     unsigned int	 height,
   1424     unsigned int	*pixelindex,
   1425     Pixel		*pixels)
   1426 {
   1427     if (image->byte_order != image->bitmap_bit_order)
   1428 	PutImagePixels(image, width, height, pixelindex, pixels);
   1429     else {
   1430 	unsigned int *iptr;
   1431 	unsigned int y;
   1432 	char *data;
   1433 
   1434 #ifdef WITHOUT_SPEEDUPS
   1435 
   1436 	unsigned int x;
   1437 
   1438 	data = image->data;
   1439 	iptr = pixelindex;
   1440 	if (image->bitmap_bit_order == MSBFirst)
   1441 	    for (y = 0; y < height; y++)
   1442 		for (x = 0; x < width; x++, iptr++) {
   1443 		    if (pixels[*iptr] & 1)
   1444 			data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
   1445 		    else
   1446 			data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
   1447 		}
   1448 	else
   1449 	    for (y = 0; y < height; y++)
   1450 		for (x = 0; x < width; x++, iptr++) {
   1451 		    if (pixels[*iptr] & 1)
   1452 			data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
   1453 		    else
   1454 			data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
   1455 		}
   1456 
   1457 #else  /* WITHOUT_SPEEDUPS */
   1458 
   1459 	char value;
   1460 	char *data_ptr, *max_data;
   1461 	int bpl = image->bytes_per_line;
   1462 	int diff, count;
   1463 
   1464 	data = image->data;
   1465 	iptr = pixelindex;
   1466 
   1467 	diff = width & 7;
   1468 	width >>= 3;
   1469 
   1470 	if (image->bitmap_bit_order == MSBFirst)
   1471 	    for (y = 0; y < height; y++) {
   1472 		data_ptr = data;
   1473 		max_data = data_ptr + width;
   1474 		while (data_ptr < max_data) {
   1475 		    value = 0;
   1476 
   1477 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1478 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1479 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1480 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1481 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1482 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1483 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1484 		    value = (value << 1) | (pixels[*(iptr++)] & 1);
   1485 
   1486 		    *(data_ptr++) = value;
   1487 		}
   1488 		if (diff) {
   1489 		    value = 0;
   1490 		    for (count = 0; count < diff; count++) {
   1491 			if (pixels[*(iptr++)] & 1)
   1492 			    value |= (0x80 >> count);
   1493 		    }
   1494 		    *(data_ptr) = value;
   1495 		}
   1496 		data += bpl;
   1497 	    }
   1498 	else
   1499 	    for (y = 0; y < height; y++) {
   1500 		data_ptr = data;
   1501 		max_data = data_ptr + width;
   1502 		while (data_ptr < max_data) {
   1503 		    value = 0;
   1504 		    iptr += 8;
   1505 
   1506 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1507 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1508 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1509 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1510 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1511 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1512 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1513 		    value = (value << 1) | (pixels[*(--iptr)] & 1);
   1514 
   1515 		    iptr += 8;
   1516 		    *(data_ptr++) = value;
   1517 		}
   1518 		if (diff) {
   1519 		    value = 0;
   1520 		    for (count = 0; count < diff; count++) {
   1521 			if (pixels[*(iptr++)] & 1)
   1522 			    value |= (1 << count);
   1523 		    }
   1524 		    *(data_ptr) = value;
   1525 		}
   1526 		data += bpl;
   1527 	    }
   1528 
   1529 #endif /* WITHOUT_SPEEDUPS */
   1530     }
   1531 }
   1532 
   1533 int
   1534 XpmCreatePixmapFromXpmImage(
   1535     Display		*display,
   1536     Drawable		 d,
   1537     XpmImage		*image,
   1538     Pixmap		*pixmap_return,
   1539     Pixmap		*shapemask_return,
   1540     XpmAttributes	*attributes)
   1541 {
   1542     XImage *ximage = NULL, *shapeimage = NULL;
   1543     int ErrorStatus;
   1544 
   1545     /* initialize return values */
   1546     if (pixmap_return)
   1547 	*pixmap_return = 0;
   1548     if (shapemask_return)
   1549 	*shapemask_return = 0;
   1550 
   1551     /* create the ximages */
   1552     ErrorStatus = XpmCreateImageFromXpmImage(display, image,
   1553 					     (pixmap_return ? &ximage : NULL),
   1554 					     (shapemask_return ?
   1555 					      &shapeimage : NULL),
   1556 					     attributes);
   1557     if (ErrorStatus < 0)
   1558 	goto cleanup;
   1559 
   1560     /* create the pixmaps and destroy images */
   1561     if (pixmap_return && ximage) {
   1562 	ErrorStatus =
   1563 	    xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
   1564 	if (ErrorStatus < 0)		/* fatal error */
   1565 	    goto cleanup;
   1566     }
   1567     if (shapemask_return && shapeimage) {
   1568 	ErrorStatus =
   1569 	    xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
   1570     }
   1571 
   1572   cleanup:
   1573     if (ximage != NULL)
   1574 	XDestroyImage(ximage);
   1575     if (shapeimage != NULL)
   1576 	XDestroyImage(shapeimage);
   1577     if (ErrorStatus < 0) {
   1578 	if (pixmap_return && *pixmap_return) {
   1579 	    XFreePixmap(display, *pixmap_return);
   1580 	    *pixmap_return = 0;
   1581 	}
   1582 	if (shapemask_return && *shapemask_return) {
   1583 	    XFreePixmap(display, *shapemask_return);
   1584 	    *shapemask_return = 0;
   1585 	}
   1586     }
   1587     return (ErrorStatus);
   1588 }
   1589 
   1590 static int
   1591 PutPixel1(
   1592     register XImage	*ximage,
   1593     int			 x,
   1594     int			 y,
   1595     unsigned long	 pixel)
   1596 {
   1597     register char *src;
   1598     register char *dst;
   1599     register int i;
   1600     Pixel px;
   1601     int nbytes;
   1602 
   1603     if(x < 0 || y < 0)
   1604     	return 0;
   1605 
   1606     for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
   1607 	((unsigned char *)&pixel)[i] = px;
   1608     src = &ximage->data[XYINDEX(x, y, ximage)];
   1609     dst = (char *)&px;
   1610     px = 0;
   1611     nbytes = ximage->bitmap_unit >> 3;
   1612     for (i = nbytes; --i >= 0; ) *dst++ = *src++;
   1613     XYNORMALIZE(&px, ximage);
   1614     i = ((x + ximage->xoffset) % ximage->bitmap_unit);
   1615     _putbits ((char *)&pixel, i, 1, (char *)&px);
   1616     XYNORMALIZE(&px, ximage);
   1617     src = (char *) &px;
   1618     dst = &ximage->data[XYINDEX(x, y, ximage)];
   1619     for (i = nbytes; --i >= 0; )
   1620 	*dst++ = *src++;
   1621 
   1622     return 1;
   1623 }
   1624 
   1625 static int
   1626 PutPixel(
   1627     register XImage	*ximage,
   1628     int			 x,
   1629     int			 y,
   1630     unsigned long	 pixel)
   1631 {
   1632     register char *src;
   1633     register char *dst;
   1634     register int i;
   1635     Pixel px;
   1636     unsigned int nbytes, ibpp;
   1637 
   1638     if(x < 0 || y < 0)
   1639     	return 0;
   1640 
   1641     ibpp = ximage->bits_per_pixel;
   1642     if (ximage->depth == 4)
   1643 	pixel &= 0xf;
   1644     for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
   1645 	((unsigned char *) &pixel)[i] = px;
   1646     src = &ximage->data[ZINDEX(x, y, ximage)];
   1647     dst = (char *) &px;
   1648     px = 0;
   1649     nbytes = (ibpp + 7) >> 3;
   1650     for (i = nbytes; --i >= 0;)
   1651 	*dst++ = *src++;
   1652     ZNORMALIZE(&px, ximage);
   1653     _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
   1654     ZNORMALIZE(&px, ximage);
   1655     src = (char *) &px;
   1656     dst = &ximage->data[ZINDEX(x, y, ximage)];
   1657     for (i = nbytes; --i >= 0;)
   1658 	*dst++ = *src++;
   1659 
   1660     return 1;
   1661 }
   1662 
   1663 #if !defined(WORD64) && !defined(LONG64)
   1664 static int
   1665 PutPixel32(
   1666     register XImage	*ximage,
   1667     int			 x,
   1668     int			 y,
   1669     unsigned long	 pixel)
   1670 {
   1671     unsigned char *addr;
   1672 
   1673     if(x < 0 || y < 0)
   1674     	return 0;
   1675 
   1676     addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
   1677     *((unsigned long *)addr) = pixel;
   1678     return 1;
   1679 }
   1680 #endif
   1681 
   1682 static int
   1683 PutPixel32MSB(
   1684     register XImage	*ximage,
   1685     int			 x,
   1686     int			 y,
   1687     unsigned long	 pixel)
   1688 {
   1689     unsigned char *addr;
   1690 
   1691     if(x < 0 || y < 0)
   1692     	return 0;
   1693 
   1694     addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
   1695     addr[0] = pixel >> 24;
   1696     addr[1] = pixel >> 16;
   1697     addr[2] = pixel >> 8;
   1698     addr[3] = pixel;
   1699     return 1;
   1700 }
   1701 
   1702 static int
   1703 PutPixel32LSB(
   1704     register XImage	*ximage,
   1705     int			 x,
   1706     int			 y,
   1707     unsigned long	 pixel)
   1708 {
   1709     unsigned char *addr;
   1710 
   1711     if(x < 0 || y < 0)
   1712     	return 0;
   1713 
   1714     addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
   1715     addr[3] = pixel >> 24;
   1716     addr[2] = pixel >> 16;
   1717     addr[1] = pixel >> 8;
   1718     addr[0] = pixel;
   1719     return 1;
   1720 }
   1721 
   1722 static int
   1723 PutPixel16MSB(
   1724     register XImage	*ximage,
   1725     int			 x,
   1726     int			 y,
   1727     unsigned long	 pixel)
   1728 {
   1729     unsigned char *addr;
   1730 
   1731     if(x < 0 || y < 0)
   1732     	return 0;
   1733 
   1734     addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
   1735     addr[0] = pixel >> 8;
   1736     addr[1] = pixel;
   1737     return 1;
   1738 }
   1739 
   1740 static int
   1741 PutPixel16LSB(
   1742     register XImage	*ximage,
   1743     int			 x,
   1744     int			 y,
   1745     unsigned long	 pixel)
   1746 {
   1747     unsigned char *addr;
   1748 
   1749     if(x < 0 || y < 0)
   1750     	return 0;
   1751 
   1752     addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
   1753     addr[1] = pixel >> 8;
   1754     addr[0] = pixel;
   1755     return 1;
   1756 }
   1757 
   1758 static int
   1759 PutPixel8(
   1760     register XImage	*ximage,
   1761     int			 x,
   1762     int			 y,
   1763     unsigned long	 pixel)
   1764 {
   1765     if(x < 0 || y < 0)
   1766     	return 0;
   1767 
   1768     ximage->data[ZINDEX8(x, y, ximage)] = pixel;
   1769     return 1;
   1770 }
   1771 
   1772 static int
   1773 PutPixel1MSB(
   1774     register XImage	*ximage,
   1775     int			 x,
   1776     int			 y,
   1777     unsigned long	 pixel)
   1778 {
   1779     if(x < 0 || y < 0)
   1780     	return 0;
   1781 
   1782     if (pixel & 1)
   1783 	ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
   1784     else
   1785 	ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
   1786     return 1;
   1787 }
   1788 
   1789 static int
   1790 PutPixel1LSB(
   1791     register XImage	*ximage,
   1792     int			 x,
   1793     int			 y,
   1794     unsigned long	 pixel)
   1795 {
   1796     if(x < 0 || y < 0)
   1797     	return 0;
   1798 
   1799     if (pixel & 1)
   1800 	ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
   1801     else
   1802 	ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
   1803     return 1;
   1804 }
   1805 
   1806 
   1807 /*
   1808  * This function parses an Xpm file or data and directly create an XImage
   1809  */
   1810 int
   1811 xpmParseDataAndCreate(
   1812     Display		 *display,
   1813     xpmData		 *data,
   1814     XImage		**image_return,
   1815     XImage		**shapeimage_return,
   1816     XpmImage		 *image,
   1817     XpmInfo		 *info,
   1818     XpmAttributes	 *attributes)
   1819 {
   1820     /* variables stored in the XpmAttributes structure */
   1821     Visual *visual;
   1822     Colormap colormap;
   1823     unsigned int depth;
   1824     int bitmap_format;
   1825     XpmFreeColorsFunc freeColors;
   1826 
   1827     /* variables to return */
   1828     XImage *ximage = NULL;
   1829     XImage *shapeimage = NULL;
   1830     unsigned int mask_pixel_index = XpmUndefPixel;
   1831 
   1832     /* calculation variables */
   1833     Pixel *image_pixels = NULL;
   1834     Pixel *mask_pixels = NULL;
   1835     Pixel *alloc_pixels = NULL;
   1836     Pixel *used_pixels = NULL;
   1837     unsigned int nalloc_pixels = 0;
   1838     unsigned int nused_pixels = 0;
   1839     unsigned int width, height, ncolors, cpp;
   1840     unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
   1841     XpmColor *colorTable = NULL;
   1842     char *hints_cmt = NULL;
   1843     char *colors_cmt = NULL;
   1844     char *pixels_cmt = NULL;
   1845 
   1846     unsigned int cmts;
   1847     int ErrorStatus;
   1848     xpmHashTable hashtable;
   1849 
   1850 
   1851     /* initialize return values */
   1852     if (image_return)
   1853 	*image_return = NULL;
   1854     if (shapeimage_return)
   1855 	*shapeimage_return = NULL;
   1856 
   1857 
   1858     /* retrieve information from the XpmAttributes */
   1859     if (attributes && (attributes->valuemask & XpmVisual))
   1860 	visual = attributes->visual;
   1861     else
   1862 	visual = XDefaultVisual(display, XDefaultScreen(display));
   1863 
   1864     if (attributes && (attributes->valuemask & XpmColormap))
   1865 	colormap = attributes->colormap;
   1866     else
   1867 	colormap = XDefaultColormap(display, XDefaultScreen(display));
   1868 
   1869     if (attributes && (attributes->valuemask & XpmDepth))
   1870 	depth = attributes->depth;
   1871     else
   1872 	depth = XDefaultDepth(display, XDefaultScreen(display));
   1873 
   1874     if (attributes && (attributes->valuemask & XpmBitmapFormat))
   1875 	bitmap_format = attributes->bitmap_format;
   1876     else
   1877 	bitmap_format = ZPixmap;
   1878 
   1879     if (attributes && (attributes->valuemask & XpmFreeColors))
   1880 	freeColors = attributes->free_colors;
   1881     else
   1882 	freeColors = FreeColors;
   1883 
   1884     cmts = info && (info->valuemask & XpmReturnComments);
   1885 
   1886     /*
   1887      * parse the header
   1888      */
   1889     ErrorStatus = xpmParseHeader(data);
   1890     if (ErrorStatus != XpmSuccess)
   1891 	return (ErrorStatus);
   1892 
   1893     /*
   1894      * read values
   1895      */
   1896     ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
   1897 				 &x_hotspot, &y_hotspot, &hotspot,
   1898 				 &extensions);
   1899     if (ErrorStatus != XpmSuccess)
   1900 	return (ErrorStatus);
   1901 
   1902     /*
   1903      * store the hints comment line
   1904      */
   1905     if (cmts)
   1906 	xpmGetCmt(data, &hints_cmt);
   1907 
   1908     /*
   1909      * init the hashtable
   1910      */
   1911     if (USE_HASHTABLE) {
   1912 	ErrorStatus = xpmHashTableInit(&hashtable);
   1913 	if (ErrorStatus != XpmSuccess)
   1914 	    RETURN(ErrorStatus);
   1915     }
   1916 
   1917     /*
   1918      * read colors
   1919      */
   1920     ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
   1921     if (ErrorStatus != XpmSuccess)
   1922 	RETURN(ErrorStatus);
   1923 
   1924     /*
   1925      * store the colors comment line
   1926      */
   1927     if (cmts)
   1928 	xpmGetCmt(data, &colors_cmt);
   1929 
   1930     /* malloc pixels index tables */
   1931     if (ncolors >= UINT_MAX / sizeof(Pixel))
   1932 	RETURN(XpmNoMemory);
   1933 
   1934     image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
   1935     if (!image_pixels)
   1936 	RETURN(XpmNoMemory);
   1937 
   1938     mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
   1939     if (!mask_pixels)
   1940 	RETURN(XpmNoMemory);
   1941 
   1942     /* maximum of allocated pixels will be the number of colors */
   1943     alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
   1944     if (!alloc_pixels)
   1945 	RETURN(XpmNoMemory);
   1946 
   1947     /* maximum of allocated pixels will be the number of colors */
   1948     used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
   1949     if (!used_pixels)
   1950 	RETURN(XpmNoMemory);
   1951 
   1952     /* get pixel colors, store them in index tables */
   1953     ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
   1954 			       image_pixels, mask_pixels, &mask_pixel_index,
   1955 			       alloc_pixels, &nalloc_pixels, used_pixels,
   1956 			       &nused_pixels);
   1957 
   1958     if (ErrorStatus != XpmSuccess
   1959 	&& (ErrorStatus < 0 || (attributes
   1960 				&& (attributes->valuemask & XpmExactColors)
   1961 				&& attributes->exactColors)))
   1962 	RETURN(ErrorStatus);
   1963 
   1964     /* now create the ximage */
   1965     if (image_return) {
   1966 	ErrorStatus = CreateXImage(display, visual, depth,
   1967 				   (depth == 1 ? bitmap_format : ZPixmap),
   1968 				   width, height, &ximage);
   1969 	if (ErrorStatus != XpmSuccess)
   1970 	    RETURN(ErrorStatus);
   1971 
   1972 
   1973 	/*
   1974 	 * set the XImage pointer function, to be used with XPutPixel,
   1975 	 * to an internal optimized function
   1976 	 */
   1977 
   1978 	if (ximage->bits_per_pixel == 8)
   1979 	    ximage->f.put_pixel = PutPixel8;
   1980 	else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
   1981 		 (ximage->byte_order == ximage->bitmap_bit_order))
   1982 	    if (ximage->bitmap_bit_order == MSBFirst)
   1983 		ximage->f.put_pixel = PutPixel1MSB;
   1984 	    else
   1985 		ximage->f.put_pixel = PutPixel1LSB;
   1986 	else if (ximage->bits_per_pixel == 16)
   1987 	    if (ximage->bitmap_bit_order == MSBFirst)
   1988 		ximage->f.put_pixel = PutPixel16MSB;
   1989 	    else
   1990 		ximage->f.put_pixel = PutPixel16LSB;
   1991 	else if (ximage->bits_per_pixel == 32)
   1992 #if !defined(WORD64) && !defined(LONG64)
   1993 	    if (*((char *)&byteorderpixel) == ximage->byte_order)
   1994 		ximage->f.put_pixel = PutPixel32;
   1995 	    else
   1996 #endif
   1997 		if (ximage->bitmap_bit_order == MSBFirst)
   1998 		    ximage->f.put_pixel = PutPixel32MSB;
   1999 		else
   2000 		    ximage->f.put_pixel = PutPixel32LSB;
   2001 	else if ((ximage->bits_per_pixel | ximage->depth) == 1)
   2002 	    ximage->f.put_pixel = PutPixel1;
   2003 	else
   2004 	    ximage->f.put_pixel = PutPixel;
   2005     }
   2006 
   2007     /* create the shape mask image */
   2008     if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
   2009 	ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
   2010 				   width, height, &shapeimage);
   2011 	if (ErrorStatus != XpmSuccess)
   2012 	    RETURN(ErrorStatus);
   2013 
   2014 	if (shapeimage->bitmap_bit_order == MSBFirst)
   2015 	    shapeimage->f.put_pixel = PutPixel1MSB;
   2016 	else
   2017 	    shapeimage->f.put_pixel = PutPixel1LSB;
   2018     }
   2019 
   2020     /*
   2021      * read pixels and put them in the XImage
   2022      */
   2023     ErrorStatus = ParseAndPutPixels(data, width, height, ncolors, cpp,
   2024 				    colorTable, &hashtable,
   2025 				    ximage, image_pixels,
   2026 				    shapeimage, mask_pixels);
   2027     XpmFree(image_pixels);
   2028     image_pixels = NULL;
   2029     XpmFree(mask_pixels);
   2030     mask_pixels = NULL;
   2031 
   2032     /*
   2033      * free the hastable
   2034      */
   2035     if (ErrorStatus != XpmSuccess)
   2036 	RETURN(ErrorStatus);
   2037     else if (USE_HASHTABLE)
   2038 	xpmHashTableFree(&hashtable);
   2039 
   2040     /*
   2041      * store the pixels comment line
   2042      */
   2043     if (cmts)
   2044 	xpmGetCmt(data, &pixels_cmt);
   2045 
   2046     /*
   2047      * parse extensions
   2048      */
   2049     if (info && (info->valuemask & XpmReturnExtensions)) {
   2050 	if (extensions) {
   2051 	    ErrorStatus = xpmParseExtensions(data, &info->extensions,
   2052 					     &info->nextensions);
   2053 	    if (ErrorStatus != XpmSuccess)
   2054 		RETURN(ErrorStatus);
   2055 	} else {
   2056 	    info->extensions = NULL;
   2057 	    info->nextensions = 0;
   2058 	}
   2059     }
   2060     /*
   2061      * store found information in the XpmImage structure
   2062      */
   2063     image->width = width;
   2064     image->height = height;
   2065     image->cpp = cpp;
   2066     image->ncolors = ncolors;
   2067     image->colorTable = colorTable;
   2068     image->data = NULL;
   2069 
   2070     if (info) {
   2071 	if (cmts) {
   2072 	    info->hints_cmt = hints_cmt;
   2073 	    info->colors_cmt = colors_cmt;
   2074 	    info->pixels_cmt = pixels_cmt;
   2075 	}
   2076 	if (hotspot) {
   2077 	    info->x_hotspot = x_hotspot;
   2078 	    info->y_hotspot = y_hotspot;
   2079 	    info->valuemask |= XpmHotspot;
   2080 	}
   2081     }
   2082     /* if requested return used pixels in the XpmAttributes structure */
   2083     if (attributes && (attributes->valuemask & XpmReturnPixels ||
   2084 /* 3.2 backward compatibility code */
   2085 	attributes->valuemask & XpmReturnInfos)) {
   2086 /* end 3.2 bc */
   2087 	attributes->pixels = used_pixels;
   2088 	attributes->npixels = nused_pixels;
   2089 	attributes->mask_pixel = mask_pixel_index;
   2090     } else
   2091 	XpmFree(used_pixels);
   2092 
   2093     /* if requested return alloc'ed pixels in the XpmAttributes structure */
   2094     if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
   2095 	attributes->alloc_pixels = alloc_pixels;
   2096 	attributes->nalloc_pixels = nalloc_pixels;
   2097     } else
   2098 	XpmFree(alloc_pixels);
   2099 
   2100     /* return created images */
   2101     if (image_return)
   2102 	*image_return = ximage;
   2103     if (shapeimage_return)
   2104 	*shapeimage_return = shapeimage;
   2105 
   2106     return (XpmSuccess);
   2107 
   2108 /* exit point in case of error, free only locally allocated variables */
   2109 error:
   2110     if (USE_HASHTABLE)
   2111 	xpmHashTableFree(&hashtable);
   2112     if (colorTable)
   2113 	xpmFreeColorTable(colorTable, ncolors);
   2114     if (hints_cmt)
   2115 	XpmFree(hints_cmt);
   2116     if (colors_cmt)
   2117 	XpmFree(colors_cmt);
   2118     if (pixels_cmt)
   2119 	XpmFree(pixels_cmt);
   2120     if (ximage)
   2121 	XDestroyImage(ximage);
   2122     if (shapeimage)
   2123 	XDestroyImage(shapeimage);
   2124     if (image_pixels)
   2125 	XpmFree(image_pixels);
   2126     if (mask_pixels)
   2127 	XpmFree(mask_pixels);
   2128     if (nalloc_pixels)
   2129 	(*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
   2130     if (alloc_pixels)
   2131 	XpmFree(alloc_pixels);
   2132     if (used_pixels)
   2133 	XpmFree(used_pixels);
   2134 
   2135     return (ErrorStatus);
   2136 }
   2137 
   2138 static int
   2139 ParseAndPutPixels(
   2140     xpmData		*data,
   2141     unsigned int	 width,
   2142     unsigned int	 height,
   2143     unsigned int	 ncolors,
   2144     unsigned int	 cpp,
   2145     XpmColor		*colorTable,
   2146     xpmHashTable	*hashtable,
   2147     XImage		*image,
   2148     Pixel		*image_pixels,
   2149     XImage		*shapeimage,
   2150     Pixel		*shape_pixels)
   2151 {
   2152     unsigned int a, x, y;
   2153 
   2154     switch (cpp) {
   2155 
   2156     case (1):				/* Optimize for single character
   2157 					 * colors */
   2158 	{
   2159 	    unsigned short colidx[256];
   2160 
   2161 	    if (ncolors > 256)
   2162 		return (XpmFileInvalid);
   2163 
   2164 	    bzero((char *)colidx, 256 * sizeof(short));
   2165 	    for (a = 0; a < ncolors; a++)
   2166 		colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
   2167 
   2168 	    for (y = 0; y < height; y++) {
   2169 		xpmNextString(data);
   2170 		for (x = 0; x < width; x++) {
   2171 		    int c = xpmGetC(data);
   2172 
   2173 		    if (c > 0 && c < 256 && colidx[c] != 0) {
   2174 			XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
   2175 			if (shapeimage)
   2176 			    XPutPixel(shapeimage, x, y,
   2177 				      shape_pixels[colidx[c] - 1]);
   2178 		    } else
   2179 			return (XpmFileInvalid);
   2180 		}
   2181 	    }
   2182 	}
   2183 	break;
   2184 
   2185     case (2):				/* Optimize for double character
   2186 					 * colors */
   2187 	{
   2188 
   2189 /* free all allocated pointers at all exits */
   2190 #define FREE_CIDX do {int f; for (f = 0; f < 256; f++) \
   2191 if (cidx[f]) XpmFree(cidx[f]);} while(0)
   2192 
   2193 	    /* array of pointers malloced by need */
   2194 	    unsigned short *cidx[256];
   2195 	    unsigned int char1;
   2196 
   2197 	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
   2198 	    for (a = 0; a < ncolors; a++) {
   2199 		char1 = (unsigned char) colorTable[a].string[0];
   2200 		if (cidx[char1] == NULL) { /* get new memory */
   2201 		    cidx[char1] = (unsigned short *)
   2202 			XpmCalloc(256, sizeof(unsigned short));
   2203 		    if (cidx[char1] == NULL) { /* new block failed */
   2204 			FREE_CIDX;
   2205 			return (XpmNoMemory);
   2206 		    }
   2207 		}
   2208 		cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
   2209 	    }
   2210 
   2211 	    for (y = 0; y < height; y++) {
   2212 		xpmNextString(data);
   2213 		for (x = 0; x < width; x++) {
   2214 		    int cc1 = xpmGetC(data);
   2215 		    if (cc1 > 0 && cc1 < 256) {
   2216 			int cc2 = xpmGetC(data);
   2217 			if (cc2 > 0 && cc2 < 256 &&
   2218 			    cidx[cc1] && cidx[cc1][cc2] != 0) {
   2219 			    XPutPixel(image, x, y,
   2220 				      image_pixels[cidx[cc1][cc2] - 1]);
   2221 			    if (shapeimage)
   2222 				XPutPixel(shapeimage, x, y,
   2223 					  shape_pixels[cidx[cc1][cc2] - 1]);
   2224 			} else {
   2225 			    FREE_CIDX;
   2226 			    return (XpmFileInvalid);
   2227 			}
   2228 		    } else {
   2229 			FREE_CIDX;
   2230 			return (XpmFileInvalid);
   2231 		    }
   2232 		}
   2233 	    }
   2234 	    FREE_CIDX;
   2235 	}
   2236 	break;
   2237 
   2238     default:				/* Non-optimized case of long color
   2239 					 * names */
   2240 	{
   2241 	    char *s;
   2242 	    char buf[BUFSIZ];
   2243 
   2244 	    if (cpp >= sizeof(buf))
   2245 		return (XpmFileInvalid);
   2246 
   2247 	    buf[cpp] = '\0';
   2248 	    if (USE_HASHTABLE) {
   2249 		xpmHashAtom *slot;
   2250 
   2251 		for (y = 0; y < height; y++) {
   2252 		    xpmNextString(data);
   2253 		    for (x = 0; x < width; x++) {
   2254 			for (a = 0, s = buf; a < cpp; a++, s++)
   2255 			    *s = xpmGetC(data);
   2256 			slot = xpmHashSlot(hashtable, buf);
   2257 			if (!*slot)	/* no color matches */
   2258 			    return (XpmFileInvalid);
   2259 			XPutPixel(image, x, y,
   2260 				  image_pixels[HashColorIndex(slot)]);
   2261 			if (shapeimage)
   2262 			    XPutPixel(shapeimage, x, y,
   2263 				      shape_pixels[HashColorIndex(slot)]);
   2264 		    }
   2265 		}
   2266 	    } else {
   2267 		for (y = 0; y < height; y++) {
   2268 		    xpmNextString(data);
   2269 		    for (x = 0; x < width; x++) {
   2270 			for (a = 0, s = buf; a < cpp; a++, s++)
   2271 			    *s = xpmGetC(data);
   2272 			for (a = 0; a < ncolors; a++)
   2273 			    if (!strcmp(colorTable[a].string, buf))
   2274 				break;
   2275 			if (a == ncolors)	/* no color matches */
   2276 			    return (XpmFileInvalid);
   2277 			XPutPixel(image, x, y, image_pixels[a]);
   2278 			if (shapeimage)
   2279 			    XPutPixel(shapeimage, x, y, shape_pixels[a]);
   2280 		    }
   2281 		}
   2282 	    }
   2283 	}
   2284 	break;
   2285     }
   2286     return (XpmSuccess);
   2287 }
   2288