]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/lcd.c
lcd: support corner cases for splashpos
[karo-tx-uboot.git] / common / lcd.c
index 90f476e7457ca124aef9ed29ca2a00c1dba65814..0782d5f21c2427661efa0909ac619c58e45ee0b9 100644 (file)
@@ -26,7 +26,7 @@
 #ifdef CONFIG_LCD_LOGO
 #include <bmp_logo.h>
 #include <bmp_logo_data.h>
-#if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
+#if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP < LCD_COLOR16)
 #error Default Color Map overlaps with Logo Color Map
 #endif
 #endif
@@ -243,8 +243,8 @@ void lcd_clear(void)
        lcd_logo();
 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
        addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
-       lcd_init_console((void *)addr, panel_info.vl_row,
-                        panel_info.vl_col, panel_info.vl_rot);
+       lcd_init_console((void *)addr, panel_info.vl_col,
+                        panel_info.vl_row, panel_info.vl_rot);
 #endif
        lcd_sync();
 }
@@ -418,17 +418,18 @@ static inline void lcd_logo_plot(int x, int y) {}
 static void splash_align_axis(int *axis, unsigned long panel_size,
                                        unsigned long picture_size)
 {
-       unsigned long panel_picture_delta = panel_size - picture_size;
-       unsigned long axis_alignment;
+       int panel_picture_delta = panel_size - picture_size;
+       int axis_alignment;
 
        if (*axis == BMP_ALIGN_CENTER)
                axis_alignment = panel_picture_delta / 2;
+       else if (abs(*axis) > (int)panel_size)
+               axis_alignment = panel_size;
        else if (*axis < 0)
                axis_alignment = panel_picture_delta + *axis + 1;
        else
                return;
-
-       *axis = max(0, (int)axis_alignment);
+       *axis = axis_alignment;
 }
 #endif
 
@@ -605,7 +606,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        unsigned long pwidth = panel_info.vl_col;
        unsigned long long colors;
        unsigned bpix, bmp_bpix;
-       bmp_color_table_entry_t *cte;
+       int hdr_size;
+       struct bmp_color_table_entry *palette = bmp->color_table;
 
        if (!bmp || !(bmp->header.signature[0] == 'B' &&
                bmp->header.signature[1] == 'M')) {
@@ -617,8 +619,10 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        width = get_unaligned_le32(&bmp->header.width);
        height = get_unaligned_le32(&bmp->header.height);
        bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
+       hdr_size = get_unaligned_le16(&bmp->header.size);
+       debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
 
-       colors = 1 << bmp_bpix;
+       colors = 1ULL << bmp_bpix;
 
        bpix = NBITS(panel_info.vl_bpix);
 
@@ -641,8 +645,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                return 1;
        }
 
-       debug("Display-bmp: %lu x %lu  with %llu colors\n",
-               width, height, colors);
+       debug("Display-bmp: %lu x %lu  with %llu colors, display %llu\n",
+               width, height, colors, 1ULL << bpix);
 
        if (bmp_bpix == 8)
                lcd_set_cmap(bmp, colors);
@@ -655,11 +659,21 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
        bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
 
-       if ((x + width) > pwidth)
+       if (x < 0) {
+               width += x;
+               bmap += -x * bmp_bpix / 8;
+               x = 0;
+       }
+       if ((x + width) > pwidth) {
                width = pwidth - x;
+       }
+       if (y < 0) {
+               height += y;
+               y = 0;
+       }
        if ((y + height) > panel_info.vl_row) {
+               bmap += (y + height - panel_info.vl_row) * bmp_bpix / 8 * padded_width;
                height = panel_info.vl_row - y;
-               bmap += (panel_info.vl_row - y) * padded_width;
        }
 
        fb   = (uchar *)(lcd_base +
@@ -671,6 +685,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                cmap_base = configuration_get_cmap();
 #ifdef CONFIG_LCD_BMP_RLE8
                u32 compression = get_unaligned_le32(&bmp->header.compression);
+               debug("compressed %d %d\n", compression, BMP_BI_RLE8);
                if (compression == BMP_BI_RLE8) {
                        if (bpix != 16) {
                                /* TODO implement render code for bpix != 16 */
@@ -685,19 +700,23 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                for (i = 0; i < height; ++i) {
                        WATCHDOG_RESET();
                        for (j = 0; j < width; j++) {
-                               if (bpix == 32) {
-                                       int i = *bmap++;
-
-                                       fb[3] = 0; /* T */
-                                       fb[0] = cte[i].blue;
-                                       fb[1] = cte[i].green;
-                                       fb[2] = cte[i].red;
-                                       fb += sizeof(uint32_t) / sizeof(*fb);
-                               } else if (bpix == 16) {
-                                       *(uint16_t *)fb = cmap_base[*(bmap++)];
-                                       fb += sizeof(uint16_t) / sizeof(*fb);
+                               if (bpix != 16) {
+                                       fb_put_byte(&fb, &bmap);
                                } else {
-                                       FB_PUT_BYTE(fb, bmap);
+                                       struct bmp_color_table_entry *entry;
+                                       uint val;
+
+                                       if (cmap_base) {
+                                               val = cmap_base[*bmap];
+                                       } else {
+                                               entry = &palette[*bmap];
+                                               val = entry->blue >> 3 |
+                                                       entry->green >> 2 << 5 |
+                                                       entry->red >> 3 << 11;
+                                       }
+                                       *(uint16_t *)fb = val;
+                                       bmap++;
+                                       fb += sizeof(uint16_t) / sizeof(*fb);
                                }
                        }
                        if (bpix > 8) {
@@ -722,7 +741,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                }
                break;
 #endif /* CONFIG_BMP_16BPP */
-#if defined(CONFIG_BMP_24BMP)
+#if defined(CONFIG_BMP_24BPP)
        case 24:
                for (i = 0; i < height; ++i) {
                        for (j = 0; j < width; j++) {