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