Add option to load image in `psplash` command line. Image is bmp3 format. If this image can not be found or loading fail, default image is print.
bmp_layout.h: describe bmp3 file inspire of bmp_layout.h from u-boot. psplash-fb.{c|h}: add function to draw GBR888 image. psplash.c: Add option to read bmp image and print it if loading file is right. Signed-off-by: Mickaël Tansorier <mickael.tansor...@smile.fr> --- bmp_layout.h | 35 +++++++++++++++++++ psplash-fb.c | 25 ++++++++++++++ psplash-fb.h | 9 +++++ psplash.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 bmp_layout.h diff --git a/bmp_layout.h b/bmp_layout.h new file mode 100644 index 0000000..f397ef9 --- /dev/null +++ b/bmp_layout.h @@ -0,0 +1,35 @@ +/* Layout of a bmp file */ +/* format = bmp3 */ + +#ifndef _BMP_LAYOUT_H_ +#define _BMP_LAYOUT_H_ + +#define BMP_IMG_BYTES_PER_PIXEL 3 + +struct __attribute__((__packed__)) bmp_header { + /* Header */ + char signature[2]; + __u32 file_size; + __u32 reserved; + __u32 data_offset; + /* InfoHeader */ + __u32 size; + __u32 width; + __u32 height; + __u16 planes; + __u16 bit_count; + __u32 compression; + __u32 image_size; + __u32 x_pixels_per_m; + __u32 y_pixels_per_m; + __u32 colors_used; + __u32 colors_important; +}; + +struct bmp_image { + struct bmp_header header; + /* ColorTable */ + uint8 * data; +}; + +#endif /* _BMP_LAYOUT_H_ */ diff --git a/psplash-fb.c b/psplash-fb.c index c064d18..307d6a8 100644 --- a/psplash-fb.c +++ b/psplash-fb.c @@ -441,6 +441,31 @@ psplash_fb_draw_image (PSplashFB *fb, } } +void +psplash_fb_draw_image_raw_GBR888 (PSplashFB *fb, + int x, + int y, + int img_width, + int img_height, + int img_bytes_per_pixel, + uint8 *rle_data) +{ + uint8 *p = rle_data; + int dx = 0, dy = 0, total_len; + int img_rowstride = img_bytes_per_pixel*img_width; + + total_len = img_rowstride * img_height; + /* Start at the end of pointer */ + p += (total_len - 1); + + while ((p - rle_data) >= 0) + { + psplash_fb_plot_pixel (fb, x-dx, y+dy, *(p), *(p-1), *(p-2)); + if (++dx * img_bytes_per_pixel >= img_rowstride) { dx=0; dy++; } + p -= img_bytes_per_pixel; + } +} + /* Font rendering code based on BOGL by Ben Pfaff */ static int diff --git a/psplash-fb.h b/psplash-fb.h index d0dce10..297add8 100644 --- a/psplash-fb.h +++ b/psplash-fb.h @@ -77,6 +77,15 @@ psplash_fb_draw_image (PSplashFB *fb, int img_rowstride, uint8 *rle_data); +void +psplash_fb_draw_image_raw_GBR888 (PSplashFB *fb, + int x, + int y, + int img_width, + int img_height, + int img_bytes_pre_pixel, + uint8 *rle_data); + void psplash_fb_text_size (int *width, int *height, diff --git a/psplash.c b/psplash.c index 992e199..f8a92b6 100644 --- a/psplash.c +++ b/psplash.c @@ -24,6 +24,7 @@ #include "psplash-poky-img.h" #include "psplash-bar-img.h" #include "radeon-font.h" +#include "bmp_layout.h" #define SPLIT_LINE_POS(fb) \ ( (fb)->height \ @@ -40,6 +41,59 @@ psplash_exit (int UNUSED(signum)) psplash_console_reset (); } +struct bmp_image *read_image_bmp(char *image_name) +{ + FILE *file; + size_t read; + struct bmp_image *bmp; + + file = fopen(image_name, "rb"); + if (file != NULL) + { + bmp = malloc(sizeof(struct bmp_image)); + + /* Read header */ + read = fread(&bmp->header, sizeof(struct bmp_header), 1, file); + if (read != 1) + { + printf("Error: Fail to read header\n"); + free(bmp); + fclose(file); + return NULL; + } + + /* Read BMP image signature */ + if (bmp->header.signature[0] != 'B' && bmp->header.signature[1] != 'M') + { + printf("Error: File format is not correct.\n"); + free(bmp); + fclose(file); + return NULL; + } + + bmp->data = malloc(sizeof(uint8) * bmp->header.image_size); + + /* Read data image */ + read = fread(bmp->data, sizeof(uint8), (bmp->header.image_size), file); + if (read != bmp->header.image_size) + { + printf("Error: Cannot read data image.\n"); + free(bmp); + fclose(file); + return NULL; + } + + fclose(file); + } + else + { + printf("Error: Cannot open %s.\n",image_name); + return NULL; + } + + return bmp; +} + void psplash_draw_msg (PSplashFB *fb, const char *msg) { @@ -208,6 +262,8 @@ main (int argc, char** argv) int pipe_fd, i = 0, angle = 0, fbdev_id = 0, ret = 0; PSplashFB *fb; bool disable_console_switch = FALSE; + char image_name[255] = ""; + struct bmp_image *bmp = NULL; signal(SIGHUP, psplash_exit); signal(SIGINT, psplash_exit); @@ -233,10 +289,16 @@ main (int argc, char** argv) fbdev_id = atoi(argv[i]); continue; } + if (!strcmp(argv[i],"-i") || !strcmp(argv[i],"--image")) + { + if (++i >= argc) goto fail; + strcpy(image_name,argv[i]); + continue; + } fail: fprintf(stderr, - "Usage: %s [-n|--no-console-switch][-a|--angle <0|90|180|270>][-f|--fbdev <0..9>]\n", + "Usage: %s [-n|--no-console-switch][-a|--angle <0|90|180|270>][-f|--fbdev <0..9>][-i|--image <bmp_image>]\n", argv[0]); exit(-1); } @@ -278,8 +340,31 @@ main (int argc, char** argv) psplash_fb_draw_rect (fb, 0, 0, fb->width, fb->height, PSPLASH_BACKGROUND_COLOR); - /* Draw the Poky logo */ - psplash_fb_draw_image (fb, + if (strcmp(image_name,"") != 0) + { + bmp = read_image_bmp(image_name); + } + + if (bmp != NULL) + { + /* Draw loaded logo */ + psplash_fb_draw_image_raw_GBR888 (fb, + (fb->width + bmp->header.width)/2, +#if PSPLASH_IMG_FULLSCREEN + (fb->height - bmp->header.height)/2, +#else + (fb->height * PSPLASH_IMG_SPLIT_NUMERATOR + / PSPLASH_IMG_SPLIT_DENOMINATOR - bmp->header.height)/2, +#endif + bmp->header.width, + bmp->header.height, + BMP_IMG_BYTES_PER_PIXEL, + bmp->data); + } + else + { + /* Draw the Poky logo */ + psplash_fb_draw_image (fb, (fb->width - POKY_IMG_WIDTH)/2, #if PSPLASH_IMG_FULLSCREEN (fb->height - POKY_IMG_HEIGHT)/2, @@ -292,6 +377,7 @@ main (int argc, char** argv) POKY_IMG_BYTES_PER_PIXEL, POKY_IMG_ROWSTRIDE, POKY_IMG_RLE_PIXEL_DATA); + } /* Draw progress bar border */ psplash_fb_draw_image (fb, @@ -320,5 +406,8 @@ main (int argc, char** argv) if (!disable_console_switch) psplash_console_reset (); + if(bmp!=NULL) + free(bmp); + return ret; } -- 2.22.0 -- _______________________________________________ yocto mailing list yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/yocto