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
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel