]>
git.saurik.com Git - wxWidgets.git/blob - src/xpm/create.c
2 * Copyright (C) 1989-94 GROUPE BULL
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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.
26 /*****************************************************************************\
30 * Create an X image and possibly its related shape mask *
31 * from the given xpmInternAttrib. *
33 * Developed by Arnaud Le Hors *
34 \*****************************************************************************/
37 * The code related to FOR_MSW has been added by
38 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
43 #include "sys$library:ctype.h"
48 LFUNC(xpmVisualType
, int, (Visual
*visual
));
51 LFUNC(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
));
58 /* let the window system take care of close colors */
61 LFUNC(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
));
68 LFUNC(CreateXImage
, int, (Display
*display
, Visual
*visual
,
69 unsigned int depth
, unsigned int width
,
70 unsigned int height
, XImage
**image_return
));
72 LFUNC(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
));
78 /* XImage pixel routines */
79 LFUNC(SetImagePixels
, void, (XImage
*image
, unsigned int width
,
80 unsigned int height
, unsigned int *pixelindex
,
83 LFUNC(SetImagePixels32
, void, (XImage
*image
, unsigned int width
,
84 unsigned int height
, unsigned int *pixelindex
,
87 LFUNC(SetImagePixels16
, void, (XImage
*image
, unsigned int width
,
88 unsigned int height
, unsigned int *pixelindex
,
91 LFUNC(SetImagePixels8
, void, (XImage
*image
, unsigned int width
,
92 unsigned int height
, unsigned int *pixelindex
,
95 LFUNC(SetImagePixels1
, void, (XImage
*image
, unsigned int width
,
96 unsigned int height
, unsigned int *pixelindex
,
98 #else /* ndef FOR_MSW */
99 /* FOR_MSW pixel routine */
100 LFUNC(MSWSetImagePixels
, void, (Display
*dc
, XImage
*image
,
101 unsigned int width
, unsigned int height
,
102 unsigned int *pixelindex
, Pixel
*pixels
));
103 #endif /* ndef FOR_MSW */
105 #ifdef NEED_STRCASECMP
106 FUNC(strcasecmp
, int, (char *s1
, char *s2
));
109 * in case strcasecmp is not provided by the system here is one
110 * which does the trick
113 strcasecmp(register char *s1
, register char *s2
)
125 return (int) (*s1
- *s2
);
131 * return the default color key related to the given visual
134 xpmVisualType(Visual
*visual
)
137 /* Xlib.h defines this to be c_class or class, depending
138 * on whether we're doing C++ or C
140 #if defined(__cplusplus) || defined(c_plusplus)
141 switch (visual
->c_class
)
143 switch (visual
->class)
148 switch (visual
->map_entries
) {
160 /* there should be a similar switch for MSW */
172 closeness_cmp(const void *a
, const void *b
)
174 CloseColor
*x
= (CloseColor
*) a
, *y
= (CloseColor
*) b
;
176 /* cast to int as qsort requires */
177 return (int) (x
->closeness
- y
->closeness
);
182 * set a close color in case the exact one can't be set
183 * return 0 if success, 1 otherwise.
187 SetCloseColor(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
)
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.
200 long int red_closeness
, green_closeness
, blue_closeness
;
203 if (attributes
&& (attributes
->valuemask
& XpmCloseness
))
204 red_closeness
= green_closeness
= blue_closeness
=
205 attributes
->closeness
;
207 red_closeness
= attributes
->red_closeness
;
208 green_closeness
= attributes
->green_closeness
;
209 blue_closeness
= attributes
->blue_closeness
;
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.
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)...
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.
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.
249 #define ITERATIONS 2 /* more than one is almost never
252 for (n
= 0; n
<= ITERATIONS
; ++n
) {
253 CloseColor
*closenesses
=
254 (CloseColor
*) XpmCalloc(ncols
, sizeof(CloseColor
));
257 for (i
= 0; i
< ncols
; ++i
) { /* build & sort closenesses table */
258 #define COLOR_FACTOR 3
259 #define BRIGHTNESS_FACTOR 1
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
+
269 - ((long) cols
[i
].red
+
270 (long) cols
[i
].green
+
271 (long) cols
[i
].blue
));
273 qsort(closenesses
, ncols
, sizeof(CloseColor
), closeness_cmp
);
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
])) {
285 XUngrabServer(display
);
286 XpmFree(closenesses
);
287 *image_pixel
= cols
[c
].pixel
;
289 (*pixels
)[*npixels
] = cols
[c
].pixel
;
296 c
= closenesses
[i
].cols_index
;
300 /* Couldn't allocate _any_ of the close colors! */
303 XUngrabServer(display
);
304 XpmFree(closenesses
);
306 if (i
== 0 || i
== ncols
) /* no color close enough or cannot */
307 return (1); /* alloc any color (full of r/w's) */
309 if (XAllocColor(display
, colormap
, col
)) {
310 *image_pixel
= col
->pixel
;
312 (*pixels
)[*npixels
] = col
->pixel
;
315 } else { /* colormap has probably changed, so
317 if (n
== ITERATIONS
- 1)
318 XGrabServer(display
);
321 if (visual
->c_class
== DirectColor
) {
325 XQueryColors(display
, colormap
, cols
, ncols
);
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))
340 /* nothing to do here, the window system does it */
344 * set the color pixel related to the given colorname,
345 * return 0 if success, 1 otherwise.
349 SetColor(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
)
355 if (strcasecmp(colorname
, TRANSPARENT_COLOR
)) {
357 if (!XParseColor(display
, (Colormap
*)colormap
, colorname
, &xcolor
))
359 if (!XParseColor(display
, (Colormap
)colormap
, colorname
, &xcolor
))
363 if (!XAllocColor(display
, (Colormap
*)colormap
, &xcolor
)) {
365 if (!XAllocColor(display
, (Colormap
)colormap
, &xcolor
)) {
369 return (SetCloseColor(display
, colormap
, visual
, &xcolor
,
370 image_pixel
, mask_pixel
, pixels
, npixels
,
371 attributes
, cols
, ncols
));
373 #endif /* ndef FOR_MSW */
376 *image_pixel
= xcolor
.pixel
;
378 (*pixels
)[*npixels
] = xcolor
.pixel
;
383 *mask_pixel_index
= color_index
; /* store the color table index */
390 CreateColors(Display
*display
, XpmAttributes
*attributes
, XpmColor
*ct
, unsigned int ncolors
,
391 Pixel
*ip
, Pixel
*mp
, unsigned int *mask_pixel
, Pixel
**pixels
, unsigned int *npixels
)
393 /* variables stored in the XpmAttributes structure */
396 XpmColorSymbol
*colorsymbols
;
397 unsigned int numsymbols
;
400 unsigned int a
, b
, l
;
403 XpmColorSymbol
*symbol
;
405 int ErrorStatus
= XpmSuccess
;
410 unsigned int ncols
= 0;
413 * retrieve information from the XpmAttributes
415 if (attributes
&& attributes
->valuemask
& XpmColorSymbols
) {
416 colorsymbols
= attributes
->colorsymbols
;
417 numsymbols
= attributes
->numsymbols
;
421 if (attributes
&& attributes
->valuemask
& XpmVisual
)
422 visual
= attributes
->visual
;
424 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
426 if (attributes
&& attributes
->valuemask
& XpmColormap
)
427 colormap
= attributes
->colormap
;
429 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
431 if (attributes
&& attributes
->valuemask
& XpmColorKey
)
432 key
= attributes
->color_key
;
434 key
= xpmVisualType(visual
);
437 if (USE_CLOSECOLOR
) {
438 /* originally from SetCloseColor */
440 if (visual
->c_class
== DirectColor
) {
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.
454 ncols
= visual
->map_entries
;
455 cols
= (XColor
*) XpmCalloc(ncols
, sizeof(XColor
));
456 for (i
= 0; i
< ncols
; ++i
)
458 XQueryColors(display
, colormap
, cols
, ncols
);
463 #endif /* ndef FOR_MSW */
481 for (a
= 0; a
< ncolors
; a
++, ct
++, ip
++, mp
++) {
483 pixel_defined
= False
;
484 defaults
= (char **) ct
;
487 * look for a defined symbol
491 for (l
= 0, symbol
= colorsymbols
; l
< numsymbols
; l
++, symbol
++) {
492 if (symbol
->name
&& s
&& !strcmp(symbol
->name
, s
))
495 if (!symbol
->name
&& symbol
->value
) { /* override value */
496 int def_index
= default_index
;
498 while (defaults
[def_index
] == NULL
) /* find defined
501 if (def_index
< 2) {/* nothing towards mono, so try
503 def_index
= default_index
+ 1;
504 while (def_index
<= 5 && defaults
[def_index
] == NULL
)
507 if (def_index
>= 2 && defaults
[def_index
] != NULL
&&
508 !strcasecmp(symbol
->value
, defaults
[def_index
]))
512 if (l
!= numsymbols
) {
513 if (symbol
->name
&& symbol
->value
)
514 colorname
= symbol
->value
;
516 pixel_defined
= True
;
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
,
524 pixel_defined
= True
;
526 ErrorStatus
= XpmColorError
;
529 while (!pixel_defined
&& b
> 1) {
531 if (!SetColor(display
, colormap
, visual
, defaults
[b
],
532 a
, ip
, mp
, mask_pixel
, pixels
, npixels
,
533 attributes
, cols
, ncols
)) {
534 pixel_defined
= True
;
537 ErrorStatus
= XpmColorError
;
542 while (!pixel_defined
&& b
< NKEYS
+ 1) {
544 if (!SetColor(display
, colormap
, visual
, defaults
[b
],
545 a
, ip
, mp
, mask_pixel
, pixels
, npixels
,
546 attributes
, cols
, ncols
)) {
547 pixel_defined
= True
;
550 ErrorStatus
= XpmColorError
;
554 if (!pixel_defined
) {
557 return (XpmColorFailed
);
560 *ip
= colorsymbols
[l
].pixel
;
562 && !strcasecmp(symbol
->value
, TRANSPARENT_COLOR
)) {
571 return (ErrorStatus
);
575 /* function call in case of error, frees only locally allocated variables */
577 #define RETURN(status) \
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); \
589 XpmCreateImageFromXpmImage(Display
*display
, XpmImage
*image
,
590 XImage
**image_return
, XImage
**shapeimage_return
, XpmAttributes
*attributes
)
592 /* variables stored in the XpmAttributes structure */
597 /* variables to return */
598 XImage
*ximage
= NULL
;
599 XImage
*shapeimage
= NULL
;
600 unsigned int mask_pixel
;
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 */
609 /* initialize return values */
611 *image_return
= NULL
;
612 if (shapeimage_return
)
613 *shapeimage_return
= NULL
;
615 /* retrieve information from the XpmAttributes */
616 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
617 visual
= attributes
->visual
;
619 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
621 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
622 colormap
= attributes
->colormap
;
624 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
626 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
627 depth
= attributes
->depth
;
629 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
631 ErrorStatus
= XpmSuccess
;
633 /* malloc pixels index tables */
634 ximage_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
636 return (XpmNoMemory
);
638 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
642 mask_pixel
= XpmUndefPixel
;
644 /* maximum of allocated pixels will be the number of colors */
645 pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
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
);
654 if (ErrorStatus
!= XpmSuccess
655 && (ErrorStatus
< 0 || (attributes
656 && (attributes
->valuemask
& XpmExactColors
)
657 && attributes
->exactColors
)))
660 /* create the ximage */
662 ErrorStatus
= CreateXImage(display
, visual
, depth
,
663 image
->width
, image
->height
, &ximage
);
664 if (ErrorStatus
!= XpmSuccess
)
670 * set the ximage data
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.
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
);
690 SetImagePixels(ximage
, image
->width
, image
->height
,
691 image
->data
, ximage_pixels
);
693 MSWSetImagePixels(display
, ximage
, image
->width
, image
->height
,
694 image
->data
, ximage_pixels
);
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
)
705 SetImagePixels1(shapeimage
, image
->width
, image
->height
,
706 image
->data
, mask_pixels
);
708 MSWSetImagePixels(display
, shapeimage
, image
->width
, image
->height
,
709 image
->data
, mask_pixels
);
713 XpmFree(mask_pixels
);
716 /* if requested store alloc'ed pixels in the XpmAttributes structure */
718 if (attributes
->valuemask
& XpmReturnPixels
||
719 /* 3.2 backward compatibility code */
720 attributes
->valuemask
& XpmReturnInfos
) {
722 if (mask_pixel
!= XpmUndefPixel
) {
723 Pixel
*pixels
, *p1
, *p2
;
726 attributes
->npixels
= image
->ncolors
- 1;
727 pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
)
728 * attributes
->npixels
);
732 for (a
= 0; a
< image
->ncolors
; a
++, p1
++)
735 attributes
->pixels
= pixels
;
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
;
742 attributes
->pixels
= NULL
;
743 attributes
->npixels
= 0;
745 XpmFree(ximage_pixels
);
747 attributes
->pixels
= ximage_pixels
;
748 attributes
->npixels
= image
->ncolors
;
750 attributes
->mask_pixel
= mask_pixel
;
752 XpmFree(ximage_pixels
);
754 XpmFree(ximage_pixels
);
756 /* return created images */
758 *image_return
= ximage
;
759 if (shapeimage_return
)
760 *shapeimage_return
= shapeimage
;
762 return (ErrorStatus
);
770 CreateXImage(Display
*display
, Visual
*visual
, unsigned int depth
,
771 unsigned int width
, unsigned int height
, XImage
**image_return
)
775 /* first get bitmap_pad */
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);
787 return (XpmNoMemory
);
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
);
794 if (!(*image_return
)->data
) {
795 XDestroyImage(*image_return
);
796 *image_return
= NULL
;
797 return (XpmNoMemory
);
800 /* under FOR_MSW XCreateImage has done it all */
807 * The functions below are written from X11R5 MIT's code (XImUtil.c)
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.
815 LFUNC(_putbits
, void, (register char *src
, int dstoffset
,
816 register int numbits
, register char *dst
));
818 LFUNC(_XReverse_Bytes
, int, (register unsigned char *bpt
, register int nb
));
820 static 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
856 _XReverse_Bytes(register unsigned char *bpt
, register int nb
)
859 *bpt
= _reverse_byte
[*bpt
];
867 xpm_xynormalizeimagebits(register unsigned char *bp
, register XImage
*img
)
869 register unsigned char c
;
871 if (img
->byte_order
!= img
->bitmap_bit_order
) {
872 switch (img
->bitmap_unit
) {
885 *(bp
+ 2) = *(bp
+ 1);
890 if (img
->bitmap_bit_order
== MSBFirst
)
891 _XReverse_Bytes(bp
, img
->bitmap_unit
>> 3);
895 xpm_znormalizeimagebits(register unsigned char *bp
, register XImage
*img
)
897 register unsigned char c
;
899 switch (img
->bits_per_pixel
) {
902 _XReverse_Bytes(bp
, 1);
906 *bp
= ((*bp
>> 4) & 0xF) | ((*bp
<< 4) & ~0xF);
926 *(bp
+ 2) = *(bp
+ 1);
932 static unsigned char Const _lomask
[0x09] = {
933 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
934 static unsigned char Const _himask
[0x09] = {
935 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
938 _putbits(register char *src
, int dstoffset
, register int numbits
, register char *dst
)
940 /* register char *src; */ /* address of source bit string */
941 /* int dstoffset; */ /* bit offset into destination;
943 /* register int numbits; */ /* number of bits to copy to
945 /* register char *dst; */ /* address of destination bit string */
947 register unsigned char chlo
, chhi
;
950 dst
= dst
+ (dstoffset
>> 3);
951 dstoffset
= dstoffset
& 7;
952 hibits
= 8 - dstoffset
;
953 chlo
= *dst
& _lomask
[dstoffset
];
955 chhi
= (*src
<< dstoffset
) & _himask
[dstoffset
];
956 if (numbits
<= hibits
) {
957 chhi
= chhi
& _lomask
[dstoffset
+ numbits
];
958 *dst
= (*dst
& _himask
[dstoffset
+ numbits
]) | chlo
| chhi
;
963 numbits
= numbits
- hibits
;
964 chlo
= (unsigned char) (*src
& _himask
[hibits
]) >> hibits
;
966 if (numbits
<= dstoffset
) {
967 chlo
= chlo
& _lomask
[numbits
];
968 *dst
= (*dst
& _himask
[numbits
]) | chlo
;
971 numbits
= numbits
- dstoffset
;
976 * Default method to write pixels into a Z image data structure.
977 * The algorithm used is:
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
987 SetImagePixels(XImage
*image
, unsigned int width
, unsigned int height
, unsigned int *pixelindex
, Pixel
*pixels
)
991 register unsigned int *iptr
;
992 register int x
, y
, i
;
995 int nbytes
, depth
, ibu
, ibpp
;
999 depth
= image
->depth
;
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);
1007 ((unsigned char *) &pixel
)[i
] = px
;
1008 src
= &data
[XYINDEX(x
, y
, image
)];
1012 for (i
= nbytes
; --i
>= 0;)
1014 XYNORMALIZE(&px
, image
);
1015 _putbits((char *) &pixel
, (x
% ibu
), 1, (char *) &px
);
1016 XYNORMALIZE(&px
, image
);
1018 dst
= &data
[XYINDEX(x
, y
, image
)];
1019 for (i
= nbytes
; --i
>= 0;)
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
];
1029 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++,
1031 ((unsigned char *) &pixel
)[i
] = px
;
1032 src
= &data
[ZINDEX(x
, y
, image
)];
1035 nbytes
= (ibpp
+ 7) >> 3;
1036 for (i
= nbytes
; --i
>= 0;)
1038 ZNORMALIZE(&px
, image
);
1039 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
1040 ZNORMALIZE(&px
, image
);
1042 dst
= &data
[ZINDEX(x
, y
, image
)];
1043 for (i
= nbytes
; --i
>= 0;)
1050 * write pixels into a 32-bits Z image data structure
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.
1059 static unsigned long /* constant */ RTXpm_byteorderpixel
= MSBFirst
<< 24;
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.
1069 SetImagePixels32(XImage
*image
, unsigned int width
, unsigned int height
, unsigned int *pixelindex
, Pixel
*pixels
)
1071 unsigned char *data
;
1076 #ifdef WITHOUT_SPEEDUPS
1079 unsigned char *addr
;
1081 data
= (unsigned char *) image
->data
;
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
];
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;
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
];
1108 addr
[1] = pixel
>> 8;
1109 addr
[2] = pixel
>> 16;
1110 addr
[3] = pixel
>> 24;
1113 #else /* WITHOUT_SPEEDUPS */
1115 int bpl
= image
->bytes_per_line
;
1116 unsigned char *data_ptr
, *max_data
;
1118 data
= (unsigned char *) image
->data
;
1121 if (*((char *) &RTXpm_byteorderpixel
) == image
->byte_order
) {
1122 for (y
= 0; y
< height
; y
++) {
1124 max_data
= data_ptr
+ (width
<< 2);
1126 while (data_ptr
< max_data
) {
1127 *((unsigned long *) data_ptr
) = pixels
[*(iptr
++)];
1128 data_ptr
+= (1 << 2);
1134 if (image
->byte_order
== MSBFirst
)
1135 for (y
= 0; y
< height
; y
++) {
1137 max_data
= data_ptr
+ (width
<< 2);
1139 while (data_ptr
< max_data
) {
1140 pixel
= pixels
[*(iptr
++)];
1142 *data_ptr
++ = pixel
>> 24;
1143 *data_ptr
++ = pixel
>> 16;
1144 *data_ptr
++ = pixel
>> 8;
1145 *data_ptr
++ = pixel
;
1151 for (y
= 0; y
< height
; y
++) {
1153 max_data
= data_ptr
+ (width
<< 2);
1155 while (data_ptr
< max_data
) {
1156 pixel
= pixels
[*(iptr
++)];
1158 *data_ptr
++ = pixel
;
1159 *data_ptr
++ = pixel
>> 8;
1160 *data_ptr
++ = pixel
>> 16;
1161 *data_ptr
++ = pixel
>> 24;
1166 #endif /* WITHOUT_SPEEDUPS */
1170 * write pixels into a 16-bits Z image data structure
1174 SetImagePixels16(XImage
*image
, unsigned int width
, unsigned int height
, unsigned int *pixelindex
, Pixel
*pixels
)
1176 unsigned char *data
;
1180 #ifdef WITHOUT_SPEEDUPS
1183 unsigned char *addr
;
1185 data
= (unsigned char *) image
->data
;
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
];
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;
1202 #else /* WITHOUT_SPEEDUPS */
1206 int bpl
= image
->bytes_per_line
;
1207 unsigned char *data_ptr
, *max_data
;
1209 data
= (unsigned char *) image
->data
;
1211 if (image
->byte_order
== MSBFirst
)
1212 for (y
= 0; y
< height
; y
++) {
1214 max_data
= data_ptr
+ (width
<< 1);
1216 while (data_ptr
< max_data
) {
1217 pixel
= pixels
[*(iptr
++)];
1219 data_ptr
[0] = pixel
>> 8;
1220 data_ptr
[1] = pixel
;
1222 data_ptr
+= (1 << 1);
1227 for (y
= 0; y
< height
; y
++) {
1229 max_data
= data_ptr
+ (width
<< 1);
1231 while (data_ptr
< max_data
) {
1232 pixel
= pixels
[*(iptr
++)];
1234 data_ptr
[0] = pixel
;
1235 data_ptr
[1] = pixel
>> 8;
1237 data_ptr
+= (1 << 1);
1242 #endif /* WITHOUT_SPEEDUPS */
1246 * write pixels into a 8-bits Z image data structure
1250 SetImagePixels8(XImage
*image
, unsigned int width
, unsigned int height
, unsigned int *pixelindex
, Pixel
*pixels
)
1256 #ifdef WITHOUT_SPEEDUPS
1262 for (y
= 0; y
< height
; y
++)
1263 for (x
= 0; x
< width
; x
++, iptr
++)
1264 data
[ZINDEX8(x
, y
, image
)] = pixels
[*iptr
];
1266 #else /* WITHOUT_SPEEDUPS */
1268 int bpl
= image
->bytes_per_line
;
1269 char *data_ptr
, *max_data
;
1274 for (y
= 0; y
< height
; y
++) {
1276 max_data
= data_ptr
+ width
;
1278 while (data_ptr
< max_data
)
1279 *(data_ptr
++) = pixels
[*(iptr
++)];
1284 #endif /* WITHOUT_SPEEDUPS */
1288 * write pixels into a 1-bit depth image data structure and **offset null**
1292 SetImagePixels1(XImage
*image
, unsigned int width
, unsigned int height
, unsigned int *pixelindex
, Pixel
*pixels
)
1294 if (image
->byte_order
!= image
->bitmap_bit_order
)
1295 SetImagePixels(image
, width
, height
, pixelindex
, pixels
);
1301 #ifdef WITHOUT_SPEEDUPS
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);
1313 data
[ZINDEX1(x
, y
, image
)] &= ~(0x80 >> (x
& 7));
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);
1321 data
[ZINDEX1(x
, y
, image
)] &= ~(1 << (x
& 7));
1324 #else /* WITHOUT_SPEEDUPS */
1327 char *data_ptr
, *max_data
;
1328 int bpl
= image
->bytes_per_line
;
1337 if (image
->bitmap_bit_order
== MSBFirst
)
1338 for (y
= 0; y
< height
; y
++) {
1340 max_data
= data_ptr
+ width
;
1341 while (data_ptr
< max_data
) {
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);
1353 *(data_ptr
++) = value
;
1357 for (count
= 0; count
< diff
; count
++) {
1358 if (pixels
[*(iptr
++)] & 1)
1359 value
|= (0x80 >> count
);
1361 *(data_ptr
) = value
;
1366 for (y
= 0; y
< height
; y
++) {
1368 max_data
= data_ptr
+ width
;
1369 while (data_ptr
< max_data
) {
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);
1383 *(data_ptr
++) = value
;
1387 for (count
= 0; count
< diff
; count
++) {
1388 if (pixels
[*(iptr
++)] & 1)
1389 value
|= (1 << count
);
1391 *(data_ptr
) = value
;
1396 #endif /* WITHOUT_SPEEDUPS */
1401 XpmCreatePixmapFromXpmImage(Display
*display
, Drawable d
, XpmImage
*image
,
1402 Pixmap
*pixmap_return
, Pixmap
*shapemask_return
, XpmAttributes
*attributes
)
1404 XImage
*ximage
, *shapeimage
;
1407 /* initialize return values */
1410 if (shapemask_return
)
1411 *shapemask_return
= 0;
1413 /* create the ximages */
1414 ErrorStatus
= XpmCreateImageFromXpmImage(display
, image
,
1415 (pixmap_return
? &ximage
: NULL
),
1417 &shapeimage
: NULL
),
1419 if (ErrorStatus
< 0)
1420 return (ErrorStatus
);
1422 /* create the pixmaps and destroy images */
1423 if (pixmap_return
&& ximage
) {
1424 xpmCreatePixmapFromImage(display
, d
, ximage
, pixmap_return
);
1425 XDestroyImage(ximage
);
1427 if (shapemask_return
&& shapeimage
) {
1428 xpmCreatePixmapFromImage(display
, d
, shapeimage
, shapemask_return
);
1429 XDestroyImage(shapeimage
);
1431 return (ErrorStatus
);
1434 #else /* FOR_MSW part follows */
1436 MSWSetImagePixels(Display
*dc
, XImage
*image
, unsigned int width
, unsigned int height
,
1437 unsigned int *pixelindex
, Pixel
*pixels
)
1439 unsigned int *data
= pixelindex
;
1442 SelectObject(*dc
, image
->bitmap
);
1443 if (image
->depth
== 1)
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] */
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] */
1461 #endif /* FOR_MSW */