]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/scan.c
Added comment makeg95.env
[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 #else
321
322 #ifndef __OS2__
323 ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap,
324 storePixel);
325 /* calling convention all messed up OS/2 -- figure out later */
326 #endif
327
328 #endif
329
330 if (ErrorStatus != XpmSuccess)
331 RETURN(ErrorStatus);
332 }
333
334 /*
335 * get rgb values and a string of char, and possibly a name for each
336 * color
337 */
338
339 colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
340 if (!colorTable)
341 RETURN(XpmNoMemory);
342
343 /* compute the minimal cpp */
344 for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
345 c *= MAXPRINTABLE;
346 if (cpp < cppm)
347 cpp = cppm;
348
349 if (pmap.mask_pixel) {
350 ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
351 if (ErrorStatus != XpmSuccess)
352 RETURN(ErrorStatus);
353 }
354
355 ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors,
356 pmap.pixels, pmap.mask_pixel, cpp,
357 attributes);
358 if (ErrorStatus != XpmSuccess)
359 RETURN(ErrorStatus);
360
361 /*
362 * store found informations in the XpmImage structure
363 */
364 xpmimage->width = width;
365 xpmimage->height = height;
366 xpmimage->cpp = cpp;
367 xpmimage->ncolors = pmap.ncolors;
368 xpmimage->colorTable = colorTable;
369 xpmimage->data = pmap.pixelindex;
370
371 XpmFree(pmap.pixels);
372 return (XpmSuccess);
373
374 /* exit point in case of error, free only locally allocated variables */
375 error:
376 if (pmap.pixelindex)
377 XpmFree(pmap.pixelindex);
378 if (pmap.pixels)
379 XpmFree(pmap.pixels);
380 if (colorTable)
381 xpmFreeColorTable(colorTable, pmap.ncolors);
382
383 return (ErrorStatus);
384 }
385
386 #ifdef __OS2__
387 /* Visual Age cannot deal with old, non-ansi, code */
388 static int ScanTransparentColor(XpmColor* color, unsigned int cpp, XpmAttributes* attributes)
389 #else
390 static int
391 ScanTransparentColor(color, cpp, attributes)
392 XpmColor *color;
393 unsigned int cpp;
394 XpmAttributes *attributes;
395 #endif
396 {
397 char *s;
398 unsigned int a, b, c;
399
400 /* first get a character string */
401 a = 0;
402 if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
403 return (XpmNoMemory);
404 *s++ = printable[c = a % MAXPRINTABLE];
405 for (b = 1; b < cpp; b++, s++)
406 *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
407 *s = '\0';
408
409 /* then retreive related info from the attributes if any */
410 if (attributes && (attributes->valuemask & XpmColorTable
411 /* 3.2 backward compatibility code */
412 || attributes->valuemask & XpmInfos)
413 /* end 3.2 bc */
414 && attributes->mask_pixel != XpmUndefPixel) {
415
416 unsigned int key;
417 char **defaults = (char **) color;
418 char **mask_defaults;
419
420 /* 3.2 backward compatibility code */
421 if (attributes->valuemask & XpmColorTable)
422 /* end 3.2 bc */
423 mask_defaults = (char **) (
424 attributes->colorTable + attributes->mask_pixel);
425 /* 3.2 backward compatibility code */
426 else
427 mask_defaults = (char **)
428 ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
429 /* end 3.2 bc */
430 for (key = 1; key <= NKEYS; key++) {
431 if (s = mask_defaults[key]) {
432 defaults[key] = (char *) xpmstrdup(s);
433 if (!defaults[key])
434 return (XpmNoMemory);
435 }
436 }
437 } else {
438 color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR);
439 if (!color->c_color)
440 return (XpmNoMemory);
441 }
442 return (XpmSuccess);
443 }
444
445 #ifdef __OS2__
446 /* Visual Age cannot deal with old, non-ansi, code */
447 static int ScanOtherColors(
448 Display* display
449 , XpmColor* colors
450 , int ncolors
451 , Pixel* pixels
452 , unsigned int mask
453 , unsigned int cpp
454 , XpmAttributes* attributes
455 )
456 #else
457 static int
458 ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
459 Display *display;
460 XpmColor *colors;
461 int ncolors;
462 Pixel *pixels;
463 unsigned int mask;
464 unsigned int cpp;
465 XpmAttributes *attributes;
466 #endif
467 {
468 /* variables stored in the XpmAttributes structure */
469 Colormap colormap;
470 char *rgb_fname;
471
472 #ifndef FOR_MSW
473 xpmRgbName rgbn[MAX_RGBNAMES];
474 #else
475 xpmRgbName *rgbn = NULL;
476 #endif
477 int rgbn_max = 0;
478 unsigned int i, j, c, i2;
479 XpmColor *color;
480 XColor *xcolors = NULL, *xcolor;
481 char *colorname, *s;
482 XpmColor *colorTable, **oldColorTable = NULL;
483 unsigned int ancolors = 0;
484 Pixel *apixels;
485 unsigned int mask_pixel;
486 Bool found;
487
488 /* retrieve information from the XpmAttributes */
489 if (attributes && (attributes->valuemask & XpmColormap))
490 colormap = attributes->colormap;
491 else
492 colormap = XDefaultColormap(display, XDefaultScreen(display));
493 if (attributes && (attributes->valuemask & XpmRgbFilename))
494 rgb_fname = attributes->rgb_fname;
495 else
496 rgb_fname = NULL;
497
498 /* start from the right element */
499 if (mask) {
500 colors++;
501 ncolors--;
502 pixels++;
503 }
504
505 /* first get character strings and rgb values */
506 xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
507 if (!xcolors)
508 return (XpmNoMemory);
509
510 for (i = 0, i2 = mask, color = colors, xcolor = xcolors;
511 i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
512
513 if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
514 XpmFree(xcolors);
515 return (XpmNoMemory);
516 }
517 *s++ = printable[c = i2 % MAXPRINTABLE];
518 for (j = 1; j < cpp; j++, s++)
519 *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
520 *s = '\0';
521
522 xcolor->pixel = *pixels;
523 }
524 #ifdef __OS2__
525 XQueryColors(display, &colormap, xcolors, ncolors);
526 #else
527 XQueryColors(display, colormap, xcolors, ncolors);
528 #endif
529
530 #ifndef FOR_MSW
531 /* read the rgb file if any was specified */
532 if (rgb_fname)
533 rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
534 #else
535 /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
536 rgbn_max = xpmReadRgbNames(NULL, NULL);
537 #endif
538
539 if (attributes && attributes->valuemask & XpmColorTable) {
540 colorTable = attributes->colorTable;
541 ancolors = attributes->ncolors;
542 apixels = attributes->pixels;
543 mask_pixel = attributes->mask_pixel;
544 }
545 /* 3.2 backward compatibility code */
546 else if (attributes && attributes->valuemask & XpmInfos) {
547 oldColorTable = (XpmColor **) attributes->colorTable;
548 ancolors = attributes->ncolors;
549 apixels = attributes->pixels;
550 mask_pixel = attributes->mask_pixel;
551 }
552 /* end 3.2 bc */
553
554 for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
555 i++, color++, xcolor++) {
556
557 /* look for related info from the attributes if any */
558 found = False;
559 if (ancolors) {
560 unsigned int offset = 0;
561
562 for (j = 0; j < ancolors; j++) {
563 if (j == mask_pixel) {
564 offset = 1;
565 continue;
566 }
567 if (apixels[j - offset] == xcolor->pixel)
568 break;
569 }
570 if (j != ancolors) {
571 unsigned int key;
572 char **defaults = (char **) color;
573 char **adefaults;
574
575 /* 3.2 backward compatibility code */
576 if (oldColorTable)
577 adefaults = (char **) oldColorTable[j];
578 else
579 /* end 3.2 bc */
580 adefaults = (char **) (colorTable + j);
581
582 found = True;
583 for (key = 1; key <= NKEYS; key++) {
584 if (s = adefaults[key])
585 defaults[key] = (char *) xpmstrdup(s);
586 }
587 }
588 }
589 if (!found) {
590 /* if nothing found look for a color name */
591 colorname = NULL;
592 if (rgbn_max)
593 colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
594 xcolor->green, xcolor->blue);
595 if (colorname)
596 color->c_color = (char *) xpmstrdup(colorname);
597 else {
598 /* at last store the rgb value */
599 char buf[BUFSIZ];
600 #ifndef FOR_MSW
601 sprintf(buf, "#%04X%04X%04X",
602 xcolor->red, xcolor->green, xcolor->blue);
603 #else
604 sprintf(buf, "#%02x%02x%02x",
605 xcolor->red, xcolor->green, xcolor->blue);
606 #endif
607 color->c_color = (char *) xpmstrdup(buf);
608 }
609 if (!color->c_color) {
610 XpmFree(xcolors);
611 xpmFreeRgbNames(rgbn, rgbn_max);
612 return (XpmNoMemory);
613 }
614 }
615 }
616
617 XpmFree(xcolors);
618 xpmFreeRgbNames(rgbn, rgbn_max);
619 return (XpmSuccess);
620 }
621
622 #ifndef FOR_MSW
623 # ifndef AMIGA
624 /*
625 * The functions below are written from X11R5 MIT's code (XImUtil.c)
626 *
627 * The idea is to have faster functions than the standard XGetPixel function
628 * to scan the image data. Indeed we can speed up things by suppressing tests
629 * performed for each pixel. We do exactly the same tests but at the image
630 * level.
631 */
632
633 static unsigned long Const low_bits_table[] = {
634 0x00000000, 0x00000001, 0x00000003, 0x00000007,
635 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
636 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
637 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
638 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
639 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
640 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
641 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
642 0xffffffff
643 };
644
645 /*
646 * Default method to scan pixels of an image data structure.
647 * The algorithm used is:
648 *
649 * copy the source bitmap_unit or Zpixel into temp
650 * normalize temp if needed
651 * extract the pixel bits into return value
652 *
653 */
654
655 static int
656 GetImagePixels(image, width, height, pmap)
657 XImage *image;
658 unsigned int width;
659 unsigned int height;
660 PixelsMap *pmap;
661 {
662 char *src;
663 char *dst;
664 unsigned int *iptr;
665 char *data;
666 int x, y, i;
667 int bits, depth, ibu, ibpp, offset;
668 unsigned long lbt;
669 Pixel pixel, px;
670
671 data = image->data;
672 iptr = pmap->pixelindex;
673 depth = image->depth;
674 lbt = low_bits_table[depth];
675 ibpp = image->bits_per_pixel;
676 offset = image->xoffset;
677
678 if ((image->bits_per_pixel | image->depth) == 1) {
679 ibu = image->bitmap_unit;
680 for (y = 0; y < height; y++)
681 for (x = 0; x < width; x++, iptr++) {
682 src = &data[XYINDEX(x, y, image)];
683 dst = (char *) &pixel;
684 pixel = 0;
685 for (i = ibu >> 3; --i >= 0;)
686 *dst++ = *src++;
687 XYNORMALIZE(&pixel, image);
688 bits = (x + offset) % ibu;
689 pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
690 if (ibpp != depth)
691 pixel &= lbt;
692 if (storePixel(pixel, pmap, iptr))
693 return (XpmNoMemory);
694 }
695 } else if (image->format == XYPixmap) {
696 int nbytes, bpl, j;
697 long plane = 0;
698 ibu = image->bitmap_unit;
699 nbytes = ibu >> 3;
700 bpl = image->bytes_per_line;
701 for (y = 0; y < height; y++)
702 for (x = 0; x < width; x++, iptr++) {
703 pixel = 0;
704 plane = 0;
705 for (i = depth; --i >= 0;) {
706 src = &data[XYINDEX(x, y, image) + plane];
707 dst = (char *) &px;
708 px = 0;
709 for (j = nbytes; --j >= 0;)
710 *dst++ = *src++;
711 XYNORMALIZE(&px, image);
712 bits = (x + offset) % ibu;
713 pixel = (pixel << 1) |
714 (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1);
715 plane = plane + (bpl * height);
716 }
717 if (ibpp != depth)
718 pixel &= lbt;
719 if (storePixel(pixel, pmap, iptr))
720 return (XpmNoMemory);
721 }
722 } else if (image->format == ZPixmap) {
723 for (y = 0; y < height; y++)
724 for (x = 0; x < width; x++, iptr++) {
725 src = &data[ZINDEX(x, y, image)];
726 dst = (char *) &px;
727 px = 0;
728 for (i = (ibpp + 7) >> 3; --i >= 0;)
729 *dst++ = *src++;
730 ZNORMALIZE(&px, image);
731 pixel = 0;
732 for (i = sizeof(unsigned long); --i >= 0;)
733 pixel = (pixel << 8) | ((unsigned char *) &px)[i];
734 if (ibpp == 4) {
735 if (x & 1)
736 pixel >>= 4;
737 else
738 pixel &= 0xf;
739 }
740 if (ibpp != depth)
741 pixel &= lbt;
742 if (storePixel(pixel, pmap, iptr))
743 return (XpmNoMemory);
744 }
745 } else
746 return (XpmColorError); /* actually a bad image */
747 return (XpmSuccess);
748 }
749
750 /*
751 * scan pixels of a 32-bits Z image data structure
752 */
753
754 #if !defined(WORD64) && !defined(LONG64)
755 static unsigned long byteorderpixel = MSBFirst << 24;
756 #endif
757
758 static int
759 GetImagePixels32(image, width, height, pmap)
760 XImage *image;
761 unsigned int width;
762 unsigned int height;
763 PixelsMap *pmap;
764 {
765 unsigned char *addr;
766 unsigned char *data;
767 unsigned int *iptr;
768 int x, y;
769 unsigned long lbt;
770 Pixel pixel;
771 int depth;
772
773 data = (unsigned char *) image->data;
774 iptr = pmap->pixelindex;
775 depth = image->depth;
776 lbt = low_bits_table[depth];
777 #if !defined(WORD64) && !defined(LONG64)
778 if (*((char *) &byteorderpixel) == image->byte_order) {
779 for (y = 0; y < height; y++)
780 for (x = 0; x < width; x++, iptr++) {
781 addr = &data[ZINDEX32(x, y, image)];
782 pixel = *((unsigned long *) addr);
783 if (depth != 32)
784 pixel &= lbt;
785 if (storePixel(pixel, pmap, iptr))
786 return (XpmNoMemory);
787 }
788 } else
789 #endif
790 if (image->byte_order == MSBFirst)
791 for (y = 0; y < height; y++)
792 for (x = 0; x < width; x++, iptr++) {
793 addr = &data[ZINDEX32(x, y, image)];
794 pixel = ((unsigned long) addr[0] << 24 |
795 (unsigned long) addr[1] << 16 |
796 (unsigned long) addr[2] << 8 |
797 addr[3]);
798 if (depth != 32)
799 pixel &= lbt;
800 if (storePixel(pixel, pmap, iptr))
801 return (XpmNoMemory);
802 }
803 else
804 for (y = 0; y < height; y++)
805 for (x = 0; x < width; x++, iptr++) {
806 addr = &data[ZINDEX32(x, y, image)];
807 pixel = (addr[0] |
808 (unsigned long) addr[1] << 8 |
809 (unsigned long) addr[2] << 16 |
810 (unsigned long) addr[3] << 24);
811 if (depth != 32)
812 pixel &= lbt;
813 if (storePixel(pixel, pmap, iptr))
814 return (XpmNoMemory);
815 }
816 return (XpmSuccess);
817 }
818
819 /*
820 * scan pixels of a 16-bits Z image data structure
821 */
822
823 static int
824 GetImagePixels16(image, width, height, pmap)
825 XImage *image;
826 unsigned int width;
827 unsigned int height;
828 PixelsMap *pmap;
829 {
830 unsigned char *addr;
831 unsigned char *data;
832 unsigned int *iptr;
833 int x, y;
834 unsigned long lbt;
835 Pixel pixel;
836 int depth;
837
838 data = (unsigned char *) image->data;
839 iptr = pmap->pixelindex;
840 depth = image->depth;
841 lbt = low_bits_table[depth];
842 if (image->byte_order == MSBFirst)
843 for (y = 0; y < height; y++)
844 for (x = 0; x < width; x++, iptr++) {
845 addr = &data[ZINDEX16(x, y, image)];
846 pixel = addr[0] << 8 | addr[1];
847 if (depth != 16)
848 pixel &= lbt;
849 if (storePixel(pixel, pmap, iptr))
850 return (XpmNoMemory);
851 }
852 else
853 for (y = 0; y < height; y++)
854 for (x = 0; x < width; x++, iptr++) {
855 addr = &data[ZINDEX16(x, y, image)];
856 pixel = addr[0] | addr[1] << 8;
857 if (depth != 16)
858 pixel &= lbt;
859 if (storePixel(pixel, pmap, iptr))
860 return (XpmNoMemory);
861 }
862 return (XpmSuccess);
863 }
864
865 /*
866 * scan pixels of a 8-bits Z image data structure
867 */
868
869 static int
870 GetImagePixels8(image, width, height, pmap)
871 XImage *image;
872 unsigned int width;
873 unsigned int height;
874 PixelsMap *pmap;
875 {
876 unsigned int *iptr;
877 unsigned char *data;
878 int x, y;
879 unsigned long lbt;
880 Pixel pixel;
881 int depth;
882
883 data = (unsigned char *) image->data;
884 iptr = pmap->pixelindex;
885 depth = image->depth;
886 lbt = low_bits_table[depth];
887 for (y = 0; y < height; y++)
888 for (x = 0; x < width; x++, iptr++) {
889 pixel = data[ZINDEX8(x, y, image)];
890 if (depth != 8)
891 pixel &= lbt;
892 if (storePixel(pixel, pmap, iptr))
893 return (XpmNoMemory);
894 }
895 return (XpmSuccess);
896 }
897
898 /*
899 * scan pixels of a 1-bit depth Z image data structure
900 */
901
902 static int
903 GetImagePixels1(image, width, height, pmap, storeFunc)
904 XImage *image;
905 unsigned int width;
906 unsigned int height;
907 PixelsMap *pmap;
908 int (*storeFunc) ();
909 {
910 unsigned int *iptr;
911 int x, y;
912 char *data;
913 Pixel pixel;
914 int xoff, yoff, offset, bpl;
915
916 data = image->data;
917 iptr = pmap->pixelindex;
918 offset = image->xoffset;
919 bpl = image->bytes_per_line;
920
921 if (image->bitmap_bit_order == MSBFirst)
922 for (y = 0; y < height; y++)
923 for (x = 0; x < width; x++, iptr++) {
924 xoff = x + offset;
925 yoff = y * bpl + (xoff >> 3);
926 xoff &= 7;
927 pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0;
928 if ((*storeFunc) (pixel, pmap, iptr))
929 return (XpmNoMemory);
930 }
931 else
932 for (y = 0; y < height; y++)
933 for (x = 0; x < width; x++, iptr++) {
934 xoff = x + offset;
935 yoff = y * bpl + (xoff >> 3);
936 xoff &= 7;
937 pixel = (data[yoff] & (1 << xoff)) ? 1 : 0;
938 if ((*storeFunc) (pixel, pmap, iptr))
939 return (XpmNoMemory);
940 }
941 return (XpmSuccess);
942 }
943
944 # else /* AMIGA */
945
946 #define CLEAN_UP(status) \
947 {\
948 if (pixels) XpmFree (pixels);\
949 if (tmp_img) FreeXImage (tmp_img);\
950 return (status);\
951 }
952
953 static int
954 AGetImagePixels (
955 XImage *image,
956 unsigned int width,
957 unsigned int height,
958 PixelsMap *pmap,
959 int (*storeFunc) ())
960 {
961 unsigned int *iptr;
962 unsigned int x, y;
963 unsigned char *pixels;
964 XImage *tmp_img;
965
966 pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels));
967 if (pixels == NULL)
968 return XpmNoMemory;
969
970 tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
971 if (tmp_img == NULL)
972 CLEAN_UP (XpmNoMemory)
973
974 iptr = pmap->pixelindex;
975 for (y = 0; y < height; ++y)
976 {
977 ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp);
978 for (x = 0; x < width; ++x, ++iptr)
979 {
980 if ((*storeFunc) (pixels[x], pmap, iptr))
981 CLEAN_UP (XpmNoMemory)
982 }
983 }
984
985 CLEAN_UP (XpmSuccess)
986 }
987
988 #undef CLEAN_UP
989
990 # endif/* AMIGA */
991 #else /* ndef FOR_MSW */
992
993 #ifdef __OS2__
994 /* Visual Age cannot deal with old, non-ansi, code */
995 static int
996 MSWGetImagePixels(
997 Display* display
998 , XImage* image
999 , unsigned int width
1000 , unsigned int height
1001 , PixelsMap* pmap
1002 , int (*storeFunc) ()
1003 )
1004 #else
1005 static int
1006 MSWGetImagePixels(display, image, width, height, pmap, storeFunc)
1007 Display *display;
1008 XImage *image;
1009 unsigned int width;
1010 unsigned int height;
1011 PixelsMap *pmap;
1012 int (*storeFunc) ();
1013 #endif
1014 {
1015 unsigned int *iptr;
1016 unsigned int x, y;
1017 Pixel pixel;
1018 #ifdef __OS2__
1019 HAB hab;
1020 HPS hps;
1021 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1022 SIZEL sizl = {0, 0};
1023 POINTL point;
1024 #endif
1025
1026 iptr = pmap->pixelindex;
1027
1028 #ifdef __OS2__
1029 hps = GpiCreatePS(hab, *display, &sizl, GPIA_ASSOC | PU_PELS);
1030 GpiSetBitmap(hps, image->bitmap);
1031 #else
1032 SelectObject(*display, image->bitmap);
1033 #endif
1034
1035 for (y = 0; y < height; y++) {
1036 for (x = 0; x < width; x++, iptr++) {
1037 #ifdef __OS2__
1038 point.x = x;
1039 point.y = y;
1040 pixel = GpiQueryPel(hps, &point);
1041 #else
1042 pixel = GetPixel(*display, x, y);
1043 #endif
1044
1045 #ifndef __OS2__
1046 /* calling convention all messed up under OS/2 */
1047 if ((*storeFunc) (pixel, pmap, iptr))
1048 return (XpmNoMemory);
1049 #endif
1050 }
1051 }
1052 return (XpmSuccess);
1053 }
1054
1055 #endif
1056
1057 #ifndef FOR_MSW
1058 # ifndef AMIGA
1059 int
1060 XpmCreateXpmImageFromPixmap(display, pixmap, shapemask,
1061 xpmimage, attributes)
1062 Display *display;
1063 Pixmap pixmap;
1064 Pixmap shapemask;
1065 XpmImage *xpmimage;
1066 XpmAttributes *attributes;
1067 {
1068 XImage *ximage = NULL;
1069 XImage *shapeimage = NULL;
1070 unsigned int width = 0;
1071 unsigned int height = 0;
1072 int ErrorStatus;
1073
1074 /* get geometry */
1075 if (attributes && attributes->valuemask & XpmSize) {
1076 width = attributes->width;
1077 height = attributes->height;
1078 }
1079 /* get the ximages */
1080 if (pixmap)
1081 xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
1082 if (shapemask)
1083 xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
1084 &width, &height);
1085
1086 /* create the related XpmImage */
1087 ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
1088 xpmimage, attributes);
1089
1090 /* destroy the ximages */
1091 if (ximage)
1092 XDestroyImage(ximage);
1093 if (shapeimage)
1094 XDestroyImage(shapeimage);
1095
1096 return (ErrorStatus);
1097 }
1098
1099 # endif/* not AMIGA */
1100 #endif /* ndef FOR_MSW */