diff -rup gimp-2.2.15-original/plug-ins/common/psd.c gimp-2.2.15-fixed/plug-ins/common/psd.c
--- gimp-2.2.15-original/plug-ins/common/psd.c	2007-04-17 14:11:24.000000000 -0700
+++ gimp-2.2.15-fixed/plug-ins/common/psd.c	2007-06-07 14:37:27.000000000 -0700
@@ -399,6 +399,7 @@ static void xfread_interlaced(FILE *fd, 
 static void read_whole_file(FILE *fd);
 static void reshuffle_cmap(guchar *map256);
 static gchar* getpascalstring(FILE *fd, gchar *why);
+static gchar* getunicodepascalstring(FILE *fd, gchar *why);
 static gchar* getstring(size_t n, FILE * fd, gchar *why);
 static void throwchunk(size_t n, FILE * fd, gchar *why);
 static void dumpchunk(size_t n, FILE * fd, gchar *why);
@@ -1088,11 +1089,104 @@ do_layer_record(FILE *fd, guint32 *offse
       (*offset) += strlen(layer->name);
       IFDBG printf("\t\t\t\t\t\tLAYER NAME: '%s'\n", layer->name);
       layer->name = sanitise_string(layer->name);
+
+      /* Layer name string lengths are padded to be divisible by 4 */
+      guchar padding = 4-((1+strlen(layer->name)) % 4);
+      if (padding == 4)
+        padding = 0;
+
+      if (padding)
+      {
+        throwchunk(padding, fd, "layer record extra data block throw");
+        (*offset) += padding;
+      }
     }
   else
     {
       IFDBG printf("\t\t\t\t\t\tNULL LAYER NAME\n");
     }
+
+  /*
+    The remaining data in this layer contains any number of blocks that follow
+    this structure:
+
+    4 bytes for signature (always 8BIM)
+    4 bytes for a key to define kind of data
+    4 bytes for size of data to follow
+    ? bytes of data
+   */
+
+  IFDBG printf( "\n\t\t\t\t\tLayer ExtraDataBlock Info\n" );
+  while (totaloff-(*offset) > 12)
+  {
+    guint32 fd_before = ftell (fd);
+
+    gchar signature[4];
+    xfread(fd, signature, 4, "layer extra data block signature");
+    guint32 key = getglong(fd, "layer extra data block key");
+    guint32 layerextradatasize = getglong(fd, "layer extra data block size");
+
+    switch(key)
+    {
+      /* luni: Long unicode name */
+      case 0x6c756e69:
+      {
+        if (layer->name)
+          g_free(layer->name);
+
+        layer->name = getunicodepascalstring(fd, "layer name");
+
+        if (layer->name)
+        {
+          layer->name = sanitise_string(layer->name);
+        }
+        IFDBG printf("\t\t\t\t\t\tluni LAYER NAME: '%s'\n",layer->name);
+      }
+      break;
+
+      /* lyid: Layer id number */
+      case 0x6c796964:
+      {
+        guint32 lyid = getglong(fd, "layer extra data block lyid");
+        IFDBG printf("\t\t\t\t\t\tLayer ID #%d\n",lyid);
+      }
+      break;
+
+      /* lclr: Layer Color */
+      case 0x6c636c72:
+      IFDBG
+        {
+          {
+            guchar *data = g_malloc(layerextradatasize);
+            xfread(fd, data, layerextradatasize, "lclr: Layer Color Data");
+            printf("\t\t\t\t\t\tLayer Color=%d ",data[1]);
+            switch(data[1])
+            {
+              case 0: printf("None\n"); break;
+              case 1: printf("Red\n"); break;
+              case 2: printf("Orange\n"); break;
+              case 3: printf("Yellow\n"); break;
+              case 4: printf("Green\n"); break;
+              case 5: printf("Blue\n"); break;
+              case 6: printf("Violet\n"); break;
+              case 7: printf("Grey\n"); break;
+              default:
+                printf("Undefined\n");
+            }
+            free(data);
+          }
+          break;
+        }
+
+      default:
+      {
+        IFDBG printf("\t\t\t\t\t\tUnknown key=0x%x\tdata size=0x%x\n", key, layerextradatasize);
+        throwchunk(layerextradatasize, fd, "layer record extra data block throw");
+      }
+    }
+    (*offset) += ftell(fd) - fd_before;
+  }
+
   /* If no layermask data - set offset and size from layer data */
   if (! layermaskdatasize)
     {
@@ -2690,6 +2784,44 @@ getpascalstring(FILE *fd, gchar *why)
   return (gchar *) tmpchunk; /* caller should free memory */
 }
 
+static gchar *
+getunicodepascalstring(FILE *fd, gchar *why)
+{
+  guchar *tmpunichunk;
+  guint32 len = getglong(fd, why);
+
+  if (len==0)
+    {
+      return NULL;
+    }
+
+  guint32 numbytes = (len + len%2) * 2;
+  tmpunichunk = g_malloc(numbytes+1);
+
+  xfread(fd, tmpunichunk, numbytes, why);
+  tmpunichunk[numbytes]=0;
+
+  guchar *tmpchunk = 0;
+  if (len)
+    {
+      tmpchunk = g_malloc(len+1);
+
+      guint newstrPtr=0;
+      guint oldstrPtr=1;
+      while(oldstrPtr < numbytes && newstrPtr < len)
+       {
+         tmpchunk[newstrPtr] = tmpunichunk[oldstrPtr];
+         newstrPtr++;
+         oldstrPtr+=2;
+       }
+
+      tmpchunk[len] = 0;
+    }
+  g_free(tmpunichunk);
+
+  return (gchar *) tmpchunk; /* caller should free memory */
+}
+
 static guchar
 getguchar(FILE *fd, gchar *why)
 {
