1/* 2 3Copyright 1986, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include "Xlibint.h" 31#include <X11/Xutil.h> /* for XDestroyImage */ 32#include "ImUtil.h" 33#include <limits.h> 34 35#define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad)) 36 37#ifdef HAVE___BUILTIN_POPCOUNTL 38# define Ones __builtin_popcountl 39#else 40/* 41 * Count the number of bits set to 1 in a 32-bit word. 42 * Algorithm from MIT AI Lab Memo 239: "HAKMEM", ITEM 169. 43 * http://dspace.mit.edu/handle/1721.1/6086 44 */ 45static inline unsigned int 46Ones(unsigned long mask) 47{ 48 register unsigned long y; 49 50 y = (mask >> 1) & 033333333333; 51 y = mask - y - ((y >>1) & 033333333333); 52 return ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); 53} 54#endif 55 56XImage *XGetImage ( 57 register Display *dpy, 58 Drawable d, 59 int x, 60 int y, 61 unsigned int width, 62 unsigned int height, 63 unsigned long plane_mask, 64 int format) /* either XYPixmap or ZPixmap */ 65{ 66 xGetImageReply rep; 67 register xGetImageReq *req; 68 char *data; 69 unsigned long nbytes; 70 XImage *image; 71 int planes; 72 LockDisplay(dpy); 73 GetReq (GetImage, req); 74 /* 75 * first set up the standard stuff in the request 76 */ 77 req->drawable = d; 78 req->x = x; 79 req->y = y; 80 req->width = width; 81 req->height = height; 82 req->planeMask = plane_mask; 83 req->format = format; 84 85 if (_XReply (dpy, (xReply *) &rep, 0, xFalse) == 0 || 86 rep.length == 0) { 87 UnlockDisplay(dpy); 88 SyncHandle(); 89 return (XImage *)NULL; 90 } 91 92 if (rep.length < (INT_MAX >> 2)) { 93 nbytes = (unsigned long)rep.length << 2; 94 data = Xmalloc(nbytes); 95 } else 96 data = NULL; 97 if (! data) { 98 _XEatDataWords(dpy, rep.length); 99 UnlockDisplay(dpy); 100 SyncHandle(); 101 return (XImage *) NULL; 102 } 103 _XReadPad (dpy, data, nbytes); 104 if (format == XYPixmap) { 105 image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), 106 Ones (plane_mask & 107 (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), 108 format, 0, data, width, height, dpy->bitmap_pad, 0); 109 planes = image->depth; 110 } else { /* format == ZPixmap */ 111 image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), 112 rep.depth, ZPixmap, 0, data, width, height, 113 _XGetScanlinePad(dpy, (int) rep.depth), 0); 114 planes = 1; 115 } 116 117 if (!image) { 118 Xfree(data); 119 } else { 120 if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 || 121 INT_MAX / image->height <= image->bytes_per_line || 122 INT_MAX / planes <= image->height * image->bytes_per_line || 123 nbytes < planes * image->height * image->bytes_per_line) { 124 XDestroyImage(image); 125 image = NULL; 126 } 127 } 128 UnlockDisplay(dpy); 129 SyncHandle(); 130 return (image); 131} 132 133XImage *XGetSubImage( 134 register Display *dpy, 135 Drawable d, 136 int x, 137 int y, 138 unsigned int width, 139 unsigned int height, 140 unsigned long plane_mask, 141 int format, /* either XYPixmap or ZPixmap */ 142 XImage *dest_image, 143 int dest_x, 144 int dest_y) 145{ 146 XImage *temp_image; 147 temp_image = XGetImage(dpy, d, x, y, width, height, 148 plane_mask, format); 149 if (!temp_image) 150 return (XImage *)NULL; 151 _XSetImage(temp_image, dest_image, dest_x, dest_y); 152 XDestroyImage(temp_image); 153 return (dest_image); 154} 155