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/fb.c b/fb2png/fb.c
new file mode 100644
index 0000000..2ed4789
--- /dev/null
+++ b/fb2png/fb.c
@@ -0,0 +1,132 @@
+/*
+ *   -- http://android-fb2png.googlecode.com/svn/trunk/fb.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 <unistd.h>
+#include <errno.h>
+
+#include "log.h"
+#include "fb.h"
+#include "img_process.h"
+
+void fb_dump(const struct fb* fb)
+{
+    D("%12s : %d", "bpp", fb->bpp);
+    D("%12s : %d", "size", fb->size);
+    D("%12s : %d", "width", fb->width);
+    D("%12s : %d", "height", fb->height);
+    D("%12s : %d %d %d %d", "ARGB offset",
+            fb->alpha_offset, fb->red_offset,
+            fb->green_offset, fb->blue_offset);
+    D("%12s : %d %d %d %d", "ARGB length",
+            fb->alpha_length, fb->red_length,
+            fb->green_length, fb->blue_length);
+}
+
+/**
+ * Returns the format of fb.
+ */
+static int fb_get_format(const struct fb *fb)
+{
+    int ao = fb->alpha_offset;
+    int ro = fb->red_offset;
+    int go = fb->green_offset;
+    int bo = fb->blue_offset;
+
+#define FB_FORMAT_UNKNOWN   0
+#define FB_FORMAT_RGB565    1
+#define FB_FORMAT_ARGB8888  2
+#define FB_FORMAT_RGBA8888  3
+#define FB_FORMAT_ABGR8888  4
+#define FB_FORMAT_BGRA8888  5
+
+    /* TODO: use offset */
+    if (fb->bpp == 16)
+        return FB_FORMAT_RGB565;
+
+    /* TODO: validate */
+    if (ao == 0 && ro == 8)
+        return FB_FORMAT_ARGB8888;
+
+    if (ao == 0 && bo == 8)
+        return FB_FORMAT_ABGR8888;
+
+    if (ro == 0)
+        return FB_FORMAT_RGBA8888;
+
+    if (bo == 0)
+        return FB_FORMAT_BGRA8888;
+
+    /* fallback */
+    return FB_FORMAT_UNKNOWN;
+}
+
+int fb_save_png(const struct fb *fb, const char *path)
+{
+    char *rgb_matrix;
+    int ret = -1;
+
+    /* Allocate RGB Matrix. */
+    rgb_matrix = malloc(fb->width * fb->height * 3);
+    if(!rgb_matrix) {
+        free(rgb_matrix);
+        return -1;
+    }
+
+    int fmt = fb_get_format(fb);
+    D("Framebuffer Pixel Format: %d", fmt);
+
+    switch(fmt) {
+        case FB_FORMAT_RGB565:
+            /* emulator use rgb565 */
+            ret = rgb565_to_rgb888(fb->data,
+                    rgb_matrix, fb->width * fb->height);
+            break;
+        case FB_FORMAT_ARGB8888:
+            /* most devices use argb8888 */
+            ret = argb8888_to_rgb888(fb->data,
+                    rgb_matrix, fb->width * fb->height);
+            break;
+        case FB_FORMAT_ABGR8888:
+            ret = abgr8888_to_rgb888(fb->data,
+                    rgb_matrix, fb->width * fb->height);
+            break;
+        case FB_FORMAT_BGRA8888:
+            ret = bgra8888_to_rgb888(fb->data,
+                    rgb_matrix, fb->width * fb->height);
+            break;
+        case FB_FORMAT_RGBA8888:
+            ret = rgba8888_to_rgb888(fb->data,
+                    rgb_matrix, fb->width * fb->height);
+            break;
+        default:
+            D("Unsupported framebuffer type.");
+            break;
+    }
+
+    if (ret != 0)
+        D("Error while processing input image.");
+    else if (0 != (ret = save_png(path, rgb_matrix, fb->width, fb->height)))
+        D("Failed to save in PNG format.");
+
+    free(rgb_matrix);
+    return ret;
+}