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[BUFSIZ1024]; | |||
559 | #ifndef FOR_MSW | |||
560 | sprintf(buf, "#%04X%04X%04X",__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "#%04X%04X%04X", xcolor->red, xcolor-> green, xcolor->blue) | |||
561 | xcolor->red, xcolor->green, xcolor->blue)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "#%04X%04X%04X", xcolor->red, xcolor-> green, xcolor->blue); | |||
562 | #else | |||
563 | sprintf(buf, "#%02x%02x%02x",__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "#%02x%02x%02x", xcolor->red, xcolor-> green, xcolor->blue) | |||
564 | xcolor->red, xcolor->green, xcolor->blue)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "#%02x%02x%02x", 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 */ |