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