[PATCH 02/11] bmp: split bmp rending in lib/bmp.c

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Fri Sep 7 09:10:16 EDT 2012


So we can add other format support

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 commands/Kconfig     |    1 +
 commands/splash.c    |  124 +++++------------------------------------------
 include/bmp_layout.h |   11 +++++
 lib/Kconfig          |    3 ++
 lib/Makefile         |    1 +
 lib/bmp.c            |  132 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 159 insertions(+), 113 deletions(-)
 create mode 100644 lib/bmp.c

diff --git a/commands/Kconfig b/commands/Kconfig
index c4623fa..9107a3e 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -538,6 +538,7 @@ config CMD_LSMOD
 config CMD_SPLASH
 	bool
 	depends on VIDEO
+	select BMP
 	prompt "splash"
 	help
 	  show bmp files on framebuffer devices
diff --git a/commands/splash.c b/commands/splash.c
index 6526b20..ad73778 100644
--- a/commands/splash.c
+++ b/commands/splash.c
@@ -8,43 +8,18 @@
 #include <fcntl.h>
 #include <fb.h>
 #include <bmp_layout.h>
-#include <asm/byteorder.h>
-
-static inline void set_pixel(struct fb_info *info, void *adr, int r, int g, int b)
-{
-	u32 px;
-
-	px = (r >> (8 - info->red.length)) << info->red.offset |
-		(g >> (8 - info->green.length)) << info->green.offset |
-		(b >> (8 - info->blue.length)) << info->blue.offset;
-
-	switch (info->bits_per_pixel) {
-	case 8:
-		break;
-	case 16:
-		*(u16 *)adr = px;
-		break;
-	case 32:
-		*(u32 *)adr = px;
-		break;
-	}
-}
 
 static int do_splash(int argc, char *argv[])
 {
 	int ret, opt, fd;
 	char *fbdev = "/dev/fb0";
-	void *fb, *offscreenbuf = NULL;
+	void *fb;
 	struct fb_info info;
-	struct bmp_image *bmp;
 	char *bmpfile;
-	int bmpsize;
-	char *image;
-	int sw, sh, width, height, startx = -1, starty = -1;
-	int bits_per_pixel, fbsize;
+	int startx = -1, starty = -1;
 	int xres, yres;
 	int offscreen = 0;
-	void *adr, *buf;
+	void *offscreenbuf = NULL;
 
 	while((opt = getopt(argc, argv, "f:x:y:o")) > 0) {
 		switch(opt) {
@@ -88,105 +63,28 @@ static int do_splash(int argc, char *argv[])
 	xres = info.xres;
 	yres = info.yres;
 
-	bmp = read_file(bmpfile, &bmpsize);
-	if (!bmp) {
-		printf("unable to read %s\n", bmpfile);
-		goto failed_memmap;
-	}
-
-	if (bmp->header.signature[0] != 'B' ||
-	      bmp->header.signature[1] != 'M') {
-		printf("No valid bmp file\n");
-	}
-
-	sw = le32_to_cpu(bmp->header.width);
-	sh = le32_to_cpu(bmp->header.height);
-
-	if (startx < 0) {
-		startx = (xres - sw) / 2;
-		if (startx < 0)
-			startx = 0;
-	}
-
-	if (starty < 0) {
-		starty = (yres - sh) / 2;
-		if (starty < 0)
-			starty = 0;
-	}
-
-	width = min(sw, xres - startx);
-	height = min(sh, yres - starty);
-
-	bits_per_pixel = le16_to_cpu(bmp->header.bit_count);
-	fbsize = xres * yres * (info.bits_per_pixel >> 3);
-
 	if (offscreen) {
+		int fbsize;
 		/* Don't fail if malloc fails, just continue rendering directly
 		 * on the framebuffer
 		 */
+
+		fbsize = xres * yres * (info.bits_per_pixel >> 3);
 		offscreenbuf = malloc(fbsize);
 		if (offscreenbuf)
 			memcpy(offscreenbuf, fb, fbsize);
 	}
 
-	buf = offscreenbuf ? offscreenbuf : fb;
-
-	if (bits_per_pixel == 8) {
-		int x, y;
-		struct bmp_color_table_entry *color_table = bmp->color_table;
-
-		for (y = 0; y < height; y++) {
-			image = (char *)bmp +
-					le32_to_cpu(bmp->header.data_offset);
-			image += (sh - y - 1) * sw * (bits_per_pixel >> 3);
-			adr = buf + ((y + starty) * xres + startx) *
-					(info.bits_per_pixel >> 3);
-			for (x = 0; x < width; x++) {
-				int pixel;
+	if (bmp_render_file(&info, bmpfile, fb, startx, starty, xres, yres,
+			    offscreenbuf) < 0)
+		ret = 1;
 
-				pixel = *image;
-
-				set_pixel(&info, adr, color_table[pixel].red,
-						color_table[pixel].green,
-						color_table[pixel].blue);
-				adr += info.bits_per_pixel >> 3;
-
-				image += bits_per_pixel >> 3;
-			}
-		}
-	} else if (bits_per_pixel == 24) {
-		int x, y;
-
-		for (y = 0; y < height; y++) {
-			image = (char *)bmp +
-					le32_to_cpu(bmp->header.data_offset);
-			image += (sh - y - 1) * sw * (bits_per_pixel >> 3);
-			adr = buf + ((y + starty) * xres + startx) *
-					(info.bits_per_pixel >> 3);
-			for (x = 0; x < width; x++) {
-				char *pixel;
-
-				pixel = image;
-
-				set_pixel(&info, adr, pixel[2], pixel[1],
-						pixel[0]);
-				adr += info.bits_per_pixel >> 3;
-
-				image += bits_per_pixel >> 3;
-			}
-		}
-	} else
-		printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
-
-	if (offscreenbuf) {
-		memcpy(fb, offscreenbuf, fbsize);
+	if (offscreenbuf)
 		free(offscreenbuf);
-	}
 
-	free(bmp);
 	close(fd);
 
-	return 0;
+	return ret;
 
 failed_memmap:
 	close(fd);
diff --git a/include/bmp_layout.h b/include/bmp_layout.h
index 63c5564..b5472dd 100644
--- a/include/bmp_layout.h
+++ b/include/bmp_layout.h
@@ -74,4 +74,15 @@ struct bmp_image {
 #define BMP_BI_RLE8	1
 #define BMP_BI_RLE4	2
 
+#ifdef CONFIG_BMP
+int bmp_render_file(struct fb_info *info, const char* bmpfile, void* fb,
+		    int startx, int starty, int xres, int yres, void* offscreenbuf);
+#else
+static inline int bmp_render_file(struct fb_info *info, const char* bmpfile, void* fb,
+		    int startx, int starty, int xres, int yres, void* offscreenbuf)
+{
+	return -ENOSYS;
+}
+#endif
+
 #endif							/* _BMP_H_ */
diff --git a/lib/Kconfig b/lib/Kconfig
index 32634df..93e360b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -38,4 +38,7 @@ config BITREV
 config QSORT
 	bool
 
+config BMP
+	bool
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 4e6b1ee..df4b5e5 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_UNCOMPRESS)	+= uncompress.o
 obj-$(CONFIG_BCH)	+= bch.o
 obj-$(CONFIG_BITREV)	+= bitrev.o
 obj-$(CONFIG_QSORT)	+= qsort.o
+obj-$(CONFIG_BMP)	+= bmp.o
diff --git a/lib/bmp.c b/lib/bmp.c
new file mode 100644
index 0000000..776d3b3
--- /dev/null
+++ b/lib/bmp.c
@@ -0,0 +1,132 @@
+#include <common.h>
+#include <fs.h>
+#include <errno.h>
+#include <malloc.h>
+#include <fb.h>
+#include <bmp_layout.h>
+#include <asm/byteorder.h>
+
+static inline void set_pixel(struct fb_info *info, void *adr, int r, int g, int b)
+{
+	u32 px;
+
+	px = (r >> (8 - info->red.length)) << info->red.offset |
+		(g >> (8 - info->green.length)) << info->green.offset |
+		(b >> (8 - info->blue.length)) << info->blue.offset;
+
+	switch (info->bits_per_pixel) {
+	case 8:
+		break;
+	case 16:
+		*(u16 *)adr = px;
+		break;
+	case 32:
+		*(u32 *)adr = px;
+		break;
+	}
+}
+
+int bmp_render_file(struct fb_info *info, const char* bmpfile, void* fb,
+		    int startx, int starty, int xres, int yres, void* offscreenbuf)
+{
+	struct bmp_image *bmp;
+	int sw, sh, width, height;
+	int bits_per_pixel, fbsize;
+	int bmpsize;
+	int ret = 0;
+	void *adr, *buf;
+	char *image;
+
+	bmp = read_file(bmpfile, &bmpsize);
+	if (!bmp) {
+		printf("unable to read %s\n", bmpfile);
+		return -ENOMEM;
+	}
+
+	if (bmp->header.signature[0] != 'B' ||
+	      bmp->header.signature[1] != 'M') {
+		printf("No valid bmp file\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	sw = le32_to_cpu(bmp->header.width);
+	sh = le32_to_cpu(bmp->header.height);
+
+	if (startx < 0) {
+		startx = (xres - sw) / 2;
+		if (startx < 0)
+			startx = 0;
+	}
+
+	if (starty < 0) {
+		starty = (yres - sh) / 2;
+		if (starty < 0)
+			starty = 0;
+	}
+
+	width = min(sw, xres - startx);
+	height = min(sh, yres - starty);
+
+	bits_per_pixel = le16_to_cpu(bmp->header.bit_count);
+	fbsize = xres * yres * (info->bits_per_pixel >> 3);
+
+	buf = offscreenbuf ? offscreenbuf : fb;
+
+	if (bits_per_pixel == 8) {
+		int x, y;
+		struct bmp_color_table_entry *color_table = bmp->color_table;
+
+		for (y = 0; y < height; y++) {
+			image = (char *)bmp +
+					le32_to_cpu(bmp->header.data_offset);
+			image += (sh - y - 1) * sw * (bits_per_pixel >> 3);
+			adr = buf + ((y + starty) * xres + startx) *
+					(info->bits_per_pixel >> 3);
+			for (x = 0; x < width; x++) {
+				int pixel;
+
+				pixel = *image;
+
+				set_pixel(info, adr, color_table[pixel].red,
+						color_table[pixel].green,
+						color_table[pixel].blue);
+				adr += info->bits_per_pixel >> 3;
+
+				image += bits_per_pixel >> 3;
+			}
+		}
+	} else if (bits_per_pixel == 24) {
+		int x, y;
+
+		for (y = 0; y < height; y++) {
+			image = (char *)bmp +
+					le32_to_cpu(bmp->header.data_offset);
+			image += (sh - y - 1) * sw * (bits_per_pixel >> 3);
+			adr = buf + ((y + starty) * xres + startx) *
+					(info->bits_per_pixel >> 3);
+			for (x = 0; x < width; x++) {
+				char *pixel;
+
+				pixel = image;
+
+				set_pixel(info, adr, pixel[2], pixel[1],
+						pixel[0]);
+				adr += info->bits_per_pixel >> 3;
+
+				image += bits_per_pixel >> 3;
+			}
+		}
+	} else
+		printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
+
+	if (offscreenbuf)
+		memcpy(fb, offscreenbuf, fbsize);
+
+	free(bmp);
+	return sh;
+
+err:
+	free(bmp);
+	return ret;
+}
-- 
1.7.10.4




More information about the barebox mailing list