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