* grub-core/video/readers/png.c: Support grayscale
This commit is contained in:
parent
e9c492a02e
commit
3ccf16dff9
2 changed files with 154 additions and 44 deletions
|
@ -1,8 +1,12 @@
|
||||||
2013-09-24 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-09-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/video/readers/png.c: Support grayscale
|
||||||
|
|
||||||
|
2013-09-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/video/readers/jpeg.c: Support grayscale.
|
* grub-core/video/readers/jpeg.c: Support grayscale.
|
||||||
|
|
||||||
2013-09-24 Jon McCune <jonmccune@google.com>
|
2013-09-26 Jon McCune <jonmccune@google.com>
|
||||||
|
|
||||||
* grub-core/commands/loadenv.c: Support skipping signature check
|
* grub-core/commands/loadenv.c: Support skipping signature check
|
||||||
and variable names filtering.
|
and variable names filtering.
|
||||||
|
|
|
@ -29,15 +29,14 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
/* Uncomment following define to enable PNG debug. */
|
/* Uncomment following define to enable PNG debug. */
|
||||||
//#define PNG_DEBUG
|
//#define PNG_DEBUG
|
||||||
|
|
||||||
#define PNG_COLOR_MASK_PALETTE 1
|
enum
|
||||||
#define PNG_COLOR_MASK_COLOR 2
|
{
|
||||||
#define PNG_COLOR_MASK_ALPHA 4
|
PNG_COLOR_TYPE_GRAY = 0,
|
||||||
|
PNG_COLOR_MASK_PALETTE = 1,
|
||||||
#define PNG_COLOR_TYPE_GRAY 0
|
PNG_COLOR_MASK_COLOR = 2,
|
||||||
#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
|
PNG_COLOR_MASK_ALPHA = 4,
|
||||||
#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
|
PNG_COLOR_TYPE_PALETTE = (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE),
|
||||||
#define PNG_COLOR_TYPE_RGBA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
|
};
|
||||||
#define PNG_COLOR_TYPE_GRAYA (PNG_COLOR_MASK_ALPHA)
|
|
||||||
|
|
||||||
#define PNG_COMPRESSION_BASE 0
|
#define PNG_COMPRESSION_BASE 0
|
||||||
|
|
||||||
|
@ -94,7 +93,8 @@ struct grub_png_data
|
||||||
|
|
||||||
grub_uint32_t next_offset;
|
grub_uint32_t next_offset;
|
||||||
|
|
||||||
int image_width, image_height, bpp, is_16bit, raw_bytes;
|
int image_width, image_height, bpp, is_16bit;
|
||||||
|
int raw_bytes, is_gray, is_alpha;
|
||||||
grub_uint8_t *image_data;
|
grub_uint8_t *image_data;
|
||||||
|
|
||||||
int inside_idat, idat_remain;
|
int inside_idat, idat_remain;
|
||||||
|
@ -218,6 +218,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
|
||||||
{
|
{
|
||||||
int color_type;
|
int color_type;
|
||||||
int color_bits;
|
int color_bits;
|
||||||
|
enum grub_video_blit_format blt;
|
||||||
|
|
||||||
data->image_width = grub_png_get_dword (data);
|
data->image_width = grub_png_get_dword (data);
|
||||||
data->image_height = grub_png_get_dword (data);
|
data->image_height = grub_png_get_dword (data);
|
||||||
|
@ -232,31 +233,34 @@ grub_png_decode_image_header (struct grub_png_data *data)
|
||||||
data->is_16bit = (color_bits == 16);
|
data->is_16bit = (color_bits == 16);
|
||||||
|
|
||||||
color_type = grub_png_get_byte (data);
|
color_type = grub_png_get_byte (data);
|
||||||
if (color_type == PNG_COLOR_TYPE_RGB)
|
if (color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR))
|
||||||
{
|
|
||||||
if (grub_video_bitmap_create (data->bitmap, data->image_width,
|
|
||||||
data->image_height,
|
|
||||||
GRUB_VIDEO_BLIT_FORMAT_RGB_888))
|
|
||||||
return grub_errno;
|
|
||||||
data->bpp = 3;
|
|
||||||
}
|
|
||||||
else if (color_type == PNG_COLOR_TYPE_RGBA)
|
|
||||||
{
|
|
||||||
if (grub_video_bitmap_create (data->bitmap, data->image_width,
|
|
||||||
data->image_height,
|
|
||||||
GRUB_VIDEO_BLIT_FORMAT_RGBA_8888))
|
|
||||||
return grub_errno;
|
|
||||||
data->bpp = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
||||||
"png: color type not supported");
|
"png: color type not supported");
|
||||||
|
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||||
|
blt = GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
|
||||||
|
else
|
||||||
|
blt = GRUB_VIDEO_BLIT_FORMAT_RGB_888;
|
||||||
|
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||||
|
data->bpp = 3;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->is_gray = 1;
|
||||||
|
data->bpp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||||
|
data->bpp++;
|
||||||
|
|
||||||
|
if (grub_video_bitmap_create (data->bitmap, data->image_width,
|
||||||
|
data->image_height,
|
||||||
|
blt))
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
if (data->is_16bit)
|
if (data->is_16bit)
|
||||||
data->bpp <<= 1;
|
data->bpp <<= 1;
|
||||||
|
|
||||||
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
if (data->is_16bit)
|
if (data->is_16bit || !(color_type & PNG_COLOR_MASK_COLOR))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
data->image_data = grub_malloc (data->image_height *
|
data->image_data = grub_malloc (data->image_height *
|
||||||
|
@ -781,9 +785,63 @@ grub_png_convert_image (struct grub_png_data *data)
|
||||||
|
|
||||||
/* Only copy the upper 8 bit. */
|
/* Only copy the upper 8 bit. */
|
||||||
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
|
if (!data->is_gray)
|
||||||
i++, d1++, d2+=2)
|
{
|
||||||
*d1 = *d2;
|
for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
|
||||||
|
i++, d1++, d2 += 2)
|
||||||
|
*d1 = *d2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (data->bpp)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
/* 16-bit gray with alpha. */
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 4)
|
||||||
|
{
|
||||||
|
d1[3] = d2[3];
|
||||||
|
d1[1] = d2[3];
|
||||||
|
d1[2] = d2[3];
|
||||||
|
d1[0] = d2[1];
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if (data->is_16bit)
|
||||||
|
/* 16-bit gray without alpha. */
|
||||||
|
{
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 2)
|
||||||
|
{
|
||||||
|
d1[0] = d2[1];
|
||||||
|
d1[1] = d2[1];
|
||||||
|
d1[2] = d2[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* 8-bit gray with alpha. */
|
||||||
|
{
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 2)
|
||||||
|
{
|
||||||
|
d1[3] = d2[1];
|
||||||
|
d1[1] = d2[1];
|
||||||
|
d1[2] = d2[1];
|
||||||
|
d1[0] = d2[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* 8-bit gray without alpha. */
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 3, d2++)
|
||||||
|
{
|
||||||
|
d1[0] = d2[0];
|
||||||
|
d1[1] = d2[0];
|
||||||
|
d1[2] = d2[0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
switch (data->bpp)
|
switch (data->bpp)
|
||||||
{
|
{
|
||||||
|
@ -808,15 +866,30 @@ grub_png_convert_image (struct grub_png_data *data)
|
||||||
d1[2] = d2[1];
|
d1[2] = d2[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* 8-bit with alpha. */
|
|
||||||
case 4:
|
case 4:
|
||||||
for (i = 0; i < (data->image_width * data->image_height);
|
if (data->is_16bit)
|
||||||
i++, d1 += 4, d2 += 4)
|
|
||||||
{
|
{
|
||||||
d1[0] = d2[3];
|
/* 16-bit gray with alpha. */
|
||||||
d1[1] = d2[2];
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
d1[2] = d2[1];
|
i++, d1 += 4, d2 += 4)
|
||||||
d1[3] = d2[0];
|
{
|
||||||
|
d1[0] = d2[3];
|
||||||
|
d1[1] = d2[3];
|
||||||
|
d1[2] = d2[3];
|
||||||
|
d1[3] = d2[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 8-bit with alpha. */
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 4)
|
||||||
|
{
|
||||||
|
d1[0] = d2[3];
|
||||||
|
d1[1] = d2[2];
|
||||||
|
d1[2] = d2[1];
|
||||||
|
d1[3] = d2[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* 8-bit without alpha. */
|
/* 8-bit without alpha. */
|
||||||
|
@ -829,6 +902,41 @@ grub_png_convert_image (struct grub_png_data *data)
|
||||||
d1[2] = d2[0];
|
d1[2] = d2[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
if (data->is_16bit)
|
||||||
|
/* 16-bit gray without alpha. */
|
||||||
|
{
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 2)
|
||||||
|
{
|
||||||
|
d1[0] = d2[1];
|
||||||
|
d1[1] = d2[1];
|
||||||
|
d1[2] = d2[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* 8-bit gray with alpha. */
|
||||||
|
{
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 4, d2 += 2)
|
||||||
|
{
|
||||||
|
d1[0] = d2[1];
|
||||||
|
d1[1] = d2[1];
|
||||||
|
d1[2] = d2[1];
|
||||||
|
d1[3] = d2[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* 8-bit gray without alpha. */
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i < (data->image_width * data->image_height);
|
||||||
|
i++, d1 += 3, d2++)
|
||||||
|
{
|
||||||
|
d1[0] = d2[0];
|
||||||
|
d1[1] = d2[0];
|
||||||
|
d1[2] = d2[0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -869,9 +977,7 @@ grub_png_decode_png (struct grub_png_data *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PNG_CHUNK_IEND:
|
case PNG_CHUNK_IEND:
|
||||||
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
if (data->image_data)
|
||||||
if (data->is_16bit)
|
|
||||||
#endif
|
|
||||||
grub_png_convert_image (data);
|
grub_png_convert_image (data);
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -926,7 +1032,7 @@ grub_video_reader_png (struct grub_video_bitmap **bitmap,
|
||||||
|
|
||||||
#if defined(PNG_DEBUG)
|
#if defined(PNG_DEBUG)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_pngtest (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_pngtest (grub_command_t cmd_d __attribute__ ((unused)),
|
||||||
int argc, char **args)
|
int argc, char **args)
|
||||||
{
|
{
|
||||||
struct grub_video_bitmap *bitmap = 0;
|
struct grub_video_bitmap *bitmap = 0;
|
||||||
|
|
Loading…
Reference in a new issue