FB2PNG: Add fb2png source to TWRP

  * Add Source of fb2png to TWRP tree
  * Android.mk by PhilZ-cwm6
  * Makefile for CrossCompiling via external toolchan by me (Talustus)

Change-Id: If9680688df6e4c9c567f74f46dfc303566b868ba
diff --git a/fb2png/adb_screenshoot.c b/fb2png/adb_screenshoot.c
new file mode 100644
index 0000000..afd54ca
--- /dev/null
+++ b/fb2png/adb_screenshoot.c
@@ -0,0 +1,191 @@
+/*
+ *   -- http://android-fb2png.googlecode.com/svn/trunk/adb_screenshoot.c --
+ *
+ *   Copyright 2011, Kyan He <kyan.ql.he@gmail.com>
+ *
+ *
+ *   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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include "fb.h"
+#include "log.h"
+
+#define DEFAULT_SAVE_PATH "fbdump.png"
+
+/* defined in $T/system/core/adb/framebuffer_service.c */
+#define DDMS_RAWIMAGE_VERSION 1
+struct fbinfo {
+    unsigned int version;
+    unsigned int bpp;
+    unsigned int size;
+    unsigned int width;
+    unsigned int height;
+    unsigned int red_offset;
+    unsigned int red_length;
+    unsigned int blue_offset;
+    unsigned int blue_length;
+    unsigned int green_offset;
+    unsigned int green_length;
+    unsigned int alpha_offset;
+    unsigned int alpha_length;
+} __attribute__((packed));
+
+static int remote_socket(const char *host, int port)
+{
+    struct sockaddr_in sa;
+    struct hostent *hp;
+    int s;
+
+    if(!(hp = gethostbyname(host))){ return -1; }
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sin_port = htons(port);
+    sa.sin_family = hp->h_addrtype;
+    memcpy((void*) &sa.sin_addr, (void*) hp->h_addr, hp->h_length);
+
+    if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
+        return -1;
+    }
+
+    if(connect(s, (struct sockaddr*) &sa, sizeof(sa)) != 0){
+        close(s);
+        return -1;
+    }
+
+    return s;
+}
+
+char *target = "usb";
+static int adb_fd;
+
+/**
+ * Write command through adb protocol.
+ * Return
+ *      Bytes have been wrote.
+ */
+static int adb_write(const char *cmd)
+{
+    char buf[1024];
+    int sz;
+
+    /* Construct command. */
+    sz = sprintf(buf, "%04x%s", strlen(cmd), cmd);
+
+    write(adb_fd, buf, sz);
+
+#if 0
+    D("<< %s", buf);
+#endif
+    return sz;
+}
+
+/**
+ * Read data through adb protocol.
+ * Return
+ *      Bytes have been read.
+ */
+static int adb_read(char *buf, int sz)
+{
+    sz = read(adb_fd, buf, sz);
+    if (sz < 0) {
+        E("Fail to read from adb socket, %s", strerror(errno));
+    }
+    buf[sz] = '\0';
+#if 0
+    D(">> %d", sz);
+#endif
+    return sz;
+}
+
+static int get_fb_from_adb(struct fb *fb)
+{
+    char buf[1024];
+    const struct fbinfo* fbinfo;
+
+    /* Init socket */
+    adb_fd = remote_socket("localhost", 5037);
+    if (adb_fd < 0) {
+        E("Fail to create socket, %s", strerror(errno));
+    }
+
+    adb_write("host:transport-");
+    adb_read(buf, 1024);
+
+    adb_write("framebuffer:");
+    adb_read(buf, 1024);
+
+    /* Parse FB header. */
+    adb_read(buf, sizeof(struct fbinfo));
+    fbinfo = (struct fbinfo*) buf;
+
+    if (fbinfo->version != DDMS_RAWIMAGE_VERSION) {
+        E("unspport adb version");
+    }
+
+    /* Assemble struct fb */
+    memcpy(fb, &fbinfo->bpp, sizeof(struct fbinfo) - 4);
+    fb_dump(fb);
+
+    fb->data = malloc(fb->size);
+    if (!fb->data) return -1;
+
+    /* Read out the whole framebuffer */
+    int bytes_read = 0;
+    while (bytes_read < fb->size) {
+        bytes_read += adb_read(fb->data + bytes_read, fb->size - bytes_read);
+    }
+
+    return 0;
+}
+
+int fb2png(const char* path)
+{
+    struct fb fb;
+
+    if (get_fb_from_adb(&fb)) {
+        D("cannot get framebuffer.");
+        return -1;
+    }
+
+    return fb_save_png(&fb, path);
+}
+
+int main(int argc, char *argv[])
+{
+    char fn[128];
+
+    if (argc == 2) {
+        //if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
+        if (argv[1][0] == '-') {
+            printf(
+                "Usage: fb2png [path/to/output.png]\n"
+                "    The default output path is ./fbdump.png\n"
+                );
+            exit(0);
+        } else {
+            sprintf(fn, "%s", argv[1]);
+        }
+    } else {
+        sprintf(fn, "%s", DEFAULT_SAVE_PATH);
+    }
+
+    return fb2png(fn);
+}