|
| 1 | + |
| 2 | +/* |
| 3 | + * This is the MSS python's module implementation in C. |
| 4 | + * |
| 5 | + * Build: gcc -O3 -lX11 test-linux.c -o test-linux |
| 6 | + * Test : python test-raw.py test-linux.raw largeur hauteur |
| 7 | + * |
| 8 | + * http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444 |
| 9 | + * |
| 10 | + */ |
| 11 | + |
| 12 | +#include <stdlib.h> |
| 13 | +#include <stdio.h> |
| 14 | +#include <time.h> |
| 15 | +#include <X11/Xlib.h> |
| 16 | + |
| 17 | +int main(void) { |
| 18 | + struct timeval start, end; |
| 19 | + Display *display; |
| 20 | + Window screen, root; |
| 21 | + XWindowAttributes gwa; |
| 22 | + XImage *image; |
| 23 | + int left, top; |
| 24 | + unsigned int x, y, width, height, offset; |
| 25 | + unsigned long allplanes, pixel; |
| 26 | + unsigned char *pixels; |
| 27 | + |
| 28 | + gettimeofday(&start, NULL); |
| 29 | + |
| 30 | + display = XOpenDisplay(NULL); |
| 31 | + screen = XDefaultScreen(display); |
| 32 | + root = XDefaultRootWindow(display); |
| 33 | + XGetWindowAttributes(display, root, &gwa); |
| 34 | + left = gwa.x; |
| 35 | + top = gwa.y; |
| 36 | + width = gwa.width; |
| 37 | + height = gwa.height; |
| 38 | + allplanes = XAllPlanes(); |
| 39 | + image = XGetImage(display, root, left, top, width, height, allplanes, ZPixmap); |
| 40 | + pixels = malloc(sizeof(unsigned char) * width * height * 3); |
| 41 | + |
| 42 | + //~ printf("display = %d\n", display); |
| 43 | + //~ printf("screen = %d\n", screen); |
| 44 | + //~ printf("root = %d\n", root); |
| 45 | + //~ printf("left = %d\n", left); |
| 46 | + //~ printf("top = %d\n", top); |
| 47 | + //~ printf("width = %d\n", width); |
| 48 | + //~ printf("height = %d\n", height); |
| 49 | + //~ printf("allplanes = %u\n", allplanes); |
| 50 | + //~ printf("bits_per_pixel = %d\n", image->bits_per_pixel); |
| 51 | + //~ printf("bytes_per_line = %d\n", image->bytes_per_line); |
| 52 | + //~ printf("depth = %d\n", image->depth); |
| 53 | + |
| 54 | + // Processus habituel |
| 55 | + //~ /* |
| 56 | + for ( x = 0; x < width; ++x ) { |
| 57 | + for ( y = 0; y < height; ++y ) { |
| 58 | + pixel = XGetPixel(image, x, y); |
| 59 | + offset = width * y * 3; |
| 60 | + pixels[x * 3 + offset] = (pixel & image->red_mask) >> 16; |
| 61 | + pixels[x * 3 + offset + 1] = (pixel & image->green_mask) >> 8; |
| 62 | + pixels[x * 3 + offset + 2] = pixel & image->blue_mask; |
| 63 | + } |
| 64 | + } |
| 65 | + //~ */ |
| 66 | + |
| 67 | + // Processus sans passer par XGetPixel (pas vraiment mieux...) |
| 68 | + /* |
| 69 | + unsigned int shift = 0xffffffff; |
| 70 | + if ( image->depth == 24 ) { |
| 71 | + shift = 0x00ffffff; |
| 72 | + } |
| 73 | + unsigned long px; |
| 74 | + register char *src, *dst; |
| 75 | + register int i, j; |
| 76 | + for ( x = 0; x < width; ++x ) { |
| 77 | + for ( y = 0; y < height; ++y ) { |
| 78 | + offset = (y * image->bytes_per_line + ((x * image->bits_per_pixel) >> 3)) + 4; |
| 79 | + src = &image->data[offset]; |
| 80 | + dst = (char*)&px; |
| 81 | + px = 0; |
| 82 | + for ( i = (image->bits_per_pixel + 7) >> 3; --i >= 0; ) |
| 83 | + *dst++ = *src++; |
| 84 | + pixel = 0; |
| 85 | + for ( i = sizeof(unsigned long); --i >= 0; ) |
| 86 | + pixel = (pixel << 8) | ((unsigned char *)&px)[i]; |
| 87 | + offset = width * y * 3; |
| 88 | + pixels[x * 3 + offset] = (pixel & image->red_mask) >> 16; |
| 89 | + pixels[x * 3 + offset + 1] = (pixel & image->green_mask) >> 8; |
| 90 | + pixels[x * 3 + offset + 2] = pixel & image->blue_mask; |
| 91 | + } |
| 92 | + } |
| 93 | + //~ */ |
| 94 | + |
| 95 | + XFree(image); |
| 96 | + XCloseDisplay(display); |
| 97 | + |
| 98 | + gettimeofday(&end, NULL); |
| 99 | + printf("Time : %u msec\n", (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec)); |
| 100 | + |
| 101 | + FILE* fh = fopen("test-linux.raw", "wb"); |
| 102 | + fwrite(pixels, sizeof(unsigned char), sizeof(unsigned char) * width * height * 3, fh); |
| 103 | + fclose(fh); |
| 104 | + return 0; |
| 105 | +} |
0 commit comments