[SeaBIOS] bmp/bootsplash: Added support for 16/24/32bpp in one function

Joseph Pacheco-Corwin posted 1 patch 5 years, 2 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/seabios tags/patchew/154844035172.22.838027367994522728@cfa51d96e5da
src/bmp.c        | 19 +++++++++----------
src/bootsplash.c | 17 +++++++++++++----
src/util.h       |  2 +-
3 files changed, 23 insertions(+), 15 deletions(-)
[SeaBIOS] bmp/bootsplash: Added support for 16/24/32bpp in one function
Posted by Joseph Pacheco-Corwin 5 years, 2 months ago
Specifically added support for 16 and 32bpp files, in addition to 24bpp.
The function bmp_show() in bmp.c has had the hardcoded check for 24bpp replaced with a general 
bpp check that uses a % to check for remainder, and returns 1 if the remainder is >0.
The previous method for adjusting the BMP data (raw_data_format_adjust_24bpp) relied
on a preset 3*bytes_per_line_src, this has been changed and the multiplication is now performed
in the function's arguments. This change still allows someone else to reuse the same function for
1/2/4bpp support if necessary. The file util.h has been modified to reflect this decision.

The changes to raw_data_format_adjust() is based on an
abandoned patch by Gert Menke (submitted March 14, 2017),
credit to them for that change and the addition of *bpp to bmp_get_info().

Any feedback? I would appreciate it.

Signed-off-by: Joseph S. Pacheco-Corwin <hammersamatom@gmail.com>
---
 src/bmp.c        | 19 +++++++++----------
 src/bootsplash.c | 17 +++++++++++++----
 src/util.h       |  2 +-
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/bmp.c b/src/bmp.c
index 96a2b3f..fecc295 100644
--- a/src/bmp.c
+++ b/src/bmp.c
@@ -56,10 +56,9 @@ typedef struct tagRGBQUAD {
 *   arrange horizontal pixel data, add extra space in the dest buffer
 *       for every line
 */
-static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width,
-                                        int height, int bytes_per_line_dest)
+static void raw_data_format_adjust(u8 *src, u8 *dest, int width,
+		int height, int bytes_per_line_src, int bytes_per_line_dest)
 {
-    int bytes_per_line_src = 3 * width;
     int i;
     for (i = 0 ; i < height ; i++) {
         memcpy(dest + i * bytes_per_line_dest,
@@ -95,22 +94,22 @@ int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
 }
 
 /* get bmp properties */
-void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height)
+void bmp_get_info(struct bmp_decdata *bmp, int *width, int *height, int *bpp)
 {
     *width = bmp->width;
     *height = bmp->height;
+    *bpp = bmp->bpp;
 }
 
 /* flush flat picture data to *pc */
-int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
-             , int height, int depth, int bytes_per_line_dest)
+int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width,
+             int height, int depth, int bytes_per_line_dest)
 {
     if (bmp->datap == pic)
         return 0;
-    /* now only support 24bpp bmp file */
-    if ((depth == 24) && (bmp->bpp == 24)) {
-        raw_data_format_adjust_24bpp(bmp->datap, pic, width, height,
-                                        bytes_per_line_dest);
+    if ((depth == bmp->bpp) && (bmp->bpp%8 == 0)) {
+        raw_data_format_adjust(bmp->datap, pic, width, height,
+			(bmp->bpp/8)*width, bytes_per_line_dest);
         return 0;
     }
     return 1;
diff --git a/src/bootsplash.c b/src/bootsplash.c
index 165c98d..401c348 100644
--- a/src/bootsplash.c
+++ b/src/bootsplash.c
@@ -172,10 +172,13 @@ enable_bootsplash(void)
             dprintf(1, "bmp_decode failed with return code %d...\n", ret);
             goto done;
         }
-        bmp_get_size(bmp, &width, &height);
-        bpp_require = 24;
+        bmp_get_info(bmp, &width, &height, &bpp_require);
     }
-    /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */
+
+    /* jpeg would use 16 or 24 bpp video mode, BMP uses 8/16/24/32 bpp mode.
+     * 8bpp for BMP has corrupted colors, and lower than 8bpp fails to display
+     * or results in a loop.
+     */
 
     // Try to find a graphics mode with the corresponding dimensions.
     int videomode = find_videomode(vesa_info, mode_info, width, height,
@@ -192,7 +195,13 @@ enable_bootsplash(void)
     dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
     dprintf(3, "bits per pixel: %d\n", depth);
 
-    // Allocate space for image and decompress it.
+    // Allocate space for image and decompress it. 
+    /*
+     * Has a weird issue with low bpp image files, imagesize is not
+     * consistent. Example: 8bpp images are correct, being essentially
+     * multiplied/divided by 1, but if you use 4bpp images, width is divided by
+     * 8, when it should be divided by 2.
+     */
     int imagesize = height * mode_info->bytes_per_scanline;
     picture = malloc_tmphigh(imagesize);
     if (!picture) {
diff --git a/src/util.h b/src/util.h
index 6dd080f..9c06850 100644
--- a/src/util.h
+++ b/src/util.h
@@ -12,7 +12,7 @@ void handle_1553(struct bregs *regs);
 // bmp.c
 struct bmp_decdata *bmp_alloc(void);
 int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size);
-void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height);
+void bmp_get_info(struct bmp_decdata *bmp, int *width, int *height, int *bpp);
 int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
              , int height, int depth, int bytes_per_line_dest);
 
-- 
2.20.1
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: bmp/bootsplash: Added support for 16/24/32bpp in one function
Posted by Joseph Pacheco-Corwin 5 years, 2 months ago
I'm an absolute fool, forgetting to add [PATCH] int he subject line. Apologies.
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: bmp/bootsplash: Added support for 16/24/32bpp in one function
Posted by Kevin O'Connor 5 years, 2 months ago
On Fri, Jan 25, 2019 at 06:19:11PM -0000, Joseph Pacheco-Corwin wrote:
> Specifically added support for 16 and 32bpp files, in addition to 24bpp.
> The function bmp_show() in bmp.c has had the hardcoded check for 24bpp replaced with a general 
> bpp check that uses a % to check for remainder, and returns 1 if the remainder is >0.
> The previous method for adjusting the BMP data (raw_data_format_adjust_24bpp) relied
> on a preset 3*bytes_per_line_src, this has been changed and the multiplication is now performed
> in the function's arguments. This change still allows someone else to reuse the same function for
> 1/2/4bpp support if necessary. The file util.h has been modified to reflect this decision.
> 
> The changes to raw_data_format_adjust() is based on an
> abandoned patch by Gert Menke (submitted March 14, 2017),
> credit to them for that change and the addition of *bpp to bmp_get_info().
> 
> Any feedback? I would appreciate it.

Thanks.  In general it looks fine, but I do have one minor comment
below.

[...]
> --- a/src/bootsplash.c
> +++ b/src/bootsplash.c
> @@ -172,10 +172,13 @@ enable_bootsplash(void)
>              dprintf(1, "bmp_decode failed with return code %d...\n", ret);
>              goto done;
>          }
> -        bmp_get_size(bmp, &width, &height);
> -        bpp_require = 24;
> +        bmp_get_info(bmp, &width, &height, &bpp_require);
>      }
> -    /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */
> +
> +    /* jpeg would use 16 or 24 bpp video mode, BMP uses 8/16/24/32 bpp mode.
> +     * 8bpp for BMP has corrupted colors, and lower than 8bpp fails to display
> +     * or results in a loop.
> +     */
>  
>      // Try to find a graphics mode with the corresponding dimensions.
>      int videomode = find_videomode(vesa_info, mode_info, width, height,
> @@ -192,7 +195,13 @@ enable_bootsplash(void)
>      dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
>      dprintf(3, "bits per pixel: %d\n", depth);
>  
> -    // Allocate space for image and decompress it.
> +    // Allocate space for image and decompress it. 
> +    /*
> +     * Has a weird issue with low bpp image files, imagesize is not
> +     * consistent. Example: 8bpp images are correct, being essentially
> +     * multiplied/divided by 1, but if you use 4bpp images, width is divided by
> +     * 8, when it should be divided by 2.
> +     */

I would ask that we avoid changing the comments to document what the
code does not do.  As I find comments discussing what is not
implemented to be confusing.

Cheers,
-Kevin
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: bmp/bootsplash: Added support for 16/24/32bpp in one function
Posted by Joseph Pacheco-Corwin 5 years, 2 months ago
I've removed the extra unneeded comments. I will keep this in mind for the future, thank you.

---
 src/bmp.c        | 19 +++++++++----------
 src/bootsplash.c |  8 ++++----
 src/util.h       |  2 +-
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/bmp.c b/src/bmp.c
index 96a2b3f..fecc295 100644
--- a/src/bmp.c
+++ b/src/bmp.c
@@ -56,10 +56,9 @@ typedef struct tagRGBQUAD {
 *   arrange horizontal pixel data, add extra space in the dest buffer
 *       for every line
 */
-static void raw_data_format_adjust_24bpp(u8 *src, u8 *dest, int width,
-                                        int height, int bytes_per_line_dest)
+static void raw_data_format_adjust(u8 *src, u8 *dest, int width,
+		int height, int bytes_per_line_src, int bytes_per_line_dest)
 {
-    int bytes_per_line_src = 3 * width;
     int i;
     for (i = 0 ; i < height ; i++) {
         memcpy(dest + i * bytes_per_line_dest,
@@ -95,22 +94,22 @@ int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size)
 }
 
 /* get bmp properties */
-void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height)
+void bmp_get_info(struct bmp_decdata *bmp, int *width, int *height, int *bpp)
 {
     *width = bmp->width;
     *height = bmp->height;
+    *bpp = bmp->bpp;
 }
 
 /* flush flat picture data to *pc */
-int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
-             , int height, int depth, int bytes_per_line_dest)
+int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width,
+             int height, int depth, int bytes_per_line_dest)
 {
     if (bmp->datap == pic)
         return 0;
-    /* now only support 24bpp bmp file */
-    if ((depth == 24) && (bmp->bpp == 24)) {
-        raw_data_format_adjust_24bpp(bmp->datap, pic, width, height,
-                                        bytes_per_line_dest);
+    if ((depth == bmp->bpp) && (bmp->bpp%8 == 0)) {
+        raw_data_format_adjust(bmp->datap, pic, width, height,
+			(bmp->bpp/8)*width, bytes_per_line_dest);
         return 0;
     }
     return 1;
diff --git a/src/bootsplash.c b/src/bootsplash.c
index 165c98d..a251bf4 100644
--- a/src/bootsplash.c
+++ b/src/bootsplash.c
@@ -172,10 +172,10 @@ enable_bootsplash(void)
             dprintf(1, "bmp_decode failed with return code %d...\n", ret);
             goto done;
         }
-        bmp_get_size(bmp, &width, &height);
-        bpp_require = 24;
+        bmp_get_info(bmp, &width, &height, &bpp_require);
     }
-    /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */
+
+    // jpeg would use 16 or 24 bpp video mode, BMP uses 16/24/32 bpp mode.
 
     // Try to find a graphics mode with the corresponding dimensions.
     int videomode = find_videomode(vesa_info, mode_info, width, height,
@@ -192,7 +192,7 @@ enable_bootsplash(void)
     dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
     dprintf(3, "bits per pixel: %d\n", depth);
 
-    // Allocate space for image and decompress it.
+    // Allocate space for image and decompress it.  
     int imagesize = height * mode_info->bytes_per_scanline;
     picture = malloc_tmphigh(imagesize);
     if (!picture) {
diff --git a/src/util.h b/src/util.h
index 6dd080f..9c06850 100644
--- a/src/util.h
+++ b/src/util.h
@@ -12,7 +12,7 @@ void handle_1553(struct bregs *regs);
 // bmp.c
 struct bmp_decdata *bmp_alloc(void);
 int bmp_decode(struct bmp_decdata *bmp, unsigned char *data, int data_size);
-void bmp_get_size(struct bmp_decdata *bmp, int *width, int *height);
+void bmp_get_info(struct bmp_decdata *bmp, int *width, int *height, int *bpp);
 int bmp_show(struct bmp_decdata *bmp, unsigned char *pic, int width
              , int height, int depth, int bytes_per_line_dest);
 
-- 
2.20.1
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: bmp/bootsplash: Added support for 16/24/32bpp in one function
Posted by Kevin O'Connor 5 years, 2 months ago
On Tue, Jan 29, 2019 at 11:00:00PM -0000, Joseph Pacheco-Corwin wrote:
> I've removed the extra unneeded comments. I will keep this in mind for the future, thank you.

Thanks.  I committed this change.

-Kevin
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org