]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/xpm/create.c
changes to match listctrl.h changes (forgot to commit yesterday, sorry)
[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#ifndef FOR_MSW
225static int closeness_cmp(Const void* a, Const void* b)
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}
232#endif
233
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 */
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
250static int
251AllocColor(display, colormap, colorname, xcolor, closure)
252 Display *display;
253 Colormap colormap;
254 char *colorname;
255 XColor *xcolor;
256 void *closure; /* not used */
257#endif
258{
259 int status;
260 if (colorname)
261#ifdef __OS2__
262 if (!XParseColor(display, &colormap, colorname, xcolor))
263 return -1;
264 status = XAllocColor(display, &colormap, xcolor);
265#else
266 if (!XParseColor(display, colormap, colorname, xcolor))
267 return -1;
268 status = XAllocColor(display, colormap, xcolor);
269#endif
270 return status != 0 ? 1 : 0;
271}
272
273
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
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;
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;
308 Bool alloc_color;
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 }
318 if (attributes && (attributes->valuemask & XpmAllocCloseColors))
319 alloc_color = attributes->alloc_close_colors;
320 else
321 alloc_color = True;
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.
335 *
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)...
340 *
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.
345 *
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) {
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 {
409 if (n == ITERATIONS)
410 XUngrabServer(display);
411 XpmFree(closenesses);
412 *image_pixel = cols[c].pixel;
413 *mask_pixel = 1;
414 return (0);
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
427 if ((*allocColor)(display, colormap, NULL, col, closure)) {
428 *image_pixel = col->pixel;
429 *mask_pixel = 1;
430 alloc_pixels[(*nalloc_pixels)++] = col->pixel;
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
438 if (visual->class == DirectColor) {
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) && \
451 (attributes->red_closeness != 0 \
452 || attributes->green_closeness != 0 \
453 || attributes->blue_closeness != 0)))
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
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
488static int
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;
509#endif
510{
511 XColor xcolor;
512 int status;
513
514 if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
515 status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
516 if (status < 0) /* parse color failed */
517 return (1);
518
519 if (status == 0) {
520#ifndef FOR_MSW
521 if (USE_CLOSECOLOR)
522 return (SetCloseColor(display, colormap, visual, &xcolor,
523 image_pixel, mask_pixel,
524 alloc_pixels, nalloc_pixels,
525 attributes, cols, ncols,
526 allocColor, closure));
527 else
528#endif /* ndef FOR_MSW */
529 return (1);
530 } else
531 alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
532 *image_pixel = xcolor.pixel;
533#ifndef FOR_MSW
534 *mask_pixel = 1;
535#else
536#ifdef __OS2__
537 *mask_pixel = OS2RGB(0,0,0);
538#else
539 *mask_pixel = RGB(0,0,0);
540#endif
541#endif
542 used_pixels[(*nused_pixels)++] = xcolor.pixel;
543 } else {
544 *image_pixel = 0;
545#ifndef FOR_MSW
546 *mask_pixel = 0;
547#else
548#ifdef __OS2__
549 *mask_pixel = OS2RGB(255,255,255);
550#else
551 *mask_pixel = RGB(255,255,255);
552#endif
553#endif
554 /* store the color table index */
555 *mask_pixel_index = color_index;
556 }
557 return (0);
558}
559
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
577static int
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;
592#endif
593{
594 /* variables stored in the XpmAttributes structure */
595 Visual *visual;
596 Colormap colormap;
597 XpmColorSymbol *colorsymbols;
598 unsigned int numsymbols;
599 XpmAllocColorFunc allocColor;
600 void *closure;
601
602 char *colorname;
603 unsigned int color, key;
604 Bool pixel_defined;
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
628 if (attributes && (attributes->valuemask & XpmColormap))
629 colormap = attributes->colormap;
630 else
631 colormap = XDefaultColormap(display, XDefaultScreen(display));
632
633 if (attributes && (attributes->valuemask & XpmColorKey))
634 key = attributes->color_key;
635 else
636 key = xpmVisualType(visual);
637
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
647#ifndef FOR_MSW
648 if (USE_CLOSECOLOR) {
649 /* originally from SetCloseColor */
650#if 0
651 if (visual->class == DirectColor) {
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
665#ifndef AMIGA
666 ncols = visual->map_entries;
667#else
668 ncols = colormap->Count;
669#endif
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
696 for (color = 0; color < ncolors; color++, colors++,
697 image_pixels++, mask_pixels++) {
698 colorname = NULL;
699 pixel_defined = False;
700 defaults = (char **) colors;
701
702 /*
703 * look for a defined symbol
704 */
705 if (numsymbols) {
706
707 unsigned int n;
708
709 s = defaults[1];
710 for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
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 &&
727 !xpmstrcasecmp(symbol->value, defaults[def_index]))
728 break;
729 }
730 }
731 if (n != numsymbols) {
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 */
739
740 unsigned int k;
741
742 if (colorname) { /* colorname given as symbol value */
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))
748 pixel_defined = True;
749 else
750 ErrorStatus = XpmColorError;
751 }
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)) {
761 pixel_defined = True;
762 break;
763 } else
764 ErrorStatus = XpmColorError;
765 }
766 k--;
767 }
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)) {
777 pixel_defined = True;
778 break;
779 } else
780 ErrorStatus = XpmColorError;
781 }
782 k++;
783 }
784 if (!pixel_defined) {
785 if (cols)
786 XpmFree(cols);
787 return (XpmColorFailed);
788 }
789 } else {
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 */
794 if (symbol->value
795 && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
796 *mask_pixels = 0;
797 *mask_pixel_index = color;
798 } else
799 *mask_pixels = 1;
800 used_pixels[(*nused_pixels)++] = *image_pixels;
801 }
802 }
803 if (cols)
804 XpmFree(cols);
805 return (ErrorStatus);
806}
807
808
809/* default FreeColors function, simply call XFreeColors */
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
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 */
828#endif
829{
830 return XFreeColors(display, colormap, pixels, n, 0);
831}
832
833
834/* function call in case of error */
835#undef RETURN
836#define RETURN(status) \
837{ \
838 ErrorStatus = status; \
839 goto error; \
840}
841
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
852int
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;
860#endif
861{
862#ifdef __OS2__
863 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
864 HPS hps;
865 SIZEL sizl = {0, 0};
866#endif
867 /* variables stored in the XpmAttributes structure */
868 Visual *visual;
869 Colormap colormap;
870 unsigned int depth;
871 int bitmap_format;
872 XpmFreeColorsFunc freeColors;
873 void *closure;
874
875 /* variables to return */
876 XImage *ximage = NULL;
877 XImage *shapeimage = NULL;
878 unsigned int mask_pixel_index = XpmUndefPixel;
879 int ErrorStatus;
880
881 /* calculation variables */
882 Pixel *image_pixels = NULL;
883 Pixel *mask_pixels = NULL;
884 Pixel *alloc_pixels = NULL;
885 Pixel *used_pixels = NULL;
886 unsigned int nalloc_pixels = 0;
887 unsigned int nused_pixels = 0;
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
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
925 ErrorStatus = XpmSuccess;
926
927 /* malloc pixels index tables */
928 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
929 if (!image_pixels)
930 return (XpmNoMemory);
931
932 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
933 if (!mask_pixels)
934 RETURN(XpmNoMemory);
935
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);
940
941 /* maximum of allocated pixels will be the number of colors */
942 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
943 if (!used_pixels)
944 RETURN(XpmNoMemory);
945
946 /* get pixel colors, store them in index tables */
947 ErrorStatus = CreateColors(display, attributes, image->colorTable,
948 image->ncolors, image_pixels, mask_pixels,
949 &mask_pixel_index, alloc_pixels, &nalloc_pixels,
950 used_pixels, &nused_pixels);
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,
961 (depth == 1 ? bitmap_format : ZPixmap),
962 image->width, image->height, &ximage);
963 if (ErrorStatus != XpmSuccess)
964 RETURN(ErrorStatus);
965
966#ifndef FOR_MSW
967# ifndef AMIGA
968
969 /*
970 * set the ximage data using optimized functions for ZPixmap
971 */
972
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);
980 else if (ximage->bits_per_pixel == 16)
981 PutImagePixels16(ximage, image->width, image->height,
982 image->data, image_pixels);
983 else if (ximage->bits_per_pixel == 32)
984 PutImagePixels32(ximage, image->width, image->height,
985 image->data, image_pixels);
986 else
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
993#else /* FOR_MSW */
994 MSWPutImagePixels(display, ximage, image->width, image->height,
995 image->data, image_pixels);
996#endif
997 }
998 /* create the shape mask image */
999 if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
1000 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
1001 image->width, image->height, &shapeimage);
1002 if (ErrorStatus != XpmSuccess)
1003 RETURN(ErrorStatus);
1004
1005#ifndef FOR_MSW
1006# ifndef AMIGA
1007 PutImagePixels1(shapeimage, image->width, image->height,
1008 image->data, mask_pixels);
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,
1015 image->data, mask_pixels);
1016#endif
1017
1018 }
1019 XpmFree(image_pixels);
1020 XpmFree(mask_pixels);
1021
1022 /* if requested return used pixels in the XpmAttributes structure */
1023 if (attributes && (attributes->valuemask & XpmReturnPixels ||
1024/* 3.2 backward compatibility code */
1025 attributes->valuemask & XpmReturnInfos)) {
1026/* end 3.2 bc */
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;
1037 } else
1038 XpmFree(alloc_pixels);
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);
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);
1066}
1067
1068
1069/*
1070 * Create an XImage with its data
1071 */
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
1084static int
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;
1093#endif
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 */
1106 *image_return = XCreateImage(display, visual, depth, format, 0, 0,
1107 width, height, bitmap_pad, 0);
1108 if (!*image_return)
1109 return (XpmNoMemory);
1110
1111#if !defined(FOR_MSW) && !defined(AMIGA)
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
1122 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1123#endif
1124 return (XpmSuccess);
1125}
1126
1127#ifndef FOR_MSW
1128# ifndef AMIGA
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
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
1183static int
1184_XReverse_Bytes(bpt, nb)
1185 register unsigned char *bpt;
1186 register int nb;
1187#endif
1188{
1189 do {
1190 *bpt = _reverse_byte[*bpt];
1191 bpt++;
1192 } while (--nb > 0);
1193 return 0;
1194}
1195
1196
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
1201void
1202xpm_xynormalizeimagebits(bp, img)
1203 register unsigned char *bp;
1204 register XImage *img;
1205#endif
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
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
1236void
1237xpm_znormalizeimagebits(bp, img)
1238 register unsigned char *bp;
1239 register XImage *img;
1240#endif
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
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
1291static void
1292_putbits(src, dstoffset, numbits, dst)
1293 register char *src; /* address of source bit string */
1294 int dstoffset; /* bit offset into destination;
1295 * range is 0-31 */
1296 register int numbits; /* number of bits to copy to
1297 * destination */
1298 register char *dst; /* address of destination bit string */
1299#endif
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
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
1350static void
1351PutImagePixels(image, width, height, pixelindex, pixels)
1352 XImage *image;
1353 unsigned int width;
1354 unsigned int height;
1355 unsigned int *pixelindex;
1356 Pixel *pixels;
1357#endif
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
1423#if !defined(WORD64) && !defined(LONG64)
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 */
1429static unsigned long byteorderpixel = MSBFirst << 24;
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
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
1449static void
1450PutImagePixels32(image, width, height, pixelindex, pixels)
1451 XImage *image;
1452 unsigned int width;
1453 unsigned int height;
1454 unsigned int *pixelindex;
1455 Pixel *pixels;
1456#endif
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;
1470#if !defined(WORD64) && !defined(LONG64)
1471 if (*((char *) &byteorderpixel) == image->byte_order) {
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;
1507#if !defined(WORD64) && !defined(LONG64)
1508 if (*((char *) &byteorderpixel) == image->byte_order) {
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
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
1570static void
1571PutImagePixels16(image, width, height, pixelindex, pixels)
1572 XImage *image;
1573 unsigned int width;
1574 unsigned int height;
1575 unsigned int *pixelindex;
1576 Pixel *pixels;
1577#endif
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
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
1662static void
1663PutImagePixels8(image, width, height, pixelindex, pixels)
1664 XImage *image;
1665 unsigned int width;
1666 unsigned int height;
1667 unsigned int *pixelindex;
1668 Pixel *pixels;
1669#endif
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
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
1720static void
1721PutImagePixels1(image, width, height, pixelindex, pixels)
1722 XImage *image;
1723 unsigned int width;
1724 unsigned int height;
1725 unsigned int *pixelindex;
1726 Pixel *pixels;
1727#endif
1728{
1729 if (image->byte_order != image->bitmap_bit_order)
1730 PutImagePixels(image, width, height, pixelindex, pixels);
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
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
1845int
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;
1854#endif
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
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;
1901
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 }
1920
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 */
1930#else /* FOR_MSW part follows */
1931
1932#ifdef __OS2__
1933/* Visual Age cannot deal with old, non-ansi, code */
1934static void MSWPutImagePixels(
1935 Display* dc
1936, XImage* image
1937, unsigned int width
1938, unsigned int height
1939, unsigned int* pixelindex
1940, Pixel* pixels
1941)
1942#else
1943static void
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;
1951#endif
1952{
1953 unsigned int *data = pixelindex;
1954 unsigned int x, y;
1955 HBITMAP obm;
1956
1957#ifdef __OS2__
1958 POINTL point;
1959
1960 obm = GpiSetBitmap(*dc, image->bitmap);
1961#else
1962 obm = SelectObject(*dc, image->bitmap);
1963#endif
1964
1965 for (y = 0; y < height; y++) {
1966 for (x = 0; x < width; x++) {
1967#ifdef __OS2__
1968 point.x = x;
1969 point.y = y;
1970 GpiSetColor(*dc, (LONG)pixels[*(data++)]);
1971 GpiSetPel(*dc, &point);
1972#else
1973
1974 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
1975#endif
1976 }
1977 }
1978#ifdef __OS2__
1979 GpiSetBitmap(*dc, obm);
1980#else
1981 SelectObject(*dc, obm);
1982#endif
1983}
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;
1997{
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;
2116
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;
2131
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
2179/*
2180 * This function parses an Xpm file or data and directly create an XImage
2181 */
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
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;
2204#endif
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
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
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;
2572#endif
2573{
2574 unsigned int a, x, y;
2575#ifdef __OS2__
2576 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
2577 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
2578 SIZEL sizl = {0, 0};
2579 POINTL point;
2580#endif
2581
2582 switch (cpp) {
2583
2584 case (1): /* Optimize for single character
2585 * colors */
2586 {
2587 unsigned short colidx[256];
2588#ifdef FOR_MSW
2589 HDC shapedc;
2590 HBITMAP obm, sobm;
2591
2592 if ( shapeimage ) {
2593#ifdef __OS2__
2594 shapedc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
2595 *dc = GpiCreatePS(hab, shapedc, &sizl, GPIA_ASSOC | PU_PELS);
2596 sobm = GpiSetBitmap(*dc, shapeimage->bitmap);
2597#else
2598 shapedc = CreateCompatibleDC(*dc);
2599 sobm = SelectObject(shapedc, shapeimage->bitmap);
2600#endif
2601 } else {
2602 shapedc = NULL;
2603 }
2604#ifdef __OS2__
2605 obm = GpiSetBitmap(*dc, image->bitmap);
2606#else
2607 obm = SelectObject(*dc, image->bitmap);
2608#endif
2609
2610#endif
2611
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]);
2628#else
2629#ifdef __OS2__
2630 point.x = x;
2631 point.y = y;
2632 GpiSetColor(*dc, (LONG)image_pixels[colidx[c] - 1]);
2633 GpiSetPel(*dc, &point);
2634#else
2635 SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
2636#endif
2637 if (shapedc) {
2638#ifdef __OS2__
2639 point.x = x;
2640 point.y = y;
2641 GpiSetColor(*dc, (LONG)shape_pixels[colidx[c] - 1]);
2642 GpiSetPel(*dc, &point);
2643#else
2644 SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
2645#endif
2646 }
2647#endif
2648 } else
2649 return (XpmFileInvalid);
2650 }
2651 }
2652#ifdef FOR_MSW
2653 if ( shapedc ) {
2654#ifdef __OS2__
2655 GpiSetBitmap(*dc, sobm);
2656 GpiDestroyPS(*dc);
2657 DevCloseDC(shapedc);
2658#else
2659 SelectObject(shapedc, sobm);
2660 DeleteDC(shapedc);
2661#endif
2662 }
2663#ifdef __OS2__
2664 GpiSetBitmap(*dc, obm);
2665#else
2666 SelectObject(*dc, obm);
2667#endif
2668#endif
2669 }
2670 break;
2671
2672 case (2): /* Optimize for double character
2673 * colors */
2674 {
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;
2682#ifdef __OS2__
2683 HDC shapedc;
2684#endif
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]);
2714#else
2715#ifdef __OS2__
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);
2724#else
2725 SelectObject(*dc, image->bitmap);
2726 SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
2727#endif
2728 if (shapeimage) {
2729#ifdef __OS2__
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);
2735#else
2736 SelectObject(*dc, shapeimage->bitmap);
2737 SetPixel(*dc, x, y,
2738 shape_pixels[cidx[cc1][cc2] - 1]);
2739#endif
2740 }
2741#endif
2742 } else {
2743 FREE_CIDX;
2744 return (XpmFileInvalid);
2745 }
2746 } else {
2747 FREE_CIDX;
2748 return (XpmFileInvalid);
2749 }
2750 }
2751 }
2752 FREE_CIDX;
2753 }
2754 break;
2755
2756 default: /* Non-optimized case of long color
2757 * names */
2758 {
2759 char *s;
2760 char buf[BUFSIZ];
2761#ifdef __OS2__
2762 HDC shapedc;
2763#endif
2764
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)]);
2783#else
2784#ifdef __OS2__
2785
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);
2794#else
2795 SelectObject(*dc, image->bitmap);
2796 SetPixel(*dc, x, y,
2797 image_pixels[HashColorIndex(slot)]);
2798#endif
2799 if (shapeimage) {
2800#ifdef __OS2__
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);
2806#else
2807 SelectObject(*dc, shapeimage->bitmap);
2808 SetPixel(*dc, x, y,
2809 shape_pixels[HashColorIndex(slot)]);
2810#endif
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]);
2830#else
2831#ifdef __OS2__
2832
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);
2841#else
2842 SelectObject(*dc, image->bitmap);
2843 SetPixel(*dc, x, y, image_pixels[a]);
2844#endif
2845 if (shapeimage) {
2846#ifdef __OS2__
2847 GpiSetBitmap(*dc, image->bitmap);
2848 point.x = x;
2849 point.y = y;
2850 GpiSetColor(*dc, (LONG)shape_pixels[a]);
2851 GpiSetPel(*dc, &point);
2852#else
2853 SelectObject(*dc, shapeimage->bitmap);
2854 SetPixel(*dc, x, y, shape_pixels[a]);
2855#endif
2856 }
2857#endif
2858 }
2859 }
2860 }
2861 }
2862 break;
2863 }
2864 return (XpmSuccess);
2865}