// filename: shot.c
#include
#include
#include
#include
#include
#include
#include
#include
/* 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; 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; 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 writeaspng(XImage *img, FILE *fp)
{
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);
png_init_io(png_struct_p, fp);
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);
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);
}
int main(int argc, char* argv[])
{
Display *display = XOpenDisplay(":0");
int screen = XDefaultScreen(display);
Window root = RootWindow(display, screen);
XImage *image = XGetImage(
display, root, 0, 0,
DisplayWidth(display, screen), DisplayHeight(display, screen),
AllPlanes, ZPixmap );
char filename[64];
sprintf(filename, "%ld.png", time(NULL));
printf("Info: filename is %sn", filename);
FILE *fp;
fp = fopen(filename, "wb");
writeaspng(image, fp);
fclose(fp);
XCloseDisplay(display);
return 0;
}