File: | scan.c |
Location: | line 316, column 31 |
Description: | Call to 'calloc' has an allocation size of 0 bytes |
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 */ |