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