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