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