Bug Summary

File:create.c
Location:line 291, column 18
Description:Access to field 'red_closeness' results in a dereference of a null pointer (loaded from variable 'attributes')

Annotated Source Code

1/*
2 * Copyright (C) 1989-95 GROUPE BULL
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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.
20 *
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.
24 */
25
26/*****************************************************************************\
27* create.c: *
28* *
29* XPM library *
30* Create an X image and possibly its related shape mask *
31* from the given XpmImage. *
32* *
33* Developed by Arnaud Le Hors *
34\*****************************************************************************/
35
36/*
37 * The code related to FOR_MSW has been added by
38 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
39 */
40
41/*
42 * The code related to AMIGA has been added by
43 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
44 */
45
46/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
47
48#ifdef HAVE_CONFIG_H1
49#include <config.h>
50#endif
51#include "XpmI.h"
52#include <ctype.h>
53
54LFUNC(xpmVisualType, int, (Visual *visual))static int xpmVisualType (Visual *visual);
55
56LFUNC(AllocColor, int, (Display *display, Colormap colormap,static int AllocColor (Display *display, Colormap colormap, char
*colorname, XColor *xcolor, void *closure)
57 char *colorname, XColor *xcolor, void *closure))static int AllocColor (Display *display, Colormap colormap, char
*colorname, XColor *xcolor, void *closure)
;
58LFUNC(FreeColors, int, (Display *display, Colormap colormap,static int FreeColors (Display *display, Colormap colormap, Pixel
*pixels, int n, void *closure)
59 Pixel *pixels, int n, void *closure))static int FreeColors (Display *display, Colormap colormap, Pixel
*pixels, int n, void *closure)
;
60
61#ifndef FOR_MSW
62LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
63 Visual *visual, XColor *col,static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
64 Pixel *image_pixel, Pixel *mask_pixel,static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
65 Pixel *alloc_pixels, unsigned int *nalloc_pixels,static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
66 XpmAttributes *attributes, XColor *cols, int ncols,static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
67 XpmAllocColorFunc allocColor, void *closure))static int SetCloseColor (Display *display, Colormap colormap
, Visual *visual, XColor *col, Pixel *image_pixel, Pixel *mask_pixel
, Pixel *alloc_pixels, unsigned int *nalloc_pixels, XpmAttributes
*attributes, XColor *cols, int ncols, XpmAllocColorFunc allocColor
, void *closure)
;
68#else
69/* let the window system take care of close colors */
70#endif
71
72LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
73 char *colorname, unsigned int color_index,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
74 Pixel *image_pixel, Pixel *mask_pixel,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
75 unsigned int *mask_pixel_index,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
76 Pixel *alloc_pixels, unsigned int *nalloc_pixels,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
77 Pixel *used_pixels, unsigned int *nused_pixels,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
78 XpmAttributes *attributes, XColor *cols, int ncols,static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
79 XpmAllocColorFunc allocColor, void *closure))static int SetColor (Display *display, Colormap colormap, Visual
*visual, char *colorname, unsigned int color_index, Pixel *image_pixel
, Pixel *mask_pixel, unsigned int *mask_pixel_index, Pixel *alloc_pixels
, unsigned int *nalloc_pixels, Pixel *used_pixels, unsigned int
*nused_pixels, XpmAttributes *attributes, XColor *cols, int ncols
, XpmAllocColorFunc allocColor, void *closure)
;
80
81LFUNC(CreateXImage, int, (Display *display, Visual *visual,static int CreateXImage (Display *display, Visual *visual, unsigned
int depth, int format, unsigned int width, unsigned int height
, XImage **image_return)
82 unsigned int depth, int format, unsigned int width,static int CreateXImage (Display *display, Visual *visual, unsigned
int depth, int format, unsigned int width, unsigned int height
, XImage **image_return)
83 unsigned int height, XImage **image_return))static int CreateXImage (Display *display, Visual *visual, unsigned
int depth, int format, unsigned int width, unsigned int height
, XImage **image_return)
;
84
85LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
86 XpmColor *colors, unsigned int ncolors,static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
87 Pixel *image_pixels, Pixel *mask_pixels,static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
88 unsigned int *mask_pixel_index,static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
89 Pixel *alloc_pixels, unsigned int *nalloc_pixels,static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
90 Pixel *used_pixels, unsigned int *nused_pixels))static int CreateColors (Display *display, XpmAttributes *attributes
, XpmColor *colors, unsigned int ncolors, Pixel *image_pixels
, Pixel *mask_pixels, unsigned int *mask_pixel_index, Pixel *
alloc_pixels, unsigned int *nalloc_pixels, Pixel *used_pixels
, unsigned int *nused_pixels)
;
91
92#ifndef FOR_MSW
93LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width,static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
94 unsigned int height, unsigned int ncolors,static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
95 unsigned int cpp, XpmColor *colorTable,static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
96 xpmHashTable *hashtable,static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
97 XImage *image, Pixel *image_pixels,static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
98 XImage *mask, Pixel *mask_pixels))static int ParseAndPutPixels (xpmData *data, unsigned int width
, unsigned int height, unsigned int ncolors, unsigned int cpp
, XpmColor *colorTable, xpmHashTable *hashtable, XImage *image
, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels)
;
99#else /* FOR_MSW */
100LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width,static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
101 unsigned int height, unsigned int ncolors,static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
102 unsigned int cpp, XpmColor *colorTable,static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
103 xpmHashTable *hashtable,static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
104 XImage *image, Pixel *image_pixels,static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
105 XImage *mask, Pixel *mask_pixels))static int ParseAndPutPixels (Display *dc, xpmData *data, unsigned
int width, unsigned int height, unsigned int ncolors, unsigned
int cpp, XpmColor *colorTable, xpmHashTable *hashtable, XImage
*image, Pixel *image_pixels, XImage *mask, Pixel *mask_pixels
)
;
106#endif
107
108#ifndef FOR_MSW
109# ifndef AMIGA
110/* XImage pixel routines */
111LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,static void PutImagePixels (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
112 unsigned int height, unsigned int *pixelindex,static void PutImagePixels (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
113 Pixel *pixels))static void PutImagePixels (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
114
115LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,static void PutImagePixels32 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
116 unsigned int height, unsigned int *pixelindex,static void PutImagePixels32 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
117 Pixel *pixels))static void PutImagePixels32 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
118
119LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,static void PutImagePixels16 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
120 unsigned int height, unsigned int *pixelindex,static void PutImagePixels16 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
121 Pixel *pixels))static void PutImagePixels16 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
122
123LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,static void PutImagePixels8 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
124 unsigned int height, unsigned int *pixelindex,static void PutImagePixels8 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
125 Pixel *pixels))static void PutImagePixels8 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
126
127LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,static void PutImagePixels1 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
128 unsigned int height, unsigned int *pixelindex,static void PutImagePixels1 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
129 Pixel *pixels))static void PutImagePixels1 (XImage *image, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
130
131LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel1 (XImage *ximage, int x, int y, unsigned long
pixel)
;
132LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel (XImage *ximage, int x, int y, unsigned long
pixel)
;
133#if !defined(WORD64) && !defined(LONG64)
134LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel32 (XImage *ximage, int x, int y, unsigned
long pixel)
;
135#endif
136LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel32MSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
137LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel32LSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
138LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel16MSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
139LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel16LSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
140LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel8 (XImage *ximage, int x, int y, unsigned long
pixel)
;
141LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel1MSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
142LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel))static int PutPixel1LSB (XImage *ximage, int x, int y, unsigned
long pixel)
;
143
144# else /* AMIGA */
145LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width,static void APutImagePixels (XImage *ximage, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
146 unsigned int height, unsigned int *pixelindex,static void APutImagePixels (XImage *ximage, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
147 Pixel *pixels))static void APutImagePixels (XImage *ximage, unsigned int width
, unsigned int height, unsigned int *pixelindex, Pixel *pixels
)
;
148# endif/* AMIGA */
149#else /* FOR_MSW */
150/* FOR_MSW pixel routine */
151LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,static void MSWPutImagePixels (Display *dc, XImage *image, unsigned
int width, unsigned int height, unsigned int *pixelindex, Pixel
*pixels)
152 unsigned int width, unsigned int height,static void MSWPutImagePixels (Display *dc, XImage *image, unsigned
int width, unsigned int height, unsigned int *pixelindex, Pixel
*pixels)
153 unsigned int *pixelindex, Pixel *pixels))static void MSWPutImagePixels (Display *dc, XImage *image, unsigned
int width, unsigned int height, unsigned int *pixelindex, Pixel
*pixels)
;
154#endif /* FOR_MSW */
155
156#ifdef NEED_STRCASECMP
157FUNC(xpmstrcasecmp, int, (char *s1, char *s2))extern int strcasecmp (char *s1, char *s2);
158
159/*
160 * in case strcasecmp is not provided by the system here is one
161 * which does the trick
162 */
163int
164xpmstrcasecmpstrcasecmp(
165 register char *s1,
166 register char *s2)
167{
168 register int c1, c2;
169
170 while (*s1 && *s2) {
171 c1 = tolower(*s1);
172 c2 = tolower(*s2);
173 if (c1 != c2)
174 return (c1 - c2);
175 s1++;
176 s2++;
177 }
178 return (int) (*s1 - *s2);
179}
180
181#endif
182
183/*
184 * return the default color key related to the given visual
185 */
186static int
187xpmVisualType(Visual *visual)
188{
189#ifndef FOR_MSW
190# ifndef AMIGA
191 switch (visual->class) {
192 case StaticGray0:
193 case GrayScale1:
194 switch (visual->map_entries) {
195 case 2:
196 return (XPM_MONO2);
197 case 4:
198 return (XPM_GRAY43);
199 default:
200 return (XPM_GRAY4);
201 }
202 default:
203 return (XPM_COLOR5);
204 }
205# else
206 /* set the key explicitly in the XpmAttributes to override this */
207 return (XPM_COLOR5);
208# endif
209#else
210 /* there should be a similar switch for MSW */
211 return (XPM_COLOR5);
212#endif
213}
214
215
216typedef struct {
217 int cols_index;
218 long closeness;
219} CloseColor;
220
221static int
222closeness_cmp(const void *a, const void *b)
223{
224 const CloseColor *x = (const CloseColor *) a, *y = (const CloseColor *) b;
225
226 /* cast to int as qsort requires */
227 return (int) (x->closeness - y->closeness);
228}
229
230
231/* default AllocColor function:
232 * call XParseColor if colorname is given, return negative value if failure
233 * call XAllocColor and return 0 if failure, positive otherwise
234 */
235static int
236AllocColor(
237 Display *display,
238 Colormap colormap,
239 char *colorname,
240 XColor *xcolor,
241 void *closure) /* not used */
242{
243 int status;
244 if (colorname)
245 if (!XParseColor(display, colormap, colorname, xcolor))
246 return -1;
247 status = XAllocColor(display, colormap, xcolor);
248 return status != 0 ? 1 : 0;
249}
250
251
252#ifndef FOR_MSW
253/*
254 * set a close color in case the exact one can't be set
255 * return 0 if success, 1 otherwise.
256 */
257
258static int
259SetCloseColor(
260 Display *display,
261 Colormap colormap,
262 Visual *visual,
263 XColor *col,
264 Pixel *image_pixel,
265 Pixel *mask_pixel,
266 Pixel *alloc_pixels,
267 unsigned int *nalloc_pixels,
268 XpmAttributes *attributes,
269 XColor *cols,
270 int ncols,
271 XpmAllocColorFunc allocColor,
272 void *closure)
273{
274
275 /*
276 * Allocation failed, so try close colors. To get here the visual must
277 * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
278 * What about sharing systems like QDSS?). Beware: we have to treat
279 * DirectColor differently.
280 */
281
282
283 long int red_closeness, green_closeness, blue_closeness;
284 int n;
285 Boolint alloc_color;
286
287 if (attributes && (attributes->valuemask & XpmCloseness(1L<<12)))
1
Taking false branch
288 red_closeness = green_closeness = blue_closeness =
289 attributes->closeness;
290 else {
291 red_closeness = attributes->red_closeness;
2
Access to field 'red_closeness' results in a dereference of a null pointer (loaded from variable 'attributes')
292 green_closeness = attributes->green_closeness;
293 blue_closeness = attributes->blue_closeness;
294 }
295 if (attributes && (attributes->valuemask & XpmAllocCloseColors(1L<<17)))
296 alloc_color = attributes->alloc_close_colors;
297 else
298 alloc_color = True1;
299
300 /*
301 * We sort the colormap by closeness and try to allocate the color
302 * closest to the target. If the allocation of this close color fails,
303 * which almost never happens, then one of two scenarios is possible.
304 * Either the colormap must have changed (since the last close color
305 * allocation or possibly while we were sorting the colormap), or the
306 * color is allocated as Read/Write by some other client. (Note: X
307 * _should_ allow clients to check if a particular color is Read/Write,
308 * but it doesn't! :-( ). We cannot determine which of these scenarios
309 * occurred, so we try the next closest color, and so on, until no more
310 * colors are within closeness of the target. If we knew that the
311 * colormap had changed, we could skip this sequence.
312 *
313 * If _none_ of the colors within closeness of the target can be allocated,
314 * then we can finally be pretty sure that the colormap has actually
315 * changed. In this case we try to allocate the original color (again),
316 * then try the closecolor stuff (again)...
317 *
318 * In theory it would be possible for an infinite loop to occur if another
319 * process kept changing the colormap every time we sorted it, so we set
320 * a maximum on the number of iterations. After this many tries, we use
321 * XGrabServer() to ensure that the colormap remains unchanged.
322 *
323 * This approach gives particularly bad worst case performance - as many as
324 * <MaximumIterations> colormap reads and sorts may be needed, and as
325 * many as <MaximumIterations> * <ColormapSize> attempted allocations
326 * may fail. On an 8-bit system, this means as many as 3 colormap reads,
327 * 3 sorts and 768 failed allocations per execution of this code!
328 * Luckily, my experiments show that in general use in a typical 8-bit
329 * color environment only about 1 in every 10000 allocations fails to
330 * succeed in the fastest possible time. So virtually every time what
331 * actually happens is a single sort followed by a successful allocate.
332 * The very first allocation also costs a colormap read, but no further
333 * reads are usually necessary.
334 */
335
336#define ITERATIONS2 2 /* more than one is almost never
337 * necessary */
338
339 for (n = 0; n <= ITERATIONS2; ++n) {
340 CloseColor *closenesses =
341 (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor))calloc((ncols), (sizeof(CloseColor)));
342 int i, c;
343
344 for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */
345#define COLOR_FACTOR3 3
346#define BRIGHTNESS_FACTOR1 1
347
348 closenesses[i].cols_index = i;
349 closenesses[i].closeness =
350 COLOR_FACTOR3 * (abs((long) col->red - (long) cols[i].red)
351 + abs((long) col->green - (long) cols[i].green)
352 + abs((long) col->blue - (long) cols[i].blue))
353 + BRIGHTNESS_FACTOR1 * abs(((long) col->red +
354 (long) col->green +
355 (long) col->blue)
356 - ((long) cols[i].red +
357 (long) cols[i].green +
358 (long) cols[i].blue));
359 }
360 qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
361
362 i = 0;
363 c = closenesses[i].cols_index;
364 while ((long) cols[c].red >= (long) col->red - red_closeness &&
365 (long) cols[c].red <= (long) col->red + red_closeness &&
366 (long) cols[c].green >= (long) col->green - green_closeness &&
367 (long) cols[c].green <= (long) col->green + green_closeness &&
368 (long) cols[c].blue >= (long) col->blue - blue_closeness &&
369 (long) cols[c].blue <= (long) col->blue + blue_closeness) {
370 if (alloc_color) {
371 if ((*allocColor)(display, colormap, NULL((void*)0), &cols[c], closure)){
372 if (n == ITERATIONS2)
373 XUngrabServer(display);
374 XpmFree(closenesses)free(closenesses);
375 *image_pixel = cols[c].pixel;
376 *mask_pixel = 1;
377 alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
378 return (0);
379 } else {
380 ++i;
381 if (i == ncols)
382 break;
383 c = closenesses[i].cols_index;
384 }
385 } else {
386 if (n == ITERATIONS2)
387 XUngrabServer(display);
388 XpmFree(closenesses)free(closenesses);
389 *image_pixel = cols[c].pixel;
390 *mask_pixel = 1;
391 return (0);
392 }
393 }
394
395 /* Couldn't allocate _any_ of the close colors! */
396
397 if (n == ITERATIONS2)
398 XUngrabServer(display);
399 XpmFree(closenesses)free(closenesses);
400
401 if (i == 0 || i == ncols) /* no color close enough or cannot */
402 return (1); /* alloc any color (full of r/w's) */
403
404 if ((*allocColor)(display, colormap, NULL((void*)0), col, closure)) {
405 *image_pixel = col->pixel;
406 *mask_pixel = 1;
407 alloc_pixels[(*nalloc_pixels)++] = col->pixel;
408 return (0);
409 } else { /* colormap has probably changed, so
410 * re-read... */
411 if (n == ITERATIONS2 - 1)
412 XGrabServer(display);
413
414#if 0
415 if (visual->class == DirectColor5) {
416 /* TODO */
417 } else
418#endif
419 XQueryColors(display, colormap, cols, ncols);
420 }
421 }
422 return (1);
423}
424
425#define USE_CLOSECOLORattributes && (((attributes->valuemask & (1L<<
12)) && attributes->closeness != 0) || ((attributes
->valuemask & (1L<<13)) && (attributes->
red_closeness != 0 || attributes->green_closeness != 0 || attributes
->blue_closeness != 0)))
attributes && \
426(((attributes->valuemask & XpmCloseness(1L<<12)) && attributes->closeness != 0) \
427 || ((attributes->valuemask & XpmRGBCloseness(1L<<13)) && \
428 (attributes->red_closeness != 0 \
429 || attributes->green_closeness != 0 \
430 || attributes->blue_closeness != 0)))
431
432#else
433 /* FOR_MSW part */
434 /* nothing to do here, the window system does it */
435#endif
436
437/*
438 * set the color pixel related to the given colorname,
439 * return 0 if success, 1 otherwise.
440 */
441
442static int
443SetColor(
444 Display *display,
445 Colormap colormap,
446 Visual *visual,
447 char *colorname,
448 unsigned int color_index,
449 Pixel *image_pixel,
450 Pixel *mask_pixel,
451 unsigned int *mask_pixel_index,
452 Pixel *alloc_pixels,
453 unsigned int *nalloc_pixels,
454 Pixel *used_pixels,
455 unsigned int *nused_pixels,
456 XpmAttributes *attributes,
457 XColor *cols,
458 int ncols,
459 XpmAllocColorFunc allocColor,
460 void *closure)
461{
462 XColor xcolor;
463 int status;
464
465 if (xpmstrcasecmpstrcasecmp(colorname, TRANSPARENT_COLOR"None")) {
466 status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
467 if (status < 0) /* parse color failed */
468 return (1);
469
470 if (status == 0) {
471#ifndef FOR_MSW
472 if (USE_CLOSECOLORattributes && (((attributes->valuemask & (1L<<
12)) && attributes->closeness != 0) || ((attributes
->valuemask & (1L<<13)) && (attributes->
red_closeness != 0 || attributes->green_closeness != 0 || attributes
->blue_closeness != 0)))
)
473 return (SetCloseColor(display, colormap, visual, &xcolor,
474 image_pixel, mask_pixel,
475 alloc_pixels, nalloc_pixels,
476 attributes, cols, ncols,
477 allocColor, closure));
478 else
479#endif /* ndef FOR_MSW */
480 return (1);
481 } else
482 alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
483 *image_pixel = xcolor.pixel;
484#ifndef FOR_MSW
485 *mask_pixel = 1;
486#else
487 *mask_pixel = RGB(0,0,0);
488#endif
489 used_pixels[(*nused_pixels)++] = xcolor.pixel;
490 } else {
491 *image_pixel = 0;
492#ifndef FOR_MSW
493 *mask_pixel = 0;
494#else
495 *mask_pixel = RGB(255,255,255);
496#endif
497 /* store the color table index */
498 *mask_pixel_index = color_index;
499 }
500 return (0);
501}
502
503
504static int
505CreateColors(
506 Display *display,
507 XpmAttributes *attributes,
508 XpmColor *colors,
509 unsigned int ncolors,
510 Pixel *image_pixels,
511 Pixel *mask_pixels,
512 unsigned int *mask_pixel_index,
513 Pixel *alloc_pixels,
514 unsigned int *nalloc_pixels,
515 Pixel *used_pixels,
516 unsigned int *nused_pixels)
517{
518 /* variables stored in the XpmAttributes structure */
519 Visual *visual;
520 Colormap colormap;
521 XpmColorSymbol *colorsymbols = NULL((void*)0);
522 unsigned int numsymbols;
523 XpmAllocColorFunc allocColor;
524 void *closure;
525
526 char *colorname;
527 unsigned int color, key;
528 Boolint pixel_defined;
529 XpmColorSymbol *symbol = NULL((void*)0);
530 char **defaults;
531 int ErrorStatus = XpmSuccess0;
532 char *s;
533 int default_index;
534
535 XColor *cols = NULL((void*)0);
536 unsigned int ncols = 0;
537
538 /*
539 * retrieve information from the XpmAttributes
540 */
541 if (attributes && attributes->valuemask & XpmColorSymbols(1L<<6)) {
542 colorsymbols = attributes->colorsymbols;
543 numsymbols = attributes->numsymbols;
544 } else
545 numsymbols = 0;
546
547 if (attributes && attributes->valuemask & XpmVisual(1L<<0))
548 visual = attributes->visual;
549 else
550 visual = XDefaultVisual(display, XDefaultScreen(display));
551
552 if (attributes && (attributes->valuemask & XpmColormap(1L<<1)))
553 colormap = attributes->colormap;
554 else
555 colormap = XDefaultColormap(display, XDefaultScreen(display));
556
557 if (attributes && (attributes->valuemask & XpmColorKey(1L<<14)))
558 key = attributes->color_key;
559 else
560 key = xpmVisualType(visual);
561
562 if (attributes && (attributes->valuemask & XpmAllocColor(1L<<19)))
563 allocColor = attributes->alloc_color;
564 else
565 allocColor = AllocColor;
566 if (attributes && (attributes->valuemask & XpmColorClosure(1L<<21)))
567 closure = attributes->color_closure;
568 else
569 closure = NULL((void*)0);
570
571#ifndef FOR_MSW
572 if (USE_CLOSECOLORattributes && (((attributes->valuemask & (1L<<
12)) && attributes->closeness != 0) || ((attributes
->valuemask & (1L<<13)) && (attributes->
red_closeness != 0 || attributes->green_closeness != 0 || attributes
->blue_closeness != 0)))
) {
573 /* originally from SetCloseColor */
574#if 0
575 if (visual->class == DirectColor5) {
576
577 /*
578 * TODO: Implement close colors for DirectColor visuals. This is
579 * difficult situation. Chances are that we will never get here,
580 * because any machine that supports DirectColor will probably
581 * also support TrueColor (and probably PseudoColor). Also,
582 * DirectColor colormaps can be very large, so looking for close
583 * colors may be too slow.
584 */
585 } else {
586#endif
587 unsigned int i;
588
589#ifndef AMIGA
590 ncols = visual->map_entries;
591#else
592 ncols = colormap->Count;
593#endif
594 cols = (XColor *) XpmCalloc(ncols, sizeof(XColor))calloc((ncols), (sizeof(XColor)));
595 for (i = 0; i < ncols; ++i)
596 cols[i].pixel = i;
597 XQueryColors(display, colormap, cols, ncols);
598#if 0
599 }
600#endif
601 }
602#endif /* ndef FOR_MSW */
603
604 switch (key) {
605 case XPM_MONO2:
606 default_index = 2;
607 break;
608 case XPM_GRAY43:
609 default_index = 3;
610 break;
611 case XPM_GRAY4:
612 default_index = 4;
613 break;
614 case XPM_COLOR5:
615 default:
616 default_index = 5;
617 break;
618 }
619
620 for (color = 0; color < ncolors; color++, colors++,
621 image_pixels++, mask_pixels++) {
622 colorname = NULL((void*)0);
623 pixel_defined = False0;
624 defaults = (char **) colors;
625
626 /*
627 * look for a defined symbol
628 */
629 if (numsymbols) {
630
631 unsigned int n;
632
633 s = defaults[1];
634 for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
635 if (symbol->name && s && !strcmp(symbol->name, s))
636 /* override name */
637 break;
638 if (!symbol->name && symbol->value) { /* override value */
639 int def_index = default_index;
640
641 while (defaults[def_index] == NULL((void*)0)) /* find defined
642 * colorname */
643 --def_index;
644 if (def_index < 2) {/* nothing towards mono, so try
645 * towards color */
646 def_index = default_index + 1;
647 while (def_index <= 5 && defaults[def_index] == NULL((void*)0))
648 ++def_index;
649 }
650 if (def_index >= 2 && defaults[def_index] != NULL((void*)0) &&
651 !xpmstrcasecmpstrcasecmp(symbol->value, defaults[def_index]))
652 break;
653 }
654 }
655 if (n != numsymbols) {
656 if (symbol->name && symbol->value)
657 colorname = symbol->value;
658 else
659 pixel_defined = True1;
660 }
661 }
662 if (!pixel_defined) { /* pixel not given as symbol value */
663
664 unsigned int k;
665
666 if (colorname) { /* colorname given as symbol value */
667 if (!SetColor(display, colormap, visual, colorname, color,
668 image_pixels, mask_pixels, mask_pixel_index,
669 alloc_pixels, nalloc_pixels, used_pixels,
670 nused_pixels, attributes, cols, ncols,
671 allocColor, closure))
672 pixel_defined = True1;
673 else
674 ErrorStatus = XpmColorError1;
675 }
676 k = key;
677 while (!pixel_defined && k > 1) {
678 if (defaults[k]) {
679 if (!SetColor(display, colormap, visual, defaults[k],
680 color, image_pixels, mask_pixels,
681 mask_pixel_index, alloc_pixels,
682 nalloc_pixels, used_pixels, nused_pixels,
683 attributes, cols, ncols,
684 allocColor, closure)) {
685 pixel_defined = True1;
686 break;
687 } else
688 ErrorStatus = XpmColorError1;
689 }
690 k--;
691 }
692 k = key + 1;
693 while (!pixel_defined && k < NKEYS5 + 1) {
694 if (defaults[k]) {
695 if (!SetColor(display, colormap, visual, defaults[k],
696 color, image_pixels, mask_pixels,
697 mask_pixel_index, alloc_pixels,
698 nalloc_pixels, used_pixels, nused_pixels,
699 attributes, cols, ncols,
700 allocColor, closure)) {
701 pixel_defined = True1;
702 break;
703 } else
704 ErrorStatus = XpmColorError1;
705 }
706 k++;
707 }
708 if (!pixel_defined) {
709 if (cols)
710 XpmFree(cols)free(cols);
711 return (XpmColorFailed-4);
712 }
713 } else {
714 /* simply use the given pixel */
715 *image_pixels = symbol->pixel;
716 /* the following makes the mask to be built even if none
717 is given a particular pixel */
718 if (symbol->value
719 && !xpmstrcasecmpstrcasecmp(symbol->value, TRANSPARENT_COLOR"None")) {
720 *mask_pixels = 0;
721 *mask_pixel_index = color;
722 } else
723 *mask_pixels = 1;
724 used_pixels[(*nused_pixels)++] = *image_pixels;
725 }
726 }
727 if (cols)
728 XpmFree(cols)free(cols);
729 return (ErrorStatus);
730}
731
732
733/* default FreeColors function, simply call XFreeColors */
734static int
735FreeColors(
736 Display *display,
737 Colormap colormap,
738 Pixel *pixels,
739 int n,
740 void *closure) /* not used */
741{
742 return XFreeColors(display, colormap, pixels, n, 0);
743}
744
745
746/* function call in case of error */
747
748#undef RETURN
749#define RETURN(status)do { ErrorStatus = status; goto error; } while(0) \
750do \
751{ \
752 ErrorStatus = status; \
753 goto error; \
754} while(0)
755
756int
757XpmCreateImageFromXpmImage(
758 Display *display,
759 XpmImage *image,
760 XImage **image_return,
761 XImage **shapeimage_return,
762 XpmAttributes *attributes)
763{
764 /* variables stored in the XpmAttributes structure */
765 Visual *visual;
766 Colormap colormap;
767 unsigned int depth;
768 int bitmap_format;
769 XpmFreeColorsFunc freeColors;
770
771 /* variables to return */
772 XImage *ximage = NULL((void*)0);
773 XImage *shapeimage = NULL((void*)0);
774 unsigned int mask_pixel_index = XpmUndefPixel0x80000000;
775 int ErrorStatus;
776
777 /* calculation variables */
778 Pixel *image_pixels = NULL((void*)0);
779 Pixel *mask_pixels = NULL((void*)0);
780 Pixel *alloc_pixels = NULL((void*)0);
781 Pixel *used_pixels = NULL((void*)0);
782 unsigned int nalloc_pixels = 0;
783 unsigned int nused_pixels = 0;
784
785 /* initialize return values */
786 if (image_return)
787 *image_return = NULL((void*)0);
788 if (shapeimage_return)
789 *shapeimage_return = NULL((void*)0);
790
791 /* retrieve information from the XpmAttributes */
792 if (attributes && (attributes->valuemask & XpmVisual(1L<<0)))
793 visual = attributes->visual;
794 else
795 visual = XDefaultVisual(display, XDefaultScreen(display));
796
797 if (attributes && (attributes->valuemask & XpmColormap(1L<<1)))
798 colormap = attributes->colormap;
799 else
800 colormap = XDefaultColormap(display, XDefaultScreen(display));
801
802 if (attributes && (attributes->valuemask & XpmDepth(1L<<2)))
803 depth = attributes->depth;
804 else
805 depth = XDefaultDepth(display, XDefaultScreen(display));
806
807 if (attributes && (attributes->valuemask & XpmBitmapFormat(1L<<18)))
808 bitmap_format = attributes->bitmap_format;
809 else
810 bitmap_format = ZPixmap2;
811
812 if (attributes && (attributes->valuemask & XpmFreeColors(1L<<20)))
813 freeColors = attributes->free_colors;
814 else
815 freeColors = FreeColors;
816
817 ErrorStatus = XpmSuccess0;
818
819 if (image->ncolors >= UINT_MAX(2147483647 *2U +1U) / sizeof(Pixel))
820 return (XpmNoMemory-3);
821
822 /* malloc pixels index tables */
823 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors)malloc((sizeof(Pixel) * image->ncolors));
824 if (!image_pixels)
825 return (XpmNoMemory-3);
826
827 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors)malloc((sizeof(Pixel) * image->ncolors));
828 if (!mask_pixels)
829 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
830
831 /* maximum of allocated pixels will be the number of colors */
832 alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors)malloc((sizeof(Pixel) * image->ncolors));
833 if (!alloc_pixels)
834 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
835
836 /* maximum of allocated pixels will be the number of colors */
837 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors)malloc((sizeof(Pixel) * image->ncolors));
838 if (!used_pixels)
839 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
840
841 /* get pixel colors, store them in index tables */
842 ErrorStatus = CreateColors(display, attributes, image->colorTable,
843 image->ncolors, image_pixels, mask_pixels,
844 &mask_pixel_index, alloc_pixels, &nalloc_pixels,
845 used_pixels, &nused_pixels);
846
847 if (ErrorStatus != XpmSuccess0
848 && (ErrorStatus < 0 || (attributes
849 && (attributes->valuemask & XpmExactColors(1L<<11))
850 && attributes->exactColors)))
851 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
852
853 /* create the ximage */
854 if (image_return) {
855 ErrorStatus = CreateXImage(display, visual, depth,
856 (depth == 1 ? bitmap_format : ZPixmap2),
857 image->width, image->height, &ximage);
858 if (ErrorStatus != XpmSuccess0)
859 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
860
861#ifndef FOR_MSW
862# ifndef AMIGA
863
864 /*
865 * set the ximage data using optimized functions for ZPixmap
866 */
867
868 if (ximage->bits_per_pixel == 8)
869 PutImagePixels8(ximage, image->width, image->height,
870 image->data, image_pixels);
871 else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
872 (ximage->byte_order == ximage->bitmap_bit_order))
873 PutImagePixels1(ximage, image->width, image->height,
874 image->data, image_pixels);
875 else if (ximage->bits_per_pixel == 16)
876 PutImagePixels16(ximage, image->width, image->height,
877 image->data, image_pixels);
878 else if (ximage->bits_per_pixel == 32)
879 PutImagePixels32(ximage, image->width, image->height,
880 image->data, image_pixels);
881 else
882 PutImagePixels(ximage, image->width, image->height,
883 image->data, image_pixels);
884# else /* AMIGA */
885 APutImagePixels(ximage, image->width, image->height,
886 image->data, image_pixels);
887# endif
888#else /* FOR_MSW */
889 MSWPutImagePixels(display, ximage, image->width, image->height,
890 image->data, image_pixels);
891#endif
892 }
893 /* create the shape mask image */
894 if (mask_pixel_index != XpmUndefPixel0x80000000 && shapeimage_return) {
895 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
896 image->width, image->height, &shapeimage);
897 if (ErrorStatus != XpmSuccess0)
898 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
899
900#ifndef FOR_MSW
901# ifndef AMIGA
902 PutImagePixels1(shapeimage, image->width, image->height,
903 image->data, mask_pixels);
904# else /* AMIGA */
905 APutImagePixels(shapeimage, image->width, image->height,
906 image->data, mask_pixels);
907# endif
908#else /* FOR_MSW */
909 MSWPutImagePixels(display, shapeimage, image->width, image->height,
910 image->data, mask_pixels);
911#endif
912
913 }
914 XpmFree(image_pixels)free(image_pixels);
915 XpmFree(mask_pixels)free(mask_pixels);
916
917 /* if requested return used pixels in the XpmAttributes structure */
918 if (attributes && (attributes->valuemask & XpmReturnPixels(1L<<9) ||
919/* 3.2 backward compatibility code */
920 attributes->valuemask & XpmReturnInfos(1L<<8))) {
921/* end 3.2 bc */
922 attributes->pixels = used_pixels;
923 attributes->npixels = nused_pixels;
924 attributes->mask_pixel = mask_pixel_index;
925 } else
926 XpmFree(used_pixels)free(used_pixels);
927
928 /* if requested return alloc'ed pixels in the XpmAttributes structure */
929 if (attributes && (attributes->valuemask & XpmReturnAllocPixels(1L<<16))) {
930 attributes->alloc_pixels = alloc_pixels;
931 attributes->nalloc_pixels = nalloc_pixels;
932 } else
933 XpmFree(alloc_pixels)free(alloc_pixels);
934
935 /* return created images */
936 if (image_return)
937 *image_return = ximage;
938 if (shapeimage_return)
939 *shapeimage_return = shapeimage;
940
941 return (ErrorStatus);
942
943/* exit point in case of error, free only locally allocated variables */
944error:
945 if (ximage)
946 XDestroyImage(ximage)((*((ximage)->f.destroy_image))((ximage)));
947 if (shapeimage)
948 XDestroyImage(shapeimage)((*((shapeimage)->f.destroy_image))((shapeimage)));
949 if (image_pixels)
950 XpmFree(image_pixels)free(image_pixels);
951 if (mask_pixels)
952 XpmFree(mask_pixels)free(mask_pixels);
953 if (nalloc_pixels)
954 (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL((void*)0));
955 if (alloc_pixels)
956 XpmFree(alloc_pixels)free(alloc_pixels);
957 if (used_pixels)
958 XpmFree(used_pixels)free(used_pixels);
959
960 return (ErrorStatus);
961}
962
963
964/*
965 * Create an XImage with its data
966 */
967static int
968CreateXImage(
969 Display *display,
970 Visual *visual,
971 unsigned int depth,
972 int format,
973 unsigned int width,
974 unsigned int height,
975 XImage **image_return)
976{
977 int bitmap_pad;
978
979 /* first get bitmap_pad */
980 if (depth > 16)
981 bitmap_pad = 32;
982 else if (depth > 8)
983 bitmap_pad = 16;
984 else
985 bitmap_pad = 8;
986
987 /* then create the XImage with data = NULL and bytes_per_line = 0 */
988 *image_return = XCreateImage(display, visual, depth, format, 0, 0,
989 width, height, bitmap_pad, 0);
990 if (!*image_return)
991 return (XpmNoMemory-3);
992
993#if !defined(FOR_MSW) && !defined(AMIGA)
994 if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX2147483647 / height) {
995 XDestroyImage(*image_return)((*((*image_return)->f.destroy_image))((*image_return)));
996 return XpmNoMemory-3;
997 }
998 /* now that bytes_per_line must have been set properly alloc data */
999 if((*image_return)->bytes_per_line == 0 || height == 0)
1000 return XpmNoMemory-3;
1001 (*image_return)->data =
1002 (char *) XpmMalloc((*image_return)->bytes_per_line * height)malloc(((*image_return)->bytes_per_line * height));
1003
1004 if (!(*image_return)->data) {
1005 XDestroyImage(*image_return)((*((*image_return)->f.destroy_image))((*image_return)));
1006 *image_return = NULL((void*)0);
1007 return (XpmNoMemory-3);
1008 }
1009#else
1010 /* under FOR_MSW and AMIGA XCreateImage has done it all */
1011#endif
1012 return (XpmSuccess0);
1013}
1014
1015#ifndef FOR_MSW
1016# ifndef AMIGA
1017/*
1018 * The functions below are written from X11R5 MIT's code (XImUtil.c)
1019 *
1020 * The idea is to have faster functions than the standard XPutPixel function
1021 * to build the image data. Indeed we can speed up things by suppressing tests
1022 * performed for each pixel. We do the same tests but at the image level.
1023 * We also assume that we use only ZPixmap images with null offsets.
1024 */
1025
1026LFUNC(_putbits, void, (register char *src, int dstoffset,static void _putbits (register char *src, int dstoffset, register
int numbits, register char *dst)
1027 register int numbits, register char *dst))static void _putbits (register char *src, int dstoffset, register
int numbits, register char *dst)
;
1028
1029LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb))static int _XReverse_Bytes (register unsigned char *bpt, register
unsigned int nb)
;
1030
1031static unsigned char const _reverse_byte[0x100] = {
1032 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1033 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1034 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1035 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1036 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1037 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1038 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1039 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1040 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1041 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1042 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1043 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1044 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1045 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1046 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1047 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1048 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1049 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1050 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1051 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1052 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1053 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1054 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1055 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1056 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1057 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1058 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1059 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1060 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1061 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1062 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1063 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1064};
1065
1066static int
1067_XReverse_Bytes(
1068 register unsigned char *bpt,
1069 register unsigned int nb)
1070{
1071 do {
1072 *bpt = _reverse_byte[*bpt];
1073 bpt++;
1074 } while (--nb > 0); /* is nb user-controled? */
1075 return 0;
1076}
1077
1078
1079void
1080xpm_xynormalizeimagebits(
1081 register unsigned char *bp,
1082 register XImage *img)
1083{
1084 register unsigned char c;
1085
1086 if (img->byte_order != img->bitmap_bit_order) {
1087 switch (img->bitmap_unit) {
1088
1089 case 16:
1090 c = *bp;
1091 *bp = *(bp + 1);
1092 *(bp + 1) = c;
1093 break;
1094
1095 case 32:
1096 c = *(bp + 3);
1097 *(bp + 3) = *bp;
1098 *bp = c;
1099 c = *(bp + 2);
1100 *(bp + 2) = *(bp + 1);
1101 *(bp + 1) = c;
1102 break;
1103 }
1104 }
1105 if (img->bitmap_bit_order == MSBFirst1)
1106 _XReverse_Bytes(bp, img->bitmap_unit >> 3);
1107}
1108
1109void
1110xpm_znormalizeimagebits(
1111 register unsigned char *bp,
1112 register XImage *img)
1113{
1114 register unsigned char c;
1115
1116 switch (img->bits_per_pixel) {
1117
1118 case 2:
1119 _XReverse_Bytes(bp, 1);
1120 break;
1121
1122 case 4:
1123 *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
1124 break;
1125
1126 case 16:
1127 c = *bp;
1128 *bp = *(bp + 1);
1129 *(bp + 1) = c;
1130 break;
1131
1132 case 24:
1133 c = *(bp + 2);
1134 *(bp + 2) = *bp;
1135 *bp = c;
1136 break;
1137
1138 case 32:
1139 c = *(bp + 3);
1140 *(bp + 3) = *bp;
1141 *bp = c;
1142 c = *(bp + 2);
1143 *(bp + 2) = *(bp + 1);
1144 *(bp + 1) = c;
1145 break;
1146 }
1147}
1148
1149static unsigned char const _lomask[0x09] = {
11500x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1151static unsigned char const _himask[0x09] = {
11520xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
1153
1154static void
1155_putbits(
1156 register char *src, /* address of source bit string */
1157 int dstoffset, /* bit offset into destination;
1158 * range is 0-31 */
1159 register int numbits, /* number of bits to copy to
1160 * destination */
1161 register char *dst) /* address of destination bit string */
1162{
1163 register unsigned char chlo, chhi;
1164 int hibits;
1165
1166 dst = dst + (dstoffset >> 3);
1167 dstoffset = dstoffset & 7;
1168 hibits = 8 - dstoffset;
1169 chlo = *dst & _lomask[dstoffset];
1170 for (;;) {
1171 chhi = (*src << dstoffset) & _himask[dstoffset];
1172 if (numbits <= hibits) {
1173 chhi = chhi & _lomask[dstoffset + numbits];
1174 *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
1175 break;
1176 }
1177 *dst = chhi | chlo;
1178 dst++;
1179 numbits = numbits - hibits;
1180 chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
1181 src++;
1182 if (numbits <= dstoffset) {
1183 chlo = chlo & _lomask[numbits];
1184 *dst = (*dst & _himask[numbits]) | chlo;
1185 break;
1186 }
1187 numbits = numbits - dstoffset;
1188 }
1189}
1190
1191/*
1192 * Default method to write pixels into a Z image data structure.
1193 * The algorithm used is:
1194 *
1195 * copy the destination bitmap_unit or Zpixel to temp
1196 * normalize temp if needed
1197 * copy the pixel bits into the temp
1198 * renormalize temp if needed
1199 * copy the temp back into the destination image data
1200 */
1201
1202static void
1203PutImagePixels(
1204 XImage *image,
1205 unsigned int width,
1206 unsigned int height,
1207 unsigned int *pixelindex,
1208 Pixel *pixels)
1209{
1210 register char *src;
1211 register char *dst;
1212 register unsigned int *iptr;
1213 register unsigned int x, y;
1214 register char *data;
1215 Pixel pixel, px;
1216 int nbytes, depth, ibu, ibpp, i;
1217
1218 data = image->data;
1219 iptr = pixelindex;
1220 depth = image->depth;
1221 if (depth == 1) {
1222 ibu = image->bitmap_unit;
1223 for (y = 0; y < height; y++) /* how can we trust height */
1224 for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
1225 pixel = pixels[*iptr];
1226 for (i = 0, px = pixel; i < sizeof(unsigned long);
1227 i++, px >>= 8)
1228 ((unsigned char *) &pixel)[i] = px;
1229 src = &data[XYINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) + image->xoffset)
/ image->bitmap_unit) * (image->bitmap_unit >> 3
)
];
1230 dst = (char *) &px;
1231 px = 0;
1232 nbytes = ibu >> 3;
1233 for (i = nbytes; --i >= 0;)
1234 *dst++ = *src++;
1235 XYNORMALIZE(&px, image)if ((image->byte_order == 1) || (image->bitmap_bit_order
== 1)) xpm_xynormalizeimagebits((unsigned char *)(&px), image
)
;
1236 _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
1237 XYNORMALIZE(&px, image)if ((image->byte_order == 1) || (image->bitmap_bit_order
== 1)) xpm_xynormalizeimagebits((unsigned char *)(&px), image
)
;
1238 src = (char *) &px;
1239 dst = &data[XYINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) + image->xoffset)
/ image->bitmap_unit) * (image->bitmap_unit >> 3
)
];
1240 for (i = nbytes; --i >= 0;)
1241 *dst++ = *src++;
1242 }
1243 } else {
1244 ibpp = image->bits_per_pixel;
1245 for (y = 0; y < height; y++)
1246 for (x = 0; x < width; x++, iptr++) {
1247 pixel = pixels[*iptr];
1248 if (depth == 4)
1249 pixel &= 0xf;
1250 for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
1251 px >>= 8)
1252 ((unsigned char *) &pixel)[i] = px;
1253 src = &data[ZINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) * image->bits_per_pixel
) >> 3)
];
1254 dst = (char *) &px;
1255 px = 0;
1256 nbytes = (ibpp + 7) >> 3;
1257 for (i = nbytes; --i >= 0;)
1258 *dst++ = *src++;
1259 ZNORMALIZE(&px, image)if (image->byte_order == 1) xpm_znormalizeimagebits((unsigned
char *)(&px), image)
;
1260 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1261 ZNORMALIZE(&px, image)if (image->byte_order == 1) xpm_znormalizeimagebits((unsigned
char *)(&px), image)
;
1262 src = (char *) &px;
1263 dst = &data[ZINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) * image->bits_per_pixel
) >> 3)
];
1264 for (i = nbytes; --i >= 0;)
1265 *dst++ = *src++;
1266 }
1267 }
1268}
1269
1270/*
1271 * write pixels into a 32-bits Z image data structure
1272 */
1273
1274#if !defined(WORD64) && !defined(LONG64)
1275/* this item is static but deterministic so let it slide; doesn't
1276 * hurt re-entrancy of this library. Note if it is actually const then would
1277 * be OK under rules of ANSI-C but probably not C++ which may not
1278 * want to allocate space for it.
1279 */
1280static unsigned long byteorderpixel = MSBFirst1 << 24;
1281
1282#endif
1283
1284/*
1285 WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
1286 3.2e code - by default you get the speeded-up version.
1287*/
1288
1289static void
1290PutImagePixels32(
1291 XImage *image,
1292 unsigned int width,
1293 unsigned int height,
1294 unsigned int *pixelindex,
1295 Pixel *pixels)
1296{
1297 unsigned char *data;
1298 unsigned int *iptr;
1299 unsigned int y;
1300 Pixel pixel;
1301
1302#ifdef WITHOUT_SPEEDUPS
1303
1304 unsigned int x;
1305 unsigned char *addr;
1306
1307 data = (unsigned char *) image->data;
1308 iptr = pixelindex;
1309#if !defined(WORD64) && !defined(LONG64)
1310 if (*((char *) &byteorderpixel) == image->byte_order) {
1311 for (y = 0; y < height; y++)
1312 for (x = 0; x < width; x++, iptr++) {
1313 addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)];
1314 *((unsigned long *) addr) = pixels[*iptr];
1315 }
1316 } else
1317#endif
1318 if (image->byte_order == MSBFirst1)
1319 for (y = 0; y < height; y++)
1320 for (x = 0; x < width; x++, iptr++) {
1321 addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)];
1322 pixel = pixels[*iptr];
1323 addr[0] = pixel >> 24;
1324 addr[1] = pixel >> 16;
1325 addr[2] = pixel >> 8;
1326 addr[3] = pixel;
1327 }
1328 else
1329 for (y = 0; y < height; y++)
1330 for (x = 0; x < width; x++, iptr++) {
1331 addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)];
1332 pixel = pixels[*iptr];
1333 addr[0] = pixel;
1334 addr[1] = pixel >> 8;
1335 addr[2] = pixel >> 16;
1336 addr[3] = pixel >> 24;
1337 }
1338
1339#else /* WITHOUT_SPEEDUPS */
1340
1341 unsigned int bpl = image->bytes_per_line;
1342 unsigned char *data_ptr, *max_data;
1343
1344 data = (unsigned char *) image->data;
1345 iptr = pixelindex;
1346#if !defined(WORD64) && !defined(LONG64)
1347 if (*((char *) &byteorderpixel) == image->byte_order) {
1348 for (y = 0; y < height; y++) {
1349 data_ptr = data;
1350 max_data = data_ptr + (width << 2);
1351
1352 while (data_ptr < max_data) {
1353 *((unsigned long *) data_ptr) = pixels[*(iptr++)];
1354 data_ptr += (1 << 2);
1355 }
1356 data += bpl;
1357 }
1358 } else
1359#endif
1360 if (image->byte_order == MSBFirst1)
1361 for (y = 0; y < height; y++) {
1362 data_ptr = data;
1363 max_data = data_ptr + (width << 2);
1364
1365 while (data_ptr < max_data) {
1366 pixel = pixels[*(iptr++)];
1367
1368 *data_ptr++ = pixel >> 24;
1369 *data_ptr++ = pixel >> 16;
1370 *data_ptr++ = pixel >> 8;
1371 *data_ptr++ = pixel;
1372
1373 }
1374 data += bpl;
1375 }
1376 else
1377 for (y = 0; y < height; y++) {
1378 data_ptr = data;
1379 max_data = data_ptr + (width << 2);
1380
1381 while (data_ptr < max_data) {
1382 pixel = pixels[*(iptr++)];
1383
1384 *data_ptr++ = pixel;
1385 *data_ptr++ = pixel >> 8;
1386 *data_ptr++ = pixel >> 16;
1387 *data_ptr++ = pixel >> 24;
1388 }
1389 data += bpl;
1390 }
1391
1392#endif /* WITHOUT_SPEEDUPS */
1393}
1394
1395/*
1396 * write pixels into a 16-bits Z image data structure
1397 */
1398
1399static void
1400PutImagePixels16(
1401 XImage *image,
1402 unsigned int width,
1403 unsigned int height,
1404 unsigned int *pixelindex,
1405 Pixel *pixels)
1406{
1407 unsigned char *data;
1408 unsigned int *iptr;
1409 unsigned int y;
1410
1411#ifdef WITHOUT_SPEEDUPS
1412
1413 unsigned int x;
1414 unsigned char *addr;
1415
1416 data = (unsigned char *) image->data;
1417 iptr = pixelindex;
1418 if (image->byte_order == MSBFirst1)
1419 for (y = 0; y < height; y++)
1420 for (x = 0; x < width; x++, iptr++) {
1421 addr = &data[ZINDEX16(x, y, image)((y) * image->bytes_per_line) + ((x) << 1)];
1422 addr[0] = pixels[*iptr] >> 8;
1423 addr[1] = pixels[*iptr];
1424 }
1425 else
1426 for (y = 0; y < height; y++)
1427 for (x = 0; x < width; x++, iptr++) {
1428 addr = &data[ZINDEX16(x, y, image)((y) * image->bytes_per_line) + ((x) << 1)];
1429 addr[0] = pixels[*iptr];
1430 addr[1] = pixels[*iptr] >> 8;
1431 }
1432
1433#else /* WITHOUT_SPEEDUPS */
1434
1435 Pixel pixel;
1436
1437 unsigned int bpl = image->bytes_per_line;
1438 unsigned char *data_ptr, *max_data;
1439
1440 data = (unsigned char *) image->data;
1441 iptr = pixelindex;
1442 if (image->byte_order == MSBFirst1)
1443 for (y = 0; y < height; y++) {
1444 data_ptr = data;
1445 max_data = data_ptr + (width << 1);
1446
1447 while (data_ptr < max_data) {
1448 pixel = pixels[*(iptr++)];
1449
1450 data_ptr[0] = pixel >> 8;
1451 data_ptr[1] = pixel;
1452
1453 data_ptr += (1 << 1);
1454 }
1455 data += bpl;
1456 }
1457 else
1458 for (y = 0; y < height; y++) {
1459 data_ptr = data;
1460 max_data = data_ptr + (width << 1);
1461
1462 while (data_ptr < max_data) {
1463 pixel = pixels[*(iptr++)];
1464
1465 data_ptr[0] = pixel;
1466 data_ptr[1] = pixel >> 8;
1467
1468 data_ptr += (1 << 1);
1469 }
1470 data += bpl;
1471 }
1472
1473#endif /* WITHOUT_SPEEDUPS */
1474}
1475
1476/*
1477 * write pixels into a 8-bits Z image data structure
1478 */
1479
1480static void
1481PutImagePixels8(
1482 XImage *image,
1483 unsigned int width,
1484 unsigned int height,
1485 unsigned int *pixelindex,
1486 Pixel *pixels)
1487{
1488 char *data;
1489 unsigned int *iptr;
1490 unsigned int y;
1491
1492#ifdef WITHOUT_SPEEDUPS
1493
1494 unsigned int x;
1495
1496 data = image->data;
1497 iptr = pixelindex;
1498 for (y = 0; y < height; y++)
1499 for (x = 0; x < width; x++, iptr++)
1500 data[ZINDEX8(x, y, image)((y) * image->bytes_per_line) + (x)] = pixels[*iptr];
1501
1502#else /* WITHOUT_SPEEDUPS */
1503
1504 unsigned int bpl = image->bytes_per_line;
1505 char *data_ptr, *max_data;
1506
1507 data = image->data;
1508 iptr = pixelindex;
1509
1510 for (y = 0; y < height; y++) {
1511 data_ptr = data;
1512 max_data = data_ptr + width;
1513
1514 while (data_ptr < max_data)
1515 *(data_ptr++) = pixels[*(iptr++)];
1516
1517 data += bpl;
1518 }
1519
1520#endif /* WITHOUT_SPEEDUPS */
1521}
1522
1523/*
1524 * write pixels into a 1-bit depth image data structure and **offset null**
1525 */
1526
1527static void
1528PutImagePixels1(
1529 XImage *image,
1530 unsigned int width,
1531 unsigned int height,
1532 unsigned int *pixelindex,
1533 Pixel *pixels)
1534{
1535 if (image->byte_order != image->bitmap_bit_order)
1536 PutImagePixels(image, width, height, pixelindex, pixels);
1537 else {
1538 unsigned int *iptr;
1539 unsigned int y;
1540 char *data;
1541
1542#ifdef WITHOUT_SPEEDUPS
1543
1544 unsigned int x;
1545
1546 data = image->data;
1547 iptr = pixelindex;
1548 if (image->bitmap_bit_order == MSBFirst1)
1549 for (y = 0; y < height; y++)
1550 for (x = 0; x < width; x++, iptr++) {
1551 if (pixels[*iptr] & 1)
1552 data[ZINDEX1(x, y, image)((y) * image->bytes_per_line) + ((x) >> 3)] |= 0x80 >> (x & 7);
1553 else
1554 data[ZINDEX1(x, y, image)((y) * image->bytes_per_line) + ((x) >> 3)] &= ~(0x80 >> (x & 7));
1555 }
1556 else
1557 for (y = 0; y < height; y++)
1558 for (x = 0; x < width; x++, iptr++) {
1559 if (pixels[*iptr] & 1)
1560 data[ZINDEX1(x, y, image)((y) * image->bytes_per_line) + ((x) >> 3)] |= 1 << (x & 7);
1561 else
1562 data[ZINDEX1(x, y, image)((y) * image->bytes_per_line) + ((x) >> 3)] &= ~(1 << (x & 7));
1563 }
1564
1565#else /* WITHOUT_SPEEDUPS */
1566
1567 char value;
1568 char *data_ptr, *max_data;
1569 int bpl = image->bytes_per_line;
1570 int diff, count;
1571
1572 data = image->data;
1573 iptr = pixelindex;
1574
1575 diff = width & 7;
1576 width >>= 3;
1577
1578 if (image->bitmap_bit_order == MSBFirst1)
1579 for (y = 0; y < height; y++) {
1580 data_ptr = data;
1581 max_data = data_ptr + width;
1582 while (data_ptr < max_data) {
1583 value = 0;
1584
1585 value = (value << 1) | (pixels[*(iptr++)] & 1);
1586 value = (value << 1) | (pixels[*(iptr++)] & 1);
1587 value = (value << 1) | (pixels[*(iptr++)] & 1);
1588 value = (value << 1) | (pixels[*(iptr++)] & 1);
1589 value = (value << 1) | (pixels[*(iptr++)] & 1);
1590 value = (value << 1) | (pixels[*(iptr++)] & 1);
1591 value = (value << 1) | (pixels[*(iptr++)] & 1);
1592 value = (value << 1) | (pixels[*(iptr++)] & 1);
1593
1594 *(data_ptr++) = value;
1595 }
1596 if (diff) {
1597 value = 0;
1598 for (count = 0; count < diff; count++) {
1599 if (pixels[*(iptr++)] & 1)
1600 value |= (0x80 >> count);
1601 }
1602 *(data_ptr) = value;
1603 }
1604 data += bpl;
1605 }
1606 else
1607 for (y = 0; y < height; y++) {
1608 data_ptr = data;
1609 max_data = data_ptr + width;
1610 while (data_ptr < max_data) {
1611 value = 0;
1612 iptr += 8;
1613
1614 value = (value << 1) | (pixels[*(--iptr)] & 1);
1615 value = (value << 1) | (pixels[*(--iptr)] & 1);
1616 value = (value << 1) | (pixels[*(--iptr)] & 1);
1617 value = (value << 1) | (pixels[*(--iptr)] & 1);
1618 value = (value << 1) | (pixels[*(--iptr)] & 1);
1619 value = (value << 1) | (pixels[*(--iptr)] & 1);
1620 value = (value << 1) | (pixels[*(--iptr)] & 1);
1621 value = (value << 1) | (pixels[*(--iptr)] & 1);
1622
1623 iptr += 8;
1624 *(data_ptr++) = value;
1625 }
1626 if (diff) {
1627 value = 0;
1628 for (count = 0; count < diff; count++) {
1629 if (pixels[*(iptr++)] & 1)
1630 value |= (1 << count);
1631 }
1632 *(data_ptr) = value;
1633 }
1634 data += bpl;
1635 }
1636
1637#endif /* WITHOUT_SPEEDUPS */
1638 }
1639}
1640
1641int
1642XpmCreatePixmapFromXpmImage(
1643 Display *display,
1644 Drawable d,
1645 XpmImage *image,
1646 Pixmap *pixmap_return,
1647 Pixmap *shapemask_return,
1648 XpmAttributes *attributes)
1649{
1650 XImage *ximage, *shapeimage;
1651 int ErrorStatus;
1652
1653 /* initialize return values */
1654 if (pixmap_return)
1655 *pixmap_return = 0;
1656 if (shapemask_return)
1657 *shapemask_return = 0;
1658
1659 /* create the ximages */
1660 ErrorStatus = XpmCreateImageFromXpmImage(display, image,
1661 (pixmap_return ? &ximage : NULL((void*)0)),
1662 (shapemask_return ?
1663 &shapeimage : NULL((void*)0)),
1664 attributes);
1665 if (ErrorStatus < 0)
1666 return (ErrorStatus);
1667
1668 /* create the pixmaps and destroy images */
1669 if (pixmap_return && ximage) {
1670 xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
1671 XDestroyImage(ximage)((*((ximage)->f.destroy_image))((ximage)));
1672 }
1673 if (shapemask_return && shapeimage) {
1674 xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
1675 XDestroyImage(shapeimage)((*((shapeimage)->f.destroy_image))((shapeimage)));
1676 }
1677 return (ErrorStatus);
1678}
1679
1680# else /* AMIGA */
1681
1682static void
1683APutImagePixels (
1684 XImage *image,
1685 unsigned int width,
1686 unsigned int height,
1687 unsigned int *pixelindex,
1688 Pixel *pixels)
1689{
1690 unsigned int *data = pixelindex;
1691 unsigned int x, y;
1692 unsigned char *array;
1693 XImage *tmp_img;
1694 BOOL success = FALSE;
1695
1696 array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array))malloc(((((width+15)>>4)<<4)*sizeof (*array)));
1697 if (array != NULL((void*)0))
1698 {
1699 tmp_img = AllocXImage ((((width+15)>>4)<<4), 1,
1700 image->rp->BitMap->Depth);
1701 if (tmp_img != NULL((void*)0))
1702 {
1703 for (y = 0; y < height; ++y)
1704 {
1705 for (x = 0; x < width; ++x)
1706 array[x] = pixels[*(data++)];
1707 WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp);
1708 }
1709 FreeXImage (tmp_img);
1710 success = TRUE;
1711 }
1712 XpmFree (array)free(array);
1713 }
1714
1715 if (!success)
1716 {
1717 for (y = 0; y < height; ++y)
1718 for (x = 0; x < width; ++x)
1719 XPutPixel (image, x, y, pixels[*(data++)])((*((image)->f.put_pixel))((image), (x), (y), (pixels[*(data
++)])))
;
1720 }
1721}
1722
1723# endif/* AMIGA */
1724#else /* FOR_MSW part follows */
1725static void
1726MSWPutImagePixels(
1727 Display *dc,
1728 XImage *image,
1729 unsigned int width,
1730 unsigned int height,
1731 unsigned int *pixelindex,
1732 Pixel *pixels)
1733{
1734 unsigned int *data = pixelindex;
1735 unsigned int x, y;
1736 HBITMAP obm;
1737
1738 obm = SelectObject(*dc, image->bitmap);
1739 for (y = 0; y < height; y++) {
1740 for (x = 0; x < width; x++) {
1741 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
1742 }
1743 }
1744 SelectObject(*dc, obm);
1745}
1746
1747#endif /* FOR_MSW */
1748
1749
1750
1751#if !defined(FOR_MSW) && !defined(AMIGA)
1752
1753static int
1754PutPixel1(
1755 register XImage *ximage,
1756 int x,
1757 int y,
1758 unsigned long pixel)
1759{
1760 register char *src;
1761 register char *dst;
1762 register int i;
1763 Pixel px;
1764 int nbytes;
1765
1766 if(x < 0 || y < 0)
1767 return 0;
1768
1769 for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
1770 ((unsigned char *)&pixel)[i] = px;
1771 src = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset
) / ximage->bitmap_unit) * (ximage->bitmap_unit >>
3)
];
1772 dst = (char *)&px;
1773 px = 0;
1774 nbytes = ximage->bitmap_unit >> 3;
1775 for (i = nbytes; --i >= 0; ) *dst++ = *src++;
1776 XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order
== 1)) xpm_xynormalizeimagebits((unsigned char *)(&px), ximage
)
;
1777 i = ((x + ximage->xoffset) % ximage->bitmap_unit);
1778 _putbits ((char *)&pixel, i, 1, (char *)&px);
1779 XYNORMALIZE(&px, ximage)if ((ximage->byte_order == 1) || (ximage->bitmap_bit_order
== 1)) xpm_xynormalizeimagebits((unsigned char *)(&px), ximage
)
;
1780 src = (char *) &px;
1781 dst = &ximage->data[XYINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) + ximage->xoffset
) / ximage->bitmap_unit) * (ximage->bitmap_unit >>
3)
];
1782 for (i = nbytes; --i >= 0; )
1783 *dst++ = *src++;
1784
1785 return 1;
1786}
1787
1788static int
1789PutPixel(
1790 register XImage *ximage,
1791 int x,
1792 int y,
1793 unsigned long pixel)
1794{
1795 register char *src;
1796 register char *dst;
1797 register int i;
1798 Pixel px;
1799 unsigned int nbytes, ibpp;
1800
1801 if(x < 0 || y < 0)
1802 return 0;
1803
1804 ibpp = ximage->bits_per_pixel;
1805 if (ximage->depth == 4)
1806 pixel &= 0xf;
1807 for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
1808 ((unsigned char *) &pixel)[i] = px;
1809 src = &ximage->data[ZINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) * ximage->bits_per_pixel
) >> 3)
];
1810 dst = (char *) &px;
1811 px = 0;
1812 nbytes = (ibpp + 7) >> 3;
1813 for (i = nbytes; --i >= 0;)
1814 *dst++ = *src++;
1815 ZNORMALIZE(&px, ximage)if (ximage->byte_order == 1) xpm_znormalizeimagebits((unsigned
char *)(&px), ximage)
;
1816 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
1817 ZNORMALIZE(&px, ximage)if (ximage->byte_order == 1) xpm_znormalizeimagebits((unsigned
char *)(&px), ximage)
;
1818 src = (char *) &px;
1819 dst = &ximage->data[ZINDEX(x, y, ximage)((y) * ximage->bytes_per_line) + (((x) * ximage->bits_per_pixel
) >> 3)
];
1820 for (i = nbytes; --i >= 0;)
1821 *dst++ = *src++;
1822
1823 return 1;
1824}
1825
1826#if !defined(WORD64) && !defined(LONG64)
1827static int
1828PutPixel32(
1829 register XImage *ximage,
1830 int x,
1831 int y,
1832 unsigned long pixel)
1833{
1834 unsigned char *addr;
1835
1836 if(x < 0 || y < 0)
1837 return 0;
1838
1839 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) << 2)];
1840 *((unsigned long *)addr) = pixel;
1841 return 1;
1842}
1843#endif
1844
1845static int
1846PutPixel32MSB(
1847 register XImage *ximage,
1848 int x,
1849 int y,
1850 unsigned long pixel)
1851{
1852 unsigned char *addr;
1853
1854 if(x < 0 || y < 0)
1855 return 0;
1856
1857 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) << 2)];
1858 addr[0] = pixel >> 24;
1859 addr[1] = pixel >> 16;
1860 addr[2] = pixel >> 8;
1861 addr[3] = pixel;
1862 return 1;
1863}
1864
1865static int
1866PutPixel32LSB(
1867 register XImage *ximage,
1868 int x,
1869 int y,
1870 unsigned long pixel)
1871{
1872 unsigned char *addr;
1873
1874 if(x < 0 || y < 0)
1875 return 0;
1876
1877 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) << 2)];
1878 addr[3] = pixel >> 24;
1879 addr[2] = pixel >> 16;
1880 addr[1] = pixel >> 8;
1881 addr[0] = pixel;
1882 return 1;
1883}
1884
1885static int
1886PutPixel16MSB(
1887 register XImage *ximage,
1888 int x,
1889 int y,
1890 unsigned long pixel)
1891{
1892 unsigned char *addr;
1893
1894 if(x < 0 || y < 0)
1895 return 0;
1896
1897 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) << 1)];
1898 addr[0] = pixel >> 8;
1899 addr[1] = pixel;
1900 return 1;
1901}
1902
1903static int
1904PutPixel16LSB(
1905 register XImage *ximage,
1906 int x,
1907 int y,
1908 unsigned long pixel)
1909{
1910 unsigned char *addr;
1911
1912 if(x < 0 || y < 0)
1913 return 0;
1914
1915 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) << 1)];
1916 addr[1] = pixel >> 8;
1917 addr[0] = pixel;
1918 return 1;
1919}
1920
1921static int
1922PutPixel8(
1923 register XImage *ximage,
1924 int x,
1925 int y,
1926 unsigned long pixel)
1927{
1928 if(x < 0 || y < 0)
1929 return 0;
1930
1931 ximage->data[ZINDEX8(x, y, ximage)((y) * ximage->bytes_per_line) + (x)] = pixel;
1932 return 1;
1933}
1934
1935static int
1936PutPixel1MSB(
1937 register XImage *ximage,
1938 int x,
1939 int y,
1940 unsigned long pixel)
1941{
1942 if(x < 0 || y < 0)
1943 return 0;
1944
1945 if (pixel & 1)
1946 ximage->data[ZINDEX1(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) >> 3)] |= 0x80 >> (x & 7);
1947 else
1948 ximage->data[ZINDEX1(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) >> 3)] &= ~(0x80 >> (x & 7));
1949 return 1;
1950}
1951
1952static int
1953PutPixel1LSB(
1954 register XImage *ximage,
1955 int x,
1956 int y,
1957 unsigned long pixel)
1958{
1959 if(x < 0 || y < 0)
1960 return 0;
1961
1962 if (pixel & 1)
1963 ximage->data[ZINDEX1(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) >> 3)] |= 1 << (x & 7);
1964 else
1965 ximage->data[ZINDEX1(x, y, ximage)((y) * ximage->bytes_per_line) + ((x) >> 3)] &= ~(1 << (x & 7));
1966 return 1;
1967}
1968
1969#endif /* not FOR_MSW && not AMIGA */
1970
1971/*
1972 * This function parses an Xpm file or data and directly create an XImage
1973 */
1974int
1975xpmParseDataAndCreate(
1976 Display *display,
1977 xpmData *data,
1978 XImage **image_return,
1979 XImage **shapeimage_return,
1980 XpmImage *image,
1981 XpmInfo *info,
1982 XpmAttributes *attributes)
1983{
1984 /* variables stored in the XpmAttributes structure */
1985 Visual *visual;
1986 Colormap colormap;
1987 unsigned int depth;
1988 int bitmap_format;
1989 XpmFreeColorsFunc freeColors;
1990
1991 /* variables to return */
1992 XImage *ximage = NULL((void*)0);
1993 XImage *shapeimage = NULL((void*)0);
1994 unsigned int mask_pixel_index = XpmUndefPixel0x80000000;
1995
1996 /* calculation variables */
1997 Pixel *image_pixels = NULL((void*)0);
1998 Pixel *mask_pixels = NULL((void*)0);
1999 Pixel *alloc_pixels = NULL((void*)0);
2000 Pixel *used_pixels = NULL((void*)0);
2001 unsigned int nalloc_pixels = 0;
2002 unsigned int nused_pixels = 0;
2003 unsigned int width, height, ncolors, cpp;
2004 unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
2005 XpmColor *colorTable = NULL((void*)0);
2006 char *hints_cmt = NULL((void*)0);
2007 char *colors_cmt = NULL((void*)0);
2008 char *pixels_cmt = NULL((void*)0);
2009
2010 unsigned int cmts;
2011 int ErrorStatus;
2012 xpmHashTable hashtable;
2013
2014
2015 /* initialize return values */
2016 if (image_return)
2017 *image_return = NULL((void*)0);
2018 if (shapeimage_return)
2019 *shapeimage_return = NULL((void*)0);
2020
2021
2022 /* retrieve information from the XpmAttributes */
2023 if (attributes && (attributes->valuemask & XpmVisual(1L<<0)))
2024 visual = attributes->visual;
2025 else
2026 visual = XDefaultVisual(display, XDefaultScreen(display));
2027
2028 if (attributes && (attributes->valuemask & XpmColormap(1L<<1)))
2029 colormap = attributes->colormap;
2030 else
2031 colormap = XDefaultColormap(display, XDefaultScreen(display));
2032
2033 if (attributes && (attributes->valuemask & XpmDepth(1L<<2)))
2034 depth = attributes->depth;
2035 else
2036 depth = XDefaultDepth(display, XDefaultScreen(display));
2037
2038 if (attributes && (attributes->valuemask & XpmBitmapFormat(1L<<18)))
2039 bitmap_format = attributes->bitmap_format;
2040 else
2041 bitmap_format = ZPixmap2;
2042
2043 if (attributes && (attributes->valuemask & XpmFreeColors(1L<<20)))
2044 freeColors = attributes->free_colors;
2045 else
2046 freeColors = FreeColors;
2047
2048 cmts = info && (info->valuemask & XpmReturnComments(1L<<8));
2049
2050 /*
2051 * parse the header
2052 */
2053 ErrorStatus = xpmParseHeader(data);
2054 if (ErrorStatus != XpmSuccess0)
2055 return (ErrorStatus);
2056
2057 /*
2058 * read values
2059 */
2060 ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
2061 &x_hotspot, &y_hotspot, &hotspot,
2062 &extensions);
2063 if (ErrorStatus != XpmSuccess0)
2064 return (ErrorStatus);
2065
2066 /*
2067 * store the hints comment line
2068 */
2069 if (cmts)
2070 xpmGetCmt(data, &hints_cmt);
2071
2072 /*
2073 * init the hashtable
2074 */
2075 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
2076 ErrorStatus = xpmHashTableInit(&hashtable);
2077 if (ErrorStatus != XpmSuccess0)
2078 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2079 }
2080
2081 /*
2082 * read colors
2083 */
2084 ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
2085 if (ErrorStatus != XpmSuccess0)
2086 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2087
2088 /*
2089 * store the colors comment line
2090 */
2091 if (cmts)
2092 xpmGetCmt(data, &colors_cmt);
2093
2094 /* malloc pixels index tables */
2095 if (ncolors >= UINT_MAX(2147483647 *2U +1U) / sizeof(Pixel))
2096 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
2097
2098 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors)malloc((sizeof(Pixel) * ncolors));
2099 if (!image_pixels)
2100 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
2101
2102 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors)malloc((sizeof(Pixel) * ncolors));
2103 if (!mask_pixels)
2104 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
2105
2106 /* maximum of allocated pixels will be the number of colors */
2107 alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors)malloc((sizeof(Pixel) * ncolors));
2108 if (!alloc_pixels)
2109 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
2110
2111 /* maximum of allocated pixels will be the number of colors */
2112 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors)malloc((sizeof(Pixel) * ncolors));
2113 if (!used_pixels)
2114 RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0);
2115
2116 /* get pixel colors, store them in index tables */
2117 ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
2118 image_pixels, mask_pixels, &mask_pixel_index,
2119 alloc_pixels, &nalloc_pixels, used_pixels,
2120 &nused_pixels);
2121
2122 if (ErrorStatus != XpmSuccess0
2123 && (ErrorStatus < 0 || (attributes
2124 && (attributes->valuemask & XpmExactColors(1L<<11))
2125 && attributes->exactColors)))
2126 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2127
2128 /* now create the ximage */
2129 if (image_return) {
2130 ErrorStatus = CreateXImage(display, visual, depth,
2131 (depth == 1 ? bitmap_format : ZPixmap2),
2132 width, height, &ximage);
2133 if (ErrorStatus != XpmSuccess0)
2134 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2135
2136#if !defined(FOR_MSW) && !defined(AMIGA)
2137
2138 /*
2139 * set the XImage pointer function, to be used with XPutPixel,
2140 * to an internal optimized function
2141 */
2142
2143 if (ximage->bits_per_pixel == 8)
2144 ximage->f.put_pixel = PutPixel8;
2145 else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
2146 (ximage->byte_order == ximage->bitmap_bit_order))
2147 if (ximage->bitmap_bit_order == MSBFirst1)
2148 ximage->f.put_pixel = PutPixel1MSB;
2149 else
2150 ximage->f.put_pixel = PutPixel1LSB;
2151 else if (ximage->bits_per_pixel == 16)
2152 if (ximage->bitmap_bit_order == MSBFirst1)
2153 ximage->f.put_pixel = PutPixel16MSB;
2154 else
2155 ximage->f.put_pixel = PutPixel16LSB;
2156 else if (ximage->bits_per_pixel == 32)
2157#if !defined(WORD64) && !defined(LONG64)
2158 if (*((char *)&byteorderpixel) == ximage->byte_order)
2159 ximage->f.put_pixel = PutPixel32;
2160 else
2161#endif
2162 if (ximage->bitmap_bit_order == MSBFirst1)
2163 ximage->f.put_pixel = PutPixel32MSB;
2164 else
2165 ximage->f.put_pixel = PutPixel32LSB;
2166 else if ((ximage->bits_per_pixel | ximage->depth) == 1)
2167 ximage->f.put_pixel = PutPixel1;
2168 else
2169 ximage->f.put_pixel = PutPixel;
2170#endif /* not FOR_MSW && not AMIGA */
2171 }
2172
2173 /* create the shape mask image */
2174 if (mask_pixel_index != XpmUndefPixel0x80000000 && shapeimage_return) {
2175 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
2176 width, height, &shapeimage);
2177 if (ErrorStatus != XpmSuccess0)
2178 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2179
2180#if !defined(FOR_MSW) && !defined(AMIGA)
2181 if (shapeimage->bitmap_bit_order == MSBFirst1)
2182 shapeimage->f.put_pixel = PutPixel1MSB;
2183 else
2184 shapeimage->f.put_pixel = PutPixel1LSB;
2185#endif
2186 }
2187
2188 /*
2189 * read pixels and put them in the XImage
2190 */
2191 ErrorStatus = ParseAndPutPixels(
2192#ifdef FOR_MSW
2193 display,
2194#endif
2195 data, width, height, ncolors, cpp,
2196 colorTable, &hashtable,
2197 ximage, image_pixels,
2198 shapeimage, mask_pixels);
2199 XpmFree(image_pixels)free(image_pixels);
2200 image_pixels = NULL((void*)0);
2201 XpmFree(mask_pixels)free(mask_pixels);
2202 mask_pixels = NULL((void*)0);
2203
2204 /*
2205 * free the hastable
2206 */
2207 if (ErrorStatus != XpmSuccess0)
2208 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2209 else if (USE_HASHTABLE(cpp > 2 && ncolors > 4))
2210 xpmHashTableFree(&hashtable);
2211
2212 /*
2213 * store the pixels comment line
2214 */
2215 if (cmts)
2216 xpmGetCmt(data, &pixels_cmt);
2217
2218 /*
2219 * parse extensions
2220 */
2221 if (info && (info->valuemask & XpmReturnExtensions(1L<<10))) {
2222 if (extensions) {
2223 ErrorStatus = xpmParseExtensions(data, &info->extensions,
2224 &info->nextensions);
2225 if (ErrorStatus != XpmSuccess0)
2226 RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0);
2227 } else {
2228 info->extensions = NULL((void*)0);
2229 info->nextensions = 0;
2230 }
2231 }
2232 /*
2233 * store found informations in the XpmImage structure
2234 */
2235 image->width = width;
2236 image->height = height;
2237 image->cpp = cpp;
2238 image->ncolors = ncolors;
2239 image->colorTable = colorTable;
2240 image->data = NULL((void*)0);
2241
2242 if (info) {
2243 if (cmts) {
2244 info->hints_cmt = hints_cmt;
2245 info->colors_cmt = colors_cmt;
2246 info->pixels_cmt = pixels_cmt;
2247 }
2248 if (hotspot) {
2249 info->x_hotspot = x_hotspot;
2250 info->y_hotspot = y_hotspot;
2251 info->valuemask |= XpmHotspot(1L<<4);
2252 }
2253 }
2254 /* if requested return used pixels in the XpmAttributes structure */
2255 if (attributes && (attributes->valuemask & XpmReturnPixels(1L<<9) ||
2256/* 3.2 backward compatibility code */
2257 attributes->valuemask & XpmReturnInfos(1L<<8))) {
2258/* end 3.2 bc */
2259 attributes->pixels = used_pixels;
2260 attributes->npixels = nused_pixels;
2261 attributes->mask_pixel = mask_pixel_index;
2262 } else
2263 XpmFree(used_pixels)free(used_pixels);
2264
2265 /* if requested return alloc'ed pixels in the XpmAttributes structure */
2266 if (attributes && (attributes->valuemask & XpmReturnAllocPixels(1L<<16))) {
2267 attributes->alloc_pixels = alloc_pixels;
2268 attributes->nalloc_pixels = nalloc_pixels;
2269 } else
2270 XpmFree(alloc_pixels)free(alloc_pixels);
2271
2272 /* return created images */
2273 if (image_return)
2274 *image_return = ximage;
2275 if (shapeimage_return)
2276 *shapeimage_return = shapeimage;
2277
2278 return (XpmSuccess0);
2279
2280/* exit point in case of error, free only locally allocated variables */
2281error:
2282 if (USE_HASHTABLE(cpp > 2 && ncolors > 4))
2283 xpmHashTableFree(&hashtable);
2284 if (colorTable)
2285 xpmFreeColorTable(colorTable, ncolors);
2286 if (hints_cmt)
2287 XpmFree(hints_cmt)free(hints_cmt);
2288 if (colors_cmt)
2289 XpmFree(colors_cmt)free(colors_cmt);
2290 if (pixels_cmt)
2291 XpmFree(pixels_cmt)free(pixels_cmt);
2292 if (ximage)
2293 XDestroyImage(ximage)((*((ximage)->f.destroy_image))((ximage)));
2294 if (shapeimage)
2295 XDestroyImage(shapeimage)((*((shapeimage)->f.destroy_image))((shapeimage)));
2296 if (image_pixels)
2297 XpmFree(image_pixels)free(image_pixels);
2298 if (mask_pixels)
2299 XpmFree(mask_pixels)free(mask_pixels);
2300 if (nalloc_pixels)
2301 (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL((void*)0));
2302 if (alloc_pixels)
2303 XpmFree(alloc_pixels)free(alloc_pixels);
2304 if (used_pixels)
2305 XpmFree(used_pixels)free(used_pixels);
2306
2307 return (ErrorStatus);
2308}
2309
2310static int
2311ParseAndPutPixels(
2312#ifdef FOR_MSW
2313 Display *dc,
2314#endif
2315 xpmData *data,
2316 unsigned int width,
2317 unsigned int height,
2318 unsigned int ncolors,
2319 unsigned int cpp,
2320 XpmColor *colorTable,
2321 xpmHashTable *hashtable,
2322 XImage *image,
2323 Pixel *image_pixels,
2324 XImage *shapeimage,
2325 Pixel *shape_pixels)
2326{
2327 unsigned int a, x, y;
2328
2329 switch (cpp) {
2330
2331 case (1): /* Optimize for single character
2332 * colors */
2333 {
2334 unsigned short colidx[256];
2335#ifdef FOR_MSW
2336 HDC shapedc;
2337 HBITMAP obm, sobm;
2338
2339 if ( shapeimage ) {
2340 shapedc = CreateCompatibleDC(*dc);
2341 sobm = SelectObject(shapedc, shapeimage->bitmap);
2342 } else {
2343 shapedc = NULL((void*)0);
2344 }
2345 obm = SelectObject(*dc, image->bitmap);
2346#endif
2347 if (ncolors > 256)
2348 return (XpmFileInvalid-2);
2349
2350 bzero((char *)colidx, 256 * sizeof(short))memset((char *)colidx,0,256 * sizeof(short));
2351 for (a = 0; a < ncolors; a++)
2352 colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
2353
2354 for (y = 0; y < height; y++) {
2355 xpmNextString(data);
2356 for (x = 0; x < width; x++) {
2357 int c = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
2358
2359 if (c > 0 && c < 256 && colidx[c] != 0) {
2360#ifndef FOR_MSW
2361 XPutPixel(image, x, y, image_pixels[colidx[c] - 1])((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[colidx[c] - 1])))
;
2362 if (shapeimage)
2363 XPutPixel(shapeimage, x, y,((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[colidx[c] - 1])))
2364 shape_pixels[colidx[c] - 1])((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[colidx[c] - 1])))
;
2365#else
2366 SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
2367 if (shapedc) {
2368 SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
2369 }
2370#endif
2371 } else
2372 return (XpmFileInvalid-2);
2373 }
2374 }
2375#ifdef FOR_MSW
2376 if ( shapedc ) {
2377 SelectObject(shapedc, sobm);
2378 DeleteDC(shapedc);
2379 }
2380 SelectObject(*dc, obm);
2381#endif
2382 }
2383 break;
2384
2385 case (2): /* Optimize for double character
2386 * colors */
2387 {
2388
2389/* free all allocated pointers at all exits */
2390#define FREE_CIDX{int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx[f
]);}
{int f; for (f = 0; f < 256; f++) \
2391if (cidx[f]) XpmFree(cidx[f])free(cidx[f]);}
2392
2393 /* array of pointers malloced by need */
2394 unsigned short *cidx[256];
2395 unsigned int char1;
2396
2397 bzero((char *)cidx, 256 * sizeof(unsigned short *))memset((char *)cidx,0,256 * sizeof(unsigned short *)); /* init */
2398 for (a = 0; a < ncolors; a++) {
2399 char1 = (unsigned char) colorTable[a].string[0];
2400 if (cidx[char1] == NULL((void*)0)) { /* get new memory */
2401 cidx[char1] = (unsigned short *)
2402 XpmCalloc(256, sizeof(unsigned short))calloc((256), (sizeof(unsigned short)));
2403 if (cidx[char1] == NULL((void*)0)) { /* new block failed */
2404 FREE_CIDX{int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx[f
]);}
;
2405 return (XpmNoMemory-3);
2406 }
2407 }
2408 cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
2409 }
2410
2411 for (y = 0; y < height; y++) {
2412 xpmNextString(data);
2413 for (x = 0; x < width; x++) {
2414 int cc1 = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
2415 if (cc1 > 0 && cc1 < 256) {
2416 int cc2 = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
2417 if (cc2 > 0 && cc2 < 256 &&
2418 cidx[cc1] && cidx[cc1][cc2] != 0) {
2419#ifndef FOR_MSW
2420 XPutPixel(image, x, y,((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[cidx[cc1][cc2] - 1])))
2421 image_pixels[cidx[cc1][cc2] - 1])((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[cidx[cc1][cc2] - 1])))
;
2422 if (shapeimage)
2423 XPutPixel(shapeimage, x, y,((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[cidx[cc1][cc2] - 1])))
2424 shape_pixels[cidx[cc1][cc2] - 1])((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[cidx[cc1][cc2] - 1])))
;
2425#else
2426 SelectObject(*dc, image->bitmap);
2427 SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
2428 if (shapeimage) {
2429 SelectObject(*dc, shapeimage->bitmap);
2430 SetPixel(*dc, x, y,
2431 shape_pixels[cidx[cc1][cc2] - 1]);
2432 }
2433#endif
2434 } else {
2435 FREE_CIDX{int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx[f
]);}
;
2436 return (XpmFileInvalid-2);
2437 }
2438 } else {
2439 FREE_CIDX{int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx[f
]);}
;
2440 return (XpmFileInvalid-2);
2441 }
2442 }
2443 }
2444 FREE_CIDX{int f; for (f = 0; f < 256; f++) if (cidx[f]) free(cidx[f
]);}
;
2445 }
2446 break;
2447
2448 default: /* Non-optimized case of long color
2449 * names */
2450 {
2451 char *s;
2452 char buf[BUFSIZ8192];
2453
2454 if (cpp >= sizeof(buf))
2455 return (XpmFileInvalid-2);
2456
2457 buf[cpp] = '\0';
2458 if (USE_HASHTABLE(cpp > 2 && ncolors > 4)) {
2459 xpmHashAtom *slot;
2460
2461 for (y = 0; y < height; y++) {
2462 xpmNextString(data);
2463 for (x = 0; x < width; x++) {
2464 for (a = 0, s = buf; a < cpp; a++, s++)
2465 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
2466 slot = xpmHashSlot(hashtable, buf);
2467 if (!*slot) /* no color matches */
2468 return (XpmFileInvalid-2);
2469#ifndef FOR_MSW
2470 XPutPixel(image, x, y,((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[((unsigned long)((*slot)->data))])))
2471 image_pixels[HashColorIndex(slot)])((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[((unsigned long)((*slot)->data))])))
;
2472 if (shapeimage)
2473 XPutPixel(shapeimage, x, y,((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[((unsigned long)((*slot)->data))])))
2474 shape_pixels[HashColorIndex(slot)])((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[((unsigned long)((*slot)->data))])))
;
2475#else
2476 SelectObject(*dc, image->bitmap);
2477 SetPixel(*dc, x, y,
2478 image_pixels[HashColorIndex(slot)((unsigned long)((*slot)->data))]);
2479 if (shapeimage) {
2480 SelectObject(*dc, shapeimage->bitmap);
2481 SetPixel(*dc, x, y,
2482 shape_pixels[HashColorIndex(slot)((unsigned long)((*slot)->data))]);
2483 }
2484#endif
2485 }
2486 }
2487 } else {
2488 for (y = 0; y < height; y++) {
2489 xpmNextString(data);
2490 for (x = 0; x < width; x++) {
2491 for (a = 0, s = buf; a < cpp; a++, s++)
2492 *s = xpmGetC(data)((!data->type || data->type == 3) ? (*data->cptr++) :
(_IO_getc (data->stream.file)))
;
2493 for (a = 0; a < ncolors; a++)
2494 if (!strcmp(colorTable[a].string, buf))
2495 break;
2496 if (a == ncolors) /* no color matches */
2497 return (XpmFileInvalid-2);
2498#ifndef FOR_MSW
2499 XPutPixel(image, x, y, image_pixels[a])((*((image)->f.put_pixel))((image), (x), (y), (image_pixels
[a])))
;
2500 if (shapeimage)
2501 XPutPixel(shapeimage, x, y, shape_pixels[a])((*((shapeimage)->f.put_pixel))((shapeimage), (x), (y), (shape_pixels
[a])))
;
2502#else
2503 SelectObject(*dc, image->bitmap);
2504 SetPixel(*dc, x, y, image_pixels[a]);
2505 if (shapeimage) {
2506 SelectObject(*dc, shapeimage->bitmap);
2507 SetPixel(*dc, x, y, shape_pixels[a]);
2508 }
2509#endif
2510 }
2511 }
2512 }
2513 }
2514 break;
2515 }
2516 return (XpmSuccess0);
2517}