Created
August 23, 2012 13:54
-
-
Save xiaolu/3436831 to your computer and use it in GitHub Desktop.
Screen snap for cwm recovery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LOCAL_PATH:= $(call my-dir) | |
include $(CLEAR_VARS) | |
LOCAL_ARM_MODE := arm | |
LOCAL_SRC_FILES := \ | |
gsnap.c | |
LOCAL_C_INCLUDES += \ | |
external/libpng \ | |
external/zlib | |
LOCAL_MODULE_TAGS := eng | |
LOCAL_MODULE := libgsnap | |
include $(BUILD_STATIC_LIBRARY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* File: gsnap.c | |
* Author: Li XianJing <[email protected]> | |
* Brief: snap the linux mobile device screen. | |
* | |
* Copyright (c) 2009 Li XianJing <[email protected]> | |
* | |
* Licensed under the Academic Free License version 2.1 | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation; either version 2 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
*/ | |
/* | |
* History: | |
* ================================================================ | |
* 2009-08-20 Li XianJing <[email protected]> created | |
* 2011-02-28 Li XianJing <[email protected]> suppport RGB888 framebuffer. | |
* 2011-04-09 Li XianJing <[email protected]> merge figofuture's png output. | |
* ref: http://blog.chinaunix.net/space.php?uid=15059847&do=blog&cuid=2040565 | |
* 2012-08-23 xiaolu <[email protected]> midify image write method. | |
*/ | |
#include <png.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <linux/fb.h> | |
#include <linux/kd.h> | |
struct _FBInfo; | |
typedef struct _FBInfo FBInfo; | |
typedef int (*UnpackPixel)(FBInfo* fb, unsigned char* pixel, | |
unsigned char* r, unsigned char* g, unsigned char* b); | |
struct _FBInfo | |
{ | |
int fd; | |
UnpackPixel unpack; | |
unsigned char *bits; | |
struct fb_fix_screeninfo fi; | |
struct fb_var_screeninfo vi; | |
}; | |
#define fb_width(fb) ((fb)->vi.xres) | |
#define fb_height(fb) ((fb)->vi.yres) | |
#define fb_bpp(fb) ((fb)->vi.bits_per_pixel>>3) | |
#define fb_size(fb) ((fb)->vi.xres * (fb)->vi.yres * fb_bpp(fb)) | |
static int fb_unpack_rgb565(FBInfo* fb, unsigned char* pixel, | |
unsigned char* r, unsigned char* g, unsigned char* b) | |
{ | |
unsigned short color = *(unsigned short*)pixel; | |
*r = ((color >> 11) & 0xff) << 3; | |
*g = ((color >> 5) & 0xff) << 2; | |
*b = (color & 0xff )<< 3; | |
return 0; | |
} | |
static int fb_unpack_rgb24(FBInfo* fb, unsigned char* pixel, | |
unsigned char* r, unsigned char* g, unsigned char* b) | |
{ | |
*r = pixel[fb->vi.red.offset>>3]; | |
*g = pixel[fb->vi.green.offset>>3]; | |
*b = pixel[fb->vi.blue.offset>>3]; | |
return 0; | |
} | |
static int fb_unpack_argb32(FBInfo* fb, unsigned char* pixel, | |
unsigned char* r, unsigned char* g, unsigned char* b) | |
{ | |
*r = pixel[fb->vi.red.offset>>3]; | |
*g = pixel[fb->vi.green.offset>>3]; | |
*b = pixel[fb->vi.blue.offset>>3]; | |
return 0; | |
} | |
static int fb_unpack_none(FBInfo* fb, unsigned char* pixel, | |
unsigned char* r, unsigned char* g, unsigned char* b) | |
{ | |
*r = *g = *b = 0; | |
return 0; | |
} | |
static void set_pixel_unpacker(FBInfo* fb) | |
{ | |
if(fb_bpp(fb) == 2) | |
{ | |
fb->unpack = fb_unpack_rgb565; | |
} | |
else if(fb_bpp(fb) == 3) | |
{ | |
fb->unpack = fb_unpack_rgb24; | |
} | |
else if(fb_bpp(fb) == 4) | |
{ | |
fb->unpack = fb_unpack_argb32; | |
} | |
else | |
{ | |
fb->unpack = fb_unpack_none; | |
printf("%s: not supported format.\n", __func__); | |
} | |
return; | |
} | |
static int fb_open(FBInfo* fb, const char* fbfilename) | |
{ | |
fb->fd = open(fbfilename, O_RDWR); | |
if (fb->fd < 0) | |
{ | |
fprintf(stderr, "can't open %s\n", fbfilename); | |
return -1; | |
} | |
if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) | |
goto fail; | |
if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) | |
goto fail; | |
fb->bits = mmap(0, fb_size(fb), PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); | |
if (fb->bits == MAP_FAILED) | |
goto fail; | |
printf("---------------framebuffer---------------\n"); | |
printf("%s: \n width : %8d\n height: %8d\n bpp : %8d\n r(%2d, %2d)\n g(%2d, %2d)\n b(%2d, %2d)\n", | |
fbfilename, fb_width(fb), fb_height(fb), fb_bpp(fb), | |
fb->vi.red.offset, fb->vi.red.length, | |
fb->vi.green.offset, fb->vi.green.length, | |
fb->vi.blue.offset, fb->vi.blue.length); | |
printf("-----------------------------------------\n"); | |
set_pixel_unpacker(fb); | |
return 0; | |
fail: | |
printf("%s is not a framebuffer.\n", fbfilename); | |
close(fb->fd); | |
return -1; | |
} | |
static void fb_close(FBInfo* fb) | |
{ | |
munmap(fb->bits, fb_size(fb)); | |
close(fb->fd); | |
return; | |
} | |
//Ref: http://blog.chinaunix.net/space.php?uid=15059847&do=blog&cuid=2040565 | |
static int snap2png(const char * filename, int quality, FBInfo* fb) | |
{ | |
FILE *outfile; | |
if ((outfile = fopen(filename, "wb+")) == NULL) | |
{ | |
fprintf(stderr, "can't open %s\n", filename); | |
return -1; | |
} | |
/* prepare the standard PNG structures */ | |
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | |
png_infop info_ptr = png_create_info_struct(png_ptr); | |
/* setjmp() must be called in every function that calls a PNG-reading libpng function */ | |
if (setjmp(png_jmpbuf(png_ptr))) | |
{ | |
png_destroy_write_struct(&png_ptr, &info_ptr); | |
fclose(outfile); | |
return -1; | |
} | |
/* initialize the png structure */ | |
png_init_io(png_ptr, outfile); | |
// | |
int width = fb_width(fb); | |
int height = fb_height(fb); | |
int bit_depth = 8; | |
int color_type = PNG_COLOR_TYPE_RGB; | |
int interlace = 0; | |
png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, | |
(!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, | |
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); | |
/* write the file header information */ | |
png_write_info(png_ptr, info_ptr); | |
png_bytep* row_pointers; | |
row_pointers = (png_bytep*)malloc(height*sizeof(png_bytep)); | |
int i = 0; | |
int j = 0; | |
unsigned char* line = NULL; | |
for(i = 0; i < height; i++ ) | |
{ | |
row_pointers[i] = (png_bytep)malloc(sizeof(unsigned char)*width*3); | |
line = (unsigned char*)fb->bits + i * width * fb_bpp(fb); | |
for(j = 0; j < width; j++, line += fb_bpp(fb)) | |
{ | |
int offset = j * 3; | |
fb->unpack(fb, line, row_pointers[i]+offset, row_pointers[i]+offset+1, row_pointers[i]+offset+2); | |
} | |
} | |
//All at once write | |
png_write_image(png_ptr, row_pointers); | |
if (setjmp(png_jmpbuf(png_ptr))) | |
{ | |
printf("[write_png_file] Error during end of write"); | |
return -1; | |
} | |
png_write_end(png_ptr, NULL); | |
fclose(outfile); | |
for(i = 0; i < height; i++ ) free(row_pointers[i]); | |
free(row_pointers); | |
png_destroy_write_struct(&png_ptr, &info_ptr); | |
return 0; | |
} | |
int gsnap_main(int argc, char* argv[]) | |
{ | |
FBInfo fb; | |
char* filename = NULL; | |
char* fbfilename = "/dev/graphics/fb0"; | |
if (argc != 2 && argc != 3) | |
{ | |
printf("\nUsage: %s [png file] [framebuffer dev]\n", argv[0]); | |
printf("Framebuffer dev default: %s\n", fbfilename); | |
printf("Example: %s /sdcard/1.png\n", argv[0]); | |
printf(" %s /sdcard/1.png /dev/graphics/fb0\n", argv[0]); | |
printf("-----------------------------------------------------------\n"); | |
return 0; | |
} | |
filename = argv[1]; | |
if (argc == 3) fbfilename = argv[2]; | |
memset(&fb, 0x00, sizeof(fb)); | |
if (fb_open(&fb, fbfilename) == 0) | |
{ | |
snap2png(filename, 100, &fb); | |
fb_close(&fb); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GSNAP_H | |
#define GSNAP_H | |
int gsnap_main(int argc, char** argv); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@koush
Snap screen for cwm recovery
https://gist.github.com/3436831