2 * Copyright (C) 1989-95 GROUPE BULL
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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.
26 /*****************************************************************************\
30 * Scanning utility for XPM file format *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
36 * The code related to FOR_MSW has been added by
37 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
41 * The code related to AMIGA has been added by
42 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
47 #define MAXPRINTABLE 92 /* number of printable ascii chars
48 * minus \ and " for string compat
49 * and ? to avoid ANSI trigraphs. */
51 static char *printable
=
52 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
53 ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
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
64 unsigned int *pixelindex
;
67 unsigned int mask_pixel
; /* whether there is or not */
70 LFUNC(storePixel
, int, (Pixel pixel
, PixelsMap
*pmap
,
71 unsigned int *index_return
));
73 LFUNC(storeMaskPixel
, int, (Pixel pixel
, PixelsMap
*pmap
,
74 unsigned int *index_return
));
78 LFUNC(GetImagePixels
, int, (XImage
*image
, unsigned int width
,
79 unsigned int height
, PixelsMap
*pmap
));
81 LFUNC(GetImagePixels32
, int, (XImage
*image
, unsigned int width
,
82 unsigned int height
, PixelsMap
*pmap
));
84 LFUNC(GetImagePixels16
, int, (XImage
*image
, unsigned int width
,
85 unsigned int height
, PixelsMap
*pmap
));
87 LFUNC(GetImagePixels8
, int, (XImage
*image
, unsigned int width
,
88 unsigned int height
, PixelsMap
*pmap
));
90 LFUNC(GetImagePixels1
, int, (XImage
*image
, unsigned int width
,
91 unsigned int height
, PixelsMap
*pmap
,
92 int (*storeFunc
) ()));
94 LFUNC(AGetImagePixels
, int, (XImage
*image
, unsigned int width
,
95 unsigned int height
, PixelsMap
*pmap
,
96 int (*storeFunc
) ()));
98 #else /* ndef FOR_MSW */
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*)));
105 LFUNC(MSWGetImagePixels
, int, (Display
*d
, XImage
*image
, unsigned int width
,
106 unsigned int height
, PixelsMap
*pmap
,
107 int (*storeFunc
) ()));
112 LFUNC(ScanTransparentColor
, int, (XpmColor
*color
, unsigned int cpp
,
113 XpmAttributes
*attributes
));
115 LFUNC(ScanOtherColors
, int, (Display
*display
, XpmColor
*colors
, int ncolors
,
116 Pixel
*pixels
, unsigned int mask
,
117 unsigned int cpp
, XpmAttributes
*attributes
));
120 * This function stores the given pixel in the given arrays which are grown
121 * if not large enough.
124 /* Visual Age cannot deal with old, non-ansi, code */
125 static int storePixel(Pixel pixel
, PixelsMap
* pmap
, unsigned int* index_return
)
128 storePixel(pixel
, pmap
, index_return
)
131 unsigned int *index_return
;
136 unsigned int ncolors
;
138 if (*index_return
) { /* this is a transparent pixel! */
142 ncolors
= pmap
->ncolors
;
143 p
= pmap
->pixels
+ pmap
->mask_pixel
;
144 for (i
= pmap
->mask_pixel
; i
< ncolors
; i
++, p
++)
148 if (ncolors
>= pmap
->size
) {
150 p
= (Pixel
*) XpmRealloc(pmap
->pixels
, sizeof(Pixel
) * pmap
->size
);
156 (pmap
->pixels
)[ncolors
] = pixel
;
164 /* Visual Age cannot deal with old, non-ansi, code */
165 static int storeMaskPixel(Pixel pixel
, PixelsMap
* pmap
, unsigned int* index_return
)
168 storeMaskPixel(pixel
, pmap
, index_return
)
171 unsigned int *index_return
;
175 if (!pmap
->ncolors
) {
177 (pmap
->pixels
)[0] = 0;
178 pmap
->mask_pixel
= 1;
186 /* function call in case of error */
188 #define RETURN(status) \
190 ErrorStatus = status; \
195 * This function scans the given image and stores the found informations in
196 * the given XpmImage structure.
199 /* Visual Age cannot deal with old, non-ansi, code */
200 int XpmCreateXpmImageFromImage(
205 , XpmAttributes
* attributes
209 XpmCreateXpmImageFromImage(display
, image
, shapeimage
,
210 xpmimage
, attributes
)
215 XpmAttributes
*attributes
;
218 /* variables stored in the XpmAttributes structure */
221 /* variables to return */
223 XpmColor
*colorTable
= NULL
;
226 /* calculation variables */
227 unsigned int width
= 0;
228 unsigned int height
= 0;
229 unsigned int cppm
; /* minimum chars per pixel */
232 /* initialize pmap */
234 pmap
.pixelindex
= NULL
;
235 pmap
.size
= 256; /* should be enough most of the time */
243 width
= image
->width
;
244 height
= image
->height
;
245 } else if (shapeimage
) {
246 width
= shapeimage
->width
;
247 height
= shapeimage
->height
;
251 * retrieve information from the XpmAttributes
253 if (attributes
&& (attributes
->valuemask
& XpmCharsPerPixel
254 /* 3.2 backward compatibility code */
255 || attributes
->valuemask
& XpmInfos
))
257 cpp
= attributes
->cpp
;
262 (unsigned int *) XpmCalloc(width
* height
, sizeof(unsigned int));
263 if (!pmap
.pixelindex
)
266 pmap
.pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * pmap
.size
);
271 * scan shape mask if any
277 ErrorStatus
= GetImagePixels1(shapeimage
, width
, height
, &pmap
,
280 ErrorStatus
= AGetImagePixels(shapeimage
, width
, height
, &pmap
,
285 ErrorStatus
= MSWGetImagePixels(display
, shapeimage
, width
, height
,
286 &pmap
, storeMaskPixel
);
288 #endif /* ndef for FOR_MSW */
290 if (ErrorStatus
!= XpmSuccess
)
295 * scan the image data
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.
306 if (((image
->bits_per_pixel
| image
->depth
) == 1) &&
307 (image
->byte_order
== image
->bitmap_bit_order
))
308 ErrorStatus
= GetImagePixels1(image
, width
, height
, &pmap
,
310 else if (image
->format
== ZPixmap
)
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
);
320 ErrorStatus
= GetImagePixels(image
, width
, height
, &pmap
);
322 ErrorStatus
= AGetImagePixels(image
, width
, height
, &pmap
,
327 ErrorStatus
= MSWGetImagePixels(display
, image
, width
, height
, &pmap
,
332 if (ErrorStatus
!= XpmSuccess
)
337 * get rgb values and a string of char, and possibly a name for each
341 colorTable
= (XpmColor
*) XpmCalloc(pmap
.ncolors
, sizeof(XpmColor
));
345 /* compute the minimal cpp */
346 for (cppm
= 1, c
= MAXPRINTABLE
; pmap
.ncolors
> c
; cppm
++)
351 if (pmap
.mask_pixel
) {
352 ErrorStatus
= ScanTransparentColor(colorTable
, cpp
, attributes
);
353 if (ErrorStatus
!= XpmSuccess
)
357 ErrorStatus
= ScanOtherColors(display
, colorTable
, pmap
.ncolors
,
358 pmap
.pixels
, pmap
.mask_pixel
, cpp
,
360 if (ErrorStatus
!= XpmSuccess
)
364 * store found informations in the XpmImage structure
366 xpmimage
->width
= width
;
367 xpmimage
->height
= height
;
369 xpmimage
->ncolors
= pmap
.ncolors
;
370 xpmimage
->colorTable
= colorTable
;
371 xpmimage
->data
= pmap
.pixelindex
;
373 XpmFree(pmap
.pixels
);
376 /* exit point in case of error, free only locally allocated variables */
379 XpmFree(pmap
.pixelindex
);
381 XpmFree(pmap
.pixels
);
383 xpmFreeColorTable(colorTable
, pmap
.ncolors
);
385 return (ErrorStatus
);
389 /* Visual Age cannot deal with old, non-ansi, code */
390 static int ScanTransparentColor(XpmColor
* color
, unsigned int cpp
, XpmAttributes
* attributes
)
393 ScanTransparentColor(color
, cpp
, attributes
)
396 XpmAttributes
*attributes
;
400 unsigned int a
, b
, c
;
402 /* first get a character string */
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
];
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
)
416 && attributes
->mask_pixel
!= XpmUndefPixel
) {
419 char **defaults
= (char **) color
;
420 char **mask_defaults
;
422 /* 3.2 backward compatibility code */
423 if (attributes
->valuemask
& XpmColorTable
)
425 mask_defaults
= (char **) (
426 attributes
->colorTable
+ attributes
->mask_pixel
);
427 /* 3.2 backward compatibility code */
429 mask_defaults
= (char **)
430 ((XpmColor
**) attributes
->colorTable
)[attributes
->mask_pixel
];
432 for (key
= 1; key
<= NKEYS
; key
++) {
433 if (s
= mask_defaults
[key
]) {
434 defaults
[key
] = (char *) xpmstrdup(s
);
436 return (XpmNoMemory
);
440 color
->c_color
= (char *) xpmstrdup(TRANSPARENT_COLOR
);
442 return (XpmNoMemory
);
448 /* Visual Age cannot deal with old, non-ansi, code */
449 static int ScanOtherColors(
456 , XpmAttributes
* attributes
460 ScanOtherColors(display
, colors
, ncolors
, pixels
, mask
, cpp
, attributes
)
467 XpmAttributes
*attributes
;
470 /* variables stored in the XpmAttributes structure */
475 xpmRgbName rgbn
[MAX_RGBNAMES
];
477 xpmRgbName
*rgbn
= NULL
;
480 unsigned int i
, j
, c
, i2
;
482 XColor
*xcolors
= NULL
, *xcolor
;
484 XpmColor
*colorTable
, **oldColorTable
= NULL
;
485 unsigned int ancolors
= 0;
487 unsigned int mask_pixel
;
490 /* retrieve information from the XpmAttributes */
491 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
492 colormap
= attributes
->colormap
;
494 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
495 if (attributes
&& (attributes
->valuemask
& XpmRgbFilename
))
496 rgb_fname
= attributes
->rgb_fname
;
500 /* start from the right element */
507 /* first get character strings and rgb values */
508 xcolors
= (XColor
*) XpmMalloc(sizeof(XColor
) * ncolors
);
510 return (XpmNoMemory
);
512 for (i
= 0, i2
= mask
, color
= colors
, xcolor
= xcolors
;
513 i
< (unsigned)ncolors
; i
++, i2
++, color
++, xcolor
++, pixels
++) {
515 if (!(s
= color
->string
= (char *) XpmMalloc(cpp
+ 1))) {
517 return (XpmNoMemory
);
519 *s
++ = printable
[c
= i2
% MAXPRINTABLE
];
520 for (j
= 1; j
< cpp
; j
++, s
++)
521 *s
= printable
[c
= ((i2
- c
) / MAXPRINTABLE
) % MAXPRINTABLE
];
524 xcolor
->pixel
= *pixels
;
527 XQueryColors(display
, &colormap
, xcolors
, ncolors
);
529 XQueryColors(display
, colormap
, xcolors
, ncolors
);
533 /* read the rgb file if any was specified */
535 rgbn_max
= xpmReadRgbNames(attributes
->rgb_fname
, rgbn
);
537 /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
538 rgbn_max
= xpmReadRgbNames(NULL
, NULL
);
541 if (attributes
&& attributes
->valuemask
& XpmColorTable
) {
542 colorTable
= attributes
->colorTable
;
543 ancolors
= attributes
->ncolors
;
544 apixels
= attributes
->pixels
;
545 mask_pixel
= attributes
->mask_pixel
;
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
;
556 for (i
= 0, color
= colors
, xcolor
= xcolors
; i
< (unsigned)ncolors
;
557 i
++, color
++, xcolor
++) {
559 /* look for related info from the attributes if any */
562 unsigned int offset
= 0;
564 for (j
= 0; j
< ancolors
; j
++) {
565 if (j
== mask_pixel
) {
569 if (apixels
[j
- offset
] == xcolor
->pixel
)
574 char **defaults
= (char **) color
;
577 /* 3.2 backward compatibility code */
579 adefaults
= (char **) oldColorTable
[j
];
582 adefaults
= (char **) (colorTable
+ j
);
585 for (key
= 1; key
<= NKEYS
; key
++) {
586 if (s
= adefaults
[key
])
587 defaults
[key
] = (char *) xpmstrdup(s
);
592 /* if nothing found look for a color name */
595 colorname
= xpmGetRgbName(rgbn
, rgbn_max
, xcolor
->red
,
596 xcolor
->green
, xcolor
->blue
);
598 color
->c_color
= (char *) xpmstrdup(colorname
);
600 /* at last store the rgb value */
603 sprintf(buf
, "#%04X%04X%04X",
604 xcolor
->red
, xcolor
->green
, xcolor
->blue
);
606 sprintf(buf
, "#%02x%02x%02x",
607 xcolor
->red
, xcolor
->green
, xcolor
->blue
);
609 color
->c_color
= (char *) xpmstrdup(buf
);
611 if (!color
->c_color
) {
613 xpmFreeRgbNames(rgbn
, rgbn_max
);
614 return (XpmNoMemory
);
620 xpmFreeRgbNames(rgbn
, rgbn_max
);
627 * The functions below are written from X11R5 MIT's code (XImUtil.c)
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
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,
648 * Default method to scan pixels of an image data structure.
649 * The algorithm used is:
651 * copy the source bitmap_unit or Zpixel into temp
652 * normalize temp if needed
653 * extract the pixel bits into return value
658 GetImagePixels(image
, width
, height
, pmap
)
669 int bits
, depth
, ibu
, ibpp
, offset
;
674 iptr
= pmap
->pixelindex
;
675 depth
= image
->depth
;
676 lbt
= low_bits_table
[depth
];
677 ibpp
= image
->bits_per_pixel
;
678 offset
= image
->xoffset
;
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
;
687 for (i
= ibu
>> 3; --i
>= 0;)
689 XYNORMALIZE(&pixel
, image
);
690 bits
= (x
+ offset
) % ibu
;
691 pixel
= ((((char *) &pixel
)[bits
>> 3]) >> (bits
& 7)) & 1;
694 if (storePixel(pixel
, pmap
, iptr
))
695 return (XpmNoMemory
);
697 } else if (image
->format
== XYPixmap
) {
700 ibu
= image
->bitmap_unit
;
702 bpl
= image
->bytes_per_line
;
703 for (y
= 0; y
< height
; y
++)
704 for (x
= 0; x
< width
; x
++, iptr
++) {
707 for (i
= depth
; --i
>= 0;) {
708 src
= &data
[XYINDEX(x
, y
, image
) + plane
];
711 for (j
= nbytes
; --j
>= 0;)
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
);
721 if (storePixel(pixel
, pmap
, iptr
))
722 return (XpmNoMemory
);
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
)];
730 for (i
= (ibpp
+ 7) >> 3; --i
>= 0;)
732 ZNORMALIZE(&px
, image
);
734 for (i
= sizeof(unsigned long); --i
>= 0;)
735 pixel
= (pixel
<< 8) | ((unsigned char *) &px
)[i
];
744 if (storePixel(pixel
, pmap
, iptr
))
745 return (XpmNoMemory
);
748 return (XpmColorError
); /* actually a bad image */
753 * scan pixels of a 32-bits Z image data structure
756 #if !defined(WORD64) && !defined(LONG64)
757 static unsigned long byteorderpixel
= MSBFirst
<< 24;
761 GetImagePixels32(image
, width
, height
, pmap
)
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
);
787 if (storePixel(pixel
, pmap
, iptr
))
788 return (XpmNoMemory
);
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 |
802 if (storePixel(pixel
, pmap
, iptr
))
803 return (XpmNoMemory
);
806 for (y
= 0; y
< height
; y
++)
807 for (x
= 0; x
< width
; x
++, iptr
++) {
808 addr
= &data
[ZINDEX32(x
, y
, image
)];
810 (unsigned long) addr
[1] << 8 |
811 (unsigned long) addr
[2] << 16 |
812 (unsigned long) addr
[3] << 24);
815 if (storePixel(pixel
, pmap
, iptr
))
816 return (XpmNoMemory
);
822 * scan pixels of a 16-bits Z image data structure
826 GetImagePixels16(image
, width
, height
, pmap
)
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];
851 if (storePixel(pixel
, pmap
, iptr
))
852 return (XpmNoMemory
);
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;
861 if (storePixel(pixel
, pmap
, iptr
))
862 return (XpmNoMemory
);
868 * scan pixels of a 8-bits Z image data structure
872 GetImagePixels8(image
, width
, height
, pmap
)
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
)];
894 if (storePixel(pixel
, pmap
, iptr
))
895 return (XpmNoMemory
);
901 * scan pixels of a 1-bit depth Z image data structure
905 GetImagePixels1(image
, width
, height
, pmap
, storeFunc
)
916 int xoff
, yoff
, offset
, bpl
;
919 iptr
= pmap
->pixelindex
;
920 offset
= image
->xoffset
;
921 bpl
= image
->bytes_per_line
;
923 if (image
->bitmap_bit_order
== MSBFirst
)
924 for (y
= 0; y
< height
; y
++)
925 for (x
= 0; x
< width
; x
++, iptr
++) {
927 yoff
= y
* bpl
+ (xoff
>> 3);
929 pixel
= (data
[yoff
] & (0x80 >> xoff
)) ? 1 : 0;
930 if ((*storeFunc
) (pixel
, pmap
, iptr
))
931 return (XpmNoMemory
);
934 for (y
= 0; y
< height
; y
++)
935 for (x
= 0; x
< width
; x
++, iptr
++) {
937 yoff
= y
* bpl
+ (xoff
>> 3);
939 pixel
= (data
[yoff
] & (1 << xoff
)) ? 1 : 0;
940 if ((*storeFunc
) (pixel
, pmap
, iptr
))
941 return (XpmNoMemory
);
948 #define CLEAN_UP(status) \
950 if (pixels) XpmFree (pixels);\
951 if (tmp_img) FreeXImage (tmp_img);\
965 unsigned char *pixels
;
968 pixels
= XpmMalloc ((((width
+15)>>4)<<4)*sizeof (*pixels
));
972 tmp_img
= AllocXImage ((((width
+15)>>4)<<4), 1, image
->rp
->BitMap
->Depth
);
974 CLEAN_UP (XpmNoMemory
)
976 iptr
= pmap
->pixelindex
;
977 for (y
= 0; y
< height
; ++y
)
979 ReadPixelLine8 (image
->rp
, 0, y
, width
, pixels
, tmp_img
->rp
);
980 for (x
= 0; x
< width
; ++x
, ++iptr
)
982 if ((*storeFunc
) (pixels
[x
], pmap
, iptr
))
983 CLEAN_UP (XpmNoMemory
)
987 CLEAN_UP (XpmSuccess
)
993 #else /* ndef FOR_MSW */
997 #ifdef __VISAGECPP30__
998 static int MSWGetImagePixels(
1001 , unsigned int width
1002 , unsigned int height
1004 , int (*storeFunc
) (Pixel
, PixelsMap
*, unsigned int*)
1007 static int MSWGetImagePixels(
1010 , unsigned int width
1011 , unsigned int height
1013 , int (*storeFunc
) ()
1019 MSWGetImagePixels(display
, image
, width
, height
, pmap
, storeFunc
)
1023 unsigned int height
;
1025 int (*storeFunc
) ();
1032 HAB hab
= WinQueryAnchorBlock(HWND_DESKTOP
);
1034 DEVOPENSTRUC dop
= {NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1035 SIZEL sizl
= {0, 0};
1039 iptr
= pmap
->pixelindex
;
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
);
1046 SelectObject(*display
, image
->bitmap
);
1049 for (y
= 0; y
< height
; y
++) {
1050 for (x
= 0; x
< width
; x
++, iptr
++) {
1054 pixel
= GpiQueryPel(*display
, &point
);
1056 pixel
= GetPixel(*display
, x
, y
);
1059 if ((*storeFunc
) (pixel
, pmap
, iptr
))
1060 return (XpmNoMemory
);
1063 return (XpmSuccess
);
1071 XpmCreateXpmImageFromPixmap(display
, pixmap
, shapemask
,
1072 xpmimage
, attributes
)
1077 XpmAttributes
*attributes
;
1079 XImage
*ximage
= NULL
;
1080 XImage
*shapeimage
= NULL
;
1081 unsigned int width
= 0;
1082 unsigned int height
= 0;
1086 if (attributes
&& attributes
->valuemask
& XpmSize
) {
1087 width
= attributes
->width
;
1088 height
= attributes
->height
;
1090 /* get the ximages */
1092 xpmCreateImageFromPixmap(display
, pixmap
, &ximage
, &width
, &height
);
1094 xpmCreateImageFromPixmap(display
, shapemask
, &shapeimage
,
1097 /* create the related XpmImage */
1098 ErrorStatus
= XpmCreateXpmImageFromImage(display
, ximage
, shapeimage
,
1099 xpmimage
, attributes
);
1101 /* destroy the ximages */
1103 XDestroyImage(ximage
);
1105 XDestroyImage(shapeimage
);
1107 return (ErrorStatus
);
1110 # endif/* not AMIGA */
1111 #endif /* ndef FOR_MSW */