#include #include #include #include #include #include #include #include #include #include "private/android_filesystem_config.h" #define LOG_TAG "screenshot" #include void take_screenshot(FILE *fb_in, FILE *fb_out) { int fb; char imgbuf[0x10000]; struct fb_var_screeninfo vinfo; png_structp png; png_infop info; unsigned int r,c,rowlen; unsigned int bytespp,offset; fb = fileno(fb_in); if(fb < 0) { ALOGE("failed to open framebuffer\n"); return; } fb_in = fdopen(fb, "r"); if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) { ALOGE("failed to get framebuffer info\n"); return; } fcntl(fb, F_SETFD, FD_CLOEXEC); png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png == NULL) { ALOGE("failed png_create_write_struct\n"); fclose(fb_in); return; } png_init_io(png, fb_out); info = png_create_info_struct(png); if (info == NULL) { ALOGE("failed png_create_info_struct\n"); png_destroy_write_struct(&png, NULL); fclose(fb_in); return; } if (setjmp(png_jmpbuf(png))) { ALOGE("failed png setjmp\n"); png_destroy_write_struct(&png, NULL); fclose(fb_in); return; } bytespp = vinfo.bits_per_pixel / 8; png_set_IHDR(png, info, vinfo.xres, vinfo.yres, vinfo.bits_per_pixel / 4, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png, info); rowlen=vinfo.xres * bytespp; if (rowlen > sizeof(imgbuf)) { ALOGE("crazy rowlen: %d\n", rowlen); png_destroy_write_struct(&png, NULL); fclose(fb_in); return; } offset = vinfo.xoffset * bytespp + vinfo.xres * vinfo.yoffset * bytespp; fseek(fb_in, offset, SEEK_SET); for(r=0; r