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 /* Visual Age cannot deal with old, non-ansi, code */
226 static int closeness_cmp(Const
void* a
, Const
void* b
)
233 CloseColor
*x
= (CloseColor
*) a
, *y
= (CloseColor
*) b
;
235 /* cast to int as qsort requires */
236 return (int) (x
->closeness
- y
->closeness
);
240 /* default AllocColor function:
241 * call XParseColor if colorname is given, return negative value if failure
242 * call XAllocColor and return 0 if failure, positive otherwise
245 /* Visual Age cannot deal with old, non-ansi, code */
256 AllocColor(display
, colormap
, colorname
, xcolor
, closure
)
261 void *closure
; /* not used */
267 if (!XParseColor(display
, &colormap
, colorname
, xcolor
))
269 status
= XAllocColor(display
, &colormap
, xcolor
);
271 if (!XParseColor(display
, colormap
, colorname
, xcolor
))
273 status
= XAllocColor(display
, colormap
, xcolor
);
275 return status
!= 0 ? 1 : 0;
281 * set a close color in case the exact one can't be set
282 * return 0 if success, 1 otherwise.
286 SetCloseColor(display
, colormap
, visual
, col
, image_pixel
, mask_pixel
,
287 alloc_pixels
, nalloc_pixels
, attributes
, cols
, ncols
,
293 Pixel
*image_pixel
, *mask_pixel
;
295 unsigned int *nalloc_pixels
;
296 XpmAttributes
*attributes
;
299 XpmAllocColorFunc allocColor
;
304 * Allocation failed, so try close colors. To get here the visual must
305 * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
306 * What about sharing systems like QDSS?). Beware: we have to treat
307 * DirectColor differently.
311 long int red_closeness
, green_closeness
, blue_closeness
;
315 if (attributes
&& (attributes
->valuemask
& XpmCloseness
))
316 red_closeness
= green_closeness
= blue_closeness
=
317 attributes
->closeness
;
319 red_closeness
= attributes
->red_closeness
;
320 green_closeness
= attributes
->green_closeness
;
321 blue_closeness
= attributes
->blue_closeness
;
323 if (attributes
&& (attributes
->valuemask
& XpmAllocCloseColors
))
324 alloc_color
= attributes
->alloc_close_colors
;
329 * We sort the colormap by closeness and try to allocate the color
330 * closest to the target. If the allocation of this close color fails,
331 * which almost never happens, then one of two scenarios is possible.
332 * Either the colormap must have changed (since the last close color
333 * allocation or possibly while we were sorting the colormap), or the
334 * color is allocated as Read/Write by some other client. (Note: X
335 * _should_ allow clients to check if a particular color is Read/Write,
336 * but it doesn't! :-( ). We cannot determine which of these scenarios
337 * occurred, so we try the next closest color, and so on, until no more
338 * colors are within closeness of the target. If we knew that the
339 * colormap had changed, we could skip this sequence.
341 * If _none_ of the colors within closeness of the target can be allocated,
342 * then we can finally be pretty sure that the colormap has actually
343 * changed. In this case we try to allocate the original color (again),
344 * then try the closecolor stuff (again)...
346 * In theory it would be possible for an infinite loop to occur if another
347 * process kept changing the colormap every time we sorted it, so we set
348 * a maximum on the number of iterations. After this many tries, we use
349 * XGrabServer() to ensure that the colormap remains unchanged.
351 * This approach gives particularly bad worst case performance - as many as
352 * <MaximumIterations> colormap reads and sorts may be needed, and as
353 * many as <MaximumIterations> * <ColormapSize> attempted allocations
354 * may fail. On an 8-bit system, this means as many as 3 colormap reads,
355 * 3 sorts and 768 failed allocations per execution of this code!
356 * Luckily, my experiments show that in general use in a typical 8-bit
357 * color environment only about 1 in every 10000 allocations fails to
358 * succeed in the fastest possible time. So virtually every time what
359 * actually happens is a single sort followed by a successful allocate.
360 * The very first allocation also costs a colormap read, but no further
361 * reads are usually necessary.
364 #define ITERATIONS 2 /* more than one is almost never
367 for (n
= 0; n
<= ITERATIONS
; ++n
) {
368 CloseColor
*closenesses
=
369 (CloseColor
*) XpmCalloc(ncols
, sizeof(CloseColor
));
372 for (i
= 0; i
< ncols
; ++i
) { /* build & sort closenesses table */
373 #define COLOR_FACTOR 3
374 #define BRIGHTNESS_FACTOR 1
376 closenesses
[i
].cols_index
= i
;
377 closenesses
[i
].closeness
=
378 COLOR_FACTOR
* (abs((long) col
->red
- (long) cols
[i
].red
)
379 + abs((long) col
->green
- (long) cols
[i
].green
)
380 + abs((long) col
->blue
- (long) cols
[i
].blue
))
381 + BRIGHTNESS_FACTOR
* abs(((long) col
->red
+
384 - ((long) cols
[i
].red
+
385 (long) cols
[i
].green
+
386 (long) cols
[i
].blue
));
388 qsort(closenesses
, ncols
, sizeof(CloseColor
), closeness_cmp
);
391 c
= closenesses
[i
].cols_index
;
392 while ((long) cols
[c
].red
>= (long) col
->red
- red_closeness
&&
393 (long) cols
[c
].red
<= (long) col
->red
+ red_closeness
&&
394 (long) cols
[c
].green
>= (long) col
->green
- green_closeness
&&
395 (long) cols
[c
].green
<= (long) col
->green
+ green_closeness
&&
396 (long) cols
[c
].blue
>= (long) col
->blue
- blue_closeness
&&
397 (long) cols
[c
].blue
<= (long) col
->blue
+ blue_closeness
) {
399 if ((*allocColor
)(display
, colormap
, NULL
, &cols
[c
], closure
)){
401 XUngrabServer(display
);
402 XpmFree(closenesses
);
403 *image_pixel
= cols
[c
].pixel
;
405 alloc_pixels
[(*nalloc_pixels
)++] = cols
[c
].pixel
;
411 c
= closenesses
[i
].cols_index
;
415 XUngrabServer(display
);
416 XpmFree(closenesses
);
417 *image_pixel
= cols
[c
].pixel
;
423 /* Couldn't allocate _any_ of the close colors! */
426 XUngrabServer(display
);
427 XpmFree(closenesses
);
429 if (i
== 0 || i
== ncols
) /* no color close enough or cannot */
430 return (1); /* alloc any color (full of r/w's) */
432 if ((*allocColor
)(display
, colormap
, NULL
, col
, closure
)) {
433 *image_pixel
= col
->pixel
;
435 alloc_pixels
[(*nalloc_pixels
)++] = col
->pixel
;
437 } else { /* colormap has probably changed, so
439 if (n
== ITERATIONS
- 1)
440 XGrabServer(display
);
443 if (visual
->class == DirectColor
) {
447 XQueryColors(display
, colormap
, cols
, ncols
);
453 #define USE_CLOSECOLOR attributes && \
454 (((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
455 || ((attributes->valuemask & XpmRGBCloseness) && \
456 (attributes->red_closeness != 0 \
457 || attributes->green_closeness != 0 \
458 || attributes->blue_closeness != 0)))
462 /* nothing to do here, the window system does it */
466 * set the color pixel related to the given colorname,
467 * return 0 if success, 1 otherwise.
471 /* Visual Age cannot deal with old, non-ansi, code */
478 , unsigned int color_index
481 , unsigned int* mask_pixel_index
482 , Pixel
* alloc_pixels
483 , unsigned int* nalloc_pixels
485 , unsigned int* nused_pixels
486 , XpmAttributes
* attributes
489 , XpmAllocColorFunc allocColor
494 SetColor(display
, colormap
, visual
, colorname
, color_index
,
495 image_pixel
, mask_pixel
, mask_pixel_index
,
496 alloc_pixels
, nalloc_pixels
, used_pixels
, nused_pixels
,
497 attributes
, cols
, ncols
, allocColor
, closure
)
502 unsigned int color_index
;
503 Pixel
*image_pixel
, *mask_pixel
;
504 unsigned int *mask_pixel_index
;
506 unsigned int *nalloc_pixels
;
508 unsigned int *nused_pixels
;
509 XpmAttributes
*attributes
;
512 XpmAllocColorFunc allocColor
;
519 if (xpmstrcasecmp(colorname
, TRANSPARENT_COLOR
)) {
520 status
= (*allocColor
)(display
, colormap
, colorname
, &xcolor
, closure
);
521 if (status
< 0) /* parse color failed */
527 return (SetCloseColor(display
, colormap
, visual
, &xcolor
,
528 image_pixel
, mask_pixel
,
529 alloc_pixels
, nalloc_pixels
,
530 attributes
, cols
, ncols
,
531 allocColor
, closure
));
533 #endif /* ndef FOR_MSW */
536 alloc_pixels
[(*nalloc_pixels
)++] = xcolor
.pixel
;
537 *image_pixel
= xcolor
.pixel
;
542 *mask_pixel
= OS2RGB(0,0,0);
544 *mask_pixel
= RGB(0,0,0);
547 used_pixels
[(*nused_pixels
)++] = xcolor
.pixel
;
554 *mask_pixel
= OS2RGB(255,255,255);
556 *mask_pixel
= RGB(255,255,255);
559 /* store the color table index */
560 *mask_pixel_index
= color_index
;
566 /* Visual Age cannot deal with old, non-ansi, code */
570 , XpmAttributes
* attributes
572 , unsigned int ncolors
573 , Pixel
* image_pixels
575 , unsigned int* mask_pixel_index
576 , Pixel
* alloc_pixels
577 , unsigned int* nalloc_pixels
579 , unsigned int* nused_pixels
583 CreateColors(display
, attributes
, colors
, ncolors
, image_pixels
, mask_pixels
,
584 mask_pixel_index
, alloc_pixels
, nalloc_pixels
,
585 used_pixels
, nused_pixels
)
587 XpmAttributes
*attributes
;
589 unsigned int ncolors
;
592 unsigned int *mask_pixel_index
;
594 unsigned int *nalloc_pixels
;
596 unsigned int *nused_pixels
;
599 /* variables stored in the XpmAttributes structure */
602 XpmColorSymbol
*colorsymbols
;
603 unsigned int numsymbols
;
604 XpmAllocColorFunc allocColor
;
608 unsigned int color
, key
;
610 XpmColorSymbol
*symbol
;
612 int ErrorStatus
= XpmSuccess
;
617 unsigned int ncols
= 0;
620 * retrieve information from the XpmAttributes
622 if (attributes
&& attributes
->valuemask
& XpmColorSymbols
) {
623 colorsymbols
= attributes
->colorsymbols
;
624 numsymbols
= attributes
->numsymbols
;
628 if (attributes
&& attributes
->valuemask
& XpmVisual
)
629 visual
= attributes
->visual
;
631 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
633 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
634 colormap
= attributes
->colormap
;
636 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
638 if (attributes
&& (attributes
->valuemask
& XpmColorKey
))
639 key
= attributes
->color_key
;
641 key
= xpmVisualType(visual
);
643 if (attributes
&& (attributes
->valuemask
& XpmAllocColor
))
644 allocColor
= attributes
->alloc_color
;
646 allocColor
= AllocColor
;
647 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
648 closure
= attributes
->color_closure
;
653 if (USE_CLOSECOLOR
) {
654 /* originally from SetCloseColor */
656 if (visual
->class == DirectColor
) {
659 * TODO: Implement close colors for DirectColor visuals. This is
660 * difficult situation. Chances are that we will never get here,
661 * because any machine that supports DirectColor will probably
662 * also support TrueColor (and probably PseudoColor). Also,
663 * DirectColor colormaps can be very large, so looking for close
664 * colors may be too slow.
671 ncols
= visual
->map_entries
;
673 ncols
= colormap
->Count
;
675 cols
= (XColor
*) XpmCalloc(ncols
, sizeof(XColor
));
676 for (i
= 0; i
< ncols
; ++i
)
678 XQueryColors(display
, colormap
, cols
, ncols
);
683 #endif /* ndef FOR_MSW */
701 for (color
= 0; color
< ncolors
; color
++, colors
++,
702 image_pixels
++, mask_pixels
++) {
704 pixel_defined
= False
;
705 defaults
= (char **) colors
;
708 * look for a defined symbol
715 for (n
= 0, symbol
= colorsymbols
; n
< numsymbols
; n
++, symbol
++) {
716 if (symbol
->name
&& s
&& !strcmp(symbol
->name
, s
))
719 if (!symbol
->name
&& symbol
->value
) { /* override value */
720 int def_index
= default_index
;
722 while (defaults
[def_index
] == NULL
) /* find defined
725 if (def_index
< 2) {/* nothing towards mono, so try
727 def_index
= default_index
+ 1;
728 while (def_index
<= 5 && defaults
[def_index
] == NULL
)
731 if (def_index
>= 2 && defaults
[def_index
] != NULL
&&
732 !xpmstrcasecmp(symbol
->value
, defaults
[def_index
]))
736 if (n
!= numsymbols
) {
737 if (symbol
->name
&& symbol
->value
)
738 colorname
= symbol
->value
;
740 pixel_defined
= True
;
743 if (!pixel_defined
) { /* pixel not given as symbol value */
747 if (colorname
) { /* colorname given as symbol value */
748 if (!SetColor(display
, colormap
, visual
, colorname
, color
,
749 image_pixels
, mask_pixels
, mask_pixel_index
,
750 alloc_pixels
, nalloc_pixels
, used_pixels
,
751 nused_pixels
, attributes
, cols
, ncols
,
752 allocColor
, closure
))
753 pixel_defined
= True
;
755 ErrorStatus
= XpmColorError
;
758 while (!pixel_defined
&& k
> 1) {
760 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
761 color
, image_pixels
, mask_pixels
,
762 mask_pixel_index
, alloc_pixels
,
763 nalloc_pixels
, used_pixels
, nused_pixels
,
764 attributes
, cols
, ncols
,
765 allocColor
, closure
)) {
766 pixel_defined
= True
;
769 ErrorStatus
= XpmColorError
;
774 while (!pixel_defined
&& k
< NKEYS
+ 1) {
776 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
777 color
, image_pixels
, mask_pixels
,
778 mask_pixel_index
, alloc_pixels
,
779 nalloc_pixels
, used_pixels
, nused_pixels
,
780 attributes
, cols
, ncols
,
781 allocColor
, closure
)) {
782 pixel_defined
= True
;
785 ErrorStatus
= XpmColorError
;
789 if (!pixel_defined
) {
792 return (XpmColorFailed
);
795 /* simply use the given pixel */
796 *image_pixels
= symbol
->pixel
;
797 /* the following makes the mask to be built even if none
798 is given a particular pixel */
800 && !xpmstrcasecmp(symbol
->value
, TRANSPARENT_COLOR
)) {
802 *mask_pixel_index
= color
;
805 used_pixels
[(*nused_pixels
)++] = *image_pixels
;
810 return (ErrorStatus
);
814 /* default FreeColors function, simply call XFreeColors */
816 /* Visual Age cannot deal with old, non-ansi, code */
827 FreeColors(display
, colormap
, pixels
, n
, closure
)
832 void *closure
; /* not used */
835 return XFreeColors(display
, colormap
, pixels
, n
, 0);
839 /* function call in case of error */
841 #define RETURN(status) \
843 ErrorStatus = status; \
848 /* Visual Age cannot deal with old, non-ansi, code */
849 int XpmCreateImageFromXpmImage(
852 , XImage
** image_return
853 , XImage
** shapeimage_return
854 , XpmAttributes
* attributes
858 XpmCreateImageFromXpmImage(display
, image
,
859 image_return
, shapeimage_return
, attributes
)
862 XImage
**image_return
;
863 XImage
**shapeimage_return
;
864 XpmAttributes
*attributes
;
872 /* variables stored in the XpmAttributes structure */
877 XpmFreeColorsFunc freeColors
;
880 /* variables to return */
881 XImage
*ximage
= NULL
;
882 XImage
*shapeimage
= NULL
;
883 unsigned int mask_pixel_index
= XpmUndefPixel
;
886 /* calculation variables */
887 Pixel
*image_pixels
= NULL
;
888 Pixel
*mask_pixels
= NULL
;
889 Pixel
*alloc_pixels
= NULL
;
890 Pixel
*used_pixels
= NULL
;
891 unsigned int nalloc_pixels
= 0;
892 unsigned int nused_pixels
= 0;
894 /* initialize return values */
896 *image_return
= NULL
;
897 if (shapeimage_return
)
898 *shapeimage_return
= NULL
;
900 /* retrieve information from the XpmAttributes */
901 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
902 visual
= attributes
->visual
;
904 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
906 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
907 colormap
= attributes
->colormap
;
909 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
911 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
912 depth
= attributes
->depth
;
914 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
916 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
917 bitmap_format
= attributes
->bitmap_format
;
919 bitmap_format
= ZPixmap
;
921 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
922 freeColors
= attributes
->free_colors
;
924 freeColors
= FreeColors
;
925 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
926 closure
= attributes
->color_closure
;
930 ErrorStatus
= XpmSuccess
;
932 /* malloc pixels index tables */
933 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
935 return (XpmNoMemory
);
937 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
941 /* maximum of allocated pixels will be the number of colors */
942 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
946 /* maximum of allocated pixels will be the number of colors */
947 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
951 /* get pixel colors, store them in index tables */
952 ErrorStatus
= CreateColors(display
, attributes
, image
->colorTable
,
953 image
->ncolors
, image_pixels
, mask_pixels
,
954 &mask_pixel_index
, alloc_pixels
, &nalloc_pixels
,
955 used_pixels
, &nused_pixels
);
957 if (ErrorStatus
!= XpmSuccess
958 && (ErrorStatus
< 0 || (attributes
959 && (attributes
->valuemask
& XpmExactColors
)
960 && attributes
->exactColors
)))
963 /* create the ximage */
965 ErrorStatus
= CreateXImage(display
, visual
, depth
,
966 (depth
== 1 ? bitmap_format
: ZPixmap
),
967 image
->width
, image
->height
, &ximage
);
968 if (ErrorStatus
!= XpmSuccess
)
975 * set the ximage data using optimized functions for ZPixmap
978 if (ximage
->bits_per_pixel
== 8)
979 PutImagePixels8(ximage
, image
->width
, image
->height
,
980 image
->data
, image_pixels
);
981 else if (((ximage
->bits_per_pixel
| ximage
->depth
) == 1) &&
982 (ximage
->byte_order
== ximage
->bitmap_bit_order
))
983 PutImagePixels1(ximage
, image
->width
, image
->height
,
984 image
->data
, image_pixels
);
985 else if (ximage
->bits_per_pixel
== 16)
986 PutImagePixels16(ximage
, image
->width
, image
->height
,
987 image
->data
, image_pixels
);
988 else if (ximage
->bits_per_pixel
== 32)
989 PutImagePixels32(ximage
, image
->width
, image
->height
,
990 image
->data
, image_pixels
);
992 PutImagePixels(ximage
, image
->width
, image
->height
,
993 image
->data
, image_pixels
);
995 APutImagePixels(ximage
, image
->width
, image
->height
,
996 image
->data
, image_pixels
);
999 MSWPutImagePixels(display
, ximage
, image
->width
, image
->height
,
1000 image
->data
, image_pixels
);
1003 /* create the shape mask image */
1004 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
1005 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
1006 image
->width
, image
->height
, &shapeimage
);
1007 if (ErrorStatus
!= XpmSuccess
)
1008 RETURN(ErrorStatus
);
1012 PutImagePixels1(shapeimage
, image
->width
, image
->height
,
1013 image
->data
, mask_pixels
);
1015 APutImagePixels(shapeimage
, image
->width
, image
->height
,
1016 image
->data
, mask_pixels
);
1019 MSWPutImagePixels(display
, shapeimage
, image
->width
, image
->height
,
1020 image
->data
, mask_pixels
);
1024 XpmFree(image_pixels
);
1025 XpmFree(mask_pixels
);
1027 /* if requested return used pixels in the XpmAttributes structure */
1028 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
1029 /* 3.2 backward compatibility code */
1030 attributes
->valuemask
& XpmReturnInfos
)) {
1032 attributes
->pixels
= used_pixels
;
1033 attributes
->npixels
= nused_pixels
;
1034 attributes
->mask_pixel
= mask_pixel_index
;
1036 XpmFree(used_pixels
);
1038 /* if requested return alloc'ed pixels in the XpmAttributes structure */
1039 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
1040 attributes
->alloc_pixels
= alloc_pixels
;
1041 attributes
->nalloc_pixels
= nalloc_pixels
;
1043 XpmFree(alloc_pixels
);
1045 /* return created images */
1047 *image_return
= ximage
;
1048 if (shapeimage_return
)
1049 *shapeimage_return
= shapeimage
;
1051 return (ErrorStatus
);
1053 /* exit point in case of error, free only locally allocated variables */
1056 XDestroyImage(ximage
);
1058 XDestroyImage(shapeimage
);
1060 XpmFree(image_pixels
);
1062 XpmFree(mask_pixels
);
1064 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
1066 XpmFree(alloc_pixels
);
1068 XpmFree(used_pixels
);
1070 return (ErrorStatus
);
1075 * Create an XImage with its data
1078 /* Visual Age cannot deal with old, non-ansi, code */
1079 static int CreateXImage(
1082 , unsigned int depth
1084 , unsigned int width
1085 , unsigned int height
1086 , XImage
** image_return
1090 CreateXImage(display
, visual
, depth
, format
, width
, height
, image_return
)
1096 unsigned int height
;
1097 XImage
**image_return
;
1102 /* first get bitmap_pad */
1110 /* then create the XImage with data = NULL and bytes_per_line = 0 */
1111 *image_return
= XCreateImage(display
, visual
, depth
, format
, 0, 0,
1112 width
, height
, bitmap_pad
, 0);
1114 return (XpmNoMemory
);
1116 #if !defined(FOR_MSW) && !defined(AMIGA)
1117 /* now that bytes_per_line must have been set properly alloc data */
1118 (*image_return
)->data
=
1119 (char *) XpmMalloc((*image_return
)->bytes_per_line
* height
);
1121 if (!(*image_return
)->data
) {
1122 XDestroyImage(*image_return
);
1123 *image_return
= NULL
;
1124 return (XpmNoMemory
);
1127 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1129 return (XpmSuccess
);
1135 * The functions below are written from X11R5 MIT's code (XImUtil.c)
1137 * The idea is to have faster functions than the standard XPutPixel function
1138 * to build the image data. Indeed we can speed up things by suppressing tests
1139 * performed for each pixel. We do the same tests but at the image level.
1140 * We also assume that we use only ZPixmap images with null offsets.
1143 LFUNC(_putbits
, void, (register char *src
, int dstoffset
,
1144 register int numbits
, register char *dst
));
1146 LFUNC(_XReverse_Bytes
, int, (register unsigned char *bpt
, register int nb
));
1148 static unsigned char Const _reverse_byte
[0x100] = {
1149 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1150 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1151 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1152 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1153 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1154 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1155 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1156 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1157 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1158 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1159 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1160 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1161 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1162 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1163 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1164 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1165 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1166 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1167 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1168 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1169 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1170 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1171 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1172 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1173 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1174 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1175 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1176 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1177 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1178 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1179 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1180 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1184 /* Visual Age cannot deal with old, non-ansi, code */
1186 _XReverse_Bytes(register unsigned char* bpt
, register int nb
)
1189 _XReverse_Bytes(bpt
, nb
)
1190 register unsigned char *bpt
;
1195 *bpt
= _reverse_byte
[*bpt
];
1203 /* Visual Age cannot deal with old, non-ansi, code */
1204 void xpm_xynormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1207 xpm_xynormalizeimagebits(bp
, img
)
1208 register unsigned char *bp
;
1209 register XImage
*img
;
1212 register unsigned char c
;
1214 if (img
->byte_order
!= img
->bitmap_bit_order
) {
1215 switch (img
->bitmap_unit
) {
1228 *(bp
+ 2) = *(bp
+ 1);
1233 if (img
->bitmap_bit_order
== MSBFirst
)
1234 _XReverse_Bytes(bp
, img
->bitmap_unit
>> 3);
1238 /* Visual Age cannot deal with old, non-ansi, code */
1239 void xpm_znormalizeimagebits(register unsigned char* bp
, register XImage
* img
)
1242 xpm_znormalizeimagebits(bp
, img
)
1243 register unsigned char *bp
;
1244 register XImage
*img
;
1247 register unsigned char c
;
1249 switch (img
->bits_per_pixel
) {
1252 _XReverse_Bytes(bp
, 1);
1256 *bp
= ((*bp
>> 4) & 0xF) | ((*bp
<< 4) & ~0xF);
1276 *(bp
+ 2) = *(bp
+ 1);
1282 static unsigned char Const _lomask
[0x09] = {
1283 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1284 static unsigned char Const _himask
[0x09] = {
1285 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
1288 /* Visual Age cannot deal with old, non-ansi, code */
1289 static void _putbits(
1292 , register int numbits
1293 , register char* dst
1297 _putbits(src
, dstoffset
, numbits
, dst
)
1298 register char *src
; /* address of source bit string */
1299 int dstoffset
; /* bit offset into destination;
1301 register int numbits
; /* number of bits to copy to
1303 register char *dst
; /* address of destination bit string */
1306 register unsigned char chlo
, chhi
;
1309 dst
= dst
+ (dstoffset
>> 3);
1310 dstoffset
= dstoffset
& 7;
1311 hibits
= 8 - dstoffset
;
1312 chlo
= *dst
& _lomask
[dstoffset
];
1314 chhi
= (*src
<< dstoffset
) & _himask
[dstoffset
];
1315 if (numbits
<= hibits
) {
1316 chhi
= chhi
& _lomask
[dstoffset
+ numbits
];
1317 *dst
= (*dst
& _himask
[dstoffset
+ numbits
]) | chlo
| chhi
;
1322 numbits
= numbits
- hibits
;
1323 chlo
= (unsigned char) (*src
& _himask
[hibits
]) >> hibits
;
1325 if (numbits
<= dstoffset
) {
1326 chlo
= chlo
& _lomask
[numbits
];
1327 *dst
= (*dst
& _himask
[numbits
]) | chlo
;
1330 numbits
= numbits
- dstoffset
;
1335 * Default method to write pixels into a Z image data structure.
1336 * The algorithm used is:
1338 * copy the destination bitmap_unit or Zpixel to temp
1339 * normalize temp if needed
1340 * copy the pixel bits into the temp
1341 * renormalize temp if needed
1342 * copy the temp back into the destination image data
1346 /* Visual Age cannot deal with old, non-ansi, code */
1347 static void PutImagePixels(
1349 , unsigned int width
1350 , unsigned int height
1351 , unsigned int* pixelindex
1356 PutImagePixels(image
, width
, height
, pixelindex
, pixels
)
1359 unsigned int height
;
1360 unsigned int *pixelindex
;
1366 register unsigned int *iptr
;
1367 register int x
, y
, i
;
1368 register char *data
;
1370 int nbytes
, depth
, ibu
, ibpp
;
1374 depth
= image
->depth
;
1376 ibu
= image
->bitmap_unit
;
1377 for (y
= 0; y
< height
; y
++)
1378 for (x
= 0; x
< width
; x
++, iptr
++) {
1379 pixel
= pixels
[*iptr
];
1380 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long);
1382 ((unsigned char *) &pixel
)[i
] = px
;
1383 src
= &data
[XYINDEX(x
, y
, image
)];
1387 for (i
= nbytes
; --i
>= 0;)
1389 XYNORMALIZE(&px
, image
);
1390 _putbits((char *) &pixel
, (x
% ibu
), 1, (char *) &px
);
1391 XYNORMALIZE(&px
, image
);
1393 dst
= &data
[XYINDEX(x
, y
, image
)];
1394 for (i
= nbytes
; --i
>= 0;)
1398 ibpp
= image
->bits_per_pixel
;
1399 for (y
= 0; y
< height
; y
++)
1400 for (x
= 0; x
< width
; x
++, iptr
++) {
1401 pixel
= pixels
[*iptr
];
1404 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++,
1406 ((unsigned char *) &pixel
)[i
] = px
;
1407 src
= &data
[ZINDEX(x
, y
, image
)];
1410 nbytes
= (ibpp
+ 7) >> 3;
1411 for (i
= nbytes
; --i
>= 0;)
1413 ZNORMALIZE(&px
, image
);
1414 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
1415 ZNORMALIZE(&px
, image
);
1417 dst
= &data
[ZINDEX(x
, y
, image
)];
1418 for (i
= nbytes
; --i
>= 0;)
1425 * write pixels into a 32-bits Z image data structure
1428 #if !defined(WORD64) && !defined(LONG64)
1429 /* this item is static but deterministic so let it slide; doesn't
1430 * hurt re-entrancy of this library. Note if it is actually const then would
1431 * be OK under rules of ANSI-C but probably not C++ which may not
1432 * want to allocate space for it.
1434 static unsigned long byteorderpixel
= MSBFirst
<< 24;
1439 WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
1440 3.2e code - by default you get the speeded-up version.
1444 /* Visual Age cannot deal with old, non-ansi, code */
1448 , unsigned int width
1449 , unsigned int height
1450 , unsigned int* pixelindex
1455 PutImagePixels32(image
, width
, height
, pixelindex
, pixels
)
1458 unsigned int height
;
1459 unsigned int *pixelindex
;
1463 unsigned char *data
;
1468 #ifdef WITHOUT_SPEEDUPS
1471 unsigned char *addr
;
1473 data
= (unsigned char *) image
->data
;
1475 #if !defined(WORD64) && !defined(LONG64)
1476 if (*((char *) &byteorderpixel
) == image
->byte_order
) {
1477 for (y
= 0; y
< height
; y
++)
1478 for (x
= 0; x
< width
; x
++, iptr
++) {
1479 addr
= &data
[ZINDEX32(x
, y
, image
)];
1480 *((unsigned long *) addr
) = pixels
[*iptr
];
1484 if (image
->byte_order
== MSBFirst
)
1485 for (y
= 0; y
< height
; y
++)
1486 for (x
= 0; x
< width
; x
++, iptr
++) {
1487 addr
= &data
[ZINDEX32(x
, y
, image
)];
1488 pixel
= pixels
[*iptr
];
1489 addr
[0] = pixel
>> 24;
1490 addr
[1] = pixel
>> 16;
1491 addr
[2] = pixel
>> 8;
1495 for (y
= 0; y
< height
; y
++)
1496 for (x
= 0; x
< width
; x
++, iptr
++) {
1497 addr
= &data
[ZINDEX32(x
, y
, image
)];
1498 pixel
= pixels
[*iptr
];
1500 addr
[1] = pixel
>> 8;
1501 addr
[2] = pixel
>> 16;
1502 addr
[3] = pixel
>> 24;
1505 #else /* WITHOUT_SPEEDUPS */
1507 int bpl
= image
->bytes_per_line
;
1508 unsigned char *data_ptr
, *max_data
;
1510 data
= (unsigned char *) image
->data
;
1512 #if !defined(WORD64) && !defined(LONG64)
1513 if (*((char *) &byteorderpixel
) == image
->byte_order
) {
1514 for (y
= 0; y
< height
; y
++) {
1516 max_data
= data_ptr
+ (width
<< 2);
1518 while (data_ptr
< max_data
) {
1519 *((unsigned long *) data_ptr
) = pixels
[*(iptr
++)];
1520 data_ptr
+= (1 << 2);
1526 if (image
->byte_order
== MSBFirst
)
1527 for (y
= 0; y
< height
; y
++) {
1529 max_data
= data_ptr
+ (width
<< 2);
1531 while (data_ptr
< max_data
) {
1532 pixel
= pixels
[*(iptr
++)];
1534 *data_ptr
++ = pixel
>> 24;
1535 *data_ptr
++ = pixel
>> 16;
1536 *data_ptr
++ = pixel
>> 8;
1537 *data_ptr
++ = pixel
;
1543 for (y
= 0; y
< height
; y
++) {
1545 max_data
= data_ptr
+ (width
<< 2);
1547 while (data_ptr
< max_data
) {
1548 pixel
= pixels
[*(iptr
++)];
1550 *data_ptr
++ = pixel
;
1551 *data_ptr
++ = pixel
>> 8;
1552 *data_ptr
++ = pixel
>> 16;
1553 *data_ptr
++ = pixel
>> 24;
1558 #endif /* WITHOUT_SPEEDUPS */
1562 * write pixels into a 16-bits Z image data structure
1566 /* Visual Age cannot deal with old, non-ansi, code */
1567 static void PutImagePixels16(
1569 , unsigned int width
1570 , unsigned int height
1571 , unsigned int* pixelindex
1576 PutImagePixels16(image
, width
, height
, pixelindex
, pixels
)
1579 unsigned int height
;
1580 unsigned int *pixelindex
;
1584 unsigned char *data
;
1588 #ifdef WITHOUT_SPEEDUPS
1591 unsigned char *addr
;
1593 data
= (unsigned char *) image
->data
;
1595 if (image
->byte_order
== MSBFirst
)
1596 for (y
= 0; y
< height
; y
++)
1597 for (x
= 0; x
< width
; x
++, iptr
++) {
1598 addr
= &data
[ZINDEX16(x
, y
, image
)];
1599 addr
[0] = pixels
[*iptr
] >> 8;
1600 addr
[1] = pixels
[*iptr
];
1603 for (y
= 0; y
< height
; y
++)
1604 for (x
= 0; x
< width
; x
++, iptr
++) {
1605 addr
= &data
[ZINDEX16(x
, y
, image
)];
1606 addr
[0] = pixels
[*iptr
];
1607 addr
[1] = pixels
[*iptr
] >> 8;
1610 #else /* WITHOUT_SPEEDUPS */
1614 int bpl
= image
->bytes_per_line
;
1615 unsigned char *data_ptr
, *max_data
;
1617 data
= (unsigned char *) image
->data
;
1619 if (image
->byte_order
== MSBFirst
)
1620 for (y
= 0; y
< height
; y
++) {
1622 max_data
= data_ptr
+ (width
<< 1);
1624 while (data_ptr
< max_data
) {
1625 pixel
= pixels
[*(iptr
++)];
1627 data_ptr
[0] = pixel
>> 8;
1628 data_ptr
[1] = pixel
;
1630 data_ptr
+= (1 << 1);
1635 for (y
= 0; y
< height
; y
++) {
1637 max_data
= data_ptr
+ (width
<< 1);
1639 while (data_ptr
< max_data
) {
1640 pixel
= pixels
[*(iptr
++)];
1642 data_ptr
[0] = pixel
;
1643 data_ptr
[1] = pixel
>> 8;
1645 data_ptr
+= (1 << 1);
1650 #endif /* WITHOUT_SPEEDUPS */
1654 * write pixels into a 8-bits Z image data structure
1658 /* Visual Age cannot deal with old, non-ansi, code */
1659 static void PutImagePixels8(
1661 , unsigned int width
1662 , unsigned int height
1663 , unsigned int* pixelindex
1668 PutImagePixels8(image
, width
, height
, pixelindex
, pixels
)
1671 unsigned int height
;
1672 unsigned int *pixelindex
;
1680 #ifdef WITHOUT_SPEEDUPS
1686 for (y
= 0; y
< height
; y
++)
1687 for (x
= 0; x
< width
; x
++, iptr
++)
1688 data
[ZINDEX8(x
, y
, image
)] = pixels
[*iptr
];
1690 #else /* WITHOUT_SPEEDUPS */
1692 int bpl
= image
->bytes_per_line
;
1693 char *data_ptr
, *max_data
;
1698 for (y
= 0; y
< height
; y
++) {
1700 max_data
= data_ptr
+ width
;
1702 while (data_ptr
< max_data
)
1703 *(data_ptr
++) = pixels
[*(iptr
++)];
1708 #endif /* WITHOUT_SPEEDUPS */
1712 * write pixels into a 1-bit depth image data structure and **offset null**
1716 /* Visual Age cannot deal with old, non-ansi, code */
1717 static void PutImagePixels1(
1719 , unsigned int width
1720 , unsigned int height
1721 , unsigned int* pixelindex
1726 PutImagePixels1(image
, width
, height
, pixelindex
, pixels
)
1729 unsigned int height
;
1730 unsigned int *pixelindex
;
1734 if (image
->byte_order
!= image
->bitmap_bit_order
)
1735 PutImagePixels(image
, width
, height
, pixelindex
, pixels
);
1741 #ifdef WITHOUT_SPEEDUPS
1747 if (image
->bitmap_bit_order
== MSBFirst
)
1748 for (y
= 0; y
< height
; y
++)
1749 for (x
= 0; x
< width
; x
++, iptr
++) {
1750 if (pixels
[*iptr
] & 1)
1751 data
[ZINDEX1(x
, y
, image
)] |= 0x80 >> (x
& 7);
1753 data
[ZINDEX1(x
, y
, image
)] &= ~(0x80 >> (x
& 7));
1756 for (y
= 0; y
< height
; y
++)
1757 for (x
= 0; x
< width
; x
++, iptr
++) {
1758 if (pixels
[*iptr
] & 1)
1759 data
[ZINDEX1(x
, y
, image
)] |= 1 << (x
& 7);
1761 data
[ZINDEX1(x
, y
, image
)] &= ~(1 << (x
& 7));
1764 #else /* WITHOUT_SPEEDUPS */
1767 char *data_ptr
, *max_data
;
1768 int bpl
= image
->bytes_per_line
;
1777 if (image
->bitmap_bit_order
== MSBFirst
)
1778 for (y
= 0; y
< height
; y
++) {
1780 max_data
= data_ptr
+ width
;
1781 while (data_ptr
< max_data
) {
1784 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1785 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1786 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1787 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1788 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1789 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1790 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1791 value
= (value
<< 1) | (pixels
[*(iptr
++)] & 1);
1793 *(data_ptr
++) = value
;
1797 for (count
= 0; count
< diff
; count
++) {
1798 if (pixels
[*(iptr
++)] & 1)
1799 value
|= (0x80 >> count
);
1801 *(data_ptr
) = value
;
1806 for (y
= 0; y
< height
; y
++) {
1808 max_data
= data_ptr
+ width
;
1809 while (data_ptr
< max_data
) {
1813 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1814 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1815 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1816 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1817 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1818 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1819 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1820 value
= (value
<< 1) | (pixels
[*(--iptr
)] & 1);
1823 *(data_ptr
++) = value
;
1827 for (count
= 0; count
< diff
; count
++) {
1828 if (pixels
[*(iptr
++)] & 1)
1829 value
|= (1 << count
);
1831 *(data_ptr
) = value
;
1836 #endif /* WITHOUT_SPEEDUPS */
1841 /* Visual Age cannot deal with old, non-ansi, code */
1842 int XpmCreatePixmapFromXpmImage(
1846 , Pixmap
* pixmap_return
1847 , Pixmap
* shapemask_return
1848 , XpmAttributes
* attributes
1851 XpmCreatePixmapFromXpmImage(display
, d
, image
,
1852 pixmap_return
, shapemask_return
, attributes
)
1856 Pixmap
*pixmap_return
;
1857 Pixmap
*shapemask_return
;
1858 XpmAttributes
*attributes
;
1861 XImage
*ximage
, *shapeimage
;
1864 /* initialize return values */
1867 if (shapemask_return
)
1868 *shapemask_return
= 0;
1870 /* create the ximages */
1871 ErrorStatus
= XpmCreateImageFromXpmImage(display
, image
,
1872 (pixmap_return
? &ximage
: NULL
),
1874 &shapeimage
: NULL
),
1876 if (ErrorStatus
< 0)
1877 return (ErrorStatus
);
1879 /* create the pixmaps and destroy images */
1880 if (pixmap_return
&& ximage
) {
1881 xpmCreatePixmapFromImage(display
, d
, ximage
, pixmap_return
);
1882 XDestroyImage(ximage
);
1884 if (shapemask_return
&& shapeimage
) {
1885 xpmCreatePixmapFromImage(display
, d
, shapeimage
, shapemask_return
);
1886 XDestroyImage(shapeimage
);
1888 return (ErrorStatus
);
1897 unsigned int height
,
1898 unsigned int *pixelindex
,
1901 unsigned int *data
= pixelindex
;
1903 unsigned char *array
;
1905 BOOL success
= FALSE
;
1907 array
= XpmMalloc ((((width
+15)>>4)<<4)*sizeof (*array
));
1910 tmp_img
= AllocXImage ((((width
+15)>>4)<<4), 1,
1911 image
->rp
->BitMap
->Depth
);
1912 if (tmp_img
!= NULL
)
1914 for (y
= 0; y
< height
; ++y
)
1916 for (x
= 0; x
< width
; ++x
)
1917 array
[x
] = pixels
[*(data
++)];
1918 WritePixelLine8 (image
->rp
, 0, y
, width
, array
, tmp_img
->rp
);
1920 FreeXImage (tmp_img
);
1928 for (y
= 0; y
< height
; ++y
)
1929 for (x
= 0; x
< width
; ++x
)
1930 XPutPixel (image
, x
, y
, pixels
[*(data
++)]);
1935 #else /* FOR_MSW part follows */
1938 /* Visual Age cannot deal with old, non-ansi, code */
1939 static void MSWPutImagePixels(
1942 , unsigned int width
1943 , unsigned int height
1944 , unsigned int* pixelindex
1949 MSWPutImagePixels(dc
, image
, width
, height
, pixelindex
, pixels
)
1953 unsigned int height
;
1954 unsigned int *pixelindex
;
1958 unsigned int *data
= pixelindex
;
1965 obm
= GpiSetBitmap(*dc
, image
->bitmap
);
1967 obm
= SelectObject(*dc
, image
->bitmap
);
1970 for (y
= 0; y
< height
; y
++) {
1971 for (x
= 0; x
< width
; x
++) {
1975 GpiSetColor(*dc
, (LONG
)pixels
[*(data
++)]);
1976 GpiSetPel(*dc
, &point
);
1979 SetPixel(*dc
, x
, y
, pixels
[*(data
++)]); /* data is [x+y*width] */
1984 GpiSetBitmap(*dc
, obm
);
1986 SelectObject(*dc
, obm
);
1990 #endif /* FOR_MSW */
1994 #if !defined(FOR_MSW) && !defined(AMIGA)
1997 PutPixel1(ximage
, x
, y
, pixel
)
1998 register XImage
*ximage
;
2001 unsigned long pixel
;
2006 register char *data
;
2010 for (i
=0, px
=pixel
; i
<sizeof(unsigned long); i
++, px
>>=8)
2011 ((unsigned char *)&pixel
)[i
] = px
;
2012 src
= &ximage
->data
[XYINDEX(x
, y
, ximage
)];
2015 nbytes
= ximage
->bitmap_unit
>> 3;
2016 for (i
= nbytes
; --i
>= 0; ) *dst
++ = *src
++;
2017 XYNORMALIZE(&px
, ximage
);
2018 i
= ((x
+ ximage
->xoffset
) % ximage
->bitmap_unit
);
2019 _putbits ((char *)&pixel
, i
, 1, (char *)&px
);
2020 XYNORMALIZE(&px
, ximage
);
2022 dst
= &ximage
->data
[XYINDEX(x
, y
, ximage
)];
2023 for (i
= nbytes
; --i
>= 0; )
2030 PutPixel(ximage
, x
, y
, pixel
)
2031 register XImage
*ximage
;
2034 unsigned long pixel
;
2039 register char *data
;
2043 ibpp
= ximage
->bits_per_pixel
;
2044 if (ximage
->depth
== 4)
2046 for (i
= 0, px
= pixel
; i
< sizeof(unsigned long); i
++, px
>>= 8)
2047 ((unsigned char *) &pixel
)[i
] = px
;
2048 src
= &ximage
->data
[ZINDEX(x
, y
, ximage
)];
2051 nbytes
= (ibpp
+ 7) >> 3;
2052 for (i
= nbytes
; --i
>= 0;)
2054 ZNORMALIZE(&px
, ximage
);
2055 _putbits((char *) &pixel
, (x
* ibpp
) & 7, ibpp
, (char *) &px
);
2056 ZNORMALIZE(&px
, ximage
);
2058 dst
= &ximage
->data
[ZINDEX(x
, y
, ximage
)];
2059 for (i
= nbytes
; --i
>= 0;)
2066 PutPixel32(ximage
, x
, y
, pixel
)
2067 register XImage
*ximage
;
2070 unsigned long pixel
;
2072 unsigned char *addr
;
2074 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2075 *((unsigned long *)addr
) = pixel
;
2080 PutPixel32MSB(ximage
, x
, y
, pixel
)
2081 register XImage
*ximage
;
2084 unsigned long pixel
;
2086 unsigned char *addr
;
2088 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2089 addr
[0] = pixel
>> 24;
2090 addr
[1] = pixel
>> 16;
2091 addr
[2] = pixel
>> 8;
2097 PutPixel32LSB(ximage
, x
, y
, pixel
)
2098 register XImage
*ximage
;
2101 unsigned long pixel
;
2103 unsigned char *addr
;
2105 addr
= &((unsigned char *)ximage
->data
) [ZINDEX32(x
, y
, ximage
)];
2106 addr
[3] = pixel
>> 24;
2107 addr
[2] = pixel
>> 16;
2108 addr
[1] = pixel
>> 8;
2114 PutPixel16MSB(ximage
, x
, y
, pixel
)
2115 register XImage
*ximage
;
2118 unsigned long pixel
;
2120 unsigned char *addr
;
2122 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2123 addr
[0] = pixel
>> 8;
2129 PutPixel16LSB(ximage
, x
, y
, pixel
)
2130 register XImage
*ximage
;
2133 unsigned long pixel
;
2135 unsigned char *addr
;
2137 addr
= &((unsigned char *)ximage
->data
) [ZINDEX16(x
, y
, ximage
)];
2138 addr
[1] = pixel
>> 8;
2144 PutPixel8(ximage
, x
, y
, pixel
)
2145 register XImage
*ximage
;
2148 unsigned long pixel
;
2150 ximage
->data
[ZINDEX8(x
, y
, ximage
)] = pixel
;
2155 PutPixel1MSB(ximage
, x
, y
, pixel
)
2156 register XImage
*ximage
;
2159 unsigned long pixel
;
2162 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 0x80 >> (x
& 7);
2164 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(0x80 >> (x
& 7));
2169 PutPixel1LSB(ximage
, x
, y
, pixel
)
2170 register XImage
*ximage
;
2173 unsigned long pixel
;
2176 ximage
->data
[ZINDEX1(x
, y
, ximage
)] |= 1 << (x
& 7);
2178 ximage
->data
[ZINDEX1(x
, y
, ximage
)] &= ~(1 << (x
& 7));
2182 #endif /* not FOR_MSW && not AMIGA */
2185 * This function parses an Xpm file or data and directly create an XImage
2188 /* Visual Age cannot deal with old, non-ansi, code */
2189 int xpmParseDataAndCreate(
2192 , XImage
** image_return
2193 , XImage
** shapeimage_return
2196 , XpmAttributes
* attributes
2200 xpmParseDataAndCreate(display
, data
, image_return
, shapeimage_return
,
2201 image
, info
, attributes
)
2204 XImage
**image_return
;
2205 XImage
**shapeimage_return
;
2208 XpmAttributes
*attributes
;
2211 /* variables stored in the XpmAttributes structure */
2216 XpmFreeColorsFunc freeColors
;
2219 /* variables to return */
2220 XImage
*ximage
= NULL
;
2221 XImage
*shapeimage
= NULL
;
2222 unsigned int mask_pixel_index
= XpmUndefPixel
;
2224 /* calculation variables */
2225 Pixel
*image_pixels
= NULL
;
2226 Pixel
*mask_pixels
= NULL
;
2227 Pixel
*alloc_pixels
= NULL
;
2228 Pixel
*used_pixels
= NULL
;
2229 unsigned int nalloc_pixels
= 0;
2230 unsigned int nused_pixels
= 0;
2231 unsigned int width
, height
, ncolors
, cpp
;
2232 unsigned int x_hotspot
, y_hotspot
, hotspot
= 0, extensions
= 0;
2233 XpmColor
*colorTable
= NULL
;
2234 char *hints_cmt
= NULL
;
2235 char *colors_cmt
= NULL
;
2236 char *pixels_cmt
= NULL
;
2240 xpmHashTable hashtable
;
2243 /* initialize return values */
2245 *image_return
= NULL
;
2246 if (shapeimage_return
)
2247 *shapeimage_return
= NULL
;
2250 /* retrieve information from the XpmAttributes */
2251 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
2252 visual
= attributes
->visual
;
2254 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
2256 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
2257 colormap
= attributes
->colormap
;
2259 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
2261 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
2262 depth
= attributes
->depth
;
2264 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
2266 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
2267 bitmap_format
= attributes
->bitmap_format
;
2269 bitmap_format
= ZPixmap
;
2271 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
2272 freeColors
= attributes
->free_colors
;
2274 freeColors
= FreeColors
;
2275 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
2276 closure
= attributes
->color_closure
;
2280 cmts
= info
&& (info
->valuemask
& XpmReturnComments
);
2285 ErrorStatus
= xpmParseHeader(data
);
2286 if (ErrorStatus
!= XpmSuccess
)
2287 return (ErrorStatus
);
2292 ErrorStatus
= xpmParseValues(data
, &width
, &height
, &ncolors
, &cpp
,
2293 &x_hotspot
, &y_hotspot
, &hotspot
,
2295 if (ErrorStatus
!= XpmSuccess
)
2296 return (ErrorStatus
);
2299 * store the hints comment line
2302 xpmGetCmt(data
, &hints_cmt
);
2307 if (USE_HASHTABLE
) {
2308 ErrorStatus
= xpmHashTableInit(&hashtable
);
2309 if (ErrorStatus
!= XpmSuccess
)
2310 return (ErrorStatus
);
2316 ErrorStatus
= xpmParseColors(data
, ncolors
, cpp
, &colorTable
, &hashtable
);
2317 if (ErrorStatus
!= XpmSuccess
)
2318 RETURN(ErrorStatus
);
2321 * store the colors comment line
2324 xpmGetCmt(data
, &colors_cmt
);
2326 /* malloc pixels index tables */
2327 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2329 RETURN(XpmNoMemory
);
2331 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2333 RETURN(XpmNoMemory
);
2335 /* maximum of allocated pixels will be the number of colors */
2336 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2338 RETURN(XpmNoMemory
);
2340 /* maximum of allocated pixels will be the number of colors */
2341 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
2343 RETURN(XpmNoMemory
);
2345 /* get pixel colors, store them in index tables */
2346 ErrorStatus
= CreateColors(display
, attributes
, colorTable
, ncolors
,
2347 image_pixels
, mask_pixels
, &mask_pixel_index
,
2348 alloc_pixels
, &nalloc_pixels
, used_pixels
,
2351 if (ErrorStatus
!= XpmSuccess
2352 && (ErrorStatus
< 0 || (attributes
2353 && (attributes
->valuemask
& XpmExactColors
)
2354 && attributes
->exactColors
)))
2355 RETURN(ErrorStatus
);
2357 /* now create the ximage */
2359 ErrorStatus
= CreateXImage(display
, visual
, depth
,
2360 (depth
== 1 ? bitmap_format
: ZPixmap
),
2361 width
, height
, &ximage
);
2362 if (ErrorStatus
!= XpmSuccess
)
2363 RETURN(ErrorStatus
);
2365 #if !defined(FOR_MSW) && !defined(AMIGA)
2368 * set the XImage pointer function, to be used with XPutPixel,
2369 * to an internal optimized function
2372 if (ximage
->bits_per_pixel
== 8)
2373 ximage
->f
.put_pixel
= PutPixel8
;
2374 else if (((ximage
->bits_per_pixel
| ximage
->depth
) == 1) &&
2375 (ximage
->byte_order
== ximage
->bitmap_bit_order
))
2376 if (ximage
->bitmap_bit_order
== MSBFirst
)
2377 ximage
->f
.put_pixel
= PutPixel1MSB
;
2379 ximage
->f
.put_pixel
= PutPixel1LSB
;
2380 else if (ximage
->bits_per_pixel
== 16)
2381 if (ximage
->bitmap_bit_order
== MSBFirst
)
2382 ximage
->f
.put_pixel
= PutPixel16MSB
;
2384 ximage
->f
.put_pixel
= PutPixel16LSB
;
2385 else if (ximage
->bits_per_pixel
== 32)
2386 #if !defined(WORD64) && !defined(LONG64)
2387 if (*((char *)&byteorderpixel
) == ximage
->byte_order
)
2388 ximage
->f
.put_pixel
= PutPixel32
;
2391 if (ximage
->bitmap_bit_order
== MSBFirst
)
2392 ximage
->f
.put_pixel
= PutPixel32MSB
;
2394 ximage
->f
.put_pixel
= PutPixel32LSB
;
2395 else if ((ximage
->bits_per_pixel
| ximage
->depth
) == 1)
2396 ximage
->f
.put_pixel
= PutPixel1
;
2398 ximage
->f
.put_pixel
= PutPixel
;
2399 #endif /* not FOR_MSW && not AMIGA */
2402 /* create the shape mask image */
2403 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
2404 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
2405 width
, height
, &shapeimage
);
2406 if (ErrorStatus
!= XpmSuccess
)
2407 RETURN(ErrorStatus
);
2409 #if !defined(FOR_MSW) && !defined(AMIGA)
2410 if (shapeimage
->bitmap_bit_order
== MSBFirst
)
2411 shapeimage
->f
.put_pixel
= PutPixel1MSB
;
2413 shapeimage
->f
.put_pixel
= PutPixel1LSB
;
2418 * read pixels and put them in the XImage
2420 ErrorStatus
= ParseAndPutPixels(
2424 data
, width
, height
, ncolors
, cpp
,
2425 colorTable
, &hashtable
,
2426 ximage
, image_pixels
,
2427 shapeimage
, mask_pixels
);
2428 XpmFree(image_pixels
);
2429 image_pixels
= NULL
;
2430 XpmFree(mask_pixels
);
2436 if (ErrorStatus
!= XpmSuccess
)
2438 else if (USE_HASHTABLE
)
2439 xpmHashTableFree(&hashtable
);
2442 * store the pixels comment line
2445 xpmGetCmt(data
, &pixels_cmt
);
2450 if (info
&& (info
->valuemask
& XpmReturnExtensions
))
2452 ErrorStatus
= xpmParseExtensions(data
, &info
->extensions
,
2453 &info
->nextensions
);
2454 if (ErrorStatus
!= XpmSuccess
)
2455 RETURN(ErrorStatus
);
2457 info
->extensions
= NULL
;
2458 info
->nextensions
= 0;
2462 * store found informations in the XpmImage structure
2464 image
->width
= width
;
2465 image
->height
= height
;
2467 image
->ncolors
= ncolors
;
2468 image
->colorTable
= colorTable
;
2473 info
->hints_cmt
= hints_cmt
;
2474 info
->colors_cmt
= colors_cmt
;
2475 info
->pixels_cmt
= pixels_cmt
;
2478 info
->x_hotspot
= x_hotspot
;
2479 info
->y_hotspot
= y_hotspot
;
2480 info
->valuemask
|= XpmHotspot
;
2483 /* if requested return used pixels in the XpmAttributes structure */
2484 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
2485 /* 3.2 backward compatibility code */
2486 attributes
->valuemask
& XpmReturnInfos
)) {
2488 attributes
->pixels
= used_pixels
;
2489 attributes
->npixels
= nused_pixels
;
2490 attributes
->mask_pixel
= mask_pixel_index
;
2492 XpmFree(used_pixels
);
2494 /* if requested return alloc'ed pixels in the XpmAttributes structure */
2495 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
2496 attributes
->alloc_pixels
= alloc_pixels
;
2497 attributes
->nalloc_pixels
= nalloc_pixels
;
2499 XpmFree(alloc_pixels
);
2501 /* return created images */
2503 *image_return
= ximage
;
2504 if (shapeimage_return
)
2505 *shapeimage_return
= shapeimage
;
2507 return (XpmSuccess
);
2509 /* exit point in case of error, free only locally allocated variables */
2512 xpmHashTableFree(&hashtable
);
2514 xpmFreeColorTable(colorTable
, ncolors
);
2518 XpmFree(colors_cmt
);
2520 XpmFree(pixels_cmt
);
2522 XDestroyImage(ximage
);
2524 XDestroyImage(shapeimage
);
2526 XpmFree(image_pixels
);
2528 XpmFree(mask_pixels
);
2530 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
2532 XpmFree(alloc_pixels
);
2534 XpmFree(used_pixels
);
2536 return (ErrorStatus
);
2540 /* Visual Age cannot deal with old, non-ansi, code */
2541 static int ParseAndPutPixels(
2544 , unsigned int width
2545 , unsigned int height
2546 , unsigned int ncolors
2548 , XpmColor
* colorTable
2549 , xpmHashTable
* hashtable
2551 , Pixel
* image_pixels
2552 , XImage
* shapeimage
2553 , Pixel
* shape_pixels
2561 data
, width
, height
, ncolors
, cpp
, colorTable
, hashtable
,
2562 image
, image_pixels
, shapeimage
, shape_pixels
)
2568 unsigned int height
;
2569 unsigned int ncolors
;
2571 XpmColor
*colorTable
;
2572 xpmHashTable
*hashtable
;
2574 Pixel
*image_pixels
;
2576 Pixel
*shape_pixels
;
2579 unsigned int a
, x
, y
;
2582 DEVOPENSTRUC dop
= {NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
2583 SIZEL sizl
= {0, 0};
2589 case (1): /* Optimize for single character
2592 unsigned short colidx
[256];
2599 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2600 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2601 sobm
= GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2603 shapedc
= CreateCompatibleDC(*dc
);
2604 sobm
= SelectObject(shapedc
, shapeimage
->bitmap
);
2610 obm
= GpiSetBitmap(*dc
, image
->bitmap
);
2612 obm
= SelectObject(*dc
, image
->bitmap
);
2618 bzero((char *)colidx
, 256 * sizeof(short));
2619 for (a
= 0; a
< ncolors
; a
++)
2620 colidx
[(unsigned char)colorTable
[a
].string
[0]] = a
+ 1;
2622 for (y
= 0; y
< height
; y
++) {
2623 xpmNextString(data
);
2624 for (x
= 0; x
< width
; x
++) {
2625 int c
= xpmGetC(data
);
2627 if (c
> 0 && c
< 256 && colidx
[c
] != 0) {
2629 XPutPixel(image
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2631 XPutPixel(shapeimage
, x
, y
,
2632 shape_pixels
[colidx
[c
] - 1]);
2637 GpiSetColor(*dc
, (LONG
)image_pixels
[colidx
[c
] - 1]);
2638 GpiSetPel(*dc
, &point
);
2640 SetPixel(*dc
, x
, y
, image_pixels
[colidx
[c
] - 1]);
2646 GpiSetColor(*dc
, (LONG
)shape_pixels
[colidx
[c
] - 1]);
2647 GpiSetPel(*dc
, &point
);
2649 SetPixel(shapedc
, x
, y
, shape_pixels
[colidx
[c
] - 1]);
2654 return (XpmFileInvalid
);
2660 GpiSetBitmap(*dc
, sobm
);
2662 DevCloseDC(shapedc
);
2664 SelectObject(shapedc
, sobm
);
2669 GpiSetBitmap(*dc
, obm
);
2671 SelectObject(*dc
, obm
);
2677 case (2): /* Optimize for double character
2680 /* free all allocated pointers at all exits */
2681 #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
2682 if (cidx[f]) XpmFree(cidx[f]);}
2684 /* array of pointers malloced by need */
2685 unsigned short *cidx
[256];
2691 bzero((char *)cidx
, 256 * sizeof(unsigned short *)); /* init */
2692 for (a
= 0; a
< ncolors
; a
++) {
2693 char1
= colorTable
[a
].string
[0];
2694 if (cidx
[char1
] == NULL
) { /* get new memory */
2695 cidx
[char1
] = (unsigned short *)
2696 XpmCalloc(256, sizeof(unsigned short));
2697 if (cidx
[char1
] == NULL
) { /* new block failed */
2699 return (XpmNoMemory
);
2702 cidx
[char1
][(unsigned char)colorTable
[a
].string
[1]] = a
+ 1;
2705 for (y
= 0; y
< height
; y
++) {
2706 xpmNextString(data
);
2707 for (x
= 0; x
< width
; x
++) {
2708 int cc1
= xpmGetC(data
);
2709 if (cc1
> 0 && cc1
< 256) {
2710 int cc2
= xpmGetC(data
);
2711 if (cc2
> 0 && cc2
< 256 &&
2712 cidx
[cc1
] && cidx
[cc1
][cc2
] != 0) {
2714 XPutPixel(image
, x
, y
,
2715 image_pixels
[cidx
[cc1
][cc2
] - 1]);
2717 XPutPixel(shapeimage
, x
, y
,
2718 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2721 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2722 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2724 GpiSetBitmap(*dc
, image
->bitmap
);
2727 GpiSetColor(*dc
, (LONG
)image_pixels
[cidx
[cc1
][cc2
] - 1]);
2728 GpiSetPel(*dc
, &point
);
2730 SelectObject(*dc
, image
->bitmap
);
2731 SetPixel(*dc
, x
, y
, image_pixels
[cidx
[cc1
][cc2
] - 1]);
2735 GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2738 GpiSetColor(*dc
, (LONG
)shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2739 GpiSetPel(*dc
, &point
);
2741 SelectObject(*dc
, shapeimage
->bitmap
);
2743 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
2749 return (XpmFileInvalid
);
2753 return (XpmFileInvalid
);
2761 default: /* Non-optimized case of long color
2771 if (USE_HASHTABLE
) {
2774 for (y
= 0; y
< height
; y
++) {
2775 xpmNextString(data
);
2776 for (x
= 0; x
< width
; x
++) {
2777 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
2779 slot
= xpmHashSlot(hashtable
, buf
);
2780 if (!*slot
) /* no color matches */
2781 return (XpmFileInvalid
);
2783 XPutPixel(image
, x
, y
,
2784 image_pixels
[HashColorIndex(slot
)]);
2786 XPutPixel(shapeimage
, x
, y
,
2787 shape_pixels
[HashColorIndex(slot
)]);
2791 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2792 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2794 GpiSetBitmap(*dc
, image
->bitmap
);
2797 GpiSetColor(*dc
, (LONG
)image_pixels
[HashColorIndex(slot
)]);
2798 GpiSetPel(*dc
, &point
);
2800 SelectObject(*dc
, image
->bitmap
);
2802 image_pixels
[HashColorIndex(slot
)]);
2806 GpiSetBitmap(*dc
, shapeimage
->bitmap
);
2809 GpiSetColor(*dc
, (LONG
)shape_pixels
[HashColorIndex(slot
)]);
2810 GpiSetPel(*dc
, &point
);
2812 SelectObject(*dc
, shapeimage
->bitmap
);
2814 shape_pixels
[HashColorIndex(slot
)]);
2821 for (y
= 0; y
< height
; y
++) {
2822 xpmNextString(data
);
2823 for (x
= 0; x
< width
; x
++) {
2824 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
2826 for (a
= 0; a
< ncolors
; a
++)
2827 if (!strcmp(colorTable
[a
].string
, buf
))
2829 if (a
== ncolors
) /* no color matches */
2830 return (XpmFileInvalid
);
2832 XPutPixel(image
, x
, y
, image_pixels
[a
]);
2834 XPutPixel(shapeimage
, x
, y
, shape_pixels
[a
]);
2838 shapedc
= DevOpenDC(hab
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&dop
, NULLHANDLE
);
2839 *dc
= GpiCreatePS(hab
, shapedc
, &sizl
, GPIA_ASSOC
| PU_PELS
);
2841 GpiSetBitmap(*dc
, image
->bitmap
);
2844 GpiSetColor(*dc
, (LONG
)image_pixels
[a
]);
2845 GpiSetPel(*dc
, &point
);
2847 SelectObject(*dc
, image
->bitmap
);
2848 SetPixel(*dc
, x
, y
, image_pixels
[a
]);
2852 GpiSetBitmap(*dc
, image
->bitmap
);
2855 GpiSetColor(*dc
, (LONG
)shape_pixels
[a
]);
2856 GpiSetPel(*dc
, &point
);
2858 SelectObject(*dc
, shapeimage
->bitmap
);
2859 SetPixel(*dc
, x
, y
, shape_pixels
[a
]);
2869 return (XpmSuccess
);