X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fbootsplash.c;h=51f4f4f6f08fdbf441418867c62afd2905f43564;hb=5042ca50f4dd808957d5550615e6c469147c9cf2;hp=cf1a603e790fabdb9a1aba15c377c4151e8294c3;hpb=e5de5ec102b5490279ceb64328bd734ddb7eaed1;p=seabios.git diff --git a/src/bootsplash.c b/src/bootsplash.c index cf1a603..51f4f4f 100644 --- a/src/bootsplash.c +++ b/src/bootsplash.c @@ -12,7 +12,7 @@ #include "jpeg.h" // splash #include "biosvar.h" // SET_EBDA #include "paravirt.h" // romfile_find - +#include "bmp.h" /**************************************************************** * VESA structures @@ -109,7 +109,7 @@ enable_vga_console(void) static int find_videomode(struct vesa_info *vesa_info, struct vesa_mode_info *mode_info - , int width, int height) + , int width, int height, int bpp_req) { dprintf(3, "Finding vesa mode with dimensions %d/%d\n", width, height); u16 *videomodes = SEGOFF_TO_FLATPTR(vesa_info->video_mode_ptr); @@ -135,8 +135,13 @@ find_videomode(struct vesa_info *vesa_info, struct vesa_mode_info *mode_info || mode_info->y_resolution != height) continue; u8 depth = mode_info->bits_per_pixel; - if (depth != 16 && depth != 24 && depth != 32) - continue; + if (bpp_req == 0) { + if (depth != 16 && depth != 24 && depth != 32) + continue; + } else { + if (depth != bpp_req) + continue; + } return videomode; } } @@ -148,17 +153,25 @@ enable_bootsplash(void) { if (!CONFIG_BOOTSPLASH) return; + /* splash picture can be bmp or jpeg file */ dprintf(3, "Checking for bootsplash\n"); + u8 type = 0; /* 0 means jpg, 1 means bmp, default is 0=jpg */ int filesize; u8 *filedata = romfile_loadfile("bootsplash.jpg", &filesize); - if (!filedata) - return; + if (!filedata) { + filedata = romfile_loadfile("bootsplash.bmp", &filesize); + if (!filedata) + return; + type = 1; + } + dprintf(3, "start showing bootsplash\n"); - u8 *picture = NULL; + u8 *picture = NULL; /* data buff used to be flushed to the video buf */ + struct jpeg_decdata *jpeg = NULL; + struct bmp_decdata *bmp = NULL; struct vesa_info *vesa_info = malloc_tmplow(sizeof(*vesa_info)); struct vesa_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info)); - struct jpeg_decdata *jpeg = jpeg_alloc(); - if (!jpeg || !vesa_info || !mode_info) { + if (!vesa_info || !mode_info) { warn_noalloc(); goto done; } @@ -184,20 +197,48 @@ enable_bootsplash(void) vesa_info->vesa_version>>8, vesa_info->vesa_version&0xff, vendor, product); - // Parse jpeg and get image size. - dprintf(5, "Decoding bootsplash.jpg\n"); - int ret = jpeg_decode(jpeg, filedata); - if (ret) { - dprintf(1, "jpeg_decode failed with return code %d...\n", ret); - goto done; + int ret, width, height; + int bpp_require = 0; + if (type == 0) { + jpeg = jpeg_alloc(); + if (!jpeg) { + warn_noalloc(); + goto done; + } + /* Parse jpeg and get image size. */ + dprintf(5, "Decoding bootsplash.jpg\n"); + ret = jpeg_decode(jpeg, filedata); + if (ret) { + dprintf(1, "jpeg_decode failed with return code %d...\n", ret); + goto done; + } + jpeg_get_size(jpeg, &width, &height); + } else { + bmp = bmp_alloc(); + if (!bmp) { + warn_noalloc(); + goto done; + } + /* Parse bmp and get image size. */ + dprintf(5, "Decoding bootsplash.bmp\n"); + ret = bmp_decode(bmp, filedata, filesize); + if (ret) { + dprintf(1, "bmp_decode failed with return code %d...\n", ret); + goto done; + } + bmp_get_size(bmp, &width, &height); + bpp_require = 24; } - int width, height; - jpeg_get_size(jpeg, &width, &height); + /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */ // Try to find a graphics mode with the corresponding dimensions. - int videomode = find_videomode(vesa_info, mode_info, width, height); - if (videomode < 0) + int videomode = find_videomode(vesa_info, mode_info, width, height, + bpp_require); + if (videomode < 0) { + dprintf(1, "failed to find a videomode with %dx%d %dbpp (0=any).\n", + width, height, bpp_require); goto done; + } void *framebuffer = mode_info->phys_base_ptr; int depth = mode_info->bits_per_pixel; dprintf(3, "mode: %04x\n", videomode); @@ -206,17 +247,28 @@ enable_bootsplash(void) dprintf(3, "bits per pixel: %d\n", depth); // Allocate space for image and decompress it. - int imagesize = width * height * (depth / 8); + int imagesize = height * mode_info->bytes_per_scanline; picture = malloc_tmphigh(imagesize); if (!picture) { warn_noalloc(); goto done; } - dprintf(5, "Decompressing bootsplash.jpg\n"); - ret = jpeg_show(jpeg, picture, width, height, depth); - if (ret) { - dprintf(1, "jpeg_show failed with return code %d...\n", ret); - goto done; + + if (type == 0) { + dprintf(5, "Decompressing bootsplash.jpg\n"); + ret = jpeg_show(jpeg, picture, width, height, depth); + if (ret) { + dprintf(1, "jpeg_show failed with return code %d...\n", ret); + goto done; + } + } else { + dprintf(5, "Decompressing bootsplash.bmp\n"); + ret = bmp_show(bmp, picture, width, height, depth, + mode_info->bytes_per_scanline); + if (ret) { + dprintf(1, "bmp_show failed with return code %d...\n", ret); + goto done; + } } /* Switch to graphics mode */ @@ -231,7 +283,7 @@ enable_bootsplash(void) } /* Show the picture */ - dprintf(5, "Showing bootsplash.jpg\n"); + dprintf(5, "Showing bootsplash picture\n"); iomemcpy(framebuffer, picture, imagesize); dprintf(5, "Bootsplash copy complete\n"); BootsplashActive = 1; @@ -242,6 +294,7 @@ done: free(vesa_info); free(mode_info); free(jpeg); + free(bmp); return; }