]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/create.c
Hashtable now supports negative keys
[wxWidgets.git] / src / xpm / create.c
CommitLineData
cfbe03c9 1/*
e6ed776f 2 * Copyright (C) 1989-95 GROUPE BULL
cfbe03c9
JS
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 *
e6ed776f 31* from the given XpmImage. *
cfbe03c9
JS
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
e6ed776f
GRG
41/*
42 * The code related to AMIGA has been added by
43 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
44 */
45
46#include "XpmI.h"
cfbe03c9 47#include <ctype.h>
cfbe03c9
JS
48
49LFUNC(xpmVisualType, int, (Visual *visual));
50
e6ed776f
GRG
51LFUNC(AllocColor, int, (Display *display, Colormap colormap,
52 char *colorname, XColor *xcolor, void *closure));
53LFUNC(FreeColors, int, (Display *display, Colormap colormap,
54 Pixel *pixels, int n, void *closure));
55
cfbe03c9
JS
56#ifndef FOR_MSW
57LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
58 Visual *visual, XColor *col,
59 Pixel *image_pixel, Pixel *mask_pixel,
e6ed776f
GRG
60 Pixel *alloc_pixels, unsigned int *nalloc_pixels,
61 XpmAttributes *attributes, XColor *cols, int ncols,
62 XpmAllocColorFunc allocColor, void *closure));
cfbe03c9
JS
63#else
64/* let the window system take care of close colors */
65#endif
66
67LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
68 char *colorname, unsigned int color_index,
69 Pixel *image_pixel, Pixel *mask_pixel,
e6ed776f
GRG
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));
cfbe03c9
JS
75
76LFUNC(CreateXImage, int, (Display *display, Visual *visual,
e6ed776f
GRG
77 unsigned int depth, int format, unsigned int width,
78 unsigned int height, XImage **image_return));
cfbe03c9
JS
79
80LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
e6ed776f
GRG
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));
86
87#ifndef FOR_MSW
88LFUNC(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));
94#else /* FOR_MSW */
95LFUNC(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));
101#endif
cfbe03c9
JS
102
103#ifndef FOR_MSW
e6ed776f 104# ifndef AMIGA
cfbe03c9 105/* XImage pixel routines */
e6ed776f 106LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
cfbe03c9
JS
107 unsigned int height, unsigned int *pixelindex,
108 Pixel *pixels));
109
e6ed776f 110LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
cfbe03c9
JS
111 unsigned int height, unsigned int *pixelindex,
112 Pixel *pixels));
113
e6ed776f 114LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
cfbe03c9
JS
115 unsigned int height, unsigned int *pixelindex,
116 Pixel *pixels));
117
e6ed776f 118LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
cfbe03c9
JS
119 unsigned int height, unsigned int *pixelindex,
120 Pixel *pixels));
121
e6ed776f 122LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
cfbe03c9
JS
123 unsigned int height, unsigned int *pixelindex,
124 Pixel *pixels));
e6ed776f
GRG
125
126LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel));
127LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel));
128LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
129LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
130LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
131LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
132LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
133LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel));
134LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
135LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
136
137# else /* AMIGA */
138LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width,
139 unsigned int height, unsigned int *pixelindex,
140 Pixel *pixels));
141# endif/* AMIGA */
142#else /* FOR_MSW */
cfbe03c9 143/* FOR_MSW pixel routine */
ea258ad3
DW
144#ifdef __OS2__
145LFUNC(MSWPutImagePixels, void, (
146 HPS hps
147, Display* dc
148, XImage* image
149, unsigned int width
150, unsigned int height
151, unsigned int* pixelindex
152, Pixel* pixels
153));
154#else
e6ed776f 155LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,
cfbe03c9
JS
156 unsigned int width, unsigned int height,
157 unsigned int *pixelindex, Pixel *pixels));
ea258ad3 158#endif
e6ed776f 159#endif /* FOR_MSW */
cfbe03c9
JS
160
161#ifdef NEED_STRCASECMP
e6ed776f 162FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
cfbe03c9
JS
163
164/*
165 * in case strcasecmp is not provided by the system here is one
166 * which does the trick
167 */
ea258ad3
DW
168#ifdef __OS2__
169/* Visual Age cannot deal with old, non-ansi, code */
170int xpmstrcasecmp(register char* s1, register char* s2)
171#else
cfbe03c9 172int
e6ed776f
GRG
173xpmstrcasecmp(s1, s2)
174 register char *s1, *s2;
ea258ad3 175#endif
cfbe03c9
JS
176{
177 register int c1, c2;
178
179 while (*s1 && *s2) {
180 c1 = tolower(*s1);
181 c2 = tolower(*s2);
182 if (c1 != c2)
183 return (c1 - c2);
184 s1++;
185 s2++;
186 }
187 return (int) (*s1 - *s2);
188}
189
190#endif
191
192/*
193 * return the default color key related to the given visual
194 */
ea258ad3
DW
195#ifdef __OS2__
196/* Visual Age cannot deal with old, non-ansi, code */
197static int xpmVisualType(Visual* visual)
198#else
cfbe03c9 199static int
e6ed776f
GRG
200xpmVisualType(visual)
201 Visual *visual;
ea258ad3 202#endif
cfbe03c9
JS
203{
204#ifndef FOR_MSW
e6ed776f
GRG
205# ifndef AMIGA
206 switch (visual->class) {
cfbe03c9
JS
207 case StaticGray:
208 case GrayScale:
209 switch (visual->map_entries) {
210 case 2:
211 return (XPM_MONO);
212 case 4:
213 return (XPM_GRAY4);
214 default:
215 return (XPM_GRAY);
216 }
217 default:
218 return (XPM_COLOR);
219 }
e6ed776f
GRG
220# else
221 /* set the key explicitly in the XpmAttributes to override this */
222 return (XPM_COLOR);
223# endif
cfbe03c9
JS
224#else
225 /* there should be a similar switch for MSW */
226 return (XPM_COLOR);
227#endif
228}
229
230
231typedef struct {
232 int cols_index;
233 long closeness;
234} CloseColor;
235
ea258ad3
DW
236#ifdef __OS2__
237/* Visual Age cannot deal with old, non-ansi, code */
238static int closeness_cmp(Const void* a, Const void* b)
239#else
cfbe03c9 240static int
e6ed776f
GRG
241closeness_cmp(a, b)
242 Const void *a, *b;
ea258ad3 243#endif
cfbe03c9
JS
244{
245 CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b;
246
247 /* cast to int as qsort requires */
248 return (int) (x->closeness - y->closeness);
249}
250
e6ed776f
GRG
251
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
255 */
ea258ad3
DW
256#ifdef __OS2__
257/* Visual Age cannot deal with old, non-ansi, code */
258static int
259AllocColor(
260 Display* display
261, Colormap colormap
262, char* colorname
263, XColor* xcolor
264, void* closure
265)
266#else
e6ed776f
GRG
267static int
268AllocColor(display, colormap, colorname, xcolor, closure)
269 Display *display;
a7846525 270 Colormap colormap;
e6ed776f
GRG
271 char *colorname;
272 XColor *xcolor;
273 void *closure; /* not used */
ea258ad3 274#endif
e6ed776f
GRG
275{
276 int status;
277 if (colorname)
ea258ad3
DW
278#ifdef __OS2__
279 if (!XParseColor(display, &colormap, colorname, xcolor))
280 return -1;
281 status = XAllocColor(display, &colormap, xcolor);
282#else
e6ed776f
GRG
283 if (!XParseColor(display, colormap, colorname, xcolor))
284 return -1;
285 status = XAllocColor(display, colormap, xcolor);
ea258ad3 286#endif
e6ed776f
GRG
287 return status != 0 ? 1 : 0;
288}
289
290
cfbe03c9
JS
291#ifndef FOR_MSW
292/*
293 * set a close color in case the exact one can't be set
294 * return 0 if success, 1 otherwise.
295 */
296
297static int
e6ed776f
GRG
298SetCloseColor(display, colormap, visual, col, image_pixel, mask_pixel,
299 alloc_pixels, nalloc_pixels, attributes, cols, ncols,
300 allocColor, closure)
301 Display *display;
302 Colormap colormap;
303 Visual *visual;
304 XColor *col;
305 Pixel *image_pixel, *mask_pixel;
306 Pixel *alloc_pixels;
307 unsigned int *nalloc_pixels;
308 XpmAttributes *attributes;
309 XColor *cols;
310 int ncols;
311 XpmAllocColorFunc allocColor;
312 void *closure;
cfbe03c9
JS
313{
314
315 /*
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.
320 */
321
322
323 long int red_closeness, green_closeness, blue_closeness;
324 int n;
e6ed776f 325 Bool alloc_color;
cfbe03c9
JS
326
327 if (attributes && (attributes->valuemask & XpmCloseness))
328 red_closeness = green_closeness = blue_closeness =
329 attributes->closeness;
330 else {
331 red_closeness = attributes->red_closeness;
332 green_closeness = attributes->green_closeness;
333 blue_closeness = attributes->blue_closeness;
334 }
e6ed776f
GRG
335 if (attributes && (attributes->valuemask & XpmAllocCloseColors))
336 alloc_color = attributes->alloc_close_colors;
337 else
338 alloc_color = True;
cfbe03c9
JS
339
340 /*
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.
ea258ad3 352 *
cfbe03c9
JS
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)...
ea258ad3 357 *
cfbe03c9
JS
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.
ea258ad3 362 *
cfbe03c9
JS
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.
374 */
375
376#define ITERATIONS 2 /* more than one is almost never
377 * necessary */
378
379 for (n = 0; n <= ITERATIONS; ++n) {
380 CloseColor *closenesses =
381 (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
382 int i, c;
383
384 for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */
385#define COLOR_FACTOR 3
386#define BRIGHTNESS_FACTOR 1
387
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 +
394 (long) col->green +
395 (long) col->blue)
396 - ((long) cols[i].red +
397 (long) cols[i].green +
398 (long) cols[i].blue));
399 }
400 qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
401
402 i = 0;
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) {
e6ed776f
GRG
410 if (alloc_color) {
411 if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){
412 if (n == ITERATIONS)
413 XUngrabServer(display);
414 XpmFree(closenesses);
415 *image_pixel = cols[c].pixel;
416 *mask_pixel = 1;
417 alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
418 return (0);
419 } else {
420 ++i;
421 if (i == ncols)
422 break;
423 c = closenesses[i].cols_index;
424 }
425 } else {
cfbe03c9
JS
426 if (n == ITERATIONS)
427 XUngrabServer(display);
428 XpmFree(closenesses);
429 *image_pixel = cols[c].pixel;
430 *mask_pixel = 1;
cfbe03c9 431 return (0);
cfbe03c9
JS
432 }
433 }
434
435 /* Couldn't allocate _any_ of the close colors! */
436
437 if (n == ITERATIONS)
438 XUngrabServer(display);
439 XpmFree(closenesses);
440
441 if (i == 0 || i == ncols) /* no color close enough or cannot */
442 return (1); /* alloc any color (full of r/w's) */
443
e6ed776f 444 if ((*allocColor)(display, colormap, NULL, col, closure)) {
cfbe03c9
JS
445 *image_pixel = col->pixel;
446 *mask_pixel = 1;
e6ed776f 447 alloc_pixels[(*nalloc_pixels)++] = col->pixel;
cfbe03c9
JS
448 return (0);
449 } else { /* colormap has probably changed, so
450 * re-read... */
451 if (n == ITERATIONS - 1)
452 XGrabServer(display);
453
454#if 0
e6ed776f 455 if (visual->class == DirectColor) {
cfbe03c9
JS
456 /* TODO */
457 } else
458#endif
459 XQueryColors(display, colormap, cols, ncols);
460 }
461 }
462 return (1);
463}
464
465#define USE_CLOSECOLOR attributes && \
466(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
467 || ((attributes->valuemask & XpmRGBCloseness) && \
e6ed776f
GRG
468 (attributes->red_closeness != 0 \
469 || attributes->green_closeness != 0 \
470 || attributes->blue_closeness != 0)))
cfbe03c9
JS
471
472#else
473 /* FOR_MSW part */
474 /* nothing to do here, the window system does it */
475#endif
476
477/*
478 * set the color pixel related to the given colorname,
479 * return 0 if success, 1 otherwise.
480 */
481
ea258ad3
DW
482#ifdef __OS2__
483/* Visual Age cannot deal with old, non-ansi, code */
484static int
485SetColor(
486 Display* display
487, Colormap colormap
488, Visual* visual
489, char* colorname
490, unsigned int color_index
491, Pixel* image_pixel
492, Pixel* mask_pixel
493, unsigned int* mask_pixel_index
494, Pixel* alloc_pixels
495, unsigned int* nalloc_pixels
496, Pixel* used_pixels
497, unsigned int* nused_pixels
498, XpmAttributes* attributes
499, XColor* cols
500, int ncols
501, XpmAllocColorFunc allocColor
502, void* closure
503)
504#else
cfbe03c9 505static int
e6ed776f
GRG
506SetColor(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)
510 Display *display;
511 Colormap colormap;
512 Visual *visual;
513 char *colorname;
514 unsigned int color_index;
515 Pixel *image_pixel, *mask_pixel;
516 unsigned int *mask_pixel_index;
517 Pixel *alloc_pixels;
518 unsigned int *nalloc_pixels;
519 Pixel *used_pixels;
520 unsigned int *nused_pixels;
521 XpmAttributes *attributes;
522 XColor *cols;
523 int ncols;
524 XpmAllocColorFunc allocColor;
525 void *closure;
ea258ad3 526#endif
cfbe03c9
JS
527{
528 XColor xcolor;
e6ed776f 529 int status;
cfbe03c9 530
e6ed776f
GRG
531 if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
532 status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
533 if (status < 0) /* parse color failed */
cfbe03c9 534 return (1);
e6ed776f
GRG
535
536 if (status == 0) {
cfbe03c9
JS
537#ifndef FOR_MSW
538 if (USE_CLOSECOLOR)
539 return (SetCloseColor(display, colormap, visual, &xcolor,
e6ed776f
GRG
540 image_pixel, mask_pixel,
541 alloc_pixels, nalloc_pixels,
542 attributes, cols, ncols,
543 allocColor, closure));
cfbe03c9
JS
544 else
545#endif /* ndef FOR_MSW */
546 return (1);
e6ed776f
GRG
547 } else
548 alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
cfbe03c9 549 *image_pixel = xcolor.pixel;
e6ed776f 550#ifndef FOR_MSW
cfbe03c9 551 *mask_pixel = 1;
ea258ad3
DW
552#else
553#ifdef __OS2__
554 *mask_pixel = OS2RGB(0,0,0);
e6ed776f
GRG
555#else
556 *mask_pixel = RGB(0,0,0);
ea258ad3 557#endif
e6ed776f
GRG
558#endif
559 used_pixels[(*nused_pixels)++] = xcolor.pixel;
cfbe03c9
JS
560 } else {
561 *image_pixel = 0;
e6ed776f 562#ifndef FOR_MSW
cfbe03c9 563 *mask_pixel = 0;
e6ed776f 564#else
ea258ad3
DW
565#ifdef __OS2__
566 *mask_pixel = OS2RGB(0,0,0);
567#else
568 *mask_pixel = RGB(0,0,0);
569#endif
e6ed776f
GRG
570#endif
571 /* store the color table index */
572 *mask_pixel_index = color_index;
cfbe03c9
JS
573 }
574 return (0);
575}
576
ea258ad3
DW
577#ifdef __OS2__
578/* Visual Age cannot deal with old, non-ansi, code */
579static int
580CreateColors(
581 Display* display
582, XpmAttributes* attributes
583, XpmColor* colors
584, unsigned int ncolors
585, Pixel* image_pixels
586, Pixel* mask_pixels
587, unsigned int* mask_pixel_index
588, Pixel* alloc_pixels
589, unsigned int* nalloc_pixels
590, Pixel* used_pixels
591, unsigned int* nused_pixels
592)
593#else
cfbe03c9 594static int
e6ed776f
GRG
595CreateColors(display, attributes, colors, ncolors, image_pixels, mask_pixels,
596 mask_pixel_index, alloc_pixels, nalloc_pixels,
597 used_pixels, nused_pixels)
598 Display *display;
599 XpmAttributes *attributes;
600 XpmColor *colors;
601 unsigned int ncolors;
602 Pixel *image_pixels;
603 Pixel *mask_pixels;
604 unsigned int *mask_pixel_index;
605 Pixel *alloc_pixels;
606 unsigned int *nalloc_pixels;
607 Pixel *used_pixels;
608 unsigned int *nused_pixels;
ea258ad3 609#endif
cfbe03c9
JS
610{
611 /* variables stored in the XpmAttributes structure */
612 Visual *visual;
613 Colormap colormap;
614 XpmColorSymbol *colorsymbols;
615 unsigned int numsymbols;
e6ed776f
GRG
616 XpmAllocColorFunc allocColor;
617 void *closure;
cfbe03c9
JS
618
619 char *colorname;
e6ed776f
GRG
620 unsigned int color, key;
621 Bool pixel_defined;
cfbe03c9
JS
622 XpmColorSymbol *symbol;
623 char **defaults;
624 int ErrorStatus = XpmSuccess;
625 char *s;
626 int default_index;
627
628 XColor *cols = NULL;
629 unsigned int ncols = 0;
630
631 /*
632 * retrieve information from the XpmAttributes
633 */
634 if (attributes && attributes->valuemask & XpmColorSymbols) {
635 colorsymbols = attributes->colorsymbols;
636 numsymbols = attributes->numsymbols;
637 } else
638 numsymbols = 0;
639
640 if (attributes && attributes->valuemask & XpmVisual)
641 visual = attributes->visual;
642 else
643 visual = XDefaultVisual(display, XDefaultScreen(display));
644
e6ed776f 645 if (attributes && (attributes->valuemask & XpmColormap))
cfbe03c9
JS
646 colormap = attributes->colormap;
647 else
648 colormap = XDefaultColormap(display, XDefaultScreen(display));
649
e6ed776f 650 if (attributes && (attributes->valuemask & XpmColorKey))
cfbe03c9
JS
651 key = attributes->color_key;
652 else
653 key = xpmVisualType(visual);
654
e6ed776f
GRG
655 if (attributes && (attributes->valuemask & XpmAllocColor))
656 allocColor = attributes->alloc_color;
657 else
658 allocColor = AllocColor;
659 if (attributes && (attributes->valuemask & XpmColorClosure))
660 closure = attributes->color_closure;
661 else
662 closure = NULL;
663
cfbe03c9
JS
664#ifndef FOR_MSW
665 if (USE_CLOSECOLOR) {
666 /* originally from SetCloseColor */
667#if 0
e6ed776f 668 if (visual->class == DirectColor) {
cfbe03c9
JS
669
670 /*
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.
677 */
678 } else {
679#endif
680 int i;
681
e6ed776f 682#ifndef AMIGA
cfbe03c9 683 ncols = visual->map_entries;
e6ed776f
GRG
684#else
685 ncols = colormap->Count;
686#endif
cfbe03c9
JS
687 cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
688 for (i = 0; i < ncols; ++i)
689 cols[i].pixel = i;
690 XQueryColors(display, colormap, cols, ncols);
691#if 0
692 }
693#endif
694 }
695#endif /* ndef FOR_MSW */
696
697 switch (key) {
698 case XPM_MONO:
699 default_index = 2;
700 break;
701 case XPM_GRAY4:
702 default_index = 3;
703 break;
704 case XPM_GRAY:
705 default_index = 4;
706 break;
707 case XPM_COLOR:
708 default:
709 default_index = 5;
710 break;
711 }
712
e6ed776f
GRG
713 for (color = 0; color < ncolors; color++, colors++,
714 image_pixels++, mask_pixels++) {
cfbe03c9
JS
715 colorname = NULL;
716 pixel_defined = False;
e6ed776f 717 defaults = (char **) colors;
cfbe03c9
JS
718
719 /*
720 * look for a defined symbol
721 */
722 if (numsymbols) {
e6ed776f
GRG
723
724 unsigned int n;
725
cfbe03c9 726 s = defaults[1];
e6ed776f 727 for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
cfbe03c9
JS
728 if (symbol->name && s && !strcmp(symbol->name, s))
729 /* override name */
730 break;
731 if (!symbol->name && symbol->value) { /* override value */
732 int def_index = default_index;
733
734 while (defaults[def_index] == NULL) /* find defined
735 * colorname */
736 --def_index;
737 if (def_index < 2) {/* nothing towards mono, so try
738 * towards color */
739 def_index = default_index + 1;
740 while (def_index <= 5 && defaults[def_index] == NULL)
741 ++def_index;
742 }
743 if (def_index >= 2 && defaults[def_index] != NULL &&
e6ed776f 744 !xpmstrcasecmp(symbol->value, defaults[def_index]))
cfbe03c9
JS
745 break;
746 }
747 }
e6ed776f 748 if (n != numsymbols) {
cfbe03c9
JS
749 if (symbol->name && symbol->value)
750 colorname = symbol->value;
751 else
752 pixel_defined = True;
753 }
754 }
755 if (!pixel_defined) { /* pixel not given as symbol value */
e6ed776f
GRG
756
757 unsigned int k;
758
cfbe03c9 759 if (colorname) { /* colorname given as symbol value */
e6ed776f
GRG
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))
cfbe03c9
JS
765 pixel_defined = True;
766 else
767 ErrorStatus = XpmColorError;
768 }
e6ed776f
GRG
769 k = key;
770 while (!pixel_defined && k > 1) {
771 if (defaults[k]) {
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)) {
cfbe03c9
JS
778 pixel_defined = True;
779 break;
780 } else
781 ErrorStatus = XpmColorError;
782 }
e6ed776f 783 k--;
cfbe03c9 784 }
e6ed776f
GRG
785 k = key + 1;
786 while (!pixel_defined && k < NKEYS + 1) {
787 if (defaults[k]) {
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)) {
cfbe03c9
JS
794 pixel_defined = True;
795 break;
796 } else
797 ErrorStatus = XpmColorError;
798 }
e6ed776f 799 k++;
cfbe03c9
JS
800 }
801 if (!pixel_defined) {
802 if (cols)
803 XpmFree(cols);
804 return (XpmColorFailed);
805 }
806 } else {
e6ed776f
GRG
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 */
cfbe03c9 811 if (symbol->value
e6ed776f
GRG
812 && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
813 *mask_pixels = 0;
814 *mask_pixel_index = color;
cfbe03c9 815 } else
e6ed776f
GRG
816 *mask_pixels = 1;
817 used_pixels[(*nused_pixels)++] = *image_pixels;
cfbe03c9
JS
818 }
819 }
820 if (cols)
821 XpmFree(cols);
822 return (ErrorStatus);
823}
824
825
e6ed776f 826/* default FreeColors function, simply call XFreeColors */
ea258ad3
DW
827#ifdef __OS2__
828/* Visual Age cannot deal with old, non-ansi, code */
829static int
830FreeColors(
831 Display* display
832, Colormap colormap
833, Pixel* pixels
834, int n
835, void* closure
836)
837#else
e6ed776f
GRG
838static int
839FreeColors(display, colormap, pixels, n, closure)
840 Display *display;
841 Colormap colormap;
842 Pixel *pixels;
843 int n;
844 void *closure; /* not used */
ea258ad3 845#endif
e6ed776f
GRG
846{
847 return XFreeColors(display, colormap, pixels, n, 0);
848}
849
850
851/* function call in case of error */
cfbe03c9
JS
852#undef RETURN
853#define RETURN(status) \
854{ \
e6ed776f
GRG
855 ErrorStatus = status; \
856 goto error; \
cfbe03c9
JS
857}
858
ea258ad3
DW
859#ifdef __OS2__
860/* Visual Age cannot deal with old, non-ansi, code */
861int XpmCreateImageFromXpmImage(
862 Display* display
863, XpmImage* image
864, XImage** image_return
865, XImage** shapeimage_return
866, XpmAttributes* attributes
867)
868#else
cfbe03c9 869int
e6ed776f
GRG
870XpmCreateImageFromXpmImage(display, image,
871 image_return, shapeimage_return, attributes)
872 Display *display;
873 XpmImage *image;
874 XImage **image_return;
875 XImage **shapeimage_return;
876 XpmAttributes *attributes;
ea258ad3 877#endif
cfbe03c9 878{
ea258ad3
DW
879#ifdef __OS2__
880 HAB hab;
881 HPS hps;
882 SIZEL sizl = {0, 0};
883#endif
cfbe03c9
JS
884 /* variables stored in the XpmAttributes structure */
885 Visual *visual;
886 Colormap colormap;
887 unsigned int depth;
e6ed776f
GRG
888 int bitmap_format;
889 XpmFreeColorsFunc freeColors;
890 void *closure;
cfbe03c9
JS
891
892 /* variables to return */
893 XImage *ximage = NULL;
894 XImage *shapeimage = NULL;
e6ed776f 895 unsigned int mask_pixel_index = XpmUndefPixel;
cfbe03c9
JS
896 int ErrorStatus;
897
898 /* calculation variables */
e6ed776f 899 Pixel *image_pixels = NULL;
cfbe03c9 900 Pixel *mask_pixels = NULL;
e6ed776f
GRG
901 Pixel *alloc_pixels = NULL;
902 Pixel *used_pixels = NULL;
903 unsigned int nalloc_pixels = 0;
904 unsigned int nused_pixels = 0;
cfbe03c9
JS
905
906 /* initialize return values */
907 if (image_return)
908 *image_return = NULL;
909 if (shapeimage_return)
910 *shapeimage_return = NULL;
911
912 /* retrieve information from the XpmAttributes */
913 if (attributes && (attributes->valuemask & XpmVisual))
914 visual = attributes->visual;
915 else
916 visual = XDefaultVisual(display, XDefaultScreen(display));
917
918 if (attributes && (attributes->valuemask & XpmColormap))
919 colormap = attributes->colormap;
920 else
921 colormap = XDefaultColormap(display, XDefaultScreen(display));
922
923 if (attributes && (attributes->valuemask & XpmDepth))
924 depth = attributes->depth;
925 else
926 depth = XDefaultDepth(display, XDefaultScreen(display));
927
e6ed776f
GRG
928 if (attributes && (attributes->valuemask & XpmBitmapFormat))
929 bitmap_format = attributes->bitmap_format;
930 else
931 bitmap_format = ZPixmap;
932
933 if (attributes && (attributes->valuemask & XpmFreeColors))
934 freeColors = attributes->free_colors;
935 else
936 freeColors = FreeColors;
937 if (attributes && (attributes->valuemask & XpmColorClosure))
938 closure = attributes->color_closure;
939 else
940 closure = NULL;
941
cfbe03c9
JS
942 ErrorStatus = XpmSuccess;
943
944 /* malloc pixels index tables */
e6ed776f
GRG
945 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
946 if (!image_pixels)
cfbe03c9
JS
947 return (XpmNoMemory);
948
949 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
950 if (!mask_pixels)
951 RETURN(XpmNoMemory);
952
e6ed776f
GRG
953 /* maximum of allocated pixels will be the number of colors */
954 alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
955 if (!alloc_pixels)
956 RETURN(XpmNoMemory);
cfbe03c9
JS
957
958 /* maximum of allocated pixels will be the number of colors */
e6ed776f
GRG
959 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
960 if (!used_pixels)
cfbe03c9
JS
961 RETURN(XpmNoMemory);
962
963 /* get pixel colors, store them in index tables */
964 ErrorStatus = CreateColors(display, attributes, image->colorTable,
e6ed776f
GRG
965 image->ncolors, image_pixels, mask_pixels,
966 &mask_pixel_index, alloc_pixels, &nalloc_pixels,
967 used_pixels, &nused_pixels);
cfbe03c9
JS
968
969 if (ErrorStatus != XpmSuccess
970 && (ErrorStatus < 0 || (attributes
971 && (attributes->valuemask & XpmExactColors)
972 && attributes->exactColors)))
973 RETURN(ErrorStatus);
974
975 /* create the ximage */
976 if (image_return) {
977 ErrorStatus = CreateXImage(display, visual, depth,
e6ed776f 978 (depth == 1 ? bitmap_format : ZPixmap),
cfbe03c9
JS
979 image->width, image->height, &ximage);
980 if (ErrorStatus != XpmSuccess)
981 RETURN(ErrorStatus);
982
983#ifndef FOR_MSW
e6ed776f 984# ifndef AMIGA
cfbe03c9
JS
985
986 /*
e6ed776f 987 * set the ximage data using optimized functions for ZPixmap
cfbe03c9
JS
988 */
989
e6ed776f
GRG
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);
cfbe03c9 997 else if (ximage->bits_per_pixel == 16)
e6ed776f
GRG
998 PutImagePixels16(ximage, image->width, image->height,
999 image->data, image_pixels);
cfbe03c9 1000 else if (ximage->bits_per_pixel == 32)
e6ed776f
GRG
1001 PutImagePixels32(ximage, image->width, image->height,
1002 image->data, image_pixels);
cfbe03c9 1003 else
e6ed776f
GRG
1004 PutImagePixels(ximage, image->width, image->height,
1005 image->data, image_pixels);
1006# else /* AMIGA */
1007 APutImagePixels(ximage, image->width, image->height,
1008 image->data, image_pixels);
1009# endif
cfbe03c9 1010#else /* FOR_MSW */
ea258ad3
DW
1011#ifdef __OS2__
1012 hps = GpiCreatePS(hab, *display, &sizl, GPIA_ASSOC|PU_PELS);
1013 MSWPutImagePixels(hps, display, ximage, image->width, image->height,
1014 image->data, image_pixels);
1015#else
e6ed776f
GRG
1016 MSWPutImagePixels(display, ximage, image->width, image->height,
1017 image->data, image_pixels);
ea258ad3 1018#endif
cfbe03c9
JS
1019#endif
1020 }
1021 /* create the shape mask image */
e6ed776f
GRG
1022 if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
1023 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
1024 image->width, image->height, &shapeimage);
cfbe03c9
JS
1025 if (ErrorStatus != XpmSuccess)
1026 RETURN(ErrorStatus);
1027
1028#ifndef FOR_MSW
e6ed776f
GRG
1029# ifndef AMIGA
1030 PutImagePixels1(shapeimage, image->width, image->height,
cfbe03c9 1031 image->data, mask_pixels);
e6ed776f
GRG
1032# else /* AMIGA */
1033 APutImagePixels(shapeimage, image->width, image->height,
1034 image->data, mask_pixels);
1035# endif
1036#else /* FOR_MSW */
ea258ad3
DW
1037#ifdef __OS2__
1038 hps = GpiCreatePS(hab, *display, &sizl, GPIA_ASSOC|PU_PELS);
1039 MSWPutImagePixels(hps, display, shapeimage, image->width, image->height,
1040 image->data, mask_pixels);
1041#else
e6ed776f 1042 MSWPutImagePixels(display, shapeimage, image->width, image->height,
cfbe03c9 1043 image->data, mask_pixels);
ea258ad3 1044#endif
cfbe03c9
JS
1045#endif
1046
1047 }
e6ed776f 1048 XpmFree(image_pixels);
cfbe03c9 1049 XpmFree(mask_pixels);
cfbe03c9 1050
e6ed776f
GRG
1051 /* if requested return used pixels in the XpmAttributes structure */
1052 if (attributes && (attributes->valuemask & XpmReturnPixels ||
cfbe03c9 1053/* 3.2 backward compatibility code */
e6ed776f 1054 attributes->valuemask & XpmReturnInfos)) {
cfbe03c9 1055/* end 3.2 bc */
e6ed776f
GRG
1056 attributes->pixels = used_pixels;
1057 attributes->npixels = nused_pixels;
1058 attributes->mask_pixel = mask_pixel_index;
1059 } else
1060 XpmFree(used_pixels);
1061
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;
cfbe03c9 1066 } else
e6ed776f 1067 XpmFree(alloc_pixels);
cfbe03c9
JS
1068
1069 /* return created images */
1070 if (image_return)
1071 *image_return = ximage;
1072 if (shapeimage_return)
1073 *shapeimage_return = shapeimage;
1074
1075 return (ErrorStatus);
e6ed776f
GRG
1076
1077/* exit point in case of error, free only locally allocated variables */
1078error:
1079 if (ximage)
1080 XDestroyImage(ximage);
1081 if (shapeimage)
1082 XDestroyImage(shapeimage);
1083 if (image_pixels)
1084 XpmFree(image_pixels);
1085 if (mask_pixels)
1086 XpmFree(mask_pixels);
1087 if (nalloc_pixels)
1088 (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
1089 if (alloc_pixels)
1090 XpmFree(alloc_pixels);
1091 if (used_pixels)
1092 XpmFree(used_pixels);
1093
1094 return (ErrorStatus);
cfbe03c9
JS
1095}
1096
1097
1098/*
e6ed776f 1099 * Create an XImage with its data
cfbe03c9 1100 */
ea258ad3
DW
1101#ifdef __OS2__
1102/* Visual Age cannot deal with old, non-ansi, code */
1103static int CreateXImage(
1104 Display* display
1105, Visual* visual
1106, unsigned int depth
1107, int format
1108, unsigned int width
1109, unsigned int height
1110, XImage** image_return
1111)
1112#else
cfbe03c9 1113static int
e6ed776f
GRG
1114CreateXImage(display, visual, depth, format, width, height, image_return)
1115 Display *display;
1116 Visual *visual;
1117 unsigned int depth;
1118 int format;
1119 unsigned int width;
1120 unsigned int height;
1121 XImage **image_return;
ea258ad3 1122#endif
cfbe03c9
JS
1123{
1124 int bitmap_pad;
1125
1126 /* first get bitmap_pad */
1127 if (depth > 16)
1128 bitmap_pad = 32;
1129 else if (depth > 8)
1130 bitmap_pad = 16;
1131 else
1132 bitmap_pad = 8;
1133
1134 /* then create the XImage with data = NULL and bytes_per_line = 0 */
e6ed776f 1135 *image_return = XCreateImage(display, visual, depth, format, 0, 0,
cfbe03c9
JS
1136 width, height, bitmap_pad, 0);
1137 if (!*image_return)
1138 return (XpmNoMemory);
1139
e6ed776f 1140#if !defined(FOR_MSW) && !defined(AMIGA)
cfbe03c9
JS
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);
1144
1145 if (!(*image_return)->data) {
1146 XDestroyImage(*image_return);
1147 *image_return = NULL;
1148 return (XpmNoMemory);
1149 }
1150#else
e6ed776f 1151 /* under FOR_MSW and AMIGA XCreateImage has done it all */
cfbe03c9
JS
1152#endif
1153 return (XpmSuccess);
1154}
1155
1156#ifndef FOR_MSW
e6ed776f 1157# ifndef AMIGA
cfbe03c9
JS
1158/*
1159 * The functions below are written from X11R5 MIT's code (XImUtil.c)
1160 *
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.
1165 */
1166
1167LFUNC(_putbits, void, (register char *src, int dstoffset,
1168 register int numbits, register char *dst));
1169
1170LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb));
1171
1172static 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
1205};
1206
ea258ad3
DW
1207#ifdef __OS2__
1208/* Visual Age cannot deal with old, non-ansi, code */
1209static int
1210_XReverse_Bytes(register unsigned char* bpt, register int nb)
1211#else
cfbe03c9 1212static int
e6ed776f
GRG
1213_XReverse_Bytes(bpt, nb)
1214 register unsigned char *bpt;
1215 register int nb;
ea258ad3 1216#endif
cfbe03c9
JS
1217{
1218 do {
1219 *bpt = _reverse_byte[*bpt];
1220 bpt++;
1221 } while (--nb > 0);
1222 return 0;
1223}
1224
1225
ea258ad3
DW
1226#ifdef __OS2__
1227/* Visual Age cannot deal with old, non-ansi, code */
1228void xpm_xynormalizeimagebits(register unsigned char* bp, register XImage* img)
1229#else
cfbe03c9 1230void
e6ed776f
GRG
1231xpm_xynormalizeimagebits(bp, img)
1232 register unsigned char *bp;
1233 register XImage *img;
ea258ad3 1234#endif
cfbe03c9
JS
1235{
1236 register unsigned char c;
1237
1238 if (img->byte_order != img->bitmap_bit_order) {
1239 switch (img->bitmap_unit) {
1240
1241 case 16:
1242 c = *bp;
1243 *bp = *(bp + 1);
1244 *(bp + 1) = c;
1245 break;
1246
1247 case 32:
1248 c = *(bp + 3);
1249 *(bp + 3) = *bp;
1250 *bp = c;
1251 c = *(bp + 2);
1252 *(bp + 2) = *(bp + 1);
1253 *(bp + 1) = c;
1254 break;
1255 }
1256 }
1257 if (img->bitmap_bit_order == MSBFirst)
1258 _XReverse_Bytes(bp, img->bitmap_unit >> 3);
1259}
1260
ea258ad3
DW
1261#ifdef __OS2__
1262/* Visual Age cannot deal with old, non-ansi, code */
1263void xpm_znormalizeimagebits(register unsigned char* bp, register XImage* img)
1264#else
cfbe03c9 1265void
e6ed776f
GRG
1266xpm_znormalizeimagebits(bp, img)
1267 register unsigned char *bp;
1268 register XImage *img;
ea258ad3 1269#endif
cfbe03c9
JS
1270{
1271 register unsigned char c;
1272
1273 switch (img->bits_per_pixel) {
1274
1275 case 2:
1276 _XReverse_Bytes(bp, 1);
1277 break;
1278
1279 case 4:
1280 *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
1281 break;
1282
1283 case 16:
1284 c = *bp;
1285 *bp = *(bp + 1);
1286 *(bp + 1) = c;
1287 break;
1288
1289 case 24:
1290 c = *(bp + 2);
1291 *(bp + 2) = *bp;
1292 *bp = c;
1293 break;
1294
1295 case 32:
1296 c = *(bp + 3);
1297 *(bp + 3) = *bp;
1298 *bp = c;
1299 c = *(bp + 2);
1300 *(bp + 2) = *(bp + 1);
1301 *(bp + 1) = c;
1302 break;
1303 }
1304}
1305
1306static unsigned char Const _lomask[0x09] = {
13070x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1308static unsigned char Const _himask[0x09] = {
13090xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
1310
ea258ad3
DW
1311#ifdef __OS2__
1312/* Visual Age cannot deal with old, non-ansi, code */
1313static void _putbits(
1314 register char* src
1315, int dstoffset
1316, register int numbits
1317, register char* dst
1318)
1319#else
cfbe03c9 1320static void
e6ed776f
GRG
1321_putbits(src, dstoffset, numbits, dst)
1322 register char *src; /* address of source bit string */
1323 int dstoffset; /* bit offset into destination;
cfbe03c9 1324 * range is 0-31 */
e6ed776f 1325 register int numbits; /* number of bits to copy to
cfbe03c9 1326 * destination */
e6ed776f 1327 register char *dst; /* address of destination bit string */
ea258ad3 1328#endif
cfbe03c9
JS
1329{
1330 register unsigned char chlo, chhi;
1331 int hibits;
1332
1333 dst = dst + (dstoffset >> 3);
1334 dstoffset = dstoffset & 7;
1335 hibits = 8 - dstoffset;
1336 chlo = *dst & _lomask[dstoffset];
1337 for (;;) {
1338 chhi = (*src << dstoffset) & _himask[dstoffset];
1339 if (numbits <= hibits) {
1340 chhi = chhi & _lomask[dstoffset + numbits];
1341 *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
1342 break;
1343 }
1344 *dst = chhi | chlo;
1345 dst++;
1346 numbits = numbits - hibits;
1347 chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
1348 src++;
1349 if (numbits <= dstoffset) {
1350 chlo = chlo & _lomask[numbits];
1351 *dst = (*dst & _himask[numbits]) | chlo;
1352 break;
1353 }
1354 numbits = numbits - dstoffset;
1355 }
1356}
1357
1358/*
1359 * Default method to write pixels into a Z image data structure.
1360 * The algorithm used is:
1361 *
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
1367 */
1368
ea258ad3
DW
1369#ifdef __OS2__
1370/* Visual Age cannot deal with old, non-ansi, code */
1371static void PutImagePixels(
1372, XImage* image
1373, unsigned int width
1374, unsigned int height
1375, unsigned int* pixelindex
1376, Pixel* pixels
1377)
1378#else
cfbe03c9 1379static void
e6ed776f
GRG
1380PutImagePixels(image, width, height, pixelindex, pixels)
1381 XImage *image;
1382 unsigned int width;
1383 unsigned int height;
1384 unsigned int *pixelindex;
1385 Pixel *pixels;
ea258ad3 1386#endif
cfbe03c9
JS
1387{
1388 register char *src;
1389 register char *dst;
1390 register unsigned int *iptr;
1391 register int x, y, i;
1392 register char *data;
1393 Pixel pixel, px;
1394 int nbytes, depth, ibu, ibpp;
1395
1396 data = image->data;
1397 iptr = pixelindex;
1398 depth = image->depth;
1399 if (depth == 1) {
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);
1405 i++, px >>= 8)
1406 ((unsigned char *) &pixel)[i] = px;
1407 src = &data[XYINDEX(x, y, image)];
1408 dst = (char *) &px;
1409 px = 0;
1410 nbytes = ibu >> 3;
1411 for (i = nbytes; --i >= 0;)
1412 *dst++ = *src++;
1413 XYNORMALIZE(&px, image);
1414 _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
1415 XYNORMALIZE(&px, image);
1416 src = (char *) &px;
1417 dst = &data[XYINDEX(x, y, image)];
1418 for (i = nbytes; --i >= 0;)
1419 *dst++ = *src++;
1420 }
1421 } else {
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];
1426 if (depth == 4)
1427 pixel &= 0xf;
1428 for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
1429 px >>= 8)
1430 ((unsigned char *) &pixel)[i] = px;
1431 src = &data[ZINDEX(x, y, image)];
1432 dst = (char *) &px;
1433 px = 0;
1434 nbytes = (ibpp + 7) >> 3;
1435 for (i = nbytes; --i >= 0;)
1436 *dst++ = *src++;
1437 ZNORMALIZE(&px, image);
1438 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1439 ZNORMALIZE(&px, image);
1440 src = (char *) &px;
1441 dst = &data[ZINDEX(x, y, image)];
1442 for (i = nbytes; --i >= 0;)
1443 *dst++ = *src++;
1444 }
1445 }
1446}
1447
1448/*
1449 * write pixels into a 32-bits Z image data structure
1450 */
1451
e6ed776f 1452#if !defined(WORD64) && !defined(LONG64)
cfbe03c9
JS
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.
1457 */
e6ed776f 1458static unsigned long byteorderpixel = MSBFirst << 24;
cfbe03c9
JS
1459
1460#endif
1461
1462/*
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.
1465*/
1466
ea258ad3
DW
1467#ifdef __OS2__
1468/* Visual Age cannot deal with old, non-ansi, code */
1469static void
1470PutImagePixels32(
1471, XImage* image
1472, unsigned int width
1473, unsigned int height
1474, unsigned int* pixelindex
1475, Pixel* pixels
1476)
1477#else
cfbe03c9 1478static void
e6ed776f
GRG
1479PutImagePixels32(image, width, height, pixelindex, pixels)
1480 XImage *image;
1481 unsigned int width;
1482 unsigned int height;
1483 unsigned int *pixelindex;
1484 Pixel *pixels;
ea258ad3 1485#endif
cfbe03c9
JS
1486{
1487 unsigned char *data;
1488 unsigned int *iptr;
1489 int y;
1490 Pixel pixel;
1491
1492#ifdef WITHOUT_SPEEDUPS
1493
1494 int x;
1495 unsigned char *addr;
1496
1497 data = (unsigned char *) image->data;
1498 iptr = pixelindex;
e6ed776f
GRG
1499#if !defined(WORD64) && !defined(LONG64)
1500 if (*((char *) &byteorderpixel) == image->byte_order) {
cfbe03c9
JS
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];
1505 }
1506 } else
1507#endif
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;
1516 addr[3] = pixel;
1517 }
1518 else
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];
1523 addr[0] = pixel;
1524 addr[1] = pixel >> 8;
1525 addr[2] = pixel >> 16;
1526 addr[3] = pixel >> 24;
1527 }
1528
1529#else /* WITHOUT_SPEEDUPS */
1530
1531 int bpl = image->bytes_per_line;
1532 unsigned char *data_ptr, *max_data;
1533
1534 data = (unsigned char *) image->data;
1535 iptr = pixelindex;
e6ed776f
GRG
1536#if !defined(WORD64) && !defined(LONG64)
1537 if (*((char *) &byteorderpixel) == image->byte_order) {
cfbe03c9
JS
1538 for (y = 0; y < height; y++) {
1539 data_ptr = data;
1540 max_data = data_ptr + (width << 2);
1541
1542 while (data_ptr < max_data) {
1543 *((unsigned long *) data_ptr) = pixels[*(iptr++)];
1544 data_ptr += (1 << 2);
1545 }
1546 data += bpl;
1547 }
1548 } else
1549#endif
1550 if (image->byte_order == MSBFirst)
1551 for (y = 0; y < height; y++) {
1552 data_ptr = data;
1553 max_data = data_ptr + (width << 2);
1554
1555 while (data_ptr < max_data) {
1556 pixel = pixels[*(iptr++)];
1557
1558 *data_ptr++ = pixel >> 24;
1559 *data_ptr++ = pixel >> 16;
1560 *data_ptr++ = pixel >> 8;
1561 *data_ptr++ = pixel;
1562
1563 }
1564 data += bpl;
1565 }
1566 else
1567 for (y = 0; y < height; y++) {
1568 data_ptr = data;
1569 max_data = data_ptr + (width << 2);
1570
1571 while (data_ptr < max_data) {
1572 pixel = pixels[*(iptr++)];
1573
1574 *data_ptr++ = pixel;
1575 *data_ptr++ = pixel >> 8;
1576 *data_ptr++ = pixel >> 16;
1577 *data_ptr++ = pixel >> 24;
1578 }
1579 data += bpl;
1580 }
1581
1582#endif /* WITHOUT_SPEEDUPS */
1583}
1584
1585/*
1586 * write pixels into a 16-bits Z image data structure
1587 */
1588
ea258ad3
DW
1589#ifdef __OS2__
1590/* Visual Age cannot deal with old, non-ansi, code */
1591static void PutImagePixels16(
1592, XImage* image
1593, unsigned int width
1594, unsigned int height
1595, unsigned int* pixelindex
1596, Pixel* pixels
1597)
1598#else
cfbe03c9 1599static void
e6ed776f
GRG
1600PutImagePixels16(image, width, height, pixelindex, pixels)
1601 XImage *image;
1602 unsigned int width;
1603 unsigned int height;
1604 unsigned int *pixelindex;
1605 Pixel *pixels;
ea258ad3 1606#endif
cfbe03c9
JS
1607{
1608 unsigned char *data;
1609 unsigned int *iptr;
1610 int y;
1611
1612#ifdef WITHOUT_SPEEDUPS
1613
1614 int x;
1615 unsigned char *addr;
1616
1617 data = (unsigned char *) image->data;
1618 iptr = pixelindex;
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];
1625 }
1626 else
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;
1632 }
1633
1634#else /* WITHOUT_SPEEDUPS */
1635
1636 Pixel pixel;
1637
1638 int bpl = image->bytes_per_line;
1639 unsigned char *data_ptr, *max_data;
1640
1641 data = (unsigned char *) image->data;
1642 iptr = pixelindex;
1643 if (image->byte_order == MSBFirst)
1644 for (y = 0; y < height; y++) {
1645 data_ptr = data;
1646 max_data = data_ptr + (width << 1);
1647
1648 while (data_ptr < max_data) {
1649 pixel = pixels[*(iptr++)];
1650
1651 data_ptr[0] = pixel >> 8;
1652 data_ptr[1] = pixel;
1653
1654 data_ptr += (1 << 1);
1655 }
1656 data += bpl;
1657 }
1658 else
1659 for (y = 0; y < height; y++) {
1660 data_ptr = data;
1661 max_data = data_ptr + (width << 1);
1662
1663 while (data_ptr < max_data) {
1664 pixel = pixels[*(iptr++)];
1665
1666 data_ptr[0] = pixel;
1667 data_ptr[1] = pixel >> 8;
1668
1669 data_ptr += (1 << 1);
1670 }
1671 data += bpl;
1672 }
1673
1674#endif /* WITHOUT_SPEEDUPS */
1675}
1676
1677/*
1678 * write pixels into a 8-bits Z image data structure
1679 */
1680
ea258ad3
DW
1681#ifdef __OS2__
1682/* Visual Age cannot deal with old, non-ansi, code */
1683static void PutImagePixels8(
1684, XImage* image
1685, unsigned int width
1686, unsigned int height
1687, unsigned int* pixelindex
1688, Pixel* pixels
1689)
1690#else
cfbe03c9 1691static void
e6ed776f
GRG
1692PutImagePixels8(image, width, height, pixelindex, pixels)
1693 XImage *image;
1694 unsigned int width;
1695 unsigned int height;
1696 unsigned int *pixelindex;
1697 Pixel *pixels;
ea258ad3 1698#endif
cfbe03c9
JS
1699{
1700 char *data;
1701 unsigned int *iptr;
1702 int y;
1703
1704#ifdef WITHOUT_SPEEDUPS
1705
1706 int x;
1707
1708 data = image->data;
1709 iptr = pixelindex;
1710 for (y = 0; y < height; y++)
1711 for (x = 0; x < width; x++, iptr++)
1712 data[ZINDEX8(x, y, image)] = pixels[*iptr];
1713
1714#else /* WITHOUT_SPEEDUPS */
1715
1716 int bpl = image->bytes_per_line;
1717 char *data_ptr, *max_data;
1718
1719 data = image->data;
1720 iptr = pixelindex;
1721
1722 for (y = 0; y < height; y++) {
1723 data_ptr = data;
1724 max_data = data_ptr + width;
1725
1726 while (data_ptr < max_data)
1727 *(data_ptr++) = pixels[*(iptr++)];
1728
1729 data += bpl;
1730 }
1731
1732#endif /* WITHOUT_SPEEDUPS */
1733}
1734
1735/*
1736 * write pixels into a 1-bit depth image data structure and **offset null**
1737 */
1738
ea258ad3
DW
1739#ifdef __OS2__
1740/* Visual Age cannot deal with old, non-ansi, code */
1741static void PutImagePixels1(
1742, XImage* image
1743, unsigned int width
1744, unsigned int height
1745, unsigned int* pixelindex
1746, Pixel* pixels
1747)
1748#else
cfbe03c9 1749static void
e6ed776f
GRG
1750PutImagePixels1(image, width, height, pixelindex, pixels)
1751 XImage *image;
1752 unsigned int width;
1753 unsigned int height;
1754 unsigned int *pixelindex;
1755 Pixel *pixels;
ea258ad3 1756#endif
cfbe03c9
JS
1757{
1758 if (image->byte_order != image->bitmap_bit_order)
e6ed776f 1759 PutImagePixels(image, width, height, pixelindex, pixels);
cfbe03c9
JS
1760 else {
1761 unsigned int *iptr;
1762 int y;
1763 char *data;
1764
1765#ifdef WITHOUT_SPEEDUPS
1766
1767 int x;
1768
1769 data = image->data;
1770 iptr = pixelindex;
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);
1776 else
1777 data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
1778 }
1779 else
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);
1784 else
1785 data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
1786 }
1787
1788#else /* WITHOUT_SPEEDUPS */
1789
1790 char value;
1791 char *data_ptr, *max_data;
1792 int bpl = image->bytes_per_line;
1793 int diff, count;
1794
1795 data = image->data;
1796 iptr = pixelindex;
1797
1798 diff = width & 7;
1799 width >>= 3;
1800
1801 if (image->bitmap_bit_order == MSBFirst)
1802 for (y = 0; y < height; y++) {
1803 data_ptr = data;
1804 max_data = data_ptr + width;
1805 while (data_ptr < max_data) {
1806 value = 0;
1807
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);
1816
1817 *(data_ptr++) = value;
1818 }
1819 if (diff) {
1820 value = 0;
1821 for (count = 0; count < diff; count++) {
1822 if (pixels[*(iptr++)] & 1)
1823 value |= (0x80 >> count);
1824 }
1825 *(data_ptr) = value;
1826 }
1827 data += bpl;
1828 }
1829 else
1830 for (y = 0; y < height; y++) {
1831 data_ptr = data;
1832 max_data = data_ptr + width;
1833 while (data_ptr < max_data) {
1834 value = 0;
1835 iptr += 8;
1836
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);
1845
1846 iptr += 8;
1847 *(data_ptr++) = value;
1848 }
1849 if (diff) {
1850 value = 0;
1851 for (count = 0; count < diff; count++) {
1852 if (pixels[*(iptr++)] & 1)
1853 value |= (1 << count);
1854 }
1855 *(data_ptr) = value;
1856 }
1857 data += bpl;
1858 }
1859
1860#endif /* WITHOUT_SPEEDUPS */
1861 }
1862}
1863
ea258ad3
DW
1864#ifdef __OS2__
1865/* Visual Age cannot deal with old, non-ansi, code */
1866int XpmCreatePixmapFromXpmImage(
1867, Display* display
1868, Drawable d
1869, XpmImage* image
1870, Pixmap* pixmap_return
1871, Pixmap* shapemask_return
1872, XpmAttributes* attributes
1873#else
cfbe03c9 1874int
e6ed776f
GRG
1875XpmCreatePixmapFromXpmImage(display, d, image,
1876 pixmap_return, shapemask_return, attributes)
1877 Display *display;
1878 Drawable d;
1879 XpmImage *image;
1880 Pixmap *pixmap_return;
1881 Pixmap *shapemask_return;
1882 XpmAttributes *attributes;
ea258ad3 1883#endif
cfbe03c9
JS
1884{
1885 XImage *ximage, *shapeimage;
1886 int ErrorStatus;
1887
1888 /* initialize return values */
1889 if (pixmap_return)
1890 *pixmap_return = 0;
1891 if (shapemask_return)
1892 *shapemask_return = 0;
1893
1894 /* create the ximages */
1895 ErrorStatus = XpmCreateImageFromXpmImage(display, image,
1896 (pixmap_return ? &ximage : NULL),
1897 (shapemask_return ?
1898 &shapeimage : NULL),
1899 attributes);
1900 if (ErrorStatus < 0)
1901 return (ErrorStatus);
1902
1903 /* create the pixmaps and destroy images */
1904 if (pixmap_return && ximage) {
1905 xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
1906 XDestroyImage(ximage);
1907 }
1908 if (shapemask_return && shapeimage) {
1909 xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
1910 XDestroyImage(shapeimage);
1911 }
1912 return (ErrorStatus);
1913}
1914
e6ed776f
GRG
1915# else /* AMIGA */
1916
1917static void
1918APutImagePixels (
1919 XImage *image,
1920 unsigned int width,
1921 unsigned int height,
1922 unsigned int *pixelindex,
1923 Pixel *pixels)
1924{
1925 unsigned int *data = pixelindex;
1926 unsigned int x, y;
1927 unsigned char *array;
1928 XImage *tmp_img;
1929 BOOL success = FALSE;
ea258ad3 1930
e6ed776f
GRG
1931 array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array));
1932 if (array != NULL)
1933 {
1934 tmp_img = AllocXImage ((((width+15)>>4)<<4), 1,
1935 image->rp->BitMap->Depth);
1936 if (tmp_img != NULL)
1937 {
1938 for (y = 0; y < height; ++y)
1939 {
1940 for (x = 0; x < width; ++x)
1941 array[x] = pixels[*(data++)];
1942 WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp);
1943 }
1944 FreeXImage (tmp_img);
1945 success = TRUE;
1946 }
1947 XpmFree (array);
1948 }
ea258ad3 1949
e6ed776f
GRG
1950 if (!success)
1951 {
1952 for (y = 0; y < height; ++y)
1953 for (x = 0; x < width; ++x)
1954 XPutPixel (image, x, y, pixels[*(data++)]);
1955 }
1956}
1957
1958# endif/* AMIGA */
cfbe03c9 1959#else /* FOR_MSW part follows */
ea258ad3
DW
1960
1961#ifdef __OS2__
1962/* Visual Age cannot deal with old, non-ansi, code */
1963static void MSWPutImagePixels(
1964 HPS hps
1965, Display* dc
1966, XImage* image
1967, unsigned int width
1968, unsigned int height
1969, unsigned int* pixelindex
1970, Pixel* pixels
1971)
1972#else
cfbe03c9 1973static void
e6ed776f
GRG
1974MSWPutImagePixels(dc, image, width, height, pixelindex, pixels)
1975 Display *dc;
1976 XImage *image;
1977 unsigned int width;
1978 unsigned int height;
1979 unsigned int *pixelindex;
1980 Pixel *pixels;
ea258ad3 1981#endif
cfbe03c9
JS
1982{
1983 unsigned int *data = pixelindex;
1984 unsigned int x, y;
e6ed776f 1985 HBITMAP obm;
cfbe03c9 1986
ea258ad3
DW
1987#ifdef __OS2__
1988 POINTL point;
1989
1990 obm = GpiSetBitmap(hps, image->bitmap);
1991#else
e6ed776f 1992 obm = SelectObject(*dc, image->bitmap);
ea258ad3
DW
1993#endif
1994
33879bb2 1995 for (y = 0; y < height; y++) {
e6ed776f 1996 for (x = 0; x < width; x++) {
ea258ad3
DW
1997#ifdef __OS2__
1998 point.x = x;
1999 point.y = y;
2000 GpiSetColor(hps, (LONG)pixels[*(data++)]);
2001 GpiSetPel(hps, &point);
2002#else
2003
e6ed776f 2004 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
ea258ad3 2005#endif
e6ed776f 2006 }
33879bb2 2007 }
ea258ad3
DW
2008#ifdef __OS2__
2009 GpiSetBitmap(hps, obm);
2010#else
e6ed776f 2011 SelectObject(*dc, obm);
ea258ad3 2012#endif
cfbe03c9 2013}
e6ed776f
GRG
2014
2015#endif /* FOR_MSW */
2016
2017
2018
2019#if !defined(FOR_MSW) && !defined(AMIGA)
2020
2021static int
2022PutPixel1(ximage, x, y, pixel)
2023 register XImage *ximage;
2024 int x;
2025 int y;
2026 unsigned long pixel;
16a12a3d 2027{
e6ed776f
GRG
2028 register char *src;
2029 register char *dst;
2030 register int i;
2031 register char *data;
2032 Pixel px;
2033 int nbytes;
2034
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)];
2038 dst = (char *)&px;
2039 px = 0;
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);
2046 src = (char *) &px;
2047 dst = &ximage->data[XYINDEX(x, y, ximage)];
2048 for (i = nbytes; --i >= 0; )
2049 *dst++ = *src++;
2050
2051 return 1;
2052}
2053
2054static int
2055PutPixel(ximage, x, y, pixel)
2056 register XImage *ximage;
2057 int x;
2058 int y;
2059 unsigned long pixel;
2060{
2061 register char *src;
2062 register char *dst;
2063 register int i;
2064 register char *data;
2065 Pixel px;
2066 int nbytes, ibpp;
2067
2068 ibpp = ximage->bits_per_pixel;
2069 if (ximage->depth == 4)
2070 pixel &= 0xf;
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)];
2074 dst = (char *) &px;
2075 px = 0;
2076 nbytes = (ibpp + 7) >> 3;
2077 for (i = nbytes; --i >= 0;)
2078 *dst++ = *src++;
2079 ZNORMALIZE(&px, ximage);
2080 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
2081 ZNORMALIZE(&px, ximage);
2082 src = (char *) &px;
2083 dst = &ximage->data[ZINDEX(x, y, ximage)];
2084 for (i = nbytes; --i >= 0;)
2085 *dst++ = *src++;
2086
2087 return 1;
2088}
2089
2090static int
2091PutPixel32(ximage, x, y, pixel)
2092 register XImage *ximage;
2093 int x;
2094 int y;
2095 unsigned long pixel;
2096{
2097 unsigned char *addr;
2098
2099 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
2100 *((unsigned long *)addr) = pixel;
2101 return 1;
2102}
2103
2104static int
2105PutPixel32MSB(ximage, x, y, pixel)
2106 register XImage *ximage;
2107 int x;
2108 int y;
2109 unsigned long pixel;
2110{
2111 unsigned char *addr;
2112
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;
2117 addr[3] = pixel;
2118 return 1;
2119}
2120
2121static int
2122PutPixel32LSB(ximage, x, y, pixel)
2123 register XImage *ximage;
2124 int x;
2125 int y;
2126 unsigned long pixel;
2127{
2128 unsigned char *addr;
2129
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;
2134 addr[0] = pixel;
2135 return 1;
2136}
2137
2138static int
2139PutPixel16MSB(ximage, x, y, pixel)
2140 register XImage *ximage;
2141 int x;
2142 int y;
2143 unsigned long pixel;
2144{
2145 unsigned char *addr;
ea258ad3 2146
e6ed776f
GRG
2147 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
2148 addr[0] = pixel >> 8;
2149 addr[1] = pixel;
2150 return 1;
2151}
2152
2153static int
2154PutPixel16LSB(ximage, x, y, pixel)
2155 register XImage *ximage;
2156 int x;
2157 int y;
2158 unsigned long pixel;
2159{
2160 unsigned char *addr;
ea258ad3 2161
e6ed776f
GRG
2162 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
2163 addr[1] = pixel >> 8;
2164 addr[0] = pixel;
2165 return 1;
2166}
2167
2168static int
2169PutPixel8(ximage, x, y, pixel)
2170 register XImage *ximage;
2171 int x;
2172 int y;
2173 unsigned long pixel;
2174{
2175 ximage->data[ZINDEX8(x, y, ximage)] = pixel;
2176 return 1;
2177}
2178
2179static int
2180PutPixel1MSB(ximage, x, y, pixel)
2181 register XImage *ximage;
2182 int x;
2183 int y;
2184 unsigned long pixel;
2185{
2186 if (pixel & 1)
2187 ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
2188 else
2189 ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
2190 return 1;
2191}
2192
2193static int
2194PutPixel1LSB(ximage, x, y, pixel)
2195 register XImage *ximage;
2196 int x;
2197 int y;
2198 unsigned long pixel;
2199{
2200 if (pixel & 1)
2201 ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
2202 else
2203 ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
2204 return 1;
2205}
2206
2207#endif /* not FOR_MSW && not AMIGA */
2208
16a12a3d 2209/*
e6ed776f
GRG
2210 * This function parses an Xpm file or data and directly create an XImage
2211 */
ea258ad3
DW
2212#ifdef __OS2__
2213/* Visual Age cannot deal with old, non-ansi, code */
2214int xpmParseDataAndCreate(
2215 Display* display
2216, xpmData* data
2217, XImage** image_return
2218, XImage** shapeimage_return
2219, XpmImage* image
2220, XpmInfo* info
2221, XpmAttributes* attributes
2222)
2223#else
e6ed776f
GRG
2224int
2225xpmParseDataAndCreate(display, data, image_return, shapeimage_return,
2226 image, info, attributes)
2227 Display *display;
2228 xpmData *data;
2229 XImage **image_return;
2230 XImage **shapeimage_return;
2231 XpmImage *image;
2232 XpmInfo *info;
2233 XpmAttributes *attributes;
ea258ad3 2234#endif
e6ed776f
GRG
2235{
2236 /* variables stored in the XpmAttributes structure */
2237 Visual *visual;
2238 Colormap colormap;
2239 unsigned int depth;
2240 int bitmap_format;
2241 XpmFreeColorsFunc freeColors;
2242 void *closure;
2243
2244 /* variables to return */
2245 XImage *ximage = NULL;
2246 XImage *shapeimage = NULL;
2247 unsigned int mask_pixel_index = XpmUndefPixel;
2248
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;
2262
2263 unsigned int cmts;
2264 int ErrorStatus;
2265 xpmHashTable hashtable;
2266
2267
2268 /* initialize return values */
2269 if (image_return)
2270 *image_return = NULL;
2271 if (shapeimage_return)
2272 *shapeimage_return = NULL;
2273
2274
2275 /* retrieve information from the XpmAttributes */
2276 if (attributes && (attributes->valuemask & XpmVisual))
2277 visual = attributes->visual;
2278 else
2279 visual = XDefaultVisual(display, XDefaultScreen(display));
2280
2281 if (attributes && (attributes->valuemask & XpmColormap))
2282 colormap = attributes->colormap;
2283 else
2284 colormap = XDefaultColormap(display, XDefaultScreen(display));
2285
2286 if (attributes && (attributes->valuemask & XpmDepth))
2287 depth = attributes->depth;
2288 else
2289 depth = XDefaultDepth(display, XDefaultScreen(display));
2290
2291 if (attributes && (attributes->valuemask & XpmBitmapFormat))
2292 bitmap_format = attributes->bitmap_format;
2293 else
2294 bitmap_format = ZPixmap;
2295
2296 if (attributes && (attributes->valuemask & XpmFreeColors))
2297 freeColors = attributes->free_colors;
2298 else
2299 freeColors = FreeColors;
2300 if (attributes && (attributes->valuemask & XpmColorClosure))
2301 closure = attributes->color_closure;
2302 else
2303 closure = NULL;
2304
2305 cmts = info && (info->valuemask & XpmReturnComments);
2306
2307 /*
2308 * parse the header
2309 */
2310 ErrorStatus = xpmParseHeader(data);
2311 if (ErrorStatus != XpmSuccess)
2312 return (ErrorStatus);
2313
2314 /*
2315 * read values
2316 */
2317 ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
2318 &x_hotspot, &y_hotspot, &hotspot,
2319 &extensions);
2320 if (ErrorStatus != XpmSuccess)
2321 return (ErrorStatus);
2322
2323 /*
2324 * store the hints comment line
2325 */
2326 if (cmts)
2327 xpmGetCmt(data, &hints_cmt);
2328
2329 /*
2330 * init the hastable
2331 */
2332 if (USE_HASHTABLE) {
2333 ErrorStatus = xpmHashTableInit(&hashtable);
2334 if (ErrorStatus != XpmSuccess)
2335 return (ErrorStatus);
2336 }
2337
2338 /*
2339 * read colors
2340 */
2341 ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
2342 if (ErrorStatus != XpmSuccess)
2343 RETURN(ErrorStatus);
2344
2345 /*
2346 * store the colors comment line
2347 */
2348 if (cmts)
2349 xpmGetCmt(data, &colors_cmt);
2350
2351 /* malloc pixels index tables */
2352 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2353 if (!image_pixels)
2354 RETURN(XpmNoMemory);
2355
2356 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2357 if (!mask_pixels)
2358 RETURN(XpmNoMemory);
2359
2360 /* maximum of allocated pixels will be the number of colors */
2361 alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2362 if (!alloc_pixels)
2363 RETURN(XpmNoMemory);
2364
2365 /* maximum of allocated pixels will be the number of colors */
2366 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
2367 if (!used_pixels)
2368 RETURN(XpmNoMemory);
2369
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,
2374 &nused_pixels);
2375
2376 if (ErrorStatus != XpmSuccess
2377 && (ErrorStatus < 0 || (attributes
2378 && (attributes->valuemask & XpmExactColors)
2379 && attributes->exactColors)))
2380 RETURN(ErrorStatus);
2381
2382 /* now create the ximage */
2383 if (image_return) {
2384 ErrorStatus = CreateXImage(display, visual, depth,
2385 (depth == 1 ? bitmap_format : ZPixmap),
2386 width, height, &ximage);
2387 if (ErrorStatus != XpmSuccess)
2388 RETURN(ErrorStatus);
2389
2390#if !defined(FOR_MSW) && !defined(AMIGA)
2391
2392 /*
2393 * set the XImage pointer function, to be used with XPutPixel,
2394 * to an internal optimized function
2395 */
2396
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;
2403 else
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;
2408 else
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;
2414 else
2415#endif
2416 if (ximage->bitmap_bit_order == MSBFirst)
2417 ximage->f.put_pixel = PutPixel32MSB;
2418 else
2419 ximage->f.put_pixel = PutPixel32LSB;
2420 else if ((ximage->bits_per_pixel | ximage->depth) == 1)
2421 ximage->f.put_pixel = PutPixel1;
2422 else
2423 ximage->f.put_pixel = PutPixel;
2424#endif /* not FOR_MSW && not AMIGA */
2425 }
2426
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);
2433
2434#if !defined(FOR_MSW) && !defined(AMIGA)
2435 if (shapeimage->bitmap_bit_order == MSBFirst)
2436 shapeimage->f.put_pixel = PutPixel1MSB;
2437 else
2438 shapeimage->f.put_pixel = PutPixel1LSB;
2439#endif
2440 }
2441
2442 /*
2443 * read pixels and put them in the XImage
2444 */
2445 ErrorStatus = ParseAndPutPixels(
2446#ifdef FOR_MSW
2447 display,
2448#endif
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);
2456 mask_pixels = NULL;
2457
2458 /*
2459 * free the hastable
2460 */
2461 if (ErrorStatus != XpmSuccess)
2462 RETURN(ErrorStatus)
2463 else if (USE_HASHTABLE)
2464 xpmHashTableFree(&hashtable);
2465
2466 /*
2467 * store the pixels comment line
2468 */
2469 if (cmts)
2470 xpmGetCmt(data, &pixels_cmt);
2471
2472 /*
2473 * parse extensions
2474 */
2475 if (info && (info->valuemask & XpmReturnExtensions))
2476 if (extensions) {
2477 ErrorStatus = xpmParseExtensions(data, &info->extensions,
2478 &info->nextensions);
2479 if (ErrorStatus != XpmSuccess)
2480 RETURN(ErrorStatus);
2481 } else {
2482 info->extensions = NULL;
2483 info->nextensions = 0;
2484 }
2485
2486 /*
2487 * store found informations in the XpmImage structure
2488 */
2489 image->width = width;
2490 image->height = height;
2491 image->cpp = cpp;
2492 image->ncolors = ncolors;
2493 image->colorTable = colorTable;
2494 image->data = NULL;
2495
2496 if (info) {
2497 if (cmts) {
2498 info->hints_cmt = hints_cmt;
2499 info->colors_cmt = colors_cmt;
2500 info->pixels_cmt = pixels_cmt;
2501 }
2502 if (hotspot) {
2503 info->x_hotspot = x_hotspot;
2504 info->y_hotspot = y_hotspot;
2505 info->valuemask |= XpmHotspot;
2506 }
2507 }
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)) {
2512/* end 3.2 bc */
2513 attributes->pixels = used_pixels;
2514 attributes->npixels = nused_pixels;
2515 attributes->mask_pixel = mask_pixel_index;
2516 } else
2517 XpmFree(used_pixels);
2518
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;
2523 } else
2524 XpmFree(alloc_pixels);
2525
2526 /* return created images */
2527 if (image_return)
2528 *image_return = ximage;
2529 if (shapeimage_return)
2530 *shapeimage_return = shapeimage;
2531
2532 return (XpmSuccess);
2533
2534/* exit point in case of error, free only locally allocated variables */
2535error:
2536 if (USE_HASHTABLE)
2537 xpmHashTableFree(&hashtable);
2538 if (colorTable)
2539 xpmFreeColorTable(colorTable, ncolors);
2540 if (hints_cmt)
2541 XpmFree(hints_cmt);
2542 if (colors_cmt)
2543 XpmFree(colors_cmt);
2544 if (pixels_cmt)
2545 XpmFree(pixels_cmt);
2546 if (ximage)
2547 XDestroyImage(ximage);
2548 if (shapeimage)
2549 XDestroyImage(shapeimage);
2550 if (image_pixels)
2551 XpmFree(image_pixels);
2552 if (mask_pixels)
2553 XpmFree(mask_pixels);
2554 if (nalloc_pixels)
2555 (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
2556 if (alloc_pixels)
2557 XpmFree(alloc_pixels);
2558 if (used_pixels)
2559 XpmFree(used_pixels);
2560
2561 return (ErrorStatus);
2562}
2563
ea258ad3
DW
2564#ifdef __OS2__
2565/* Visual Age cannot deal with old, non-ansi, code */
2566static int ParseAndPutPixels(
2567 Display* dc
2568, xpmData* data
2569, unsigned int width
2570, unsigned int height
2571, unsigned int ncolors
2572, unsigned int cpp
2573, XpmColor* colorTable
2574, xpmHashTable* hashtable
2575, XImage* image
2576, Pixel* image_pixels
2577, XImage* shapeimage
2578, Pixel* shape_pixels
2579)
2580#else
e6ed776f
GRG
2581static int
2582ParseAndPutPixels(
2583#ifdef FOR_MSW
2584 dc,
2585#endif
2586 data, width, height, ncolors, cpp, colorTable, hashtable,
2587 image, image_pixels, shapeimage, shape_pixels)
2588#ifdef FOR_MSW
2589 Display *dc;
2590#endif
2591 xpmData *data;
2592 unsigned int width;
2593 unsigned int height;
2594 unsigned int ncolors;
2595 unsigned int cpp;
2596 XpmColor *colorTable;
2597 xpmHashTable *hashtable;
2598 XImage *image;
2599 Pixel *image_pixels;
2600 XImage *shapeimage;
2601 Pixel *shape_pixels;
ea258ad3 2602#endif
e6ed776f
GRG
2603{
2604 unsigned int a, x, y;
ea258ad3
DW
2605#ifdef __OS2__
2606 HAB hab;
2607 HPS hps;
2608 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
2609 SIZEL sizl = {0, 0};
2610 POINTL point;
2611#endif
e6ed776f
GRG
2612
2613 switch (cpp) {
2614
2615 case (1): /* Optimize for single character
2616 * colors */
16a12a3d 2617 {
e6ed776f
GRG
2618 unsigned short colidx[256];
2619#ifdef FOR_MSW
2620 HDC shapedc;
2621 HBITMAP obm, sobm;
2622
2623 if ( shapeimage ) {
ea258ad3
DW
2624#ifdef __OS2__
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);
2628#else
e6ed776f
GRG
2629 shapedc = CreateCompatibleDC(*dc);
2630 sobm = SelectObject(shapedc, shapeimage->bitmap);
ea258ad3 2631#endif
e6ed776f
GRG
2632 } else {
2633 shapedc = NULL;
2634 }
ea258ad3
DW
2635#ifdef __OS2__
2636 obm = GpiSetBitmap(hps, image->bitmap);
2637#else
e6ed776f
GRG
2638 obm = SelectObject(*dc, image->bitmap);
2639#endif
2640
ea258ad3
DW
2641#endif
2642
e6ed776f
GRG
2643
2644 bzero((char *)colidx, 256 * sizeof(short));
2645 for (a = 0; a < ncolors; a++)
2646 colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
2647
2648 for (y = 0; y < height; y++) {
2649 xpmNextString(data);
2650 for (x = 0; x < width; x++) {
2651 int c = xpmGetC(data);
2652
2653 if (c > 0 && c < 256 && colidx[c] != 0) {
2654#ifndef FOR_MSW
2655 XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
2656 if (shapeimage)
2657 XPutPixel(shapeimage, x, y,
2658 shape_pixels[colidx[c] - 1]);
ea258ad3
DW
2659#else
2660#ifdef __OS2__
2661 point.x = x;
2662 point.y = y;
2663 GpiSetColor(hps, (LONG)image_pixels[colidx[c] - 1]);
2664 GpiSetPel(hps, &point);
e6ed776f
GRG
2665#else
2666 SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
ea258ad3 2667#endif
e6ed776f 2668 if (shapedc) {
ea258ad3
DW
2669#ifdef __OS2__
2670 point.x = x;
2671 point.y = y;
2672 GpiSetColor(hps, (LONG)shape_pixels[colidx[c] - 1]);
2673 GpiSetPel(hps, &point);
2674#else
e6ed776f 2675 SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
ea258ad3 2676#endif
16a12a3d 2677 }
e6ed776f
GRG
2678#endif
2679 } else
2680 return (XpmFileInvalid);
16a12a3d 2681 }
e6ed776f
GRG
2682 }
2683#ifdef FOR_MSW
2684 if ( shapedc ) {
ea258ad3
DW
2685#ifdef __OS2__
2686 GpiSetBitmap(hps, sobm);
2687 DevCloseDC(shapedc);
2688#else
e6ed776f
GRG
2689 SelectObject(shapedc, sobm);
2690 DeleteDC(shapedc);
ea258ad3 2691#endif
e6ed776f 2692 }
ea258ad3
DW
2693#ifdef __OS2__
2694 GpiSetBitmap(hps, obm);
2695#else
e6ed776f 2696 SelectObject(*dc, obm);
ea258ad3 2697#endif
e6ed776f 2698#endif
16a12a3d 2699 }
e6ed776f
GRG
2700 break;
2701
2702 case (2): /* Optimize for double character
2703 * colors */
16a12a3d 2704 {
e6ed776f
GRG
2705/* free all allocated pointers at all exits */
2706#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
2707if (cidx[f]) XpmFree(cidx[f]);}
2708
2709 /* array of pointers malloced by need */
2710 unsigned short *cidx[256];
2711 int char1;
2712
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 */
2720 FREE_CIDX;
2721 return (XpmNoMemory);
2722 }
2723 }
2724 cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
2725 }
2726
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) {
2735#ifndef FOR_MSW
2736 XPutPixel(image, x, y,
2737 image_pixels[cidx[cc1][cc2] - 1]);
2738 if (shapeimage)
2739 XPutPixel(shapeimage, x, y,
2740 shape_pixels[cidx[cc1][cc2] - 1]);
ea258ad3
DW
2741#else
2742#ifdef __OS2__
2743 *dc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
2744 hps = GpiCreatePS(hab, *dc, &sizl, GPIA_ASSOC | PU_PELS);
2745
2746 GpiSetBitmap(hps, image->bitmap);
2747 point.x = x;
2748 point.y = y;
2749 GpiSetColor(hps, (LONG)image_pixels[cidx[cc1][cc2] - 1]);
2750 GpiSetPel(hps, &point);
e6ed776f
GRG
2751#else
2752 SelectObject(*dc, image->bitmap);
2753 SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
ea258ad3 2754#endif
e6ed776f 2755 if (shapeimage) {
ea258ad3
DW
2756#ifdef __OS2__
2757 GpiSetBitmap(hps, shapeimage->bitmap);
2758 point.x = x;
2759 point.y = y;
2760 GpiSetColor(hps, (LONG)shape_pixels[cidx[cc1][cc2] - 1]);
2761 GpiSetPel(hps, &point);
2762#else
e6ed776f
GRG
2763 SelectObject(*dc, shapeimage->bitmap);
2764 SetPixel(*dc, x, y,
2765 shape_pixels[cidx[cc1][cc2] - 1]);
ea258ad3 2766#endif
e6ed776f
GRG
2767 }
2768#endif
2769 } else {
2770 FREE_CIDX;
2771 return (XpmFileInvalid);
16a12a3d 2772 }
e6ed776f
GRG
2773 } else {
2774 FREE_CIDX;
2775 return (XpmFileInvalid);
2776 }
16a12a3d 2777 }
e6ed776f
GRG
2778 }
2779 FREE_CIDX;
16a12a3d 2780 }
e6ed776f 2781 break;
16a12a3d 2782
e6ed776f
GRG
2783 default: /* Non-optimized case of long color
2784 * names */
2785 {
2786 char *s;
2787 char buf[BUFSIZ];
cfbe03c9 2788
e6ed776f
GRG
2789 buf[cpp] = '\0';
2790 if (USE_HASHTABLE) {
2791 xpmHashAtom *slot;
2792
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++)
2797 *s = xpmGetC(data);
2798 slot = xpmHashSlot(hashtable, buf);
2799 if (!*slot) /* no color matches */
2800 return (XpmFileInvalid);
2801#ifndef FOR_MSW
2802 XPutPixel(image, x, y,
2803 image_pixels[HashColorIndex(slot)]);
2804 if (shapeimage)
2805 XPutPixel(shapeimage, x, y,
2806 shape_pixels[HashColorIndex(slot)]);
ea258ad3
DW
2807#else
2808#ifdef __OS2__
2809 *dc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
2810 hps = GpiCreatePS(hab, *dc, &sizl, GPIA_ASSOC | PU_PELS);
2811
2812 GpiSetBitmap(hps, image->bitmap);
2813 point.x = x;
2814 point.y = y;
2815 GpiSetColor(hps, (LONG)image_pixels[HashColorIndex(slot)]);
2816 GpiSetPel(hps, &point);
e6ed776f
GRG
2817#else
2818 SelectObject(*dc, image->bitmap);
2819 SetPixel(*dc, x, y,
2820 image_pixels[HashColorIndex(slot)]);
ea258ad3 2821#endif
e6ed776f 2822 if (shapeimage) {
ea258ad3
DW
2823#ifdef __OS2__
2824 GpiSetBitmap(hps, shapeimage->bitmap);
2825 point.x = x;
2826 point.y = y;
2827 GpiSetColor(hps, (LONG)shape_pixels[HashColorIndex(slot)]);
2828 GpiSetPel(hps, &point);
2829#else
e6ed776f
GRG
2830 SelectObject(*dc, shapeimage->bitmap);
2831 SetPixel(*dc, x, y,
2832 shape_pixels[HashColorIndex(slot)]);
ea258ad3 2833#endif
e6ed776f
GRG
2834 }
2835#endif
2836 }
2837 }
2838 } else {
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++)
2843 *s = xpmGetC(data);
2844 for (a = 0; a < ncolors; a++)
2845 if (!strcmp(colorTable[a].string, buf))
2846 break;
2847 if (a == ncolors) /* no color matches */
2848 return (XpmFileInvalid);
2849#ifndef FOR_MSW
2850 XPutPixel(image, x, y, image_pixels[a]);
2851 if (shapeimage)
2852 XPutPixel(shapeimage, x, y, shape_pixels[a]);
ea258ad3
DW
2853#else
2854#ifdef __OS2__
2855 *dc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
2856 hps = GpiCreatePS(hab, *dc, &sizl, GPIA_ASSOC | PU_PELS);
2857
2858 GpiSetBitmap(hps, image->bitmap);
2859 point.x = x;
2860 point.y = y;
2861 GpiSetColor(hps, (LONG)image_pixels[a]);
2862 GpiSetPel(hps, &point);
e6ed776f
GRG
2863#else
2864 SelectObject(*dc, image->bitmap);
2865 SetPixel(*dc, x, y, image_pixels[a]);
ea258ad3 2866#endif
e6ed776f 2867 if (shapeimage) {
ea258ad3
DW
2868#ifdef __OS2__
2869 GpiSetBitmap(hps, image->bitmap);
2870 point.x = x;
2871 point.y = y;
2872 GpiSetColor(hps, (LONG)shape_pixels[a]);
2873 GpiSetPel(hps, &point);
2874#else
e6ed776f
GRG
2875 SelectObject(*dc, shapeimage->bitmap);
2876 SetPixel(*dc, x, y, shape_pixels[a]);
ea258ad3 2877#endif
e6ed776f
GRG
2878 }
2879#endif
2880 }
2881 }
2882 }
2883 }
2884 break;
2885 }
2886 return (XpmSuccess);
2887}