]> git.ipfire.org Git - people/ms/u-boot.git/blame - cmd/bmp.c
Merge CONFIG_BOOTCOUNT and CONFIG_BOOTCOUNT_LIMIT
[people/ms/u-boot.git] / cmd / bmp.c
CommitLineData
059ae173
WD
1/*
2 * (C) Copyright 2002
b37c7e5e 3 * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
059ae173 4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
059ae173
WD
6 */
7
8/*
9 * BMP handling routines
10 */
11
12#include <common.h>
b01c7923 13#include <dm.h>
6111722a 14#include <lcd.h>
b01c7923 15#include <mapmem.h>
059ae173
WD
16#include <bmp_layout.h>
17#include <command.h>
8655b6f8 18#include <asm/byteorder.h>
c29ab9d7 19#include <malloc.h>
72b335e9 20#include <mapmem.h>
ff8fb56b 21#include <splash.h>
f674f7cf 22#include <video.h>
059ae173 23
059ae173 24static int bmp_info (ulong addr);
059ae173 25
43ef1c38
HCE
26/*
27 * Allocate and decompress a BMP image using gunzip().
28 *
f7ef9d61
PW
29 * Returns a pointer to the decompressed image data. This pointer is
30 * aligned to 32-bit-aligned-address + 2.
31 * See doc/README.displaying-bmps for explanation.
32 *
33 * The allocation address is passed to 'alloc_addr' and must be freed
34 * by the caller after use.
43ef1c38
HCE
35 *
36 * Returns NULL if decompression failed, or if the decompressed data
37 * didn't contain a valid BMP signature.
38 */
39#ifdef CONFIG_VIDEO_BMP_GZIP
1c3dbe56
SG
40struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
41 void **alloc_addr)
43ef1c38
HCE
42{
43 void *dst;
44 unsigned long len;
1c3dbe56 45 struct bmp_image *bmp;
43ef1c38
HCE
46
47 /*
48 * Decompress bmp image
49 */
6d0f6bcf 50 len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
f7ef9d61
PW
51 /* allocate extra 3 bytes for 32-bit-aligned-address + 2 alignment */
52 dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE + 3);
43ef1c38
HCE
53 if (dst == NULL) {
54 puts("Error: malloc in gunzip failed!\n");
55 return NULL;
56 }
f7ef9d61
PW
57
58 bmp = dst;
59
60 /* align to 32-bit-aligned-address + 2 */
1c3dbe56 61 bmp = (struct bmp_image *)((((unsigned int)dst + 1) & ~3) + 2);
f7ef9d61 62
72b335e9
SG
63 if (gunzip(bmp, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, map_sysmem(addr, 0),
64 &len) != 0) {
43ef1c38
HCE
65 free(dst);
66 return NULL;
67 }
6d0f6bcf 68 if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)
43ef1c38 69 puts("Image could be truncated"
6d0f6bcf 70 " (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
43ef1c38 71
43ef1c38
HCE
72 /*
73 * Check for bmp mark 'BM'
74 */
75 if (!((bmp->header.signature[0] == 'B') &&
76 (bmp->header.signature[1] == 'M'))) {
77 free(dst);
78 return NULL;
79 }
80
17f79e45 81 debug("Gzipped BMP image detected!\n");
43ef1c38 82
f7ef9d61 83 *alloc_addr = dst;
43ef1c38
HCE
84 return bmp;
85}
86#else
1c3dbe56
SG
87struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
88 void **alloc_addr)
43ef1c38
HCE
89{
90 return NULL;
91}
92#endif
93
54841ab5 94static int do_bmp_info(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
9acd4f0e
FM
95{
96 ulong addr;
43ef1c38 97
9acd4f0e
FM
98 switch (argc) {
99 case 1: /* use load_addr as default address */
100 addr = load_addr;
101 break;
102 case 2: /* use argument */
103 addr = simple_strtoul(argv[1], NULL, 16);
104 break;
105 default:
4c12eeb8 106 return CMD_RET_USAGE;
9acd4f0e
FM
107 }
108
109 return (bmp_info(addr));
110}
111
54841ab5 112static int do_bmp_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
059ae173
WD
113{
114 ulong addr;
4b248f3f 115 int x = 0, y = 0;
059ae173 116
ff8fb56b
AG
117 splash_get_pos(&x, &y);
118
059ae173 119 switch (argc) {
9acd4f0e 120 case 1: /* use load_addr as default address */
059ae173
WD
121 addr = load_addr;
122 break;
9acd4f0e
FM
123 case 2: /* use argument */
124 addr = simple_strtoul(argv[1], NULL, 16);
059ae173 125 break;
9acd4f0e
FM
126 case 4:
127 addr = simple_strtoul(argv[1], NULL, 16);
93e14596
WD
128 x = simple_strtoul(argv[2], NULL, 10);
129 y = simple_strtoul(argv[3], NULL, 10);
130 break;
059ae173 131 default:
4c12eeb8 132 return CMD_RET_USAGE;
059ae173
WD
133 }
134
9acd4f0e
FM
135 return (bmp_display(addr, x, y));
136}
137
138static cmd_tbl_t cmd_bmp_sub[] = {
139 U_BOOT_CMD_MKENT(info, 3, 0, do_bmp_info, "", ""),
140 U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""),
141};
142
2e5167cc 143#ifdef CONFIG_NEEDS_MANUAL_RELOC
f1d2b313
HS
144void bmp_reloc(void) {
145 fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub));
146}
147#endif
148
9acd4f0e
FM
149/*
150 * Subroutine: do_bmp
151 *
152 * Description: Handler for 'bmp' command..
153 *
154 * Inputs: argv[1] contains the subcommand
155 *
156 * Return: None
157 *
158 */
54841ab5 159static int do_bmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
9acd4f0e
FM
160{
161 cmd_tbl_t *c;
162
163 /* Strip off leading 'bmp' command argument */
164 argc--;
165 argv++;
166
167 c = find_cmd_tbl(argv[0], &cmd_bmp_sub[0], ARRAY_SIZE(cmd_bmp_sub));
168
47e26b1b 169 if (c)
9acd4f0e 170 return c->cmd(cmdtp, flag, argc, argv);
47e26b1b 171 else
4c12eeb8 172 return CMD_RET_USAGE;
059ae173
WD
173}
174
0d498393 175U_BOOT_CMD(
4b248f3f 176 bmp, 5, 1, do_bmp,
2fb2604d 177 "manipulate BMP image data",
4b248f3f 178 "info <imageAddr> - display image info\n"
a89c33db 179 "bmp display <imageAddr> [x y] - display image at x,y"
b0fce99b
WD
180);
181
059ae173
WD
182/*
183 * Subroutine: bmp_info
184 *
185 * Description: Show information about bmp file in memory
186 *
187 * Inputs: addr address of the bmp file
188 *
189 * Return: None
190 *
191 */
192static int bmp_info(ulong addr)
193{
72b335e9 194 struct bmp_image *bmp = (struct bmp_image *)map_sysmem(addr, 0);
f7ef9d61 195 void *bmp_alloc_addr = NULL;
43ef1c38 196 unsigned long len;
c29ab9d7 197
059ae173 198 if (!((bmp->header.signature[0]=='B') &&
43ef1c38 199 (bmp->header.signature[1]=='M')))
f7ef9d61 200 bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr);
c29ab9d7 201
43ef1c38 202 if (bmp == NULL) {
059ae173 203 printf("There is no valid bmp file at the given address\n");
43ef1c38 204 return 1;
059ae173 205 }
43ef1c38 206
059ae173
WD
207 printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width),
208 le32_to_cpu(bmp->header.height));
209 printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count));
210 printf("Compression : %d\n", le32_to_cpu(bmp->header.compression));
c29ab9d7 211
f7ef9d61
PW
212 if (bmp_alloc_addr)
213 free(bmp_alloc_addr);
c29ab9d7 214
059ae173
WD
215 return(0);
216}
217
218/*
219 * Subroutine: bmp_display
220 *
221 * Description: Display bmp file located in memory
222 *
223 * Inputs: addr address of the bmp file
224 *
225 * Return: None
226 *
227 */
de3b49c4 228int bmp_display(ulong addr, int x, int y)
059ae173 229{
b01c7923
SG
230#ifdef CONFIG_DM_VIDEO
231 struct udevice *dev;
232#endif
43ef1c38 233 int ret;
72b335e9 234 struct bmp_image *bmp = map_sysmem(addr, 0);
f7ef9d61 235 void *bmp_alloc_addr = NULL;
43ef1c38
HCE
236 unsigned long len;
237
238 if (!((bmp->header.signature[0]=='B') &&
239 (bmp->header.signature[1]=='M')))
f7ef9d61 240 bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr);
43ef1c38
HCE
241
242 if (!bmp) {
243 printf("There is no valid bmp file at the given address\n");
244 return 1;
245 }
72b335e9 246 addr = map_to_sysmem(bmp);
43ef1c38 247
b01c7923 248#ifdef CONFIG_DM_VIDEO
3f603cbb 249 ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
b01c7923 250 if (!ret) {
3f603cbb 251 bool align = false;
b01c7923
SG
252
253# ifdef CONFIG_SPLASH_SCREEN_ALIGN
3f603cbb 254 align = true;
b01c7923 255# endif /* CONFIG_SPLASH_SCREEN_ALIGN */
3f603cbb 256 ret = video_bmp_display(dev, addr, x, y, align);
b01c7923 257 }
b01c7923 258#elif defined(CONFIG_LCD)
72b335e9 259 ret = lcd_display_bitmap(addr, x, y);
281e00a3 260#elif defined(CONFIG_VIDEO)
72b335e9 261 ret = video_display_bitmap(addr, x, y);
281e00a3
WD
262#else
263# error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
4b248f3f 264#endif
43ef1c38 265
f7ef9d61
PW
266 if (bmp_alloc_addr)
267 free(bmp_alloc_addr);
43ef1c38 268
e517db73 269 return ret ? CMD_RET_FAILURE : 0;
059ae173 270}