]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/scan.c
Using P.Getchar(i) instead of p[i]
[wxWidgets.git] / src / xpm / scan.c
1 /*
2 * Copyright (C) 1989-94 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 #include "xpm34p.h"
41
42 #define MAXPRINTABLE 92 /* number of printable ascii chars
43 * minus \ and " for string compat
44 * and ? to avoid ANSI trigraphs. */
45
46 static char *printable =
47 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
48 ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
49
50 /*
51 * printable begin with a space, so in most case, due to my algorithm, when
52 * the number of different colors is less than MAXPRINTABLE, it will give a
53 * char follow by "nothing" (a space) in the readable xpm file
54 */
55
56
57 typedef struct {
58 Pixel *pixels;
59 unsigned int *pixelindex;
60 unsigned int size;
61 unsigned int ncolors;
62 unsigned int mask_pixel; /* whether there is or not */
63 } PixelsMap;
64
65 LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
66 unsigned int *index_return));
67
68 LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
69 unsigned int *index_return));
70
71 #ifndef FOR_MSW
72 LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
73 unsigned int height, PixelsMap *pmap));
74
75 LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
76 unsigned int height, PixelsMap *pmap));
77
78 LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
79 unsigned int height, PixelsMap *pmap));
80
81 LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
82 unsigned int height, PixelsMap *pmap));
83
84 LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
85 unsigned int height, PixelsMap *pmap,
86 int (*storeFunc) (Pixel,PixelsMap*,
87 unsigned int*)));
88
89 /*
90 int (*storeFunc) ()));
91 */
92
93 #else /* ndef FOR_MSW */
94 LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
95 unsigned int height, PixelsMap *pmap));
96 #endif
97 LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
98 XpmAttributes *attributes));
99
100 LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
101 Pixel *pixels, unsigned int mask,
102 unsigned int cpp, XpmAttributes *attributes));
103
104 /*
105 * This function stores the given pixel in the given arrays which are grown
106 * if not large enough.
107 */
108 static int
109 storePixel(Pixel pixel, PixelsMap *pmap, unsigned int *index_return)
110 {
111 unsigned int i;
112 Pixel *p;
113 unsigned int ncolors;
114
115 if (*index_return) { /* this is a transparent pixel! */
116 *index_return = 0;
117 return 0;
118 }
119 ncolors = pmap->ncolors;
120 p = pmap->pixels + pmap->mask_pixel;
121 for (i = pmap->mask_pixel; i < ncolors; i++, p++)
122 if (*p == pixel)
123 break;
124 if (i == ncolors) {
125 if (ncolors >= pmap->size) {
126 pmap->size *= 2;
127 p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
128 if (!p)
129 return (1);
130 pmap->pixels = p;
131
132 }
133 (pmap->pixels)[ncolors] = pixel;
134 pmap->ncolors++;
135 }
136 *index_return = i;
137 return 0;
138 }
139
140 static int
141 storeMaskPixel(Pixel pixel, PixelsMap *pmap, unsigned int *index_return)
142 {
143 if (!pixel) {
144 if (!pmap->ncolors) {
145 pmap->ncolors = 1;
146 (pmap->pixels)[0] = 0;
147 pmap->mask_pixel = 1;
148 }
149 *index_return = 1;
150 } else
151 *index_return = 0;
152 return 0;
153 }
154
155 /* function call in case of error, frees only locally allocated variables */
156 #undef RETURN
157 #define RETURN(status) \
158 { \
159 if (pmap.pixelindex) XpmFree(pmap.pixelindex); \
160 if (pmap.pixels) XpmFree(pmap.pixels); \
161 if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \
162 return(status); \
163 }
164
165 /*
166 * This function scans the given image and stores the found informations in
167 * the given XpmImage structure.
168 */
169 int
170 XpmCreateXpmImageFromImage(Display *display, XImage *image, XImage *shapeimage,
171 XpmImage *xpmimage, XpmAttributes *attributes)
172 {
173 /* variables stored in the XpmAttributes structure */
174 unsigned int cpp;
175
176 /* variables to return */
177 PixelsMap pmap;
178 XpmColor *colorTable = NULL;
179 int ErrorStatus;
180
181 /* calculation variables */
182 unsigned int width = 0;
183 unsigned int height = 0;
184 unsigned int cppm; /* minimum chars per pixel */
185 unsigned int c;
186 unsigned int offset;
187
188 /* initialize pmap */
189 pmap.pixels = NULL;
190 pmap.pixelindex = NULL;
191 pmap.size = 256; /* should be enough most of the time */
192 pmap.ncolors = 0;
193 pmap.mask_pixel = 0;
194
195 /*
196 * get geometry
197 */
198 if (image) {
199 width = image->width;
200 height = image->height;
201 } else if (shapeimage) {
202 width = shapeimage->width;
203 height = shapeimage->height;
204 }
205
206 /*
207 * retrieve information from the XpmAttributes
208 */
209 if (attributes && (attributes->valuemask & XpmCharsPerPixel
210 /* 3.2 backward compatibility code */
211 || attributes->valuemask & XpmInfos))
212 /* end 3.2 bc */
213 cpp = attributes->cpp;
214 else
215 cpp = 0;
216
217 pmap.pixelindex =
218 (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
219 if (!pmap.pixelindex)
220 RETURN(XpmNoMemory);
221
222 pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
223 if (!pmap.pixels)
224 RETURN(XpmNoMemory);
225
226 /*
227 * scan shape mask if any
228 */
229 if (shapeimage) {
230 #ifndef FOR_MSW
231 ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
232 storeMaskPixel);
233 #else
234 ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
235 &pmap);
236 #endif
237 if (ErrorStatus != XpmSuccess)
238 RETURN(ErrorStatus);
239 }
240
241 /*
242 * scan the image data
243 *
244 * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
245 * functions, otherwise use slower but sure general one.
246 *
247 */
248
249 if (image) {
250 #ifndef FOR_MSW
251 if (image->depth == 1)
252 ErrorStatus = GetImagePixels1(image, width, height, &pmap,
253 storePixel);
254 else if (image->bits_per_pixel == 8)
255 ErrorStatus = GetImagePixels8(image, width, height, &pmap);
256 else if (image->bits_per_pixel == 16)
257 ErrorStatus = GetImagePixels16(image, width, height, &pmap);
258 else if (image->bits_per_pixel == 32)
259 ErrorStatus = GetImagePixels32(image, width, height, &pmap);
260 else
261 ErrorStatus = GetImagePixels(image, width, height, &pmap);
262 #else /* FOR_MSW */
263 ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap);
264 #endif
265 if (ErrorStatus != XpmSuccess)
266 RETURN(ErrorStatus);
267 }
268
269 /*
270 * get rgb values and a string of char, and possibly a name for each
271 * color
272 */
273
274 colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
275 if (!colorTable)
276 RETURN(XpmNoMemory);
277
278 /* compute the minimal cpp */
279 for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
280 c *= MAXPRINTABLE;
281 if (cpp < cppm)
282 cpp = cppm;
283
284 if (pmap.mask_pixel) {
285 ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
286 if (ErrorStatus != XpmSuccess)
287 RETURN(ErrorStatus);
288 offset = 1;
289 } else
290 offset = 0;
291
292 ErrorStatus = ScanOtherColors(display, colorTable + offset,
293 pmap.ncolors - offset, pmap.pixels + offset,
294 pmap.mask_pixel, cpp, attributes);
295 if (ErrorStatus != XpmSuccess)
296 RETURN(ErrorStatus);
297
298 /*
299 * store found informations in the XpmImage structure
300 */
301 xpmimage->width = width;
302 xpmimage->height = height;
303 xpmimage->cpp = cpp;
304 xpmimage->ncolors = pmap.ncolors;
305 xpmimage->colorTable = colorTable;
306 xpmimage->data = pmap.pixelindex;
307
308 XpmFree(pmap.pixels);
309 return (XpmSuccess);
310 }
311
312 static int
313 ScanTransparentColor(XpmColor *color, unsigned int cpp, XpmAttributes *attributes)
314 {
315 char *s;
316 unsigned int a, b, c;
317
318 /* first get a character string */
319 a = 0;
320 if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
321 return (XpmNoMemory);
322 *s++ = printable[c = a % MAXPRINTABLE];
323 for (b = 1; b < cpp; b++, s++)
324 *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
325 *s = '\0';
326
327 /* then retreive related info from the attributes if any */
328 if (attributes && attributes->mask_pixel != XpmUndefPixel && (
329 /* 3.2 backward compatibility code */
330 attributes->valuemask & XpmInfos ||
331 /* end 3.2 bc */
332 attributes->valuemask & XpmColorTable)) {
333
334 unsigned int key;
335 char **defaults = (char **) color;
336 char **mask_defaults;
337
338 /* 3.2 backward compatibility code */
339 if (attributes->valuemask & XpmInfos)
340 mask_defaults = (char **)
341 ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
342 else
343 /* end 3.2 bc */
344 mask_defaults = (char **) (
345 attributes->colorTable + attributes->mask_pixel);
346 for (key = 1; key <= NKEYS; key++) {
347 if (s = mask_defaults[key]) {
348 defaults[key] = (char *) strdup(s);
349 if (!defaults[key])
350 return (XpmNoMemory);
351 }
352 }
353 } else {
354 color->c_color = (char *) strdup(TRANSPARENT_COLOR);
355 if (!color->c_color)
356 return (XpmNoMemory);
357 }
358 return (XpmSuccess);
359 }
360
361 static int
362 ScanOtherColors(Display *display, XpmColor *colors, int ncolors, Pixel *pixels,
363 unsigned int mask, unsigned int cpp, XpmAttributes *attributes)
364 {
365 /* variables stored in the XpmAttributes structure */
366 Colormap colormap;
367 char *rgb_fname;
368
369 #ifndef FOR_MSW
370 xpmRgbName rgbn[MAX_RGBNAMES];
371 #else
372 xpmRgbName *rgbn = NULL;
373 #endif
374 int rgbn_max = 0;
375 unsigned int i, j, c, i2;
376 XpmColor *color;
377 XColor *xcolors = NULL, *xcolor;
378 char *colorname, *s;
379 XpmColor *colorTable, **oldColorTable = NULL;
380 unsigned int ancolors = 0;
381 Pixel *apixels;
382 unsigned int mask_pixel;
383 int found;
384
385 /* retrieve information from the XpmAttributes */
386 if (attributes && (attributes->valuemask & XpmColormap))
387 colormap = attributes->colormap;
388 else
389 colormap = XDefaultColormap(display, XDefaultScreen(display));
390 if (attributes && (attributes->valuemask & XpmRgbFilename))
391 rgb_fname = attributes->rgb_fname;
392 else
393 rgb_fname = NULL;
394
395 /* first get character strings and rgb values */
396 xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
397 if (!xcolors)
398 return (XpmNoMemory);
399
400 for (i = 0, i2 = (mask ? i + 1 : i), color = colors, xcolor = xcolors;
401 i < (unsigned int)ncolors; i++, i2++, color++, xcolor++, pixels++) {
402
403 if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
404 XpmFree(xcolors);
405 return (XpmNoMemory);
406 }
407 *s++ = printable[c = i2 % MAXPRINTABLE];
408 for (j = 1; j < cpp; j++, s++)
409 *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
410 *s = '\0';
411
412 xcolor->pixel = *pixels;
413 }
414 #if defined(wx_msw) || defined(wx_pm)
415 XQueryColors(display, (Colormap *)colormap, xcolors, ncolors);
416 #else
417 XQueryColors(display, (Colormap)colormap, xcolors, ncolors);
418 #endif
419
420 #ifndef FOR_MSW
421 /* read the rgb file if any was specified */
422 if (rgb_fname)
423 rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
424 #else
425 /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
426 rgbn_max = xpmReadRgbNames(NULL, NULL);
427 #endif
428
429 if (attributes && attributes->valuemask & XpmColorTable) {
430 colorTable = attributes->colorTable;
431 ancolors = attributes->ncolors;
432 apixels = attributes->pixels;
433 mask_pixel = attributes->mask_pixel;
434 }
435 /* 3.2 backward compatibility code */
436 else if (attributes && attributes->valuemask & XpmInfos) {
437 oldColorTable = (XpmColor **) attributes->colorTable;
438 ancolors = attributes->ncolors;
439 apixels = attributes->pixels;
440 mask_pixel = attributes->mask_pixel;
441 }
442 /* end 3.2 bc */
443
444 for (i = 0, color = colors, xcolor = xcolors; i < (unsigned int)ncolors;
445 i++, color++, xcolor++) {
446
447 /* look for related info from the attributes if any */
448 found = False;
449 if (ancolors) {
450 unsigned int offset = 0;
451
452 for (j = 0; j < ancolors; j++) {
453 if (j == mask_pixel) {
454 offset = 1;
455 continue;
456 }
457 if (apixels[j - offset] == xcolor->pixel)
458 break;
459 }
460 if (j != ancolors) {
461 unsigned int key;
462 char **defaults = (char **) color;
463 char **adefaults;
464
465 /* 3.2 backward compatibility code */
466 if (oldColorTable)
467 adefaults = (char **) oldColorTable[j];
468 else
469 /* end 3.2 bc */
470 adefaults = (char **) (colorTable + j);
471
472 found = True;
473 for (key = 1; key <= NKEYS; key++) {
474 if (s = adefaults[key])
475 defaults[key] = (char *) strdup(s);
476 }
477 }
478 }
479 if (!found) {
480 /* if nothing found look for a color name */
481 colorname = NULL;
482 if (rgbn_max)
483 colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
484 xcolor->green, xcolor->blue);
485 if (colorname)
486 color->c_color = (char *) strdup(colorname);
487 else {
488 /* at last store the rgb value */
489 char buf[BUFSIZ];
490 #ifndef FOR_MSW
491 sprintf(buf, "#%04X%04X%04X",
492 xcolor->red, xcolor->green, xcolor->blue);
493 #else
494 sprintf(buf, "#%02x%02x%02x",
495 xcolor->red, xcolor->green, xcolor->blue);
496 #endif
497 color->c_color = (char *) strdup(buf);
498 }
499 if (!color->c_color) {
500 XpmFree(xcolors);
501 xpmFreeRgbNames(rgbn, rgbn_max);
502 return (XpmNoMemory);
503 }
504 }
505 }
506
507 XpmFree(xcolors);
508 xpmFreeRgbNames(rgbn, rgbn_max);
509 return (XpmSuccess);
510 }
511
512 #ifndef FOR_MSW
513 /*
514 * The functions below are written from X11R5 MIT's code (XImUtil.c)
515 *
516 * The idea is to have faster functions than the standard XGetPixel function
517 * to scan the image data. Indeed we can speed up things by suppressing tests
518 * performed for each pixel. We do exactly the same tests but at the image
519 * level. Assuming that we use only ZPixmap images.
520 */
521
522 static unsigned long Const low_bits_table[] = {
523 0x00000000, 0x00000001, 0x00000003, 0x00000007,
524 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
525 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
526 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
527 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
528 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
529 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
530 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
531 0xffffffff
532 };
533
534 /*
535 * Default method to scan pixels of a Z image data structure.
536 * The algorithm used is:
537 *
538 * copy the source bitmap_unit or Zpixel into temp
539 * normalize temp if needed
540 * extract the pixel bits into return value
541 *
542 */
543
544 static int
545 GetImagePixels(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap)
546 {
547 char *src;
548 char *dst;
549 unsigned int *iptr;
550 char *data;
551 int x, y, i;
552 int bits, depth, ibu, ibpp;
553 unsigned long lbt;
554 Pixel pixel, px;
555
556 data = image->data;
557 iptr = pmap->pixelindex;
558 depth = image->depth;
559 lbt = low_bits_table[depth];
560 ibpp = image->bits_per_pixel;
561 if (image->depth == 1) {
562 ibu = image->bitmap_unit;
563 for (y = 0; y < height; y++)
564 for (x = 0; x < width; x++, iptr++) {
565 src = &data[XYINDEX(x, y, image)];
566 dst = (char *) &pixel;
567 pixel = 0;
568 for (i = ibu >> 3; --i >= 0;)
569 *dst++ = *src++;
570 XYNORMALIZE(&pixel, image);
571 bits = x % ibu;
572 pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
573 if (ibpp != depth)
574 pixel &= lbt;
575 if (storePixel(pixel, pmap, iptr))
576 return (XpmNoMemory);
577 }
578 } else {
579 for (y = 0; y < height; y++)
580 for (x = 0; x < width; x++, iptr++) {
581 src = &data[ZINDEX(x, y, image)];
582 dst = (char *) &px;
583 px = 0;
584 for (i = (ibpp + 7) >> 3; --i >= 0;)
585 *dst++ = *src++;
586 ZNORMALIZE(&px, image);
587 pixel = 0;
588 for (i = sizeof(unsigned long); --i >= 0;)
589 pixel = (pixel << 8) | ((unsigned char *) &px)[i];
590 if (ibpp == 4) {
591 if (x & 1)
592 pixel >>= 4;
593 else
594 pixel &= 0xf;
595 }
596 if (ibpp != depth)
597 pixel &= lbt;
598 if (storePixel(pixel, pmap, iptr))
599 return (XpmNoMemory);
600 }
601 }
602 return (XpmSuccess);
603 }
604
605 /*
606 * scan pixels of a 32-bits Z image data structure
607 */
608
609 #ifndef WORD64
610 static unsigned long byteorderpixel = MSBFirst << 24;
611
612 #endif
613
614 static int
615 GetImagePixels32(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap)
616 {
617 unsigned char *addr;
618 unsigned char *data;
619 unsigned int *iptr;
620 int x, y;
621 unsigned long lbt;
622 Pixel pixel;
623 int depth;
624
625 data = (unsigned char *) image->data;
626 iptr = pmap->pixelindex;
627 depth = image->depth;
628 lbt = low_bits_table[depth];
629 #ifndef WORD64
630 if (*((char *) &byteorderpixel) == image->byte_order) {
631 for (y = 0; y < height; y++)
632 for (x = 0; x < width; x++, iptr++) {
633 addr = &data[ZINDEX32(x, y, image)];
634 pixel = *((unsigned long *) addr);
635 if (depth != 32)
636 pixel &= lbt;
637 if (storePixel(pixel, pmap, iptr))
638 return (XpmNoMemory);
639 }
640 } else
641 #endif
642 if (image->byte_order == MSBFirst)
643 for (y = 0; y < height; y++)
644 for (x = 0; x < width; x++, iptr++) {
645 addr = &data[ZINDEX32(x, y, image)];
646 pixel = ((unsigned long) addr[0] << 24 |
647 (unsigned long) addr[1] << 16 |
648 (unsigned long) addr[2] << 8 |
649 addr[4]);
650 if (depth != 32)
651 pixel &= lbt;
652 if (storePixel(pixel, pmap, iptr))
653 return (XpmNoMemory);
654 }
655 else
656 for (y = 0; y < height; y++)
657 for (x = 0; x < width; x++, iptr++) {
658 addr = &data[ZINDEX32(x, y, image)];
659 pixel = (addr[0] |
660 (unsigned long) addr[1] << 8 |
661 (unsigned long) addr[2] << 16 |
662 (unsigned long) addr[3] << 24);
663 if (depth != 32)
664 pixel &= lbt;
665 if (storePixel(pixel, pmap, iptr))
666 return (XpmNoMemory);
667 }
668 return (XpmSuccess);
669 }
670
671 /*
672 * scan pixels of a 16-bits Z image data structure
673 */
674
675 static int
676 GetImagePixels16(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap)
677 {
678 unsigned char *addr;
679 unsigned char *data;
680 unsigned int *iptr;
681 int x, y;
682 unsigned long lbt;
683 Pixel pixel;
684 int depth;
685
686 data = (unsigned char *) image->data;
687 iptr = pmap->pixelindex;
688 depth = image->depth;
689 lbt = low_bits_table[depth];
690 if (image->byte_order == MSBFirst)
691 for (y = 0; y < height; y++)
692 for (x = 0; x < width; x++, iptr++) {
693 addr = &data[ZINDEX16(x, y, image)];
694 pixel = addr[0] << 8 | addr[1];
695 if (depth != 16)
696 pixel &= lbt;
697 if (storePixel(pixel, pmap, iptr))
698 return (XpmNoMemory);
699 }
700 else
701 for (y = 0; y < height; y++)
702 for (x = 0; x < width; x++, iptr++) {
703 addr = &data[ZINDEX16(x, y, image)];
704 pixel = addr[0] | addr[1] << 8;
705 if (depth != 16)
706 pixel &= lbt;
707 if (storePixel(pixel, pmap, iptr))
708 return (XpmNoMemory);
709 }
710 return (XpmSuccess);
711 }
712
713 /*
714 * scan pixels of a 8-bits Z image data structure
715 */
716
717 static int
718 GetImagePixels8(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap)
719 {
720 unsigned int *iptr;
721 unsigned char *data;
722 int x, y;
723 unsigned long lbt;
724 Pixel pixel;
725 int depth;
726
727 data = (unsigned char *) image->data;
728 iptr = pmap->pixelindex;
729 depth = image->depth;
730 lbt = low_bits_table[depth];
731 for (y = 0; y < height; y++)
732 for (x = 0; x < width; x++, iptr++) {
733 pixel = data[ZINDEX8(x, y, image)];
734 if (depth != 8)
735 pixel &= lbt;
736 if (storePixel(pixel, pmap, iptr))
737 return (XpmNoMemory);
738 }
739 return (XpmSuccess);
740 }
741
742 /*
743 * scan pixels of a 1-bit depth Z image data structure
744 */
745
746 static int
747 GetImagePixels1(XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap,
748 /*
749 int (*storeFunc)()
750 */
751 int (*storeFunc)(Pixel,PixelsMap*,unsigned int*)
752 )
753 {
754 unsigned int *iptr;
755 int x, y;
756 char *data;
757 Pixel pixel;
758
759 if (image->byte_order != image->bitmap_bit_order)
760 return (GetImagePixels(image, width, height, pmap));
761 else {
762 data = image->data;
763 iptr = pmap->pixelindex;
764 if (image->bitmap_bit_order == MSBFirst)
765 for (y = 0; y < height; y++)
766 for (x = 0; x < width; x++, iptr++) {
767 pixel = (data[ZINDEX1(x, y, image)] & (0x80 >> (x & 7)))
768 ? 1 : 0;
769 if ((*storeFunc) (pixel, pmap, iptr))
770 return (XpmNoMemory);
771 }
772 else
773 for (y = 0; y < height; y++)
774 for (x = 0; x < width; x++, iptr++) {
775 pixel = (data[ZINDEX1(x, y, image)] & (1 << (x & 7)))
776 ? 1 : 0;
777 if ((*storeFunc) (pixel, pmap, iptr))
778 return (XpmNoMemory);
779 }
780 }
781 return (XpmSuccess);
782 }
783
784 #else /* ndef FOR_MSW */
785 static int
786 MSWGetImagePixels(Display *display, XImage *image, unsigned int width, unsigned int height, PixelsMap *pmap)
787 {
788 unsigned int *iptr;
789 unsigned int x, y;
790 Pixel pixel;
791
792 iptr = pmap->pixelindex;
793
794 for (y = 0; y < height; y++) {
795 #if !defined(__VISAGECPP__) /* fixme for OS/2 */
796 for (x = 0; x < width; x++, iptr++) {
797 /* bitmap must be selected !!! ??? */
798 pixel = GetPixel(*display, x, y);
799 if (storePixel(pixel, pmap, iptr))
800 return (XpmNoMemory);
801 }
802 #endif
803 }
804 return (XpmSuccess);
805 }
806
807 #endif
808
809 #ifndef FOR_MSW
810 int
811 XpmCreateXpmImageFromPixmap(Display *display, Pixmap pixmap, Pixmap shapemask,
812 XpmImage *xpmimage, XpmAttributes *attributes)
813 {
814 XImage *ximage = NULL;
815 XImage *shapeimage = NULL;
816 unsigned int width = 0;
817 unsigned int height = 0;
818 int ErrorStatus;
819
820 /* get geometry */
821 if (attributes && attributes->valuemask & XpmSize) {
822 width = attributes->width;
823 height = attributes->height;
824 }
825 /* get the ximages */
826 if (pixmap)
827 xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
828 if (shapemask)
829 xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
830 &width, &height);
831
832 /* create the related XpmImage */
833 ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
834 xpmimage, attributes);
835
836 /* destroy the ximages */
837 if (ximage)
838 XDestroyImage(ximage);
839 if (shapeimage)
840 XDestroyImage(shapeimage);
841
842 return (ErrorStatus);
843 }
844
845 #endif /* ndef FOR_MSW */