create.c revision 4e08afa9
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    if (width != 0 && (*image_return)->bits_per_pixel >= INT_MAX / width) {
1001	XDestroyImage(*image_return);
1002	*image_return = NULL;
1003	return XpmNoMemory;
1004    }
1005    /* now that bytes_per_line must have been set properly alloc data */
1006    if((*image_return)->bytes_per_line == 0 ||  height == 0) {
1007	XDestroyImage(*image_return);
1008	*image_return = NULL;
1009    	return XpmNoMemory;
1010    }
1011    (*image_return)->data =
1012	(char *) XpmMalloc((*image_return)->bytes_per_line * height);
1013
1014    if (!(*image_return)->data) {
1015	XDestroyImage(*image_return);
1016	*image_return = NULL;
1017	return (XpmNoMemory);
1018    }
1019#else
1020    /* under FOR_MSW and AMIGA XCreateImage has done it all */
1021#endif
1022    return (XpmSuccess);
1023}
1024
1025#ifndef FOR_MSW
1026# ifndef AMIGA
1027/*
1028 * The functions below are written from X11R5 MIT's code (XImUtil.c)
1029 *
1030 * The idea is to have faster functions than the standard XPutPixel function
1031 * to build the image data. Indeed we can speed up things by suppressing tests
1032 * performed for each pixel. We do the same tests but at the image level.
1033 * We also assume that we use only ZPixmap images with null offsets.
1034 */
1035
1036LFUNC(_putbits, void, (register char *src, int dstoffset,
1037		       register int numbits, register char *dst));
1038
1039LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
1040
1041static unsigned char const _reverse_byte[0x100] = {
1042    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1043    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1044    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1045    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1046    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1047    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1048    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1049    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1050    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1051    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1052    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1053    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1054    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1055    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1056    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1057    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1058    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1059    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1060    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1061    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1062    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1063    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1064    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1065    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1066    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1067    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1068    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1069    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1070    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1071    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1072    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1073    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1074};
1075
1076static int
1077_XReverse_Bytes(
1078    register unsigned char	*bpt,
1079    register unsigned int	 nb)
1080{
1081    do {
1082	*bpt = _reverse_byte[*bpt];
1083	bpt++;
1084    } while (--nb > 0); /* is nb user-controled? */
1085    return 0;
1086}
1087
1088
1089void
1090xpm_xynormalizeimagebits(
1091    register unsigned char	*bp,
1092    register XImage		*img)
1093{
1094    register unsigned char c;
1095
1096    if (img->byte_order != img->bitmap_bit_order) {
1097	switch (img->bitmap_unit) {
1098
1099	case 16:
1100	    c = *bp;
1101	    *bp = *(bp + 1);
1102	    *(bp + 1) = c;
1103	    break;
1104
1105	case 32:
1106	    c = *(bp + 3);
1107	    *(bp + 3) = *bp;
1108	    *bp = c;
1109	    c = *(bp + 2);
1110	    *(bp + 2) = *(bp + 1);
1111	    *(bp + 1) = c;
1112	    break;
1113	}
1114    }
1115    if (img->bitmap_bit_order == MSBFirst)
1116	_XReverse_Bytes(bp, img->bitmap_unit >> 3);
1117}
1118
1119void
1120xpm_znormalizeimagebits(
1121    register unsigned char	*bp,
1122    register XImage		*img)
1123{
1124    register unsigned char c;
1125
1126    switch (img->bits_per_pixel) {
1127
1128    case 2:
1129	_XReverse_Bytes(bp, 1);
1130	break;
1131
1132    case 4:
1133	*bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
1134	break;
1135
1136    case 16:
1137	c = *bp;
1138	*bp = *(bp + 1);
1139	*(bp + 1) = c;
1140	break;
1141
1142    case 24:
1143	c = *(bp + 2);
1144	*(bp + 2) = *bp;
1145	*bp = c;
1146	break;
1147
1148    case 32:
1149	c = *(bp + 3);
1150	*(bp + 3) = *bp;
1151	*bp = c;
1152	c = *(bp + 2);
1153	*(bp + 2) = *(bp + 1);
1154	*(bp + 1) = c;
1155	break;
1156    }
1157}
1158
1159static unsigned char const _lomask[0x09] = {
11600x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1161static unsigned char const _himask[0x09] = {
11620xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
1163
1164static void
1165_putbits(
1166    register char	*src,		/* address of source bit string */
1167    int			 dstoffset,	/* bit offset into destination;
1168					 * range is 0-31 */
1169    register int	 numbits,	/* number of bits to copy to
1170					 * destination */
1171    register char	*dst)		/* address of destination bit string */
1172{
1173    register unsigned char chlo, chhi;
1174    int hibits;
1175
1176    dst = dst + (dstoffset >> 3);
1177    dstoffset = dstoffset & 7;
1178    hibits = 8 - dstoffset;
1179    chlo = *dst & _lomask[dstoffset];
1180    for (;;) {
1181	chhi = (*src << dstoffset) & _himask[dstoffset];
1182	if (numbits <= hibits) {
1183	    chhi = chhi & _lomask[dstoffset + numbits];
1184	    *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
1185	    break;
1186	}
1187	*dst = chhi | chlo;
1188	dst++;
1189	numbits = numbits - hibits;
1190	chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
1191	src++;
1192	if (numbits <= dstoffset) {
1193	    chlo = chlo & _lomask[numbits];
1194	    *dst = (*dst & _himask[numbits]) | chlo;
1195	    break;
1196	}
1197	numbits = numbits - dstoffset;
1198    }
1199}
1200
1201/*
1202 * Default method to write pixels into a Z image data structure.
1203 * The algorithm used is:
1204 *
1205 *	copy the destination bitmap_unit or Zpixel to temp
1206 *	normalize temp if needed
1207 *	copy the pixel bits into the temp
1208 *	renormalize temp if needed
1209 *	copy the temp back into the destination image data
1210 */
1211
1212static void
1213PutImagePixels(
1214    XImage		*image,
1215    unsigned int	 width,
1216    unsigned int	 height,
1217    unsigned int	*pixelindex,
1218    Pixel		*pixels)
1219{
1220    register char *src;
1221    register char *dst;
1222    register unsigned int *iptr;
1223    register unsigned int x, y;
1224    register char *data;
1225    Pixel pixel, px;
1226    int nbytes, depth, ibu, ibpp, i;
1227
1228    data = image->data;
1229    iptr = pixelindex;
1230    depth = image->depth;
1231    if (depth == 1) {
1232	ibu = image->bitmap_unit;
1233	for (y = 0; y < height; y++) /* how can we trust height */
1234	    for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
1235		pixel = pixels[*iptr];
1236		for (i = 0, px = pixel; i < sizeof(unsigned long);
1237		     i++, px >>= 8)
1238		    ((unsigned char *) &pixel)[i] = px;
1239		src = &data[XYINDEX(x, y, image)];
1240		dst = (char *) &px;
1241		px = 0;
1242		nbytes = ibu >> 3;
1243		for (i = nbytes; --i >= 0;)
1244		    *dst++ = *src++;
1245		XYNORMALIZE(&px, image);
1246		_putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
1247		XYNORMALIZE(&px, image);
1248		src = (char *) &px;
1249		dst = &data[XYINDEX(x, y, image)];
1250		for (i = nbytes; --i >= 0;)
1251		    *dst++ = *src++;
1252	    }
1253    } else {
1254	ibpp = image->bits_per_pixel;
1255	for (y = 0; y < height; y++)
1256	    for (x = 0; x < width; x++, iptr++) {
1257		pixel = pixels[*iptr];
1258		if (depth == 4)
1259		    pixel &= 0xf;
1260		for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
1261		     px >>= 8)
1262		    ((unsigned char *) &pixel)[i] = px;
1263		src = &data[ZINDEX(x, y, image)];
1264		dst = (char *) &px;
1265		px = 0;
1266		nbytes = (ibpp + 7) >> 3;
1267		for (i = nbytes; --i >= 0;)
1268		    *dst++ = *src++;
1269		ZNORMALIZE(&px, image);
1270		_putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1271		ZNORMALIZE(&px, image);
1272		src = (char *) &px;
1273		dst = &data[ZINDEX(x, y, image)];
1274		for (i = nbytes; --i >= 0;)
1275		    *dst++ = *src++;
1276	    }
1277    }
1278}
1279
1280/*
1281 * write pixels into a 32-bits Z image data structure
1282 */
1283
1284#if !defined(WORD64) && !defined(LONG64)
1285/* this item is static but deterministic so let it slide; doesn't
1286 * hurt re-entrancy of this library. Note if it is actually const then would
1287 * be OK under rules of ANSI-C but probably not C++ which may not
1288 * want to allocate space for it.
1289 */
1290static unsigned long byteorderpixel = MSBFirst << 24;
1291
1292#endif
1293
1294/*
1295   WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
1296   3.2e code - by default you get the speeded-up version.
1297*/
1298
1299static void
1300PutImagePixels32(
1301    XImage		*image,
1302    unsigned int	 width,
1303    unsigned int	 height,
1304    unsigned int	*pixelindex,
1305    Pixel		*pixels)
1306{
1307    unsigned char *data;
1308    unsigned int *iptr;
1309    unsigned int y;
1310    Pixel pixel;
1311
1312#ifdef WITHOUT_SPEEDUPS
1313
1314    unsigned int x;
1315    unsigned char *addr;
1316
1317    data = (unsigned char *) image->data;
1318    iptr = pixelindex;
1319#if !defined(WORD64) && !defined(LONG64)
1320    if (*((char *) &byteorderpixel) == image->byte_order) {
1321	for (y = 0; y < height; y++)
1322	    for (x = 0; x < width; x++, iptr++) {
1323		addr = &data[ZINDEX32(x, y, image)];
1324		*((unsigned long *) addr) = pixels[*iptr];
1325	    }
1326    } else
1327#endif
1328    if (image->byte_order == MSBFirst)
1329	for (y = 0; y < height; y++)
1330	    for (x = 0; x < width; x++, iptr++) {
1331		addr = &data[ZINDEX32(x, y, image)];
1332		pixel = pixels[*iptr];
1333		addr[0] = pixel >> 24;
1334		addr[1] = pixel >> 16;
1335		addr[2] = pixel >> 8;
1336		addr[3] = pixel;
1337	    }
1338    else
1339	for (y = 0; y < height; y++)
1340	    for (x = 0; x < width; x++, iptr++) {
1341		addr = &data[ZINDEX32(x, y, image)];
1342		pixel = pixels[*iptr];
1343		addr[0] = pixel;
1344		addr[1] = pixel >> 8;
1345		addr[2] = pixel >> 16;
1346		addr[3] = pixel >> 24;
1347	    }
1348
1349#else  /* WITHOUT_SPEEDUPS */
1350
1351    unsigned int bpl = image->bytes_per_line;
1352    unsigned char *data_ptr, *max_data;
1353
1354    data = (unsigned char *) image->data;
1355    iptr = pixelindex;
1356#if !defined(WORD64) && !defined(LONG64)
1357    if (*((char *) &byteorderpixel) == image->byte_order) {
1358	for (y = 0; y < height; y++) {
1359	    data_ptr = data;
1360	    max_data = data_ptr + (width << 2);
1361
1362	    while (data_ptr < max_data) {
1363		*((unsigned long *) data_ptr) = pixels[*(iptr++)];
1364		data_ptr += (1 << 2);
1365	    }
1366	    data += bpl;
1367	}
1368    } else
1369#endif
1370    if (image->byte_order == MSBFirst)
1371	for (y = 0; y < height; y++) {
1372	    data_ptr = data;
1373	    max_data = data_ptr + (width << 2);
1374
1375	    while (data_ptr < max_data) {
1376		pixel = pixels[*(iptr++)];
1377
1378		*data_ptr++ = pixel >> 24;
1379		*data_ptr++ = pixel >> 16;
1380		*data_ptr++ = pixel >> 8;
1381		*data_ptr++ = pixel;
1382
1383	    }
1384	    data += bpl;
1385	}
1386    else
1387	for (y = 0; y < height; y++) {
1388	    data_ptr = data;
1389	    max_data = data_ptr + (width << 2);
1390
1391	    while (data_ptr < max_data) {
1392		pixel = pixels[*(iptr++)];
1393
1394		*data_ptr++ = pixel;
1395		*data_ptr++ = pixel >> 8;
1396		*data_ptr++ = pixel >> 16;
1397		*data_ptr++ = pixel >> 24;
1398	    }
1399	    data += bpl;
1400	}
1401
1402#endif /* WITHOUT_SPEEDUPS */
1403}
1404
1405/*
1406 * write pixels into a 16-bits Z image data structure
1407 */
1408
1409static void
1410PutImagePixels16(
1411    XImage		*image,
1412    unsigned int	 width,
1413    unsigned int	 height,
1414    unsigned int	*pixelindex,
1415    Pixel		*pixels)
1416{
1417    unsigned char *data;
1418    unsigned int *iptr;
1419    unsigned int y;
1420
1421#ifdef WITHOUT_SPEEDUPS
1422
1423    unsigned int x;
1424    unsigned char *addr;
1425
1426    data = (unsigned char *) image->data;
1427    iptr = pixelindex;
1428    if (image->byte_order == MSBFirst)
1429	for (y = 0; y < height; y++)
1430	    for (x = 0; x < width; x++, iptr++) {
1431		addr = &data[ZINDEX16(x, y, image)];
1432		addr[0] = pixels[*iptr] >> 8;
1433		addr[1] = pixels[*iptr];
1434	    }
1435    else
1436	for (y = 0; y < height; y++)
1437	    for (x = 0; x < width; x++, iptr++) {
1438		addr = &data[ZINDEX16(x, y, image)];
1439		addr[0] = pixels[*iptr];
1440		addr[1] = pixels[*iptr] >> 8;
1441	    }
1442
1443#else  /* WITHOUT_SPEEDUPS */
1444
1445    Pixel pixel;
1446
1447    unsigned int bpl = image->bytes_per_line;
1448    unsigned char *data_ptr, *max_data;
1449
1450    data = (unsigned char *) image->data;
1451    iptr = pixelindex;
1452    if (image->byte_order == MSBFirst)
1453	for (y = 0; y < height; y++) {
1454	    data_ptr = data;
1455	    max_data = data_ptr + (width << 1);
1456
1457	    while (data_ptr < max_data) {
1458		pixel = pixels[*(iptr++)];
1459
1460		data_ptr[0] = pixel >> 8;
1461		data_ptr[1] = pixel;
1462
1463		data_ptr += (1 << 1);
1464	    }
1465	    data += bpl;
1466	}
1467    else
1468	for (y = 0; y < height; y++) {
1469	    data_ptr = data;
1470	    max_data = data_ptr + (width << 1);
1471
1472	    while (data_ptr < max_data) {
1473		pixel = pixels[*(iptr++)];
1474
1475		data_ptr[0] = pixel;
1476		data_ptr[1] = pixel >> 8;
1477
1478		data_ptr += (1 << 1);
1479	    }
1480	    data += bpl;
1481	}
1482
1483#endif /* WITHOUT_SPEEDUPS */
1484}
1485
1486/*
1487 * write pixels into a 8-bits Z image data structure
1488 */
1489
1490static void
1491PutImagePixels8(
1492    XImage		*image,
1493    unsigned int	 width,
1494    unsigned int	 height,
1495    unsigned int	*pixelindex,
1496    Pixel		*pixels)
1497{
1498    char *data;
1499    unsigned int *iptr;
1500    unsigned int y;
1501
1502#ifdef WITHOUT_SPEEDUPS
1503
1504    unsigned int x;
1505
1506    data = image->data;
1507    iptr = pixelindex;
1508    for (y = 0; y < height; y++)
1509	for (x = 0; x < width; x++, iptr++)
1510	    data[ZINDEX8(x, y, image)] = pixels[*iptr];
1511
1512#else  /* WITHOUT_SPEEDUPS */
1513
1514    unsigned int bpl = image->bytes_per_line;
1515    char *data_ptr, *max_data;
1516
1517    data = image->data;
1518    iptr = pixelindex;
1519
1520    for (y = 0; y < height; y++) {
1521	data_ptr = data;
1522	max_data = data_ptr + width;
1523
1524	while (data_ptr < max_data)
1525	    *(data_ptr++) = pixels[*(iptr++)];
1526
1527	data += bpl;
1528    }
1529
1530#endif /* WITHOUT_SPEEDUPS */
1531}
1532
1533/*
1534 * write pixels into a 1-bit depth image data structure and **offset null**
1535 */
1536
1537static void
1538PutImagePixels1(
1539    XImage		*image,
1540    unsigned int	 width,
1541    unsigned int	 height,
1542    unsigned int	*pixelindex,
1543    Pixel		*pixels)
1544{
1545    if (image->byte_order != image->bitmap_bit_order)
1546	PutImagePixels(image, width, height, pixelindex, pixels);
1547    else {
1548	unsigned int *iptr;
1549	unsigned int y;
1550	char *data;
1551
1552#ifdef WITHOUT_SPEEDUPS
1553
1554	unsigned int x;
1555
1556	data = image->data;
1557	iptr = pixelindex;
1558	if (image->bitmap_bit_order == MSBFirst)
1559	    for (y = 0; y < height; y++)
1560		for (x = 0; x < width; x++, iptr++) {
1561		    if (pixels[*iptr] & 1)
1562			data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
1563		    else
1564			data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
1565		}
1566	else
1567	    for (y = 0; y < height; y++)
1568		for (x = 0; x < width; x++, iptr++) {
1569		    if (pixels[*iptr] & 1)
1570			data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
1571		    else
1572			data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
1573		}
1574
1575#else  /* WITHOUT_SPEEDUPS */
1576
1577	char value;
1578	char *data_ptr, *max_data;
1579	int bpl = image->bytes_per_line;
1580	int diff, count;
1581
1582	data = image->data;
1583	iptr = pixelindex;
1584
1585	diff = width & 7;
1586	width >>= 3;
1587
1588	if (image->bitmap_bit_order == MSBFirst)
1589	    for (y = 0; y < height; y++) {
1590		data_ptr = data;
1591		max_data = data_ptr + width;
1592		while (data_ptr < max_data) {
1593		    value = 0;
1594
1595		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1596		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1597		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1598		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1599		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1600		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1601		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1602		    value = (value << 1) | (pixels[*(iptr++)] & 1);
1603
1604		    *(data_ptr++) = value;
1605		}
1606		if (diff) {
1607		    value = 0;
1608		    for (count = 0; count < diff; count++) {
1609			if (pixels[*(iptr++)] & 1)
1610			    value |= (0x80 >> count);
1611		    }
1612		    *(data_ptr) = value;
1613		}
1614		data += bpl;
1615	    }
1616	else
1617	    for (y = 0; y < height; y++) {
1618		data_ptr = data;
1619		max_data = data_ptr + width;
1620		while (data_ptr < max_data) {
1621		    value = 0;
1622		    iptr += 8;
1623
1624		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1625		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1626		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1627		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1628		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1629		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1630		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1631		    value = (value << 1) | (pixels[*(--iptr)] & 1);
1632
1633		    iptr += 8;
1634		    *(data_ptr++) = value;
1635		}
1636		if (diff) {
1637		    value = 0;
1638		    for (count = 0; count < diff; count++) {
1639			if (pixels[*(iptr++)] & 1)
1640			    value |= (1 << count);
1641		    }
1642		    *(data_ptr) = value;
1643		}
1644		data += bpl;
1645	    }
1646
1647#endif /* WITHOUT_SPEEDUPS */
1648    }
1649}
1650
1651int
1652XpmCreatePixmapFromXpmImage(
1653    Display		*display,
1654    Drawable		 d,
1655    XpmImage		*image,
1656    Pixmap		*pixmap_return,
1657    Pixmap		*shapemask_return,
1658    XpmAttributes	*attributes)
1659{
1660    XImage *ximage = NULL, *shapeimage = NULL;
1661    int ErrorStatus;
1662
1663    /* initialize return values */
1664    if (pixmap_return)
1665	*pixmap_return = 0;
1666    if (shapemask_return)
1667	*shapemask_return = 0;
1668
1669    /* create the ximages */
1670    ErrorStatus = XpmCreateImageFromXpmImage(display, image,
1671					     (pixmap_return ? &ximage : NULL),
1672					     (shapemask_return ?
1673					      &shapeimage : NULL),
1674					     attributes);
1675    if (ErrorStatus < 0)
1676	goto cleanup;
1677
1678    /* create the pixmaps and destroy images */
1679    if (pixmap_return && ximage) {
1680	ErrorStatus =
1681	    xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
1682	if (ErrorStatus < 0)		/* fatal error */
1683	    goto cleanup;
1684    }
1685    if (shapemask_return && shapeimage) {
1686	ErrorStatus =
1687	    xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
1688    }
1689
1690  cleanup:
1691    if (ximage != NULL)
1692	XDestroyImage(ximage);
1693    if (shapeimage != NULL)
1694	XDestroyImage(shapeimage);
1695    if (ErrorStatus < 0) {
1696	if (pixmap_return && *pixmap_return) {
1697	    XFreePixmap(display, *pixmap_return);
1698	    *pixmap_return = 0;
1699	}
1700	if (shapemask_return && *shapemask_return) {
1701	    XFreePixmap(display, *shapemask_return);
1702	    *shapemask_return = 0;
1703	}
1704    }
1705    return (ErrorStatus);
1706}
1707
1708# else /* AMIGA */
1709
1710static void
1711APutImagePixels (
1712    XImage        *image,
1713    unsigned int   width,
1714    unsigned int   height,
1715    unsigned int  *pixelindex,
1716    Pixel         *pixels)
1717{
1718    unsigned int   *data = pixelindex;
1719    unsigned int    x, y;
1720    unsigned char  *array;
1721    XImage         *tmp_img;
1722    BOOL            success = FALSE;
1723
1724    array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array));
1725    if (array != NULL)
1726    {
1727	tmp_img = AllocXImage ((((width+15)>>4)<<4), 1,
1728			       image->rp->BitMap->Depth);
1729	if (tmp_img != NULL)
1730	{
1731	    for (y = 0; y < height; ++y)
1732	    {
1733		for (x = 0; x < width; ++x)
1734		    array[x] = pixels[*(data++)];
1735		WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp);
1736	    }
1737	    FreeXImage (tmp_img);
1738	    success = TRUE;
1739	}
1740	XpmFree (array);
1741    }
1742
1743    if (!success)
1744    {
1745	for (y = 0; y < height; ++y)
1746	    for (x = 0; x < width; ++x)
1747		XPutPixel (image, x, y, pixels[*(data++)]);
1748    }
1749}
1750
1751# endif/* AMIGA */
1752#else  /* FOR_MSW part follows */
1753static void
1754MSWPutImagePixels(
1755    Display		*dc,
1756    XImage		*image,
1757    unsigned int	 width,
1758    unsigned int	 height,
1759    unsigned int	*pixelindex,
1760    Pixel		*pixels)
1761{
1762    unsigned int *data = pixelindex;
1763    unsigned int x, y;
1764    HBITMAP obm;
1765
1766    obm = SelectObject(*dc, image->bitmap);
1767    for (y = 0; y < height; y++) {
1768	for (x = 0; x < width; x++) {
1769	    SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
1770	}
1771    }
1772    SelectObject(*dc, obm);
1773}
1774
1775#endif /* FOR_MSW */
1776
1777
1778
1779#if !defined(FOR_MSW) && !defined(AMIGA)
1780
1781static int
1782PutPixel1(
1783    register XImage	*ximage,
1784    int			 x,
1785    int			 y,
1786    unsigned long	 pixel)
1787{
1788    register char *src;
1789    register char *dst;
1790    register int i;
1791    Pixel px;
1792    int nbytes;
1793
1794    if(x < 0 || y < 0)
1795    	return 0;
1796
1797    for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
1798	((unsigned char *)&pixel)[i] = px;
1799    src = &ximage->data[XYINDEX(x, y, ximage)];
1800    dst = (char *)&px;
1801    px = 0;
1802    nbytes = ximage->bitmap_unit >> 3;
1803    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
1804    XYNORMALIZE(&px, ximage);
1805    i = ((x + ximage->xoffset) % ximage->bitmap_unit);
1806    _putbits ((char *)&pixel, i, 1, (char *)&px);
1807    XYNORMALIZE(&px, ximage);
1808    src = (char *) &px;
1809    dst = &ximage->data[XYINDEX(x, y, ximage)];
1810    for (i = nbytes; --i >= 0; )
1811	*dst++ = *src++;
1812
1813    return 1;
1814}
1815
1816static int
1817PutPixel(
1818    register XImage	*ximage,
1819    int			 x,
1820    int			 y,
1821    unsigned long	 pixel)
1822{
1823    register char *src;
1824    register char *dst;
1825    register int i;
1826    Pixel px;
1827    unsigned int nbytes, ibpp;
1828
1829    if(x < 0 || y < 0)
1830    	return 0;
1831
1832    ibpp = ximage->bits_per_pixel;
1833    if (ximage->depth == 4)
1834	pixel &= 0xf;
1835    for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
1836	((unsigned char *) &pixel)[i] = px;
1837    src = &ximage->data[ZINDEX(x, y, ximage)];
1838    dst = (char *) &px;
1839    px = 0;
1840    nbytes = (ibpp + 7) >> 3;
1841    for (i = nbytes; --i >= 0;)
1842	*dst++ = *src++;
1843    ZNORMALIZE(&px, ximage);
1844    _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1845    ZNORMALIZE(&px, ximage);
1846    src = (char *) &px;
1847    dst = &ximage->data[ZINDEX(x, y, ximage)];
1848    for (i = nbytes; --i >= 0;)
1849	*dst++ = *src++;
1850
1851    return 1;
1852}
1853
1854#if !defined(WORD64) && !defined(LONG64)
1855static int
1856PutPixel32(
1857    register XImage	*ximage,
1858    int			 x,
1859    int			 y,
1860    unsigned long	 pixel)
1861{
1862    unsigned char *addr;
1863
1864    if(x < 0 || y < 0)
1865    	return 0;
1866
1867    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
1868    *((unsigned long *)addr) = pixel;
1869    return 1;
1870}
1871#endif
1872
1873static int
1874PutPixel32MSB(
1875    register XImage	*ximage,
1876    int			 x,
1877    int			 y,
1878    unsigned long	 pixel)
1879{
1880    unsigned char *addr;
1881
1882    if(x < 0 || y < 0)
1883    	return 0;
1884
1885    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
1886    addr[0] = pixel >> 24;
1887    addr[1] = pixel >> 16;
1888    addr[2] = pixel >> 8;
1889    addr[3] = pixel;
1890    return 1;
1891}
1892
1893static int
1894PutPixel32LSB(
1895    register XImage	*ximage,
1896    int			 x,
1897    int			 y,
1898    unsigned long	 pixel)
1899{
1900    unsigned char *addr;
1901
1902    if(x < 0 || y < 0)
1903    	return 0;
1904
1905    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
1906    addr[3] = pixel >> 24;
1907    addr[2] = pixel >> 16;
1908    addr[1] = pixel >> 8;
1909    addr[0] = pixel;
1910    return 1;
1911}
1912
1913static int
1914PutPixel16MSB(
1915    register XImage	*ximage,
1916    int			 x,
1917    int			 y,
1918    unsigned long	 pixel)
1919{
1920    unsigned char *addr;
1921
1922    if(x < 0 || y < 0)
1923    	return 0;
1924
1925    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
1926    addr[0] = pixel >> 8;
1927    addr[1] = pixel;
1928    return 1;
1929}
1930
1931static int
1932PutPixel16LSB(
1933    register XImage	*ximage,
1934    int			 x,
1935    int			 y,
1936    unsigned long	 pixel)
1937{
1938    unsigned char *addr;
1939
1940    if(x < 0 || y < 0)
1941    	return 0;
1942
1943    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
1944    addr[1] = pixel >> 8;
1945    addr[0] = pixel;
1946    return 1;
1947}
1948
1949static int
1950PutPixel8(
1951    register XImage	*ximage,
1952    int			 x,
1953    int			 y,
1954    unsigned long	 pixel)
1955{
1956    if(x < 0 || y < 0)
1957    	return 0;
1958
1959    ximage->data[ZINDEX8(x, y, ximage)] = pixel;
1960    return 1;
1961}
1962
1963static int
1964PutPixel1MSB(
1965    register XImage	*ximage,
1966    int			 x,
1967    int			 y,
1968    unsigned long	 pixel)
1969{
1970    if(x < 0 || y < 0)
1971    	return 0;
1972
1973    if (pixel & 1)
1974	ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
1975    else
1976	ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
1977    return 1;
1978}
1979
1980static int
1981PutPixel1LSB(
1982    register XImage	*ximage,
1983    int			 x,
1984    int			 y,
1985    unsigned long	 pixel)
1986{
1987    if(x < 0 || y < 0)
1988    	return 0;
1989
1990    if (pixel & 1)
1991	ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
1992    else
1993	ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
1994    return 1;
1995}
1996
1997#endif /* not FOR_MSW && not AMIGA */
1998
1999/*
2000 * This function parses an Xpm file or data and directly create an XImage
2001 */
2002int
2003xpmParseDataAndCreate(
2004    Display		 *display,
2005    xpmData		 *data,
2006    XImage		**image_return,
2007    XImage		**shapeimage_return,
2008    XpmImage		 *image,
2009    XpmInfo		 *info,
2010    XpmAttributes	 *attributes)
2011{
2012    /* variables stored in the XpmAttributes structure */
2013    Visual *visual;
2014    Colormap colormap;
2015    unsigned int depth;
2016    int bitmap_format;
2017    XpmFreeColorsFunc freeColors;
2018
2019    /* variables to return */
2020    XImage *ximage = NULL;
2021    XImage *shapeimage = NULL;
2022    unsigned int mask_pixel_index = XpmUndefPixel;
2023
2024    /* calculation variables */
2025    Pixel *image_pixels = NULL;
2026    Pixel *mask_pixels = NULL;
2027    Pixel *alloc_pixels = NULL;
2028    Pixel *used_pixels = NULL;
2029    unsigned int nalloc_pixels = 0;
2030    unsigned int nused_pixels = 0;
2031    unsigned int width, height, ncolors, cpp;
2032    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
2033    XpmColor *colorTable = NULL;
2034    char *hints_cmt = NULL;
2035    char *colors_cmt = NULL;
2036    char *pixels_cmt = NULL;
2037
2038    unsigned int cmts;
2039    int ErrorStatus;
2040    xpmHashTable hashtable;
2041
2042
2043    /* initialize return values */
2044    if (image_return)
2045	*image_return = NULL;
2046    if (shapeimage_return)
2047	*shapeimage_return = NULL;
2048
2049
2050    /* retrieve information from the XpmAttributes */
2051    if (attributes && (attributes->valuemask & XpmVisual))
2052	visual = attributes->visual;
2053    else
2054	visual = XDefaultVisual(display, XDefaultScreen(display));
2055
2056    if (attributes && (attributes->valuemask & XpmColormap))
2057	colormap = attributes->colormap;
2058    else
2059	colormap = XDefaultColormap(display, XDefaultScreen(display));
2060
2061    if (attributes && (attributes->valuemask & XpmDepth))
2062	depth = attributes->depth;
2063    else
2064	depth = XDefaultDepth(display, XDefaultScreen(display));
2065
2066    if (attributes && (attributes->valuemask & XpmBitmapFormat))
2067	bitmap_format = attributes->bitmap_format;
2068    else
2069	bitmap_format = ZPixmap;
2070
2071    if (attributes && (attributes->valuemask & XpmFreeColors))
2072	freeColors = attributes->free_colors;
2073    else
2074	freeColors = FreeColors;
2075
2076    cmts = info && (info->valuemask & XpmReturnComments);
2077
2078    /*
2079     * parse the header
2080     */
2081    ErrorStatus = xpmParseHeader(data);
2082    if (ErrorStatus != XpmSuccess)
2083	return (ErrorStatus);
2084
2085    /*
2086     * read values
2087     */
2088    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
2089				 &x_hotspot, &y_hotspot, &hotspot,
2090				 &extensions);
2091    if (ErrorStatus != XpmSuccess)
2092	return (ErrorStatus);
2093
2094    /*
2095     * store the hints comment line
2096     */
2097    if (cmts)
2098	xpmGetCmt(data, &hints_cmt);
2099
2100    /*
2101     * init the hashtable
2102     */
2103    if (USE_HASHTABLE) {
2104	ErrorStatus = xpmHashTableInit(&hashtable);
2105	if (ErrorStatus != XpmSuccess)
2106	    RETURN(ErrorStatus);
2107    }
2108
2109    /*
2110     * read colors
2111     */
2112    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
2113    if (ErrorStatus != XpmSuccess)
2114	RETURN(ErrorStatus);
2115
2116    /*
2117     * store the colors comment line
2118     */
2119    if (cmts)
2120	xpmGetCmt(data, &colors_cmt);
2121
2122    /* malloc pixels index tables */
2123    if (ncolors >= UINT_MAX / sizeof(Pixel))
2124	RETURN(XpmNoMemory);
2125
2126    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2127    if (!image_pixels)
2128	RETURN(XpmNoMemory);
2129
2130    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2131    if (!mask_pixels)
2132	RETURN(XpmNoMemory);
2133
2134    /* maximum of allocated pixels will be the number of colors */
2135    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2136    if (!alloc_pixels)
2137	RETURN(XpmNoMemory);
2138
2139    /* maximum of allocated pixels will be the number of colors */
2140    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2141    if (!used_pixels)
2142	RETURN(XpmNoMemory);
2143
2144    /* get pixel colors, store them in index tables */
2145    ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
2146			       image_pixels, mask_pixels, &mask_pixel_index,
2147			       alloc_pixels, &nalloc_pixels, used_pixels,
2148			       &nused_pixels);
2149
2150    if (ErrorStatus != XpmSuccess
2151	&& (ErrorStatus < 0 || (attributes
2152				&& (attributes->valuemask & XpmExactColors)
2153				&& attributes->exactColors)))
2154	RETURN(ErrorStatus);
2155
2156    /* now create the ximage */
2157    if (image_return) {
2158	ErrorStatus = CreateXImage(display, visual, depth,
2159				   (depth == 1 ? bitmap_format : ZPixmap),
2160				   width, height, &ximage);
2161	if (ErrorStatus != XpmSuccess)
2162	    RETURN(ErrorStatus);
2163
2164#if !defined(FOR_MSW) && !defined(AMIGA)
2165
2166	/*
2167	 * set the XImage pointer function, to be used with XPutPixel,
2168	 * to an internal optimized function
2169	 */
2170
2171	if (ximage->bits_per_pixel == 8)
2172	    ximage->f.put_pixel = PutPixel8;
2173	else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
2174		 (ximage->byte_order == ximage->bitmap_bit_order))
2175	    if (ximage->bitmap_bit_order == MSBFirst)
2176		ximage->f.put_pixel = PutPixel1MSB;
2177	    else
2178		ximage->f.put_pixel = PutPixel1LSB;
2179	else if (ximage->bits_per_pixel == 16)
2180	    if (ximage->bitmap_bit_order == MSBFirst)
2181		ximage->f.put_pixel = PutPixel16MSB;
2182	    else
2183		ximage->f.put_pixel = PutPixel16LSB;
2184	else if (ximage->bits_per_pixel == 32)
2185#if !defined(WORD64) && !defined(LONG64)
2186	    if (*((char *)&byteorderpixel) == ximage->byte_order)
2187		ximage->f.put_pixel = PutPixel32;
2188	    else
2189#endif
2190		if (ximage->bitmap_bit_order == MSBFirst)
2191		    ximage->f.put_pixel = PutPixel32MSB;
2192		else
2193		    ximage->f.put_pixel = PutPixel32LSB;
2194	else if ((ximage->bits_per_pixel | ximage->depth) == 1)
2195	    ximage->f.put_pixel = PutPixel1;
2196	else
2197	    ximage->f.put_pixel = PutPixel;
2198#endif /* not FOR_MSW && not AMIGA */
2199    }
2200
2201    /* create the shape mask image */
2202    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
2203	ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
2204				   width, height, &shapeimage);
2205	if (ErrorStatus != XpmSuccess)
2206	    RETURN(ErrorStatus);
2207
2208#if !defined(FOR_MSW) && !defined(AMIGA)
2209	if (shapeimage->bitmap_bit_order == MSBFirst)
2210	    shapeimage->f.put_pixel = PutPixel1MSB;
2211	else
2212	    shapeimage->f.put_pixel = PutPixel1LSB;
2213#endif
2214    }
2215
2216    /*
2217     * read pixels and put them in the XImage
2218     */
2219    ErrorStatus = ParseAndPutPixels(
2220#ifdef FOR_MSW
2221				    display,
2222#endif
2223				    data, width, height, ncolors, cpp,
2224				    colorTable, &hashtable,
2225				    ximage, image_pixels,
2226				    shapeimage, mask_pixels);
2227    XpmFree(image_pixels);
2228    image_pixels = NULL;
2229    XpmFree(mask_pixels);
2230    mask_pixels = NULL;
2231
2232    /*
2233     * free the hastable
2234     */
2235    if (ErrorStatus != XpmSuccess)
2236	RETURN(ErrorStatus);
2237    else if (USE_HASHTABLE)
2238	xpmHashTableFree(&hashtable);
2239
2240    /*
2241     * store the pixels comment line
2242     */
2243    if (cmts)
2244	xpmGetCmt(data, &pixels_cmt);
2245
2246    /*
2247     * parse extensions
2248     */
2249    if (info && (info->valuemask & XpmReturnExtensions)) {
2250	if (extensions) {
2251	    ErrorStatus = xpmParseExtensions(data, &info->extensions,
2252					     &info->nextensions);
2253	    if (ErrorStatus != XpmSuccess)
2254		RETURN(ErrorStatus);
2255	} else {
2256	    info->extensions = NULL;
2257	    info->nextensions = 0;
2258	}
2259    }
2260    /*
2261     * store found information in the XpmImage structure
2262     */
2263    image->width = width;
2264    image->height = height;
2265    image->cpp = cpp;
2266    image->ncolors = ncolors;
2267    image->colorTable = colorTable;
2268    image->data = NULL;
2269
2270    if (info) {
2271	if (cmts) {
2272	    info->hints_cmt = hints_cmt;
2273	    info->colors_cmt = colors_cmt;
2274	    info->pixels_cmt = pixels_cmt;
2275	}
2276	if (hotspot) {
2277	    info->x_hotspot = x_hotspot;
2278	    info->y_hotspot = y_hotspot;
2279	    info->valuemask |= XpmHotspot;
2280	}
2281    }
2282    /* if requested return used pixels in the XpmAttributes structure */
2283    if (attributes && (attributes->valuemask & XpmReturnPixels ||
2284/* 3.2 backward compatibility code */
2285	attributes->valuemask & XpmReturnInfos)) {
2286/* end 3.2 bc */
2287	attributes->pixels = used_pixels;
2288	attributes->npixels = nused_pixels;
2289	attributes->mask_pixel = mask_pixel_index;
2290    } else
2291	XpmFree(used_pixels);
2292
2293    /* if requested return alloc'ed pixels in the XpmAttributes structure */
2294    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
2295	attributes->alloc_pixels = alloc_pixels;
2296	attributes->nalloc_pixels = nalloc_pixels;
2297    } else
2298	XpmFree(alloc_pixels);
2299
2300    /* return created images */
2301    if (image_return)
2302	*image_return = ximage;
2303    if (shapeimage_return)
2304	*shapeimage_return = shapeimage;
2305
2306    return (XpmSuccess);
2307
2308/* exit point in case of error, free only locally allocated variables */
2309error:
2310    if (USE_HASHTABLE)
2311	xpmHashTableFree(&hashtable);
2312    if (colorTable)
2313	xpmFreeColorTable(colorTable, ncolors);
2314    if (hints_cmt)
2315	XpmFree(hints_cmt);
2316    if (colors_cmt)
2317	XpmFree(colors_cmt);
2318    if (pixels_cmt)
2319	XpmFree(pixels_cmt);
2320    if (ximage)
2321	XDestroyImage(ximage);
2322    if (shapeimage)
2323	XDestroyImage(shapeimage);
2324    if (image_pixels)
2325	XpmFree(image_pixels);
2326    if (mask_pixels)
2327	XpmFree(mask_pixels);
2328    if (nalloc_pixels)
2329	(*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
2330    if (alloc_pixels)
2331	XpmFree(alloc_pixels);
2332    if (used_pixels)
2333	XpmFree(used_pixels);
2334
2335    return (ErrorStatus);
2336}
2337
2338static int
2339ParseAndPutPixels(
2340#ifdef FOR_MSW
2341    Display		*dc,
2342#endif
2343    xpmData		*data,
2344    unsigned int	 width,
2345    unsigned int	 height,
2346    unsigned int	 ncolors,
2347    unsigned int	 cpp,
2348    XpmColor		*colorTable,
2349    xpmHashTable	*hashtable,
2350    XImage		*image,
2351    Pixel		*image_pixels,
2352    XImage		*shapeimage,
2353    Pixel		*shape_pixels)
2354{
2355    unsigned int a, x, y;
2356
2357    switch (cpp) {
2358
2359    case (1):				/* Optimize for single character
2360					 * colors */
2361	{
2362	    unsigned short colidx[256];
2363#ifdef FOR_MSW
2364	    HDC shapedc;
2365	    HBITMAP obm, sobm;
2366
2367	    if ( shapeimage ) {
2368		shapedc = CreateCompatibleDC(*dc);
2369		sobm = SelectObject(shapedc, shapeimage->bitmap);
2370	    } else {
2371	        shapedc = NULL;
2372	    }
2373	    obm = SelectObject(*dc, image->bitmap);
2374#endif
2375	    if (ncolors > 256)
2376		return (XpmFileInvalid);
2377
2378	    bzero((char *)colidx, 256 * sizeof(short));
2379	    for (a = 0; a < ncolors; a++)
2380		colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
2381
2382	    for (y = 0; y < height; y++) {
2383		xpmNextString(data);
2384		for (x = 0; x < width; x++) {
2385		    int c = xpmGetC(data);
2386
2387		    if (c > 0 && c < 256 && colidx[c] != 0) {
2388#ifndef FOR_MSW
2389			XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
2390			if (shapeimage)
2391			    XPutPixel(shapeimage, x, y,
2392				      shape_pixels[colidx[c] - 1]);
2393#else
2394			SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
2395			if (shapedc) {
2396			    SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
2397			}
2398#endif
2399		    } else
2400			return (XpmFileInvalid);
2401		}
2402	    }
2403#ifdef FOR_MSW
2404	    if ( shapedc ) {
2405	        SelectObject(shapedc, sobm);
2406		DeleteDC(shapedc);
2407	    }
2408	    SelectObject(*dc, obm);
2409#endif
2410	}
2411	break;
2412
2413    case (2):				/* Optimize for double character
2414					 * colors */
2415	{
2416
2417/* free all allocated pointers at all exits */
2418#define FREE_CIDX do {int f; for (f = 0; f < 256; f++) \
2419if (cidx[f]) XpmFree(cidx[f]);} while(0)
2420
2421	    /* array of pointers malloced by need */
2422	    unsigned short *cidx[256];
2423	    unsigned int char1;
2424
2425	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
2426	    for (a = 0; a < ncolors; a++) {
2427		char1 = (unsigned char) colorTable[a].string[0];
2428		if (cidx[char1] == NULL) { /* get new memory */
2429		    cidx[char1] = (unsigned short *)
2430			XpmCalloc(256, sizeof(unsigned short));
2431		    if (cidx[char1] == NULL) { /* new block failed */
2432			FREE_CIDX;
2433			return (XpmNoMemory);
2434		    }
2435		}
2436		cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
2437	    }
2438
2439	    for (y = 0; y < height; y++) {
2440		xpmNextString(data);
2441		for (x = 0; x < width; x++) {
2442		    int cc1 = xpmGetC(data);
2443		    if (cc1 > 0 && cc1 < 256) {
2444			int cc2 = xpmGetC(data);
2445			if (cc2 > 0 && cc2 < 256 &&
2446			    cidx[cc1] && cidx[cc1][cc2] != 0) {
2447#ifndef FOR_MSW
2448			    XPutPixel(image, x, y,
2449				      image_pixels[cidx[cc1][cc2] - 1]);
2450			    if (shapeimage)
2451				XPutPixel(shapeimage, x, y,
2452					  shape_pixels[cidx[cc1][cc2] - 1]);
2453#else
2454			SelectObject(*dc, image->bitmap);
2455			SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
2456			if (shapeimage) {
2457			    SelectObject(*dc, shapeimage->bitmap);
2458			    SetPixel(*dc, x, y,
2459				     shape_pixels[cidx[cc1][cc2] - 1]);
2460			}
2461#endif
2462			} else {
2463			    FREE_CIDX;
2464			    return (XpmFileInvalid);
2465			}
2466		    } else {
2467			FREE_CIDX;
2468			return (XpmFileInvalid);
2469		    }
2470		}
2471	    }
2472	    FREE_CIDX;
2473	}
2474	break;
2475
2476    default:				/* Non-optimized case of long color
2477					 * names */
2478	{
2479	    char *s;
2480	    char buf[BUFSIZ];
2481
2482	    if (cpp >= sizeof(buf))
2483		return (XpmFileInvalid);
2484
2485	    buf[cpp] = '\0';
2486	    if (USE_HASHTABLE) {
2487		xpmHashAtom *slot;
2488
2489		for (y = 0; y < height; y++) {
2490		    xpmNextString(data);
2491		    for (x = 0; x < width; x++) {
2492			for (a = 0, s = buf; a < cpp; a++, s++)
2493			    *s = xpmGetC(data);
2494			slot = xpmHashSlot(hashtable, buf);
2495			if (!*slot)	/* no color matches */
2496			    return (XpmFileInvalid);
2497#ifndef FOR_MSW
2498			XPutPixel(image, x, y,
2499				  image_pixels[HashColorIndex(slot)]);
2500			if (shapeimage)
2501			    XPutPixel(shapeimage, x, y,
2502				      shape_pixels[HashColorIndex(slot)]);
2503#else
2504			SelectObject(*dc, image->bitmap);
2505			SetPixel(*dc, x, y,
2506				 image_pixels[HashColorIndex(slot)]);
2507			if (shapeimage) {
2508			    SelectObject(*dc, shapeimage->bitmap);
2509			    SetPixel(*dc, x, y,
2510				     shape_pixels[HashColorIndex(slot)]);
2511			}
2512#endif
2513		    }
2514		}
2515	    } else {
2516		for (y = 0; y < height; y++) {
2517		    xpmNextString(data);
2518		    for (x = 0; x < width; x++) {
2519			for (a = 0, s = buf; a < cpp; a++, s++)
2520			    *s = xpmGetC(data);
2521			for (a = 0; a < ncolors; a++)
2522			    if (!strcmp(colorTable[a].string, buf))
2523				break;
2524			if (a == ncolors)	/* no color matches */
2525			    return (XpmFileInvalid);
2526#ifndef FOR_MSW
2527			XPutPixel(image, x, y, image_pixels[a]);
2528			if (shapeimage)
2529			    XPutPixel(shapeimage, x, y, shape_pixels[a]);
2530#else
2531			SelectObject(*dc, image->bitmap);
2532			SetPixel(*dc, x, y, image_pixels[a]);
2533			if (shapeimage) {
2534			    SelectObject(*dc, shapeimage->bitmap);
2535			    SetPixel(*dc, x, y, shape_pixels[a]);
2536			}
2537#endif
2538		    }
2539		}
2540	    }
2541	}
2542	break;
2543    }
2544    return (XpmSuccess);
2545}
2546