File: | scan.c |
Location: | line 543, column 16 |
Description: | Array access (from variable 'adefaults') results in a null pointer dereference |
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 | * scan.c: * | ||
28 | * * | ||
29 | * XPM library * | ||
30 | * Scanning utility for XPM file format * | ||
31 | * * | ||
32 | * Developed by Arnaud Le Hors * | ||
33 | \*****************************************************************************/ | ||
34 | |||
35 | /* | ||
36 | * The code related to FOR_MSW has been added by | ||
37 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | ||
38 | */ | ||
39 | |||
40 | /* | ||
41 | * The code related to AMIGA has been added by | ||
42 | * Lorens Younes (d93-hyo@nada.kth.se) 4/96 | ||
43 | */ | ||
44 | |||
45 | /* October 2004, source code review by Thomas Biege <thomas@suse.de> */ | ||
46 | |||
47 | #ifdef HAVE_CONFIG_H1 | ||
48 | #include <config.h> | ||
49 | #endif | ||
50 | #include "XpmI.h" | ||
51 | |||
52 | #define MAXPRINTABLE92 92 /* number of printable ascii chars | ||
53 | * minus \ and " for string compat | ||
54 | * and ? to avoid ANSI trigraphs. */ | ||
55 | |||
56 | static const char *printable = | ||
57 | " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ | ||
58 | ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; | ||
59 | |||
60 | /* | ||
61 | * printable begin with a space, so in most case, due to my algorithm, when | ||
62 | * the number of different colors is less than MAXPRINTABLE, it will give a | ||
63 | * char follow by "nothing" (a space) in the readable xpm file | ||
64 | */ | ||
65 | |||
66 | |||
67 | typedef struct { | ||
68 | Pixel *pixels; | ||
69 | unsigned int *pixelindex; | ||
70 | unsigned int size; | ||
71 | unsigned int ncolors; | ||
72 | unsigned int mask_pixel; /* whether there is or not */ | ||
73 | } PixelsMap; | ||
74 | |||
75 | LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,static int storePixel (Pixel pixel, PixelsMap *pmap, unsigned int *index_return) | ||
76 | unsigned int *index_return))static int storePixel (Pixel pixel, PixelsMap *pmap, unsigned int *index_return); | ||
77 | |||
78 | LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,static int storeMaskPixel (Pixel pixel, PixelsMap *pmap, unsigned int *index_return) | ||
79 | unsigned int *index_return))static int storeMaskPixel (Pixel pixel, PixelsMap *pmap, unsigned int *index_return); | ||
80 | |||
81 | typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap, | ||
82 | unsigned int *index_return); | ||
83 | |||
84 | #ifndef FOR_MSW | ||
85 | # ifndef AMIGA | ||
86 | LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,static int GetImagePixels (XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap) | ||
87 | unsigned int height, PixelsMap *pmap))static int GetImagePixels (XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap); | ||
88 | |||
89 | LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,static int GetImagePixels32 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap) | ||
90 | unsigned int height, PixelsMap *pmap))static int GetImagePixels32 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap); | ||
91 | |||
92 | LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,static int GetImagePixels16 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap) | ||
93 | unsigned int height, PixelsMap *pmap))static int GetImagePixels16 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap); | ||
94 | |||
95 | LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,static int GetImagePixels8 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap) | ||
96 | unsigned int height, PixelsMap *pmap))static int GetImagePixels8 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap); | ||
97 | |||
98 | LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,static int GetImagePixels1 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ) | ||
99 | unsigned int height, PixelsMap *pmap,static int GetImagePixels1 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ) | ||
100 | storeFuncPtr storeFunc))static int GetImagePixels1 (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ); | ||
101 | # else /* AMIGA */ | ||
102 | LFUNC(AGetImagePixels, int, (XImage *image, unsigned int width,static int AGetImagePixels (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ) | ||
103 | unsigned int height, PixelsMap *pmap,static int AGetImagePixels (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ) | ||
104 | storeFuncPtr storeFunc))static int AGetImagePixels (XImage *image, unsigned int width , unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc ); | ||
105 | # endif/* AMIGA */ | ||
106 | #else /* ndef FOR_MSW */ | ||
107 | LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,static int MSWGetImagePixels (Display *d, XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc) | ||
108 | unsigned int height, PixelsMap *pmap,static int MSWGetImagePixels (Display *d, XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc) | ||
109 | storeFuncPtr storeFunc))static int MSWGetImagePixels (Display *d, XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap, storeFuncPtr storeFunc); | ||
110 | #endif | ||
111 | LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,static int ScanTransparentColor (XpmColor *color, unsigned int cpp, XpmAttributes *attributes) | ||
112 | XpmAttributes *attributes))static int ScanTransparentColor (XpmColor *color, unsigned int cpp, XpmAttributes *attributes); | ||
113 | |||
114 | LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors,static int ScanOtherColors (Display *display, XpmColor *colors , unsigned int ncolors, Pixel *pixels, unsigned int mask, unsigned int cpp, XpmAttributes *attributes) | ||
115 | unsigned int ncolors,static int ScanOtherColors (Display *display, XpmColor *colors , unsigned int ncolors, Pixel *pixels, unsigned int mask, unsigned int cpp, XpmAttributes *attributes) | ||
116 | Pixel *pixels, unsigned int mask,static int ScanOtherColors (Display *display, XpmColor *colors , unsigned int ncolors, Pixel *pixels, unsigned int mask, unsigned int cpp, XpmAttributes *attributes) | ||
117 | unsigned int cpp, XpmAttributes *attributes))static int ScanOtherColors (Display *display, XpmColor *colors , unsigned int ncolors, Pixel *pixels, unsigned int mask, unsigned int cpp, XpmAttributes *attributes); | ||
118 | |||
119 | /* | ||
120 | * This function stores the given pixel in the given arrays which are grown | ||
121 | * if not large enough. | ||
122 | */ | ||
123 | static int | ||
124 | storePixel( | ||
125 | Pixel pixel, | ||
126 | PixelsMap *pmap, | ||
127 | unsigned int *index_return) | ||
128 | { | ||
129 | unsigned int i; | ||
130 | Pixel *p; | ||
131 | unsigned int ncolors; | ||
132 | |||
133 | if (*index_return) { /* this is a transparent pixel! */ | ||
134 | *index_return = 0; | ||
135 | return 0; | ||
136 | } | ||
137 | ncolors = pmap->ncolors; | ||
138 | p = pmap->pixels + pmap->mask_pixel; | ||
139 | for (i = pmap->mask_pixel; i < ncolors; i++, p++) | ||
140 | if (*p == pixel) | ||
141 | break; | ||
142 | if (i == ncolors) { | ||
143 | if (ncolors >= pmap->size) { | ||
144 | pmap->size *= 2; | ||
145 | p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size)realloc((pmap->pixels), (sizeof(Pixel) * pmap->size)); | ||
146 | if (!p) | ||
147 | return (1); | ||
148 | pmap->pixels = p; | ||
149 | |||
150 | } | ||
151 | (pmap->pixels)[ncolors] = pixel; | ||
152 | pmap->ncolors++; | ||
153 | } | ||
154 | *index_return = i; | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int | ||
159 | storeMaskPixel( | ||
160 | Pixel pixel, | ||
161 | PixelsMap *pmap, | ||
162 | unsigned int *index_return) | ||
163 | { | ||
164 | if (!pixel) { | ||
165 | if (!pmap->ncolors) { | ||
166 | pmap->ncolors = 1; | ||
167 | (pmap->pixels)[0] = 0; | ||
168 | pmap->mask_pixel = 1; | ||
169 | } | ||
170 | *index_return = 1; | ||
171 | } else | ||
172 | *index_return = 0; | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | /* function call in case of error */ | ||
177 | #undef RETURN | ||
178 | #define RETURN(status)do { ErrorStatus = status; goto error; } while(0) \ | ||
179 | do { \ | ||
180 | ErrorStatus = status; \ | ||
181 | goto error; \ | ||
182 | } while(0) | ||
183 | |||
184 | /* | ||
185 | * This function scans the given image and stores the found informations in | ||
186 | * the given XpmImage structure. | ||
187 | */ | ||
188 | int | ||
189 | XpmCreateXpmImageFromImage( | ||
190 | Display *display, | ||
191 | XImage *image, | ||
192 | XImage *shapeimage, | ||
193 | XpmImage *xpmimage, | ||
194 | XpmAttributes *attributes) | ||
195 | { | ||
196 | /* variables stored in the XpmAttributes structure */ | ||
197 | unsigned int cpp; | ||
198 | |||
199 | /* variables to return */ | ||
200 | PixelsMap pmap; | ||
201 | XpmColor *colorTable = NULL((void*)0); | ||
202 | int ErrorStatus = 0; | ||
203 | |||
204 | /* calculation variables */ | ||
205 | unsigned int width = 0; | ||
206 | unsigned int height = 0; | ||
207 | unsigned int cppm; /* minimum chars per pixel */ | ||
208 | unsigned int c; | ||
209 | |||
210 | /* initialize pmap */ | ||
211 | pmap.pixels = NULL((void*)0); | ||
212 | pmap.pixelindex = NULL((void*)0); | ||
213 | pmap.size = 256; /* should be enough most of the time */ | ||
214 | pmap.ncolors = 0; | ||
215 | pmap.mask_pixel = 0; | ||
216 | |||
217 | /* | ||
218 | * get geometry | ||
219 | */ | ||
220 | if (image) { | ||
221 | width = image->width; | ||
222 | height = image->height; | ||
223 | } else if (shapeimage) { | ||
224 | width = shapeimage->width; | ||
225 | height = shapeimage->height; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * retrieve information from the XpmAttributes | ||
230 | */ | ||
231 | if (attributes && (attributes->valuemask & XpmCharsPerPixel(1L<<5) | ||
232 | /* 3.2 backward compatibility code */ | ||
233 | || attributes->valuemask & XpmInfos(1L<<8))) | ||
234 | /* end 3.2 bc */ | ||
235 | cpp = attributes->cpp; | ||
236 | else | ||
237 | cpp = 0; | ||
238 | |||
239 | if ((height > 0 && width >= UINT_MAX(2147483647 *2U +1U) / height) || | ||
240 | width * height >= UINT_MAX(2147483647 *2U +1U) / sizeof(unsigned int)) | ||
241 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
242 | pmap.pixelindex = | ||
243 | (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int))calloc((width * height), (sizeof(unsigned int))); | ||
244 | if (!pmap.pixelindex) | ||
245 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
246 | |||
247 | if (pmap.size >= UINT_MAX(2147483647 *2U +1U) / sizeof(Pixel)) | ||
248 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
249 | |||
250 | pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size)malloc((sizeof(Pixel) * pmap.size)); | ||
251 | if (!pmap.pixels) | ||
252 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
253 | |||
254 | /* | ||
255 | * scan shape mask if any | ||
256 | */ | ||
257 | if (shapeimage) { | ||
258 | #ifndef FOR_MSW | ||
259 | # ifndef AMIGA | ||
260 | ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, | ||
261 | storeMaskPixel); | ||
262 | # else | ||
263 | ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap, | ||
264 | storeMaskPixel); | ||
265 | # endif | ||
266 | #else | ||
267 | ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height, | ||
268 | &pmap, storeMaskPixel); | ||
269 | #endif | ||
270 | if (ErrorStatus != XpmSuccess0) | ||
271 | RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0); | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * scan the image data | ||
276 | * | ||
277 | * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized | ||
278 | * functions, otherwise use slower but sure general one. | ||
279 | * | ||
280 | */ | ||
281 | |||
282 | if (image) { | ||
283 | #ifndef FOR_MSW | ||
284 | # ifndef AMIGA | ||
285 | if (((image->bits_per_pixel | image->depth) == 1) && | ||
286 | (image->byte_order == image->bitmap_bit_order)) | ||
287 | ErrorStatus = GetImagePixels1(image, width, height, &pmap, | ||
288 | storePixel); | ||
289 | else if (image->format == ZPixmap2) { | ||
290 | if (image->bits_per_pixel == 8) | ||
291 | ErrorStatus = GetImagePixels8(image, width, height, &pmap); | ||
292 | else if (image->bits_per_pixel == 16) | ||
293 | ErrorStatus = GetImagePixels16(image, width, height, &pmap); | ||
294 | else if (image->bits_per_pixel == 32) | ||
295 | ErrorStatus = GetImagePixels32(image, width, height, &pmap); | ||
296 | } else | ||
297 | ErrorStatus = GetImagePixels(image, width, height, &pmap); | ||
298 | # else | ||
299 | ErrorStatus = AGetImagePixels(image, width, height, &pmap, | ||
300 | storePixel); | ||
301 | # endif | ||
302 | #else | ||
303 | ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap, | ||
304 | storePixel); | ||
305 | #endif | ||
306 | if (ErrorStatus != XpmSuccess0) | ||
307 | RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * get rgb values and a string of char, and possibly a name for each | ||
312 | * color | ||
313 | */ | ||
314 | if (pmap.ncolors >= UINT_MAX(2147483647 *2U +1U) / sizeof(XpmColor)) | ||
315 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
316 | colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor))calloc((pmap.ncolors), (sizeof(XpmColor))); | ||
317 | if (!colorTable) | ||
318 | RETURN(XpmNoMemory)do { ErrorStatus = -3; goto error; } while(0); | ||
319 | |||
320 | /* compute the minimal cpp */ | ||
321 | for (cppm = 1, c = MAXPRINTABLE92; pmap.ncolors > c; cppm++) | ||
322 | c *= MAXPRINTABLE92; | ||
323 | if (cpp < cppm) | ||
324 | cpp = cppm; | ||
325 | |||
326 | if (pmap.mask_pixel) { | ||
327 | ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes); | ||
328 | if (ErrorStatus != XpmSuccess0) | ||
329 | RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0); | ||
330 | } | ||
331 | |||
332 | ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors, | ||
333 | pmap.pixels, pmap.mask_pixel, cpp, | ||
334 | attributes); | ||
335 | if (ErrorStatus != XpmSuccess0) | ||
336 | RETURN(ErrorStatus)do { ErrorStatus = ErrorStatus; goto error; } while(0); | ||
337 | |||
338 | /* | ||
339 | * store found informations in the XpmImage structure | ||
340 | */ | ||
341 | xpmimage->width = width; | ||
342 | xpmimage->height = height; | ||
343 | xpmimage->cpp = cpp; | ||
344 | xpmimage->ncolors = pmap.ncolors; | ||
345 | xpmimage->colorTable = colorTable; | ||
346 | xpmimage->data = pmap.pixelindex; | ||
347 | |||
348 | XpmFree(pmap.pixels)free(pmap.pixels); | ||
349 | return (XpmSuccess0); | ||
350 | |||
351 | /* exit point in case of error, free only locally allocated variables */ | ||
352 | error: | ||
353 | if (pmap.pixelindex) | ||
354 | XpmFree(pmap.pixelindex)free(pmap.pixelindex); | ||
355 | if (pmap.pixels) | ||
356 | XpmFree(pmap.pixels)free(pmap.pixels); | ||
357 | if (colorTable) | ||
358 | xpmFreeColorTable(colorTable, pmap.ncolors); | ||
359 | |||
360 | return (ErrorStatus); | ||
361 | } | ||
362 | |||
363 | static int | ||
364 | ScanTransparentColor( | ||
365 | XpmColor *color, | ||
366 | unsigned int cpp, | ||
367 | XpmAttributes *attributes) | ||
368 | { | ||
369 | char *s; | ||
370 | unsigned int a, b, c; | ||
371 | |||
372 | /* first get a character string */ | ||
373 | a = 0; | ||
374 | if (cpp >= UINT_MAX(2147483647 *2U +1U) - 1) | ||
375 | return (XpmNoMemory-3); | ||
376 | if (!(s = color->string = (char *) XpmMalloc(cpp + 1)malloc((cpp + 1)))) | ||
377 | return (XpmNoMemory-3); | ||
378 | *s++ = printable[c = a % MAXPRINTABLE92]; | ||
379 | for (b = 1; b < cpp; b++, s++) | ||
380 | *s = printable[c = ((a - c) / MAXPRINTABLE92) % MAXPRINTABLE92]; | ||
381 | *s = '\0'; | ||
382 | |||
383 | /* then retreive related info from the attributes if any */ | ||
384 | if (attributes && (attributes->valuemask & XpmColorTable(1L<<15) | ||
385 | /* 3.2 backward compatibility code */ | ||
386 | || attributes->valuemask & XpmInfos(1L<<8)) | ||
387 | /* end 3.2 bc */ | ||
388 | && attributes->mask_pixel != XpmUndefPixel0x80000000) { | ||
389 | |||
390 | unsigned int key; | ||
391 | char **defaults = (char **) color; | ||
392 | char **mask_defaults; | ||
393 | |||
394 | /* 3.2 backward compatibility code */ | ||
395 | if (attributes->valuemask & XpmColorTable(1L<<15)) | ||
396 | /* end 3.2 bc */ | ||
397 | mask_defaults = (char **) ( | ||
398 | attributes->colorTable + attributes->mask_pixel); | ||
399 | /* 3.2 backward compatibility code */ | ||
400 | else | ||
401 | mask_defaults = (char **) | ||
402 | ((XpmColor **) attributes->colorTable)[attributes->mask_pixel]; | ||
403 | /* end 3.2 bc */ | ||
404 | for (key = 1; key <= NKEYS5; key++) { | ||
405 | if ((s = mask_defaults[key])) { | ||
406 | defaults[key] = (char *) xpmstrdupstrdup(s); | ||
407 | if (!defaults[key]) | ||
408 | return (XpmNoMemory-3); | ||
409 | } | ||
410 | } | ||
411 | } else { | ||
412 | color->c_color = (char *) xpmstrdupstrdup(TRANSPARENT_COLOR"None"); | ||
413 | if (!color->c_color) | ||
414 | return (XpmNoMemory-3); | ||
415 | } | ||
416 | return (XpmSuccess0); | ||
417 | } | ||
418 | |||
419 | static int | ||
420 | ScanOtherColors( | ||
421 | Display *display, | ||
422 | XpmColor *colors, | ||
423 | unsigned int ncolors, | ||
424 | Pixel *pixels, | ||
425 | unsigned int mask, | ||
426 | unsigned int cpp, | ||
427 | XpmAttributes *attributes) | ||
428 | { | ||
429 | /* variables stored in the XpmAttributes structure */ | ||
430 | Colormap colormap; | ||
431 | char *rgb_fname; | ||
432 | |||
433 | #ifndef FOR_MSW | ||
434 | xpmRgbName rgbn[MAX_RGBNAMES1024]; | ||
435 | #else | ||
436 | xpmRgbName *rgbn = NULL((void*)0); | ||
437 | #endif | ||
438 | int rgbn_max = 0; | ||
439 | unsigned int i, j, c, i2; | ||
440 | XpmColor *color; | ||
441 | XColor *xcolors = NULL((void*)0), *xcolor; | ||
442 | char *colorname, *s; | ||
443 | XpmColor *colorTable = NULL((void*)0), **oldColorTable = NULL((void*)0); | ||
444 | unsigned int ancolors = 0; | ||
445 | Pixel *apixels = NULL((void*)0); | ||
446 | unsigned int mask_pixel = 0; | ||
447 | Boolint found; | ||
448 | |||
449 | /* retrieve information from the XpmAttributes */ | ||
450 | if (attributes && (attributes->valuemask & XpmColormap(1L<<1))) | ||
| |||
451 | colormap = attributes->colormap; | ||
452 | else | ||
453 | colormap = XDefaultColormap(display, XDefaultScreen(display)); | ||
454 | if (attributes && (attributes->valuemask & XpmRgbFilename(1L<<7))) | ||
| |||
455 | rgb_fname = attributes->rgb_fname; | ||
456 | else | ||
457 | rgb_fname = NULL((void*)0); | ||
458 | |||
459 | /* start from the right element */ | ||
460 | if (mask) { | ||
| |||
| |||
461 | colors++; | ||
462 | ncolors--; | ||
463 | pixels++; | ||
464 | } | ||
465 | |||
466 | /* first get character strings and rgb values */ | ||
467 | if (ncolors >= UINT_MAX(2147483647 *2U +1U) / sizeof(XColor) || cpp >= UINT_MAX(2147483647 *2U +1U) - 1) | ||
| |||
468 | return (XpmNoMemory-3); | ||
469 | xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors)malloc((sizeof(XColor) * ncolors)); | ||
470 | if (!xcolors) | ||
| |||
| |||
471 | return (XpmNoMemory-3); | ||
472 | |||
473 | for (i = 0, i2 = mask, color = colors, xcolor = xcolors; | ||
| |||
| |||
474 | i < ncolors; i++, i2++, color++, xcolor++, pixels++) { | ||
| |||
| |||
475 | |||
476 | if (!(s = color->string = (char *) XpmMalloc(cpp + 1)malloc((cpp + 1)))) { | ||
| |||
| |||
477 | XpmFree(xcolors)free(xcolors); | ||
478 | return (XpmNoMemory-3); | ||
479 | } | ||
480 | *s++ = printable[c = i2 % MAXPRINTABLE92]; | ||
481 | for (j = 1; j < cpp; j++, s++) | ||
| |||
| |||
482 | *s = printable[c = ((i2 - c) / MAXPRINTABLE92) % MAXPRINTABLE92]; | ||
483 | *s = '\0'; | ||
484 | |||
485 | xcolor->pixel = *pixels; | ||
486 | } | ||
487 | XQueryColors(display, colormap, xcolors, ncolors); | ||
488 | |||
489 | #ifndef FOR_MSW | ||
490 | /* read the rgb file if any was specified */ | ||
491 | if (rgb_fname) | ||
| |||
492 | rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn); | ||
493 | #else | ||
494 | /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */ | ||
495 | rgbn_max = xpmReadRgbNames(NULL((void*)0), NULL((void*)0)); | ||
496 | #endif | ||
497 | |||
498 | if (attributes && attributes->valuemask & XpmColorTable(1L<<15)) { | ||
| |||
499 | colorTable = attributes->colorTable; | ||
500 | ancolors = attributes->ncolors; | ||
501 | apixels = attributes->pixels; | ||
502 | mask_pixel = attributes->mask_pixel; | ||
503 | } | ||
504 | /* 3.2 backward compatibility code */ | ||
505 | else if (attributes && attributes->valuemask & XpmInfos(1L<<8)) { | ||
| |||
506 | oldColorTable = (XpmColor **) attributes->colorTable; | ||
507 | ancolors = attributes->ncolors; | ||
508 | apixels = attributes->pixels; | ||
509 | mask_pixel = attributes->mask_pixel; | ||
510 | } | ||
511 | /* end 3.2 bc */ | ||
512 | |||
513 | for (i = 0, color = colors, xcolor = xcolors; i < ncolors; | ||
| |||
514 | i++, color++, xcolor++) { | ||
515 | |||
516 | /* look for related info from the attributes if any */ | ||
517 | found = False0; | ||
518 | if (ancolors) { | ||
| |||
| |||
519 | unsigned int offset = 0; | ||
520 | |||
521 | for (j = 0; j < ancolors; j++) { | ||
| |||
522 | if (j == mask_pixel) { | ||
| |||
| |||
523 | offset = 1; | ||
524 | continue; | ||
525 | } | ||
526 | if (apixels[j - offset] == xcolor->pixel) | ||
| |||
527 | break; | ||
| |||
528 | } | ||
529 | if (j != ancolors) { | ||
| |||
530 | unsigned int key; | ||
531 | char **defaults = (char **) color; | ||
532 | char **adefaults; | ||
533 | |||
534 | /* 3.2 backward compatibility code */ | ||
535 | if (oldColorTable) | ||
| |||
| |||
536 | adefaults = (char **) oldColorTable[j]; | ||
537 | else | ||
538 | /* end 3.2 bc */ | ||
539 | adefaults = (char **) (colorTable + j); | ||
540 | |||
541 | found = True1; | ||
542 | for (key = 1; key <= NKEYS5; key++) { | ||
| |||
543 | if ((s = adefaults[key])) | ||
| |||
544 | defaults[key] = (char *) xpmstrdupstrdup(s); | ||
545 | } | ||
546 | } | ||
547 | } | ||
548 | if (!found) { | ||
549 | /* if nothing found look for a color name */ | ||
550 | colorname = NULL((void*)0); | ||
551 | if (rgbn_max) | ||
552 | colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red, | ||
553 | xcolor->green, xcolor->blue); | ||
554 | if (colorname) | ||
555 | color->c_color = (char *) xpmstrdupstrdup(colorname); | ||
556 | else { | ||
557 | /* at last store the rgb value */ | ||
558 | char buf[BUFSIZ8192]; | ||
559 | #ifndef FOR_MSW | ||
560 | sprintf(buf, "#%04X%04X%04X", | ||
561 | xcolor->red, xcolor->green, xcolor->blue); | ||
562 | #else | ||
563 | sprintf(buf, "#%02x%02x%02x", | ||
564 | xcolor->red, xcolor->green, xcolor->blue); | ||
565 | #endif | ||
566 | color->c_color = (char *) xpmstrdupstrdup(buf); | ||
567 | } | ||
568 | if (!color->c_color) { | ||
569 | XpmFree(xcolors)free(xcolors); | ||
570 | xpmFreeRgbNames(rgbn, rgbn_max); | ||
571 | return (XpmNoMemory-3); | ||
572 | } | ||
573 | } | ||
574 | } | ||
575 | |||
576 | XpmFree(xcolors)free(xcolors); | ||
577 | xpmFreeRgbNames(rgbn, rgbn_max); | ||
578 | return (XpmSuccess0); | ||
579 | } | ||
580 | |||
581 | #ifndef FOR_MSW | ||
582 | # ifndef AMIGA | ||
583 | /* | ||
584 | * The functions below are written from X11R5 MIT's code (XImUtil.c) | ||
585 | * | ||
586 | * The idea is to have faster functions than the standard XGetPixel function | ||
587 | * to scan the image data. Indeed we can speed up things by suppressing tests | ||
588 | * performed for each pixel. We do exactly the same tests but at the image | ||
589 | * level. | ||
590 | */ | ||
591 | |||
592 | static unsigned long const low_bits_table[] = { | ||
593 | 0x00000000, 0x00000001, 0x00000003, 0x00000007, | ||
594 | 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, | ||
595 | 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, | ||
596 | 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, | ||
597 | 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, | ||
598 | 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, | ||
599 | 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, | ||
600 | 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, | ||
601 | 0xffffffff | ||
602 | }; | ||
603 | |||
604 | /* | ||
605 | * Default method to scan pixels of an image data structure. | ||
606 | * The algorithm used is: | ||
607 | * | ||
608 | * copy the source bitmap_unit or Zpixel into temp | ||
609 | * normalize temp if needed | ||
610 | * extract the pixel bits into return value | ||
611 | * | ||
612 | */ | ||
613 | |||
614 | static int | ||
615 | GetImagePixels( | ||
616 | XImage *image, | ||
617 | unsigned int width, | ||
618 | unsigned int height, | ||
619 | PixelsMap *pmap) | ||
620 | { | ||
621 | char *src; | ||
622 | char *dst; | ||
623 | unsigned int *iptr; | ||
624 | char *data; | ||
625 | unsigned int x, y; | ||
626 | int bits, depth, ibu, ibpp, offset, i; | ||
627 | unsigned long lbt; | ||
628 | Pixel pixel, px; | ||
629 | |||
630 | data = image->data; | ||
631 | iptr = pmap->pixelindex; | ||
632 | depth = image->depth; | ||
633 | lbt = low_bits_table[depth]; | ||
634 | ibpp = image->bits_per_pixel; | ||
635 | offset = image->xoffset; | ||
636 | |||
637 | if (image->bitmap_unit < 0) | ||
638 | return (XpmNoMemory-3); | ||
639 | |||
640 | if ((image->bits_per_pixel | image->depth) == 1) { | ||
641 | ibu = image->bitmap_unit; | ||
642 | for (y = 0; y < height; y++) | ||
643 | for (x = 0; x < width; x++, iptr++) { | ||
644 | src = &data[XYINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) + image->xoffset) / image->bitmap_unit) * (image->bitmap_unit >> 3 )]; | ||
645 | dst = (char *) &pixel; | ||
646 | pixel = 0; | ||
647 | for (i = ibu >> 3; --i >= 0;) | ||
648 | *dst++ = *src++; | ||
649 | XYNORMALIZE(&pixel, image)if ((image->byte_order == 1) || (image->bitmap_bit_order == 1)) xpm_xynormalizeimagebits((unsigned char *)(&pixel ), image); | ||
650 | bits = (x + offset) % ibu; | ||
651 | pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; | ||
652 | if (ibpp != depth) | ||
653 | pixel &= lbt; | ||
654 | if (storePixel(pixel, pmap, iptr)) | ||
655 | return (XpmNoMemory-3); | ||
656 | } | ||
657 | } else if (image->format == XYPixmap1) { | ||
658 | int nbytes, bpl, j; | ||
659 | long plane = 0; | ||
660 | ibu = image->bitmap_unit; | ||
661 | nbytes = ibu >> 3; | ||
662 | bpl = image->bytes_per_line; | ||
663 | for (y = 0; y < height; y++) | ||
664 | for (x = 0; x < width; x++, iptr++) { | ||
665 | pixel = 0; | ||
666 | plane = 0; | ||
667 | for (i = depth; --i >= 0;) { | ||
668 | src = &data[XYINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) + image->xoffset) / image->bitmap_unit) * (image->bitmap_unit >> 3 ) + plane]; | ||
669 | dst = (char *) &px; | ||
670 | px = 0; | ||
671 | for (j = nbytes; --j >= 0;) | ||
672 | *dst++ = *src++; | ||
673 | XYNORMALIZE(&px, image)if ((image->byte_order == 1) || (image->bitmap_bit_order == 1)) xpm_xynormalizeimagebits((unsigned char *)(&px), image ); | ||
674 | bits = (x + offset) % ibu; | ||
675 | pixel = (pixel << 1) | | ||
676 | (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1); | ||
677 | plane = plane + (bpl * height); | ||
678 | } | ||
679 | if (ibpp != depth) | ||
680 | pixel &= lbt; | ||
681 | if (storePixel(pixel, pmap, iptr)) | ||
682 | return (XpmNoMemory-3); | ||
683 | } | ||
684 | } else if (image->format == ZPixmap2) { | ||
685 | for (y = 0; y < height; y++) | ||
686 | for (x = 0; x < width; x++, iptr++) { | ||
687 | src = &data[ZINDEX(x, y, image)((y) * image->bytes_per_line) + (((x) * image->bits_per_pixel ) >> 3)]; | ||
688 | dst = (char *) &px; | ||
689 | px = 0; | ||
690 | for (i = (ibpp + 7) >> 3; --i >= 0;) | ||
691 | *dst++ = *src++; | ||
692 | ZNORMALIZE(&px, image)if (image->byte_order == 1) xpm_znormalizeimagebits((unsigned char *)(&px), image); | ||
693 | pixel = 0; | ||
694 | for (i = sizeof(unsigned long); --i >= 0;) | ||
695 | pixel = (pixel << 8) | ((unsigned char *) &px)[i]; | ||
696 | if (ibpp == 4) { | ||
697 | if (x & 1) | ||
698 | pixel >>= 4; | ||
699 | else | ||
700 | pixel &= 0xf; | ||
701 | } | ||
702 | if (ibpp != depth) | ||
703 | pixel &= lbt; | ||
704 | if (storePixel(pixel, pmap, iptr)) | ||
705 | return (XpmNoMemory-3); | ||
706 | } | ||
707 | } else | ||
708 | return (XpmColorError1); /* actually a bad image */ | ||
709 | return (XpmSuccess0); | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * scan pixels of a 32-bits Z image data structure | ||
714 | */ | ||
715 | |||
716 | #if !defined(WORD64) && !defined(LONG64) | ||
717 | static unsigned long byteorderpixel = MSBFirst1 << 24; | ||
718 | #endif | ||
719 | |||
720 | static int | ||
721 | GetImagePixels32( | ||
722 | XImage *image, | ||
723 | unsigned int width, | ||
724 | unsigned int height, | ||
725 | PixelsMap *pmap) | ||
726 | { | ||
727 | unsigned char *addr; | ||
728 | unsigned char *data; | ||
729 | unsigned int *iptr; | ||
730 | unsigned int x, y; | ||
731 | unsigned long lbt; | ||
732 | Pixel pixel; | ||
733 | int depth; | ||
734 | |||
735 | data = (unsigned char *) image->data; | ||
736 | iptr = pmap->pixelindex; | ||
737 | depth = image->depth; | ||
738 | lbt = low_bits_table[depth]; | ||
739 | #if !defined(WORD64) && !defined(LONG64) | ||
740 | if (*((char *) &byteorderpixel) == image->byte_order) { | ||
741 | for (y = 0; y < height; y++) | ||
742 | for (x = 0; x < width; x++, iptr++) { | ||
743 | addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)]; | ||
744 | pixel = *((unsigned long *) addr); | ||
745 | if (depth != 32) | ||
746 | pixel &= lbt; | ||
747 | if (storePixel(pixel, pmap, iptr)) | ||
748 | return (XpmNoMemory-3); | ||
749 | } | ||
750 | } else | ||
751 | #endif | ||
752 | if (image->byte_order == MSBFirst1) | ||
753 | for (y = 0; y < height; y++) | ||
754 | for (x = 0; x < width; x++, iptr++) { | ||
755 | addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)]; | ||
756 | pixel = ((unsigned long) addr[0] << 24 | | ||
757 | (unsigned long) addr[1] << 16 | | ||
758 | (unsigned long) addr[2] << 8 | | ||
759 | addr[3]); | ||
760 | if (depth != 32) | ||
761 | pixel &= lbt; | ||
762 | if (storePixel(pixel, pmap, iptr)) | ||
763 | return (XpmNoMemory-3); | ||
764 | } | ||
765 | else | ||
766 | for (y = 0; y < height; y++) | ||
767 | for (x = 0; x < width; x++, iptr++) { | ||
768 | addr = &data[ZINDEX32(x, y, image)((y) * image->bytes_per_line) + ((x) << 2)]; | ||
769 | pixel = (addr[0] | | ||
770 | (unsigned long) addr[1] << 8 | | ||
771 | (unsigned long) addr[2] << 16 | | ||
772 | (unsigned long) addr[3] << 24); | ||
773 | if (depth != 32) | ||
774 | pixel &= lbt; | ||
775 | if (storePixel(pixel, pmap, iptr)) | ||
776 | return (XpmNoMemory-3); | ||
777 | } | ||
778 | return (XpmSuccess0); | ||
779 | } | ||
780 | |||
781 | /* | ||
782 | * scan pixels of a 16-bits Z image data structure | ||
783 | */ | ||
784 | |||
785 | static int | ||
786 | GetImagePixels16( | ||
787 | XImage *image, | ||
788 | unsigned int width, | ||
789 | unsigned int height, | ||
790 | PixelsMap *pmap) | ||
791 | { | ||
792 | unsigned char *addr; | ||
793 | unsigned char *data; | ||
794 | unsigned int *iptr; | ||
795 | unsigned int x, y; | ||
796 | unsigned long lbt; | ||
797 | Pixel pixel; | ||
798 | int depth; | ||
799 | |||
800 | data = (unsigned char *) image->data; | ||
801 | iptr = pmap->pixelindex; | ||
802 | depth = image->depth; | ||
803 | lbt = low_bits_table[depth]; | ||
804 | if (image->byte_order == MSBFirst1) | ||
805 | for (y = 0; y < height; y++) | ||
806 | for (x = 0; x < width; x++, iptr++) { | ||
807 | addr = &data[ZINDEX16(x, y, image)((y) * image->bytes_per_line) + ((x) << 1)]; | ||
808 | pixel = addr[0] << 8 | addr[1]; | ||
809 | if (depth != 16) | ||
810 | pixel &= lbt; | ||
811 | if (storePixel(pixel, pmap, iptr)) | ||
812 | return (XpmNoMemory-3); | ||
813 | } | ||
814 | else | ||
815 | for (y = 0; y < height; y++) | ||
816 | for (x = 0; x < width; x++, iptr++) { | ||
817 | addr = &data[ZINDEX16(x, y, image)((y) * image->bytes_per_line) + ((x) << 1)]; | ||
818 | pixel = addr[0] | addr[1] << 8; | ||
819 | if (depth != 16) | ||
820 | pixel &= lbt; | ||
821 | if (storePixel(pixel, pmap, iptr)) | ||
822 | return (XpmNoMemory-3); | ||
823 | } | ||
824 | return (XpmSuccess0); | ||
825 | } | ||
826 | |||
827 | /* | ||
828 | * scan pixels of a 8-bits Z image data structure | ||
829 | */ | ||
830 | |||
831 | static int | ||
832 | GetImagePixels8( | ||
833 | XImage *image, | ||
834 | unsigned int width, | ||
835 | unsigned int height, | ||
836 | PixelsMap *pmap) | ||
837 | { | ||
838 | unsigned int *iptr; | ||
839 | unsigned char *data; | ||
840 | unsigned int x, y; | ||
841 | unsigned long lbt; | ||
842 | Pixel pixel; | ||
843 | int depth; | ||
844 | |||
845 | data = (unsigned char *) image->data; | ||
846 | iptr = pmap->pixelindex; | ||
847 | depth = image->depth; | ||
848 | lbt = low_bits_table[depth]; | ||
849 | for (y = 0; y < height; y++) | ||
850 | for (x = 0; x < width; x++, iptr++) { | ||
851 | pixel = data[ZINDEX8(x, y, image)((y) * image->bytes_per_line) + (x)]; | ||
852 | if (depth != 8) | ||
853 | pixel &= lbt; | ||
854 | if (storePixel(pixel, pmap, iptr)) | ||
855 | return (XpmNoMemory-3); | ||
856 | } | ||
857 | return (XpmSuccess0); | ||
858 | } | ||
859 | |||
860 | /* | ||
861 | * scan pixels of a 1-bit depth Z image data structure | ||
862 | */ | ||
863 | |||
864 | static int | ||
865 | GetImagePixels1( | ||
866 | XImage *image, | ||
867 | unsigned int width, | ||
868 | unsigned int height, | ||
869 | PixelsMap *pmap, | ||
870 | storeFuncPtr storeFunc) | ||
871 | { | ||
872 | unsigned int *iptr; | ||
873 | unsigned int x, y; | ||
874 | char *data; | ||
875 | Pixel pixel; | ||
876 | int xoff, yoff, offset, bpl; | ||
877 | |||
878 | data = image->data; | ||
879 | iptr = pmap->pixelindex; | ||
880 | offset = image->xoffset; | ||
881 | bpl = image->bytes_per_line; | ||
882 | |||
883 | if (image->bitmap_bit_order == MSBFirst1) | ||
884 | for (y = 0; y < height; y++) | ||
885 | for (x = 0; x < width; x++, iptr++) { | ||
886 | xoff = x + offset; | ||
887 | yoff = y * bpl + (xoff >> 3); | ||
888 | xoff &= 7; | ||
889 | pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0; | ||
890 | if ((*storeFunc) (pixel, pmap, iptr)) | ||
891 | return (XpmNoMemory-3); | ||
892 | } | ||
893 | else | ||
894 | for (y = 0; y < height; y++) | ||
895 | for (x = 0; x < width; x++, iptr++) { | ||
896 | xoff = x + offset; | ||
897 | yoff = y * bpl + (xoff >> 3); | ||
898 | xoff &= 7; | ||
899 | pixel = (data[yoff] & (1 << xoff)) ? 1 : 0; | ||
900 | if ((*storeFunc) (pixel, pmap, iptr)) | ||
901 | return (XpmNoMemory-3); | ||
902 | } | ||
903 | return (XpmSuccess0); | ||
904 | } | ||
905 | |||
906 | # else /* AMIGA */ | ||
907 | |||
908 | #define CLEAN_UP(status) \ | ||
909 | do {\ | ||
910 | if (pixels) XpmFree (pixels)free(pixels);\ | ||
911 | if (tmp_img) FreeXImage (tmp_img);\ | ||
912 | return (status);\ | ||
913 | } while(0) | ||
914 | |||
915 | static int | ||
916 | AGetImagePixels ( | ||
917 | XImage *image, | ||
918 | unsigned int width, | ||
919 | unsigned int height, | ||
920 | PixelsMap *pmap, | ||
921 | int (*storeFunc) (Pixel, PixelsMap *, unsigned int *)) | ||
922 | { | ||
923 | unsigned int *iptr; | ||
924 | unsigned int x, y; | ||
925 | unsigned char *pixels; | ||
926 | XImage *tmp_img; | ||
927 | |||
928 | pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels))malloc(((((width+15)>>4)<<4)*sizeof (*pixels))); | ||
929 | if (pixels == NULL((void*)0)) | ||
930 | return XpmNoMemory-3; | ||
931 | |||
932 | tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth); | ||
933 | if (tmp_img == NULL((void*)0)) | ||
934 | CLEAN_UP (XpmNoMemory-3); | ||
935 | |||
936 | iptr = pmap->pixelindex; | ||
937 | for (y = 0; y < height; ++y) | ||
938 | { | ||
939 | ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp); | ||
940 | for (x = 0; x < width; ++x, ++iptr) | ||
941 | { | ||
942 | if ((*storeFunc) (pixels[x], pmap, iptr)) | ||
943 | CLEAN_UP (XpmNoMemory-3); | ||
944 | } | ||
945 | } | ||
946 | |||
947 | CLEAN_UP (XpmSuccess0); | ||
948 | } | ||
949 | |||
950 | #undef CLEAN_UP | ||
951 | |||
952 | # endif/* AMIGA */ | ||
953 | #else /* ndef FOR_MSW */ | ||
954 | static int | ||
955 | MSWGetImagePixels( | ||
956 | Display *display, | ||
957 | XImage *image, | ||
958 | unsigned int width, | ||
959 | unsigned int height, | ||
960 | PixelsMap *pmap, | ||
961 | int (*storeFunc) (Pixel, PixelsMap*, unsigned int *)) | ||
962 | { | ||
963 | unsigned int *iptr; | ||
964 | unsigned int x, y; | ||
965 | Pixel pixel; | ||
966 | |||
967 | iptr = pmap->pixelindex; | ||
968 | |||
969 | SelectObject(*display, image->bitmap); | ||
970 | for (y = 0; y < height; y++) { | ||
971 | for (x = 0; x < width; x++, iptr++) { | ||
972 | pixel = GetPixel(*display, x, y); | ||
973 | if ((*storeFunc) (pixel, pmap, iptr)) | ||
974 | return (XpmNoMemory-3); | ||
975 | } | ||
976 | } | ||
977 | return (XpmSuccess0); | ||
978 | } | ||
979 | |||
980 | #endif | ||
981 | |||
982 | #ifndef FOR_MSW | ||
983 | # ifndef AMIGA | ||
984 | int | ||
985 | XpmCreateXpmImageFromPixmap( | ||
986 | Display *display, | ||
987 | Pixmap pixmap, | ||
988 | Pixmap shapemask, | ||
989 | XpmImage *xpmimage, | ||
990 | XpmAttributes *attributes) | ||
991 | { | ||
992 | XImage *ximage = NULL((void*)0); | ||
993 | XImage *shapeimage = NULL((void*)0); | ||
994 | unsigned int width = 0; | ||
995 | unsigned int height = 0; | ||
996 | int ErrorStatus; | ||
997 | |||
998 | /* get geometry */ | ||
999 | if (attributes && attributes->valuemask & XpmSize(1L<<3)) { | ||
1000 | width = attributes->width; | ||
1001 | height = attributes->height; | ||
1002 | } | ||
1003 | /* get the ximages */ | ||
1004 | if (pixmap) | ||
1005 | xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); | ||
1006 | if (shapemask) | ||
1007 | xpmCreateImageFromPixmap(display, shapemask, &shapeimage, | ||
1008 | &width, &height); | ||
1009 | |||
1010 | /* create the related XpmImage */ | ||
1011 | ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage, | ||
1012 | xpmimage, attributes); | ||
1013 | |||
1014 | /* destroy the ximages */ | ||
1015 | if (ximage) | ||
1016 | XDestroyImage(ximage)((*((ximage)->f.destroy_image))((ximage))); | ||
1017 | if (shapeimage) | ||
1018 | XDestroyImage(shapeimage)((*((shapeimage)->f.destroy_image))((shapeimage))); | ||
1019 | |||
1020 | return (ErrorStatus); | ||
1021 | } | ||
1022 | |||
1023 | # endif/* not AMIGA */ | ||
1024 | #endif /* ndef FOR_MSW */ |