]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/lcd.c
lcd: fix integer overflow in calculation of number of colors
[karo-tx-uboot.git] / common / lcd.c
index 90f476e7457ca124aef9ed29ca2a00c1dba65814..e8c18aa0d842330c37e41708e1c7e14e4f069276 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();
 }
@@ -605,7 +605,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 +618,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 +644,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);
@@ -671,6 +674,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 +689,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 +730,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++) {