"Das U-Boot" Source Tree
at master 141 lines 3.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2002 4 * Detlev Zundel, DENX Software Engineering, dzu@denx.de. 5 */ 6 7/* 8 * BMP handling routines 9 */ 10 11#include <bmp_layout.h> 12#include <command.h> 13#include <dm.h> 14#include <gzip.h> 15#include <log.h> 16#include <malloc.h> 17#include <mapmem.h> 18#include <splash.h> 19#include <video.h> 20#include <asm/byteorder.h> 21 22/* 23 * Allocate and decompress a BMP image using gunzip(). 24 * 25 * Returns a pointer to the decompressed image data. This pointer is 26 * aligned to 32-bit-aligned-address + 2. 27 * See doc/README.displaying-bmps for explanation. 28 * 29 * The allocation address is passed to 'alloc_addr' and must be freed 30 * by the caller after use. 31 * 32 * Returns NULL if decompression failed, or if the decompressed data 33 * didn't contain a valid BMP signature or decompression is not enabled in 34 * Kconfig. 35 */ 36struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp, 37 void **alloc_addr) 38{ 39 void *dst; 40 unsigned long len; 41 struct bmp_image *bmp; 42 43 if (!CONFIG_IS_ENABLED(VIDEO_BMP_GZIP)) 44 return NULL; 45 46 /* 47 * Decompress bmp image 48 */ 49 len = CONFIG_VAL(VIDEO_LOGO_MAX_SIZE); 50 /* allocate extra 3 bytes for 32-bit-aligned-address + 2 alignment */ 51 dst = malloc(CONFIG_VAL(VIDEO_LOGO_MAX_SIZE) + 3); 52 if (!dst) { 53 puts("Error: malloc in gunzip failed!\n"); 54 return NULL; 55 } 56 57 /* align to 32-bit-aligned-address + 2 */ 58 bmp = dst + 2; 59 60 if (gunzip(bmp, CONFIG_VAL(VIDEO_LOGO_MAX_SIZE), map_sysmem(addr, 0), 61 &len)) { 62 free(dst); 63 return NULL; 64 } 65 if (len == CONFIG_VAL(VIDEO_LOGO_MAX_SIZE)) 66 puts("Image could be truncated (increase CONFIG_VIDEO_LOGO_MAX_SIZE)!\n"); 67 68 /* 69 * Check for bmp mark 'BM' 70 */ 71 if (!((bmp->header.signature[0] == 'B') && 72 (bmp->header.signature[1] == 'M'))) { 73 free(dst); 74 return NULL; 75 } 76 77 debug("Gzipped BMP image detected!\n"); 78 79 *alloc_addr = dst; 80 return bmp; 81} 82 83int bmp_info(ulong addr) 84{ 85 struct bmp_image *bmp = (struct bmp_image *)map_sysmem(addr, 0); 86 void *bmp_alloc_addr = NULL; 87 unsigned long len; 88 89 if (!((bmp->header.signature[0] == 'B') && 90 (bmp->header.signature[1] == 'M'))) 91 bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr); 92 93 if (!bmp) { 94 printf("There is no valid bmp file at the given address\n"); 95 return 1; 96 } 97 98 printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width), 99 le32_to_cpu(bmp->header.height)); 100 printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count)); 101 printf("Compression : %d\n", le32_to_cpu(bmp->header.compression)); 102 103 if (bmp_alloc_addr) 104 free(bmp_alloc_addr); 105 106 return 0; 107} 108 109int bmp_display(ulong addr, int x, int y) 110{ 111 struct udevice *dev; 112 int ret; 113 struct bmp_image *bmp = map_sysmem(addr, 0); 114 void *bmp_alloc_addr = NULL; 115 unsigned long len; 116 117 if (!((bmp->header.signature[0] == 'B') && 118 (bmp->header.signature[1] == 'M'))) 119 bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr); 120 121 if (!bmp) { 122 printf("There is no valid bmp file at the given address\n"); 123 return 1; 124 } 125 addr = map_to_sysmem(bmp); 126 127 ret = uclass_first_device_err(UCLASS_VIDEO, &dev); 128 if (!ret) { 129 bool align = false; 130 131 if (x == BMP_ALIGN_CENTER || y == BMP_ALIGN_CENTER) 132 align = true; 133 134 ret = video_bmp_display(dev, addr, x, y, align); 135 } 136 137 if (bmp_alloc_addr) 138 free(bmp_alloc_addr); 139 140 return ret ? CMD_RET_FAILURE : 0; 141}