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