@@ -65,7 +65,7 @@ class XWindowAttributes(Structure):
6565
6666 class XImage (Structure ):
6767 _fields_ = [('width' , c_int ), ('height' , c_int ), ('xoffset' , c_int ),
68- ('format' , c_int ), ('data' , c_char_p ),
68+ ('format' , c_int ), ('data' , c_void_p ),
6969 ('byte_order' , c_int ), ('bitmap_unit' , c_int ),
7070 ('bitmap_bit_order' , c_int ), ('bitmap_pad' , c_int ),
7171 ('depth' , c_int ), ('bytes_per_line' , c_int ),
@@ -349,7 +349,7 @@ def _set_argtypes(self):
349349 self .xlib .XGetImage .argtypes = [POINTER (Display ), POINTER (Display ),
350350 c_int , c_int , c_uint , c_uint , c_ulong ,
351351 c_int ]
352- self .xlib .XGetPixel .argtypes = [POINTER (XImage ), c_int , c_int ]
352+ # self.xlib.XGetPixel.argtypes = [POINTER(XImage), c_int, c_int]
353353 self .xlib .XDestroyImage .argtypes = [POINTER (XImage )]
354354 self .xlib .XCloseDisplay .argtypes = [POINTER (Display )]
355355 self .xrandr .XRRGetScreenResources .argtypes = [POINTER (Display ),
@@ -370,7 +370,7 @@ def _set_restypes(self):
370370 self .xlib .XGetWindowAttributes .restype = c_int
371371 self .xlib .XAllPlanes .restype = c_ulong
372372 self .xlib .XGetImage .restype = POINTER (XImage )
373- self .xlib .XGetPixel .restype = c_ulong
373+ # self.xlib.XGetPixel.restype = c_ulong
374374 self .xlib .XDestroyImage .restype = c_void_p
375375 self .xlib .XCloseDisplay .restype = c_void_p
376376 self .xlib .XDefaultRootWindow .restype = POINTER (XWindowAttributes )
@@ -427,33 +427,61 @@ def get_pixels(self, monitor):
427427 if not ximage :
428428 raise ScreenshotError ('MSS: XGetImage() failed.' )
429429
430- from ctypes import c_ubyte , c_char
430+ '''
431+ pixels = malloc(sizeof(unsigned char) * width * height * 3);
432+
433+ for ( x = 0; x < width; ++x )
434+ for ( y = 0; y < height; ++y )
435+ offset = width * y * 3;
436+ //~ pixel = XGetPixel(ximage, x, y);
437+ addr = &(ximage->data)[y * ximage->bytes_per_line + (x << 2)];
438+ pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
439+ pixels[x * 3 + offset] = (pixel & ximage->red_mask) >> 16;
440+ pixels[x * 3 + offset + 1] = (pixel & ximage->green_mask) >> 8;
441+ pixels[x * 3 + offset + 2] = pixel & ximage->blue_mask;
442+ '''
443+ """from ctypes import create_string_buffer, c_char, sizeof
444+ rmask = ximage.contents.red_mask
445+ gmask = ximage.contents.green_mask
446+ bmask = ximage.contents.blue_mask
431447 bpl = ximage.contents.bytes_per_line
432- data = cast (ximage .contents .data , POINTER (width * height * c_ubyte )).contents
433-
448+ data = cast(ximage.contents.data, POINTER(c_char * width * height * 3)).contents
449+ self.image = create_string_buffer(sizeof(c_char) * width * height * 3)
450+ xrange = getattr(__builtins__, 'xrange', range)
451+ for x in xrange(width):
452+ for y in xrange(height):
453+ offset = width * y * 3
454+ addr = data[y * bpl + (x << 2)][0]
455+ pixel = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]
456+ self.image[x * 3 + offset] = (pixel & rmask) >> 16
457+ self.image[x * 3 + offset + 1] = (pixel & gmask) >> 8
458+ self.image[x * 3 + offset + 2] = pixel & bmask
459+ #~ self.image[x * 3 + offset:x * 3 + offset + 2] = \
460+ #~ (pixel & rmask) >> 16, (pixel & gmask) >> 8, pixel & bmask
461+
462+ """
434463 # @TODO: this part takes most of the time. Need a better solution.
435464 def pix (pixel , _resultats = {}, b = pack ):
436465 ''' Apply shifts to a pixel to get the RGB values.
437466 This method uses of memoization.
438467 '''
439468 if pixel not in _resultats :
440- _resultats [pixel ] = b (b'<B' , pixel >> 24 ) + \
441- b (b'<B' , pixel >> 16 ) + b (b'<B' , pixel )
469+ _resultats [pixel ] = b (b'<B' , ( pixel & rmask ) >> 16 ) + \
470+ b (b'<B' , ( pixel & gmask ) >> 8 ) + b (b'<B' , pixel & bmask )
442471 return _resultats [pixel ]
443472
444473 # http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444
445- #~ get_pix = self.xlib.XGetPixel
446- #~ def get_pix(x, y):
447-
474+ xrange = getattr (__builtins__ , 'xrange' , range )
448475 rmask = ximage .contents .red_mask
449476 gmask = ximage .contents .green_mask
450477 bmask = ximage .contents .blue_mask
451- bpl = ximage .contents .bytes_per_line
452- xrange = getattr (__builtins__ , 'xrange' , range )
453- pixels = [pix (data [idx ])
454- for idx in xrange (0 , (width * height ) - 2 , 3 )]
455- self .xlib .XDestroyImage (ximage )
478+ get_pix = self .xlib .XGetPixel
479+ pixels = [pix (get_pix (ximage , x , y ))
480+ for y in range (height ) for x in range (width )]
456481 self .image = b'' .join (pixels )
482+ #"""
483+
484+ self .xlib .XDestroyImage (ximage )
457485 return self .image
458486
459487
0 commit comments