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

Reply via email to