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 */
144 LFUNC(MSWPutImagePixels
, void, (Display
*dc
, XImage
*image
,
145 unsigned int width
, unsigned int height
,
146 unsigned int *pixelindex
, Pixel
*pixels
));
149 #ifdef NEED_STRCASECMP
150 FUNC(xpmstrcasecmp
, int, (char *s1
, char *s2
));
153 * in case strcasecmp is not provided by the system here is one
154 * which does the trick
157 /* Visual Age cannot deal with old, non-ansi, code */
158 int xpmstrcasecmp(register char* s1
, register char* s2
)
161 xpmstrcasecmp(s1
, s2
)
162 register char *s1
, *s2
;
175 return (int) (*s1
- *s2
);
181 * return the default color key related to the given visual
184 /* Visual Age cannot deal with old, non-ansi, code */
185 static int xpmVisualType(Visual
* visual
)
188 xpmVisualType(visual
)
194 switch (visual
->class) {
197 switch (visual
->map_entries
) {
209 /* set the key explicitly in the XpmAttributes to override this */
213 /* there should be a similar switch for MSW */
225 static int closeness_cmp(Const
void* a
, Const
void* b
)
227 CloseColor
*x
= (CloseColor
*) a
, *y
= (CloseColor
*) b
;
229 /* cast to int as qsort requires */
230 return (int) (x
->closeness
- y
->closeness
);
235 /* default AllocColor function:
236 * call XParseColor if colorname is given, return negative value if failure
237 * call XAllocColor and return 0 if failure, positive otherwise
240 /* Visual Age cannot deal with old, non-ansi, code */
251 AllocColor(display
, colormap
, colorname
, xcolor
, closure
)
256 void *closure
; /* not used */
262 if (!XParseColor(display
, &colormap
, colorname
, xcolor
))
264 status
= XAllocColor(display
, &colormap
, xcolor
);
266 if (!XParseColor(display
, colormap
, colorname
, xcolor
))
268 status
= XAllocColor(display
, colormap
, xcolor
);
270 return status
!= 0 ? 1 : 0;
276 * set a close color in case the exact one can't be set
277 * return 0 if success, 1 otherwise.
281 SetCloseColor(display
, colormap
, visual
, col
, image_pixel
, mask_pixel
,
282 alloc_pixels
, nalloc_pixels
, attributes
, cols
, ncols
,
288 Pixel
*image_pixel
, *mask_pixel
;
290 unsigned int *nalloc_pixels
;
291 XpmAttributes
*attributes
;
294 XpmAllocColorFunc allocColor
;
299 * Allocation failed, so try close colors. To get here the visual must
300 * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
301 * What about sharing systems like QDSS?). Beware: we have to treat
302 * DirectColor differently.
306 long int red_closeness
, green_closeness
, blue_closeness
;
310 if (attributes
&& (attributes
->valuemask
& XpmCloseness
))
311 red_closeness
= green_closeness
= blue_closeness
=
312 attributes
->closeness
;
314 red_closeness
= attributes
->red_closeness
;
315 green_closeness
= attributes
->green_closeness
;
316 blue_closeness
= attributes
->blue_closeness
;
318 if (attributes
&& (attributes
->valuemask
& XpmAllocCloseColors
))
319 alloc_color
= attributes
->alloc_close_colors
;
324 * We sort the colormap by closeness and try to allocate the color
325 * closest to the target. If the allocation of this close color fails,
326 * which almost never happens, then one of two scenarios is possible.
327 * Either the colormap must have changed (since the last close color
328 * allocation or possibly while we were sorting the colormap), or the
329 * color is allocated as Read/Write by some other client. (Note: X
330 * _should_ allow clients to check if a particular color is Read/Write,
331 * but it doesn't! :-( ). We cannot determine which of these scenarios
332 * occurred, so we try the next closest color, and so on, until no more
333 * colors are within closeness of the target. If we knew that the
334 * colormap had changed, we could skip this sequence.
336 * If _none_ of the colors within closeness of the target can be allocated,
337 * then we can finally be pretty sure that the colormap has actually
338 * changed. In this case we try to allocate the original color (again),
339 * then try the closecolor stuff (again)...
341 * In theory it would be possible for an infinite loop to occur if another
342 * process kept changing the colormap every time we sorted it, so we set
343 * a maximum on the number of iterations. After this many tries, we use
344 * XGrabServer() to ensure that the colormap remains unchanged.
346 * This approach gives particularly bad worst case performance - as many as
347 * <MaximumIterations> colormap reads and sorts may be needed, and as
348 * many as <MaximumIterations> * <ColormapSize> attempted allocations
349 * may fail. On an 8-bit system, this means as many as 3 colormap reads,
350 * 3 sorts and 768 failed allocations per execution of this code!
351 * Luckily, my experiments show that in general use in a typical 8-bit
352 * color environment only about 1 in every 10000 allocations fails to
353 * succeed in the fastest possible time. So virtually every time what
354 * actually happens is a single sort followed by a successful allocate.
355 * The very first allocation also costs a colormap read, but no further
356 * reads are usually necessary.
359 #define ITERATIONS 2 /* more than one is almost never
362 for (n
= 0; n
<= ITERATIONS
; ++n
) {
363 CloseColor
*closenesses
=
364 (CloseColor
*) XpmCalloc(ncols
, sizeof(CloseColor
));
367 for (i
= 0; i
< ncols
; ++i
) { /* build & sort closenesses table */
368 #define COLOR_FACTOR 3
369 #define BRIGHTNESS_FACTOR 1
371 closenesses
[i
].cols_index
= i
;
372 closenesses
[i
].closeness
=
373 COLOR_FACTOR
* (abs((long) col
->red
- (long) cols
[i
].red
)
374 + abs((long) col
->green
- (long) cols
[i
].green
)
375 + abs((long) col
->blue
- (long) cols
[i
].blue
))
376 + BRIGHTNESS_FACTOR
* abs(((long) col
->red
+
379 - ((long) cols
[i
].red
+
380 (long) cols
[i
].green
+
381 (long) cols
[i
].blue
));
383 qsort(closenesses
, ncols
, sizeof(CloseColor
), closeness_cmp
);
386 c
= closenesses
[i
].cols_index
;
387 while ((long) cols
[c
].red
>= (long) col
->red
- red_closeness
&&
388 (long) cols
[c
].red
<= (long) col
->red
+ red_closeness
&&
389 (long) cols
[c
].green
>= (long) col
->green
- green_closeness
&&
390 (long) cols
[c
].green
<= (long) col
->green
+ green_closeness
&&
391 (long) cols
[c
].blue
>= (long) col
->blue
- blue_closeness
&&
392 (long) cols
[c
].blue
<= (long) col
->blue
+ blue_closeness
) {
394 if ((*allocColor
)(display
, colormap
, NULL
, &cols
[c
], closure
)){
396 XUngrabServer(display
);
397 XpmFree(closenesses
);
398 *image_pixel
= cols
[c
].pixel
;
400 alloc_pixels
[(*nalloc_pixels
)++] = cols
[c
].pixel
;
406 c
= closenesses
[i
].cols_index
;
410 XUngrabServer(display
);
411 XpmFree(closenesses
);
412 *image_pixel
= cols
[c
].pixel
;
418 /* Couldn't allocate _any_ of the close colors! */
421 XUngrabServer(display
);
422 XpmFree(closenesses
);
424 if (i
== 0 || i
== ncols
) /* no color close enough or cannot */
425 return (1); /* alloc any color (full of r/w's) */
427 if ((*allocColor
)(display
, colormap
, NULL
, col
, closure
)) {
428 *image_pixel
= col
->pixel
;
430 alloc_pixels
[(*nalloc_pixels
)++] = col
->pixel
;
432 } else { /* colormap has probably changed, so
434 if (n
== ITERATIONS
- 1)
435 XGrabServer(display
);
438 if (visual
->class == DirectColor
) {
442 XQueryColors(display
, colormap
, cols
, ncols
);
448 #define USE_CLOSECOLOR attributes && \
449 (((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
450 || ((attributes->valuemask & XpmRGBCloseness) && \
451 (attributes->red_closeness != 0 \
452 || attributes->green_closeness != 0 \
453 || attributes->blue_closeness != 0)))
457 /* nothing to do here, the window system does it */
461 * set the color pixel related to the given colorname,
462 * return 0 if success, 1 otherwise.
466 /* Visual Age cannot deal with old, non-ansi, code */
473 , unsigned int color_index
476 , unsigned int* mask_pixel_index
477 , Pixel
* alloc_pixels
478 , unsigned int* nalloc_pixels
480 , unsigned int* nused_pixels
481 , XpmAttributes
* attributes
484 , XpmAllocColorFunc allocColor
489 SetColor(display
, colormap
, visual
, colorname
, color_index
,
490 image_pixel
, mask_pixel
, mask_pixel_index
,
491 alloc_pixels
, nalloc_pixels
, used_pixels
, nused_pixels
,
492 attributes
, cols
, ncols
, allocColor
, closure
)
497 unsigned int color_index
;
498 Pixel
*image_pixel
, *mask_pixel
;
499 unsigned int *mask_pixel_index
;
501 unsigned int *nalloc_pixels
;
503 unsigned int *nused_pixels
;
504 XpmAttributes
*attributes
;
507 XpmAllocColorFunc allocColor
;
514 if (xpmstrcasecmp(colorname
, TRANSPARENT_COLOR
)) {
515 status
= (*allocColor
)(display
, colormap
, colorname
, &xcolor
, closure
);
516 if (status
< 0) /* parse color failed */
522 return (SetCloseColor(display
, colormap
, visual
, &xcolor
,
523 image_pixel
, mask_pixel
,
524 alloc_pixels
, nalloc_pixels
,
525 attributes
, cols
, ncols
,
526 allocColor
, closure
));
528 #endif /* ndef FOR_MSW */
531 alloc_pixels
[(*nalloc_pixels
)++] = xcolor
.pixel
;
532 *image_pixel
= xcolor
.pixel
;
537 *mask_pixel
= OS2RGB(0,0,0);
539 *mask_pixel
= RGB(0,0,0);
542 used_pixels
[(*nused_pixels
)++] = xcolor
.pixel
;
549 *mask_pixel
= OS2RGB(255,255,255);
551 *mask_pixel
= RGB(255,255,255);
554 /* store the color table index */
555 *mask_pixel_index
= color_index
;
561 /* Visual Age cannot deal with old, non-ansi, code */
565 , XpmAttributes
* attributes
567 , unsigned int ncolors
568 , Pixel
* image_pixels
570 , unsigned int* mask_pixel_index
571 , Pixel
* alloc_pixels
572 , unsigned int* nalloc_pixels
574 , unsigned int* nused_pixels
578 CreateColors(display
, attributes
, colors
, ncolors
, image_pixels
, mask_pixels
,
579 mask_pixel_index
, alloc_pixels
, nalloc_pixels
,
580 used_pixels
, nused_pixels
)
582 XpmAttributes
*attributes
;
584 unsigned int ncolors
;
587 unsigned int *mask_pixel_index
;
589 unsigned int *nalloc_pixels
;
591 unsigned int *nused_pixels
;
594 /* variables stored in the XpmAttributes structure */
597 XpmColorSymbol
*colorsymbols
;
598 unsigned int numsymbols
;
599 XpmAllocColorFunc allocColor
;
603 unsigned int color
, key
;
605 XpmColorSymbol
*symbol
;
607 int ErrorStatus
= XpmSuccess
;
612 unsigned int ncols
= 0;
615 * retrieve information from the XpmAttributes
617 if (attributes
&& attributes
->valuemask
& XpmColorSymbols
) {
618 colorsymbols
= attributes
->colorsymbols
;
619 numsymbols
= attributes
->numsymbols
;
623 if (attributes
&& attributes
->valuemask
& XpmVisual
)
624 visual
= attributes
->visual
;
626 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
628 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
629 colormap
= attributes
->colormap
;
631 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
633 if (attributes
&& (attributes
->valuemask
& XpmColorKey
))
634 key
= attributes
->color_key
;
636 key
= xpmVisualType(visual
);
638 if (attributes
&& (attributes
->valuemask
& XpmAllocColor
))
639 allocColor
= attributes
->alloc_color
;
641 allocColor
= AllocColor
;
642 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
643 closure
= attributes
->color_closure
;
648 if (USE_CLOSECOLOR
) {
649 /* originally from SetCloseColor */
651 if (visual
->class == DirectColor
) {
654 * TODO: Implement close colors for DirectColor visuals. This is
655 * difficult situation. Chances are that we will never get here,
656 * because any machine that supports DirectColor will probably
657 * also support TrueColor (and probably PseudoColor). Also,
658 * DirectColor colormaps can be very large, so looking for close
659 * colors may be too slow.
666 ncols
= visual
->map_entries
;
668 ncols
= colormap
->Count
;
670 cols
= (XColor
*) XpmCalloc(ncols
, sizeof(XColor
));
671 for (i
= 0; i
< ncols
; ++i
)
673 XQueryColors(display
, colormap
, cols
, ncols
);
678 #endif /* ndef FOR_MSW */
696 for (color
= 0; color
< ncolors
; color
++, colors
++,
697 image_pixels
++, mask_pixels
++) {
699 pixel_defined
= False
;
700 defaults
= (char **) colors
;
703 * look for a defined symbol
710 for (n
= 0, symbol
= colorsymbols
; n
< numsymbols
; n
++, symbol
++) {
711 if (symbol
->name
&& s
&& !strcmp(symbol
->name
, s
))
714 if (!symbol
->name
&& symbol
->value
) { /* override value */
715 int def_index
= default_index
;
717 while (defaults
[def_index
] == NULL
) /* find defined
720 if (def_index
< 2) {/* nothing towards mono, so try
722 def_index
= default_index
+ 1;
723 while (def_index
<= 5 && defaults
[def_index
] == NULL
)
726 if (def_index
>= 2 && defaults
[def_index
] != NULL
&&
727 !xpmstrcasecmp(symbol
->value
, defaults
[def_index
]))
731 if (n
!= numsymbols
) {
732 if (symbol
->name
&& symbol
->value
)
733 colorname
= symbol
->value
;
735 pixel_defined
= True
;
738 if (!pixel_defined
) { /* pixel not given as symbol value */
742 if (colorname
) { /* colorname given as symbol value */
743 if (!SetColor(display
, colormap
, visual
, colorname
, color
,
744 image_pixels
, mask_pixels
, mask_pixel_index
,
745 alloc_pixels
, nalloc_pixels
, used_pixels
,
746 nused_pixels
, attributes
, cols
, ncols
,
747 allocColor
, closure
))
748 pixel_defined
= True
;
750 ErrorStatus
= XpmColorError
;
753 while (!pixel_defined
&& k
> 1) {
755 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
756 color
, image_pixels
, mask_pixels
,
757 mask_pixel_index
, alloc_pixels
,
758 nalloc_pixels
, used_pixels
, nused_pixels
,
759 attributes
, cols
, ncols
,
760 allocColor
, closure
)) {
761 pixel_defined
= True
;
764 ErrorStatus
= XpmColorError
;
769 while (!pixel_defined
&& k
< NKEYS
+ 1) {
771 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
772 color
, image_pixels
, mask_pixels
,
773 mask_pixel_index
, alloc_pixels
,
774 nalloc_pixels
, used_pixels
, nused_pixels
,
775 attributes
, cols
, ncols
,
776 allocColor
, closure
)) {
777 pixel_defined
= True
;
780 ErrorStatus
= XpmColorError
;
784 if (!pixel_defined
) {
787 return (XpmColorFailed
);
790 /* simply use the given pixel */
791 *image_pixels
= symbol
->pixel
;
792 /* the following makes the mask to be built even if none
793 is given a particular pixel */
795 && !xpmstrcasecmp(symbol
->value
, TRANSPARENT_COLOR
)) {
797 *mask_pixel_index
= color
;
800 used_pixels
[(*nused_pixels
)++] = *image_pixels
;
805 return (ErrorStatus
);
809 /* default FreeColors function, simply call XFreeColors */
811 /* Visual Age cannot deal with old, non-ansi, code */
822 FreeColors(display
, colormap
, pixels
, n
, closure
)
827 void *closure
; /* not used */
830 return XFreeColors(display
, colormap
, pixels
, n
, 0);
834 /* function call in case of error */
836 #define RETURN(status) \
838 ErrorStatus = status; \
843 /* Visual Age cannot deal with old, non-ansi, code */
844 int XpmCreateImageFromXpmImage(
847 , XImage
** image_return
848 , XImage
** shapeimage_return
849 , XpmAttributes
* attributes
853 XpmCreateImageFromXpmImage(display
, image
,
854 image_return
, shapeimage_return
, attributes
)
857 XImage
**image_return
;
858 XImage
**shapeimage_return
;
859 XpmAttributes
*attributes
;
863 HAB hab
= WinQueryAnchorBlock(HWND_DESKTOP
);
867 /* variables stored in the XpmAttributes structure */
872 XpmFreeColorsFunc freeColors
;
875 /* variables to return */
876 XImage
*ximage
= NULL
;
877 XImage
*shapeimage
= NULL
;
878 unsigned int mask_pixel_index
= XpmUndefPixel
;
881 /* calculation variables */
882 Pixel
*image_pixels
= NULL
;
883 Pixel
*mask_pixels
= NULL
;
884 Pixel
*alloc_pixels
= NULL
;
885 Pixel
*used_pixels
= NULL
;
886 unsigned int nalloc_pixels
= 0;
887 unsigned int nused_pixels
= 0;
889 /* initialize return values */
891 *image_return
= NULL
;
892 if (shapeimage_return
)
893 *shapeimage_return
= NULL
;
895 /* retrieve information from the XpmAttributes */
896 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
897 visual
= attributes
->visual
;
899 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
901 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
902 colormap
= attributes
->colormap
;
904 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
906 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
907 depth
= attributes
->depth
;
909 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
911 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
912 bitmap_format
= attributes
->bitmap_format
;
914 bitmap_format
= ZPixmap
;
916 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
917 freeColors
= attributes
->free_colors
;
919 freeColors
= FreeColors
;
920 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
921 closure
= attributes
->color_closure
;
925 ErrorStatus
= XpmSuccess
;
927 /* malloc pixels index tables */
928 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
930 return (XpmNoMemory
);
932 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
936 /* maximum of allocated pixels will be the number of colors */
937 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
941 /* maximum of allocated pixels will be the number of colors */
942 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
946 /* get pixel colors, store them in index tables */
947 ErrorStatus
= CreateColors(display
, attributes
, image
->colorTable
,
948 image
->ncolors
, image_pixels
, mask_pixels
,
949 &mask_pixel_index
, alloc_pixels
, &nalloc_pixels
,
950 used_pixels
, &nused_pixels
);
952 if (ErrorStatus
!= XpmSuccess
953 && (ErrorStatus
< 0 || (attributes
954 && (attributes
->valuemask
& XpmExactColors
)
955 && attributes
->exactColors
)))
958 /* create the ximage */
960 ErrorStatus
= CreateXImage(display
, visual
, depth
,
961 (depth
== 1 ? bitmap_format
: ZPixmap
),
962 image
->width
, image
->height
, &ximage
);
963 if (ErrorStatus
!= XpmSuccess
)
970 * set the ximage data using optimized functions for ZPixmap
973 if (ximage
->bits_per_pixel
== 8)
974 PutImagePixels8(ximage
, image
->width
, image
->height
,
975 image
->data
, image_pixels
);
976 else if (((ximage
->bits_per_pixel
| ximage
->depth
) == 1) &&
977 (ximage
->byte_order
== ximage
->bitmap_bit_order
))
978 PutImagePixels1(ximage
, image
->width
, image
->height
,
979 image
->data
, image_pixels
);
980 else if (ximage
->bits_per_pixel
== 16)
981 PutImagePixels16(ximage
, image
->width
, image
->height
,
982 image
->data
, image_pixels
);
983 else if (ximage
->bits_per_pixel
== 32)
984 PutImagePixels32(ximage
, image
->width
, image
->height
,
985 image
->data
, image_pixels
);
987 PutImagePixels(ximage
, image
->width
, image
->height
,
988 image
->data
, image_pixels
);
990 APutImagePixels(ximage
, image
->width
, image
->height
,
991 image
->data
, image_pixels
);
994 MSWPutImagePixels(display
, ximage
, image
->width
, image
->height
,
995 image
->data
, image_pixels
);
998 /* create the shape mask image */
999 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
1000 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
1001 image
->width
, image
->height
, &shapeimage
);
1002 if (ErrorStatus
!= XpmSuccess
)
1003 RETURN(ErrorStatus
);
1007 PutImagePixels1(shapeimage
, image
->width
, image
->height
,
1008 image
->data
, mask_pixels
);
1010 APutImagePixels(shapeimage
, image
->width
, image
->height
,
1011 image
->data
, mask_pixels
);
1014 MSWPutImagePixels(display
, shapeimage
, image
->width
, image
->height
,
1015 image
->data
, mask_pixels
);
1019 XpmFree(image_pixels
);
1020 XpmFree(mask_pixels
);
1022 /* if requested return used pixels in the XpmAttributes structure */
1023 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
1024 /* 3.2 backward compatibility code */
1025 attributes
->valuemask
& XpmReturnInfos
)) {
1027 attributes
->pixels
= used_pixels
;
1028 attributes
->npixels
= nused_pixels
;
1029 attributes
->mask_pixel
= mask_pixel_index
;
1031 XpmFree(used_pixels
);
1033 /* if requested return alloc'ed pixels in the XpmAttributes structure */
1034 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
1035 attributes
->alloc_pixels
= alloc_pixels
;
1036 attributes
->nalloc_pixels
= nalloc_pixels
;
1038 XpmFree(alloc_pixels
);
1040 /* return created images */
1042 *image_return
= ximage
;
1043 if (shapeimage_return
)
1044 *shapeimage_return
= shapeimage
;
1046 return (ErrorStatus
);
1048 /* exit point in case of error, free only locally allocated variables */
1051 XDestroyImage(ximage
);
1053 XDestroyImage(shapeimage
);
1055 XpmFree(image_pixels
);
1057 XpmFree(mask_pixels
);
1059 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
1061 XpmFree(alloc_pixels
);
1063 XpmFree(used_pixels
);
1065 return (ErrorStatus
);
1070 * Create an XImage with its data
1073 /* Visual Age cannot deal with old, non-ansi, code */
1074 static int CreateXImage(
1077 , unsigned int depth
1079 , unsigned int width
1080 , unsigned int height
1081 , XImage
** image_return
1085 CreateXImage(display
, visual
, depth
, format
, width
, height
, image_return
)
1091 unsigned int height
;
1092 XImage
**image_return
;
1097 /* first get bitmap_pad */
1105 /* then create the XImage with data = NULL and bytes_per_line = 0 */
1106 *image_return
= XCreateImage(display
, visual
, depth
, format
, 0, 0,
1107 width
, height
, bitmap_pad
, 0);
1109 return (XpmNoMemory
);
1111 #if !defined(FOR_MSW) && !defined(AMIGA)
1112 /* now that bytes_per_line must have been set properly alloc data */
1113 (*image_return
)->data
=
1114 (char *) XpmMalloc((*image_return
)->bytes_per_line
* height
);
1116 if (!(*image_return
)->data
) {
1117 XDestroyImage(*image_return
);
1118 *image_return
= NULL
;
1119 return (XpmNoMemory
);
1122 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1124 return (XpmSuccess
);
1130 * The functions below are written from X11R5 MIT's code (XImUtil.c)
1132 * The idea is to have faster functions than the standard XPutPixel function
1133 * to build the image data. Indeed we can speed up things by suppressing tests
1134 * performed for each pixel. We do the same tests but at the image level.
1135 * We also assume that we use only ZPixmap images with null offsets.
1138 LFUNC(_putbits
, void, (register char *src
, int dstoffset
,
1139 register int numbits
, register char *dst
));
1141 LFUNC(_XReverse_Bytes
, int, (register unsigned char *bpt
, register int nb
));
1143 static unsigned char Const _reverse_byte
[0x100] = {
1144 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1145 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1146 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1147 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1148 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1149 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1150 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1151 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1152 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1153 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1154 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1155 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1156 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1157 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1158 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1159 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1160 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1161 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1162 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1163 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1164 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1165 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1166 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1167 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1168 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1169 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1170 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1171 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1172 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1173 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1174 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1175 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1179 /* Visual Age cannot deal with old, non-ansi, code */
1181 _XReverse_Bytes(register unsigned char* bpt
, register int nb
)
1184 _XReverse_Bytes(bpt
, nb
)
1185 register unsigned char *bpt
;
1190 *bpt
= _reverse_byte
[*bpt
];
1198 /* Visual Age cannot deal with old, non-ansi, code */
1199 void xpm_xynormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1202 xpm_xynormalizeimagebits(bp
, img
)
1203 register unsigned char *bp
;
1204 register XImage
*img
;
1207 register unsigned char c
;
1209 if (img
->byte_order
!= img
->bitmap_bit_order
) {
1210 switch (img
->bitmap_unit
) {
1223 *(bp
+ 2) = *(bp
+ 1);
1228 if (img
->bitmap_bit_order
== MSBFirst
)
1229 _XReverse_Bytes(bp
, img
->bitmap_unit
>> 3);
1233 /* Visual Age cannot deal with old, non-ansi, code */
1234 void xpm_znormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1237 xpm_znormalizeimagebits(bp
, img
)
1238 register unsigned char *bp
;
1239 register XImage
*img
;
1242 register unsigned char c
;
1244 switch (img
->bits_per_pixel
) {
1247 _XReverse_Bytes(bp
, 1);
1251 *bp
= ((*bp
>> 4) & 0xF) | ((*bp
<< 4) & ~0xF);
1271 *(bp
+ 2) = *(bp
+ 1);
1277 static unsigned char Const _lomask
[0x09] = {
1278 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1279 static unsigned char Const _himask
[0x09] = {
1280 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
1283 /* Visual Age cannot deal with old, non-ansi, code */
1284 static void _putbits(
1287 , register int numbits
1288 , register char* dst
1292 _putbits(src
, dstoffset
, numbits
, dst
)
1293 register char *src
; /* address of source bit string */
1294 int dstoffset
; /* bit offset into destination;
1296 register int numbits
; /* number of bits to copy to
1298 register char *dst
; /* address of destination bit string */
1301 register unsigned char chlo
, chhi
;
1304 dst
= dst
+ (dstoffset
>> 3);
1305 dstoffset
= dstoffset
& 7;
1306 hibits
= 8 - dstoffset
;
1307 chlo
= *dst
& _lomask
[dstoffset
];
1309 chhi
= (*src
<< dstoffset
) & _himask
[dstoffset
];
1310 if (numbits
<= hibits
) {
1311 chhi
= chhi
& _lomask
[dstoffset
+ numbits
];
1312 *dst
= (*dst
& _himask
[dstoffset
+ numbits
]) | chlo
| chhi
;
1317 numbits
= numbits
- hibits
;
1318 chlo
= (unsigned char) (*src
& _himask
[hibits
]) >> hibits
;
1320 if (numbits
<= dstoffset
) {
1321 chlo
= chlo
& _lomask
[numbits
];
1322 *dst
= (*dst
& _himask
[numbits
]) | chlo
;
1325 numbits
= numbits
- dstoffset
;
1330 * Default method to write pixels into a Z image data structure.
1331 * The algorithm used is:
1333 * copy the destination bitmap_unit or Zpixel to temp
1334 * normalize temp if needed
1335 * copy the pixel bits into the temp
1336 * renormalize temp if needed
1337 * copy the temp back into the destination image data
1341 /* Visual Age cannot deal with old, non-ansi, code */
1342 static void PutImagePixels(
1344 , unsigned int width
1345 , unsigned int height
1346 , unsigned int* pixelindex
1351 PutImagePixels(image
, width
, height
, pixelindex
, pixels
)
1354 unsigned int height
;
1355 unsigned int *pixelindex
;
1361 register unsigned int *iptr
;
1362 register int x
, y
, i
;
1363 register char *data
;
1365 int nbytes
, depth
, ibu
, ibpp
;
1369 depth
= image
->depth
;
1371 ibu
= image
->bitmap_unit
;
1372 for (y
= 0; y
< height
; y
++)
1373 for (x
= 0; x
< width
; x
++, iptr
++) {
1374 pixel
= pixels
[*iptr
];
1375 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long);
1377 ((unsigned char *) &pixel
)[i
] = px
;
1378 src
= &data
[XYINDEX(x
, y
, image
)];
1382 for (i
= nbytes
; --i
>= 0;)
1384 XYNORMALIZE(&px
, image
);
1385 _putbits((char *) &pixel
, (x
% ibu
), 1, (char *) &px
);
1386 XYNORMALIZE(&px
, image
);
1388 dst
= &data
[XYINDEX(x
, y
, image
)];
1389 for (i
= nbytes
; --i
>= 0;)
1393 ibpp
= image
->bits_per_pixel
;
1394 for (y
= 0; y
< height
; y
++)
1395 for (x
= 0; x
< width
; x
++, iptr
++) {
1396 pixel
= pixels
[*iptr
];
1399 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++,
1401 ((unsigned char *) &pixel
)[i
] = px
;
1402 src
= &data
[ZINDEX(x
, y
, image
)];
1405 nbytes
= (ibpp
+ 7) >> 3;
1406 for (i
= nbytes
; --i
>= 0;)
1408 ZNORMALIZE(&px
, image
);
1409 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
1410 ZNORMALIZE(&px
, image
);
1412 dst
= &data
[ZINDEX(x
, y
, image
)];
1413 for (i
= nbytes
; --i
>= 0;)
1420 * write pixels into a 32-bits Z image data structure
1423 #if !defined(WORD64) && !defined(LONG64)
1424 /* this item is static but deterministic so let it slide; doesn't
1425 * hurt re-entrancy of this library. Note if it is actually const then would
1426 * be OK under rules of ANSI-C but probably not C++ which may not
1427 * want to allocate space for it.
1429 static unsigned long byteorderpixel
= MSBFirst
<< 24;
1434 WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
1435 3.2e code - by default you get the speeded-up version.
1439 /* Visual Age cannot deal with old, non-ansi, code */
1443 , unsigned int width
1444 , unsigned int height
1445 , unsigned int* pixelindex
1450 PutImagePixels32(image
, width
, height
, pixelindex
, pixels
)
1453 unsigned int height
;
1454 unsigned int *pixelindex
;
1458 unsigned char *data
;
1463 #ifdef WITHOUT_SPEEDUPS
1466 unsigned char *addr
;
1468 data
= (unsigned char *) image
->data
;
1470 #if !defined(WORD64) && !defined(LONG64)
1471 if (*((char *) &byteorderpixel
) == image
->byte_order
) {
1472 for (y
= 0; y
< height
; y
++)
1473 for (x
= 0; x
< width
; x
++, iptr
++) {
1474 addr
= &data
[ZINDEX32(x
, y
, image
)];
1475 *((unsigned long *) addr
) = pixels
[*iptr
];
1479 if (image
->byte_order
== MSBFirst
)
1480 for (y
= 0; y
< height
; y
++)
1481 for (x
= 0; x
< width
; x
++, iptr
++) {
1482 addr
= &data
[ZINDEX32(x
, y
, image
)];
1483 pixel
= pixels
[*iptr
];
1484 addr
[0] = pixel
>> 24;
1485 addr
[1] = pixel
>> 16;
1486 addr
[2] = pixel
>> 8;
1490 for (y
= 0; y
< height
; y
++)
1491 for (x
= 0; x
< width
; x
++, iptr
++) {
1492 addr
= &data
[ZINDEX32(x
, y
, image
)];
1493 pixel
= pixels
[*iptr
];
1495 addr
[1] = pixel
>> 8;
1496 addr
[2] = pixel
>> 16;
1497 addr
[3] = pixel
>> 24;
1500 #else /* WITHOUT_SPEEDUPS */
1502 int bpl
= image
->bytes_per_line
;
1503 unsigned char *data_ptr
, *max_data
;
1505 data
= (unsigned char *) image
->data
;
1507 #if !defined(WORD64) && !defined(LONG64)
1508 if (*((char *) &byteorderpixel
) == image
->byte_order
) {
1509 for (y
= 0; y
< height
; y
++) {
1511 max_data
= data_ptr
+ (width
<< 2);
1513 while (data_ptr
< max_data
) {
1514 *((unsigned long *) data_ptr
) = pixels
[*(iptr
++)];
1515 data_ptr
+= (1 << 2);
1521 if (image
->byte_order
== MSBFirst
)
1522 for (y
= 0; y
< height
; y
++) {
1524 max_data
= data_ptr
+ (width
<< 2);
1526 while (data_ptr
< max_data
) {
1527 pixel
= pixels
[*(iptr
++)];
1529 *data_ptr
++ = pixel
>> 24;
1530 *data_ptr
++ = pixel
>> 16;
1531 *data_ptr
++ = pixel
>> 8;
1532 *data_ptr
++ = pixel
;
1538 for (y
= 0; y
< height
; y
++) {
1540 max_data
= data_ptr
+ (width
<< 2);
1542 while (data_ptr
< max_data
) {
1543 pixel
= pixels
[*(iptr
++)];
1545 *data_ptr
++ = pixel
;
1546 *data_ptr
++ = pixel
>> 8;
1547 *data_ptr
++ = pixel
>> 16;
1548 *data_ptr
++ = pixel
>> 24;
1553 #endif /* WITHOUT_SPEEDUPS */
1557 * write pixels into a 16-bits Z image data structure
1561 /* Visual Age cannot deal with old, non-ansi, code */
1562 static void PutImagePixels16(
1564 , unsigned int width
1565 , unsigned int height
1566 , unsigned int* pixelindex
1571 PutImagePixels16(image
, width
, height
, pixelindex
, pixels
)
1574 unsigned int height
;
1575 unsigned int *pixelindex
;
1579 unsigned char *data
;
1583 #ifdef WITHOUT_SPEEDUPS
1586 unsigned char *addr
;
1588 data
= (unsigned char *) image
->data
;
1590 if (image
->byte_order
== MSBFirst
)
1591 for (y
= 0; y
< height
; y
++)
1592 for (x
= 0; x
< width
; x
++, iptr
++) {
1593 addr
= &data
[ZINDEX16(x
, y
, image
)];
1594 addr
[0] = pixels
[*iptr
] >> 8;
1595 addr
[1] = pixels
[*iptr
];
1598 for (y
= 0; y
< height
; y
++)
1599 for (x
= 0; x
< width
; x
++, iptr
++) {
1600 addr
= &data
[ZINDEX16(x
, y
, image
)];
1601 addr
[0] = pixels
[*iptr
];
1602 addr
[1] = pixels
[*iptr
] >> 8;
1605 #else /* WITHOUT_SPEEDUPS */
1609 int bpl
= image
->bytes_per_line
;
1610 unsigned char *data_ptr
, *max_data
;
1612 data
= (unsigned char *) image
->data
;
1614 if (image
->byte_order
== MSBFirst
)
1615 for (y
= 0; y
< height
; y
++) {
1617 max_data
= data_ptr
+ (width
<< 1);
1619 while (data_ptr
< max_data
) {
1620 pixel
= pixels
[*(iptr
++)];
1622 data_ptr
[0] = pixel
>> 8;
1623 data_ptr
[1] = pixel
;
1625 data_ptr
+= (1 << 1);
1630 for (y
= 0; y
< height
; y
++) {
1632 max_data
= data_ptr
+ (width
<< 1);
1634 while (data_ptr
< max_data
) {
1635 pixel
= pixels
[*(iptr
++)];
1637 data_ptr
[0] = pixel
;
1638 data_ptr
[1] = pixel
>> 8;
1640 data_ptr
+= (1 << 1);
1645 #endif /* WITHOUT_SPEEDUPS */
1649 * write pixels into a 8-bits Z image data structure
1653 /* Visual Age cannot deal with old, non-ansi, code */
1654 static void PutImagePixels8(
1656 , unsigned int width
1657 , unsigned int height
1658 , unsigned int* pixelindex
1663 PutImagePixels8(image
, width
, height
, pixelindex
, pixels
)
1666 unsigned int height
;
1667 unsigned int *pixelindex
;
1675 #ifdef WITHOUT_SPEEDUPS
1681 for (y
= 0; y
< height
; y
++)
1682 for (x
= 0; x
< width
; x
++, iptr
++)
1683 data
[ZINDEX8(x
, y
, image
)] = pixels
[*iptr
];
1685 #else /* WITHOUT_SPEEDUPS */
1687 int bpl
= image
->bytes_per_line
;
1688 char *data_ptr
, *max_data
;
1693 for (y
= 0; y
< height
; y
++) {
1695 max_data
= data_ptr
+ width
;
1697 while (data_ptr
< max_data
)
1698 *(data_ptr
++) = pixels
[*(iptr
++)];
1703 #endif /* WITHOUT_SPEEDUPS */
1707 * write pixels into a 1-bit depth image data structure and **offset null**
1711 /* Visual Age cannot deal with old, non-ansi, code */
1712 static void PutImagePixels1(
1714 , unsigned int width
1715 , unsigned int height
1716 , unsigned int* pixelindex
1721 PutImagePixels1(image
, width
, height
, pixelindex
, pixels
)
1724 unsigned int height
;
1725 unsigned int *pixelindex
;
1729 if (image
->byte_order
!= image
->bitmap_bit_order
)
1730 PutImagePixels(image
, width
, height
, pixelindex
, pixels
);
1736 #ifdef WITHOUT_SPEEDUPS
1742 if (image
->bitmap_bit_order
== MSBFirst
)
1743 for (y
= 0; y
< height
; y
++)
1744 for (x
= 0; x
< width
; x
++, iptr
++) {
1745 if (pixels
[*iptr
] & 1)
1746 data
[ZINDEX1(x
, y
, image
)] |= 0x80 >> (x
& 7);
1748 data
[ZINDEX1(x
, y
, image
)] &= ~(0x80 >> (x
& 7));
1751 for (y
= 0; y
< height
; y
++)
1752 for (x
= 0; x
< width
; x
++, iptr
++) {
1753 if (pixels
[*iptr
] & 1)
1754 data
[ZINDEX1(x
, y
, image
)] |= 1 << (x
& 7);
1756 data
[ZINDEX1(x
, y
, image
)] &= ~(1 << (x
& 7));
1759 #else /* WITHOUT_SPEEDUPS */
1762 char *data_ptr
, *max_data
;
1763 int bpl
= image
->bytes_per_line
;
1772 if (image
->bitmap_bit_order
== MSBFirst
)
1773 for (y
= 0; y
< height
; y
++) {
1775 max_data
= data_ptr
+ width
;
1776 while (data_ptr
< max_data
) {
1779 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1780 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1781 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1782 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1783 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1784 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1785 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1786 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1788 *(data_ptr
++) = value
;
1792 for (count
= 0; count
< diff
; count
++) {
1793 if (pixels
[*(iptr
++)] & 1)
1794 value
|= (0x80 >> count
);
1796 *(data_ptr
) = value
;
1801 for (y
= 0; y
< height
; y
++) {
1803 max_data
= data_ptr
+ width
;
1804 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);
1818 *(data_ptr
++) = value
;
1822 for (count
= 0; count
< diff
; count
++) {
1823 if (pixels
[*(iptr
++)] & 1)
1824 value
|= (1 << count
);
1826 *(data_ptr
) = value
;
1831 #endif /* WITHOUT_SPEEDUPS */
1836 /* Visual Age cannot deal with old, non-ansi, code */
1837 int XpmCreatePixmapFromXpmImage(
1841 , Pixmap
* pixmap_return
1842 , Pixmap
* shapemask_return
1843 , XpmAttributes
* attributes
1846 XpmCreatePixmapFromXpmImage(display
, d
, image
,
1847 pixmap_return
, shapemask_return
, attributes
)
1851 Pixmap
*pixmap_return
;
1852 Pixmap
*shapemask_return
;
1853 XpmAttributes
*attributes
;
1856 XImage
*ximage
, *shapeimage
;
1859 /* initialize return values */
1862 if (shapemask_return
)
1863 *shapemask_return
= 0;
1865 /* create the ximages */
1866 ErrorStatus
= XpmCreateImageFromXpmImage(display
, image
,
1867 (pixmap_return
? &ximage
: NULL
),
1869 &shapeimage
: NULL
),
1871 if (ErrorStatus
< 0)
1872 return (ErrorStatus
);
1874 /* create the pixmaps and destroy images */
1875 if (pixmap_return
&& ximage
) {
1876 xpmCreatePixmapFromImage(display
, d
, ximage
, pixmap_return
);
1877 XDestroyImage(ximage
);
1879 if (shapemask_return
&& shapeimage
) {
1880 xpmCreatePixmapFromImage(display
, d
, shapeimage
, shapemask_return
);
1881 XDestroyImage(shapeimage
);
1883 return (ErrorStatus
);
1892 unsigned int height
,
1893 unsigned int *pixelindex
,
1896 unsigned int *data
= pixelindex
;
1898 unsigned char *array
;
1900 BOOL success
= FALSE
;
1902 array
= XpmMalloc ((((width
+15)>>4)<<4)*sizeof (*array
));
1905 tmp_img
= AllocXImage ((((width
+15)>>4)<<4), 1,
1906 image
->rp
->BitMap
->Depth
);
1907 if (tmp_img
!= NULL
)
1909 for (y
= 0; y
< height
; ++y
)
1911 for (x
= 0; x
< width
; ++x
)
1912 array
[x
] = pixels
[*(data
++)];
1913 WritePixelLine8 (image
->rp
, 0, y
, width
, array
, tmp_img
->rp
);
1915 FreeXImage (tmp_img
);
1923 for (y
= 0; y
< height
; ++y
)
1924 for (x
= 0; x
< width
; ++x
)
1925 XPutPixel (image
, x
, y
, pixels
[*(data
++)]);
1930 #else /* FOR_MSW part follows */
1933 /* Visual Age cannot deal with old, non-ansi, code */
1934 static void MSWPutImagePixels(
1937 , unsigned int width
1938 , unsigned int height
1939 , unsigned int* pixelindex
1944 MSWPutImagePixels(dc
, image
, width
, height
, pixelindex
, pixels
)
1948 unsigned int height
;
1949 unsigned int *pixelindex
;
1953 unsigned int *data
= pixelindex
;
1960 obm
= GpiSetBitmap(*dc
, image
->bitmap
);
1962 obm
= SelectObject(*dc
, image
->bitmap
);
1965 for (y
= 0; y
< height
; y
++) {
1966 for (x
= 0; x
< width
; x
++) {
1970 GpiSetColor(*dc
, (LONG
)pixels
[*(data
++)]);
1971 GpiSetPel(*dc
, &point
);
1974 SetPixel(*dc
, x
, y
, pixels
[*(data
++)]); /* data is [x+y*width] */
1979 GpiSetBitmap(*dc
, obm
);
1981 SelectObject(*dc
, obm
);
1985 #endif /* FOR_MSW */
1989 #if !defined(FOR_MSW) && !defined(AMIGA)
1992 PutPixel1(ximage
, x
, y
, pixel
)
1993 register XImage
*ximage
;
1996 unsigned long pixel
;
2001 register char *data
;
2005 for (i
=0, px
=pixel
; i
<sizeof(unsigned long); i
++, px
>>=8)
2006 ((unsigned char *)&pixel
)[i
] = px
;
2007 src
= &ximage
->data
[XYINDEX(x
, y
, ximage
)];
2010 nbytes
= ximage
->bitmap_unit
>> 3;
2011 for (i
= nbytes
; --i
>= 0; ) *dst
++ = *src
++;
2012 XYNORMALIZE(&px
, ximage
);
2013 i
= ((x
+ ximage
->xoffset
) % ximage
->bitmap_unit
);
2014 _putbits ((char *)&pixel
, i
, 1, (char *)&px
);
2015 XYNORMALIZE(&px
, ximage
);
2017 dst
= &ximage
->data
[XYINDEX(x
, y
, ximage
)];
2018 for (i
= nbytes
; --i
>= 0; )
2025 PutPixel(ximage
, x
, y
, pixel
)
2026 register XImage
*ximage
;
2029 unsigned long pixel
;
2034 register char *data
;
2038 ibpp
= ximage
->bits_per_pixel
;
2039 if (ximage
->depth
== 4)
2041 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++, px
>>= 8)
2042 ((unsigned char *) &pixel
)[i
] = px
;
2043 src
= &ximage
->data
[ZINDEX(x
, y
, ximage
)];
2046 nbytes
= (ibpp
+ 7) >> 3;
2047 for (i
= nbytes
; --i
>= 0;)
2049 ZNORMALIZE(&px
, ximage
);
2050 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
2051 ZNORMALIZE(&px
, ximage
);
2053 dst
= &ximage
->data
[ZINDEX(x
, y
, ximage
)];
2054 for (i
= nbytes
; --i
>= 0;)
2061 PutPixel32(ximage
, x
, y
, pixel
)
2062 register XImage
*ximage
;
2065 unsigned long pixel
;
2067 unsigned char *addr
;
2069 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2070 *((unsigned long *)addr
) = pixel
;
2075 PutPixel32MSB(ximage
, x
, y
, pixel
)
2076 register XImage
*ximage
;
2079 unsigned long pixel
;
2081 unsigned char *addr
;
2083 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2084 addr
[0] = pixel
>> 24;
2085 addr
[1] = pixel
>> 16;
2086 addr
[2] = pixel
>> 8;
2092 PutPixel32LSB(ximage
, x
, y
, pixel
)
2093 register XImage
*ximage
;
2096 unsigned long pixel
;
2098 unsigned char *addr
;
2100 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2101 addr
[3] = pixel
>> 24;
2102 addr
[2] = pixel
>> 16;
2103 addr
[1] = pixel
>> 8;
2109 PutPixel16MSB(ximage
, x
, y
, pixel
)
2110 register XImage
*ximage
;
2113 unsigned long pixel
;
2115 unsigned char *addr
;
2117 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2118 addr
[0] = pixel
>> 8;
2124 PutPixel16LSB(ximage
, x
, y
, pixel
)
2125 register XImage
*ximage
;
2128 unsigned long pixel
;
2130 unsigned char *addr
;
2132 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2133 addr
[1] = pixel
>> 8;
2139 PutPixel8(ximage
, x
, y
, pixel
)
2140 register XImage
*ximage
;
2143 unsigned long pixel
;
2145 ximage
->data
[ZINDEX8(x
, y
, ximage
)] = pixel
;
2150 PutPixel1MSB(ximage
, x
, y
, pixel
)
2151 register XImage
*ximage
;
2154 unsigned long pixel
;
2157 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 0x80 >> (x
& 7);
2159 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(0x80 >> (x
& 7));
2164 PutPixel1LSB(ximage
, x
, y
, pixel
)
2165 register XImage
*ximage
;
2168 unsigned long pixel
;
2171 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 1 << (x
& 7);
2173 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(1 << (x
& 7));
2177 #endif /* not FOR_MSW && not AMIGA */
2180 * This function parses an Xpm file or data and directly create an XImage
2183 /* Visual Age cannot deal with old, non-ansi, code */
2184 int xpmParseDataAndCreate(
2187 , XImage
** image_return
2188 , XImage
** shapeimage_return
2191 , XpmAttributes
* attributes
2195 xpmParseDataAndCreate(display
, data
, image_return
, shapeimage_return
,
2196 image
, info
, attributes
)
2199 XImage
**image_return
;
2200 XImage
**shapeimage_return
;
2203 XpmAttributes
*attributes
;
2206 /* variables stored in the XpmAttributes structure */
2211 XpmFreeColorsFunc freeColors
;
2214 /* variables to return */
2215 XImage
*ximage
= NULL
;
2216 XImage
*shapeimage
= NULL
;
2217 unsigned int mask_pixel_index
= XpmUndefPixel
;
2219 /* calculation variables */
2220 Pixel
*image_pixels
= NULL
;
2221 Pixel
*mask_pixels
= NULL
;
2222 Pixel
*alloc_pixels
= NULL
;
2223 Pixel
*used_pixels
= NULL
;
2224 unsigned int nalloc_pixels
= 0;
2225 unsigned int nused_pixels
= 0;
2226 unsigned int width
, height
, ncolors
, cpp
;
2227 unsigned int x_hotspot
, y_hotspot
, hotspot
= 0, extensions
= 0;
2228 XpmColor
*colorTable
= NULL
;
2229 char *hints_cmt
= NULL
;
2230 char *colors_cmt
= NULL
;
2231 char *pixels_cmt
= NULL
;
2235 xpmHashTable hashtable
;
2238 /* initialize return values */
2240 *image_return
= NULL
;
2241 if (shapeimage_return
)
2242 *shapeimage_return
= NULL
;
2245 /* retrieve information from the XpmAttributes */
2246 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
2247 visual
= attributes
->visual
;
2249 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
2251 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
2252 colormap
= attributes
->colormap
;
2254 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
2256 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
2257 depth
= attributes
->depth
;
2259 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
2261 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
2262 bitmap_format
= attributes
->bitmap_format
;
2264 bitmap_format
= ZPixmap
;
2266 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
2267 freeColors
= attributes
->free_colors
;
2269 freeColors
= FreeColors
;
2270 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
2271 closure
= attributes
->color_closure
;
2275 cmts
= info
&& (info
->valuemask
& XpmReturnComments
);
2280 ErrorStatus
= xpmParseHeader(data
);
2281 if (ErrorStatus
!= XpmSuccess
)
2282 return (ErrorStatus
);
2287 ErrorStatus
= xpmParseValues(data
, &width
, &height
, &ncolors
, &cpp
,
2288 &x_hotspot
, &y_hotspot
, &hotspot
,
2290 if (ErrorStatus
!= XpmSuccess
)
2291 return (ErrorStatus
);
2294 * store the hints comment line
2297 xpmGetCmt(data
, &hints_cmt
);
2302 if (USE_HASHTABLE
) {
2303 ErrorStatus
= xpmHashTableInit(&hashtable
);
2304 if (ErrorStatus
!= XpmSuccess
)
2305 return (ErrorStatus
);
2311 ErrorStatus
= xpmParseColors(data
, ncolors
, cpp
, &colorTable
, &hashtable
);
2312 if (ErrorStatus
!= XpmSuccess
)
2313 RETURN(ErrorStatus
);
2316 * store the colors comment line
2319 xpmGetCmt(data
, &colors_cmt
);
2321 /* malloc pixels index tables */
2322 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2324 RETURN(XpmNoMemory
);
2326 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2328 RETURN(XpmNoMemory
);
2330 /* maximum of allocated pixels will be the number of colors */
2331 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2333 RETURN(XpmNoMemory
);
2335 /* maximum of allocated pixels will be the number of colors */
2336 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2338 RETURN(XpmNoMemory
);
2340 /* get pixel colors, store them in index tables */
2341 ErrorStatus
= CreateColors(display
, attributes
, colorTable
, ncolors
,
2342 image_pixels
, mask_pixels
, &mask_pixel_index
,
2343 alloc_pixels
, &nalloc_pixels
, used_pixels
,
2346 if (ErrorStatus
!= XpmSuccess
2347 && (ErrorStatus
< 0 || (attributes
2348 && (attributes
->valuemask
& XpmExactColors
)
2349 && attributes
->exactColors
)))
2350 RETURN(ErrorStatus
);
2352 /* now create the ximage */
2354 ErrorStatus
= CreateXImage(display
, visual
, depth
,
2355 (depth
== 1 ? bitmap_format
: ZPixmap
),
2356 width
, height
, &ximage
);
2357 if (ErrorStatus
!= XpmSuccess
)
2358 RETURN(ErrorStatus
);
2360 #if !defined(FOR_MSW) && !defined(AMIGA)
2363 * set the XImage pointer function, to be used with XPutPixel,
2364 * to an internal optimized function
2367 if (ximage
->bits_per_pixel
== 8)
2368 ximage
->f
.put_pixel
= PutPixel8
;
2369 else if (((ximage
->bits_per_pixel
| ximage
->depth
) == 1) &&
2370 (ximage
->byte_order
== ximage
->bitmap_bit_order
))
2371 if (ximage
->bitmap_bit_order
== MSBFirst
)
2372 ximage
->f
.put_pixel
= PutPixel1MSB
;
2374 ximage
->f
.put_pixel
= PutPixel1LSB
;
2375 else if (ximage
->bits_per_pixel
== 16)
2376 if (ximage
->bitmap_bit_order
== MSBFirst
)
2377 ximage
->f
.put_pixel
= PutPixel16MSB
;
2379 ximage
->f
.put_pixel
= PutPixel16LSB
;
2380 else if (ximage
->bits_per_pixel
== 32)
2381 #if !defined(WORD64) && !defined(LONG64)
2382 if (*((char *)&byteorderpixel
) == ximage
->byte_order
)
2383 ximage
->f
.put_pixel
= PutPixel32
;
2386 if (ximage
->bitmap_bit_order
== MSBFirst
)
2387 ximage
->f
.put_pixel
= PutPixel32MSB
;
2389 ximage
->f
.put_pixel
= PutPixel32LSB
;
2390 else if ((ximage
->bits_per_pixel
| ximage
->depth
) == 1)
2391 ximage
->f
.put_pixel
= PutPixel1
;
2393 ximage
->f
.put_pixel
= PutPixel
;
2394 #endif /* not FOR_MSW && not AMIGA */
2397 /* create the shape mask image */
2398 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
2399 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
2400 width
, height
, &shapeimage
);
2401 if (ErrorStatus
!= XpmSuccess
)
2402 RETURN(ErrorStatus
);
2404 #if !defined(FOR_MSW) && !defined(AMIGA)
2405 if (shapeimage
->bitmap_bit_order
== MSBFirst
)
2406 shapeimage
->f
.put_pixel
= PutPixel1MSB
;
2408 shapeimage
->f
.put_pixel
= PutPixel1LSB
;
2413 * read pixels and put them in the XImage
2415 ErrorStatus
= ParseAndPutPixels(
2419 data
, width
, height
, ncolors
, cpp
,
2420 colorTable
, &hashtable
,
2421 ximage
, image_pixels
,
2422 shapeimage
, mask_pixels
);
2423 XpmFree(image_pixels
);
2424 image_pixels
= NULL
;
2425 XpmFree(mask_pixels
);
2431 if (ErrorStatus
!= XpmSuccess
)
2433 else if (USE_HASHTABLE
)
2434 xpmHashTableFree(&hashtable
);
2437 * store the pixels comment line
2440 xpmGetCmt(data
, &pixels_cmt
);
2445 if (info
&& (info
->valuemask
& XpmReturnExtensions
))
2447 ErrorStatus
= xpmParseExtensions(data
, &info
->extensions
,
2448 &info
->nextensions
);
2449 if (ErrorStatus
!= XpmSuccess
)
2450 RETURN(ErrorStatus
);
2452 info
->extensions
= NULL
;
2453 info
->nextensions
= 0;
2457 * store found informations in the XpmImage structure
2459 image
->width
= width
;
2460 image
->height
= height
;
2462 image
->ncolors
= ncolors
;
2463 image
->colorTable
= colorTable
;
2468 info
->hints_cmt
= hints_cmt
;
2469 info
->colors_cmt
= colors_cmt
;
2470 info
->pixels_cmt
= pixels_cmt
;
2473 info
->x_hotspot
= x_hotspot
;
2474 info
->y_hotspot
= y_hotspot
;
2475 info
->valuemask
|= XpmHotspot
;
2478 /* if requested return used pixels in the XpmAttributes structure */
2479 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
2480 /* 3.2 backward compatibility code */
2481 attributes
->valuemask
& XpmReturnInfos
)) {
2483 attributes
->pixels
= used_pixels
;
2484 attributes
->npixels
= nused_pixels
;
2485 attributes
->mask_pixel
= mask_pixel_index
;
2487 XpmFree(used_pixels
);
2489 /* if requested return alloc'ed pixels in the XpmAttributes structure */
2490 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
2491 attributes
->alloc_pixels
= alloc_pixels
;
2492 attributes
->nalloc_pixels
= nalloc_pixels
;
2494 XpmFree(alloc_pixels
);
2496 /* return created images */
2498 *image_return
= ximage
;
2499 if (shapeimage_return
)
2500 *shapeimage_return
= shapeimage
;
2502 return (XpmSuccess
);
2504 /* exit point in case of error, free only locally allocated variables */
2507 xpmHashTableFree(&hashtable
);
2509 xpmFreeColorTable(colorTable
, ncolors
);
2513 XpmFree(colors_cmt
);
2515 XpmFree(pixels_cmt
);
2517 XDestroyImage(ximage
);
2519 XDestroyImage(shapeimage
);
2521 XpmFree(image_pixels
);
2523 XpmFree(mask_pixels
);
2525 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
2527 XpmFree(alloc_pixels
);
2529 XpmFree(used_pixels
);
2531 return (ErrorStatus
);
2535 /* Visual Age cannot deal with old, non-ansi, code */
2536 static int ParseAndPutPixels(
2539 , unsigned int width
2540 , unsigned int height
2541 , unsigned int ncolors
2543 , XpmColor
* colorTable
2544 , xpmHashTable
* hashtable
2546 , Pixel
* image_pixels
2547 , XImage
* shapeimage
2548 , Pixel
* shape_pixels
2556 data
, width
, height
, ncolors
, cpp
, colorTable
, hashtable
,
2557 image
, image_pixels
, shapeimage
, shape_pixels
)
2563 unsigned int height
;
2564 unsigned int ncolors
;
2566 XpmColor
*colorTable
;
2567 xpmHashTable
*hashtable
;
2569 Pixel
*image_pixels
;
2571 Pixel
*shape_pixels
;
2574 unsigned int a
, x
, y
;
2576 HAB hab
= WinQueryAnchorBlock(HWND_DESKTOP
);
2577 DEVOPENSTRUC dop
= {NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2578 SIZEL sizl
= {0, 0};
2584 case (1): /* Optimize for single character
2587 unsigned short colidx
[256];
2594 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2595 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2596 sobm
= GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2598 shapedc
= CreateCompatibleDC(*dc
);
2599 sobm
= SelectObject(shapedc
, shapeimage
->bitmap
);
2605 obm
= GpiSetBitmap(*dc
, image
->bitmap
);
2607 obm
= SelectObject(*dc
, image
->bitmap
);
2613 bzero((char *)colidx
, 256 * sizeof(short));
2614 for (a
= 0; a
< ncolors
; a
++)
2615 colidx
[(unsigned char)colorTable
[a
].string
[0]] = a
+ 1;
2617 for (y
= 0; y
< height
; y
++) {
2618 xpmNextString(data
);
2619 for (x
= 0; x
< width
; x
++) {
2620 int c
= xpmGetC(data
);
2622 if (c
> 0 && c
< 256 && colidx
[c
] != 0) {
2624 XPutPixel(image
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2626 XPutPixel(shapeimage
, x
, y
,
2627 shape_pixels
[colidx
[c
] - 1]);
2632 GpiSetColor(*dc
, (LONG
)image_pixels
[colidx
[c
] - 1]);
2633 GpiSetPel(*dc
, &point
);
2635 SetPixel(*dc
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2641 GpiSetColor(*dc
, (LONG
)shape_pixels
[colidx
[c
] - 1]);
2642 GpiSetPel(*dc
, &point
);
2644 SetPixel(shapedc
, x
, y
, shape_pixels
[colidx
[c
] - 1]);
2649 return (XpmFileInvalid
);
2655 GpiSetBitmap(*dc
, sobm
);
2657 DevCloseDC(shapedc
);
2659 SelectObject(shapedc
, sobm
);
2664 GpiSetBitmap(*dc
, obm
);
2666 SelectObject(*dc
, obm
);
2672 case (2): /* Optimize for double character
2675 /* free all allocated pointers at all exits */
2676 #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
2677 if (cidx[f]) XpmFree(cidx[f]);}
2679 /* array of pointers malloced by need */
2680 unsigned short *cidx
[256];
2686 bzero((char *)cidx
, 256 * sizeof(unsigned short *)); /* init */
2687 for (a
= 0; a
< ncolors
; a
++) {
2688 char1
= colorTable
[a
].string
[0];
2689 if (cidx
[char1
] == NULL
) { /* get new memory */
2690 cidx
[char1
] = (unsigned short *)
2691 XpmCalloc(256, sizeof(unsigned short));
2692 if (cidx
[char1
] == NULL
) { /* new block failed */
2694 return (XpmNoMemory
);
2697 cidx
[char1
][(unsigned char)colorTable
[a
].string
[1]] = a
+ 1;
2700 for (y
= 0; y
< height
; y
++) {
2701 xpmNextString(data
);
2702 for (x
= 0; x
< width
; x
++) {
2703 int cc1
= xpmGetC(data
);
2704 if (cc1
> 0 && cc1
< 256) {
2705 int cc2
= xpmGetC(data
);
2706 if (cc2
> 0 && cc2
< 256 &&
2707 cidx
[cc1
] && cidx
[cc1
][cc2
] != 0) {
2709 XPutPixel(image
, x
, y
,
2710 image_pixels
[cidx
[cc1
][cc2
] - 1]);
2712 XPutPixel(shapeimage
, x
, y
,
2713 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2716 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2717 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2719 GpiSetBitmap(*dc
, image
->bitmap
);
2722 GpiSetColor(*dc
, (LONG
)image_pixels
[cidx
[cc1
][cc2
] - 1]);
2723 GpiSetPel(*dc
, &point
);
2725 SelectObject(*dc
, image
->bitmap
);
2726 SetPixel(*dc
, x
, y
, image_pixels
[cidx
[cc1
][cc2
] - 1]);
2730 GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2733 GpiSetColor(*dc
, (LONG
)shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2734 GpiSetPel(*dc
, &point
);
2736 SelectObject(*dc
, shapeimage
->bitmap
);
2738 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2744 return (XpmFileInvalid
);
2748 return (XpmFileInvalid
);
2756 default: /* Non-optimized case of long color
2766 if (USE_HASHTABLE
) {
2769 for (y
= 0; y
< height
; y
++) {
2770 xpmNextString(data
);
2771 for (x
= 0; x
< width
; x
++) {
2772 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
2774 slot
= xpmHashSlot(hashtable
, buf
);
2775 if (!*slot
) /* no color matches */
2776 return (XpmFileInvalid
);
2778 XPutPixel(image
, x
, y
,
2779 image_pixels
[HashColorIndex(slot
)]);
2781 XPutPixel(shapeimage
, x
, y
,
2782 shape_pixels
[HashColorIndex(slot
)]);
2786 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2787 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2789 GpiSetBitmap(*dc
, image
->bitmap
);
2792 GpiSetColor(*dc
, (LONG
)image_pixels
[HashColorIndex(slot
)]);
2793 GpiSetPel(*dc
, &point
);
2795 SelectObject(*dc
, image
->bitmap
);
2797 image_pixels
[HashColorIndex(slot
)]);
2801 GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2804 GpiSetColor(*dc
, (LONG
)shape_pixels
[HashColorIndex(slot
)]);
2805 GpiSetPel(*dc
, &point
);
2807 SelectObject(*dc
, shapeimage
->bitmap
);
2809 shape_pixels
[HashColorIndex(slot
)]);
2816 for (y
= 0; y
< height
; y
++) {
2817 xpmNextString(data
);
2818 for (x
= 0; x
< width
; x
++) {
2819 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
2821 for (a
= 0; a
< ncolors
; a
++)
2822 if (!strcmp(colorTable
[a
].string
, buf
))
2824 if (a
== ncolors
) /* no color matches */
2825 return (XpmFileInvalid
);
2827 XPutPixel(image
, x
, y
, image_pixels
[a
]);
2829 XPutPixel(shapeimage
, x
, y
, shape_pixels
[a
]);
2833 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2834 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2836 GpiSetBitmap(*dc
, image
->bitmap
);
2839 GpiSetColor(*dc
, (LONG
)image_pixels
[a
]);
2840 GpiSetPel(*dc
, &point
);
2842 SelectObject(*dc
, image
->bitmap
);
2843 SetPixel(*dc
, x
, y
, image_pixels
[a
]);
2847 GpiSetBitmap(*dc
, image
->bitmap
);
2850 GpiSetColor(*dc
, (LONG
)shape_pixels
[a
]);
2851 GpiSetPel(*dc
, &point
);
2853 SelectObject(*dc
, shapeimage
->bitmap
);
2854 SetPixel(*dc
, x
, y
, shape_pixels
[a
]);
2864 return (XpmSuccess
);