summaryrefslogtreecommitdiffstats
path: root/fb2png/fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fb2png/fb.c')
-rw-r--r--fb2png/fb.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/fb2png/fb.c b/fb2png/fb.c
new file mode 100644
index 000000000..2ed478902
--- /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;
+}