From c29ab9d71d229ee94e8263845ea54222005e3880 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 8 Oct 2005 10:19:07 +0200 Subject: [PATCH] Fix gzip bmp support (test if malloc fails, warning when truncated). Increase CFG_VIDEO_LOGO_MAX_SIZE on HH405 board. Patch by Stefan Roese, 08 Oct 2005 --- CHANGELOG | 4 ++++ board/esd/common/lcd.c | 23 +++++++++++++-------- common/cmd_bmp.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/cfb_console.c | 7 +++++++ include/configs/APC405.h | 2 +- include/configs/HH405.h | 6 ++---- include/configs/VOH405.h | 2 +- 7 files changed, 82 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 802f5d3..3c0ff3f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,10 @@ Changes for U-Boot 1.1.4: ====================================================================== +* Fix gzip bmp support (test if malloc fails, warning when truncated). + Increase CFG_VIDEO_LOGO_MAX_SIZE on HH405 board. + Patch by Stefan Roese, 07 Oct 2005 + * Fix booting from serial dataflash on AT91RM9200 Patch by Peter Menzebach, 29 Aug 2005 diff --git a/board/esd/common/lcd.c b/board/esd/common/lcd.c index 05c76ff..0edc083 100644 --- a/board/esd/common/lcd.c +++ b/board/esd/common/lcd.c @@ -81,7 +81,7 @@ void lcd_bmp(uchar *logo_bmp) uchar *ptr; ushort *ptr2; ushort val; - unsigned char *dst; + unsigned char *dst = NULL; int x, y; int width, height, bpp, colors, line_size; int header_size; @@ -89,7 +89,6 @@ void lcd_bmp(uchar *logo_bmp) unsigned char r, g, b; BITMAPINFOHEADER *bm_info; ulong len; - int do_free = 0; /* * Check for bmp mark 'BM' @@ -99,12 +98,18 @@ void lcd_bmp(uchar *logo_bmp) /* * Decompress bmp image */ - len = CFG_LCD_LOGO_MAX_SIZE; - dst = malloc(CFG_LCD_LOGO_MAX_SIZE); - do_free = 1; - if (gunzip(dst, CFG_LCD_LOGO_MAX_SIZE, (uchar *)logo_bmp, &len) != 0) { + len = CFG_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc in gunzip failed!\n"); return; } + if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)logo_bmp, &len) != 0) { + return; + } + if (len == CFG_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); + } /* * Check for bmp mark 'BM' @@ -147,7 +152,9 @@ void lcd_bmp(uchar *logo_bmp) break; default: printf("LCD: Unknown bpp (%d) im image!\n", bpp); - free(dst); + if ((dst != NULL) && (dst != (uchar *)logo_bmp)) { + free(dst); + } return; } printf(" (%d*%d, %dbpp)\n", width, height, bpp); @@ -205,7 +212,7 @@ void lcd_bmp(uchar *logo_bmp) } } - if (do_free) { + if ((dst != NULL) && (dst != (uchar *)logo_bmp)) { free(dst); } } diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index daa54e7..ad412c8 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -29,12 +29,15 @@ #include #include #include +#include #if (CONFIG_COMMANDS & CFG_CMD_BMP) static int bmp_info (ulong addr); static int bmp_display (ulong addr, int x, int y); +int gunzip(void *, int, unsigned char *, unsigned long *); + /* * Subroutine: do_bmp * @@ -100,15 +103,64 @@ U_BOOT_CMD( static int bmp_info(ulong addr) { bmp_image_t *bmp=(bmp_image_t *)addr; +#ifdef CONFIG_VIDEO_BMP_GZIP + unsigned char *dst = NULL; + ulong len; +#endif /* CONFIG_VIDEO_BMP_GZIP */ + if (!((bmp->header.signature[0]=='B') && (bmp->header.signature[1]=='M'))) { + +#ifdef CONFIG_VIDEO_BMP_GZIP + /* + * Decompress bmp image + */ + len = CFG_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc in gunzip failed!\n"); + return(1); + } + if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) { + printf("There is no valid bmp file at the given address\n"); + return(1); + } + if (len == CFG_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); + } + + /* + * Set addr to decompressed image + */ + bmp = (bmp_image_t *)dst; + + /* + * Check for bmp mark 'BM' + */ + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) { + printf("There is no valid bmp file at the given address\n"); + free(dst); + return(1); + } + + printf("Gzipped BMP image detected!\n"); +#else /* CONFIG_VIDEO_BMP_GZIP */ printf("There is no valid bmp file at the given address\n"); return(1); +#endif /* CONFIG_VIDEO_BMP_GZIP */ } printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width), le32_to_cpu(bmp->header.height)); printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count)); printf("Compression : %d\n", le32_to_cpu(bmp->header.compression)); + +#ifdef CONFIG_VIDEO_BMP_GZIP + if (dst) { + free(dst); + } +#endif /* CONFIG_VIDEO_BMP_GZIP */ + return(0); } diff --git a/drivers/cfb_console.c b/drivers/cfb_console.c index aba4a03..82b35e5 100644 --- a/drivers/cfb_console.c +++ b/drivers/cfb_console.c @@ -779,11 +779,18 @@ int video_display_bitmap (ulong bmp_image, int x, int y) */ len = CFG_VIDEO_LOGO_MAX_SIZE; dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc in gunzip failed!\n"); + return(1); + } if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) { printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image); free(dst); return 1; } + if (len == CFG_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); + } /* * Set addr to decompressed image diff --git a/include/configs/APC405.h b/include/configs/APC405.h index b53e85e..3ac567b 100644 --- a/include/configs/APC405.h +++ b/include/configs/APC405.h @@ -357,7 +357,7 @@ #define CFG_LCD_MEM CFG_LCD_BIG_MEM #define CFG_LCD_REG CFG_LCD_BIG_REG -#define CFG_LCD_LOGO_MAX_SIZE (1024*1024) +#define CFG_VIDEO_LOGO_MAX_SIZE (1 << 20) /*----------------------------------------------------------------------- * Definitions for initial stack pointer and data area (in data cache) diff --git a/include/configs/HH405.h b/include/configs/HH405.h index dd29be0..131c215 100644 --- a/include/configs/HH405.h +++ b/include/configs/HH405.h @@ -88,7 +88,7 @@ #define CFG_CONSOLE_IS_IN_ENV #define CONFIG_SPLASH_SCREEN #define CONFIG_VIDEO_BMP_GZIP /* gzip compressed bmp images */ -#define CFG_VIDEO_LOGO_MAX_SIZE (1024*1024) /* for decompressed img */ +#define CFG_VIDEO_LOGO_MAX_SIZE (2 << 20) /* for decompressed img */ #define ADD_BMP_CMD CFG_CMD_BMP #else @@ -308,7 +308,7 @@ #define CFG_FLASH_BASE 0xFFF80000 #define CFG_MONITOR_BASE TEXT_BASE #define CFG_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Monitor */ -#define CFG_MALLOC_LEN (2 * 1024*1024) /* Reserve 2 MB for malloc() */ +#define CFG_MALLOC_LEN (4 << 20) /* Reserve 4 MB for malloc() */ #if (CFG_MONITOR_BASE < FLASH_BASE0_PRELIM) # define CFG_RAMBOOT 1 @@ -409,8 +409,6 @@ #define CFG_LCD_SMALL_MEM 0xF1400000 /* Epson S1D13704 Mem Base Address */ #define CFG_LCD_SMALL_REG 0xF140FFE0 /* Epson S1D13704 Reg Base Address */ -#define CFG_LCD_LOGO_MAX_SIZE (1024*1024) - /*----------------------------------------------------------------------- * Universal Interrupt Controller (UIC) Setup */ diff --git a/include/configs/VOH405.h b/include/configs/VOH405.h index b3ce3da..3ca137e 100644 --- a/include/configs/VOH405.h +++ b/include/configs/VOH405.h @@ -362,7 +362,7 @@ #define CFG_LCD_SMALL_MEM 0xF1400000 /* Epson S1D13704 Mem Base Address */ #define CFG_LCD_SMALL_REG 0xF140FFE0 /* Epson S1D13704 Reg Base Address */ -#define CFG_LCD_LOGO_MAX_SIZE (1024*1024) +#define CFG_VIDEO_LOGO_MAX_SIZE (1 << 20) /*----------------------------------------------------------------------- * FPGA stuff