2  * Copyright (C) 1989-95 GROUPE BULL 
   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: 
  11  * The above copyright notice and this permission notice shall be included in 
  12  * all copies or substantial portions of the Software. 
  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. 
  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. 
  26 /*****************************************************************************\ 
  30 *  Create an X image and possibly its related shape mask                      * 
  31 *  from the given XpmImage.                                                   * 
  33 *  Developed by Arnaud Le Hors                                                * 
  34 \*****************************************************************************/ 
  37  * The code related to FOR_MSW has been added by 
  38  * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 
  42  * The code related to AMIGA has been added by 
  43  * Lorens Younes (d93-hyo@nada.kth.se) 4/96 
  49 LFUNC(xpmVisualType
, int, (Visual 
*visual
)); 
  51 LFUNC(AllocColor
, int, (Display 
*display
, Colormap colormap
, 
  52                         char *colorname
, XColor 
*xcolor
, void *closure
)); 
  53 LFUNC(FreeColors
, int, (Display 
*display
, Colormap colormap
, 
  54                         Pixel 
*pixels
, int n
, void *closure
)); 
  57 LFUNC(SetCloseColor
, int, (Display 
*display
, Colormap colormap
, 
  58                            Visual 
*visual
, XColor 
*col
, 
  59                            Pixel 
*image_pixel
, Pixel 
*mask_pixel
, 
  60                            Pixel 
*alloc_pixels
, unsigned int *nalloc_pixels
, 
  61                            XpmAttributes 
*attributes
, XColor 
*cols
, int ncols
, 
  62                            XpmAllocColorFunc allocColor
, void *closure
)); 
  64 /* let the window system take care of close colors */ 
  67 LFUNC(SetColor
, int, (Display 
*display
, Colormap colormap
, Visual 
*visual
, 
  68                       char *colorname
, unsigned int color_index
, 
  69                       Pixel 
*image_pixel
, Pixel 
*mask_pixel
, 
  70                       unsigned int *mask_pixel_index
, 
  71                       Pixel 
*alloc_pixels
, unsigned int *nalloc_pixels
, 
  72                       Pixel 
*used_pixels
, unsigned int *nused_pixels
, 
  73                       XpmAttributes 
*attributes
, XColor 
*cols
, int ncols
, 
  74                       XpmAllocColorFunc allocColor
, void *closure
)); 
  76 LFUNC(CreateXImage
, int, (Display 
*display
, Visual 
*visual
, 
  77                           unsigned int depth
, int format
, unsigned int width
, 
  78                           unsigned int height
, XImage 
**image_return
)); 
  80 LFUNC(CreateColors
, int, (Display 
*display
, XpmAttributes 
*attributes
, 
  81                           XpmColor 
*colors
, unsigned int ncolors
, 
  82                           Pixel 
*image_pixels
, Pixel 
*mask_pixels
, 
  83                           unsigned int *mask_pixel_index
, 
  84                           Pixel 
*alloc_pixels
, unsigned int *nalloc_pixels
, 
  85                           Pixel 
*used_pixels
, unsigned int *nused_pixels
)); 
  88 LFUNC(ParseAndPutPixels
, int, (xpmData 
*data
, unsigned int width
, 
  89                                unsigned int height
, unsigned int ncolors
, 
  90                                unsigned int cpp
, XpmColor 
*colorTable
, 
  91                                xpmHashTable 
*hashtable
, 
  92                                XImage 
*image
, Pixel 
*image_pixels
, 
  93                                XImage 
*mask
, Pixel 
*mask_pixels
)); 
  95 LFUNC(ParseAndPutPixels
, int, (Display 
*dc
, 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
)); 
 105 /* XImage pixel routines */ 
 106 LFUNC(PutImagePixels
, void, (XImage 
*image
, unsigned int width
, 
 107                              unsigned int height
, unsigned int *pixelindex
, 
 110 LFUNC(PutImagePixels32
, void, (XImage 
*image
, unsigned int width
, 
 111                                unsigned int height
, unsigned int *pixelindex
, 
 114 LFUNC(PutImagePixels16
, void, (XImage 
*image
, unsigned int width
, 
 115                                unsigned int height
, unsigned int *pixelindex
, 
 118 LFUNC(PutImagePixels8
, void, (XImage 
*image
, unsigned int width
, 
 119                               unsigned int height
, unsigned int *pixelindex
, 
 122 LFUNC(PutImagePixels1
, void, (XImage 
*image
, unsigned int width
, 
 123                               unsigned int height
, unsigned int *pixelindex
, 
 126 LFUNC(PutPixel1
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 127 LFUNC(PutPixel
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 128 LFUNC(PutPixel32
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 129 LFUNC(PutPixel32MSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 130 LFUNC(PutPixel32LSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 131 LFUNC(PutPixel16MSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 132 LFUNC(PutPixel16LSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 133 LFUNC(PutPixel8
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 134 LFUNC(PutPixel1MSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 135 LFUNC(PutPixel1LSB
, int, (XImage 
*ximage
, int x
, int y
, unsigned long pixel
)); 
 138 LFUNC(APutImagePixels
, void, (XImage 
*ximage
, unsigned int width
, 
 139                               unsigned int height
, unsigned int *pixelindex
, 
 143 /* FOR_MSW pixel routine */ 
 145 LFUNC(MSWPutImagePixels
, void, ( 
 150 , unsigned int  height
 
 151 , unsigned int* pixelindex
 
 155 LFUNC(MSWPutImagePixels
, void, (Display 
*dc
, XImage 
*image
, 
 156                                 unsigned int width
, unsigned int height
, 
 157                                 unsigned int *pixelindex
, Pixel 
*pixels
)); 
 161 #ifdef NEED_STRCASECMP 
 162 FUNC(xpmstrcasecmp
, int, (char *s1
, char *s2
)); 
 165  * in case strcasecmp is not provided by the system here is one 
 166  * which does the trick 
 169 /* Visual Age cannot deal with old, non-ansi, code */ 
 170 int xpmstrcasecmp(register char* s1
, register char* s2
) 
 173 xpmstrcasecmp(s1
, s2
) 
 174     register char *s1
, *s2
; 
 187     return (int) (*s1 
- *s2
); 
 193  * return the default color key related to the given visual 
 196 /* Visual Age cannot deal with old, non-ansi, code */ 
 197 static int xpmVisualType(Visual
* visual
) 
 200 xpmVisualType(visual
) 
 206     switch (visual
->class) { 
 209         switch (visual
->map_entries
) { 
 221     /* set the key explicitly in the XpmAttributes to override this */ 
 225     /* there should be a similar switch for MSW */ 
 237 /* Visual Age cannot deal with old, non-ansi, code */ 
 238 static int closeness_cmp(Const 
void* a
, Const 
void* b
) 
 245     CloseColor 
*x 
= (CloseColor 
*) a
, *y 
= (CloseColor 
*) b
; 
 247     /* cast to int as qsort requires */ 
 248     return (int) (x
->closeness 
- y
->closeness
); 
 252 /* default AllocColor function: 
 253  *   call XParseColor if colorname is given, return negative value if failure 
 254  *   call XAllocColor and return 0 if failure, positive otherwise 
 257 /* Visual Age cannot deal with old, non-ansi, code */ 
 268 AllocColor(display
, colormap
, colorname
, xcolor
, closure
) 
 273     void *closure
;              /* not used */ 
 279         if (!XParseColor(display
, &colormap
, colorname
, xcolor
)) 
 281     status 
= XAllocColor(display
, &colormap
, xcolor
); 
 283         if (!XParseColor(display
, colormap
, colorname
, xcolor
)) 
 285     status 
= XAllocColor(display
, colormap
, xcolor
); 
 287     return status 
!= 0 ? 1 : 0; 
 293  * set a close color in case the exact one can't be set 
 294  * return 0 if success, 1 otherwise. 
 298 SetCloseColor(display
, colormap
, visual
, col
, image_pixel
, mask_pixel
, 
 299               alloc_pixels
, nalloc_pixels
, attributes
, cols
, ncols
, 
 305     Pixel 
*image_pixel
, *mask_pixel
; 
 307     unsigned int *nalloc_pixels
; 
 308     XpmAttributes 
*attributes
; 
 311     XpmAllocColorFunc allocColor
; 
 316      * Allocation failed, so try close colors. To get here the visual must 
 317      * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor? 
 318      * What about sharing systems like QDSS?). Beware: we have to treat 
 319      * DirectColor differently. 
 323     long int red_closeness
, green_closeness
, blue_closeness
; 
 327     if (attributes 
&& (attributes
->valuemask 
& XpmCloseness
)) 
 328         red_closeness 
= green_closeness 
= blue_closeness 
= 
 329             attributes
->closeness
; 
 331         red_closeness 
= attributes
->red_closeness
; 
 332         green_closeness 
= attributes
->green_closeness
; 
 333         blue_closeness 
= attributes
->blue_closeness
; 
 335     if (attributes 
&& (attributes
->valuemask 
& XpmAllocCloseColors
)) 
 336         alloc_color 
= attributes
->alloc_close_colors
; 
 341      * We sort the colormap by closeness and try to allocate the color 
 342      * closest to the target. If the allocation of this close color fails, 
 343      * which almost never happens, then one of two scenarios is possible. 
 344      * Either the colormap must have changed (since the last close color 
 345      * allocation or possibly while we were sorting the colormap), or the 
 346      * color is allocated as Read/Write by some other client. (Note: X 
 347      * _should_ allow clients to check if a particular color is Read/Write, 
 348      * but it doesn't! :-( ). We cannot determine which of these scenarios 
 349      * occurred, so we try the next closest color, and so on, until no more 
 350      * colors are within closeness of the target. If we knew that the 
 351      * colormap had changed, we could skip this sequence. 
 353      * If _none_ of the colors within closeness of the target can be allocated, 
 354      * then we can finally be pretty sure that the colormap has actually 
 355      * changed. In this case we try to allocate the original color (again), 
 356      * then try the closecolor stuff (again)... 
 358      * In theory it would be possible for an infinite loop to occur if another 
 359      * process kept changing the colormap every time we sorted it, so we set 
 360      * a maximum on the number of iterations. After this many tries, we use 
 361      * XGrabServer() to ensure that the colormap remains unchanged. 
 363      * This approach gives particularly bad worst case performance - as many as 
 364      * <MaximumIterations> colormap reads and sorts may be needed, and as 
 365      * many as <MaximumIterations> * <ColormapSize> attempted allocations 
 366      * may fail. On an 8-bit system, this means as many as 3 colormap reads, 
 367      * 3 sorts and 768 failed allocations per execution of this code! 
 368      * Luckily, my experiments show that in general use in a typical 8-bit 
 369      * color environment only about 1 in every 10000 allocations fails to 
 370      * succeed in the fastest possible time. So virtually every time what 
 371      * actually happens is a single sort followed by a successful allocate. 
 372      * The very first allocation also costs a colormap read, but no further 
 373      * reads are usually necessary. 
 376 #define ITERATIONS 2                    /* more than one is almost never 
 379     for (n 
= 0; n 
<= ITERATIONS
; ++n
) { 
 380         CloseColor 
*closenesses 
= 
 381             (CloseColor 
*) XpmCalloc(ncols
, sizeof(CloseColor
)); 
 384         for (i 
= 0; i 
< ncols
; ++i
) {   /* build & sort closenesses table */ 
 385 #define COLOR_FACTOR       3 
 386 #define BRIGHTNESS_FACTOR  1 
 388             closenesses
[i
].cols_index 
= i
; 
 389             closenesses
[i
].closeness 
= 
 390                 COLOR_FACTOR 
* (abs((long) col
->red 
- (long) cols
[i
].red
) 
 391                                 + abs((long) col
->green 
- (long) cols
[i
].green
) 
 392                                 + abs((long) col
->blue 
- (long) cols
[i
].blue
)) 
 393                 + BRIGHTNESS_FACTOR 
* abs(((long) col
->red 
+ 
 396                                            - ((long) cols
[i
].red 
+ 
 397                                               (long) cols
[i
].green 
+ 
 398                                               (long) cols
[i
].blue
)); 
 400         qsort(closenesses
, ncols
, sizeof(CloseColor
), closeness_cmp
); 
 403         c 
= closenesses
[i
].cols_index
; 
 404         while ((long) cols
[c
].red 
>= (long) col
->red 
- red_closeness 
&& 
 405                (long) cols
[c
].red 
<= (long) col
->red 
+ red_closeness 
&& 
 406                (long) cols
[c
].green 
>= (long) col
->green 
- green_closeness 
&& 
 407                (long) cols
[c
].green 
<= (long) col
->green 
+ green_closeness 
&& 
 408                (long) cols
[c
].blue 
>= (long) col
->blue 
- blue_closeness 
&& 
 409                (long) cols
[c
].blue 
<= (long) col
->blue 
+ blue_closeness
) { 
 411                 if ((*allocColor
)(display
, colormap
, NULL
, &cols
[c
], closure
)){ 
 413                         XUngrabServer(display
); 
 414                     XpmFree(closenesses
); 
 415                     *image_pixel 
= cols
[c
].pixel
; 
 417                     alloc_pixels
[(*nalloc_pixels
)++] = cols
[c
].pixel
; 
 423                     c 
= closenesses
[i
].cols_index
; 
 427                     XUngrabServer(display
); 
 428                 XpmFree(closenesses
); 
 429                 *image_pixel 
= cols
[c
].pixel
; 
 435         /* Couldn't allocate _any_ of the close colors! */ 
 438             XUngrabServer(display
); 
 439         XpmFree(closenesses
); 
 441         if (i 
== 0 || i 
== ncols
)       /* no color close enough or cannot */ 
 442             return (1);                 /* alloc any color (full of r/w's) */ 
 444         if ((*allocColor
)(display
, colormap
, NULL
, col
, closure
)) { 
 445             *image_pixel 
= col
->pixel
; 
 447             alloc_pixels
[(*nalloc_pixels
)++] = col
->pixel
; 
 449         } else {                        /* colormap has probably changed, so 
 451             if (n 
== ITERATIONS 
- 1) 
 452                 XGrabServer(display
); 
 455             if (visual
->class == DirectColor
) { 
 459                 XQueryColors(display
, colormap
, cols
, ncols
); 
 465 #define USE_CLOSECOLOR attributes && \ 
 466 (((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \ 
 467  || ((attributes->valuemask & XpmRGBCloseness) && \ 
 468      (attributes->red_closeness != 0 \ 
 469       || attributes->green_closeness != 0 \ 
 470       || attributes->blue_closeness != 0))) 
 474     /* nothing to do here, the window system does it */ 
 478  * set the color pixel related to the given colorname, 
 479  * return 0 if success, 1 otherwise. 
 483 /* Visual Age cannot deal with old, non-ansi, code */ 
 490 , unsigned int      color_index
 
 493 , unsigned int*     mask_pixel_index
 
 494 , Pixel
*            alloc_pixels
 
 495 , unsigned int*     nalloc_pixels
 
 497 , unsigned int*     nused_pixels
 
 498 , XpmAttributes
*    attributes
 
 501 , XpmAllocColorFunc allocColor
 
 506 SetColor(display
, colormap
, visual
, colorname
, color_index
, 
 507          image_pixel
, mask_pixel
, mask_pixel_index
, 
 508          alloc_pixels
, nalloc_pixels
, used_pixels
, nused_pixels
, 
 509          attributes
, cols
, ncols
, allocColor
, closure
) 
 514     unsigned int color_index
; 
 515     Pixel 
*image_pixel
, *mask_pixel
; 
 516     unsigned int *mask_pixel_index
; 
 518     unsigned int *nalloc_pixels
; 
 520     unsigned int *nused_pixels
; 
 521     XpmAttributes 
*attributes
; 
 524     XpmAllocColorFunc allocColor
; 
 531     if (xpmstrcasecmp(colorname
, TRANSPARENT_COLOR
)) { 
 532         status 
= (*allocColor
)(display
, colormap
, colorname
, &xcolor
, closure
); 
 533         if (status 
< 0)         /* parse color failed */ 
 539                 return (SetCloseColor(display
, colormap
, visual
, &xcolor
, 
 540                                       image_pixel
, mask_pixel
, 
 541                                       alloc_pixels
, nalloc_pixels
, 
 542                                       attributes
, cols
, ncols
, 
 543                                       allocColor
, closure
)); 
 545 #endif /* ndef FOR_MSW */ 
 548             alloc_pixels
[(*nalloc_pixels
)++] = xcolor
.pixel
; 
 549         *image_pixel 
= xcolor
.pixel
; 
 554         *mask_pixel 
= OS2RGB(0,0,0); 
 556         *mask_pixel 
= RGB(0,0,0); 
 559         used_pixels
[(*nused_pixels
)++] = xcolor
.pixel
; 
 566     *mask_pixel 
= OS2RGB(255,255,255); 
 568     *mask_pixel 
= RGB(255,255,255); 
 571         /* store the color table index */ 
 572         *mask_pixel_index 
= color_index
; 
 578 /* Visual Age cannot deal with old, non-ansi, code */ 
 582 , XpmAttributes
*    attributes
 
 584 , unsigned int      ncolors
 
 585 , Pixel
*            image_pixels
 
 587 , unsigned int*     mask_pixel_index
 
 588 , Pixel
*            alloc_pixels
 
 589 , unsigned int*     nalloc_pixels
 
 591 , unsigned int*     nused_pixels
 
 595 CreateColors(display
, attributes
, colors
, ncolors
, image_pixels
, mask_pixels
, 
 596              mask_pixel_index
, alloc_pixels
, nalloc_pixels
, 
 597              used_pixels
, nused_pixels
) 
 599     XpmAttributes 
*attributes
; 
 601     unsigned int ncolors
; 
 604     unsigned int *mask_pixel_index
; 
 606     unsigned int *nalloc_pixels
; 
 608     unsigned int *nused_pixels
; 
 611     /* variables stored in the XpmAttributes structure */ 
 614     XpmColorSymbol 
*colorsymbols
; 
 615     unsigned int numsymbols
; 
 616     XpmAllocColorFunc allocColor
; 
 620     unsigned int color
, key
; 
 622     XpmColorSymbol 
*symbol
; 
 624     int ErrorStatus 
= XpmSuccess
; 
 629     unsigned int ncols 
= 0; 
 632      * retrieve information from the XpmAttributes 
 634     if (attributes 
&& attributes
->valuemask 
& XpmColorSymbols
) { 
 635         colorsymbols 
= attributes
->colorsymbols
; 
 636         numsymbols 
= attributes
->numsymbols
; 
 640     if (attributes 
&& attributes
->valuemask 
& XpmVisual
) 
 641         visual 
= attributes
->visual
; 
 643         visual 
= XDefaultVisual(display
, XDefaultScreen(display
)); 
 645     if (attributes 
&& (attributes
->valuemask 
& XpmColormap
)) 
 646         colormap 
= attributes
->colormap
; 
 648         colormap 
= XDefaultColormap(display
, XDefaultScreen(display
)); 
 650     if (attributes 
&& (attributes
->valuemask 
& XpmColorKey
)) 
 651         key 
= attributes
->color_key
; 
 653         key 
= xpmVisualType(visual
); 
 655     if (attributes 
&& (attributes
->valuemask 
& XpmAllocColor
)) 
 656         allocColor 
= attributes
->alloc_color
; 
 658         allocColor 
= AllocColor
; 
 659     if (attributes 
&& (attributes
->valuemask 
& XpmColorClosure
)) 
 660         closure 
= attributes
->color_closure
; 
 665     if (USE_CLOSECOLOR
) { 
 666         /* originally from SetCloseColor */ 
 668         if (visual
->class == DirectColor
) { 
 671              * TODO: Implement close colors for DirectColor visuals. This is 
 672              * difficult situation. Chances are that we will never get here, 
 673              * because any machine that supports DirectColor will probably 
 674              * also support TrueColor (and probably PseudoColor). Also, 
 675              * DirectColor colormaps can be very large, so looking for close 
 676              * colors may be too slow. 
 683             ncols 
= visual
->map_entries
; 
 685             ncols 
= colormap
->Count
; 
 687             cols 
= (XColor 
*) XpmCalloc(ncols
, sizeof(XColor
)); 
 688             for (i 
= 0; i 
< ncols
; ++i
) 
 690             XQueryColors(display
, colormap
, cols
, ncols
); 
 695 #endif /* ndef FOR_MSW */ 
 713     for (color 
= 0; color 
< ncolors
; color
++, colors
++, 
 714                                          image_pixels
++, mask_pixels
++) { 
 716         pixel_defined 
= False
; 
 717         defaults 
= (char **) colors
; 
 720          * look for a defined symbol 
 727             for (n 
= 0, symbol 
= colorsymbols
; n 
< numsymbols
; n
++, symbol
++) { 
 728                 if (symbol
->name 
&& s 
&& !strcmp(symbol
->name
, s
)) 
 731                 if (!symbol
->name 
&& symbol
->value
) {   /* override value */ 
 732                     int def_index 
= default_index
; 
 734                     while (defaults
[def_index
] == NULL
) /* find defined 
 737                     if (def_index 
< 2) {/* nothing towards mono, so try 
 739                         def_index 
= default_index 
+ 1; 
 740                         while (def_index 
<= 5 && defaults
[def_index
] == NULL
) 
 743                     if (def_index 
>= 2 && defaults
[def_index
] != NULL 
&& 
 744                         !xpmstrcasecmp(symbol
->value
, defaults
[def_index
])) 
 748             if (n 
!= numsymbols
) { 
 749                 if (symbol
->name 
&& symbol
->value
) 
 750                     colorname 
= symbol
->value
; 
 752                     pixel_defined 
= True
; 
 755         if (!pixel_defined
) {           /* pixel not given as symbol value */ 
 759             if (colorname
) {            /* colorname given as symbol value */ 
 760                 if (!SetColor(display
, colormap
, visual
, colorname
, color
, 
 761                               image_pixels
, mask_pixels
, mask_pixel_index
, 
 762                               alloc_pixels
, nalloc_pixels
, used_pixels
, 
 763                               nused_pixels
, attributes
, cols
, ncols
, 
 764                               allocColor
, closure
)) 
 765                     pixel_defined 
= True
; 
 767                     ErrorStatus 
= XpmColorError
; 
 770             while (!pixel_defined 
&& k 
> 1) { 
 772                     if (!SetColor(display
, colormap
, visual
, defaults
[k
], 
 773                                   color
, image_pixels
, mask_pixels
, 
 774                                   mask_pixel_index
, alloc_pixels
, 
 775                                   nalloc_pixels
, used_pixels
, nused_pixels
, 
 776                                   attributes
, cols
, ncols
, 
 777                                   allocColor
, closure
)) { 
 778                         pixel_defined 
= True
; 
 781                         ErrorStatus 
= XpmColorError
; 
 786             while (!pixel_defined 
&& k 
< NKEYS 
+ 1) { 
 788                     if (!SetColor(display
, colormap
, visual
, defaults
[k
], 
 789                                   color
, image_pixels
, mask_pixels
, 
 790                                   mask_pixel_index
, alloc_pixels
, 
 791                                   nalloc_pixels
, used_pixels
, nused_pixels
, 
 792                                   attributes
, cols
, ncols
, 
 793                                   allocColor
, closure
)) { 
 794                         pixel_defined 
= True
; 
 797                         ErrorStatus 
= XpmColorError
; 
 801             if (!pixel_defined
) { 
 804                 return (XpmColorFailed
); 
 807             /* simply use the given pixel */ 
 808             *image_pixels 
= symbol
->pixel
; 
 809             /* the following makes the mask to be built even if none 
 810                is given a particular pixel */ 
 812                 && !xpmstrcasecmp(symbol
->value
, TRANSPARENT_COLOR
)) { 
 814                 *mask_pixel_index 
= color
; 
 817             used_pixels
[(*nused_pixels
)++] = *image_pixels
; 
 822     return (ErrorStatus
); 
 826 /* default FreeColors function, simply call XFreeColors */ 
 828 /* Visual Age cannot deal with old, non-ansi, code */ 
 839 FreeColors(display
, colormap
, pixels
, n
, closure
) 
 844     void *closure
;              /* not used */ 
 847     return XFreeColors(display
, colormap
, pixels
, n
, 0); 
 851 /* function call in case of error */ 
 853 #define RETURN(status) \ 
 855       ErrorStatus = status; \ 
 860 /* Visual Age cannot deal with old, non-ansi, code */ 
 861 int XpmCreateImageFromXpmImage( 
 864 , XImage
**       image_return
 
 865 , XImage
**       shapeimage_return
 
 866 , XpmAttributes
* attributes
 
 870 XpmCreateImageFromXpmImage(display
, image
, 
 871                            image_return
, shapeimage_return
, attributes
) 
 874     XImage 
**image_return
; 
 875     XImage 
**shapeimage_return
; 
 876     XpmAttributes 
*attributes
; 
 884     /* variables stored in the XpmAttributes structure */ 
 889     XpmFreeColorsFunc freeColors
; 
 892     /* variables to return */ 
 893     XImage 
*ximage 
= NULL
; 
 894     XImage 
*shapeimage 
= NULL
; 
 895     unsigned int mask_pixel_index 
= XpmUndefPixel
; 
 898     /* calculation variables */ 
 899     Pixel 
*image_pixels 
= NULL
; 
 900     Pixel 
*mask_pixels 
= NULL
; 
 901     Pixel 
*alloc_pixels 
= NULL
; 
 902     Pixel 
*used_pixels 
= NULL
; 
 903     unsigned int nalloc_pixels 
= 0; 
 904     unsigned int nused_pixels 
= 0; 
 906     /* initialize return values */ 
 908         *image_return 
= NULL
; 
 909     if (shapeimage_return
) 
 910         *shapeimage_return 
= NULL
; 
 912     /* retrieve information from the XpmAttributes */ 
 913     if (attributes 
&& (attributes
->valuemask 
& XpmVisual
)) 
 914         visual 
= attributes
->visual
; 
 916         visual 
= XDefaultVisual(display
, XDefaultScreen(display
)); 
 918     if (attributes 
&& (attributes
->valuemask 
& XpmColormap
)) 
 919         colormap 
= attributes
->colormap
; 
 921         colormap 
= XDefaultColormap(display
, XDefaultScreen(display
)); 
 923     if (attributes 
&& (attributes
->valuemask 
& XpmDepth
)) 
 924         depth 
= attributes
->depth
; 
 926         depth 
= XDefaultDepth(display
, XDefaultScreen(display
)); 
 928     if (attributes 
&& (attributes
->valuemask 
& XpmBitmapFormat
)) 
 929         bitmap_format 
= attributes
->bitmap_format
; 
 931         bitmap_format 
= ZPixmap
; 
 933     if (attributes 
&& (attributes
->valuemask 
& XpmFreeColors
)) 
 934         freeColors 
= attributes
->free_colors
; 
 936         freeColors 
= FreeColors
; 
 937     if (attributes 
&& (attributes
->valuemask 
& XpmColorClosure
)) 
 938         closure 
= attributes
->color_closure
; 
 942     ErrorStatus 
= XpmSuccess
; 
 944     /* malloc pixels index tables */ 
 945     image_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
); 
 947         return (XpmNoMemory
); 
 949     mask_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
); 
 953     /* maximum of allocated pixels will be the number of colors */ 
 954     alloc_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
); 
 958     /* maximum of allocated pixels will be the number of colors */ 
 959     used_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
); 
 963     /* get pixel colors, store them in index tables */ 
 964     ErrorStatus 
= CreateColors(display
, attributes
, image
->colorTable
, 
 965                                image
->ncolors
, image_pixels
, mask_pixels
, 
 966                                &mask_pixel_index
, alloc_pixels
, &nalloc_pixels
, 
 967                                used_pixels
, &nused_pixels
); 
 969     if (ErrorStatus 
!= XpmSuccess
 
 970         && (ErrorStatus 
< 0 || (attributes
 
 971                                 && (attributes
->valuemask 
& XpmExactColors
) 
 972                                 && attributes
->exactColors
))) 
 975     /* create the ximage */ 
 977         ErrorStatus 
= CreateXImage(display
, visual
, depth
, 
 978                                    (depth 
== 1 ? bitmap_format 
: ZPixmap
), 
 979                                    image
->width
, image
->height
, &ximage
); 
 980         if (ErrorStatus 
!= XpmSuccess
) 
 987          * set the ximage data using optimized functions for ZPixmap 
 990         if (ximage
->bits_per_pixel 
== 8) 
 991             PutImagePixels8(ximage
, image
->width
, image
->height
, 
 992                             image
->data
, image_pixels
); 
 993         else if (((ximage
->bits_per_pixel 
| ximage
->depth
) == 1) && 
 994                  (ximage
->byte_order 
== ximage
->bitmap_bit_order
)) 
 995             PutImagePixels1(ximage
, image
->width
, image
->height
, 
 996                             image
->data
, image_pixels
); 
 997         else if (ximage
->bits_per_pixel 
== 16) 
 998             PutImagePixels16(ximage
, image
->width
, image
->height
, 
 999                              image
->data
, image_pixels
); 
1000         else if (ximage
->bits_per_pixel 
== 32) 
1001             PutImagePixels32(ximage
, image
->width
, image
->height
, 
1002                              image
->data
, image_pixels
); 
1004             PutImagePixels(ximage
, image
->width
, image
->height
, 
1005                            image
->data
, image_pixels
); 
1007         APutImagePixels(ximage
, image
->width
, image
->height
, 
1008                         image
->data
, image_pixels
); 
1012  hps 
= GpiCreatePS(hab
, *display
, &sizl
, GPIA_ASSOC
|PU_PELS
); 
1013         MSWPutImagePixels(hps
, display
, ximage
, image
->width
, image
->height
, 
1014                           image
->data
, image_pixels
); 
1016         MSWPutImagePixels(display
, ximage
, image
->width
, image
->height
, 
1017                           image
->data
, image_pixels
); 
1021     /* create the shape mask image */ 
1022     if (mask_pixel_index 
!= XpmUndefPixel 
&& shapeimage_return
) { 
1023         ErrorStatus 
= CreateXImage(display
, visual
, 1, bitmap_format
, 
1024                                    image
->width
, image
->height
, &shapeimage
); 
1025         if (ErrorStatus 
!= XpmSuccess
) 
1026             RETURN(ErrorStatus
); 
1030         PutImagePixels1(shapeimage
, image
->width
, image
->height
, 
1031                         image
->data
, mask_pixels
); 
1033         APutImagePixels(shapeimage
, image
->width
, image
->height
, 
1034                         image
->data
, mask_pixels
); 
1038  hps 
= GpiCreatePS(hab
, *display
, &sizl
, GPIA_ASSOC
|PU_PELS
); 
1039         MSWPutImagePixels(hps
, display
, shapeimage
, image
->width
, image
->height
, 
1040                           image
->data
, mask_pixels
); 
1042         MSWPutImagePixels(display
, shapeimage
, image
->width
, image
->height
, 
1043                           image
->data
, mask_pixels
); 
1048     XpmFree(image_pixels
); 
1049     XpmFree(mask_pixels
); 
1051     /* if requested return used pixels in the XpmAttributes structure */ 
1052     if (attributes 
&& (attributes
->valuemask 
& XpmReturnPixels 
|| 
1053 /* 3.2 backward compatibility code */ 
1054         attributes
->valuemask 
& XpmReturnInfos
)) { 
1056         attributes
->pixels 
= used_pixels
; 
1057         attributes
->npixels 
= nused_pixels
; 
1058         attributes
->mask_pixel 
= mask_pixel_index
; 
1060         XpmFree(used_pixels
); 
1062     /* if requested return alloc'ed pixels in the XpmAttributes structure */ 
1063     if (attributes 
&& (attributes
->valuemask 
& XpmReturnAllocPixels
)) { 
1064         attributes
->alloc_pixels 
= alloc_pixels
; 
1065         attributes
->nalloc_pixels 
= nalloc_pixels
; 
1067         XpmFree(alloc_pixels
); 
1069     /* return created images */ 
1071         *image_return 
= ximage
; 
1072     if (shapeimage_return
) 
1073         *shapeimage_return 
= shapeimage
; 
1075     return (ErrorStatus
); 
1077 /* exit point in case of error, free only locally allocated variables */ 
1080         XDestroyImage(ximage
); 
1082         XDestroyImage(shapeimage
); 
1084         XpmFree(image_pixels
); 
1086         XpmFree(mask_pixels
); 
1088         (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
); 
1090         XpmFree(alloc_pixels
); 
1092         XpmFree(used_pixels
); 
1094     return (ErrorStatus
); 
1099  * Create an XImage with its data 
1102 /* Visual Age cannot deal with old, non-ansi, code */ 
1103 static int CreateXImage( 
1106 , unsigned int  depth
 
1108 , unsigned int  width
 
1109 , unsigned int  height
 
1110 , XImage
**      image_return
 
1114 CreateXImage(display
, visual
, depth
, format
, width
, height
, image_return
) 
1120     unsigned int height
; 
1121     XImage 
**image_return
; 
1126     /* first get bitmap_pad */ 
1134     /* then create the XImage with data = NULL and bytes_per_line = 0 */ 
1135     *image_return 
= XCreateImage(display
, visual
, depth
, format
, 0, 0, 
1136                                  width
, height
, bitmap_pad
, 0); 
1138         return (XpmNoMemory
); 
1140 #if !defined(FOR_MSW) && !defined(AMIGA) 
1141     /* now that bytes_per_line must have been set properly alloc data */ 
1142     (*image_return
)->data 
= 
1143         (char *) XpmMalloc((*image_return
)->bytes_per_line 
* height
); 
1145     if (!(*image_return
)->data
) { 
1146         XDestroyImage(*image_return
); 
1147         *image_return 
= NULL
; 
1148         return (XpmNoMemory
); 
1151     /* under FOR_MSW and AMIGA XCreateImage has done it all */ 
1153     return (XpmSuccess
); 
1159  * The functions below are written from X11R5 MIT's code (XImUtil.c) 
1161  * The idea is to have faster functions than the standard XPutPixel function 
1162  * to build the image data. Indeed we can speed up things by suppressing tests 
1163  * performed for each pixel. We do the same tests but at the image level. 
1164  * We also assume that we use only ZPixmap images with null offsets. 
1167 LFUNC(_putbits
, void, (register char *src
, int dstoffset
, 
1168                        register int numbits
, register char *dst
)); 
1170 LFUNC(_XReverse_Bytes
, int, (register unsigned char *bpt
, register int nb
)); 
1172 static unsigned char Const _reverse_byte
[0x100] = { 
1173     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
1174     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
1175     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
1176     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
1177     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
1178     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
1179     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
1180     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
1181     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
1182     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
1183     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
1184     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
1185     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
1186     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
1187     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
1188     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
1189     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
1190     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
1191     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
1192     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
1193     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
1194     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
1195     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
1196     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
1197     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
1198     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
1199     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
1200     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
1201     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
1202     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
1203     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
1204     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 
1208 /* Visual Age cannot deal with old, non-ansi, code */ 
1210 _XReverse_Bytes(register unsigned char* bpt
, register int nb
) 
1213 _XReverse_Bytes(bpt
, nb
) 
1214     register unsigned char *bpt
; 
1219         *bpt 
= _reverse_byte
[*bpt
]; 
1227 /* Visual Age cannot deal with old, non-ansi, code */ 
1228 void xpm_xynormalizeimagebits(register unsigned char* bp
, register XImage
* img
) 
1231 xpm_xynormalizeimagebits(bp
, img
) 
1232     register unsigned char *bp
; 
1233     register XImage 
*img
; 
1236     register unsigned char c
; 
1238     if (img
->byte_order 
!= img
->bitmap_bit_order
) { 
1239         switch (img
->bitmap_unit
) { 
1252             *(bp 
+ 2) = *(bp 
+ 1); 
1257     if (img
->bitmap_bit_order 
== MSBFirst
) 
1258         _XReverse_Bytes(bp
, img
->bitmap_unit 
>> 3); 
1262 /* Visual Age cannot deal with old, non-ansi, code */ 
1263 void xpm_znormalizeimagebits(register unsigned char* bp
, register XImage
* img
) 
1266 xpm_znormalizeimagebits(bp
, img
) 
1267     register unsigned char *bp
; 
1268     register XImage 
*img
; 
1271     register unsigned char c
; 
1273     switch (img
->bits_per_pixel
) { 
1276         _XReverse_Bytes(bp
, 1); 
1280         *bp 
= ((*bp 
>> 4) & 0xF) | ((*bp 
<< 4) & ~0xF); 
1300         *(bp 
+ 2) = *(bp 
+ 1); 
1306 static unsigned char Const _lomask
[0x09] = { 
1307 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 
1308 static unsigned char Const _himask
[0x09] = { 
1309 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; 
1312 /* Visual Age cannot deal with old, non-ansi, code */ 
1313 static void _putbits( 
1316 , register int   numbits
 
1317 , register char* dst
 
1321 _putbits(src
, dstoffset
, numbits
, dst
) 
1322     register char *src
;                 /* address of source bit string */ 
1323     int dstoffset
;                      /* bit offset into destination; 
1325     register int numbits
;               /* number of bits to copy to 
1327     register char *dst
;                 /* address of destination bit string */ 
1330     register unsigned char chlo
, chhi
; 
1333     dst 
= dst 
+ (dstoffset 
>> 3); 
1334     dstoffset 
= dstoffset 
& 7; 
1335     hibits 
= 8 - dstoffset
; 
1336     chlo 
= *dst 
& _lomask
[dstoffset
]; 
1338         chhi 
= (*src 
<< dstoffset
) & _himask
[dstoffset
]; 
1339         if (numbits 
<= hibits
) { 
1340             chhi 
= chhi 
& _lomask
[dstoffset 
+ numbits
]; 
1341             *dst 
= (*dst 
& _himask
[dstoffset 
+ numbits
]) | chlo 
| chhi
; 
1346         numbits 
= numbits 
- hibits
; 
1347         chlo 
= (unsigned char) (*src 
& _himask
[hibits
]) >> hibits
; 
1349         if (numbits 
<= dstoffset
) { 
1350             chlo 
= chlo 
& _lomask
[numbits
]; 
1351             *dst 
= (*dst 
& _himask
[numbits
]) | chlo
; 
1354         numbits 
= numbits 
- dstoffset
; 
1359  * Default method to write pixels into a Z image data structure. 
1360  * The algorithm used is: 
1362  *      copy the destination bitmap_unit or Zpixel to temp 
1363  *      normalize temp if needed 
1364  *      copy the pixel bits into the temp 
1365  *      renormalize temp if needed 
1366  *      copy the temp back into the destination image data 
1370 /* Visual Age cannot deal with old, non-ansi, code */ 
1371 static void PutImagePixels( 
1373 , unsigned int  width
 
1374 , unsigned int  height
 
1375 , unsigned int* pixelindex
 
1380 PutImagePixels(image
, width
, height
, pixelindex
, pixels
) 
1383     unsigned int height
; 
1384     unsigned int *pixelindex
; 
1390     register unsigned int *iptr
; 
1391     register int x
, y
, i
; 
1392     register char *data
; 
1394     int nbytes
, depth
, ibu
, ibpp
; 
1398     depth 
= image
->depth
; 
1400         ibu 
= image
->bitmap_unit
; 
1401         for (y 
= 0; y 
< height
; y
++) 
1402             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1403                 pixel 
= pixels
[*iptr
]; 
1404                 for (i 
= 0, px 
= pixel
; i 
< sizeof(unsigned long); 
1406                     ((unsigned char *) &pixel
)[i
] = px
; 
1407                 src 
= &data
[XYINDEX(x
, y
, image
)]; 
1411                 for (i 
= nbytes
; --i 
>= 0;) 
1413                 XYNORMALIZE(&px
, image
); 
1414                 _putbits((char *) &pixel
, (x 
% ibu
), 1, (char *) &px
); 
1415                 XYNORMALIZE(&px
, image
); 
1417                 dst 
= &data
[XYINDEX(x
, y
, image
)]; 
1418                 for (i 
= nbytes
; --i 
>= 0;) 
1422         ibpp 
= image
->bits_per_pixel
; 
1423         for (y 
= 0; y 
< height
; y
++) 
1424             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1425                 pixel 
= pixels
[*iptr
]; 
1428                 for (i 
= 0, px 
= pixel
; i 
< sizeof(unsigned long); i
++, 
1430                     ((unsigned char *) &pixel
)[i
] = px
; 
1431                 src 
= &data
[ZINDEX(x
, y
, image
)]; 
1434                 nbytes 
= (ibpp 
+ 7) >> 3; 
1435                 for (i 
= nbytes
; --i 
>= 0;) 
1437                 ZNORMALIZE(&px
, image
); 
1438                 _putbits((char *) &pixel
, (x 
* ibpp
) & 7, ibpp
, (char *) &px
); 
1439                 ZNORMALIZE(&px
, image
); 
1441                 dst 
= &data
[ZINDEX(x
, y
, image
)]; 
1442                 for (i 
= nbytes
; --i 
>= 0;) 
1449  * write pixels into a 32-bits Z image data structure 
1452 #if !defined(WORD64) && !defined(LONG64) 
1453 /* this item is static but deterministic so let it slide; doesn't 
1454  * hurt re-entrancy of this library. Note if it is actually const then would 
1455  * be OK under rules of ANSI-C but probably not C++ which may not 
1456  * want to allocate space for it. 
1458 static unsigned long byteorderpixel 
= MSBFirst 
<< 24; 
1463    WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original 
1464    3.2e code - by default you get the speeded-up version. 
1468 /* Visual Age cannot deal with old, non-ansi, code */ 
1472 , unsigned int  width
 
1473 , unsigned int  height
 
1474 , unsigned int* pixelindex
 
1479 PutImagePixels32(image
, width
, height
, pixelindex
, pixels
) 
1482     unsigned int height
; 
1483     unsigned int *pixelindex
; 
1487     unsigned char *data
; 
1492 #ifdef WITHOUT_SPEEDUPS 
1495     unsigned char *addr
; 
1497     data 
= (unsigned char *) image
->data
; 
1499 #if !defined(WORD64) && !defined(LONG64) 
1500     if (*((char *) &byteorderpixel
) == image
->byte_order
) { 
1501         for (y 
= 0; y 
< height
; y
++) 
1502             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1503                 addr 
= &data
[ZINDEX32(x
, y
, image
)]; 
1504                 *((unsigned long *) addr
) = pixels
[*iptr
]; 
1508     if (image
->byte_order 
== MSBFirst
) 
1509         for (y 
= 0; y 
< height
; y
++) 
1510             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1511                 addr 
= &data
[ZINDEX32(x
, y
, image
)]; 
1512                 pixel 
= pixels
[*iptr
]; 
1513                 addr
[0] = pixel 
>> 24; 
1514                 addr
[1] = pixel 
>> 16; 
1515                 addr
[2] = pixel 
>> 8; 
1519         for (y 
= 0; y 
< height
; y
++) 
1520             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1521                 addr 
= &data
[ZINDEX32(x
, y
, image
)]; 
1522                 pixel 
= pixels
[*iptr
]; 
1524                 addr
[1] = pixel 
>> 8; 
1525                 addr
[2] = pixel 
>> 16; 
1526                 addr
[3] = pixel 
>> 24; 
1529 #else  /* WITHOUT_SPEEDUPS */ 
1531     int bpl 
= image
->bytes_per_line
; 
1532     unsigned char *data_ptr
, *max_data
; 
1534     data 
= (unsigned char *) image
->data
; 
1536 #if !defined(WORD64) && !defined(LONG64) 
1537     if (*((char *) &byteorderpixel
) == image
->byte_order
) { 
1538         for (y 
= 0; y 
< height
; y
++) { 
1540             max_data 
= data_ptr 
+ (width 
<< 2); 
1542             while (data_ptr 
< max_data
) { 
1543                 *((unsigned long *) data_ptr
) = pixels
[*(iptr
++)]; 
1544                 data_ptr 
+= (1 << 2); 
1550     if (image
->byte_order 
== MSBFirst
) 
1551         for (y 
= 0; y 
< height
; y
++) { 
1553             max_data 
= data_ptr 
+ (width 
<< 2); 
1555             while (data_ptr 
< max_data
) { 
1556                 pixel 
= pixels
[*(iptr
++)]; 
1558                 *data_ptr
++ = pixel 
>> 24; 
1559                 *data_ptr
++ = pixel 
>> 16; 
1560                 *data_ptr
++ = pixel 
>> 8; 
1561                 *data_ptr
++ = pixel
; 
1567         for (y 
= 0; y 
< height
; y
++) { 
1569             max_data 
= data_ptr 
+ (width 
<< 2); 
1571             while (data_ptr 
< max_data
) { 
1572                 pixel 
= pixels
[*(iptr
++)]; 
1574                 *data_ptr
++ = pixel
; 
1575                 *data_ptr
++ = pixel 
>> 8; 
1576                 *data_ptr
++ = pixel 
>> 16; 
1577                 *data_ptr
++ = pixel 
>> 24; 
1582 #endif /* WITHOUT_SPEEDUPS */ 
1586  * write pixels into a 16-bits Z image data structure 
1590 /* Visual Age cannot deal with old, non-ansi, code */ 
1591 static void PutImagePixels16( 
1593 , unsigned int  width
 
1594 , unsigned int  height
 
1595 , unsigned int* pixelindex
 
1600 PutImagePixels16(image
, width
, height
, pixelindex
, pixels
) 
1603     unsigned int height
; 
1604     unsigned int *pixelindex
; 
1608     unsigned char *data
; 
1612 #ifdef WITHOUT_SPEEDUPS 
1615     unsigned char *addr
; 
1617     data 
= (unsigned char *) image
->data
; 
1619     if (image
->byte_order 
== MSBFirst
) 
1620         for (y 
= 0; y 
< height
; y
++) 
1621             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1622                 addr 
= &data
[ZINDEX16(x
, y
, image
)]; 
1623                 addr
[0] = pixels
[*iptr
] >> 8; 
1624                 addr
[1] = pixels
[*iptr
]; 
1627         for (y 
= 0; y 
< height
; y
++) 
1628             for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1629                 addr 
= &data
[ZINDEX16(x
, y
, image
)]; 
1630                 addr
[0] = pixels
[*iptr
]; 
1631                 addr
[1] = pixels
[*iptr
] >> 8; 
1634 #else  /* WITHOUT_SPEEDUPS */ 
1638     int bpl 
= image
->bytes_per_line
; 
1639     unsigned char *data_ptr
, *max_data
; 
1641     data 
= (unsigned char *) image
->data
; 
1643     if (image
->byte_order 
== MSBFirst
) 
1644         for (y 
= 0; y 
< height
; y
++) { 
1646             max_data 
= data_ptr 
+ (width 
<< 1); 
1648             while (data_ptr 
< max_data
) { 
1649                 pixel 
= pixels
[*(iptr
++)]; 
1651                 data_ptr
[0] = pixel 
>> 8; 
1652                 data_ptr
[1] = pixel
; 
1654                 data_ptr 
+= (1 << 1); 
1659         for (y 
= 0; y 
< height
; y
++) { 
1661             max_data 
= data_ptr 
+ (width 
<< 1); 
1663             while (data_ptr 
< max_data
) { 
1664                 pixel 
= pixels
[*(iptr
++)]; 
1666                 data_ptr
[0] = pixel
; 
1667                 data_ptr
[1] = pixel 
>> 8; 
1669                 data_ptr 
+= (1 << 1); 
1674 #endif /* WITHOUT_SPEEDUPS */ 
1678  * write pixels into a 8-bits Z image data structure 
1682 /* Visual Age cannot deal with old, non-ansi, code */ 
1683 static void PutImagePixels8( 
1685 , unsigned int  width
 
1686 , unsigned int  height
 
1687 , unsigned int* pixelindex
 
1692 PutImagePixels8(image
, width
, height
, pixelindex
, pixels
) 
1695     unsigned int height
; 
1696     unsigned int *pixelindex
; 
1704 #ifdef WITHOUT_SPEEDUPS 
1710     for (y 
= 0; y 
< height
; y
++) 
1711         for (x 
= 0; x 
< width
; x
++, iptr
++) 
1712             data
[ZINDEX8(x
, y
, image
)] = pixels
[*iptr
]; 
1714 #else  /* WITHOUT_SPEEDUPS */ 
1716     int bpl 
= image
->bytes_per_line
; 
1717     char *data_ptr
, *max_data
; 
1722     for (y 
= 0; y 
< height
; y
++) { 
1724         max_data 
= data_ptr 
+ width
; 
1726         while (data_ptr 
< max_data
) 
1727             *(data_ptr
++) = pixels
[*(iptr
++)]; 
1732 #endif /* WITHOUT_SPEEDUPS */ 
1736  * write pixels into a 1-bit depth image data structure and **offset null** 
1740 /* Visual Age cannot deal with old, non-ansi, code */ 
1741 static void PutImagePixels1( 
1743 , unsigned int  width
 
1744 , unsigned int  height
 
1745 , unsigned int* pixelindex
 
1750 PutImagePixels1(image
, width
, height
, pixelindex
, pixels
) 
1753     unsigned int height
; 
1754     unsigned int *pixelindex
; 
1758     if (image
->byte_order 
!= image
->bitmap_bit_order
) 
1759         PutImagePixels(image
, width
, height
, pixelindex
, pixels
); 
1765 #ifdef WITHOUT_SPEEDUPS 
1771         if (image
->bitmap_bit_order 
== MSBFirst
) 
1772             for (y 
= 0; y 
< height
; y
++) 
1773                 for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1774                     if (pixels
[*iptr
] & 1) 
1775                         data
[ZINDEX1(x
, y
, image
)] |= 0x80 >> (x 
& 7); 
1777                         data
[ZINDEX1(x
, y
, image
)] &= ~(0x80 >> (x 
& 7)); 
1780             for (y 
= 0; y 
< height
; y
++) 
1781                 for (x 
= 0; x 
< width
; x
++, iptr
++) { 
1782                     if (pixels
[*iptr
] & 1) 
1783                         data
[ZINDEX1(x
, y
, image
)] |= 1 << (x 
& 7); 
1785                         data
[ZINDEX1(x
, y
, image
)] &= ~(1 << (x 
& 7)); 
1788 #else  /* WITHOUT_SPEEDUPS */ 
1791         char *data_ptr
, *max_data
; 
1792         int bpl 
= image
->bytes_per_line
; 
1801         if (image
->bitmap_bit_order 
== MSBFirst
) 
1802             for (y 
= 0; y 
< height
; y
++) { 
1804                 max_data 
= data_ptr 
+ width
; 
1805                 while (data_ptr 
< max_data
) { 
1808                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1809                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1810                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1811                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1812                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1813                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1814                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1815                     value 
= (value 
<< 1) | (pixels
[*(iptr
++)] & 1); 
1817                     *(data_ptr
++) = value
; 
1821                     for (count 
= 0; count 
< diff
; count
++) { 
1822                         if (pixels
[*(iptr
++)] & 1) 
1823                             value 
|= (0x80 >> count
); 
1825                     *(data_ptr
) = value
; 
1830             for (y 
= 0; y 
< height
; y
++) { 
1832                 max_data 
= data_ptr 
+ width
; 
1833                 while (data_ptr 
< max_data
) { 
1837                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1838                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1839                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1840                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1841                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1842                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1843                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1844                     value 
= (value 
<< 1) | (pixels
[*(--iptr
)] & 1); 
1847                     *(data_ptr
++) = value
; 
1851                     for (count 
= 0; count 
< diff
; count
++) { 
1852                         if (pixels
[*(iptr
++)] & 1) 
1853                             value 
|= (1 << count
); 
1855                     *(data_ptr
) = value
; 
1860 #endif /* WITHOUT_SPEEDUPS */ 
1865 /* Visual Age cannot deal with old, non-ansi, code */ 
1866 int XpmCreatePixmapFromXpmImage( 
1870 , Pixmap
*        pixmap_return
 
1871 , Pixmap
*        shapemask_return
 
1872 , XpmAttributes
* attributes
 
1875 XpmCreatePixmapFromXpmImage(display
, d
, image
, 
1876                             pixmap_return
, shapemask_return
, attributes
) 
1880     Pixmap 
*pixmap_return
; 
1881     Pixmap 
*shapemask_return
; 
1882     XpmAttributes 
*attributes
; 
1885     XImage 
*ximage
, *shapeimage
; 
1888     /* initialize return values */ 
1891     if (shapemask_return
) 
1892         *shapemask_return 
= 0; 
1894     /* create the ximages */ 
1895     ErrorStatus 
= XpmCreateImageFromXpmImage(display
, image
, 
1896                                              (pixmap_return 
? &ximage 
: NULL
), 
1898                                               &shapeimage 
: NULL
), 
1900     if (ErrorStatus 
< 0) 
1901         return (ErrorStatus
); 
1903     /* create the pixmaps and destroy images */ 
1904     if (pixmap_return 
&& ximage
) { 
1905         xpmCreatePixmapFromImage(display
, d
, ximage
, pixmap_return
); 
1906         XDestroyImage(ximage
); 
1908     if (shapemask_return 
&& shapeimage
) { 
1909         xpmCreatePixmapFromImage(display
, d
, shapeimage
, shapemask_return
); 
1910         XDestroyImage(shapeimage
); 
1912     return (ErrorStatus
); 
1921     unsigned int   height
, 
1922     unsigned int  *pixelindex
, 
1925     unsigned int   *data 
= pixelindex
; 
1927     unsigned char  *array
; 
1929     BOOL            success 
= FALSE
; 
1931     array 
= XpmMalloc ((((width
+15)>>4)<<4)*sizeof (*array
)); 
1934         tmp_img 
= AllocXImage ((((width
+15)>>4)<<4), 1, 
1935                                image
->rp
->BitMap
->Depth
); 
1936         if (tmp_img 
!= NULL
) 
1938             for (y 
= 0; y 
< height
; ++y
) 
1940                 for (x 
= 0; x 
< width
; ++x
) 
1941                     array
[x
] = pixels
[*(data
++)]; 
1942                 WritePixelLine8 (image
->rp
, 0, y
, width
, array
, tmp_img
->rp
); 
1944             FreeXImage (tmp_img
); 
1952         for (y 
= 0; y 
< height
; ++y
) 
1953             for (x 
= 0; x 
< width
; ++x
) 
1954                 XPutPixel (image
, x
, y
, pixels
[*(data
++)]); 
1959 #else  /* FOR_MSW part follows */ 
1962 /* Visual Age cannot deal with old, non-ansi, code */ 
1963 static void MSWPutImagePixels( 
1967 , unsigned int  width
 
1968 , unsigned int  height
 
1969 , unsigned int* pixelindex
 
1974 MSWPutImagePixels(dc
, image
, width
, height
, pixelindex
, pixels
) 
1978     unsigned int height
; 
1979     unsigned int *pixelindex
; 
1983     unsigned int *data 
= pixelindex
; 
1990     obm 
= GpiSetBitmap(hps
, image
->bitmap
); 
1992     obm 
= SelectObject(*dc
, image
->bitmap
); 
1995     for (y 
= 0; y 
< height
; y
++) { 
1996         for (x 
= 0; x 
< width
; x
++) { 
2000      GpiSetColor(hps
, (LONG
)pixels
[*(data
++)]); 
2001      GpiSetPel(hps
, &point
); 
2004             SetPixel(*dc
, x
, y
, pixels
[*(data
++)]); /* data is [x+y*width] */ 
2009     GpiSetBitmap(hps
, obm
); 
2011     SelectObject(*dc
, obm
); 
2015 #endif /* FOR_MSW */ 
2019 #if !defined(FOR_MSW) && !defined(AMIGA) 
2022 PutPixel1(ximage
, x
, y
, pixel
) 
2023     register XImage 
*ximage
; 
2026     unsigned long pixel
; 
2031     register char *data
; 
2035     for (i
=0, px
=pixel
; i
<sizeof(unsigned long); i
++, px
>>=8) 
2036         ((unsigned char *)&pixel
)[i
] = px
; 
2037     src 
= &ximage
->data
[XYINDEX(x
, y
, ximage
)]; 
2040     nbytes 
= ximage
->bitmap_unit 
>> 3; 
2041     for (i 
= nbytes
; --i 
>= 0; ) *dst
++ = *src
++; 
2042     XYNORMALIZE(&px
, ximage
); 
2043     i 
= ((x 
+ ximage
->xoffset
) % ximage
->bitmap_unit
); 
2044     _putbits ((char *)&pixel
, i
, 1, (char *)&px
); 
2045     XYNORMALIZE(&px
, ximage
); 
2047     dst 
= &ximage
->data
[XYINDEX(x
, y
, ximage
)]; 
2048     for (i 
= nbytes
; --i 
>= 0; ) 
2055 PutPixel(ximage
, x
, y
, pixel
) 
2056     register XImage 
*ximage
; 
2059     unsigned long pixel
; 
2064     register char *data
; 
2068     ibpp 
= ximage
->bits_per_pixel
; 
2069     if (ximage
->depth 
== 4) 
2071     for (i 
= 0, px 
= pixel
; i 
< sizeof(unsigned long); i
++, px 
>>= 8) 
2072         ((unsigned char *) &pixel
)[i
] = px
; 
2073     src 
= &ximage
->data
[ZINDEX(x
, y
, ximage
)]; 
2076     nbytes 
= (ibpp 
+ 7) >> 3; 
2077     for (i 
= nbytes
; --i 
>= 0;) 
2079     ZNORMALIZE(&px
, ximage
); 
2080     _putbits((char *) &pixel
, (x 
* ibpp
) & 7, ibpp
, (char *) &px
); 
2081     ZNORMALIZE(&px
, ximage
); 
2083     dst 
= &ximage
->data
[ZINDEX(x
, y
, ximage
)]; 
2084     for (i 
= nbytes
; --i 
>= 0;) 
2091 PutPixel32(ximage
, x
, y
, pixel
) 
2092     register XImage 
*ximage
; 
2095     unsigned long pixel
; 
2097     unsigned char *addr
; 
2099     addr 
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)]; 
2100     *((unsigned long *)addr
) = pixel
; 
2105 PutPixel32MSB(ximage
, x
, y
, pixel
) 
2106     register XImage 
*ximage
; 
2109     unsigned long pixel
; 
2111     unsigned char *addr
; 
2113     addr 
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)]; 
2114     addr
[0] = pixel 
>> 24; 
2115     addr
[1] = pixel 
>> 16; 
2116     addr
[2] = pixel 
>> 8; 
2122 PutPixel32LSB(ximage
, x
, y
, pixel
) 
2123     register XImage 
*ximage
; 
2126     unsigned long pixel
; 
2128     unsigned char *addr
; 
2130     addr 
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)]; 
2131     addr
[3] = pixel 
>> 24; 
2132     addr
[2] = pixel 
>> 16; 
2133     addr
[1] = pixel 
>> 8; 
2139 PutPixel16MSB(ximage
, x
, y
, pixel
) 
2140     register XImage 
*ximage
; 
2143     unsigned long pixel
; 
2145     unsigned char *addr
; 
2147     addr 
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)]; 
2148     addr
[0] = pixel 
>> 8; 
2154 PutPixel16LSB(ximage
, x
, y
, pixel
) 
2155     register XImage 
*ximage
; 
2158     unsigned long pixel
; 
2160     unsigned char *addr
; 
2162     addr 
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)]; 
2163     addr
[1] = pixel 
>> 8; 
2169 PutPixel8(ximage
, x
, y
, pixel
) 
2170     register XImage 
*ximage
; 
2173     unsigned long pixel
; 
2175     ximage
->data
[ZINDEX8(x
, y
, ximage
)] = pixel
; 
2180 PutPixel1MSB(ximage
, x
, y
, pixel
) 
2181     register XImage 
*ximage
; 
2184     unsigned long pixel
; 
2187         ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 0x80 >> (x 
& 7); 
2189         ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(0x80 >> (x 
& 7)); 
2194 PutPixel1LSB(ximage
, x
, y
, pixel
) 
2195     register XImage 
*ximage
; 
2198     unsigned long pixel
; 
2201         ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 1 << (x 
& 7); 
2203         ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(1 << (x 
& 7)); 
2207 #endif /* not FOR_MSW && not AMIGA */ 
2210  * This function parses an Xpm file or data and directly create an XImage 
2213 /* Visual Age cannot deal with old, non-ansi, code */ 
2214 int xpmParseDataAndCreate( 
2217 , XImage
**       image_return
 
2218 , XImage
**       shapeimage_return
 
2221 , XpmAttributes
* attributes
 
2225 xpmParseDataAndCreate(display
, data
, image_return
, shapeimage_return
, 
2226                       image
, info
, attributes
) 
2229     XImage 
**image_return
; 
2230     XImage 
**shapeimage_return
; 
2233     XpmAttributes 
*attributes
; 
2236     /* variables stored in the XpmAttributes structure */ 
2241     XpmFreeColorsFunc freeColors
; 
2244     /* variables to return */ 
2245     XImage 
*ximage 
= NULL
; 
2246     XImage 
*shapeimage 
= NULL
; 
2247     unsigned int mask_pixel_index 
= XpmUndefPixel
; 
2249     /* calculation variables */ 
2250     Pixel 
*image_pixels 
= NULL
; 
2251     Pixel 
*mask_pixels 
= NULL
; 
2252     Pixel 
*alloc_pixels 
= NULL
; 
2253     Pixel 
*used_pixels 
= NULL
; 
2254     unsigned int nalloc_pixels 
= 0; 
2255     unsigned int nused_pixels 
= 0; 
2256     unsigned int width
, height
, ncolors
, cpp
; 
2257     unsigned int x_hotspot
, y_hotspot
, hotspot 
= 0, extensions 
= 0; 
2258     XpmColor 
*colorTable 
= NULL
; 
2259     char *hints_cmt 
= NULL
; 
2260     char *colors_cmt 
= NULL
; 
2261     char *pixels_cmt 
= NULL
; 
2265     xpmHashTable hashtable
; 
2268     /* initialize return values */ 
2270         *image_return 
= NULL
; 
2271     if (shapeimage_return
) 
2272         *shapeimage_return 
= NULL
; 
2275     /* retrieve information from the XpmAttributes */ 
2276     if (attributes 
&& (attributes
->valuemask 
& XpmVisual
)) 
2277         visual 
= attributes
->visual
; 
2279         visual 
= XDefaultVisual(display
, XDefaultScreen(display
)); 
2281     if (attributes 
&& (attributes
->valuemask 
& XpmColormap
)) 
2282         colormap 
= attributes
->colormap
; 
2284         colormap 
= XDefaultColormap(display
, XDefaultScreen(display
)); 
2286     if (attributes 
&& (attributes
->valuemask 
& XpmDepth
)) 
2287         depth 
= attributes
->depth
; 
2289         depth 
= XDefaultDepth(display
, XDefaultScreen(display
)); 
2291     if (attributes 
&& (attributes
->valuemask 
& XpmBitmapFormat
)) 
2292         bitmap_format 
= attributes
->bitmap_format
; 
2294         bitmap_format 
= ZPixmap
; 
2296     if (attributes 
&& (attributes
->valuemask 
& XpmFreeColors
)) 
2297         freeColors 
= attributes
->free_colors
; 
2299         freeColors 
= FreeColors
; 
2300     if (attributes 
&& (attributes
->valuemask 
& XpmColorClosure
)) 
2301         closure 
= attributes
->color_closure
; 
2305     cmts 
= info 
&& (info
->valuemask 
& XpmReturnComments
); 
2310     ErrorStatus 
= xpmParseHeader(data
); 
2311     if (ErrorStatus 
!= XpmSuccess
) 
2312         return (ErrorStatus
); 
2317     ErrorStatus 
= xpmParseValues(data
, &width
, &height
, &ncolors
, &cpp
, 
2318                                  &x_hotspot
, &y_hotspot
, &hotspot
, 
2320     if (ErrorStatus 
!= XpmSuccess
) 
2321         return (ErrorStatus
); 
2324      * store the hints comment line 
2327         xpmGetCmt(data
, &hints_cmt
); 
2332     if (USE_HASHTABLE
) { 
2333         ErrorStatus 
= xpmHashTableInit(&hashtable
); 
2334         if (ErrorStatus 
!= XpmSuccess
) 
2335             return (ErrorStatus
); 
2341     ErrorStatus 
= xpmParseColors(data
, ncolors
, cpp
, &colorTable
, &hashtable
); 
2342     if (ErrorStatus 
!= XpmSuccess
) 
2343         RETURN(ErrorStatus
); 
2346      * store the colors comment line 
2349         xpmGetCmt(data
, &colors_cmt
); 
2351     /* malloc pixels index tables */ 
2352     image_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * ncolors
); 
2354         RETURN(XpmNoMemory
); 
2356     mask_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * ncolors
); 
2358         RETURN(XpmNoMemory
); 
2360     /* maximum of allocated pixels will be the number of colors */ 
2361     alloc_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * ncolors
); 
2363         RETURN(XpmNoMemory
); 
2365     /* maximum of allocated pixels will be the number of colors */ 
2366     used_pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * ncolors
); 
2368         RETURN(XpmNoMemory
); 
2370     /* get pixel colors, store them in index tables */ 
2371     ErrorStatus 
= CreateColors(display
, attributes
, colorTable
, ncolors
, 
2372                                image_pixels
, mask_pixels
, &mask_pixel_index
, 
2373                                alloc_pixels
, &nalloc_pixels
, used_pixels
, 
2376     if (ErrorStatus 
!= XpmSuccess
 
2377         && (ErrorStatus 
< 0 || (attributes
 
2378                                 && (attributes
->valuemask 
& XpmExactColors
) 
2379                                 && attributes
->exactColors
))) 
2380         RETURN(ErrorStatus
); 
2382     /* now create the ximage */ 
2384         ErrorStatus 
= CreateXImage(display
, visual
, depth
, 
2385                                    (depth 
== 1 ? bitmap_format 
: ZPixmap
), 
2386                                    width
, height
, &ximage
); 
2387         if (ErrorStatus 
!= XpmSuccess
) 
2388             RETURN(ErrorStatus
); 
2390 #if !defined(FOR_MSW) && !defined(AMIGA) 
2393          * set the XImage pointer function, to be used with XPutPixel, 
2394          * to an internal optimized function 
2397         if (ximage
->bits_per_pixel 
== 8) 
2398             ximage
->f
.put_pixel 
= PutPixel8
; 
2399         else if (((ximage
->bits_per_pixel 
| ximage
->depth
) == 1) && 
2400                  (ximage
->byte_order 
== ximage
->bitmap_bit_order
)) 
2401             if (ximage
->bitmap_bit_order 
== MSBFirst
) 
2402                 ximage
->f
.put_pixel 
= PutPixel1MSB
; 
2404                 ximage
->f
.put_pixel 
= PutPixel1LSB
; 
2405         else if (ximage
->bits_per_pixel 
== 16) 
2406             if (ximage
->bitmap_bit_order 
== MSBFirst
) 
2407                 ximage
->f
.put_pixel 
= PutPixel16MSB
; 
2409                 ximage
->f
.put_pixel 
= PutPixel16LSB
; 
2410         else if (ximage
->bits_per_pixel 
== 32) 
2411 #if !defined(WORD64) && !defined(LONG64) 
2412             if (*((char *)&byteorderpixel
) == ximage
->byte_order
) 
2413                 ximage
->f
.put_pixel 
= PutPixel32
; 
2416                 if (ximage
->bitmap_bit_order 
== MSBFirst
) 
2417                     ximage
->f
.put_pixel 
= PutPixel32MSB
; 
2419                     ximage
->f
.put_pixel 
= PutPixel32LSB
; 
2420         else if ((ximage
->bits_per_pixel 
| ximage
->depth
) == 1) 
2421             ximage
->f
.put_pixel 
= PutPixel1
; 
2423             ximage
->f
.put_pixel 
= PutPixel
; 
2424 #endif /* not FOR_MSW && not AMIGA */ 
2427     /* create the shape mask image */ 
2428     if (mask_pixel_index 
!= XpmUndefPixel 
&& shapeimage_return
) { 
2429         ErrorStatus 
= CreateXImage(display
, visual
, 1, bitmap_format
, 
2430                                    width
, height
, &shapeimage
); 
2431         if (ErrorStatus 
!= XpmSuccess
) 
2432             RETURN(ErrorStatus
); 
2434 #if !defined(FOR_MSW) && !defined(AMIGA) 
2435         if (shapeimage
->bitmap_bit_order 
== MSBFirst
) 
2436             shapeimage
->f
.put_pixel 
= PutPixel1MSB
; 
2438             shapeimage
->f
.put_pixel 
= PutPixel1LSB
; 
2443      * read pixels and put them in the XImage 
2445     ErrorStatus 
= ParseAndPutPixels( 
2449                                     data
, width
, height
, ncolors
, cpp
, 
2450                                     colorTable
, &hashtable
, 
2451                                     ximage
, image_pixels
, 
2452                                     shapeimage
, mask_pixels
); 
2453     XpmFree(image_pixels
); 
2454     image_pixels 
= NULL
; 
2455     XpmFree(mask_pixels
); 
2461     if (ErrorStatus 
!= XpmSuccess
) 
2463     else if (USE_HASHTABLE
) 
2464         xpmHashTableFree(&hashtable
); 
2467      * store the pixels comment line 
2470         xpmGetCmt(data
, &pixels_cmt
); 
2475     if (info 
&& (info
->valuemask 
& XpmReturnExtensions
)) 
2477             ErrorStatus 
= xpmParseExtensions(data
, &info
->extensions
, 
2478                                              &info
->nextensions
); 
2479             if (ErrorStatus 
!= XpmSuccess
) 
2480                 RETURN(ErrorStatus
); 
2482             info
->extensions 
= NULL
; 
2483             info
->nextensions 
= 0; 
2487      * store found informations in the XpmImage structure 
2489     image
->width 
= width
; 
2490     image
->height 
= height
; 
2492     image
->ncolors 
= ncolors
; 
2493     image
->colorTable 
= colorTable
; 
2498             info
->hints_cmt 
= hints_cmt
; 
2499             info
->colors_cmt 
= colors_cmt
; 
2500             info
->pixels_cmt 
= pixels_cmt
; 
2503             info
->x_hotspot 
= x_hotspot
; 
2504             info
->y_hotspot 
= y_hotspot
; 
2505             info
->valuemask 
|= XpmHotspot
; 
2508     /* if requested return used pixels in the XpmAttributes structure */ 
2509     if (attributes 
&& (attributes
->valuemask 
& XpmReturnPixels 
|| 
2510 /* 3.2 backward compatibility code */ 
2511         attributes
->valuemask 
& XpmReturnInfos
)) { 
2513         attributes
->pixels 
= used_pixels
; 
2514         attributes
->npixels 
= nused_pixels
; 
2515         attributes
->mask_pixel 
= mask_pixel_index
; 
2517         XpmFree(used_pixels
); 
2519     /* if requested return alloc'ed pixels in the XpmAttributes structure */ 
2520     if (attributes 
&& (attributes
->valuemask 
& XpmReturnAllocPixels
)) { 
2521         attributes
->alloc_pixels 
= alloc_pixels
; 
2522         attributes
->nalloc_pixels 
= nalloc_pixels
; 
2524         XpmFree(alloc_pixels
); 
2526     /* return created images */ 
2528         *image_return 
= ximage
; 
2529     if (shapeimage_return
) 
2530         *shapeimage_return 
= shapeimage
; 
2532     return (XpmSuccess
); 
2534 /* exit point in case of error, free only locally allocated variables */ 
2537         xpmHashTableFree(&hashtable
); 
2539         xpmFreeColorTable(colorTable
, ncolors
); 
2543         XpmFree(colors_cmt
); 
2545         XpmFree(pixels_cmt
); 
2547         XDestroyImage(ximage
); 
2549         XDestroyImage(shapeimage
); 
2551         XpmFree(image_pixels
); 
2553         XpmFree(mask_pixels
); 
2555         (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
); 
2557         XpmFree(alloc_pixels
); 
2559         XpmFree(used_pixels
); 
2561     return (ErrorStatus
); 
2565 /* Visual Age cannot deal with old, non-ansi, code */ 
2566 static int ParseAndPutPixels( 
2569 , unsigned int  width
 
2570 , unsigned int  height
 
2571 , unsigned int  ncolors
 
2573 , XpmColor
*     colorTable
 
2574 , xpmHashTable
* hashtable
 
2576 , Pixel
*        image_pixels
 
2577 , XImage
*       shapeimage
 
2578 , Pixel
*        shape_pixels
 
2586                   data
, width
, height
, ncolors
, cpp
, colorTable
, hashtable
, 
2587                   image
, image_pixels
, shapeimage
, shape_pixels
) 
2593     unsigned int height
; 
2594     unsigned int ncolors
; 
2596     XpmColor 
*colorTable
; 
2597     xpmHashTable 
*hashtable
; 
2599     Pixel 
*image_pixels
; 
2601     Pixel 
*shape_pixels
; 
2604     unsigned int a
, x
, y
; 
2608      DEVOPENSTRUC dop 
= {NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}; 
2609      SIZEL        sizl 
= {0, 0}; 
2615     case (1):                           /* Optimize for single character 
2618             unsigned short colidx
[256]; 
2625       shapedc 
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
); 
2626       hps 
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC 
| PU_PELS
); 
2627       sobm 
= GpiSetBitmap(hps
, shapeimage
->bitmap
); 
2629                 shapedc 
= CreateCompatibleDC(*dc
); 
2630                 sobm 
= SelectObject(shapedc
, shapeimage
->bitmap
); 
2636      obm 
= GpiSetBitmap(hps
, image
->bitmap
); 
2638             obm 
= SelectObject(*dc
, image
->bitmap
); 
2644             bzero((char *)colidx
, 256 * sizeof(short)); 
2645             for (a 
= 0; a 
< ncolors
; a
++) 
2646                 colidx
[(unsigned char)colorTable
[a
].string
[0]] = a 
+ 1; 
2648             for (y 
= 0; y 
< height
; y
++) { 
2649                 xpmNextString(data
); 
2650                 for (x 
= 0; x 
< width
; x
++) { 
2651                     int c 
= xpmGetC(data
); 
2653                     if (c 
> 0 && c 
< 256 && colidx
[c
] != 0) { 
2655                         XPutPixel(image
, x
, y
, image_pixels
[colidx
[c
] - 1]); 
2657                             XPutPixel(shapeimage
, x
, y
, 
2658                                       shape_pixels
[colidx
[c
] - 1]); 
2663      GpiSetColor(hps
, (LONG
)image_pixels
[colidx
[c
] - 1]); 
2664      GpiSetPel(hps
, &point
); 
2666                         SetPixel(*dc
, x
, y
, image_pixels
[colidx
[c
] - 1]); 
2672      GpiSetColor(hps
, (LONG
)shape_pixels
[colidx
[c
] - 1]); 
2673      GpiSetPel(hps
, &point
); 
2675                             SetPixel(shapedc
, x
, y
, shape_pixels
[colidx
[c
] - 1]); 
2680                         return (XpmFileInvalid
); 
2686          GpiSetBitmap(hps
, sobm
); 
2687          DevCloseDC(shapedc
); 
2689                 SelectObject(shapedc
, sobm
); 
2694      GpiSetBitmap(hps
, obm
); 
2696             SelectObject(*dc
, obm
); 
2702     case (2):                           /* Optimize for double character 
2705 /* free all allocated pointers at all exits */ 
2706 #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ 
2707 if (cidx[f]) XpmFree(cidx[f]);} 
2709             /* array of pointers malloced by need */ 
2710             unsigned short *cidx
[256]; 
2713             bzero((char *)cidx
, 256 * sizeof(unsigned short *)); /* init */ 
2714             for (a 
= 0; a 
< ncolors
; a
++) { 
2715                 char1 
= colorTable
[a
].string
[0]; 
2716                 if (cidx
[char1
] == NULL
) { /* get new memory */ 
2717                     cidx
[char1
] = (unsigned short *) 
2718                         XpmCalloc(256, sizeof(unsigned short)); 
2719                     if (cidx
[char1
] == NULL
) { /* new block failed */ 
2721                         return (XpmNoMemory
); 
2724                 cidx
[char1
][(unsigned char)colorTable
[a
].string
[1]] = a 
+ 1; 
2727             for (y 
= 0; y 
< height
; y
++) { 
2728                 xpmNextString(data
); 
2729                 for (x 
= 0; x 
< width
; x
++) { 
2730                     int cc1 
= xpmGetC(data
); 
2731                     if (cc1 
> 0 && cc1 
< 256) { 
2732                         int cc2 
= xpmGetC(data
); 
2733                         if (cc2 
> 0 && cc2 
< 256 && 
2734                             cidx
[cc1
] && cidx
[cc1
][cc2
] != 0) { 
2736                             XPutPixel(image
, x
, y
, 
2737                                       image_pixels
[cidx
[cc1
][cc2
] - 1]); 
2739                                 XPutPixel(shapeimage
, x
, y
, 
2740                                           shape_pixels
[cidx
[cc1
][cc2
] - 1]); 
2743      *dc 
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
); 
2744      hps 
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC 
| PU_PELS
); 
2746      GpiSetBitmap(hps
, image
->bitmap
); 
2749      GpiSetColor(hps
, (LONG
)image_pixels
[cidx
[cc1
][cc2
] - 1]); 
2750      GpiSetPel(hps
, &point
); 
2752                         SelectObject(*dc
, image
->bitmap
); 
2753                         SetPixel(*dc
, x
, y
, image_pixels
[cidx
[cc1
][cc2
] - 1]); 
2757      GpiSetBitmap(hps
, shapeimage
->bitmap
); 
2760      GpiSetColor(hps
, (LONG
)shape_pixels
[cidx
[cc1
][cc2
] - 1]); 
2761      GpiSetPel(hps
, &point
); 
2763                             SelectObject(*dc
, shapeimage
->bitmap
); 
2765                                      shape_pixels
[cidx
[cc1
][cc2
] - 1]); 
2771                             return (XpmFileInvalid
); 
2775                         return (XpmFileInvalid
); 
2783     default:                            /* Non-optimized case of long color 
2790             if (USE_HASHTABLE
) { 
2793                 for (y 
= 0; y 
< height
; y
++) { 
2794                     xpmNextString(data
); 
2795                     for (x 
= 0; x 
< width
; x
++) { 
2796                         for (a 
= 0, s 
= buf
; a 
< cpp
; a
++, s
++) 
2798                         slot 
= xpmHashSlot(hashtable
, buf
); 
2799                         if (!*slot
)     /* no color matches */ 
2800                             return (XpmFileInvalid
); 
2802                         XPutPixel(image
, x
, y
, 
2803                                   image_pixels
[HashColorIndex(slot
)]); 
2805                             XPutPixel(shapeimage
, x
, y
, 
2806                                       shape_pixels
[HashColorIndex(slot
)]); 
2809      *dc 
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
); 
2810      hps 
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC 
| PU_PELS
); 
2812      GpiSetBitmap(hps
, image
->bitmap
); 
2815      GpiSetColor(hps
, (LONG
)image_pixels
[HashColorIndex(slot
)]); 
2816      GpiSetPel(hps
, &point
); 
2818                         SelectObject(*dc
, image
->bitmap
); 
2820                                  image_pixels
[HashColorIndex(slot
)]); 
2824      GpiSetBitmap(hps
, shapeimage
->bitmap
); 
2827      GpiSetColor(hps
, (LONG
)shape_pixels
[HashColorIndex(slot
)]); 
2828      GpiSetPel(hps
, &point
); 
2830                             SelectObject(*dc
, shapeimage
->bitmap
); 
2832                                      shape_pixels
[HashColorIndex(slot
)]); 
2839                 for (y 
= 0; y 
< height
; y
++) { 
2840                     xpmNextString(data
); 
2841                     for (x 
= 0; x 
< width
; x
++) { 
2842                         for (a 
= 0, s 
= buf
; a 
< cpp
; a
++, s
++) 
2844                         for (a 
= 0; a 
< ncolors
; a
++) 
2845                             if (!strcmp(colorTable
[a
].string
, buf
)) 
2847                         if (a 
== ncolors
)       /* no color matches */ 
2848                             return (XpmFileInvalid
); 
2850                         XPutPixel(image
, x
, y
, image_pixels
[a
]); 
2852                             XPutPixel(shapeimage
, x
, y
, shape_pixels
[a
]); 
2855      *dc 
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
); 
2856      hps 
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC 
| PU_PELS
); 
2858      GpiSetBitmap(hps
, image
->bitmap
); 
2861      GpiSetColor(hps
, (LONG
)image_pixels
[a
]); 
2862      GpiSetPel(hps
, &point
); 
2864                         SelectObject(*dc
, image
->bitmap
); 
2865                         SetPixel(*dc
, x
, y
, image_pixels
[a
]); 
2869      GpiSetBitmap(hps
, image
->bitmap
); 
2872      GpiSetColor(hps
, (LONG
)shape_pixels
[a
]); 
2873      GpiSetPel(hps
, &point
); 
2875                             SelectObject(*dc
, shapeimage
->bitmap
); 
2876                             SetPixel(*dc
, x
, y
, shape_pixels
[a
]); 
2886     return (XpmSuccess
);