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