]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/create.c
declared (not implemented yet) wxMimeTypesManager::AddFallbacks()
[wxWidgets.git] / src / xpm / create.c
CommitLineData
cfbe03c9
JS
1/*
2 * Copyright (C) 1989-94 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 xpmInternAttrib. *
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#include "xpm34p.h"
42#ifdef VMS
43#include "sys$library:ctype.h"
44#else
45#include <ctype.h>
46#endif
47
48LFUNC(xpmVisualType, int, (Visual *visual));
49
50#ifndef FOR_MSW
51LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
52 Visual *visual, XColor *col,
53 Pixel *image_pixel, Pixel *mask_pixel,
54 Pixel **pixels, unsigned int *npixels,
55 XpmAttributes *attributes,
56 XColor *cols, int ncols));
57#else
58/* let the window system take care of close colors */
59#endif
60
61LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
62 char *colorname, unsigned int color_index,
63 Pixel *image_pixel, Pixel *mask_pixel,
64 unsigned int *mask_pixel_index, Pixel **pixels,
65 unsigned int *npixels, XpmAttributes *attributes,
66 XColor *cols, int ncols));
67
68LFUNC(CreateXImage, int, (Display *display, Visual *visual,
69 unsigned int depth, unsigned int width,
70 unsigned int height, XImage **image_return));
71
72LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
73 XpmColor *ct, unsigned int ncolors, Pixel *ip,
74 Pixel *mp, unsigned int *mask_pixel,
75 Pixel **pixels, unsigned int *npixels));
76
77#ifndef FOR_MSW
78/* XImage pixel routines */
79LFUNC(SetImagePixels, void, (XImage *image, unsigned int width,
80 unsigned int height, unsigned int *pixelindex,
81 Pixel *pixels));
82
83LFUNC(SetImagePixels32, void, (XImage *image, unsigned int width,
84 unsigned int height, unsigned int *pixelindex,
85 Pixel *pixels));
86
87LFUNC(SetImagePixels16, void, (XImage *image, unsigned int width,
88 unsigned int height, unsigned int *pixelindex,
89 Pixel *pixels));
90
91LFUNC(SetImagePixels8, void, (XImage *image, unsigned int width,
92 unsigned int height, unsigned int *pixelindex,
93 Pixel *pixels));
94
95LFUNC(SetImagePixels1, void, (XImage *image, unsigned int width,
96 unsigned int height, unsigned int *pixelindex,
97 Pixel *pixels));
98#else /* ndef FOR_MSW */
99/* FOR_MSW pixel routine */
100LFUNC(MSWSetImagePixels, void, (Display *dc, XImage *image,
101 unsigned int width, unsigned int height,
102 unsigned int *pixelindex, Pixel *pixels));
103#endif /* ndef FOR_MSW */
104
105#ifdef NEED_STRCASECMP
106FUNC(strcasecmp, int, (char *s1, char *s2));
107
108/*
109 * in case strcasecmp is not provided by the system here is one
110 * which does the trick
111 */
112int
113strcasecmp(register char *s1, register char *s2)
114{
115 register int c1, c2;
116
117 while (*s1 && *s2) {
118 c1 = tolower(*s1);
119 c2 = tolower(*s2);
120 if (c1 != c2)
121 return (c1 - c2);
122 s1++;
123 s2++;
124 }
125 return (int) (*s1 - *s2);
126}
127
128#endif
129
130/*
131 * return the default color key related to the given visual
132 */
133static int
134xpmVisualType(Visual *visual)
135{
136#ifndef FOR_MSW
137/* Xlib.h defines this to be c_class or class, depending
138 * on whether we're doing C++ or C
139 */
140#if defined(__cplusplus) || defined(c_plusplus)
141 switch (visual->c_class)
142#else
143 switch (visual->class)
144#endif
145 {
146 case StaticGray:
147 case GrayScale:
148 switch (visual->map_entries) {
149 case 2:
150 return (XPM_MONO);
151 case 4:
152 return (XPM_GRAY4);
153 default:
154 return (XPM_GRAY);
155 }
156 default:
157 return (XPM_COLOR);
158 }
159#else
160 /* there should be a similar switch for MSW */
161 return (XPM_COLOR);
162#endif
163}
164
165
166typedef struct {
167 int cols_index;
168 long closeness;
169} CloseColor;
170
171static int
172closeness_cmp(const void *a, const void *b)
173{
174 CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b;
175
176 /* cast to int as qsort requires */
177 return (int) (x->closeness - y->closeness);
178}
179
180#ifndef FOR_MSW
181/*
182 * set a close color in case the exact one can't be set
183 * return 0 if success, 1 otherwise.
184 */
185
186static int
187SetCloseColor(Display *display, Colormap colormap, Visual *visual, XColor *col,
188 Pixel *image_pixel, Pixel *mask_pixel, Pixel **pixels, unsigned int *npixels, XpmAttributes *attributes,
189 XColor *cols, int ncols)
190{
191
192 /*
193 * Allocation failed, so try close colors. To get here the visual must
194 * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
195 * What about sharing systems like QDSS?). Beware: we have to treat
196 * DirectColor differently.
197 */
198
199
200 long int red_closeness, green_closeness, blue_closeness;
201 int n;
202
203 if (attributes && (attributes->valuemask & XpmCloseness))
204 red_closeness = green_closeness = blue_closeness =
205 attributes->closeness;
206 else {
207 red_closeness = attributes->red_closeness;
208 green_closeness = attributes->green_closeness;
209 blue_closeness = attributes->blue_closeness;
210 }
211
212
213 /*
214 * We sort the colormap by closeness and try to allocate the color
215 * closest to the target. If the allocation of this close color fails,
216 * which almost never happens, then one of two scenarios is possible.
217 * Either the colormap must have changed (since the last close color
218 * allocation or possibly while we were sorting the colormap), or the
219 * color is allocated as Read/Write by some other client. (Note: X
220 * _should_ allow clients to check if a particular color is Read/Write,
221 * but it doesn't! :-( ). We cannot determine which of these scenarios
222 * occurred, so we try the next closest color, and so on, until no more
223 * colors are within closeness of the target. If we knew that the
224 * colormap had changed, we could skip this sequence.
225 *
226 * If _none_ of the colors within closeness of the target can be allocated,
227 * then we can finally be pretty sure that the colormap has actually
228 * changed. In this case we try to allocate the original color (again),
229 * then try the closecolor stuff (again)...
230 *
231 * In theory it would be possible for an infinite loop to occur if another
232 * process kept changing the colormap every time we sorted it, so we set
233 * a maximum on the number of iterations. After this many tries, we use
234 * XGrabServer() to ensure that the colormap remains unchanged.
235 *
236 * This approach gives particularly bad worst case performance - as many as
237 * <MaximumIterations> colormap reads and sorts may be needed, and as
238 * many as <MaximumIterations> * <ColormapSize> attempted allocations
239 * may fail. On an 8-bit system, this means as many as 3 colormap reads,
240 * 3 sorts and 768 failed allocations per execution of this code!
241 * Luckily, my experiments show that in general use in a typical 8-bit
242 * color environment only about 1 in every 10000 allocations fails to
243 * succeed in the fastest possible time. So virtually every time what
244 * actually happens is a single sort followed by a successful allocate.
245 * The very first allocation also costs a colormap read, but no further
246 * reads are usually necessary.
247 */
248
249#define ITERATIONS 2 /* more than one is almost never
250 * necessary */
251
252 for (n = 0; n <= ITERATIONS; ++n) {
253 CloseColor *closenesses =
254 (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
255 int i, c;
256
257 for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */
258#define COLOR_FACTOR 3
259#define BRIGHTNESS_FACTOR 1
260
261 closenesses[i].cols_index = i;
262 closenesses[i].closeness =
263 COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red)
264 + abs((long) col->green - (long) cols[i].green)
265 + abs((long) col->blue - (long) cols[i].blue))
266 + BRIGHTNESS_FACTOR * abs(((long) col->red +
267 (long) col->green +
268 (long) col->blue)
269 - ((long) cols[i].red +
270 (long) cols[i].green +
271 (long) cols[i].blue));
272 }
273 qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
274
275 i = 0;
276 c = closenesses[i].cols_index;
277 while ((long) cols[c].red >= (long) col->red - red_closeness &&
278 (long) cols[c].red <= (long) col->red + red_closeness &&
279 (long) cols[c].green >= (long) col->green - green_closeness &&
280 (long) cols[c].green <= (long) col->green + green_closeness &&
281 (long) cols[c].blue >= (long) col->blue - blue_closeness &&
282 (long) cols[c].blue <= (long) col->blue + blue_closeness) {
283 if (XAllocColor(display, colormap, &cols[c])) {
284 if (n == ITERATIONS)
285 XUngrabServer(display);
286 XpmFree(closenesses);
287 *image_pixel = cols[c].pixel;
288 *mask_pixel = 1;
289 (*pixels)[*npixels] = cols[c].pixel;
290 (*npixels)++;
291 return (0);
292 } else {
293 ++i;
294 if (i == ncols)
295 break;
296 c = closenesses[i].cols_index;
297 }
298 }
299
300 /* Couldn't allocate _any_ of the close colors! */
301
302 if (n == ITERATIONS)
303 XUngrabServer(display);
304 XpmFree(closenesses);
305
306 if (i == 0 || i == ncols) /* no color close enough or cannot */
307 return (1); /* alloc any color (full of r/w's) */
308
309 if (XAllocColor(display, colormap, col)) {
310 *image_pixel = col->pixel;
311 *mask_pixel = 1;
312 (*pixels)[*npixels] = col->pixel;
313 (*npixels)++;
314 return (0);
315 } else { /* colormap has probably changed, so
316 * re-read... */
317 if (n == ITERATIONS - 1)
318 XGrabServer(display);
319
320#if 0
321 if (visual->c_class == DirectColor) {
322 /* TODO */
323 } else
324#endif
325 XQueryColors(display, colormap, cols, ncols);
326 }
327 }
328 return (1);
329}
330
331#define USE_CLOSECOLOR attributes && \
332(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
333 || ((attributes->valuemask & XpmRGBCloseness) && \
334 attributes->red_closeness != 0 \
335 && attributes->green_closeness != 0 \
336 && attributes->blue_closeness != 0))
337
338#else
339 /* FOR_MSW part */
340 /* nothing to do here, the window system does it */
341#endif
342
343/*
344 * set the color pixel related to the given colorname,
345 * return 0 if success, 1 otherwise.
346 */
347
348static int
349SetColor(Display *display, Colormap colormap, Visual *visual, char *colorname, unsigned int color_index,
350 Pixel *image_pixel, Pixel *mask_pixel, unsigned int *mask_pixel_index,
351 Pixel **pixels, unsigned int *npixels, XpmAttributes *attributes, XColor *cols, int ncols)
352{
353 XColor xcolor;
354
355 if (strcasecmp(colorname, TRANSPARENT_COLOR)) {
356#ifdef wx_msw
357 if (!XParseColor(display, (Colormap *)colormap, colorname, &xcolor))
358#else
359 if (!XParseColor(display, (Colormap)colormap, colorname, &xcolor))
360#endif
361 return (1);
362#ifdef wx_msw
363 if (!XAllocColor(display, (Colormap *)colormap, &xcolor)) {
364#else
365 if (!XAllocColor(display, (Colormap)colormap, &xcolor)) {
366#endif
367#ifndef FOR_MSW
368 if (USE_CLOSECOLOR)
369 return (SetCloseColor(display, colormap, visual, &xcolor,
370 image_pixel, mask_pixel, pixels, npixels,
371 attributes, cols, ncols));
372 else
373#endif /* ndef FOR_MSW */
374 return (1);
375 }
376 *image_pixel = xcolor.pixel;
377 *mask_pixel = 1;
378 (*pixels)[*npixels] = xcolor.pixel;
379 (*npixels)++;
380 } else {
381 *image_pixel = 0;
382 *mask_pixel = 0;
383 *mask_pixel_index = color_index; /* store the color table index */
384 }
385 return (0);
386}
387
388
389static int
390CreateColors(Display *display, XpmAttributes *attributes, XpmColor *ct, unsigned int ncolors,
391 Pixel *ip, Pixel *mp, unsigned int *mask_pixel, Pixel **pixels, unsigned int *npixels)
392{
393 /* variables stored in the XpmAttributes structure */
394 Visual *visual;
395 Colormap colormap;
396 XpmColorSymbol *colorsymbols;
397 unsigned int numsymbols;
398
399 char *colorname;
400 unsigned int a, b, l;
401 int pixel_defined;
402 unsigned int key;
403 XpmColorSymbol *symbol;
404 char **defaults;
405 int ErrorStatus = XpmSuccess;
406 char *s;
407 int default_index;
408
409 XColor *cols = NULL;
410 unsigned int ncols = 0;
411
412 /*
413 * retrieve information from the XpmAttributes
414 */
415 if (attributes && attributes->valuemask & XpmColorSymbols) {
416 colorsymbols = attributes->colorsymbols;
417 numsymbols = attributes->numsymbols;
418 } else
419 numsymbols = 0;
420
421 if (attributes && attributes->valuemask & XpmVisual)
422 visual = attributes->visual;
423 else
424 visual = XDefaultVisual(display, XDefaultScreen(display));
425
426 if (attributes && attributes->valuemask & XpmColormap)
427 colormap = attributes->colormap;
428 else
429 colormap = XDefaultColormap(display, XDefaultScreen(display));
430
431 if (attributes && attributes->valuemask & XpmColorKey)
432 key = attributes->color_key;
433 else
434 key = xpmVisualType(visual);
435
436#ifndef FOR_MSW
437 if (USE_CLOSECOLOR) {
438 /* originally from SetCloseColor */
439#if 0
440 if (visual->c_class == DirectColor) {
441
442 /*
443 * TODO: Implement close colors for DirectColor visuals. This is
444 * difficult situation. Chances are that we will never get here,
445 * because any machine that supports DirectColor will probably
446 * also support TrueColor (and probably PseudoColor). Also,
447 * DirectColor colormaps can be very large, so looking for close
448 * colors may be too slow.
449 */
450 } else {
451#endif
452 int i;
453
454 ncols = visual->map_entries;
455 cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
456 for (i = 0; i < ncols; ++i)
457 cols[i].pixel = i;
458 XQueryColors(display, colormap, cols, ncols);
459#if 0
460 }
461#endif
462 }
463#endif /* ndef FOR_MSW */
464
465 switch (key) {
466 case XPM_MONO:
467 default_index = 2;
468 break;
469 case XPM_GRAY4:
470 default_index = 3;
471 break;
472 case XPM_GRAY:
473 default_index = 4;
474 break;
475 case XPM_COLOR:
476 default:
477 default_index = 5;
478 break;
479 }
480
481 for (a = 0; a < ncolors; a++, ct++, ip++, mp++) {
482 colorname = NULL;
483 pixel_defined = False;
484 defaults = (char **) ct;
485
486 /*
487 * look for a defined symbol
488 */
489 if (numsymbols) {
490 s = defaults[1];
491 for (l = 0, symbol = colorsymbols; l < numsymbols; l++, symbol++) {
492 if (symbol->name && s && !strcmp(symbol->name, s))
493 /* override name */
494 break;
495 if (!symbol->name && symbol->value) { /* override value */
496 int def_index = default_index;
497
498 while (defaults[def_index] == NULL) /* find defined
499 * colorname */
500 --def_index;
501 if (def_index < 2) {/* nothing towards mono, so try
502 * towards color */
503 def_index = default_index + 1;
504 while (def_index <= 5 && defaults[def_index] == NULL)
505 ++def_index;
506 }
507 if (def_index >= 2 && defaults[def_index] != NULL &&
508 !strcasecmp(symbol->value, defaults[def_index]))
509 break;
510 }
511 }
512 if (l != numsymbols) {
513 if (symbol->name && symbol->value)
514 colorname = symbol->value;
515 else
516 pixel_defined = True;
517 }
518 }
519 if (!pixel_defined) { /* pixel not given as symbol value */
520 if (colorname) { /* colorname given as symbol value */
521 if (!SetColor(display, colormap, visual, colorname, a, ip, mp,
522 mask_pixel, pixels, npixels, attributes,
523 cols, ncols))
524 pixel_defined = True;
525 else
526 ErrorStatus = XpmColorError;
527 }
528 b = key;
529 while (!pixel_defined && b > 1) {
530 if (defaults[b]) {
531 if (!SetColor(display, colormap, visual, defaults[b],
532 a, ip, mp, mask_pixel, pixels, npixels,
533 attributes, cols, ncols)) {
534 pixel_defined = True;
535 break;
536 } else
537 ErrorStatus = XpmColorError;
538 }
539 b--;
540 }
541 b = key + 1;
542 while (!pixel_defined && b < NKEYS + 1) {
543 if (defaults[b]) {
544 if (!SetColor(display, colormap, visual, defaults[b],
545 a, ip, mp, mask_pixel, pixels, npixels,
546 attributes, cols, ncols)) {
547 pixel_defined = True;
548 break;
549 } else
550 ErrorStatus = XpmColorError;
551 }
552 b++;
553 }
554 if (!pixel_defined) {
555 if (cols)
556 XpmFree(cols);
557 return (XpmColorFailed);
558 }
559 } else {
560 *ip = colorsymbols[l].pixel;
561 if (symbol->value
562 && !strcasecmp(symbol->value, TRANSPARENT_COLOR)) {
563 *mp = 0;
564 *mask_pixel = 0;
565 } else
566 *mp = 1;
567 }
568 }
569 if (cols)
570 XpmFree(cols);
571 return (ErrorStatus);
572}
573
574
575/* function call in case of error, frees only locally allocated variables */
576#undef RETURN
577#define RETURN(status) \
578{ \
579 if (ximage) XDestroyImage(ximage); \
580 if (shapeimage) XDestroyImage(shapeimage); \
581 if (ximage_pixels) XpmFree(ximage_pixels); \
582 if (mask_pixels) XpmFree(mask_pixels); \
583 if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \
584 if (pixels) XpmFree(pixels); \
585 return (status); \
586}
587
588int
589XpmCreateImageFromXpmImage(Display *display, XpmImage *image,
590 XImage **image_return, XImage **shapeimage_return, XpmAttributes *attributes)
591{
592 /* variables stored in the XpmAttributes structure */
593 Visual *visual;
594 Colormap colormap;
595 unsigned int depth;
596
597 /* variables to return */
598 XImage *ximage = NULL;
599 XImage *shapeimage = NULL;
600 unsigned int mask_pixel;
601 int ErrorStatus;
602
603 /* calculation variables */
604 Pixel *ximage_pixels = NULL;
605 Pixel *mask_pixels = NULL;
606 Pixel *pixels = NULL; /* allocated pixels */
607 unsigned int npixels = 0; /* number of allocated pixels */
608
609 /* initialize return values */
610 if (image_return)
611 *image_return = NULL;
612 if (shapeimage_return)
613 *shapeimage_return = NULL;
614
615 /* retrieve information from the XpmAttributes */
616 if (attributes && (attributes->valuemask & XpmVisual))
617 visual = attributes->visual;
618 else
619 visual = XDefaultVisual(display, XDefaultScreen(display));
620
621 if (attributes && (attributes->valuemask & XpmColormap))
622 colormap = attributes->colormap;
623 else
624 colormap = XDefaultColormap(display, XDefaultScreen(display));
625
626 if (attributes && (attributes->valuemask & XpmDepth))
627 depth = attributes->depth;
628 else
629 depth = XDefaultDepth(display, XDefaultScreen(display));
630
631 ErrorStatus = XpmSuccess;
632
633 /* malloc pixels index tables */
634 ximage_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
635 if (!ximage_pixels)
636 return (XpmNoMemory);
637
638 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
639 if (!mask_pixels)
640 RETURN(XpmNoMemory);
641
642 mask_pixel = XpmUndefPixel;
643
644 /* maximum of allocated pixels will be the number of colors */
645 pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
646 if (!pixels)
647 RETURN(XpmNoMemory);
648
649 /* get pixel colors, store them in index tables */
650 ErrorStatus = CreateColors(display, attributes, image->colorTable,
651 image->ncolors, ximage_pixels, mask_pixels,
652 &mask_pixel, &pixels, &npixels);
653
654 if (ErrorStatus != XpmSuccess
655 && (ErrorStatus < 0 || (attributes
656 && (attributes->valuemask & XpmExactColors)
657 && attributes->exactColors)))
658 RETURN(ErrorStatus);
659
660 /* create the ximage */
661 if (image_return) {
662 ErrorStatus = CreateXImage(display, visual, depth,
663 image->width, image->height, &ximage);
664 if (ErrorStatus != XpmSuccess)
665 RETURN(ErrorStatus);
666
667#ifndef FOR_MSW
668
669 /*
670 * set the ximage data
671 *
672 * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use
673 * optimized functions, otherwise use slower but sure general one.
674 *
675 */
676
677 if (ximage->depth == 1)
678 SetImagePixels1(ximage, image->width, image->height,
679 image->data, ximage_pixels);
680 else if (ximage->bits_per_pixel == 8)
681 SetImagePixels8(ximage, image->width, image->height,
682 image->data, ximage_pixels);
683 else if (ximage->bits_per_pixel == 16)
684 SetImagePixels16(ximage, image->width, image->height,
685 image->data, ximage_pixels);
686 else if (ximage->bits_per_pixel == 32)
687 SetImagePixels32(ximage, image->width, image->height,
688 image->data, ximage_pixels);
689 else
690 SetImagePixels(ximage, image->width, image->height,
691 image->data, ximage_pixels);
692#else /* FOR_MSW */
693 MSWSetImagePixels(display, ximage, image->width, image->height,
694 image->data, ximage_pixels);
695#endif
696 }
697 /* create the shape mask image */
698 if (mask_pixel != XpmUndefPixel && shapeimage_return) {
699 ErrorStatus = CreateXImage(display, visual, 1, image->width,
700 image->height, &shapeimage);
701 if (ErrorStatus != XpmSuccess)
702 RETURN(ErrorStatus);
703
704#ifndef FOR_MSW
705 SetImagePixels1(shapeimage, image->width, image->height,
706 image->data, mask_pixels);
707#else
708 MSWSetImagePixels(display, shapeimage, image->width, image->height,
709 image->data, mask_pixels);
710#endif
711
712 }
713 XpmFree(mask_pixels);
714 XpmFree(pixels);
715
716 /* if requested store alloc'ed pixels in the XpmAttributes structure */
717 if (attributes) {
718 if (attributes->valuemask & XpmReturnPixels ||
719/* 3.2 backward compatibility code */
720 attributes->valuemask & XpmReturnInfos) {
721/* end 3.2 bc */
722 if (mask_pixel != XpmUndefPixel) {
723 Pixel *pixels, *p1, *p2;
724 unsigned int a;
725
726 attributes->npixels = image->ncolors - 1;
727 pixels = (Pixel *) XpmMalloc(sizeof(Pixel)
728 * attributes->npixels);
729 if (pixels) {
730 p1 = ximage_pixels;
731 p2 = pixels;
732 for (a = 0; a < image->ncolors; a++, p1++)
733 if (a != mask_pixel)
734 *p2++ = *p1;
735 attributes->pixels = pixels;
736 } else {
737 /* if error just say we can't return requested data */
738 attributes->valuemask &= ~XpmReturnPixels;
739/* 3.2 backward compatibility code */
740 attributes->valuemask &= ~XpmReturnInfos;
741/* end 3.2 bc */
742 attributes->pixels = NULL;
743 attributes->npixels = 0;
744 }
745 XpmFree(ximage_pixels);
746 } else {
747 attributes->pixels = ximage_pixels;
748 attributes->npixels = image->ncolors;
749 }
750 attributes->mask_pixel = mask_pixel;
751 } else
752 XpmFree(ximage_pixels);
753 } else
754 XpmFree(ximage_pixels);
755
756 /* return created images */
757 if (image_return)
758 *image_return = ximage;
759 if (shapeimage_return)
760 *shapeimage_return = shapeimage;
761
762 return (ErrorStatus);
763}
764
765
766/*
767 * Create an XImage
768 */
769static int
770CreateXImage(Display *display, Visual *visual, unsigned int depth,
771 unsigned int width, unsigned int height, XImage **image_return)
772{
773 int bitmap_pad;
774
775 /* first get bitmap_pad */
776 if (depth > 16)
777 bitmap_pad = 32;
778 else if (depth > 8)
779 bitmap_pad = 16;
780 else
781 bitmap_pad = 8;
782
783 /* then create the XImage with data = NULL and bytes_per_line = 0 */
784 *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0,
785 width, height, bitmap_pad, 0);
786 if (!*image_return)
787 return (XpmNoMemory);
788
789#ifndef FOR_MSW
790 /* now that bytes_per_line must have been set properly alloc data */
791 (*image_return)->data =
792 (char *) XpmMalloc((*image_return)->bytes_per_line * height);
793
794 if (!(*image_return)->data) {
795 XDestroyImage(*image_return);
796 *image_return = NULL;
797 return (XpmNoMemory);
798 }
799#else
800 /* under FOR_MSW XCreateImage has done it all */
801#endif
802 return (XpmSuccess);
803}
804
805#ifndef FOR_MSW
806/*
807 * The functions below are written from X11R5 MIT's code (XImUtil.c)
808 *
809 * The idea is to have faster functions than the standard XPutPixel function
810 * to build the image data. Indeed we can speed up things by suppressing tests
811 * performed for each pixel. We do the same tests but at the image level.
812 * We also assume that we use only ZPixmap images with null offsets.
813 */
814
815LFUNC(_putbits, void, (register char *src, int dstoffset,
816 register int numbits, register char *dst));
817
818LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb));
819
820static unsigned char Const _reverse_byte[0x100] = {
821 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
822 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
823 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
824 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
825 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
826 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
827 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
828 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
829 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
830 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
831 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
832 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
833 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
834 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
835 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
836 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
837 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
838 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
839 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
840 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
841 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
842 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
843 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
844 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
845 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
846 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
847 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
848 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
849 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
850 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
851 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
852 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
853};
854
855static int
856_XReverse_Bytes(register unsigned char *bpt, register int nb)
857{
858 do {
859 *bpt = _reverse_byte[*bpt];
860 bpt++;
861 } while (--nb > 0);
862 return 0;
863}
864
865
866void
867xpm_xynormalizeimagebits(register unsigned char *bp, register XImage *img)
868{
869 register unsigned char c;
870
871 if (img->byte_order != img->bitmap_bit_order) {
872 switch (img->bitmap_unit) {
873
874 case 16:
875 c = *bp;
876 *bp = *(bp + 1);
877 *(bp + 1) = c;
878 break;
879
880 case 32:
881 c = *(bp + 3);
882 *(bp + 3) = *bp;
883 *bp = c;
884 c = *(bp + 2);
885 *(bp + 2) = *(bp + 1);
886 *(bp + 1) = c;
887 break;
888 }
889 }
890 if (img->bitmap_bit_order == MSBFirst)
891 _XReverse_Bytes(bp, img->bitmap_unit >> 3);
892}
893
894void
895xpm_znormalizeimagebits(register unsigned char *bp, register XImage *img)
896{
897 register unsigned char c;
898
899 switch (img->bits_per_pixel) {
900
901 case 2:
902 _XReverse_Bytes(bp, 1);
903 break;
904
905 case 4:
906 *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
907 break;
908
909 case 16:
910 c = *bp;
911 *bp = *(bp + 1);
912 *(bp + 1) = c;
913 break;
914
915 case 24:
916 c = *(bp + 2);
917 *(bp + 2) = *bp;
918 *bp = c;
919 break;
920
921 case 32:
922 c = *(bp + 3);
923 *(bp + 3) = *bp;
924 *bp = c;
925 c = *(bp + 2);
926 *(bp + 2) = *(bp + 1);
927 *(bp + 1) = c;
928 break;
929 }
930}
931
932static unsigned char Const _lomask[0x09] = {
9330x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
934static unsigned char Const _himask[0x09] = {
9350xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
936
937static void
938_putbits(register char *src, int dstoffset, register int numbits, register char *dst)
939
940/* register char *src; */ /* address of source bit string */
941/* int dstoffset; */ /* bit offset into destination;
942 * range is 0-31 */
943/* register int numbits; */ /* number of bits to copy to
944 * destination */
945/* register char *dst; */ /* address of destination bit string */
946{
947 register unsigned char chlo, chhi;
948 int hibits;
949
950 dst = dst + (dstoffset >> 3);
951 dstoffset = dstoffset & 7;
952 hibits = 8 - dstoffset;
953 chlo = *dst & _lomask[dstoffset];
954 for (;;) {
955 chhi = (*src << dstoffset) & _himask[dstoffset];
956 if (numbits <= hibits) {
957 chhi = chhi & _lomask[dstoffset + numbits];
958 *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
959 break;
960 }
961 *dst = chhi | chlo;
962 dst++;
963 numbits = numbits - hibits;
964 chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
965 src++;
966 if (numbits <= dstoffset) {
967 chlo = chlo & _lomask[numbits];
968 *dst = (*dst & _himask[numbits]) | chlo;
969 break;
970 }
971 numbits = numbits - dstoffset;
972 }
973}
974
975/*
976 * Default method to write pixels into a Z image data structure.
977 * The algorithm used is:
978 *
979 * copy the destination bitmap_unit or Zpixel to temp
980 * normalize temp if needed
981 * copy the pixel bits into the temp
982 * renormalize temp if needed
983 * copy the temp back into the destination image data
984 */
985
986static void
987SetImagePixels(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels)
988{
989 register char *src;
990 register char *dst;
991 register unsigned int *iptr;
992 register int x, y, i;
993 register char *data;
994 Pixel pixel, px;
995 int nbytes, depth, ibu, ibpp;
996
997 data = image->data;
998 iptr = pixelindex;
999 depth = image->depth;
1000 if (depth == 1) {
1001 ibu = image->bitmap_unit;
1002 for (y = 0; y < height; y++)
1003 for (x = 0; x < width; x++, iptr++) {
1004 pixel = pixels[*iptr];
1005 for (i = 0, px = pixel; i < sizeof(unsigned long);
1006 i++, px >>= 8)
1007 ((unsigned char *) &pixel)[i] = px;
1008 src = &data[XYINDEX(x, y, image)];
1009 dst = (char *) &px;
1010 px = 0;
1011 nbytes = ibu >> 3;
1012 for (i = nbytes; --i >= 0;)
1013 *dst++ = *src++;
1014 XYNORMALIZE(&px, image);
1015 _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
1016 XYNORMALIZE(&px, image);
1017 src = (char *) &px;
1018 dst = &data[XYINDEX(x, y, image)];
1019 for (i = nbytes; --i >= 0;)
1020 *dst++ = *src++;
1021 }
1022 } else {
1023 ibpp = image->bits_per_pixel;
1024 for (y = 0; y < height; y++)
1025 for (x = 0; x < width; x++, iptr++) {
1026 pixel = pixels[*iptr];
1027 if (depth == 4)
1028 pixel &= 0xf;
1029 for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
1030 px >>= 8)
1031 ((unsigned char *) &pixel)[i] = px;
1032 src = &data[ZINDEX(x, y, image)];
1033 dst = (char *) &px;
1034 px = 0;
1035 nbytes = (ibpp + 7) >> 3;
1036 for (i = nbytes; --i >= 0;)
1037 *dst++ = *src++;
1038 ZNORMALIZE(&px, image);
1039 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1040 ZNORMALIZE(&px, image);
1041 src = (char *) &px;
1042 dst = &data[ZINDEX(x, y, image)];
1043 for (i = nbytes; --i >= 0;)
1044 *dst++ = *src++;
1045 }
1046 }
1047}
1048
1049/*
1050 * write pixels into a 32-bits Z image data structure
1051 */
1052
1053#ifndef WORD64
1054/* this item is static but deterministic so let it slide; doesn't
1055 * hurt re-entrancy of this library. Note if it is actually const then would
1056 * be OK under rules of ANSI-C but probably not C++ which may not
1057 * want to allocate space for it.
1058 */
1059static unsigned long /* constant */ RTXpm_byteorderpixel = MSBFirst << 24;
1060
1061#endif
1062
1063/*
1064 WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
1065 3.2e code - by default you get the speeded-up version.
1066*/
1067
1068static void
1069SetImagePixels32(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels)
1070{
1071 unsigned char *data;
1072 unsigned int *iptr;
1073 int y;
1074 Pixel pixel;
1075
1076#ifdef WITHOUT_SPEEDUPS
1077
1078 int x;
1079 unsigned char *addr;
1080
1081 data = (unsigned char *) image->data;
1082 iptr = pixelindex;
1083#ifndef WORD64
1084 if (*((char *) &RTXpm_byteorderpixel) == image->byte_order) {
1085 for (y = 0; y < height; y++)
1086 for (x = 0; x < width; x++, iptr++) {
1087 addr = &data[ZINDEX32(x, y, image)];
1088 *((unsigned long *) addr) = pixels[*iptr];
1089 }
1090 } else
1091#endif
1092 if (image->byte_order == MSBFirst)
1093 for (y = 0; y < height; y++)
1094 for (x = 0; x < width; x++, iptr++) {
1095 addr = &data[ZINDEX32(x, y, image)];
1096 pixel = pixels[*iptr];
1097 addr[0] = pixel >> 24;
1098 addr[1] = pixel >> 16;
1099 addr[2] = pixel >> 8;
1100 addr[3] = pixel;
1101 }
1102 else
1103 for (y = 0; y < height; y++)
1104 for (x = 0; x < width; x++, iptr++) {
1105 addr = &data[ZINDEX32(x, y, image)];
1106 pixel = pixels[*iptr];
1107 addr[0] = pixel;
1108 addr[1] = pixel >> 8;
1109 addr[2] = pixel >> 16;
1110 addr[3] = pixel >> 24;
1111 }
1112
1113#else /* WITHOUT_SPEEDUPS */
1114
1115 int bpl = image->bytes_per_line;
1116 unsigned char *data_ptr, *max_data;
1117
1118 data = (unsigned char *) image->data;
1119 iptr = pixelindex;
1120#ifndef WORD64
1121 if (*((char *) &RTXpm_byteorderpixel) == image->byte_order) {
1122 for (y = 0; y < height; y++) {
1123 data_ptr = data;
1124 max_data = data_ptr + (width << 2);
1125
1126 while (data_ptr < max_data) {
1127 *((unsigned long *) data_ptr) = pixels[*(iptr++)];
1128 data_ptr += (1 << 2);
1129 }
1130 data += bpl;
1131 }
1132 } else
1133#endif
1134 if (image->byte_order == MSBFirst)
1135 for (y = 0; y < height; y++) {
1136 data_ptr = data;
1137 max_data = data_ptr + (width << 2);
1138
1139 while (data_ptr < max_data) {
1140 pixel = pixels[*(iptr++)];
1141
1142 *data_ptr++ = pixel >> 24;
1143 *data_ptr++ = pixel >> 16;
1144 *data_ptr++ = pixel >> 8;
1145 *data_ptr++ = pixel;
1146
1147 }
1148 data += bpl;
1149 }
1150 else
1151 for (y = 0; y < height; y++) {
1152 data_ptr = data;
1153 max_data = data_ptr + (width << 2);
1154
1155 while (data_ptr < max_data) {
1156 pixel = pixels[*(iptr++)];
1157
1158 *data_ptr++ = pixel;
1159 *data_ptr++ = pixel >> 8;
1160 *data_ptr++ = pixel >> 16;
1161 *data_ptr++ = pixel >> 24;
1162 }
1163 data += bpl;
1164 }
1165
1166#endif /* WITHOUT_SPEEDUPS */
1167}
1168
1169/*
1170 * write pixels into a 16-bits Z image data structure
1171 */
1172
1173static void
1174SetImagePixels16(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels)
1175{
1176 unsigned char *data;
1177 unsigned int *iptr;
1178 int y;
1179
1180#ifdef WITHOUT_SPEEDUPS
1181
1182 int x;
1183 unsigned char *addr;
1184
1185 data = (unsigned char *) image->data;
1186 iptr = pixelindex;
1187 if (image->byte_order == MSBFirst)
1188 for (y = 0; y < height; y++)
1189 for (x = 0; x < width; x++, iptr++) {
1190 addr = &data[ZINDEX16(x, y, image)];
1191 addr[0] = pixels[*iptr] >> 8;
1192 addr[1] = pixels[*iptr];
1193 }
1194 else
1195 for (y = 0; y < height; y++)
1196 for (x = 0; x < width; x++, iptr++) {
1197 addr = &data[ZINDEX16(x, y, image)];
1198 addr[0] = pixels[*iptr];
1199 addr[1] = pixels[*iptr] >> 8;
1200 }
1201
1202#else /* WITHOUT_SPEEDUPS */
1203
1204 Pixel pixel;
1205
1206 int bpl = image->bytes_per_line;
1207 unsigned char *data_ptr, *max_data;
1208
1209 data = (unsigned char *) image->data;
1210 iptr = pixelindex;
1211 if (image->byte_order == MSBFirst)
1212 for (y = 0; y < height; y++) {
1213 data_ptr = data;
1214 max_data = data_ptr + (width << 1);
1215
1216 while (data_ptr < max_data) {
1217 pixel = pixels[*(iptr++)];
1218
1219 data_ptr[0] = pixel >> 8;
1220 data_ptr[1] = pixel;
1221
1222 data_ptr += (1 << 1);
1223 }
1224 data += bpl;
1225 }
1226 else
1227 for (y = 0; y < height; y++) {
1228 data_ptr = data;
1229 max_data = data_ptr + (width << 1);
1230
1231 while (data_ptr < max_data) {
1232 pixel = pixels[*(iptr++)];
1233
1234 data_ptr[0] = pixel;
1235 data_ptr[1] = pixel >> 8;
1236
1237 data_ptr += (1 << 1);
1238 }
1239 data += bpl;
1240 }
1241
1242#endif /* WITHOUT_SPEEDUPS */
1243}
1244
1245/*
1246 * write pixels into a 8-bits Z image data structure
1247 */
1248
1249static void
1250SetImagePixels8(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels)
1251{
1252 char *data;
1253 unsigned int *iptr;
1254 int y;
1255
1256#ifdef WITHOUT_SPEEDUPS
1257
1258 int x;
1259
1260 data = image->data;
1261 iptr = pixelindex;
1262 for (y = 0; y < height; y++)
1263 for (x = 0; x < width; x++, iptr++)
1264 data[ZINDEX8(x, y, image)] = pixels[*iptr];
1265
1266#else /* WITHOUT_SPEEDUPS */
1267
1268 int bpl = image->bytes_per_line;
1269 char *data_ptr, *max_data;
1270
1271 data = image->data;
1272 iptr = pixelindex;
1273
1274 for (y = 0; y < height; y++) {
1275 data_ptr = data;
1276 max_data = data_ptr + width;
1277
1278 while (data_ptr < max_data)
1279 *(data_ptr++) = pixels[*(iptr++)];
1280
1281 data += bpl;
1282 }
1283
1284#endif /* WITHOUT_SPEEDUPS */
1285}
1286
1287/*
1288 * write pixels into a 1-bit depth image data structure and **offset null**
1289 */
1290
1291static void
1292SetImagePixels1(XImage *image, unsigned int width, unsigned int height, unsigned int *pixelindex, Pixel *pixels)
1293{
1294 if (image->byte_order != image->bitmap_bit_order)
1295 SetImagePixels(image, width, height, pixelindex, pixels);
1296 else {
1297 unsigned int *iptr;
1298 int y;
1299 char *data;
1300
1301#ifdef WITHOUT_SPEEDUPS
1302
1303 int x;
1304
1305 data = image->data;
1306 iptr = pixelindex;
1307 if (image->bitmap_bit_order == MSBFirst)
1308 for (y = 0; y < height; y++)
1309 for (x = 0; x < width; x++, iptr++) {
1310 if (pixels[*iptr] & 1)
1311 data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
1312 else
1313 data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
1314 }
1315 else
1316 for (y = 0; y < height; y++)
1317 for (x = 0; x < width; x++, iptr++) {
1318 if (pixels[*iptr] & 1)
1319 data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
1320 else
1321 data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
1322 }
1323
1324#else /* WITHOUT_SPEEDUPS */
1325
1326 char value;
1327 char *data_ptr, *max_data;
1328 int bpl = image->bytes_per_line;
1329 int diff, count;
1330
1331 data = image->data;
1332 iptr = pixelindex;
1333
1334 diff = width & 7;
1335 width >>= 3;
1336
1337 if (image->bitmap_bit_order == MSBFirst)
1338 for (y = 0; y < height; y++) {
1339 data_ptr = data;
1340 max_data = data_ptr + width;
1341 while (data_ptr < max_data) {
1342 value = 0;
1343
1344 value = (value << 1) | (pixels[*(iptr++)] & 1);
1345 value = (value << 1) | (pixels[*(iptr++)] & 1);
1346 value = (value << 1) | (pixels[*(iptr++)] & 1);
1347 value = (value << 1) | (pixels[*(iptr++)] & 1);
1348 value = (value << 1) | (pixels[*(iptr++)] & 1);
1349 value = (value << 1) | (pixels[*(iptr++)] & 1);
1350 value = (value << 1) | (pixels[*(iptr++)] & 1);
1351 value = (value << 1) | (pixels[*(iptr++)] & 1);
1352
1353 *(data_ptr++) = value;
1354 }
1355 if (diff) {
1356 value = 0;
1357 for (count = 0; count < diff; count++) {
1358 if (pixels[*(iptr++)] & 1)
1359 value |= (0x80 >> count);
1360 }
1361 *(data_ptr) = value;
1362 }
1363 data += bpl;
1364 }
1365 else
1366 for (y = 0; y < height; y++) {
1367 data_ptr = data;
1368 max_data = data_ptr + width;
1369 while (data_ptr < max_data) {
1370 value = 0;
1371 iptr += 8;
1372
1373 value = (value << 1) | (pixels[*(--iptr)] & 1);
1374 value = (value << 1) | (pixels[*(--iptr)] & 1);
1375 value = (value << 1) | (pixels[*(--iptr)] & 1);
1376 value = (value << 1) | (pixels[*(--iptr)] & 1);
1377 value = (value << 1) | (pixels[*(--iptr)] & 1);
1378 value = (value << 1) | (pixels[*(--iptr)] & 1);
1379 value = (value << 1) | (pixels[*(--iptr)] & 1);
1380 value = (value << 1) | (pixels[*(--iptr)] & 1);
1381
1382 iptr += 8;
1383 *(data_ptr++) = value;
1384 }
1385 if (diff) {
1386 value = 0;
1387 for (count = 0; count < diff; count++) {
1388 if (pixels[*(iptr++)] & 1)
1389 value |= (1 << count);
1390 }
1391 *(data_ptr) = value;
1392 }
1393 data += bpl;
1394 }
1395
1396#endif /* WITHOUT_SPEEDUPS */
1397 }
1398}
1399
1400int
1401XpmCreatePixmapFromXpmImage(Display *display, Drawable d, XpmImage *image,
1402 Pixmap *pixmap_return, Pixmap *shapemask_return, XpmAttributes *attributes)
1403{
1404 XImage *ximage, *shapeimage;
1405 int ErrorStatus;
1406
1407 /* initialize return values */
1408 if (pixmap_return)
1409 *pixmap_return = 0;
1410 if (shapemask_return)
1411 *shapemask_return = 0;
1412
1413 /* create the ximages */
1414 ErrorStatus = XpmCreateImageFromXpmImage(display, image,
1415 (pixmap_return ? &ximage : NULL),
1416 (shapemask_return ?
1417 &shapeimage : NULL),
1418 attributes);
1419 if (ErrorStatus < 0)
1420 return (ErrorStatus);
1421
1422 /* create the pixmaps and destroy images */
1423 if (pixmap_return && ximage) {
1424 xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
1425 XDestroyImage(ximage);
1426 }
1427 if (shapemask_return && shapeimage) {
1428 xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
1429 XDestroyImage(shapeimage);
1430 }
1431 return (ErrorStatus);
1432}
1433
1434#else /* FOR_MSW part follows */
1435static void
1436MSWSetImagePixels(Display *dc, XImage *image, unsigned int width, unsigned int height,
1437 unsigned int *pixelindex, Pixel *pixels)
1438{
1439 unsigned int *data = pixelindex;
1440 unsigned int x, y;
1441
1442 SelectObject(*dc, image->bitmap);
1443 if (image->depth == 1)
1444 {
1445 for (y = 0; y < height; y++) {
1446 for (x = 0; x < width; x++) {
1447 SetPixel(*dc, x, y, (pixels[*(data++)] ? RGB(255,255,255) : 0)); /* data is [x+y*width] */
1448 }
1449 }
1450 }
1451 else
1452 {
1453 for (y = 0; y < height; y++) {
1454 for (x = 0; x < width; x++) {
1455 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
1456 }
1457 }
1458 }
1459}
1460
1461#endif /* FOR_MSW */