Angel Pons | 118a9c7 | 2020-04-02 23:48:34 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Johanna Schander | db7a3ae | 2019-07-24 10:14:26 +0200 | [diff] [blame] | 2 | |
| 3 | #include <cbfs.h> |
| 4 | #include <vbe.h> |
| 5 | #include <console/console.h> |
| 6 | #include <endian.h> |
| 7 | #include <bootsplash.h> |
| 8 | |
| 9 | #include "jpeg.h" |
| 10 | |
Johanna Schander | db7a3ae | 2019-07-24 10:14:26 +0200 | [diff] [blame] | 11 | |
| 12 | void set_bootsplash(unsigned char *framebuffer, unsigned int x_resolution, |
Nico Huber | 99eee16 | 2023-07-14 00:09:00 +0200 | [diff] [blame] | 13 | unsigned int y_resolution, unsigned int bytes_per_line, |
| 14 | unsigned int fb_resolution) |
Johanna Schander | db7a3ae | 2019-07-24 10:14:26 +0200 | [diff] [blame] | 15 | { |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 16 | if ((x_resolution > INT_MAX) || (y_resolution) > INT_MAX) { |
| 17 | printk(BIOS_ERR, "Display resolution way too large.\n"); |
| 18 | return; |
| 19 | } |
| 20 | int xres = x_resolution, yres = y_resolution; |
Johanna Schander | 7fc006f | 2019-07-28 08:48:36 +0200 | [diff] [blame] | 21 | printk(BIOS_INFO, "Setting up bootsplash in %dx%d@%d\n", x_resolution, y_resolution, |
| 22 | fb_resolution); |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 23 | size_t filesize; |
| 24 | unsigned char *jpeg = cbfs_map("bootsplash.jpg", &filesize); |
Johanna Schander | db7a3ae | 2019-07-24 10:14:26 +0200 | [diff] [blame] | 25 | if (!jpeg) { |
| 26 | printk(BIOS_ERR, "Could not find bootsplash.jpg\n"); |
| 27 | return; |
| 28 | } |
| 29 | |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 30 | unsigned int image_width, image_height; |
| 31 | if (jpeg_fetch_size(jpeg, filesize, &image_width, &image_height) != 0) { |
| 32 | printk(BIOS_ERR, "Could not parse bootsplash.jpg\n"); |
| 33 | return; |
| 34 | } |
Johanna Schander | 7fc006f | 2019-07-28 08:48:36 +0200 | [diff] [blame] | 35 | |
| 36 | printk(BIOS_DEBUG, "Bootsplash image resolution: %dx%d\n", image_width, image_height); |
| 37 | |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 38 | if (image_width > xres || image_height > yres) { |
Nico Huber | 99eee16 | 2023-07-14 00:09:00 +0200 | [diff] [blame] | 39 | printk(BIOS_NOTICE, "Bootsplash image can't fit framebuffer.\n"); |
| 40 | cbfs_unmap(jpeg); |
| 41 | return; |
| 42 | } |
| 43 | |
| 44 | /* center image: */ |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 45 | framebuffer += (yres - image_height) / 2 * bytes_per_line |
| 46 | + (xres - image_width) / 2 * (fb_resolution / 8); |
Nico Huber | 99eee16 | 2023-07-14 00:09:00 +0200 | [diff] [blame] | 47 | |
Patrick Georgi | 1d029b4 | 2023-10-06 20:19:15 +0200 | [diff] [blame] | 48 | int ret = jpeg_decode(jpeg, filesize, framebuffer, image_width, image_height, |
| 49 | bytes_per_line, fb_resolution); |
Julius Werner | 834b3ec | 2020-03-04 16:52:08 -0800 | [diff] [blame] | 50 | cbfs_unmap(jpeg); |
Johanna Schander | db7a3ae | 2019-07-24 10:14:26 +0200 | [diff] [blame] | 51 | if (ret != 0) { |
| 52 | printk(BIOS_ERR, "Bootsplash could not be decoded. jpeg_decode returned %d.\n", |
| 53 | ret); |
| 54 | return; |
| 55 | } |
| 56 | printk(BIOS_INFO, "Bootsplash loaded\n"); |
| 57 | } |