xscreenshot improvements, thanks sin and frign! - xscreenshot - screen capture tool
 (HTM) git clone git://git.codemadness.org/xscreenshot
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d027bcf68df72a92e3b0f6d2b7b97e73e736f4ed
 (DIR) parent 82ccf27dff05c70fe7c0bcde466edb9a36aa0314
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Mon, 28 Jul 2014 15:21:28 +0000
       
       xscreenshot improvements, thanks sin and frign!
       
       - use imagefile tools for conversion, don't depend on libpng anymore
         directly.
       - use XGetPixel to get pixel values.
       - update documentation accordingly.
       
       Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
       
       Diffstat:
         M LICENSE                             |       2 ++
         M README                              |      15 ++++++++++-----
         M TODO                                |       2 --
         M config.mk                           |       2 +-
         M xscreenshot.c                       |     105 ++++++++-----------------------
       
       5 files changed, 38 insertions(+), 88 deletions(-)
       ---
 (DIR) diff --git a/LICENSE b/LICENSE
       @@ -1,6 +1,8 @@
        MIT/X Consortium License
        
        (c) 2014 Hiltjo Posthuma <hiltjo@codemadness.org>
       +(c) 2014 sin <sin@2f30.org>
       +(c) 2014 Laslo Hunhold <dev@frign.de>
        
        Permission is hereby granted, free of charge, to any person obtaining a
        copy of this software and associated documentation files (the "Software"),
 (DIR) diff --git a/README b/README
       @@ -7,22 +7,27 @@ xscreenshot is a simple screenshot utility. It writes image data to stdout.
        Dependencies
        ------------
        
       -- libpng
        - libX11
        
        
       +Optional dependencies
       +---------------------
       +
       +- To convert imagefile data you can use if2png from:
       +  http://git.2f30.org/imagefile
       +
        Compile
        -------
        
       -run make or:
       -
       -cc xscreenshot.c -o xscreenshot -lX11 -lpng
       +$ make
       +# make install
        
        
        Usage
        -----
        
       -xscreenshot [winid] > file.png
       +xscreenshot [winid] > file.if
       +if2png < file.if > file.png
        
        
        Known issues
 (DIR) diff --git a/TODO b/TODO
       @@ -1,3 +1 @@
       -[ ] I might have missed a few cases of color conversion (convertrow_*).
        [ ] better multi-monitor support.
       -[ ] write a "if" output:  http://git.2f30.org/imagefile/.
 (DIR) diff --git a/config.mk b/config.mk
       @@ -8,7 +8,7 @@ MANPREFIX = ${PREFIX}/share/man
        
        # includes and libs
        INCS =
       -LIBS = -lc -lpng -lX11
       +LIBS = -lc -lX11
        
        # debug
        CFLAGS = -O0 -g -std=c99 -Wall -Wextra -pedantic \
 (DIR) diff --git a/xscreenshot.c b/xscreenshot.c
       @@ -8,8 +8,7 @@
        #include <X11/X.h>
        #include <X11/Xlib.h>
        #include <X11/Xutil.h>
       -
       -#include <png.h>
       +#include <arpa/inet.h>
        
        static void
        die(const char *s) {
       @@ -17,82 +16,6 @@ die(const char *s) {
                exit(EXIT_FAILURE);
        }
        
       -/* LSBFirst: BGRA -> RGBA */
       -static void
       -convertrow_lsb(unsigned char *drow, unsigned char *srow, XImage *img) {
       -        int sx, dx;
       -
       -        for(sx = 0, dx = 0; dx < img->bytes_per_line - 4; sx += 4) {
       -                drow[dx++] = srow[sx + 2]; /* B -> R */
       -                drow[dx++] = srow[sx + 1]; /* G -> G */
       -                drow[dx++] = srow[sx];     /* R -> B */
       -                if(img->depth == 32)
       -                        drow[dx++] = srow[sx + 3]; /* A -> A */
       -                else
       -                        drow[dx++] = 255;
       -        }
       -}
       -
       -/* MSBFirst: ARGB -> RGBA */
       -static void
       -convertrow_msb(unsigned char *drow, unsigned char *srow, XImage *img) {
       -        int sx, dx;
       -
       -        for(sx = 0, dx = 0; dx < img->bytes_per_line - 4; sx += 4) {
       -                drow[dx++] = srow[sx + 1]; /* G -> R */
       -                drow[dx++] = srow[sx + 2]; /* B -> G */
       -                drow[dx++] = srow[sx + 3]; /* A -> B */
       -                if(img->depth == 32)
       -                        drow[dx++] = srow[sx]; /* R -> A */
       -                else
       -                        drow[dx++] = 255;
       -        }
       -}
       -
       -static void
       -pngstdout(XImage *img)
       -{
       -        png_structp png_struct_p;
       -        png_infop png_info_p;
       -        void (*convert)(unsigned char *, unsigned char *, XImage *);
       -        unsigned char *drow = NULL, *srow;
       -        int h;
       -
       -        png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
       -                                               NULL);
       -        png_info_p = png_create_info_struct(png_struct_p);
       -
       -        if(!png_struct_p || !png_info_p || setjmp(png_jmpbuf(png_struct_p)))
       -                die("failed to initialize libpng");
       -
       -        png_init_io(png_struct_p, stdout);
       -        png_set_IHDR(png_struct_p, png_info_p, img->width, img->height, 8,
       -                     PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
       -                     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
       -        png_write_info(png_struct_p, png_info_p);
       -
       -        srow = (unsigned char *)img->data;
       -        drow = calloc(1, img->width * 4); /* output RGBA */
       -        if(!drow)
       -                die("Can't calloc");
       -
       -        if(img->byte_order == LSBFirst)
       -                convert = convertrow_lsb;
       -        else
       -                convert = convertrow_msb;
       -
       -        for(h = 0; h < img->height; h++) {
       -                convert(drow, srow, img);
       -                srow += img->bytes_per_line;
       -                png_write_row(png_struct_p, drow);
       -        }
       -        png_write_end(png_struct_p, NULL);
       -
       -        free(drow);
       -        png_free_data(png_struct_p, png_info_p, PNG_FREE_ALL, -1);
       -        png_destroy_write_struct(&png_struct_p, NULL);
       -}
       -
        static void
        usage(void)
        {
       @@ -108,12 +31,15 @@ main(int argc, char *argv[])
                Display *dpy;
                Window win;
                XWindowAttributes attr;
       +        uint32_t tmp, pix;
       +        uint8_t rgba[4] = {0, 0, 0, 255};
       +        int w, h;
        
                dpy = XOpenDisplay(NULL);
                if(!dpy)
                        die("Can't XOpenDisplay");
        
       -        /* win */
       +        /* identify window */
                if(argc > 1) {
                        if(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-v") == 0)
                                usage();
       @@ -133,7 +59,26 @@ main(int argc, char *argv[])
                XCloseDisplay(dpy);
                if(!img)
                        die("Can't XGetImage");
       -        pngstdout(img);
       +
       +        /* write header with big endian width and height-values */
       +        fprintf(stdout, "imagefile");
       +        tmp = htonl(img->width);
       +        fwrite(&tmp, sizeof(uint32_t), 1, stdout);
       +        tmp = htonl(img->height);
       +        fwrite(&tmp, sizeof(uint32_t), 1, stdout);
       +
       +        /* write pixels */
       +        for(h = 0; h < img->height; ++h) {
       +                for(w = 0; w < img->width; ++w) {
       +                        pix = XGetPixel(img, w, h);
       +                        rgba[0] = (pix & img->red_mask)   >> 16;
       +                        rgba[1] = (pix & img->green_mask) >> 8;
       +                        rgba[2] = (pix & img->blue_mask)  >> 0;
       +                        if(fwrite(&rgba, sizeof(uint8_t), 4, stdout) != 4)
       +                                die("fwrite() failed");
       +                }
       +        }
       +
                XDestroyImage(img);
        
                return EXIT_SUCCESS;