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

Sascha Hauer s.hauer at pengutronix.de
Wed Sep 12 11:08:29 EDT 2012


Argh!

Why am I writing mails anyway.

In Subject: s/rending/rendering/

Or better: Move bmp rendering to lib/bmp.c


On Wed, Sep 12, 2012 at 03:42:40PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> 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
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list