Bug Summary

File:scan.c
Location:line 243, column 19
Description:Call to 'calloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2 * Copyright (C) 1989-95 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26/*****************************************************************************\
27* 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
56static const char *printable =
57" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
58ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
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
67typedef 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
75LFUNC(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
78LFUNC(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
81typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap,
82 unsigned int *index_return);
83
84#ifndef FOR_MSW
85# ifndef AMIGA
86LFUNC(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
89LFUNC(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
92LFUNC(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
95LFUNC(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
98LFUNC(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 */
102LFUNC(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 */
107LFUNC(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
111LFUNC(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
114LFUNC(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 */
123static int
124storePixel(
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
158static int
159storeMaskPixel(
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) \
179do { \
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 */
188int
189XpmCreateXpmImageFromImage(
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) {
1
Assuming 'image' is null
2
Taking false branch
221 width = image->width;
222 height = image->height;
223 } else if (shapeimage) {
3
Assuming 'shapeimage' is null
4
Taking false branch
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)
5
Taking false branch
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) ||
6
Taking false branch
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)));
7
Within the expansion of the macro 'XpmCalloc':
a
Call to 'calloc' has an allocation size of 0 bytes
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 */
352error:
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
363static int
364ScanTransparentColor(
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
419static int
420ScanOtherColors(
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
592static 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
614static int
615GetImagePixels(
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)
717static unsigned long byteorderpixel = MSBFirst1 << 24;
718#endif
719
720static int
721GetImagePixels32(
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
785static int
786GetImagePixels16(
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
831static int
832GetImagePixels8(
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
864static int
865GetImagePixels1(
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) \
909do {\
910 if (pixels) XpmFree (pixels)free(pixels);\
911 if (tmp_img) FreeXImage (tmp_img);\
912 return (status);\
913} while(0)
914
915static int
916AGetImagePixels (
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 */
954static int
955MSWGetImagePixels(
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
984int
985XpmCreateXpmImageFromPixmap(
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 */