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