Skip to content

Commit f4bcc8e

Browse files
author
BoboTiG
committed
MSSLinux: reduce operation time by a factor of 2
1 parent aace94b commit f4bcc8e

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

mss.py

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)