1 /* xpixmap.c - Make RImage from Pixmap or XImage
3 * Raster graphics library
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
26 #include <X11/Xutil.h>
36 static int get_shifts(unsigned long mask
)
47 #define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
48 : ((pixel) & rmask) << -rshift)
49 #define NORMALIZE_GREEN(pixel) ((gshift>0) ? ((pixel) & gmask) >> gshift \
50 : ((pixel) & gmask) << -gshift)
51 #define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
52 : ((pixel) & bmask) << -bshift)
54 RImage
*RCreateImageFromXImage(RContext
* context
, XImage
* image
, XImage
* mask
)
60 int rshift
, gshift
, bshift
;
61 int rmask
, gmask
, bmask
;
63 assert(image
!= NULL
);
64 assert(image
->format
== ZPixmap
);
65 assert(!mask
|| mask
->format
== ZPixmap
);
67 img
= RCreateImage(image
->width
, image
->height
, mask
!= NULL
);
72 /* I don't know why, but XGetImage() for pixmaps don't set the
73 * {red,green,blue}_mask values correctly.
75 if (context
->depth
== image
->depth
) {
76 rmask
= context
->visual
->red_mask
;
77 gmask
= context
->visual
->green_mask
;
78 bmask
= context
->visual
->blue_mask
;
80 rmask
= image
->red_mask
;
81 gmask
= image
->green_mask
;
82 bmask
= image
->blue_mask
;
85 /* how many bits to shift to normalize the color into 8bpp */
86 rshift
= get_shifts(rmask
) - 8;
87 gshift
= get_shifts(gmask
) - 8;
88 bshift
= get_shifts(bmask
) - 8;
92 if (image
->depth
== 1) {
93 for (y
= 0; y
< image
->height
; y
++) {
94 for (x
= 0; x
< image
->width
; x
++) {
95 pixel
= XGetPixel(image
, x
, y
);
110 for (y
= 0; y
< image
->height
; y
++) {
111 for (x
= 0; x
< image
->width
; x
++) {
112 pixel
= XGetPixel(image
, x
, y
);
113 *(data
++) = NORMALIZE_RED(pixel
);
114 *(data
++) = NORMALIZE_GREEN(pixel
);
115 *(data
++) = NORMALIZE_BLUE(pixel
);
122 #define MIN(a,b) ((a)<(b)?(a):(b))
124 data
= img
->data
+ 3; /* Skip R, G & B */
125 for (y
= 0; y
< MIN(mask
->height
, image
->height
); y
++) {
126 for (x
= 0; x
< MIN(mask
->width
, image
->width
); x
++) {
127 if (mask
->width
<= image
->width
&& XGetPixel(mask
, x
, y
)) {
134 for (; x
< image
->width
; x
++) {
139 for (; y
< image
->height
; y
++) {
140 for (x
= 0; x
< image
->width
; x
++) {
149 RImage
*RCreateImageFromDrawable(RContext
* context
, Drawable drawable
, Pixmap mask
)
153 unsigned int w
, h
, bar
;
157 assert(drawable
!= None
);
159 if (!XGetGeometry(context
->dpy
, drawable
, &baz
, &foo
, &foo
, &w
, &h
, &bar
, &bar
)) {
160 fprintf(stderr
, _("wrlib: invalid window or pixmap passed to RCreateImageFromDrawable\n"));
163 pimg
= XGetImage(context
->dpy
, drawable
, 0, 0, w
, h
, AllPlanes
, ZPixmap
);
166 RErrorCode
= RERR_XERROR
;
171 if (XGetGeometry(context
->dpy
, mask
, &baz
, &foo
, &foo
, &w
, &h
, &bar
, &bar
)) {
172 mimg
= XGetImage(context
->dpy
, mask
, 0, 0, w
, h
, AllPlanes
, ZPixmap
);
176 image
= RCreateImageFromXImage(context
, pimg
, mimg
);