+2008-03-31 Bean <bean123ch@gmail.com>
+
+ * video/reader/png.c (grub_png_data): New member is_16bit and
+ image_data.
+ (grub_png_decode_image_header): Detect 16 bit png image.
+ (grub_png_convert_image): New function to convert 16 bit image to 8 bit.
+ (grub_png_decode_png): Call grub_png_convert_image for 16 bit image.
+ (grub_video_reader_png): Release memory occupied by image_data.
+
+ * fs/ntfs.c (find_attr): Handle non-resident attribute list larger than
+ 4096 bytes.
+ (grub_nfs_mount): Skip the test for sector per cluster.
+
+ * include/grub/ntfs.h (MAX_SPC): Removed.
+
2008-03-31 Bean <bean123ch@gmail.com>
* conf/common.rmk (pkgdata_MODULES): Add afs.mod.
pa = at->attr_end;
if (pa[8])
{
- if (u32at (pa, 0x28) > 4096)
- {
- grub_error (GRUB_ERR_BAD_FS,
- "Non-resident attribute list too large");
- return NULL;
- }
+ int n;
+
+ n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
+ & (~(GRUB_DISK_SECTOR_SIZE - 1)));
at->attr_cur = at->attr_end;
- at->edat_buf = grub_malloc (u32at (pa, 0x28));
+ at->edat_buf = grub_malloc (n);
if (!at->edat_buf)
return NULL;
- if (read_data (at, pa, at->edat_buf, 0, u32at (pa, 0x28), 0, 0))
+ if (read_data (at, pa, at->edat_buf, 0, n, 0, 0))
{
grub_error (GRUB_ERR_BAD_FS,
"Fail to read non-resident attribute list");
data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
- if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX) ||
- (data->spc > MAX_SPC) || (data->spc > data->idx_size))
+ if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
goto fail;
data->mmft.data = 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;
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);
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)
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;
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)
{
break;
case PNG_CHUNK_IEND:
+ if (data->is_16bit)
+ grub_png_convert_image (data);
+
return grub_errno;
default:
grub_png_decode_png (data);
+ grub_free (data->image_data);
grub_free (data);
}