]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/xpm/create.c
detabified
[wxWidgets.git] / src / xpm / create.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 1989-95 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26/*****************************************************************************\
27* create.c: *
28* *
29* XPM library *
30* Create an X image and possibly its related shape mask *
31* from the given XpmImage. *
32* *
33* Developed by Arnaud Le Hors *
34\*****************************************************************************/
35
36/*
37 * The code related to FOR_MSW has been added by
38 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
39 */
40
41/*
42 * The code related to AMIGA has been added by
43 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
44 */
45
46#include "XpmI.h"
47#include <ctype.h>
48
49LFUNC(xpmVisualType, int, (Visual *visual));
50
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
56#ifndef FOR_MSW
57LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
58 Visual *visual, XColor *col,
59 Pixel *image_pixel, Pixel *mask_pixel,
60 Pixel *alloc_pixels, unsigned int *nalloc_pixels,
61 XpmAttributes *attributes, XColor *cols, int ncols,
62 XpmAllocColorFunc allocColor, void *closure));
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,
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));
75
76LFUNC(CreateXImage, int, (Display *display, Visual *visual,
77 unsigned int depth, int format, unsigned int width,
78 unsigned int height, XImage **image_return));
79
80LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
81 XpmColor *colors, unsigned int ncolors,
82 Pixel *image_pixels, Pixel *mask_pixels,
83 unsigned int *mask_pixel_index,
84 Pixel *alloc_pixels, unsigned int *nalloc_pixels,
85 Pixel *used_pixels, unsigned int *nused_pixels));
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
102
103#ifndef FOR_MSW
104# ifndef AMIGA
105/* XImage pixel routines */
106LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
107 unsigned int height, unsigned int *pixelindex,
108 Pixel *pixels));
109
110LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
111 unsigned int height, unsigned int *pixelindex,
112 Pixel *pixels));
113
114LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
115 unsigned int height, unsigned int *pixelindex,
116 Pixel *pixels));
117
118LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
119 unsigned int height, unsigned int *pixelindex,
120 Pixel *pixels));
121
122LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
123 unsigned int height, unsigned int *pixelindex,
124 Pixel *pixels));
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 */
143/* FOR_MSW pixel routine */
144LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,
145 unsigned int width, unsigned int height,
146 unsigned int *pixelindex, Pixel *pixels));
147#endif /* FOR_MSW */
148
149#ifdef NEED_STRCASECMP
150FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
151
152/*
153 * in case strcasecmp is not provided by the system here is one
154 * which does the trick
155 */
156#ifdef __OS2__
157/* Visual Age cannot deal with old, non-ansi, code */
158int xpmstrcasecmp(register char* s1, register char* s2)
159#else
160int
161xpmstrcasecmp(s1, s2)
162 register char *s1, *s2;
163#endif
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 */
183#ifdef __OS2__
184/* Visual Age cannot deal with old, non-ansi, code */
185static int xpmVisualType(Visual* visual)
186#else
187static int
188xpmVisualType(visual)
189 Visual *visual;
190#endif
191{
192#ifndef FOR_MSW
193# ifndef AMIGA
194 switch (visual->class) {
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 }
208# else
209 /* set the key explicitly in the XpmAttributes to override this */
210 return (XPM_COLOR);
211# endif
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
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
228static int
229closeness_cmp(a, b)
230 Const void *a, *b;
231#endif
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
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 */
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
255static int
256AllocColor(display, colormap, colorname, xcolor, closure)
257 Display *display;
258 Colormap colormap;
259 char *colorname;
260 XColor *xcolor;
261 void *closure; /* not used */
262#endif
263{
264 int status;
265 if (colorname)
266#ifdef __OS2__
267 if (!XParseColor(display, &colormap, colorname, xcolor))
268 return -1;
269 status = XAllocColor(display, &colormap, xcolor);
270#else
271 if (!XParseColor(display, colormap, colorname, xcolor))
272 return -1;
273 status = XAllocColor(display, colormap, xcolor);
274#endif
275 return status != 0 ? 1 : 0;
276}
277
278
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
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;
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;
313 Bool alloc_color;
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 }
323 if (attributes && (attributes->valuemask & XpmAllocCloseColors))
324 alloc_color = attributes->alloc_close_colors;
325 else
326 alloc_color = True;
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.
340 *
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)...
345 *
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.
350 *
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) {
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 {
414 if (n == ITERATIONS)
415 XUngrabServer(display);
416 XpmFree(closenesses);
417 *image_pixel = cols[c].pixel;
418 *mask_pixel = 1;
419 return (0);
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
432 if ((*allocColor)(display, colormap, NULL, col, closure)) {
433 *image_pixel = col->pixel;
434 *mask_pixel = 1;
435 alloc_pixels[(*nalloc_pixels)++] = col->pixel;
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
443 if (visual->class == DirectColor) {
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) && \
456 (attributes->red_closeness != 0 \
457 || attributes->green_closeness != 0 \
458 || attributes->blue_closeness != 0)))
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
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
493static int
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;
514#endif
515{
516 XColor xcolor;
517 int status;
518
519 if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
520 status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
521 if (status < 0) /* parse color failed */
522 return (1);
523
524 if (status == 0) {
525#ifndef FOR_MSW
526 if (USE_CLOSECOLOR)
527 return (SetCloseColor(display, colormap, visual, &xcolor,
528 image_pixel, mask_pixel,
529 alloc_pixels, nalloc_pixels,
530 attributes, cols, ncols,
531 allocColor, closure));
532 else
533#endif /* ndef FOR_MSW */
534 return (1);
535 } else
536 alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
537 *image_pixel = xcolor.pixel;
538#ifndef FOR_MSW
539 *mask_pixel = 1;
540#else
541#ifdef __OS2__
542 *mask_pixel = OS2RGB(0,0,0);
543#else
544 *mask_pixel = RGB(0,0,0);
545#endif
546#endif
547 used_pixels[(*nused_pixels)++] = xcolor.pixel;
548 } else {
549 *image_pixel = 0;
550#ifndef FOR_MSW
551 *mask_pixel = 0;
552#else
553#ifdef __OS2__
554 *mask_pixel = OS2RGB(255,255,255);
555#else
556 *mask_pixel = RGB(255,255,255);
557#endif
558#endif
559 /* store the color table index */
560 *mask_pixel_index = color_index;
561 }
562 return (0);
563}
564
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
582static int
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;
597#endif
598{
599 /* variables stored in the XpmAttributes structure */
600 Visual *visual;
601 Colormap colormap;
602 XpmColorSymbol *colorsymbols;
603 unsigned int numsymbols;
604 XpmAllocColorFunc allocColor;
605 void *closure;
606
607 char *colorname;
608 unsigned int color, key;
609 Bool pixel_defined;
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
633 if (attributes && (attributes->valuemask & XpmColormap))
634 colormap = attributes->colormap;
635 else
636 colormap = XDefaultColormap(display, XDefaultScreen(display));
637
638 if (attributes && (attributes->valuemask & XpmColorKey))
639 key = attributes->color_key;
640 else
641 key = xpmVisualType(visual);
642
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
652#ifndef FOR_MSW
653 if (USE_CLOSECOLOR) {
654 /* originally from SetCloseColor */
655#if 0
656 if (visual->class == DirectColor) {
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
670#ifndef AMIGA
671 ncols = visual->map_entries;
672#else
673 ncols = colormap->Count;
674#endif
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
701 for (color = 0; color < ncolors; color++, colors++,
702 image_pixels++, mask_pixels++) {
703 colorname = NULL;
704 pixel_defined = False;
705 defaults = (char **) colors;
706
707 /*
708 * look for a defined symbol
709 */
710 if (numsymbols) {
711
712 unsigned int n;
713
714 s = defaults[1];
715 for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
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 &&
732 !xpmstrcasecmp(symbol->value, defaults[def_index]))
733 break;
734 }
735 }
736 if (n != numsymbols) {
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 */
744
745 unsigned int k;
746
747 if (colorname) { /* colorname given as symbol value */
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))
753 pixel_defined = True;
754 else
755 ErrorStatus = XpmColorError;
756 }
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)) {
766 pixel_defined = True;
767 break;
768 } else
769 ErrorStatus = XpmColorError;
770 }
771 k--;
772 }
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)) {
782 pixel_defined = True;
783 break;
784 } else
785 ErrorStatus = XpmColorError;
786 }
787 k++;
788 }
789 if (!pixel_defined) {
790 if (cols)
791 XpmFree(cols);
792 return (XpmColorFailed);
793 }
794 } else {
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 */
799 if (symbol->value
800 && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
801 *mask_pixels = 0;
802 *mask_pixel_index = color;
803 } else
804 *mask_pixels = 1;
805 used_pixels[(*nused_pixels)++] = *image_pixels;
806 }
807 }
808 if (cols)
809 XpmFree(cols);
810 return (ErrorStatus);
811}
812
813
814/* default FreeColors function, simply call XFreeColors */
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
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 */
833#endif
834{
835 return XFreeColors(display, colormap, pixels, n, 0);
836}
837
838
839/* function call in case of error */
840#undef RETURN
841#define RETURN(status) \
842{ \
843 ErrorStatus = status; \
844 goto error; \
845}
846
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
857int
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;
865#endif
866{
867#ifdef __OS2__
868 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
869 HPS hps;
870 SIZEL sizl = {0, 0};
871#endif
872 /* variables stored in the XpmAttributes structure */
873 Visual *visual;
874 Colormap colormap;
875 unsigned int depth;
876 int bitmap_format;
877 XpmFreeColorsFunc freeColors;
878 void *closure;
879
880 /* variables to return */
881 XImage *ximage = NULL;
882 XImage *shapeimage = NULL;
883 unsigned int mask_pixel_index = XpmUndefPixel;
884 int ErrorStatus;
885
886 /* calculation variables */
887 Pixel *image_pixels = NULL;
888 Pixel *mask_pixels = NULL;
889 Pixel *alloc_pixels = NULL;
890 Pixel *used_pixels = NULL;
891 unsigned int nalloc_pixels = 0;
892 unsigned int nused_pixels = 0;
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
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
930 ErrorStatus = XpmSuccess;
931
932 /* malloc pixels index tables */
933 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
934 if (!image_pixels)
935 return (XpmNoMemory);
936
937 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
938 if (!mask_pixels)
939 RETURN(XpmNoMemory);
940
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);
945
946 /* maximum of allocated pixels will be the number of colors */
947 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
948 if (!used_pixels)
949 RETURN(XpmNoMemory);
950
951 /* get pixel colors, store them in index tables */
952 ErrorStatus = CreateColors(display, attributes, image->colorTable,
953 image->ncolors, image_pixels, mask_pixels,
954 &mask_pixel_index, alloc_pixels, &nalloc_pixels,
955 used_pixels, &nused_pixels);
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,
966 (depth == 1 ? bitmap_format : ZPixmap),
967 image->width, image->height, &ximage);
968 if (ErrorStatus != XpmSuccess)
969 RETURN(ErrorStatus);
970
971#ifndef FOR_MSW
972# ifndef AMIGA
973
974 /*
975 * set the ximage data using optimized functions for ZPixmap
976 */
977
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);
985 else if (ximage->bits_per_pixel == 16)
986 PutImagePixels16(ximage, image->width, image->height,
987 image->data, image_pixels);
988 else if (ximage->bits_per_pixel == 32)
989 PutImagePixels32(ximage, image->width, image->height,
990 image->data, image_pixels);
991 else
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
998#else /* FOR_MSW */
999 MSWPutImagePixels(display, ximage, image->width, image->height,
1000 image->data, image_pixels);
1001#endif
1002 }
1003 /* create the shape mask image */
1004 if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
1005 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
1006 image->width, image->height, &shapeimage);
1007 if (ErrorStatus != XpmSuccess)
1008 RETURN(ErrorStatus);
1009
1010#ifndef FOR_MSW
1011# ifndef AMIGA
1012 PutImagePixels1(shapeimage, image->width, image->height,
1013 image->data, mask_pixels);
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,
1020 image->data, mask_pixels);
1021#endif
1022
1023 }
1024 XpmFree(image_pixels);
1025 XpmFree(mask_pixels);
1026
1027 /* if requested return used pixels in the XpmAttributes structure */
1028 if (attributes && (attributes->valuemask & XpmReturnPixels ||
1029/* 3.2 backward compatibility code */
1030 attributes->valuemask & XpmReturnInfos)) {
1031/* end 3.2 bc */
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;
1042 } else
1043 XpmFree(alloc_pixels);
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);
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);
1071}
1072
1073
1074/*
1075 * Create an XImage with its data
1076 */
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
1089static int
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;
1098#endif
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 */
1111 *image_return = XCreateImage(display, visual, depth, format, 0, 0,
1112 width, height, bitmap_pad, 0);
1113 if (!*image_return)
1114 return (XpmNoMemory);
1115
1116#if !defined(FOR_MSW) && !defined(AMIGA)
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
1127 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1128#endif
1129 return (XpmSuccess);
1130}
1131
1132#ifndef FOR_MSW
1133# ifndef AMIGA
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
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
1188static int
1189_XReverse_Bytes(bpt, nb)
1190 register unsigned char *bpt;
1191 register int nb;
1192#endif
1193{
1194 do {
1195 *bpt = _reverse_byte[*bpt];
1196 bpt++;
1197 } while (--nb > 0);
1198 return 0;
1199}
1200
1201
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
1206void
1207xpm_xynormalizeimagebits(bp, img)
1208 register unsigned char *bp;
1209 register XImage *img;
1210#endif
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
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
1241void
1242xpm_znormalizeimagebits(bp, img)
1243 register unsigned char *bp;
1244 register XImage *img;
1245#endif
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
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
1296static void
1297_putbits(src, dstoffset, numbits, dst)
1298 register char *src; /* address of source bit string */
1299 int dstoffset; /* bit offset into destination;
1300 * range is 0-31 */
1301 register int numbits; /* number of bits to copy to
1302 * destination */
1303 register char *dst; /* address of destination bit string */
1304#endif
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
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
1355static void
1356PutImagePixels(image, width, height, pixelindex, pixels)
1357 XImage *image;
1358 unsigned int width;
1359 unsigned int height;
1360 unsigned int *pixelindex;
1361 Pixel *pixels;
1362#endif
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
1428#if !defined(WORD64) && !defined(LONG64)
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 */
1434static unsigned long byteorderpixel = MSBFirst << 24;
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
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
1454static void
1455PutImagePixels32(image, width, height, pixelindex, pixels)
1456 XImage *image;
1457 unsigned int width;
1458 unsigned int height;
1459 unsigned int *pixelindex;
1460 Pixel *pixels;
1461#endif
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;
1475#if !defined(WORD64) && !defined(LONG64)
1476 if (*((char *) &byteorderpixel) == image->byte_order) {
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;
1512#if !defined(WORD64) && !defined(LONG64)
1513 if (*((char *) &byteorderpixel) == image->byte_order) {
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
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
1575static void
1576PutImagePixels16(image, width, height, pixelindex, pixels)
1577 XImage *image;
1578 unsigned int width;
1579 unsigned int height;
1580 unsigned int *pixelindex;
1581 Pixel *pixels;
1582#endif
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
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
1667static void
1668PutImagePixels8(image, width, height, pixelindex, pixels)
1669 XImage *image;
1670 unsigned int width;
1671 unsigned int height;
1672 unsigned int *pixelindex;
1673 Pixel *pixels;
1674#endif
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
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
1725static void
1726PutImagePixels1(image, width, height, pixelindex, pixels)
1727 XImage *image;
1728 unsigned int width;
1729 unsigned int height;
1730 unsigned int *pixelindex;
1731 Pixel *pixels;
1732#endif
1733{
1734 if (image->byte_order != image->bitmap_bit_order)
1735 PutImagePixels(image, width, height, pixelindex, pixels);
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
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
1850int
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;
1859#endif
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
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;
1906
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 }
1925
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 */
1935#else /* FOR_MSW part follows */
1936
1937#ifdef __OS2__
1938/* Visual Age cannot deal with old, non-ansi, code */
1939static void MSWPutImagePixels(
1940 Display* dc
1941, XImage* image
1942, unsigned int width
1943, unsigned int height
1944, unsigned int* pixelindex
1945, Pixel* pixels
1946)
1947#else
1948static void
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;
1956#endif
1957{
1958 unsigned int *data = pixelindex;
1959 unsigned int x, y;
1960 HBITMAP obm;
1961
1962#ifdef __OS2__
1963 POINTL point;
1964
1965 obm = GpiSetBitmap(*dc, image->bitmap);
1966#else
1967 obm = SelectObject(*dc, image->bitmap);
1968#endif
1969
1970 for (y = 0; y < height; y++) {
1971 for (x = 0; x < width; x++) {
1972#ifdef __OS2__
1973 point.x = x;
1974 point.y = y;
1975 GpiSetColor(*dc, (LONG)pixels[*(data++)]);
1976 GpiSetPel(*dc, &point);
1977#else
1978
1979 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
1980#endif
1981 }
1982 }
1983#ifdef __OS2__
1984 GpiSetBitmap(*dc, obm);
1985#else
1986 SelectObject(*dc, obm);
1987#endif
1988}
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;
2002{
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;
2121
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;
2136
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
2184/*
2185 * This function parses an Xpm file or data and directly create an XImage
2186 */
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
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;
2209#endif
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
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
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;
2577#endif
2578{
2579 unsigned int a, x, y;
2580#ifdef __OS2__
2581 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
2582 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
2583 SIZEL sizl = {0, 0};
2584 POINTL point;
2585#endif
2586
2587 switch (cpp) {
2588
2589 case (1): /* Optimize for single character
2590 * colors */
2591 {
2592 unsigned short colidx[256];
2593#ifdef FOR_MSW
2594 HDC shapedc;
2595 HBITMAP obm, sobm;
2596
2597 if ( shapeimage ) {
2598#ifdef __OS2__
2599 shapedc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
2600 *dc = GpiCreatePS(hab, shapedc, &sizl, GPIA_ASSOC | PU_PELS);
2601 sobm = GpiSetBitmap(*dc, shapeimage->bitmap);
2602#else
2603 shapedc = CreateCompatibleDC(*dc);
2604 sobm = SelectObject(shapedc, shapeimage->bitmap);
2605#endif
2606 } else {
2607 shapedc = NULL;
2608 }
2609#ifdef __OS2__
2610 obm = GpiSetBitmap(*dc, image->bitmap);
2611#else
2612 obm = SelectObject(*dc, image->bitmap);
2613#endif
2614
2615#endif
2616
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]);
2633#else
2634#ifdef __OS2__
2635 point.x = x;
2636 point.y = y;
2637 GpiSetColor(*dc, (LONG)image_pixels[colidx[c] - 1]);
2638 GpiSetPel(*dc, &point);
2639#else
2640 SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
2641#endif
2642 if (shapedc) {
2643#ifdef __OS2__
2644 point.x = x;
2645 point.y = y;
2646 GpiSetColor(*dc, (LONG)shape_pixels[colidx[c] - 1]);
2647 GpiSetPel(*dc, &point);
2648#else
2649 SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
2650#endif
2651 }
2652#endif
2653 } else
2654 return (XpmFileInvalid);
2655 }
2656 }
2657#ifdef FOR_MSW
2658 if ( shapedc ) {
2659#ifdef __OS2__
2660 GpiSetBitmap(*dc, sobm);
2661 GpiDestroyPS(*dc);
2662 DevCloseDC(shapedc);
2663#else
2664 SelectObject(shapedc, sobm);
2665 DeleteDC(shapedc);
2666#endif
2667 }
2668#ifdef __OS2__
2669 GpiSetBitmap(*dc, obm);
2670#else
2671 SelectObject(*dc, obm);
2672#endif
2673#endif
2674 }
2675 break;
2676
2677 case (2): /* Optimize for double character
2678 * colors */
2679 {
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;
2687#ifdef __OS2__
2688 HDC shapedc;
2689#endif
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]);
2719#else
2720#ifdef __OS2__
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);
2729#else
2730 SelectObject(*dc, image->bitmap);
2731 SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
2732#endif
2733 if (shapeimage) {
2734#ifdef __OS2__
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);
2740#else
2741 SelectObject(*dc, shapeimage->bitmap);
2742 SetPixel(*dc, x, y,
2743 shape_pixels[cidx[cc1][cc2] - 1]);
2744#endif
2745 }
2746#endif
2747 } else {
2748 FREE_CIDX;
2749 return (XpmFileInvalid);
2750 }
2751 } else {
2752 FREE_CIDX;
2753 return (XpmFileInvalid);
2754 }
2755 }
2756 }
2757 FREE_CIDX;
2758 }
2759 break;
2760
2761 default: /* Non-optimized case of long color
2762 * names */
2763 {
2764 char *s;
2765 char buf[BUFSIZ];
2766#ifdef __OS2__
2767 HDC shapedc;
2768#endif
2769
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)]);
2788#else
2789#ifdef __OS2__
2790
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);
2799#else
2800 SelectObject(*dc, image->bitmap);
2801 SetPixel(*dc, x, y,
2802 image_pixels[HashColorIndex(slot)]);
2803#endif
2804 if (shapeimage) {
2805#ifdef __OS2__
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);
2811#else
2812 SelectObject(*dc, shapeimage->bitmap);
2813 SetPixel(*dc, x, y,
2814 shape_pixels[HashColorIndex(slot)]);
2815#endif
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]);
2835#else
2836#ifdef __OS2__
2837
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);
2846#else
2847 SelectObject(*dc, image->bitmap);
2848 SetPixel(*dc, x, y, image_pixels[a]);
2849#endif
2850 if (shapeimage) {
2851#ifdef __OS2__
2852 GpiSetBitmap(*dc, image->bitmap);
2853 point.x = x;
2854 point.y = y;
2855 GpiSetColor(*dc, (LONG)shape_pixels[a]);
2856 GpiSetPel(*dc, &point);
2857#else
2858 SelectObject(*dc, shapeimage->bitmap);
2859 SetPixel(*dc, x, y, shape_pixels[a]);
2860#endif
2861 }
2862#endif
2863 }
2864 }
2865 }
2866 }
2867 break;
2868 }
2869 return (XpmSuccess);
2870}