On Thu, Mar 27, 2008 at 11:30 PM, Pavel Roskin <[EMAIL PROTECTED]> wrote:
> On Thu, 2008-03-27 at 16:24 +0800, Bean wrote:
>  > On Thu, Mar 27, 2008 at 10:09 AM, Pavel Roskin <[EMAIL PROTECTED]> wrote:
>  > >  It turned out that the splash image called isolinux/splash.jpg is
>  > >  actually a png file.  What's worse, GRUB won't use it because it's not
>  > >  8-bit:
>  > >
>  > >  $ identify splash.jpg
>  > >  splash.jpg PNG 640x480 640x480+0+0 DirectClass 16-bit 436.441kb
>  >
>  > It's quite easy to support 16-bit png, but i don't have one to test.
>  > would you please send the image to me ?
>
>  http://red-bean.com/proski/splash.png

Hi,

This patch add support for 16-bit png. Unfortuanate, grub itself
doesn't support 16-bit color, so I convert the image to 8 bit to
display.

-- 
Bean
diff --git a/video/readers/png.c b/video/readers/png.c
index fd97ca4..608fa5e 100644
--- a/video/readers/png.c
+++ b/video/readers/png.c
@@ -89,7 +89,8 @@ struct grub_png_data
 
   grub_uint32_t next_offset;
 
-  int image_width, image_height, bpp, raw_bytes;
+  int image_width, image_height, bpp, is_16bit, raw_bytes;
+  grub_uint8_t *image_data;
 
   int inside_idat, idat_remain;
 
@@ -211,6 +212,7 @@ static grub_err_t
 grub_png_decode_image_header (struct grub_png_data *data)
 {
   int color_type;
+  int color_bits;
 
   data->image_width = grub_png_get_dword (data);
   data->image_height = grub_png_get_dword (data);
@@ -218,8 +220,11 @@ grub_png_decode_image_header (struct grub_png_data *data)
   if ((!data->image_height) || (!data->image_width))
     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
 
-  if (grub_png_get_byte (data) != 8)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: bit depth must be 8");
+  color_bits = grub_png_get_byte (data);
+  if ((color_bits != 8) && (color_bits != 16))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                       "png: bit depth must be 8 or 16");
+  data->is_16bit = (color_bits == 16);
 
   color_type = grub_png_get_byte (data);
   if (color_type == PNG_COLOR_TYPE_RGB)
@@ -242,9 +247,25 @@ grub_png_decode_image_header (struct grub_png_data *data)
     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
                       "png: color type not supported");
 
+  if (data->is_16bit)
+    {
+      data->bpp <<= 1;
+
+      data->image_data = grub_malloc (data->image_height *
+                                      data->image_width *  data->bpp);
+      if (grub_errno)
+        return grub_errno;
+
+      data->cur_rgb = data->image_data;
+    }
+  else
+    {
+      data->image_data = 0;
+      data->cur_rgb = (*data->bitmap)->data;
+    }
+
   data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp;
 
-  data->cur_rgb = (*data->bitmap)->data;
   data->cur_colume = 0;
   data->first_line = 1;
 
@@ -705,6 +726,21 @@ grub_png_decode_image_data (struct grub_png_data *data)
 static const grub_uint8_t png_magic[8] =
   { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0x0a };
 
+static void
+grub_png_convert_image (struct grub_png_data *data)
+{
+  int i;
+  grub_uint8_t *d1, *d2;
+
+  d1 = (*data->bitmap)->data;
+  d2 = data->image_data + 1;
+
+  /* Only copy the upper 8 bit.  */
+  for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
+       i++, d1++, d2+=2)
+    *d1 = *d2;
+}
+
 static grub_err_t
 grub_png_decode_png (struct grub_png_data *data)
 {
@@ -741,6 +777,9 @@ grub_png_decode_png (struct grub_png_data *data)
          break;
 
        case PNG_CHUNK_IEND:
+          if (data->is_16bit)
+            grub_png_convert_image (data);
+
          return grub_errno;
 
        default:
@@ -778,6 +817,7 @@ grub_video_reader_png (struct grub_video_bitmap **bitmap,
 
       grub_png_decode_png (data);
 
+      grub_free (data->image_data);
       grub_free (data);
     }
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to