diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-09-12 15:42:40 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-12 17:21:10 +0200 |
commit | 6ce5bc4624456e26fe2c534b6ef3ec32b42685a4 (patch) | |
tree | 32446aa30d86df81a3c9e906387921e7f8e618fc /lib | |
parent | a87361dfc30a49b5dd6cbd7e13cda40af223bfd5 (diff) | |
download | barebox-6ce5bc4624456e26fe2c534b6ef3ec32b42685a4.tar.gz barebox-6ce5bc4624456e26fe2c534b6ef3ec32b42685a4.tar.xz |
bmp: Move bmp rendering to lib/bmp.c
So we can add other format support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 3 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/bmp.c | 132 |
3 files changed, 136 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 32634dfbc..93e360b30 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 4e6b1ee90..df4b5e548 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 000000000..776d3b3e0 --- /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; +} |