Signed-off-by: Xiangfu Liu <[email protected]> --- src/Makefile | 2 +- src/fbgrab.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/fbgrab.h | 23 +++++++ src/pngload.c | 59 +++++++++++++++++++ src/pngload.h | 3 +- src/shellext.c | 174 ++------------------------------------------------------ 6 files changed, 250 insertions(+), 171 deletions(-) create mode 100644 src/fbgrab.c create mode 100644 src/fbgrab.h
diff --git a/src/Makefile b/src/Makefile index e29f514..90526e0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,7 +15,7 @@ OBJDIR=obj BINDIR=bin # base -OBJS=shellext.o sysconfig.o config.o fb.o input.o reboot.o osc.o pngload.o flashvalid.o main.o +OBJS=shellext.o sysconfig.o config.o fb.o input.o reboot.o osc.o pngload.o flashvalid.o main.o fbgrab.o # GUI OBJS+=messagebox.o filedialog.o resmgr.o guirender.o performance.o cp.o keyboard.o ir.o audio.o midi.o oscsettings.o dmxspy.o dmxtable.o dmx.o videoin.o patcheditor.o monitor.o firstpatch.o sysettings.o about.o flash.o shutdown.o diff --git a/src/fbgrab.c b/src/fbgrab.c new file mode 100644 index 0000000..02c7686 --- /dev/null +++ b/src/fbgrab.c @@ -0,0 +1,160 @@ +/* + * Flickernoise + * Copyright (C) 2010, 2011 Sebastien Bourdeauducq + * Copyright (C) 2011 Xiangfu Liu + * + * 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, version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <rtems.h> +#include <rtems/fb.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <png.h> + +#include "pngload.h" +#include "fbgrab.h" + +static char *filename = "/flash/Screenshot-00.png"; + +static char *get_name() +{ + struct stat st; + int i, result; + for(i=0;i<100;i++) { + result = stat(filename, &st); + if (result < 0) { + if (errno == ENOENT) + break; + } else + sprintf(filename + 18, "%02d.png", i); + } + + return filename; +} + +static void convert565to32(int width, int height, + unsigned char *inbuffer, + unsigned char *outbuffer) +{ + unsigned int i; + + for (i=0; i < height*width*2; i+=2) + { + /* BLUE = 0 */ + outbuffer[(i<<1)+0] = (inbuffer[i+1] & 0x1f) << 3; + /* GREEN = 1 */ + outbuffer[(i<<1)+1] = + (((inbuffer[i] & 0x7) << 3) | (inbuffer[i+1] & 0xE0) >> 5) + << 2; + /* RED = 2 */ + outbuffer[(i<<1)+2] = (inbuffer[i] & 0xF8); + /* ALPHA = 3 */ + outbuffer[(i<<1)+3] = '\0'; + } +} + +static int convert_and_write(unsigned char *inbuffer, char *filename, + int width, int height, int bits, int interlace) +{ + int ret = 0; + + size_t bufsize = width * height * 4; + + unsigned char *outbuffer = malloc(bufsize); + if (outbuffer == NULL) { + fprintf(stderr, "Not enough memory"); + return -1; + } + + memset(outbuffer, 0, bufsize); + + printf("grab screen to %s\n", filename); + + switch (bits) { + case 16: + convert565to32(width, height, inbuffer, outbuffer); + ret = png_write(outbuffer, filename, width, height, interlace); + break; + case 15: + case 24: + case 32: + default: + fprintf(stderr, "%d bits per pixel are not supported! ", bits); + } + + free(outbuffer); + + return ret; +} + +int fbgrab(char *fn) +{ + int fd; + unsigned char *buf_p; + int ret = 0; + struct fb_var_screeninfo fb_var; + unsigned int bitdepth = 16; + size_t width; + size_t height; + size_t buf_size; + int interlace = PNG_INTERLACE_NONE; + + char *device = "/dev/fb"; + char *outfile = NULL; + + if(fn == NULL) { + outfile = get_name(); + } else + outfile = fn; + + fd = open(device, O_RDONLY); + if(fd == -1) { + perror("Unable to open /dev/fb"); + return 2; + } + + ioctl(fd, FBIOGET_VSCREENINFO, &fb_var); + width = fb_var.xres; + height = fb_var.yres; + buf_size = width * height * 2; + + buf_p = malloc(buf_size); + if(buf_p == NULL) { + fprintf(stderr, "Unable to get %d bytes memory\n", buf_size); + ret = 3; + goto close0; + } + + if(read(fd, buf_p, buf_size) != buf_size) { + perror("Unable to read device"); + ret = 4; + goto free0; + } + + ret = convert_and_write(buf_p, outfile, + width, height, bitdepth, + interlace); +free0: + free(buf_p); +close0: + close(fd); + + return ret; +} diff --git a/src/fbgrab.h b/src/fbgrab.h new file mode 100644 index 0000000..2b704cc --- /dev/null +++ b/src/fbgrab.h @@ -0,0 +1,23 @@ +/* + * Flickernoise + * Copyright (C) 2010 Sebastien Bourdeauducq + * + * 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, version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __FBGRAB_H +#define __FBGRAB_H + +int fbgrab(char *fn); + +#endif /* FBGRAB_H */ diff --git a/src/pngload.c b/src/pngload.c index c0b9a30..4df4b32 100644 --- a/src/pngload.c +++ b/src/pngload.c @@ -196,3 +196,62 @@ free1: free0: return ret; } + +int png_write(unsigned char *outbuffer, const char *filename, + int width, int height, int interlace) +{ + int i; + int bit_depth = 0, color_type; + png_bytep row_pointers[height]; + png_structp png_ptr; + png_infop info_ptr; + FILE *outfile; + + for (i=0; i<height; i++) + row_pointers[i] = outbuffer + i * 4 * width; + + outfile = fopen(filename, "w"); + if (outfile == NULL) { + perror("Error: Couldn't fopen"); + return -1; + } + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) { + fprintf(stderr, "Error: Couldn't create PNG write struct"); + return -1; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + fprintf(stderr, "Error: Couldn't create PNG info struct"); + return -1; + } + + png_init_io(png_ptr, outfile); + + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + + bit_depth = 8; + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + png_set_invert_alpha(png_ptr); + png_set_bgr(png_ptr); + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png_ptr, info_ptr); + + png_write_image(png_ptr, row_pointers); + + png_write_end(png_ptr, info_ptr); + /* puh, done, now freeing memory... */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + fclose(outfile); + + return 0; +} diff --git a/src/pngload.h b/src/pngload.h index 111e010..64659ec 100644 --- a/src/pngload.h +++ b/src/pngload.h @@ -19,5 +19,6 @@ #define __PNGLOAD_H unsigned short *png_load(const char *filename, unsigned int *w, unsigned int *h); - +int png_write(unsigned char *outbuffer, const char *filename, + int width, int height, int interlace); #endif /* __PNGLOAD_H */ diff --git a/src/shellext.c b/src/shellext.c index aa42eb4..3f61a07 100644 --- a/src/shellext.c +++ b/src/shellext.c @@ -18,7 +18,6 @@ #include <rtems.h> #include <rtems/shell.h> -#include <rtems/fb.h> #include <bsp/milkymist_flash.h> #include <sys/ioctl.h> #include <sys/types.h> @@ -26,10 +25,9 @@ #include <fcntl.h> #include <unistd.h> #include <stdio.h> -#include <stdlib.h> -#include <png.h> #include "shellext.h" +#include "fbgrab.h" int main_erase(int argc, char **argv) { @@ -91,175 +89,13 @@ rtems_shell_cmd_t shell_usercmd = { NULL /* next */ }; -static int write_PNG(unsigned char *outbuffer, char *filename, - int width, int height, int interlace) -{ - int i; - int bit_depth = 0, color_type; - png_bytep row_pointers[height]; - png_structp png_ptr; - png_infop info_ptr; - FILE *outfile; - - for (i=0; i<height; i++) - row_pointers[i] = outbuffer + i * 4 * width; - - outfile = fopen(filename, "w"); - if (outfile == NULL) { - perror("Error: Couldn't fopen"); - return -1; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!png_ptr) { - fprintf(stderr, "Error: Couldn't create PNG write struct"); - return -1; - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, (png_infopp) NULL); - fprintf(stderr, "Error: Couldn't create PNG info struct"); - return -1; - } - - png_init_io(png_ptr, outfile); - - png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); - - bit_depth = 8; - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - png_set_invert_alpha(png_ptr); - png_set_bgr(png_ptr); - - png_set_IHDR(png_ptr, info_ptr, width, height, - bit_depth, color_type, interlace, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - png_write_info(png_ptr, info_ptr); - - printf("Now writing PNG file...\n"); - - png_write_image(png_ptr, row_pointers); - - png_write_end(png_ptr, info_ptr); - /* puh, done, now freeing memory... */ - png_destroy_write_struct(&png_ptr, &info_ptr); - - if (outfile != NULL) - fclose(outfile); - - return 0; -} - -static void convert565to32(int width, int height, - unsigned char *inbuffer, - unsigned char *outbuffer) -{ - unsigned int i; - - for (i=0; i < height*width*2; i+=2) - { - /* BLUE = 0 */ - outbuffer[(i<<1)+0] = (inbuffer[i+1] & 0x1f) << 3; - /* GREEN = 1 */ - outbuffer[(i<<1)+1] = - (((inbuffer[i] & 0x7) << 3) | (inbuffer[i+1] & 0xE0) >> 5) - << 2; - /* RED = 2 */ - outbuffer[(i<<1)+2] = (inbuffer[i] & 0xF8); - /* ALPHA = 3 */ - outbuffer[(i<<1)+3] = '\0'; - } -} - -static int convert_and_write(unsigned char *inbuffer, char *filename, - int width, int height, int bits, int interlace) -{ - int ret = 0; - - size_t bufsize = width * height * 4; - - unsigned char *outbuffer = malloc(bufsize); - if (outbuffer == NULL) { - fprintf(stderr, "Not enough memory"); - return -1; - } - - memset(outbuffer, 0, bufsize); - - printf("Converting image from %i\n", bits); - - switch (bits) { - case 16: - convert565to32(width, height, inbuffer, outbuffer); - ret = write_PNG(outbuffer, filename, width, height, interlace); - break; - case 15: - case 24: - case 32: - default: - fprintf(stderr, "%d bits per pixel are not supported! ", bits); - } - - free(outbuffer); - - return ret; -} - int main_fbgrab(int argc, char **argv) { - int fd; - unsigned char *buf_p; int ret = 0; - struct fb_var_screeninfo fb_var; - unsigned int bitdepth = 16; - size_t width; - size_t height; - size_t buf_size; - int interlace = PNG_INTERLACE_NONE; - - char *device = "/dev/fb"; - char *outfile = NULL; - - if(argc != 2) { - fprintf(stderr, "%s: you must specify a file name\n", argv[0]); - return 1; - } - outfile = argv[1]; - - fd = open(device, O_RDONLY); - if(fd == -1) { - perror("Unable to open /dev/fb"); - return 2; - } - - ioctl(fd, FBIOGET_VSCREENINFO, &fb_var); - width = fb_var.xres; - height = fb_var.yres; - buf_size = width * height * 2; - - buf_p = malloc(buf_size); - if(buf_p == NULL) { - fprintf(stderr, "Unable to get %d bytes memory\n", buf_size); - ret = 3; - goto close0; - } - - if(read(fd, buf_p, buf_size) != buf_size) { - perror("Unable to read device"); - ret = 4; - goto free0; - } - - ret = convert_and_write(buf_p, outfile, - width, height, bitdepth, - interlace); -free0: - free(buf_p); -close0: - close(fd); + if(argc == 2) + ret = fbgrab(argv[1]); + else + ret = fbgrab(NULL); return ret; } -- 1.7.0.4 _______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkymist@Freenode Twitter: www.twitter.com/milkymistvj Ideas? http://milkymist.uservoice.com
