Allow displaying run length encoded bitmaps.

Signed-off-by: Anatolij Gustschin <ag...@denx.de>
---
 board/freescale/common/fsl_diu_fb.c |   78 +++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/board/freescale/common/fsl_diu_fb.c 
b/board/freescale/common/fsl_diu_fb.c
index 2fc878b..d7c55b5 100644
--- a/board/freescale/common/fsl_diu_fb.c
+++ b/board/freescale/common/fsl_diu_fb.c
@@ -26,6 +26,7 @@
 #include <common.h>
 #include <i2c.h>
 #include <malloc.h>
+#include <bmp_layout.h>
 
 #include "fsl_diu_fb.h"
 
@@ -464,6 +465,78 @@ static int allocate_buf(struct diu_addr *buf, u32 size, 
u32 bytes_align)
        return 0;
 }
 
+int display_rle8_bitmap(unsigned char *bmp, unsigned int *palette,
+                       int yoff, int xoff)
+{
+       struct fb_info *info = &fsl_fb_info;
+       bmp_header_t *im = (bmp_header_t *)bmp;
+       unsigned char *bm;
+       unsigned int *fbp;
+       unsigned int cnt;
+       int decode = 1;
+       int x, y, bpp, i;
+
+       x = 0;
+       y = __le32_to_cpu(im->height) - 1;
+       bpp = info->var.bits_per_pixel / 8;
+       fbp = (unsigned int *) ((unsigned int)info->screen_base +
+                               (((y + yoff) * info->var.xres) + xoff) * bpp);
+       bm = bmp + __le32_to_cpu(im->data_offset);
+
+       while (decode) {
+               switch (bm[0]) {
+               case 0:
+                       switch (bm[1]) {
+                       case 0:
+                               /* scan line end marker */
+                               bm += 2;
+                               x = 0;
+                               y--;
+                               fbp = (unsigned int *)
+                                       ((unsigned int)info->screen_base +
+                                        (((y + yoff) * info->var.xres) +
+                                         xoff) * bpp);
+                               continue;
+                       case 1:
+                               /* end of bitmap data marker */
+                               decode = 0;
+                               break;
+                       case 2:
+                               /* run offset marker */
+                               x += bm[2];
+                               y -= bm[3];
+                               fbp = (unsigned int *)
+                                       ((unsigned int)info->screen_base +
+                                        (((y + yoff) * info->var.xres) +
+                                         x + xoff) * bpp);
+                               bm += 4;
+                               break;
+                       default:
+                               /* unencoded run */
+                               cnt = bm[1];
+                               bm += 2;
+                               for (i = 0; i < cnt; i++) {
+                                       *fbp++ = palette[bm[0]];
+                                       bm++;
+                                       x++;
+                               }
+                               if (cnt & 1)
+                                       bm++;
+                       }
+                       break;
+               default:
+                       /* encoded run */
+                       for (i = 0; i < bm[0]; i++) {
+                               *fbp++ = palette[bm[1]];
+                               x++;
+                       }
+                       bm += 2;
+                       break;
+               }
+       }
+       return __le32_to_cpu(im->height);
+}
+
 int fsl_diu_display_bmp(unsigned char *bmp,
                        int xoffset,
                        int yoffset,
@@ -544,6 +617,11 @@ int fsl_diu_display_bmp(unsigned char *bmp,
                }
                break;
        case 8:
+               if (bmp[30] == BMP_BI_RLE8) {
+                       return display_rle8_bitmap(bmp, palette, yoffset,
+                                                  xoffset);
+               }
+
                for (y = height - 1; y >= 0; y--) {
                        fb_t = (unsigned int *) ((unsigned 
int)info->screen_base + (((y+yoffset) * info->var.xres) + xoffset)*cpp);
                        for (x = 0; x < width; x++) {
-- 
1.6.3.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to