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
));
56 LFUNC(SetColor
, int, (Display
*display
, Colormap colormap
, Visual
*visual
,
57 char *colorname
, unsigned int color_index
,
58 Pixel
*image_pixel
, Pixel
*mask_pixel
,
59 unsigned int *mask_pixel_index
,
60 Pixel
*alloc_pixels
, unsigned int *nalloc_pixels
,
61 Pixel
*used_pixels
, unsigned int *nused_pixels
,
62 XpmAttributes
*attributes
, XColor
*cols
, int ncols
,
63 XpmAllocColorFunc allocColor
, void *closure
));
65 LFUNC(CreateXImage
, int, (Display
*display
, Visual
*visual
,
66 unsigned int depth
, int format
, unsigned int width
,
67 unsigned int height
, XImage
**image_return
));
69 LFUNC(CreateColors
, int, (Display
*display
, XpmAttributes
*attributes
,
70 XpmColor
*colors
, unsigned int ncolors
,
71 Pixel
*image_pixels
, Pixel
*mask_pixels
,
72 unsigned int *mask_pixel_index
,
73 Pixel
*alloc_pixels
, unsigned int *nalloc_pixels
,
74 Pixel
*used_pixels
, unsigned int *nused_pixels
));
76 LFUNC(ParseAndPutPixels
, int, (Display
*dc
, xpmData
*data
, unsigned int width
,
77 unsigned int height
, unsigned int ncolors
,
78 unsigned int cpp
, XpmColor
*colorTable
,
79 xpmHashTable
*hashtable
,
80 XImage
*image
, Pixel
*image_pixels
,
81 XImage
*mask
, Pixel
*mask_pixels
));
83 LFUNC(PlatformPutImagePixels
, void, (Display
*dc
, XImage
*image
,
84 unsigned int width
, unsigned int height
,
85 unsigned int *pixelindex
, Pixel
*pixels
));
88 #ifdef NEED_STRCASECMP
89 FUNC(xpmstrcasecmp
, int, (char *s1
, char *s2
));
92 * in case strcasecmp is not provided by the system here is one
93 * which does the trick
97 register char *s1
, *s2
;
109 return (int) (*s1
- *s2
);
115 * return the default color key related to the given visual
118 xpmVisualType(visual
)
134 CloseColor
*x
= (CloseColor
*) a
, *y
= (CloseColor
*) b
;
136 /* cast to int as qsort requires */
137 return (int) (x
->closeness
- y
->closeness
);
141 /* default AllocColor function:
142 * call XParseColor if colorname is given, return negative value if failure
143 * call XAllocColor and return 0 if failure, positive otherwise
146 AllocColor(display
, colormap
, colorname
, xcolor
, closure
)
151 void *closure
; /* not used */
155 if (!XParseColor(display
, colormap
, colorname
, xcolor
))
157 status
= XAllocColor(display
, colormap
, xcolor
);
158 return status
!= 0 ? 1 : 0;
162 * set the color pixel related to the given colorname,
163 * return 0 if success, 1 otherwise.
167 SetColor(display
, colormap
, visual
, colorname
, color_index
,
168 image_pixel
, mask_pixel
, mask_pixel_index
,
169 alloc_pixels
, nalloc_pixels
, used_pixels
, nused_pixels
,
170 attributes
, cols
, ncols
, allocColor
, closure
)
175 unsigned int color_index
;
176 Pixel
*image_pixel
, *mask_pixel
;
177 unsigned int *mask_pixel_index
;
179 unsigned int *nalloc_pixels
;
181 unsigned int *nused_pixels
;
182 XpmAttributes
*attributes
;
185 XpmAllocColorFunc allocColor
;
191 if (xpmstrcasecmp(colorname
, TRANSPARENT_COLOR
))
193 status
= (*allocColor
)(display
, colormap
, colorname
, &xcolor
, closure
);
194 if (status
< 0) /* parse color failed */
200 alloc_pixels
[(*nalloc_pixels
)++] = xcolor
.pixel
;
201 *image_pixel
= xcolor
.pixel
;
203 SET_ZERO_PIXEL( *mask_pixel
);
205 used_pixels
[(*nused_pixels
)++] = xcolor
.pixel
;
209 // this is a special for mac - we have to get white as background for transparency
211 SET_WHITE_PIXEL( *image_pixel
) ;
213 SET_ZERO_PIXEL( *image_pixel
);
215 SET_WHITE_PIXEL( *mask_pixel
) ;
217 /* store the color table index */
218 *mask_pixel_index
= color_index
;
225 CreateColors(display
, attributes
, colors
, ncolors
, image_pixels
, mask_pixels
,
226 mask_pixel_index
, alloc_pixels
, nalloc_pixels
,
227 used_pixels
, nused_pixels
)
229 XpmAttributes
*attributes
;
231 unsigned int ncolors
;
234 unsigned int *mask_pixel_index
;
236 unsigned int *nalloc_pixels
;
238 unsigned int *nused_pixels
;
240 /* variables stored in the XpmAttributes structure */
243 XpmColorSymbol
*colorsymbols
;
244 unsigned int numsymbols
;
245 XpmAllocColorFunc allocColor
;
249 unsigned int color
, key
;
251 XpmColorSymbol
*symbol
;
253 int ErrorStatus
= XpmSuccess
;
258 unsigned int ncols
= 0;
261 * retrieve information from the XpmAttributes
263 if (attributes
&& attributes
->valuemask
& XpmColorSymbols
) {
264 colorsymbols
= attributes
->colorsymbols
;
265 numsymbols
= attributes
->numsymbols
;
269 if (attributes
&& attributes
->valuemask
& XpmVisual
)
270 visual
= attributes
->visual
;
272 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
274 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
275 colormap
= attributes
->colormap
;
277 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
279 if (attributes
&& (attributes
->valuemask
& XpmColorKey
))
280 key
= attributes
->color_key
;
282 key
= xpmVisualType(visual
);
284 if (attributes
&& (attributes
->valuemask
& XpmAllocColor
))
285 allocColor
= attributes
->alloc_color
;
287 allocColor
= AllocColor
;
288 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
289 closure
= attributes
->color_closure
;
309 for (color
= 0; color
< ncolors
; color
++, colors
++,
310 image_pixels
++, mask_pixels
++) {
312 pixel_defined
= False
;
313 defaults
= (char **) colors
;
316 * look for a defined symbol
323 for (n
= 0, symbol
= colorsymbols
; n
< numsymbols
; n
++, symbol
++) {
324 if (symbol
->name
&& s
&& !strcmp(symbol
->name
, s
))
327 if (!symbol
->name
&& symbol
->value
) { /* override value */
328 int def_index
= default_index
;
330 while (defaults
[def_index
] == NULL
) /* find defined
333 if (def_index
< 2) {/* nothing towards mono, so try
335 def_index
= default_index
+ 1;
336 while (def_index
<= 5 && defaults
[def_index
] == NULL
)
339 if (def_index
>= 2 && defaults
[def_index
] != NULL
&&
340 !xpmstrcasecmp(symbol
->value
, defaults
[def_index
]))
344 if (n
!= numsymbols
) {
345 if (symbol
->name
&& symbol
->value
)
346 colorname
= symbol
->value
;
348 pixel_defined
= True
;
351 if (!pixel_defined
) { /* pixel not given as symbol value */
355 if (colorname
) { /* colorname given as symbol value */
356 if (!SetColor(display
, colormap
, visual
, colorname
, color
,
357 image_pixels
, mask_pixels
, mask_pixel_index
,
358 alloc_pixels
, nalloc_pixels
, used_pixels
,
359 nused_pixels
, attributes
, cols
, ncols
,
360 allocColor
, closure
))
361 pixel_defined
= True
;
363 ErrorStatus
= XpmColorError
;
366 while (!pixel_defined
&& k
> 1) {
368 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
369 color
, image_pixels
, mask_pixels
,
370 mask_pixel_index
, alloc_pixels
,
371 nalloc_pixels
, used_pixels
, nused_pixels
,
372 attributes
, cols
, ncols
,
373 allocColor
, closure
)) {
374 pixel_defined
= True
;
377 ErrorStatus
= XpmColorError
;
382 while (!pixel_defined
&& k
< NKEYS
+ 1) {
384 if (!SetColor(display
, colormap
, visual
, defaults
[k
],
385 color
, image_pixels
, mask_pixels
,
386 mask_pixel_index
, alloc_pixels
,
387 nalloc_pixels
, used_pixels
, nused_pixels
,
388 attributes
, cols
, ncols
,
389 allocColor
, closure
)) {
390 pixel_defined
= True
;
393 ErrorStatus
= XpmColorError
;
397 if (!pixel_defined
) {
400 return (XpmColorFailed
);
403 /* simply use the given pixel */
404 *image_pixels
= symbol
->pixel
;
405 /* the following makes the mask to be built even if none
406 is given a particular pixel */
408 && !xpmstrcasecmp(symbol
->value
, TRANSPARENT_COLOR
))
410 SET_ZERO_PIXEL( *mask_pixels
) ;
411 *mask_pixel_index
= color
;
415 #if defined(macintosh) || defined(__APPLE__)
416 SET_WHITE_PIXEL( *mask_pixels
) ; // is this correct CS ????
418 *mask_pixels
= 1; // is this correct CS ????
421 used_pixels
[(*nused_pixels
)++] = *image_pixels
;
426 return (ErrorStatus
);
430 /* default FreeColors function, simply call XFreeColors */
432 FreeColors(display
, colormap
, pixels
, n
, closure
)
437 void *closure
; /* not used */
439 return XFreeColors(display
, colormap
, pixels
, n
, 0);
443 /* function call in case of error */
445 #define RETURN(status) \
447 ErrorStatus = status; \
452 XpmCreateImageFromXpmImage(display
, image
,
453 image_return
, shapeimage_return
, attributes
)
456 XImage
**image_return
;
457 XImage
**shapeimage_return
;
458 XpmAttributes
*attributes
;
460 /* variables stored in the XpmAttributes structure */
465 XpmFreeColorsFunc freeColors
;
468 /* variables to return */
469 XImage
*ximage
= NULL
;
470 XImage
*shapeimage
= NULL
;
471 unsigned int mask_pixel_index
= XpmUndefPixel
;
474 /* calculation variables */
475 Pixel
*image_pixels
= NULL
;
476 Pixel
*mask_pixels
= NULL
;
477 Pixel
*alloc_pixels
= NULL
;
478 Pixel
*used_pixels
= NULL
;
479 unsigned int nalloc_pixels
= 0;
480 unsigned int nused_pixels
= 0;
482 /* initialize return values */
484 *image_return
= NULL
;
485 if (shapeimage_return
)
486 *shapeimage_return
= NULL
;
488 /* retrieve information from the XpmAttributes */
489 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
490 visual
= attributes
->visual
;
492 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
494 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
495 colormap
= attributes
->colormap
;
497 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
499 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
500 depth
= attributes
->depth
;
502 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
504 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
505 bitmap_format
= attributes
->bitmap_format
;
507 bitmap_format
= ZPixmap
;
509 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
510 freeColors
= attributes
->free_colors
;
512 freeColors
= FreeColors
;
513 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
514 closure
= attributes
->color_closure
;
518 ErrorStatus
= XpmSuccess
;
520 /* malloc pixels index tables */
521 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
523 return (XpmNoMemory
);
525 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
529 /* maximum of allocated pixels will be the number of colors */
530 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
534 /* maximum of allocated pixels will be the number of colors */
535 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * image
->ncolors
);
539 /* get pixel colors, store them in index tables */
540 ErrorStatus
= CreateColors(display
, attributes
, image
->colorTable
,
541 image
->ncolors
, image_pixels
, mask_pixels
,
542 &mask_pixel_index
, alloc_pixels
, &nalloc_pixels
,
543 used_pixels
, &nused_pixels
);
545 if (ErrorStatus
!= XpmSuccess
546 && (ErrorStatus
< 0 || (attributes
547 && (attributes
->valuemask
& XpmExactColors
)
548 && attributes
->exactColors
)))
551 /* create the ximage */
553 ErrorStatus
= CreateXImage(display
, visual
, depth
,
554 (depth
== 1 ? bitmap_format
: ZPixmap
),
555 image
->width
, image
->height
, &ximage
);
556 if (ErrorStatus
!= XpmSuccess
)
559 PlatformPutImagePixels(display
, ximage
, image
->width
, image
->height
,
560 image
->data
, image_pixels
);
563 /* create the shape mask image */
564 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
565 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
566 image
->width
, image
->height
, &shapeimage
);
567 if (ErrorStatus
!= XpmSuccess
)
570 PlatformPutImagePixels(display
, shapeimage
, image
->width
, image
->height
,
571 image
->data
, mask_pixels
);
574 XpmFree(image_pixels
);
575 XpmFree(mask_pixels
);
577 /* if requested return used pixels in the XpmAttributes structure */
578 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
579 /* 3.2 backward compatibility code */
580 attributes
->valuemask
& XpmReturnInfos
)) {
582 attributes
->pixels
= used_pixels
;
583 attributes
->npixels
= nused_pixels
;
584 attributes
->mask_pixel
= mask_pixel_index
;
586 XpmFree(used_pixels
);
588 /* if requested return alloc'ed pixels in the XpmAttributes structure */
589 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
590 attributes
->alloc_pixels
= alloc_pixels
;
591 attributes
->nalloc_pixels
= nalloc_pixels
;
593 XpmFree(alloc_pixels
);
595 /* return created images */
597 *image_return
= ximage
;
598 if (shapeimage_return
)
599 *shapeimage_return
= shapeimage
;
601 return (ErrorStatus
);
603 /* exit point in case of error, free only locally allocated variables */
606 XDestroyImage(ximage
);
608 XDestroyImage(shapeimage
);
610 XpmFree(image_pixels
);
612 XpmFree(mask_pixels
);
614 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
616 XpmFree(alloc_pixels
);
618 XpmFree(used_pixels
);
620 return (ErrorStatus
);
625 * Create an XImage with its data
628 CreateXImage(display
, visual
, depth
, format
, width
, height
, image_return
)
635 XImage
**image_return
;
639 /* first get bitmap_pad */
647 /* then create the XImage with data = NULL and bytes_per_line = 0 */
648 *image_return
= XCreateImage(display
, visual
, depth
, format
, 0, 0,
649 width
, height
, bitmap_pad
, 0);
651 return (XpmNoMemory
);
653 /* XCreateImage has done it all */
659 PlatformPutImagePixels(dc
, image
, width
, height
, pixelindex
, pixels
)
664 unsigned int *pixelindex
;
669 unsigned int *data
= pixelindex
;
673 obm
= SelectObject(*dc
, image
->bitmap
);
674 for (y
= 0; y
< height
; y
++) {
675 for (x
= 0; x
< width
; x
++) {
676 SetPixel(*dc
, x
, y
, pixels
[*(data
++)]); // data is [x+y*width]
679 SelectObject(*dc
, obm
);
680 #elif defined(macintosh) || defined(__APPLE__)
682 GDHandle origDevice
;
684 unsigned int *data
= pixelindex
;
687 GetGWorld( &origPort
, &origDevice
) ;
688 SetGWorld( image
->gworldptr
, NULL
) ;
690 for (y
= 0; y
< height
; y
++)
692 for (x
= 0; x
< width
; x
++)
694 SetCPixel( x
, y
, &pixels
[*(data
++)]); // data is [x+y*width]
697 SetGWorld( origPort
, origDevice
) ;
702 * This function parses an Xpm file or data and directly create an XImage
705 xpmParseDataAndCreate(display
, data
, image_return
, shapeimage_return
,
706 image
, info
, attributes
)
709 XImage
**image_return
;
710 XImage
**shapeimage_return
;
713 XpmAttributes
*attributes
;
715 /* variables stored in the XpmAttributes structure */
720 XpmFreeColorsFunc freeColors
;
723 /* variables to return */
724 XImage
*ximage
= NULL
;
725 XImage
*shapeimage
= NULL
;
726 unsigned int mask_pixel_index
= XpmUndefPixel
;
728 /* calculation variables */
729 Pixel
*image_pixels
= NULL
;
730 Pixel
*mask_pixels
= NULL
;
731 Pixel
*alloc_pixels
= NULL
;
732 Pixel
*used_pixels
= NULL
;
733 unsigned int nalloc_pixels
= 0;
734 unsigned int nused_pixels
= 0;
735 unsigned int width
, height
, ncolors
, cpp
;
736 unsigned int x_hotspot
, y_hotspot
, hotspot
= 0, extensions
= 0;
737 XpmColor
*colorTable
= NULL
;
738 char *hints_cmt
= NULL
;
739 char *colors_cmt
= NULL
;
740 char *pixels_cmt
= NULL
;
744 xpmHashTable hashtable
;
747 /* initialize return values */
749 *image_return
= NULL
;
750 if (shapeimage_return
)
751 *shapeimage_return
= NULL
;
754 /* retrieve information from the XpmAttributes */
755 if (attributes
&& (attributes
->valuemask
& XpmVisual
))
756 visual
= attributes
->visual
;
758 visual
= XDefaultVisual(display
, XDefaultScreen(display
));
760 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
761 colormap
= attributes
->colormap
;
763 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
765 if (attributes
&& (attributes
->valuemask
& XpmDepth
))
766 depth
= attributes
->depth
;
768 depth
= XDefaultDepth(display
, XDefaultScreen(display
));
770 if (attributes
&& (attributes
->valuemask
& XpmBitmapFormat
))
771 bitmap_format
= attributes
->bitmap_format
;
773 bitmap_format
= ZPixmap
;
775 if (attributes
&& (attributes
->valuemask
& XpmFreeColors
))
776 freeColors
= attributes
->free_colors
;
778 freeColors
= FreeColors
;
779 if (attributes
&& (attributes
->valuemask
& XpmColorClosure
))
780 closure
= attributes
->color_closure
;
784 cmts
= info
&& (info
->valuemask
& XpmReturnComments
);
789 ErrorStatus
= xpmParseHeader(data
);
790 if (ErrorStatus
!= XpmSuccess
)
791 return (ErrorStatus
);
796 ErrorStatus
= xpmParseValues(data
, &width
, &height
, &ncolors
, &cpp
,
797 &x_hotspot
, &y_hotspot
, &hotspot
,
799 if (ErrorStatus
!= XpmSuccess
)
800 return (ErrorStatus
);
803 * store the hints comment line
806 xpmGetCmt(data
, &hints_cmt
);
812 ErrorStatus
= xpmHashTableInit(&hashtable
);
813 if (ErrorStatus
!= XpmSuccess
)
814 return (ErrorStatus
);
820 ErrorStatus
= xpmParseColors(data
, ncolors
, cpp
, &colorTable
, &hashtable
);
821 if (ErrorStatus
!= XpmSuccess
)
825 * store the colors comment line
828 xpmGetCmt(data
, &colors_cmt
);
830 /* malloc pixels index tables */
831 image_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
835 mask_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
839 /* maximum of allocated pixels will be the number of colors */
840 alloc_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
844 /* maximum of allocated pixels will be the number of colors */
845 used_pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * ncolors
);
849 /* get pixel colors, store them in index tables */
850 ErrorStatus
= CreateColors(display
, attributes
, colorTable
, ncolors
,
851 image_pixels
, mask_pixels
, &mask_pixel_index
,
852 alloc_pixels
, &nalloc_pixels
, used_pixels
,
855 if (ErrorStatus
!= XpmSuccess
856 && (ErrorStatus
< 0 || (attributes
857 && (attributes
->valuemask
& XpmExactColors
)
858 && attributes
->exactColors
)))
861 /* now create the ximage */
863 ErrorStatus
= CreateXImage(display
, visual
, depth
,
864 (depth
== 1 ? bitmap_format
: ZPixmap
),
865 width
, height
, &ximage
);
866 if (ErrorStatus
!= XpmSuccess
)
871 /* create the shape mask image */
872 if (mask_pixel_index
!= XpmUndefPixel
&& shapeimage_return
) {
873 ErrorStatus
= CreateXImage(display
, visual
, 1, bitmap_format
,
874 width
, height
, &shapeimage
);
875 if (ErrorStatus
!= XpmSuccess
)
881 * read pixels and put them in the XImage
883 ErrorStatus
= ParseAndPutPixels(
885 data
, width
, height
, ncolors
, cpp
,
886 colorTable
, &hashtable
,
887 ximage
, image_pixels
,
888 shapeimage
, mask_pixels
);
889 XpmFree(image_pixels
);
891 XpmFree(mask_pixels
);
897 if (ErrorStatus
!= XpmSuccess
)
899 else if (USE_HASHTABLE
)
900 xpmHashTableFree(&hashtable
);
903 * store the pixels comment line
906 xpmGetCmt(data
, &pixels_cmt
);
911 if (info
&& (info
->valuemask
& XpmReturnExtensions
))
913 ErrorStatus
= xpmParseExtensions(data
, &info
->extensions
,
915 if (ErrorStatus
!= XpmSuccess
)
918 info
->extensions
= NULL
;
919 info
->nextensions
= 0;
923 * store found informations in the XpmImage structure
925 image
->width
= width
;
926 image
->height
= height
;
928 image
->ncolors
= ncolors
;
929 image
->colorTable
= colorTable
;
934 info
->hints_cmt
= hints_cmt
;
935 info
->colors_cmt
= colors_cmt
;
936 info
->pixels_cmt
= pixels_cmt
;
939 info
->x_hotspot
= x_hotspot
;
940 info
->y_hotspot
= y_hotspot
;
941 info
->valuemask
|= XpmHotspot
;
944 /* if requested return used pixels in the XpmAttributes structure */
945 if (attributes
&& (attributes
->valuemask
& XpmReturnPixels
||
946 /* 3.2 backward compatibility code */
947 attributes
->valuemask
& XpmReturnInfos
)) {
949 attributes
->pixels
= used_pixels
;
950 attributes
->npixels
= nused_pixels
;
951 attributes
->mask_pixel
= mask_pixel_index
;
953 XpmFree(used_pixels
);
955 /* if requested return alloc'ed pixels in the XpmAttributes structure */
956 if (attributes
&& (attributes
->valuemask
& XpmReturnAllocPixels
)) {
957 attributes
->alloc_pixels
= alloc_pixels
;
958 attributes
->nalloc_pixels
= nalloc_pixels
;
960 XpmFree(alloc_pixels
);
962 /* return created images */
964 *image_return
= ximage
;
965 if (shapeimage_return
)
966 *shapeimage_return
= shapeimage
;
970 /* exit point in case of error, free only locally allocated variables */
973 xpmHashTableFree(&hashtable
);
975 xpmFreeColorTable(colorTable
, ncolors
);
983 XDestroyImage(ximage
);
985 XDestroyImage(shapeimage
);
987 XpmFree(image_pixels
);
989 XpmFree(mask_pixels
);
991 (*freeColors
)(display
, colormap
, alloc_pixels
, nalloc_pixels
, NULL
);
993 XpmFree(alloc_pixels
);
995 XpmFree(used_pixels
);
997 return (ErrorStatus
);
1003 data
, width
, height
, ncolors
, cpp
, colorTable
, hashtable
,
1004 image
, image_pixels
, shapeimage
, shape_pixels
)
1008 unsigned int height
;
1009 unsigned int ncolors
;
1011 XpmColor
*colorTable
;
1012 xpmHashTable
*hashtable
;
1014 Pixel
*image_pixels
;
1016 Pixel
*shape_pixels
;
1018 unsigned int a
, x
, y
;
1022 case (1): /* Optimize for single character
1025 unsigned short colidx
[256];
1032 shapedc
= CreateCompatibleDC(*dc
);
1033 sobm
= SelectObject(shapedc
, shapeimage
->bitmap
);
1037 obm
= SelectObject(*dc
, image
->bitmap
);
1039 #elif defined(macintosh) || defined(__APPLE__)
1041 GDHandle origDevice
;
1043 GetGWorld( &origPort
, &origDevice
) ;
1045 SetGWorld( image
->gworldptr
, NULL
) ;
1049 bzero((char *)colidx
, 256 * sizeof(short));
1050 for (a
= 0; a
< ncolors
; a
++)
1051 colidx
[(unsigned char)colorTable
[a
].string
[0]] = a
+ 1;
1053 for (y
= 0; y
< height
; y
++)
1055 xpmNextString(data
);
1056 for (x
= 0; x
< width
; x
++)
1058 int c
= xpmGetC(data
);
1060 if (c
> 0 && c
< 256 && colidx
[c
] != 0)
1063 SetPixel(*dc
, x
, y
, image_pixels
[colidx
[c
] - 1]);
1066 SetPixel(shapedc
, x
, y
, shape_pixels
[colidx
[c
] - 1]);
1068 #elif defined(macintosh) || defined(__APPLE__)
1069 SetCPixel( x
, y
, &image_pixels
[colidx
[c
] - 1]);
1072 SetGWorld( shapeimage
->gworldptr
, NULL
) ;
1073 SetCPixel( x
, y
, &shape_pixels
[colidx
[c
] - 1]);
1074 SetGWorld( image
->gworldptr
, NULL
) ;
1079 return (XpmFileInvalid
);
1085 SelectObject(shapedc
, sobm
);
1088 SelectObject(*dc
, obm
);
1089 #elif defined(macintosh) || defined(__APPLE__)
1090 SetGWorld( origPort
, origDevice
) ;
1095 case (2): /* Optimize for double character
1099 /* free all allocated pointers at all exits */
1100 #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
1101 if (cidx[f]) XpmFree(cidx[f]);}
1103 /* array of pointers malloced by need */
1104 unsigned short *cidx
[256];
1106 #if defined(macintosh) || defined(__APPLE__)
1108 GDHandle origDevice
;
1109 GetGWorld( &origPort
, &origDevice
) ;
1110 SetGWorld( image
->gworldptr
, NULL
) ;
1112 bzero((char *)cidx
, 256 * sizeof(unsigned short *)); /* init */
1113 for (a
= 0; a
< ncolors
; a
++) {
1114 char1
= colorTable
[a
].string
[0];
1115 if (cidx
[char1
] == NULL
) { /* get new memory */
1116 cidx
[char1
] = (unsigned short *)
1117 XpmCalloc(256, sizeof(unsigned short));
1118 if (cidx
[char1
] == NULL
) { /* new block failed */
1119 #if defined(macintosh) || defined(__APPLE__)
1120 SetGWorld( origPort
, origDevice
) ;
1123 return (XpmNoMemory
);
1126 cidx
[char1
][(unsigned char)colorTable
[a
].string
[1]] = a
+ 1;
1129 for (y
= 0; y
< height
; y
++) {
1130 xpmNextString(data
);
1131 for (x
= 0; x
< width
; x
++)
1133 int cc1
= xpmGetC(data
);
1134 if (cc1
> 0 && cc1
< 256) {
1135 int cc2
= xpmGetC(data
);
1136 if (cc2
> 0 && cc2
< 256 &&
1137 cidx
[cc1
] && cidx
[cc1
][cc2
] != 0) {
1140 SelectObject(*dc
, image
->bitmap
);
1141 SetPixel(*dc
, x
, y
, image_pixels
[cidx
[cc1
][cc2
] - 1]);
1144 SelectObject(*dc
, shapeimage
->bitmap
);
1146 shape_pixels
[cidx
[cc1
][cc2
] - 1]);
1148 #elif defined(macintosh) || defined(__APPLE__)
1149 SetCPixel( x
, y
, &image_pixels
[cidx
[cc1
][cc2
] - 1]);
1153 #if defined(macintosh) || defined(__APPLE__)
1154 SetGWorld( origPort
, origDevice
) ;
1157 return (XpmFileInvalid
);
1160 #if defined(macintosh) || defined(__APPLE__)
1161 SetGWorld( origPort
, origDevice
) ;
1164 return (XpmFileInvalid
);
1168 #if defined(macintosh) || defined(__APPLE__)
1169 SetGWorld( origPort
, origDevice
) ;
1175 default: /* Non-optimized case of long color
1180 #if defined(macintosh) || defined(__APPLE__)
1182 GDHandle origDevice
;
1183 GetGWorld( &origPort
, &origDevice
) ;
1184 SetGWorld( image
->gworldptr
, NULL
) ;
1188 if (USE_HASHTABLE
) {
1191 for (y
= 0; y
< height
; y
++) {
1192 xpmNextString(data
);
1193 for (x
= 0; x
< width
; x
++) {
1194 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
1196 slot
= xpmHashSlot(hashtable
, buf
);
1197 if (!*slot
) /* no color matches */
1199 #if defined(macintosh) || defined(__APPLE__)
1200 SetGWorld( origPort
, origDevice
) ;
1202 return (XpmFileInvalid
);
1206 SelectObject(*dc
, image
->bitmap
);
1208 image_pixels
[HashColorIndex(slot
)]);
1211 SelectObject(*dc
, shapeimage
->bitmap
);
1213 shape_pixels
[HashColorIndex(slot
)]);
1215 #elif defined(macintosh) || defined(__APPLE__)
1216 SetCPixel( x
, y
, &image_pixels
[HashColorIndex(slot
)]);
1221 for (y
= 0; y
< height
; y
++) {
1222 xpmNextString(data
);
1223 for (x
= 0; x
< width
; x
++) {
1224 for (a
= 0, s
= buf
; a
< cpp
; a
++, s
++)
1226 for (a
= 0; a
< ncolors
; a
++)
1227 if (!strcmp(colorTable
[a
].string
, buf
))
1229 if (a
== ncolors
) /* no color matches */
1231 #if defined(macintosh) || defined(__APPLE__)
1232 SetGWorld( origPort
, origDevice
) ;
1234 return (XpmFileInvalid
);
1238 SelectObject(*dc
, image
->bitmap
);
1239 SetPixel(*dc
, x
, y
, image_pixels
[a
]);
1241 SelectObject(*dc
, shapeimage
->bitmap
);
1242 SetPixel(*dc
, x
, y
, shape_pixels
[a
]);
1244 #elif defined(macintosh) || defined(__APPLE__)
1245 SetCPixel( x
, y
, &image_pixels
[a
]); // data is [x+y*width]
1250 #if defined(macintosh) || defined(__APPLE__)
1251 SetGWorld( origPort
, origDevice
) ;
1257 return (XpmSuccess
);