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