[yocto] [psplash][PATCH] bmp: Add option to print bmp image
Mickaël Tansorier
mickael.tansorier at smile.fr
Wed Aug 21 04:46:33 PDT 2019
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.tansorier at 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
More information about the yocto
mailing list