diff --git a/ChangeLog b/ChangeLog
index f8e24de4b..cbe7f0cf4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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.
diff --git a/fs/ntfs.c b/fs/ntfs.c
index 8247efb03..2922ade6e 100644
--- a/fs/ntfs.c
+++ b/fs/ntfs.c
@@ -176,17 +176,15 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr)
       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");
@@ -818,8 +816,7 @@ grub_ntfs_mount (grub_disk_t disk)
 
   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;
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
index 2b0f21d35..e66e0c318 100644
--- a/include/grub/ntfs.h
+++ b/include/grub/ntfs.h
@@ -71,7 +71,6 @@
 
 #define MAX_MFT		(1024 >> BLK_SHR)
 #define MAX_IDX		(16384 >> BLK_SHR)
-#define MAX_SPC		(4096 >> BLK_SHR)
 
 #define COM_LEN		4096
 #define COM_SEC		(COM_LEN >> BLK_SHR)
diff --git a/video/readers/png.c b/video/readers/png.c
index fd97ca481..608fa5e4a 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);
     }