4 #include <linux/stat.h>
10 #include <bmp_layout.h>
11 #include <asm/byteorder.h>
13 static inline void set_pixel(struct fb_info
*info
, void *adr
, int r
, int g
, int b
)
17 px
= (r
>> (8 - info
->red
.length
)) << info
->red
.offset
|
18 (g
>> (8 - info
->green
.length
)) << info
->green
.offset
|
19 (b
>> (8 - info
->blue
.length
)) << info
->blue
.offset
;
21 switch (info
->bits_per_pixel
) {
32 static int do_bmp(cmd_tbl_t
*cmdtp
, int argc
, char *argv
[])
35 char *fbdev
= "/dev/fb0";
36 void *fb
, *offscreenbuf
= NULL
;
38 struct bmp_image
*bmp
;
42 int sw
, sh
, width
, height
, startx
= -1, starty
= -1;
43 int bits_per_pixel
, fbsize
;
48 while((opt
= getopt(argc
, argv
, "f:x:y:o")) > 0) {
54 startx
= simple_strtoul(optarg
, NULL
, 0);
57 starty
= simple_strtoul(optarg
, NULL
, 0);
64 printf("no filename given\n");
67 bmpfile
= argv
[optind
];
69 fd
= open(fbdev
, O_RDWR
);
75 fb
= memmap(fd
, PROT_READ
| PROT_WRITE
);
76 if (fb
== (void *)-1) {
81 ret
= ioctl(fd
, FBIOGET_SCREENINFO
, &info
);
90 bmp
= read_file(bmpfile
, &bmpsize
);
92 printf("unable to read %s\n", bmpfile
);
96 if (bmp
->header
.signature
[0] != 'B' ||
97 bmp
->header
.signature
[1] != 'M') {
98 printf("No valid bmp file\n");
101 sw
= le32_to_cpu(bmp
->header
.width
);
102 sh
= le32_to_cpu(bmp
->header
.height
);
105 startx
= (xres
- sw
) / 2;
111 starty
= (yres
- sh
) / 2;
116 width
= min(sw
, xres
- startx
);
117 height
= min(sh
, yres
- starty
);
119 bits_per_pixel
= le16_to_cpu(bmp
->header
.bit_count
);
120 fbsize
= xres
* yres
* (info
.bits_per_pixel
>> 3);
123 /* Don't fail if malloc fails, just continue rendering directly
126 offscreenbuf
= malloc(fbsize
);
128 memcpy(offscreenbuf
, fb
, fbsize
);
131 buf
= offscreenbuf
? offscreenbuf
: fb
;
133 if (bits_per_pixel
== 8) {
135 struct bmp_color_table_entry
*color_table
= bmp
->color_table
;
137 for (y
= 0; y
< height
; y
++) {
138 image
= (char *)bmp
+
139 le32_to_cpu(bmp
->header
.data_offset
);
140 image
+= (sh
- y
- 1) * sw
* (bits_per_pixel
>> 3);
141 adr
= buf
+ ((y
+ starty
) * xres
+ startx
) *
142 (info
.bits_per_pixel
>> 3);
143 for (x
= 0; x
< width
; x
++) {
148 set_pixel(&info
, adr
, color_table
[pixel
].red
,
149 color_table
[pixel
].green
,
150 color_table
[pixel
].blue
);
151 adr
+= info
.bits_per_pixel
>> 3;
153 image
+= bits_per_pixel
>> 3;
156 } else if (bits_per_pixel
== 24) {
159 for (y
= 0; y
< height
; y
++) {
160 image
= (char *)bmp
+
161 le32_to_cpu(bmp
->header
.data_offset
);
162 image
+= (sh
- y
- 1) * sw
* (bits_per_pixel
>> 3);
163 adr
= buf
+ ((y
+ starty
) * xres
+ startx
) *
164 (info
.bits_per_pixel
>> 3);
165 for (x
= 0; x
< width
; x
++) {
170 set_pixel(&info
, adr
, pixel
[2], pixel
[1],
172 adr
+= info
.bits_per_pixel
>> 3;
174 image
+= bits_per_pixel
>> 3;
178 printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel
);
181 memcpy(fb
, offscreenbuf
, fbsize
);
196 static const __maybe_unused
char cmd_bmp_help
[] =
197 "Usage: bmp [OPTION]... FILE\n"
198 "show bmp image FILE.\n"
199 " -f <fb> framebuffer device (/dev/fb0)\n"
200 " -x <xofs> x offset (default center)\n"
201 " -y <yofs> y offset (default center)\n"
202 " -o render offscreen\n";
204 U_BOOT_CMD_START(bmp
)
206 .usage
= "show a bmp image",
207 U_BOOT_CMD_HELP(cmd_bmp_help
)