2 * Copyright (C) 1989-95 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 XpmImage. *
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
42 * The code related to AMIGA has been added by
43 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
49 LFUNC(xpmVisualType
, int, (Visual
*visual
));
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
));
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
));
64 /* let the window system take care of close colors */
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
));
76 LFUNC(CreateXImage
, int, (Display
*display
, Visual
*visual
,
77 unsigned int depth
, int format
, unsigned int width
,
78 unsigned int height
, XImage
**image_return
));
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
));
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
));
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
));
105 /* XImage pixel routines */
106 LFUNC(PutImagePixels
, void, (XImage
*image
, unsigned int width
,
107 unsigned int height
, unsigned int *pixelindex
,
110 LFUNC(PutImagePixels32
, void, (XImage
*image
, unsigned int width
,
111 unsigned int height
, unsigned int *pixelindex
,
114 LFUNC(PutImagePixels16
, void, (XImage
*image
, unsigned int width
,
115 unsigned int height
, unsigned int *pixelindex
,
118 LFUNC(PutImagePixels8
, void, (XImage
*image
, unsigned int width
,
119 unsigned int height
, unsigned int *pixelindex
,
122 LFUNC(PutImagePixels1
, void, (XImage
*image
, unsigned int width
,
123 unsigned int height
, unsigned int *pixelindex
,
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
));
138 LFUNC(APutImagePixels
, void, (XImage
*ximage
, unsigned int width
,
139 unsigned int height
, unsigned int *pixelindex
,
143 /* FOR_MSW pixel routine */
145 LFUNC(MSWPutImagePixels
, void, (
150 , unsigned int height
151 , unsigned int* pixelindex
155 LFUNC(MSWPutImagePixels
, void, (Display
*dc
, XImage
*image
,
156 unsigned int width
, unsigned int height
,
157 unsigned int *pixelindex
, Pixel
*pixels
));
161 #ifdef NEED_STRCASECMP
162 FUNC(xpmstrcasecmp
, int, (char *s1
, char *s2
));
165 * in case strcasecmp is not provided by the system here is one
166 * which does the trick
169 /* Visual Age cannot deal with old, non-ansi, code */
170 int xpmstrcasecmp(register char* s1
, register char* s2
)
173 xpmstrcasecmp(s1
, s2
)
174 register char *s1
, *s2
;
187 return (int) (*s1
- *s2
);
193 * return the default color key related to the given visual
196 /* Visual Age cannot deal with old, non-ansi, code */
197 static int xpmVisualType(Visual
* visual
)
200 xpmVisualType(visual
)
206 switch (visual
->class) {
209 switch (visual
->map_entries
) {
221 /* set the key explicitly in the XpmAttributes to override this */
225 /* there should be a similar switch for MSW */
237 /* Visual Age cannot deal with old, non-ansi, code */
238 static int closeness_cmp(Const
void* a
, Const
void* b
)
245 CloseColor
*x
= (CloseColor
*) a
, *y
= (CloseColor
*) b
;
247 /* cast to int as qsort requires */
248 return (int) (x
->closeness
- y
->closeness
);
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
257 /* Visual Age cannot deal with old, non-ansi, code */
268 AllocColor(display
, colormap
, colorname
, xcolor
, closure
)
273 void *closure
; /* not used */
279 if (!XParseColor(display
, &colormap
, colorname
, xcolor
))
281 status
= XAllocColor(display
, &colormap
, xcolor
);
283 if (!XParseColor(display
, colormap
, colorname
, xcolor
))
285 status
= XAllocColor(display
, colormap
, xcolor
);
287 return status
!= 0 ? 1 : 0;
293 * set a close color in case the exact one can't be set
294 * return 0 if success, 1 otherwise.
298 SetCloseColor(display
, colormap
, visual
, col
, image_pixel
, mask_pixel
,
299 alloc_pixels
, nalloc_pixels
, attributes
, cols
, ncols
,
305 Pixel
*image_pixel
, *mask_pixel
;
307 unsigned int *nalloc_pixels
;
308 XpmAttributes
*attributes
;
311 XpmAllocColorFunc allocColor
;
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.
323 long int red_closeness
, green_closeness
, blue_closeness
;
327 if (attributes
&& (attributes
->valuemask
& XpmCloseness
))
328 red_closeness
= green_closeness
= blue_closeness
=
329 attributes
->closeness
;
331 red_closeness
= attributes
->red_closeness
;
332 green_closeness
= attributes
->green_closeness
;
333 blue_closeness
= attributes
->blue_closeness
;
335 if (attributes
&& (attributes
->valuemask
& XpmAllocCloseColors
))
336 alloc_color
= attributes
->alloc_close_colors
;
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.
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)...
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.
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.
376 #define ITERATIONS 2 /* more than one is almost never
379 for (n
= 0; n
<= ITERATIONS
; ++n
) {
380 CloseColor
*closenesses
=
381 (CloseColor
*) XpmCalloc(ncols
, sizeof(CloseColor
));
384 for (i
= 0; i
< ncols
; ++i
) { /* build & sort closenesses table */
385 #define COLOR_FACTOR 3
386 #define BRIGHTNESS_FACTOR 1
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
+
396 - ((long) cols
[i
].red
+
397 (long) cols
[i
].green
+
398 (long) cols
[i
].blue
));
400 qsort(closenesses
, ncols
, sizeof(CloseColor
), closeness_cmp
);
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
) {
411 if ((*allocColor
)(display
, colormap
, NULL
, &cols
[c
], closure
)){
413 XUngrabServer(display
);
414 XpmFree(closenesses
);
415 *image_pixel
= cols
[c
].pixel
;
417 alloc_pixels
[(*nalloc_pixels
)++] = cols
[c
].pixel
;
423 c
= closenesses
[i
].cols_index
;
427 XUngrabServer(display
);
428 XpmFree(closenesses
);
429 *image_pixel
= cols
[c
].pixel
;
435 /* Couldn't allocate _any_ of the close colors! */
438 XUngrabServer(display
);
439 XpmFree(closenesses
);
441 if (i
== 0 || i
== ncols
) /* no color close enough or cannot */
442 return (1); /* alloc any color (full of r/w's) */
444 if ((*allocColor
)(display
, colormap
, NULL
, col
, closure
)) {
445 *image_pixel
= col
->pixel
;
447 alloc_pixels
[(*nalloc_pixels
)++] = col
->pixel
;
449 } else { /* colormap has probably changed, so
451 if (n
== ITERATIONS
- 1)
452 XGrabServer(display
);
455 if (visual
->class == DirectColor
) {
459 XQueryColors(display
, colormap
, cols
, ncols
);
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)))
474 /* nothing to do here, the window system does it */
478 * set the color pixel related to the given colorname,
479 * return 0 if success, 1 otherwise.
483 /* Visual Age cannot deal with old, non-ansi, code */
490 , unsigned int color_index
493 , unsigned int* mask_pixel_index
494 , Pixel
* alloc_pixels
495 , unsigned int* nalloc_pixels
497 , unsigned int* nused_pixels
498 , XpmAttributes
* attributes
501 , XpmAllocColorFunc allocColor
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
)
514 unsigned int color_index
;
515 Pixel
*image_pixel
, *mask_pixel
;
516 unsigned int *mask_pixel_index
;
518 unsigned int *nalloc_pixels
;
520 unsigned int *nused_pixels
;
521 XpmAttributes
*attributes
;
524 XpmAllocColorFunc allocColor
;
531 if (xpmstrcasecmp(colorname
, TRANSPARENT_COLOR
)) {
532 status
= (*allocColor
)(display
, colormap
, colorname
, &xcolor
, closure
);
533 if (status
< 0) /* parse color failed */
539 return (SetCloseColor(display
, colormap
, visual
, &xcolor
,
540 image_pixel
, mask_pixel
,
541 alloc_pixels
, nalloc_pixels
,
542 attributes
, cols
, ncols
,
543 allocColor
, closure
));
545 #endif /* ndef FOR_MSW */
548 alloc_pixels
[(*nalloc_pixels
)++] = xcolor
.pixel
;
549 *image_pixel
= xcolor
.pixel
;
554 *mask_pixel
= OS2RGB(0,0,0);
556 *mask_pixel
= RGB(0,0,0);
559 used_pixels
[(*nused_pixels
)++] = xcolor
.pixel
;
566 *mask_pixel
= OS2RGB(0,0,0);
568 *mask_pixel
= RGB(0,0,0);
571 /* store the color table index */
572 *mask_pixel_index
= color_index
;
578 /* Visual Age cannot deal with old, non-ansi, code */
582 , XpmAttributes
* attributes
584 , unsigned int ncolors
585 , Pixel
* image_pixels
587 , unsigned int* mask_pixel_index
588 , Pixel
* alloc_pixels
589 , unsigned int* nalloc_pixels
591 , unsigned int* nused_pixels
595 CreateColors(display
, attributes
, colors
, ncolors
, image_pixels
, mask_pixels
,
596 mask_pixel_index
, alloc_pixels
, nalloc_pixels
,
597 used_pixels
, nused_pixels
)
599 XpmAttributes
*attributes
;
601 unsigned int ncolors
;
604 unsigned int *mask_pixel_index
;
606 unsigned int *nalloc_pixels
;
608 unsigned int *nused_pixels
;
611 /* variables stored in the XpmAttributes structure */
614 XpmColorSymbol
*colorsymbols
;
615 unsigned int numsymbols
;
616 XpmAllocColorFunc allocColor
;
620 unsigned int color
, key
;
622 XpmColorSymbol
*symbol
;
624 int ErrorStatus
= XpmSuccess
;
629 unsigned int ncols
= 0;
632 * retrieve information from the XpmAttributes
634 if (attributes
&& attributes
->valuemask
& XpmColorSymbols
) {
635 colorsymbols
= attributes
->colorsymbols
;
636 numsymbols
= attributes
->numsymbols
;
640 if (attributes
&& attributes
->valuemask
& XpmVisual
)
641 visual
= attributes
->visual
;
643 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
645 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
646 colormap
= attributes
->colormap
;
648 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
650 if (attributes
&& (attributes
->valuemask
& XpmColorKey
))
651 key
= attributes
->color_key
;
653 key
= xpmVisualType(visual
);
655 if (attributes
&& (attributes
->valuemask
& XpmAllocColor
))
656 allocColor
= attributes
->alloc_color
;
658 allocColor
= AllocColor
;
659 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
660 closure
= attributes
->color_closure
;
665 if (USE_CLOSECOLOR
) {
666 /* originally from SetCloseColor */
668 if (visual
->class == DirectColor
) {
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.
683 ncols
= visual
->map_entries
;
685 ncols
= colormap
->Count
;
687 cols
= (XColor
*) XpmCalloc(ncols
, sizeof(XColor
));
688 for (i
= 0; i
< ncols
; ++i
)
690 XQueryColors(display
, colormap
, cols
, ncols
);
695 #endif /* ndef FOR_MSW */
713 for (color
= 0; color
< ncolors
; color
++, colors
++,
714 image_pixels
++, mask_pixels
++) {
716 pixel_defined
= False
;
717 defaults
= (char **) colors
;
720 * look for a defined symbol
727 for (n
= 0, symbol
= colorsymbols
; n
< numsymbols
; n
++, symbol
++) {
728 if (symbol
->name
&& s
&& !strcmp(symbol
->name
, s
))
731 if (!symbol
->name
&& symbol
->value
) { /* override value */
732 int def_index
= default_index
;
734 while (defaults
[def_index
] == NULL
) /* find defined
737 if (def_index
< 2) {/* nothing towards mono, so try
739 def_index
= default_index
+ 1;
740 while (def_index
<= 5 && defaults
[def_index
] == NULL
)
743 if (def_index
>= 2 && defaults
[def_index
] != NULL
&&
744 !xpmstrcasecmp(symbol
->value
, defaults
[def_index
]))
748 if (n
!= numsymbols
) {
749 if (symbol
->name
&& symbol
->value
)
750 colorname
= symbol
->value
;
752 pixel_defined
= True
;
755 if (!pixel_defined
) { /* pixel not given as symbol value */
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
;
767 ErrorStatus
= XpmColorError
;
770 while (!pixel_defined
&& k
> 1) {
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
;
781 ErrorStatus
= XpmColorError
;
786 while (!pixel_defined
&& k
< NKEYS
+ 1) {
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
;
797 ErrorStatus
= XpmColorError
;
801 if (!pixel_defined
) {
804 return (XpmColorFailed
);
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 */
812 && !xpmstrcasecmp(symbol
->value
, TRANSPARENT_COLOR
)) {
814 *mask_pixel_index
= color
;
817 used_pixels
[(*nused_pixels
)++] = *image_pixels
;
822 return (ErrorStatus
);
826 /* default FreeColors function, simply call XFreeColors */
828 /* Visual Age cannot deal with old, non-ansi, code */
839 FreeColors(display
, colormap
, pixels
, n
, closure
)
844 void *closure
; /* not used */
847 return XFreeColors(display
, colormap
, pixels
, n
, 0);
851 /* function call in case of error */
853 #define RETURN(status) \
855 ErrorStatus = status; \
860 /* Visual Age cannot deal with old, non-ansi, code */
861 int XpmCreateImageFromXpmImage(
864 , XImage
** image_return
865 , XImage
** shapeimage_return
866 , XpmAttributes
* attributes
870 XpmCreateImageFromXpmImage(display
, image
,
871 image_return
, shapeimage_return
, attributes
)
874 XImage
**image_return
;
875 XImage
**shapeimage_return
;
876 XpmAttributes
*attributes
;
884 /* variables stored in the XpmAttributes structure */
889 XpmFreeColorsFunc freeColors
;
892 /* variables to return */
893 XImage
*ximage
= NULL
;
894 XImage
*shapeimage
= NULL
;
895 unsigned int mask_pixel_index
= XpmUndefPixel
;
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;
906 /* initialize return values */
908 *image_return
= NULL
;
909 if (shapeimage_return
)
910 *shapeimage_return
= NULL
;
912 /* retrieve information from the XpmAttributes */
913 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
914 visual
= attributes
->visual
;
916 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
918 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
919 colormap
= attributes
->colormap
;
921 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
923 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
924 depth
= attributes
->depth
;
926 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
928 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
929 bitmap_format
= attributes
->bitmap_format
;
931 bitmap_format
= ZPixmap
;
933 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
934 freeColors
= attributes
->free_colors
;
936 freeColors
= FreeColors
;
937 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
938 closure
= attributes
->color_closure
;
942 ErrorStatus
= XpmSuccess
;
944 /* malloc pixels index tables */
945 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
947 return (XpmNoMemory
);
949 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
953 /* maximum of allocated pixels will be the number of colors */
954 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
958 /* maximum of allocated pixels will be the number of colors */
959 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
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
);
969 if (ErrorStatus
!= XpmSuccess
970 && (ErrorStatus
< 0 || (attributes
971 && (attributes
->valuemask
& XpmExactColors
)
972 && attributes
->exactColors
)))
975 /* create the ximage */
977 ErrorStatus
= CreateXImage(display
, visual
, depth
,
978 (depth
== 1 ? bitmap_format
: ZPixmap
),
979 image
->width
, image
->height
, &ximage
);
980 if (ErrorStatus
!= XpmSuccess
)
987 * set the ximage data using optimized functions for ZPixmap
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
);
1004 PutImagePixels(ximage
, image
->width
, image
->height
,
1005 image
->data
, image_pixels
);
1007 APutImagePixels(ximage
, image
->width
, image
->height
,
1008 image
->data
, image_pixels
);
1012 hps
= GpiCreatePS(hab
, *display
, &sizl
, GPIA_ASSOC
|PU_PELS
);
1013 MSWPutImagePixels(hps
, display
, ximage
, image
->width
, image
->height
,
1014 image
->data
, image_pixels
);
1016 MSWPutImagePixels(display
, ximage
, image
->width
, image
->height
,
1017 image
->data
, image_pixels
);
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
);
1030 PutImagePixels1(shapeimage
, image
->width
, image
->height
,
1031 image
->data
, mask_pixels
);
1033 APutImagePixels(shapeimage
, image
->width
, image
->height
,
1034 image
->data
, mask_pixels
);
1038 hps
= GpiCreatePS(hab
, *display
, &sizl
, GPIA_ASSOC
|PU_PELS
);
1039 MSWPutImagePixels(hps
, display
, shapeimage
, image
->width
, image
->height
,
1040 image
->data
, mask_pixels
);
1042 MSWPutImagePixels(display
, shapeimage
, image
->width
, image
->height
,
1043 image
->data
, mask_pixels
);
1048 XpmFree(image_pixels
);
1049 XpmFree(mask_pixels
);
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
)) {
1056 attributes
->pixels
= used_pixels
;
1057 attributes
->npixels
= nused_pixels
;
1058 attributes
->mask_pixel
= mask_pixel_index
;
1060 XpmFree(used_pixels
);
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
;
1067 XpmFree(alloc_pixels
);
1069 /* return created images */
1071 *image_return
= ximage
;
1072 if (shapeimage_return
)
1073 *shapeimage_return
= shapeimage
;
1075 return (ErrorStatus
);
1077 /* exit point in case of error, free only locally allocated variables */
1080 XDestroyImage(ximage
);
1082 XDestroyImage(shapeimage
);
1084 XpmFree(image_pixels
);
1086 XpmFree(mask_pixels
);
1088 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
1090 XpmFree(alloc_pixels
);
1092 XpmFree(used_pixels
);
1094 return (ErrorStatus
);
1099 * Create an XImage with its data
1102 /* Visual Age cannot deal with old, non-ansi, code */
1103 static int CreateXImage(
1106 , unsigned int depth
1108 , unsigned int width
1109 , unsigned int height
1110 , XImage
** image_return
1114 CreateXImage(display
, visual
, depth
, format
, width
, height
, image_return
)
1120 unsigned int height
;
1121 XImage
**image_return
;
1126 /* first get bitmap_pad */
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);
1138 return (XpmNoMemory
);
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
);
1145 if (!(*image_return
)->data
) {
1146 XDestroyImage(*image_return
);
1147 *image_return
= NULL
;
1148 return (XpmNoMemory
);
1151 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1153 return (XpmSuccess
);
1159 * The functions below are written from X11R5 MIT's code (XImUtil.c)
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.
1167 LFUNC(_putbits
, void, (register char *src
, int dstoffset
,
1168 register int numbits
, register char *dst
));
1170 LFUNC(_XReverse_Bytes
, int, (register unsigned char *bpt
, register int nb
));
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
1208 /* Visual Age cannot deal with old, non-ansi, code */
1210 _XReverse_Bytes(register unsigned char* bpt
, register int nb
)
1213 _XReverse_Bytes(bpt
, nb
)
1214 register unsigned char *bpt
;
1219 *bpt
= _reverse_byte
[*bpt
];
1227 /* Visual Age cannot deal with old, non-ansi, code */
1228 void xpm_xynormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1231 xpm_xynormalizeimagebits(bp
, img
)
1232 register unsigned char *bp
;
1233 register XImage
*img
;
1236 register unsigned char c
;
1238 if (img
->byte_order
!= img
->bitmap_bit_order
) {
1239 switch (img
->bitmap_unit
) {
1252 *(bp
+ 2) = *(bp
+ 1);
1257 if (img
->bitmap_bit_order
== MSBFirst
)
1258 _XReverse_Bytes(bp
, img
->bitmap_unit
>> 3);
1262 /* Visual Age cannot deal with old, non-ansi, code */
1263 void xpm_znormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1266 xpm_znormalizeimagebits(bp
, img
)
1267 register unsigned char *bp
;
1268 register XImage
*img
;
1271 register unsigned char c
;
1273 switch (img
->bits_per_pixel
) {
1276 _XReverse_Bytes(bp
, 1);
1280 *bp
= ((*bp
>> 4) & 0xF) | ((*bp
<< 4) & ~0xF);
1300 *(bp
+ 2) = *(bp
+ 1);
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};
1312 /* Visual Age cannot deal with old, non-ansi, code */
1313 static void _putbits(
1316 , register int numbits
1317 , register char* dst
1321 _putbits(src
, dstoffset
, numbits
, dst
)
1322 register char *src
; /* address of source bit string */
1323 int dstoffset
; /* bit offset into destination;
1325 register int numbits
; /* number of bits to copy to
1327 register char *dst
; /* address of destination bit string */
1330 register unsigned char chlo
, chhi
;
1333 dst
= dst
+ (dstoffset
>> 3);
1334 dstoffset
= dstoffset
& 7;
1335 hibits
= 8 - dstoffset
;
1336 chlo
= *dst
& _lomask
[dstoffset
];
1338 chhi
= (*src
<< dstoffset
) & _himask
[dstoffset
];
1339 if (numbits
<= hibits
) {
1340 chhi
= chhi
& _lomask
[dstoffset
+ numbits
];
1341 *dst
= (*dst
& _himask
[dstoffset
+ numbits
]) | chlo
| chhi
;
1346 numbits
= numbits
- hibits
;
1347 chlo
= (unsigned char) (*src
& _himask
[hibits
]) >> hibits
;
1349 if (numbits
<= dstoffset
) {
1350 chlo
= chlo
& _lomask
[numbits
];
1351 *dst
= (*dst
& _himask
[numbits
]) | chlo
;
1354 numbits
= numbits
- dstoffset
;
1359 * Default method to write pixels into a Z image data structure.
1360 * The algorithm used is:
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
1370 /* Visual Age cannot deal with old, non-ansi, code */
1371 static void PutImagePixels(
1373 , unsigned int width
1374 , unsigned int height
1375 , unsigned int* pixelindex
1380 PutImagePixels(image
, width
, height
, pixelindex
, pixels
)
1383 unsigned int height
;
1384 unsigned int *pixelindex
;
1390 register unsigned int *iptr
;
1391 register int x
, y
, i
;
1392 register char *data
;
1394 int nbytes
, depth
, ibu
, ibpp
;
1398 depth
= image
->depth
;
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);
1406 ((unsigned char *) &pixel
)[i
] = px
;
1407 src
= &data
[XYINDEX(x
, y
, image
)];
1411 for (i
= nbytes
; --i
>= 0;)
1413 XYNORMALIZE(&px
, image
);
1414 _putbits((char *) &pixel
, (x
% ibu
), 1, (char *) &px
);
1415 XYNORMALIZE(&px
, image
);
1417 dst
= &data
[XYINDEX(x
, y
, image
)];
1418 for (i
= nbytes
; --i
>= 0;)
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
];
1428 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++,
1430 ((unsigned char *) &pixel
)[i
] = px
;
1431 src
= &data
[ZINDEX(x
, y
, image
)];
1434 nbytes
= (ibpp
+ 7) >> 3;
1435 for (i
= nbytes
; --i
>= 0;)
1437 ZNORMALIZE(&px
, image
);
1438 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
1439 ZNORMALIZE(&px
, image
);
1441 dst
= &data
[ZINDEX(x
, y
, image
)];
1442 for (i
= nbytes
; --i
>= 0;)
1449 * write pixels into a 32-bits Z image data structure
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.
1458 static unsigned long byteorderpixel
= MSBFirst
<< 24;
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.
1468 /* Visual Age cannot deal with old, non-ansi, code */
1472 , unsigned int width
1473 , unsigned int height
1474 , unsigned int* pixelindex
1479 PutImagePixels32(image
, width
, height
, pixelindex
, pixels
)
1482 unsigned int height
;
1483 unsigned int *pixelindex
;
1487 unsigned char *data
;
1492 #ifdef WITHOUT_SPEEDUPS
1495 unsigned char *addr
;
1497 data
= (unsigned char *) image
->data
;
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
];
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;
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
];
1524 addr
[1] = pixel
>> 8;
1525 addr
[2] = pixel
>> 16;
1526 addr
[3] = pixel
>> 24;
1529 #else /* WITHOUT_SPEEDUPS */
1531 int bpl
= image
->bytes_per_line
;
1532 unsigned char *data_ptr
, *max_data
;
1534 data
= (unsigned char *) image
->data
;
1536 #if !defined(WORD64) && !defined(LONG64)
1537 if (*((char *) &byteorderpixel
) == image
->byte_order
) {
1538 for (y
= 0; y
< height
; y
++) {
1540 max_data
= data_ptr
+ (width
<< 2);
1542 while (data_ptr
< max_data
) {
1543 *((unsigned long *) data_ptr
) = pixels
[*(iptr
++)];
1544 data_ptr
+= (1 << 2);
1550 if (image
->byte_order
== MSBFirst
)
1551 for (y
= 0; y
< height
; y
++) {
1553 max_data
= data_ptr
+ (width
<< 2);
1555 while (data_ptr
< max_data
) {
1556 pixel
= pixels
[*(iptr
++)];
1558 *data_ptr
++ = pixel
>> 24;
1559 *data_ptr
++ = pixel
>> 16;
1560 *data_ptr
++ = pixel
>> 8;
1561 *data_ptr
++ = pixel
;
1567 for (y
= 0; y
< height
; y
++) {
1569 max_data
= data_ptr
+ (width
<< 2);
1571 while (data_ptr
< max_data
) {
1572 pixel
= pixels
[*(iptr
++)];
1574 *data_ptr
++ = pixel
;
1575 *data_ptr
++ = pixel
>> 8;
1576 *data_ptr
++ = pixel
>> 16;
1577 *data_ptr
++ = pixel
>> 24;
1582 #endif /* WITHOUT_SPEEDUPS */
1586 * write pixels into a 16-bits Z image data structure
1590 /* Visual Age cannot deal with old, non-ansi, code */
1591 static void PutImagePixels16(
1593 , unsigned int width
1594 , unsigned int height
1595 , unsigned int* pixelindex
1600 PutImagePixels16(image
, width
, height
, pixelindex
, pixels
)
1603 unsigned int height
;
1604 unsigned int *pixelindex
;
1608 unsigned char *data
;
1612 #ifdef WITHOUT_SPEEDUPS
1615 unsigned char *addr
;
1617 data
= (unsigned char *) image
->data
;
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
];
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;
1634 #else /* WITHOUT_SPEEDUPS */
1638 int bpl
= image
->bytes_per_line
;
1639 unsigned char *data_ptr
, *max_data
;
1641 data
= (unsigned char *) image
->data
;
1643 if (image
->byte_order
== MSBFirst
)
1644 for (y
= 0; y
< height
; y
++) {
1646 max_data
= data_ptr
+ (width
<< 1);
1648 while (data_ptr
< max_data
) {
1649 pixel
= pixels
[*(iptr
++)];
1651 data_ptr
[0] = pixel
>> 8;
1652 data_ptr
[1] = pixel
;
1654 data_ptr
+= (1 << 1);
1659 for (y
= 0; y
< height
; y
++) {
1661 max_data
= data_ptr
+ (width
<< 1);
1663 while (data_ptr
< max_data
) {
1664 pixel
= pixels
[*(iptr
++)];
1666 data_ptr
[0] = pixel
;
1667 data_ptr
[1] = pixel
>> 8;
1669 data_ptr
+= (1 << 1);
1674 #endif /* WITHOUT_SPEEDUPS */
1678 * write pixels into a 8-bits Z image data structure
1682 /* Visual Age cannot deal with old, non-ansi, code */
1683 static void PutImagePixels8(
1685 , unsigned int width
1686 , unsigned int height
1687 , unsigned int* pixelindex
1692 PutImagePixels8(image
, width
, height
, pixelindex
, pixels
)
1695 unsigned int height
;
1696 unsigned int *pixelindex
;
1704 #ifdef WITHOUT_SPEEDUPS
1710 for (y
= 0; y
< height
; y
++)
1711 for (x
= 0; x
< width
; x
++, iptr
++)
1712 data
[ZINDEX8(x
, y
, image
)] = pixels
[*iptr
];
1714 #else /* WITHOUT_SPEEDUPS */
1716 int bpl
= image
->bytes_per_line
;
1717 char *data_ptr
, *max_data
;
1722 for (y
= 0; y
< height
; y
++) {
1724 max_data
= data_ptr
+ width
;
1726 while (data_ptr
< max_data
)
1727 *(data_ptr
++) = pixels
[*(iptr
++)];
1732 #endif /* WITHOUT_SPEEDUPS */
1736 * write pixels into a 1-bit depth image data structure and **offset null**
1740 /* Visual Age cannot deal with old, non-ansi, code */
1741 static void PutImagePixels1(
1743 , unsigned int width
1744 , unsigned int height
1745 , unsigned int* pixelindex
1750 PutImagePixels1(image
, width
, height
, pixelindex
, pixels
)
1753 unsigned int height
;
1754 unsigned int *pixelindex
;
1758 if (image
->byte_order
!= image
->bitmap_bit_order
)
1759 PutImagePixels(image
, width
, height
, pixelindex
, pixels
);
1765 #ifdef WITHOUT_SPEEDUPS
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);
1777 data
[ZINDEX1(x
, y
, image
)] &= ~(0x80 >> (x
& 7));
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);
1785 data
[ZINDEX1(x
, y
, image
)] &= ~(1 << (x
& 7));
1788 #else /* WITHOUT_SPEEDUPS */
1791 char *data_ptr
, *max_data
;
1792 int bpl
= image
->bytes_per_line
;
1801 if (image
->bitmap_bit_order
== MSBFirst
)
1802 for (y
= 0; y
< height
; y
++) {
1804 max_data
= data_ptr
+ width
;
1805 while (data_ptr
< max_data
) {
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);
1817 *(data_ptr
++) = value
;
1821 for (count
= 0; count
< diff
; count
++) {
1822 if (pixels
[*(iptr
++)] & 1)
1823 value
|= (0x80 >> count
);
1825 *(data_ptr
) = value
;
1830 for (y
= 0; y
< height
; y
++) {
1832 max_data
= data_ptr
+ width
;
1833 while (data_ptr
< max_data
) {
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);
1847 *(data_ptr
++) = value
;
1851 for (count
= 0; count
< diff
; count
++) {
1852 if (pixels
[*(iptr
++)] & 1)
1853 value
|= (1 << count
);
1855 *(data_ptr
) = value
;
1860 #endif /* WITHOUT_SPEEDUPS */
1865 /* Visual Age cannot deal with old, non-ansi, code */
1866 int XpmCreatePixmapFromXpmImage(
1870 , Pixmap
* pixmap_return
1871 , Pixmap
* shapemask_return
1872 , XpmAttributes
* attributes
1875 XpmCreatePixmapFromXpmImage(display
, d
, image
,
1876 pixmap_return
, shapemask_return
, attributes
)
1880 Pixmap
*pixmap_return
;
1881 Pixmap
*shapemask_return
;
1882 XpmAttributes
*attributes
;
1885 XImage
*ximage
, *shapeimage
;
1888 /* initialize return values */
1891 if (shapemask_return
)
1892 *shapemask_return
= 0;
1894 /* create the ximages */
1895 ErrorStatus
= XpmCreateImageFromXpmImage(display
, image
,
1896 (pixmap_return
? &ximage
: NULL
),
1898 &shapeimage
: NULL
),
1900 if (ErrorStatus
< 0)
1901 return (ErrorStatus
);
1903 /* create the pixmaps and destroy images */
1904 if (pixmap_return
&& ximage
) {
1905 xpmCreatePixmapFromImage(display
, d
, ximage
, pixmap_return
);
1906 XDestroyImage(ximage
);
1908 if (shapemask_return
&& shapeimage
) {
1909 xpmCreatePixmapFromImage(display
, d
, shapeimage
, shapemask_return
);
1910 XDestroyImage(shapeimage
);
1912 return (ErrorStatus
);
1921 unsigned int height
,
1922 unsigned int *pixelindex
,
1925 unsigned int *data
= pixelindex
;
1927 unsigned char *array
;
1929 BOOL success
= FALSE
;
1931 array
= XpmMalloc ((((width
+15)>>4)<<4)*sizeof (*array
));
1934 tmp_img
= AllocXImage ((((width
+15)>>4)<<4), 1,
1935 image
->rp
->BitMap
->Depth
);
1936 if (tmp_img
!= NULL
)
1938 for (y
= 0; y
< height
; ++y
)
1940 for (x
= 0; x
< width
; ++x
)
1941 array
[x
] = pixels
[*(data
++)];
1942 WritePixelLine8 (image
->rp
, 0, y
, width
, array
, tmp_img
->rp
);
1944 FreeXImage (tmp_img
);
1952 for (y
= 0; y
< height
; ++y
)
1953 for (x
= 0; x
< width
; ++x
)
1954 XPutPixel (image
, x
, y
, pixels
[*(data
++)]);
1959 #else /* FOR_MSW part follows */
1962 /* Visual Age cannot deal with old, non-ansi, code */
1963 static void MSWPutImagePixels(
1967 , unsigned int width
1968 , unsigned int height
1969 , unsigned int* pixelindex
1974 MSWPutImagePixels(dc
, image
, width
, height
, pixelindex
, pixels
)
1978 unsigned int height
;
1979 unsigned int *pixelindex
;
1983 unsigned int *data
= pixelindex
;
1990 obm
= GpiSetBitmap(hps
, image
->bitmap
);
1992 obm
= SelectObject(*dc
, image
->bitmap
);
1995 for (y
= 0; y
< height
; y
++) {
1996 for (x
= 0; x
< width
; x
++) {
2000 GpiSetColor(hps
, (LONG
)pixels
[*(data
++)]);
2001 GpiSetPel(hps
, &point
);
2004 SetPixel(*dc
, x
, y
, pixels
[*(data
++)]); /* data is [x+y*width] */
2009 GpiSetBitmap(hps
, obm
);
2011 SelectObject(*dc
, obm
);
2015 #endif /* FOR_MSW */
2019 #if !defined(FOR_MSW) && !defined(AMIGA)
2022 PutPixel1(ximage
, x
, y
, pixel
)
2023 register XImage
*ximage
;
2026 unsigned long pixel
;
2031 register char *data
;
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
)];
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
);
2047 dst
= &ximage
->data
[XYINDEX(x
, y
, ximage
)];
2048 for (i
= nbytes
; --i
>= 0; )
2055 PutPixel(ximage
, x
, y
, pixel
)
2056 register XImage
*ximage
;
2059 unsigned long pixel
;
2064 register char *data
;
2068 ibpp
= ximage
->bits_per_pixel
;
2069 if (ximage
->depth
== 4)
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
)];
2076 nbytes
= (ibpp
+ 7) >> 3;
2077 for (i
= nbytes
; --i
>= 0;)
2079 ZNORMALIZE(&px
, ximage
);
2080 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
2081 ZNORMALIZE(&px
, ximage
);
2083 dst
= &ximage
->data
[ZINDEX(x
, y
, ximage
)];
2084 for (i
= nbytes
; --i
>= 0;)
2091 PutPixel32(ximage
, x
, y
, pixel
)
2092 register XImage
*ximage
;
2095 unsigned long pixel
;
2097 unsigned char *addr
;
2099 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2100 *((unsigned long *)addr
) = pixel
;
2105 PutPixel32MSB(ximage
, x
, y
, pixel
)
2106 register XImage
*ximage
;
2109 unsigned long pixel
;
2111 unsigned char *addr
;
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;
2122 PutPixel32LSB(ximage
, x
, y
, pixel
)
2123 register XImage
*ximage
;
2126 unsigned long pixel
;
2128 unsigned char *addr
;
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;
2139 PutPixel16MSB(ximage
, x
, y
, pixel
)
2140 register XImage
*ximage
;
2143 unsigned long pixel
;
2145 unsigned char *addr
;
2147 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2148 addr
[0] = pixel
>> 8;
2154 PutPixel16LSB(ximage
, x
, y
, pixel
)
2155 register XImage
*ximage
;
2158 unsigned long pixel
;
2160 unsigned char *addr
;
2162 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2163 addr
[1] = pixel
>> 8;
2169 PutPixel8(ximage
, x
, y
, pixel
)
2170 register XImage
*ximage
;
2173 unsigned long pixel
;
2175 ximage
->data
[ZINDEX8(x
, y
, ximage
)] = pixel
;
2180 PutPixel1MSB(ximage
, x
, y
, pixel
)
2181 register XImage
*ximage
;
2184 unsigned long pixel
;
2187 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 0x80 >> (x
& 7);
2189 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(0x80 >> (x
& 7));
2194 PutPixel1LSB(ximage
, x
, y
, pixel
)
2195 register XImage
*ximage
;
2198 unsigned long pixel
;
2201 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 1 << (x
& 7);
2203 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(1 << (x
& 7));
2207 #endif /* not FOR_MSW && not AMIGA */
2210 * This function parses an Xpm file or data and directly create an XImage
2213 /* Visual Age cannot deal with old, non-ansi, code */
2214 int xpmParseDataAndCreate(
2217 , XImage
** image_return
2218 , XImage
** shapeimage_return
2221 , XpmAttributes
* attributes
2225 xpmParseDataAndCreate(display
, data
, image_return
, shapeimage_return
,
2226 image
, info
, attributes
)
2229 XImage
**image_return
;
2230 XImage
**shapeimage_return
;
2233 XpmAttributes
*attributes
;
2236 /* variables stored in the XpmAttributes structure */
2241 XpmFreeColorsFunc freeColors
;
2244 /* variables to return */
2245 XImage
*ximage
= NULL
;
2246 XImage
*shapeimage
= NULL
;
2247 unsigned int mask_pixel_index
= XpmUndefPixel
;
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
;
2265 xpmHashTable hashtable
;
2268 /* initialize return values */
2270 *image_return
= NULL
;
2271 if (shapeimage_return
)
2272 *shapeimage_return
= NULL
;
2275 /* retrieve information from the XpmAttributes */
2276 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
2277 visual
= attributes
->visual
;
2279 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
2281 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
2282 colormap
= attributes
->colormap
;
2284 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
2286 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
2287 depth
= attributes
->depth
;
2289 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
2291 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
2292 bitmap_format
= attributes
->bitmap_format
;
2294 bitmap_format
= ZPixmap
;
2296 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
2297 freeColors
= attributes
->free_colors
;
2299 freeColors
= FreeColors
;
2300 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
2301 closure
= attributes
->color_closure
;
2305 cmts
= info
&& (info
->valuemask
& XpmReturnComments
);
2310 ErrorStatus
= xpmParseHeader(data
);
2311 if (ErrorStatus
!= XpmSuccess
)
2312 return (ErrorStatus
);
2317 ErrorStatus
= xpmParseValues(data
, &width
, &height
, &ncolors
, &cpp
,
2318 &x_hotspot
, &y_hotspot
, &hotspot
,
2320 if (ErrorStatus
!= XpmSuccess
)
2321 return (ErrorStatus
);
2324 * store the hints comment line
2327 xpmGetCmt(data
, &hints_cmt
);
2332 if (USE_HASHTABLE
) {
2333 ErrorStatus
= xpmHashTableInit(&hashtable
);
2334 if (ErrorStatus
!= XpmSuccess
)
2335 return (ErrorStatus
);
2341 ErrorStatus
= xpmParseColors(data
, ncolors
, cpp
, &colorTable
, &hashtable
);
2342 if (ErrorStatus
!= XpmSuccess
)
2343 RETURN(ErrorStatus
);
2346 * store the colors comment line
2349 xpmGetCmt(data
, &colors_cmt
);
2351 /* malloc pixels index tables */
2352 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2354 RETURN(XpmNoMemory
);
2356 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2358 RETURN(XpmNoMemory
);
2360 /* maximum of allocated pixels will be the number of colors */
2361 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2363 RETURN(XpmNoMemory
);
2365 /* maximum of allocated pixels will be the number of colors */
2366 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2368 RETURN(XpmNoMemory
);
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
,
2376 if (ErrorStatus
!= XpmSuccess
2377 && (ErrorStatus
< 0 || (attributes
2378 && (attributes
->valuemask
& XpmExactColors
)
2379 && attributes
->exactColors
)))
2380 RETURN(ErrorStatus
);
2382 /* now create the ximage */
2384 ErrorStatus
= CreateXImage(display
, visual
, depth
,
2385 (depth
== 1 ? bitmap_format
: ZPixmap
),
2386 width
, height
, &ximage
);
2387 if (ErrorStatus
!= XpmSuccess
)
2388 RETURN(ErrorStatus
);
2390 #if !defined(FOR_MSW) && !defined(AMIGA)
2393 * set the XImage pointer function, to be used with XPutPixel,
2394 * to an internal optimized function
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
;
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
;
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
;
2416 if (ximage
->bitmap_bit_order
== MSBFirst
)
2417 ximage
->f
.put_pixel
= PutPixel32MSB
;
2419 ximage
->f
.put_pixel
= PutPixel32LSB
;
2420 else if ((ximage
->bits_per_pixel
| ximage
->depth
) == 1)
2421 ximage
->f
.put_pixel
= PutPixel1
;
2423 ximage
->f
.put_pixel
= PutPixel
;
2424 #endif /* not FOR_MSW && not AMIGA */
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
);
2434 #if !defined(FOR_MSW) && !defined(AMIGA)
2435 if (shapeimage
->bitmap_bit_order
== MSBFirst
)
2436 shapeimage
->f
.put_pixel
= PutPixel1MSB
;
2438 shapeimage
->f
.put_pixel
= PutPixel1LSB
;
2443 * read pixels and put them in the XImage
2445 ErrorStatus
= ParseAndPutPixels(
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
);
2461 if (ErrorStatus
!= XpmSuccess
)
2463 else if (USE_HASHTABLE
)
2464 xpmHashTableFree(&hashtable
);
2467 * store the pixels comment line
2470 xpmGetCmt(data
, &pixels_cmt
);
2475 if (info
&& (info
->valuemask
& XpmReturnExtensions
))
2477 ErrorStatus
= xpmParseExtensions(data
, &info
->extensions
,
2478 &info
->nextensions
);
2479 if (ErrorStatus
!= XpmSuccess
)
2480 RETURN(ErrorStatus
);
2482 info
->extensions
= NULL
;
2483 info
->nextensions
= 0;
2487 * store found informations in the XpmImage structure
2489 image
->width
= width
;
2490 image
->height
= height
;
2492 image
->ncolors
= ncolors
;
2493 image
->colorTable
= colorTable
;
2498 info
->hints_cmt
= hints_cmt
;
2499 info
->colors_cmt
= colors_cmt
;
2500 info
->pixels_cmt
= pixels_cmt
;
2503 info
->x_hotspot
= x_hotspot
;
2504 info
->y_hotspot
= y_hotspot
;
2505 info
->valuemask
|= XpmHotspot
;
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
)) {
2513 attributes
->pixels
= used_pixels
;
2514 attributes
->npixels
= nused_pixels
;
2515 attributes
->mask_pixel
= mask_pixel_index
;
2517 XpmFree(used_pixels
);
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
;
2524 XpmFree(alloc_pixels
);
2526 /* return created images */
2528 *image_return
= ximage
;
2529 if (shapeimage_return
)
2530 *shapeimage_return
= shapeimage
;
2532 return (XpmSuccess
);
2534 /* exit point in case of error, free only locally allocated variables */
2537 xpmHashTableFree(&hashtable
);
2539 xpmFreeColorTable(colorTable
, ncolors
);
2543 XpmFree(colors_cmt
);
2545 XpmFree(pixels_cmt
);
2547 XDestroyImage(ximage
);
2549 XDestroyImage(shapeimage
);
2551 XpmFree(image_pixels
);
2553 XpmFree(mask_pixels
);
2555 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
2557 XpmFree(alloc_pixels
);
2559 XpmFree(used_pixels
);
2561 return (ErrorStatus
);
2565 /* Visual Age cannot deal with old, non-ansi, code */
2566 static int ParseAndPutPixels(
2569 , unsigned int width
2570 , unsigned int height
2571 , unsigned int ncolors
2573 , XpmColor
* colorTable
2574 , xpmHashTable
* hashtable
2576 , Pixel
* image_pixels
2577 , XImage
* shapeimage
2578 , Pixel
* shape_pixels
2586 data
, width
, height
, ncolors
, cpp
, colorTable
, hashtable
,
2587 image
, image_pixels
, shapeimage
, shape_pixels
)
2593 unsigned int height
;
2594 unsigned int ncolors
;
2596 XpmColor
*colorTable
;
2597 xpmHashTable
*hashtable
;
2599 Pixel
*image_pixels
;
2601 Pixel
*shape_pixels
;
2604 unsigned int a
, x
, y
;
2608 DEVOPENSTRUC dop
= {NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2609 SIZEL sizl
= {0, 0};
2615 case (1): /* Optimize for single character
2618 unsigned short colidx
[256];
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
);
2629 shapedc
= CreateCompatibleDC(*dc
);
2630 sobm
= SelectObject(shapedc
, shapeimage
->bitmap
);
2636 obm
= GpiSetBitmap(hps
, image
->bitmap
);
2638 obm
= SelectObject(*dc
, image
->bitmap
);
2644 bzero((char *)colidx
, 256 * sizeof(short));
2645 for (a
= 0; a
< ncolors
; a
++)
2646 colidx
[(unsigned char)colorTable
[a
].string
[0]] = a
+ 1;
2648 for (y
= 0; y
< height
; y
++) {
2649 xpmNextString(data
);
2650 for (x
= 0; x
< width
; x
++) {
2651 int c
= xpmGetC(data
);
2653 if (c
> 0 && c
< 256 && colidx
[c
] != 0) {
2655 XPutPixel(image
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2657 XPutPixel(shapeimage
, x
, y
,
2658 shape_pixels
[colidx
[c
] - 1]);
2663 GpiSetColor(hps
, (LONG
)image_pixels
[colidx
[c
] - 1]);
2664 GpiSetPel(hps
, &point
);
2666 SetPixel(*dc
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2672 GpiSetColor(hps
, (LONG
)shape_pixels
[colidx
[c
] - 1]);
2673 GpiSetPel(hps
, &point
);
2675 SetPixel(shapedc
, x
, y
, shape_pixels
[colidx
[c
] - 1]);
2680 return (XpmFileInvalid
);
2686 GpiSetBitmap(hps
, sobm
);
2687 DevCloseDC(shapedc
);
2689 SelectObject(shapedc
, sobm
);
2694 GpiSetBitmap(hps
, obm
);
2696 SelectObject(*dc
, obm
);
2702 case (2): /* Optimize for double character
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]);}
2709 /* array of pointers malloced by need */
2710 unsigned short *cidx
[256];
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 */
2721 return (XpmNoMemory
);
2724 cidx
[char1
][(unsigned char)colorTable
[a
].string
[1]] = a
+ 1;
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) {
2736 XPutPixel(image
, x
, y
,
2737 image_pixels
[cidx
[cc1
][cc2
] - 1]);
2739 XPutPixel(shapeimage
, x
, y
,
2740 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2743 *dc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2744 hps
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2746 GpiSetBitmap(hps
, image
->bitmap
);
2749 GpiSetColor(hps
, (LONG
)image_pixels
[cidx
[cc1
][cc2
] - 1]);
2750 GpiSetPel(hps
, &point
);
2752 SelectObject(*dc
, image
->bitmap
);
2753 SetPixel(*dc
, x
, y
, image_pixels
[cidx
[cc1
][cc2
] - 1]);
2757 GpiSetBitmap(hps
, shapeimage
->bitmap
);
2760 GpiSetColor(hps
, (LONG
)shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2761 GpiSetPel(hps
, &point
);
2763 SelectObject(*dc
, shapeimage
->bitmap
);
2765 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2771 return (XpmFileInvalid
);
2775 return (XpmFileInvalid
);
2783 default: /* Non-optimized case of long color
2790 if (USE_HASHTABLE
) {
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
++)
2798 slot
= xpmHashSlot(hashtable
, buf
);
2799 if (!*slot
) /* no color matches */
2800 return (XpmFileInvalid
);
2802 XPutPixel(image
, x
, y
,
2803 image_pixels
[HashColorIndex(slot
)]);
2805 XPutPixel(shapeimage
, x
, y
,
2806 shape_pixels
[HashColorIndex(slot
)]);
2809 *dc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2810 hps
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2812 GpiSetBitmap(hps
, image
->bitmap
);
2815 GpiSetColor(hps
, (LONG
)image_pixels
[HashColorIndex(slot
)]);
2816 GpiSetPel(hps
, &point
);
2818 SelectObject(*dc
, image
->bitmap
);
2820 image_pixels
[HashColorIndex(slot
)]);
2824 GpiSetBitmap(hps
, shapeimage
->bitmap
);
2827 GpiSetColor(hps
, (LONG
)shape_pixels
[HashColorIndex(slot
)]);
2828 GpiSetPel(hps
, &point
);
2830 SelectObject(*dc
, shapeimage
->bitmap
);
2832 shape_pixels
[HashColorIndex(slot
)]);
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
++)
2844 for (a
= 0; a
< ncolors
; a
++)
2845 if (!strcmp(colorTable
[a
].string
, buf
))
2847 if (a
== ncolors
) /* no color matches */
2848 return (XpmFileInvalid
);
2850 XPutPixel(image
, x
, y
, image_pixels
[a
]);
2852 XPutPixel(shapeimage
, x
, y
, shape_pixels
[a
]);
2855 *dc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2856 hps
= GpiCreatePS(hab
, *dc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2858 GpiSetBitmap(hps
, image
->bitmap
);
2861 GpiSetColor(hps
, (LONG
)image_pixels
[a
]);
2862 GpiSetPel(hps
, &point
);
2864 SelectObject(*dc
, image
->bitmap
);
2865 SetPixel(*dc
, x
, y
, image_pixels
[a
]);
2869 GpiSetBitmap(hps
, image
->bitmap
);
2872 GpiSetColor(hps
, (LONG
)shape_pixels
[a
]);
2873 GpiSetPel(hps
, &point
);
2875 SelectObject(*dc
, shapeimage
->bitmap
);
2876 SetPixel(*dc
, x
, y
, shape_pixels
[a
]);
2886 return (XpmSuccess
);