Index: psd-image-res-load.c
===================================================================
--- psd-image-res-load.c	(revision 24558)
+++ psd-image-res-load.c	(working copy)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-
 /* ----- Known Image Resource Block Types -----
   All image resources not otherwise handled, including unknown types
   are added as image parasites.
@@ -83,12 +82,12 @@
   PSD_PATH_INFO_LAST    = 2998,    Loaded     * 0x0bb6 - Last path info block *
   PSD_CLIPPING_PATH     = 2999,               * 0x0bb7 - Name of clipping path *
   PSD_PRINT_FLAGS_2     = 10000               * 0x2710 - Print flags *
-
 */
 
 #include "config.h"
 
 #include <string.h>
+#include <errno.h>
 
 #include <glib/gstdio.h>
 #include <libgimp/gimp.h>
@@ -111,230 +110,256 @@
 
 #define EXIF_HEADER_SIZE 8
 
-
 /*  Local function prototypes  */
 static gint     load_resource_unknown  (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_ps_only  (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1005     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1006     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1007     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1008     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1022     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1024     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1028     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1032     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1033     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1039     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1045     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1046     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1053     (const PSDimageres     *res_a,
                                         const gint32           image_id,
                                         PSDimage              *img_a,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1058     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_1060     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 static gint     load_resource_2000     (const PSDimageres     *res_a,
                                         const gint32           image_id,
-                                        FILE                  *f);
+                                        FILE                  *f,
+                                        GError               **error);
 
 /* Public Functions */
 gint
-get_image_resource_header (PSDimageres *res_a,
-                           FILE        *f)
+get_image_resource_header (PSDimageres  *res_a,
+                           FILE         *f,
+                           GError      **error)
 {
-  gint32               read_len,
-                       write_len;
-  gchar                *name;
+  gint32        read_len;
+  gint32        write_len;
+  gchar        *name;
 
   if (fread (&res_a->type, 4, 1, f) < 1
       || fread (&res_a->id, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block header"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   res_a->id = GUINT16_FROM_BE (res_a->id);
-  name = fread_pascal_string (&read_len, &write_len, 2, f);
+  name = fread_pascal_string (&read_len, &write_len, 2, f, error);
+  if (*error)
+    return -1;
   if (name != NULL)
     g_strlcpy (res_a->name, name, write_len + 1);
   else
-    res_a->name[0] = 0;
+    res_a->name[0] = 0x0;
   g_free (name);
   if (fread (&res_a->data_len, 4, 1, f) < 1)
     {
-      g_message (_("Error image resource block length"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   res_a->data_len = GUINT32_FROM_BE (res_a->data_len);
   res_a->data_start = ftell (f);
 
   IFDBG(2) g_debug ("Type: %.4s, id: %d, start: %d, len: %d",
-                        res_a->type, res_a->id, res_a->data_start, res_a->data_len);
+                    res_a->type, res_a->id, res_a->data_start, res_a->data_len);
 
   return 0;
 }
 
 gint
-load_image_resource (PSDimageres  *res_a,
-                     const gint32  image_id,
-                     PSDimage     *img_a,
-                     FILE         *f)
+load_image_resource (PSDimageres   *res_a,
+                     const gint32   image_id,
+                     PSDimage      *img_a,
+                     FILE          *f,
+                     GError       **error)
 {
   gint  pad;
 
   /* Set file position to start of image resource data block */
   if (fseek (f, res_a->data_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
    /* Process image resource blocks */
   if (memcmp (res_a->type, "8BIM", 4) != 0 &&
       memcmp (res_a->type, "MeSa", 4) !=0)
-      g_message (_("Unknown image resource type signature %.4s"), res_a->type);
-
-  switch (res_a->id)
     {
-      case PSD_PS2_IMAGE_INFO:
-      case PSD_PS2_COLOR_TAB:
-      case PSD_OBSOLETE_01:
-      case PSD_OBSOLETE_02:
-      case PSD_OBSOLETE_03:
-        /* Drop obsolete image resource blocks */
-        IFDBG(2) g_debug ("Obsolete image resource block: %d",
-                           res_a->id);
-        break;
+      IFDBG(1) g_debug ("Unknown image resource type signature %.4s",
+                        res_a->type);
+    }
+  else
+    {
+      switch (res_a->id)
+        {
+          case PSD_PS2_IMAGE_INFO:
+          case PSD_PS2_COLOR_TAB:
+          case PSD_OBSOLETE_01:
+          case PSD_OBSOLETE_02:
+          case PSD_OBSOLETE_03:
+            /* Drop obsolete image resource blocks */
+            IFDBG(2) g_debug ("Obsolete image resource block: %d",
+                               res_a->id);
+            break;
 
-      case PSD_THUMB_RES:
-      case PSD_THUMB_RES2:
-        /* Drop thumbnails from standard file load */
-        IFDBG(2) g_debug ("Thumbnail resource block: %d",
-                           res_a->id);
-        break;
+          case PSD_THUMB_RES:
+          case PSD_THUMB_RES2:
+            /* Drop thumbnails from standard file load */
+            IFDBG(2) g_debug ("Thumbnail resource block: %d",
+                               res_a->id);
+            break;
 
-      case PSD_MAC_PRINT_INFO:
-      case PSD_JPEG_QUAL:
-        /* Save photoshop resources with no meaning for GIMP
-          as image parasites */
-        load_resource_ps_only (res_a, image_id, f);
-        break;
+          case PSD_MAC_PRINT_INFO:
+          case PSD_JPEG_QUAL:
+            /* Save photoshop resources with no meaning for GIMP
+              as image parasites */
+            load_resource_ps_only (res_a, image_id, f, error);
+            break;
 
-      case PSD_RESN_INFO:
-        load_resource_1005 (res_a, image_id, f);
-        break;
+          case PSD_RESN_INFO:
+            load_resource_1005 (res_a, image_id, f, error);
+            break;
 
-      case PSD_ALPHA_NAMES:
-        load_resource_1006 (res_a, image_id, img_a, f);
-        break;
+          case PSD_ALPHA_NAMES:
+            load_resource_1006 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_DISPLAY_INFO:
-        load_resource_1007 (res_a, image_id, img_a, f);
-        break;
+          case PSD_DISPLAY_INFO:
+            load_resource_1007 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_CAPTION:
-        load_resource_1008 (res_a, image_id, f);
-        break;
+          case PSD_CAPTION:
+            load_resource_1008 (res_a, image_id, f, error);
+            break;
 
-      case PSD_QUICK_MASK:
-        load_resource_1022 (res_a, image_id, img_a, f);
-        break;
+          case PSD_QUICK_MASK:
+            load_resource_1022 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_LAYER_STATE:
-        load_resource_1024 (res_a, image_id, img_a, f);
-        break;
+          case PSD_LAYER_STATE:
+            load_resource_1024 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_IPTC_NAA_DATA:
-        load_resource_1028 (res_a, image_id, f);
-        break;
+          case PSD_IPTC_NAA_DATA:
+            load_resource_1028 (res_a, image_id, f, error);
+            break;
 
-      case PSD_GRID_GUIDE:
-        load_resource_1032 (res_a, image_id, f);
-        break;
+          case PSD_GRID_GUIDE:
+            load_resource_1032 (res_a, image_id, f, error);
+            break;
 
-      case PSD_ICC_PROFILE:
-        load_resource_1039 (res_a, image_id, f);
-        break;
+          case PSD_ICC_PROFILE:
+            load_resource_1039 (res_a, image_id, f, error);
+            break;
 
-      case PSD_ALPHA_NAMES_UNI:
-        load_resource_1045 (res_a, image_id, img_a,  f);
-        break;
+          case PSD_ALPHA_NAMES_UNI:
+            load_resource_1045 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_IDX_COL_TAB_CNT:
-        load_resource_1046 (res_a, image_id, f);
-        break;
+          case PSD_IDX_COL_TAB_CNT:
+            load_resource_1046 (res_a, image_id, f, error);
+            break;
 
-      case PSD_ALPHA_ID:
-        load_resource_1053 (res_a, image_id, img_a, f);
-        break;
+          case PSD_ALPHA_ID:
+            load_resource_1053 (res_a, image_id, img_a, f, error);
+            break;
 
-      case PSD_EXIF_DATA:
-        load_resource_1058 (res_a, image_id, f);
-        break;
+          case PSD_EXIF_DATA:
+            load_resource_1058 (res_a, image_id, f, error);
+            break;
 
-      case PSD_XMP_DATA:
-        load_resource_1060 (res_a, image_id, f);
-        break;
+          case PSD_XMP_DATA:
+            load_resource_1060 (res_a, image_id, f, error);
+            break;
 
-      default:
-        if (res_a->id >= 2000 &&
-            res_a->id <  2999)
-          load_resource_2000 (res_a, image_id, f);
-        else
-          load_resource_unknown (res_a, image_id, f);
+          default:
+            if (res_a->id >= 2000 &&
+                res_a->id <  2999)
+              load_resource_2000 (res_a, image_id, f, error);
+            else
+              load_resource_unknown (res_a, image_id, f, error);
+        }
     }
 
   /* Image blocks are null padded to even length */
@@ -346,7 +371,7 @@
   /* Set file position to end of image resource block */
   if (fseek (f, res_a->data_start + res_a->data_len + pad, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -354,9 +379,10 @@
 }
 
 gint
-load_thumbnail_resource (PSDimageres  *res_a,
-                         const gint32  image_id,
-                         FILE         *f)
+load_thumbnail_resource (PSDimageres   *res_a,
+                         const gint32   image_id,
+                         FILE          *f,
+                         GError       **error)
 {
   gint  rtn = 0;
   gint  pad;
@@ -364,7 +390,7 @@
   /* Set file position to start of image resource data block */
   if (fseek (f, res_a->data_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -373,7 +399,7 @@
      || res_a->id == PSD_THUMB_RES2)
    {
         /* Load thumbnails from standard file load */
-        load_resource_1033 (res_a, image_id, f);
+        load_resource_1033 (res_a, image_id, f, error);
         rtn = 1;
    }
 
@@ -386,7 +412,7 @@
   /* Set file position to end of image resource block */
   if (fseek (f, res_a->data_start + res_a->data_len + pad, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -396,9 +422,10 @@
 /* Private Functions */
 
 static gint
-load_resource_unknown (const PSDimageres *res_a,
-                       const gint32       image_id,
-                       FILE              *f)
+load_resource_unknown (const PSDimageres  *res_a,
+                       const gint32        image_id,
+                       FILE               *f,
+                       GError            **error)
 {
   /* Unknown image resources attached as parasites to re-save later */
   GimpParasite  *parasite;
@@ -410,7 +437,7 @@
   data = g_malloc (res_a->data_len);
   if (fread (data, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -428,9 +455,10 @@
 }
 
 static gint
-load_resource_ps_only (const PSDimageres *res_a,
-                       const gint32       image_id,
-                       FILE              *f)
+load_resource_ps_only (const PSDimageres  *res_a,
+                       const gint32        image_id,
+                       FILE               *f,
+                       GError            **error)
 {
   /* Save photoshop resources with no meaning for GIMP as image parasites
      to re-save later */
@@ -443,7 +471,7 @@
   data = g_malloc (res_a->data_len);
   if (fread (data, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -461,9 +489,10 @@
 }
 
 static gint
-load_resource_1005 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1005 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load image resolution and unit of measure */
 
@@ -481,7 +510,7 @@
       || fread (&res_info.vResUnit, 2, 1, f) < 1
       || fread (&res_info.heightUnit, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   res_info.hRes = GINT32_FROM_BE (res_info.hRes);
@@ -499,7 +528,7 @@
                       res_info.vResUnit,
                       res_info.heightUnit);
 
-  /* Resolution always record as pixels / inch in a fixed point implied
+  /* Resolution always recorded as pixels / inch in a fixed point implied
      decimal int32 with 16 bits before point and 16 after (i.e. cast as
      double and divide resolution by 2^16 */
   gimp_image_set_resolution (image_id,
@@ -524,24 +553,25 @@
 }
 
 static gint
-load_resource_1006 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1006 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load alpha channel names stored as a series of pascal strings
      unpadded between strings */
 
   gchar        *str;
-  gint32        block_rem,
-                read_len,
-                write_len;
+  gint32        block_rem;
+  gint32        read_len;
+  gint32        write_len;
 
   IFDBG(2) g_debug ("Process image resource block 1006: Alpha Channel Names");
 
   if (img_a->alpha_names)
     {
-      IFDBG(2) g_debug ("Alpha names loaded from unicode resource block");
+      IFDBG(3) g_debug ("Alpha names loaded from unicode resource block");
       return 0;
     }
 
@@ -550,12 +580,13 @@
   block_rem = res_a->data_len;
   while (block_rem > 1)
     {
-      str = fread_pascal_string (&read_len, &write_len, 1, f);
-      IFDBG(2) g_debug ("String: %s, %d, %d", str, read_len, write_len);
+      str = fread_pascal_string (&read_len, &write_len, 1, f, error);
+      if (*error)
+        return -1;
+      IFDBG(3) g_debug ("String: %s, %d, %d", str, read_len, write_len);
       if (write_len >= 0)
         {
-          g_ptr_array_add (img_a->alpha_names, (gpointer) g_strdup (str));
-          g_free (str);
+          g_ptr_array_add (img_a->alpha_names, (gpointer) str);
         }
       block_rem -= read_len;
     }
@@ -564,10 +595,11 @@
 }
 
 static gint
-load_resource_1007 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1007 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load alpha channel display info */
 
@@ -594,7 +626,7 @@
           || fread (&dsp_info.kind, 1, 1, f) < 1
           || fread (&dsp_info.padding, 1, 1, f) < 1)
         {
-          g_message (_("Error reading image resource block %d"), res_a->id);
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       dsp_info.colorSpace = GINT16_FROM_BE (dsp_info.colorSpace);
@@ -642,9 +674,14 @@
           case PSD_CS_DIC:
           case PSD_CS_ANPA:
           default:
-            IFDBG(2) g_debug ("Color space %d not supported by GIMP", dsp_info.colorSpace);
+            if (CONVERSION_WARNINGS)
+              g_message ("Unsupported color space: %d",
+                         dsp_info.colorSpace);
             gimp_rgb_set (&gimp_rgb, 1.0, 0.0, 0.0);
         }
+
+      gimp_rgb_set_alpha (&gimp_rgb, 1.0);
+
       IFDBG(2) g_debug ("PS cSpace: %d, col: %d %d %d %d, opacity: %d, kind: %d",
              dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta,
              ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity,
@@ -666,20 +703,23 @@
 }
 
 static gint
-load_resource_1008 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1008 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load image caption */
   GimpParasite  *parasite;
   gchar         *caption;
-  gint32         read_len,
-                 write_len;
+  gint32         read_len;
+  gint32         write_len;
 
   IFDBG(2) g_debug ("Process image resource block: 1008: Caption");
-  caption = fread_pascal_string (&read_len, &write_len, 1, f);
+  caption = fread_pascal_string (&read_len, &write_len, 1, f, error);
+  if (*error)
+    return -1;
 
-  IFDBG(2) g_debug ("Caption: %s", caption);
+  IFDBG(3) g_debug ("Caption: %s", caption);
   parasite = gimp_parasite_new (GIMP_PARASITE_COMMENT, GIMP_PARASITE_PERSISTENT,
                                 write_len, caption);
   gimp_image_parasite_attach (image_id, parasite);
@@ -690,10 +730,11 @@
 }
 
 static gint
-load_resource_1022 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1022 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load quick mask info */
   gboolean              quick_mask_empty;       /* Quick mask initially empty */
@@ -703,7 +744,7 @@
   if (fread (&img_a->quick_mask_id, 2, 1, f) < 1
       || fread (&quick_mask_empty, 1, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   img_a->quick_mask_id = GUINT16_FROM_BE (img_a->quick_mask_id);
@@ -716,17 +757,18 @@
 }
 
 static gint
-load_resource_1024 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1024 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load image layer state - current active layer counting from bottom up */
   IFDBG(2) g_debug ("Process image resource block: 1024: Layer State");
 
   if (fread (&img_a->layer_state, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   img_a->layer_state = GUINT16_FROM_BE (img_a->layer_state);
@@ -735,9 +777,10 @@
 }
 
 static gint
-load_resource_1028 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1028 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load IPTC data block */
 
@@ -757,7 +800,7 @@
   res_data = g_malloc (res_a->data_len);
   if (fread (res_data, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -787,7 +830,7 @@
   IFDBG (2) g_debug ("Processing IPTC data as psd parasite");
   name = g_strdup_printf ("psd-image-resource-%.4s-%.4x",
                            res_a->type, res_a->id);
-  IFDBG(2) g_debug ("Parasite name: %s", name);
+  IFDBG(3) g_debug ("Parasite name: %s", name);
 
   parasite = gimp_parasite_new (name, 0, res_a->data_len, res_data);
   gimp_image_parasite_attach (image_id, parasite);
@@ -801,9 +844,10 @@
 }
 
 static gint
-load_resource_1032 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1032 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load grid and guides */
 
@@ -820,7 +864,7 @@
       || fread (&hdr.fGridCycleH, 4, 1, f) < 1
       || fread (&hdr.fGuideCount, 4, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   hdr.fVersion = GUINT32_FROM_BE (hdr.fVersion);
@@ -828,7 +872,7 @@
   hdr.fGridCycleH = GUINT32_FROM_BE (hdr.fGridCycleH);
   hdr.fGuideCount = GUINT32_FROM_BE (hdr.fGuideCount);
 
-  IFDBG(2) g_debug ("Grids & Guides: %d, %d, %d, %d",
+  IFDBG(3) g_debug ("Grids & Guides: %d, %d, %d, %d",
                      hdr.fVersion,
                      hdr.fGridCycleV,
                      hdr.fGridCycleH,
@@ -839,13 +883,13 @@
       if (fread (&guide.fLocation, 4, 1, f) < 1
           || fread (&guide.fDirection, 1, 1, f) < 1)
         {
-          g_message (_("Error reading image resource block %d"), res_a->id);
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       guide.fLocation = GUINT32_FROM_BE (guide.fLocation);
       guide.fLocation /= 32;
 
-      IFDBG(2) g_debug ("Guide: %d px, %d",
+      IFDBG(3) g_debug ("Guide: %d px, %d",
                          guide.fLocation,
                          guide.fDirection);
 
@@ -859,9 +903,10 @@
 }
 
 static gint
-load_resource_1033 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1033 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load thumbnail image */
 
@@ -872,9 +917,9 @@
   GimpDrawable         *drawable;
   GimpPixelRgn          pixel_rgn;
   gint32                layer_id;
-  guchar               *buf,
-                       *rgb_buf,
-                      **rowbuf;
+  guchar               *buf;
+  guchar               *rgb_buf;
+  guchar              **rowbuf;
   gint                  i;
 
   IFDBG(2) g_debug ("Process image resource block %d: Thumbnail Image", res_a->id);
@@ -889,7 +934,7 @@
       || fread (&thumb_info.bitspixel, 2, 1, f) < 1
       || fread (&thumb_info.planes, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   thumb_info.format = GINT32_FROM_BE (thumb_info.format);
@@ -910,7 +955,7 @@
 
   if (thumb_info.format != 1)
     {
-      g_message (_("Unknown thumbnail format %d"), thumb_info.format);
+      IFDBG(1) g_debug ("Unknown thumbnail format %d", thumb_info.format);
       return -1;
     }
 
@@ -1008,9 +1053,10 @@
 }
 
 static gint
-load_resource_1039 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1039 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load ICC profile */
   GimpParasite  *parasite;
@@ -1021,7 +1067,7 @@
   icc_profile = g_malloc (res_a->data_len);
   if (fread (icc_profile, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -1036,24 +1082,31 @@
 }
 
 static gint
-load_resource_1045 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1045 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load alpha channel names stored as a series of unicode strings
      in a GPtrArray */
 
   gchar        *str;
-  gint32        block_rem,
-                read_len,
-                write_len;
+  gint32        block_rem;
+  gint32        read_len;
+  gint32        write_len;
 
   IFDBG(2) g_debug ("Process image resource block 1045: Unicode Alpha Channel Names");
 
   if (img_a->alpha_names)
     {
-      IFDBG(2) g_debug ("Deleting localised alpha channel names");
+      gint      i;
+      IFDBG(3) g_debug ("Deleting localised alpha channel names");
+      for (i = 0; i < img_a->alpha_names->len; ++i)
+        {
+          str = g_ptr_array_index (img_a->alpha_names, i);
+          g_free (str);
+        }
       g_ptr_array_free (img_a->alpha_names, TRUE);
     }
 
@@ -1062,12 +1115,14 @@
   block_rem = res_a->data_len;
   while (block_rem > 1)
     {
-      str = fread_unicode_string (&read_len, &write_len, 1, f);
-      IFDBG(2) g_debug ("String: %s, %d, %d", str, read_len, write_len);
+      str = fread_unicode_string (&read_len, &write_len, 1, f, error);
+      if (*error)
+        return -1;
+
+      IFDBG(3) g_debug ("String: %s, %d, %d", str, read_len, write_len);
       if (write_len >= 0)
         {
-          g_ptr_array_add (img_a->alpha_names, (gpointer) g_strdup (str));
-          g_free (str);
+          g_ptr_array_add (img_a->alpha_names, (gpointer) str);
         }
       block_rem -= read_len;
     }
@@ -1076,9 +1131,10 @@
 }
 
 static gint
-load_resource_1046 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1046 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load indexed color table count */
   guchar       *cmap;
@@ -1089,12 +1145,12 @@
 
   if (fread (&index_count, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   index_count = GINT16_FROM_BE (index_count);
 
-  IFDBG(2) g_debug ("Indexed color table count: %d", index_count);
+  IFDBG(3) g_debug ("Indexed color table count: %d", index_count);
   /* FIXME - check that we have indexed image */
   if (index_count && index_count < 256)
     {
@@ -1107,14 +1163,15 @@
 }
 
 static gint
-load_resource_1053 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    PSDimage          *img_a,
-                    FILE              *f)
+load_resource_1053 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    PSDimage           *img_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load image alpha channel ids (tattoos) */
-  gint16        tot_rec,
-                cidx;
+  gint16        tot_rec;
+  gint16        cidx;
 
   IFDBG(2) g_debug ("Process image resource block: 1053: Channel ID");
 
@@ -1128,7 +1185,7 @@
     {
       if (fread (&img_a->alpha_id[cidx], 4, 1, f) < 1)
         {
-          g_message (_("Error reading image resource block %d"), res_a->id);
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       img_a->alpha_id[cidx] = GUINT32_FROM_BE (img_a->alpha_id[cidx]);
@@ -1140,20 +1197,22 @@
 }
 
 static gint
-load_resource_1058 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1058 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load EXIF data block */
 
 #ifdef HAVE_EXIF
   ExifData     *exif_data;
   ExifEntry    *exif_entry;
-  guchar       *exif_buf,
-               *tmp_data;
+  guchar       *exif_buf;
+  guchar       *tmp_data;
   guint         exif_buf_len;
-  gint16        jpeg_len,
-                jpeg_fill = 0;
+  gint16        jpeg_len;
+  gint16        jpeg_fill = 0;
+  GimpParam    *return_vals;
   gint          nreturn_vals;
 #else
   gchar        *name;
@@ -1167,7 +1226,7 @@
   res_data = g_malloc (res_a->data_len);
   if (fread (res_data, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -1198,19 +1257,20 @@
   if ((exif_entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                             EXIF_TAG_XML_PACKET)))
     {
-      IFDBG(2) g_debug ("Processing Exif XMP data block");
+      IFDBG(3) g_debug ("Processing Exif XMP data block");
       /*Create NULL terminated EXIF data block */
       tmp_data = g_malloc (exif_entry->size + 1);
       memcpy (tmp_data, exif_entry->data, exif_entry->size);
       tmp_data[exif_entry->size] = 0;
       /* Merge with existing XMP data block */
-      gimp_run_procedure (DECODE_XMP_PROC,
-                          &nreturn_vals,
-                          GIMP_PDB_IMAGE,  image_id,
-                          GIMP_PDB_STRING, tmp_data,
-                          GIMP_PDB_END);
+      return_vals = gimp_run_procedure (DECODE_XMP_PROC,
+                                        &nreturn_vals,
+                                        GIMP_PDB_IMAGE,  image_id,
+                                        GIMP_PDB_STRING, tmp_data,
+                                        GIMP_PDB_END);
       g_free (tmp_data);
-      IFDBG(2) g_debug ("Deleting XMP block from Exif data");
+      gimp_destroy_params (return_vals, nreturn_vals);
+      IFDBG(3) g_debug ("Deleting XMP block from Exif data");
       /* Delete XMP data from Exif block */
       exif_content_remove_entry (exif_data->ifd[EXIF_IFD_0],
                                  exif_entry);
@@ -1220,7 +1280,7 @@
   if ((exif_entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                             EXIF_TAG_IMAGE_RESOURCES)))
     {
-      IFDBG(2) g_debug ("Deleting PS Image Resource block from Exif data");
+      IFDBG(3) g_debug ("Deleting PS Image Resource block from Exif data");
       /* Delete PS Image Resource data from Exif block */
       exif_content_remove_entry (exif_data->ifd[EXIF_IFD_0],
                                  exif_entry);
@@ -1247,7 +1307,7 @@
   IFDBG (2) g_debug ("Processing exif data as psd parasite");
   name = g_strdup_printf ("psd-image-resource-%.4s-%.4x",
                            res_a->type, res_a->id);
-  IFDBG(2) g_debug ("Parasite name: %s", name);
+  IFDBG(3) g_debug ("Parasite name: %s", name);
 
   parasite = gimp_parasite_new (name, 0, res_a->data_len, res_data);
   gimp_image_parasite_attach (image_id, parasite);
@@ -1261,11 +1321,13 @@
 }
 
 static gint
-load_resource_1060 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_1060 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load XMP Metadata block */
+  GimpParam    *return_vals;
   gint          nreturn_vals;
   gchar        *res_data;
 
@@ -1274,42 +1336,42 @@
   res_data = g_malloc (res_a->data_len + 1);
   if (fread (res_data, res_a->data_len, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   /* Null terminate metadata block for decode procedure */
   res_data[res_a->data_len] = 0;
 
-  gimp_run_procedure (DECODE_XMP_PROC,
-                      &nreturn_vals,
-                      GIMP_PDB_IMAGE,  image_id,
-                      GIMP_PDB_STRING, res_data,
-                      GIMP_PDB_END);
-
+  return_vals = gimp_run_procedure (DECODE_XMP_PROC,
+                                    &nreturn_vals,
+                                    GIMP_PDB_IMAGE,  image_id,
+                                    GIMP_PDB_STRING, res_data,
+                                    GIMP_PDB_END);
   g_free (res_data);
+  gimp_destroy_params (return_vals, nreturn_vals);
   return 0;
 }
 
 static gint
-load_resource_2000 (const PSDimageres *res_a,
-                    const gint32       image_id,
-                    FILE              *f)
+load_resource_2000 (const PSDimageres  *res_a,
+                    const gint32        image_id,
+                    FILE               *f,
+                    GError            **error)
 {
-  gchar        *name;
   gdouble      *controlpoints;
-  gint32        x[3],
-                y[3],
-                vector_id = -1;
-  gint16        type,
-                init_fill,
-                num_rec,
-                path_rec,
-                cntr;
-  gint          image_width,
-                image_height,
-                i;
-  gboolean      closed,
-                fill;
+  gint32        x[3];
+  gint32        y[3];
+  gint32        vector_id = -1;
+  gint16        type;
+  gint16        init_fill;
+  gint16        num_rec;
+  gint16        path_rec;
+  gint16        cntr;
+  gint          image_width;
+  gint          image_height;
+  gint          i;
+  gboolean      closed;
+  gboolean      fill;
 
   /* Load path data from image resources 2000-2998 */
 
@@ -1320,13 +1382,13 @@
 
   if (fread (&type, 2, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block %d"), res_a->id);
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   type = GINT16_FROM_BE (type);
   if (type != PSD_PATH_FILL_RULE)
     {
-      g_message (_("Unexpected path record type: %d"), type);
+      IFDBG(1) g_debug ("Unexpected path record type: %d", type);
       return -1;
     }
   else
@@ -1334,7 +1396,7 @@
 
   if (fseek (f, 24, SEEK_CUR) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -1346,27 +1408,25 @@
   image_height = gimp_image_height (image_id);
 
   /* Create path */
-  name = gimp_any_to_utf8 (res_a->name, -1, _("Invalid UTF-8 string in PSD file"));
-  vector_id = gimp_vectors_new (image_id, name);
-  g_free (name);
+  vector_id = gimp_vectors_new (image_id, res_a->name);
   gimp_image_add_vectors (image_id, vector_id, -1);
 
   while (path_rec > 0)
     {
       if (fread (&type, 2, 1, f) < 1)
         {
-          g_message (_("Error reading image resource block %d"), res_a->id);
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       type = GINT16_FROM_BE (type);
-      IFDBG(2) g_debug ("Path record type %d", type);
+      IFDBG(3) g_debug ("Path record type %d", type);
 
       if (type == PSD_PATH_FILL_RULE)
         {
           fill = FALSE;
           if (fseek (f, 24, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
         }
@@ -1375,7 +1435,7 @@
         {
           if (fread (&init_fill, 2, 1, f) < 1)
             {
-              g_message (_("Error reading image resource block %d"), res_a->id);
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
           if (init_fill != 0)
@@ -1383,7 +1443,7 @@
 
           if (fseek (f, 22, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
         }
@@ -1393,16 +1453,16 @@
         {
           if (fread (&num_rec, 2, 1, f) < 1)
             {
-              g_message (_("Error reading image resource block %d"), res_a->id);
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
           num_rec = GINT16_FROM_BE (num_rec);
           if (num_rec > path_rec)
             {
-              g_message (_("Too many path point records"));
+              psd_set_error (feof (f), errno, error);
               return - 1;
             }
-          IFDBG(2) g_debug ("Num path records %d", num_rec);
+          IFDBG(3) g_debug ("Num path records %d", num_rec);
 
           if (type == PSD_PATH_CL_LEN)
             closed = TRUE;
@@ -1412,7 +1472,7 @@
           controlpoints = g_malloc (sizeof (gdouble) * num_rec * 6);
           if (fseek (f, 22, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
 
@@ -1420,12 +1480,11 @@
             {
               if (fread (&type, 2, 1, f) < 1)
                 {
-                  g_message (_("Error reading image resource block %d"),
-                             res_a->id);
+                  psd_set_error (feof (f), errno, error);
                   return -1;
                 }
               type = GINT16_FROM_BE (type);
-              IFDBG(2) g_debug ("Path record type %d", type);
+              IFDBG(3) g_debug ("Path record type %d", type);
 
               if (type == PSD_PATH_CL_LNK
                   || type == PSD_PATH_CL_UNLNK
@@ -1439,8 +1498,7 @@
                     || fread (&y[2], 4, 1, f) < 1
                     || fread (&x[2], 4, 1, f) < 1)
                     {
-                      g_message (_("Error reading image resource block %d"),
-                                 res_a->id);
+                      psd_set_error (feof (f), errno, error);
                       return -1;
                     }
                   for (i = 0; i < 3; ++i)
@@ -1452,15 +1510,15 @@
                       controlpoints[cntr] = y[i] / 16777216.0 * image_height;
                       cntr++;
                     }
-                  IFDBG(2) g_debug ("Path points (%d,%d), (%d,%d), (%d,%d)",
+                  IFDBG(3) g_debug ("Path points (%d,%d), (%d,%d), (%d,%d)",
                                     x[0], y[0], x[1], y[1], x[2], y[2]);
                 }
               else
                 {
-                  g_message (_("Unexpected path type record %d"), type);
+                  IFDBG(1) g_debug ("Unexpected path type record %d", type);
                   if (fseek (f, 24, SEEK_CUR) < 0)
                     {
-                      g_message (_("Error setting file position"));
+                      psd_set_error (feof (f), errno, error);
                       return -1;
                     }
                 }
@@ -1478,7 +1536,7 @@
         {
           if (fseek (f, 24, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
         }
Index: psd-image-res-load.h
===================================================================
--- psd-image-res-load.h	(revision 24558)
+++ psd-image-res-load.h	(working copy)
@@ -24,16 +24,18 @@
 
 
 gint  get_image_resource_header (PSDimageres  *res_a,
-                                 FILE         *f);
+                                 FILE         *f,
+                                 GError      **error);
 
-gint  load_image_resource       (PSDimageres  *res_a,
-                                 const gint32  image_id,
-                                 PSDimage     *img_a,
-                                 FILE         *f);
+gint  load_image_resource       (PSDimageres   *res_a,
+                                 const gint32   image_id,
+                                 PSDimage      *img_a,
+                                 FILE          *f,
+                                 GError       **error);
 
-gint  load_thumbnail_resource   (PSDimageres  *res_a,
-                                 const gint32  image_id,
-                                 FILE         *f);
+gint  load_thumbnail_resource   (PSDimageres   *res_a,
+                                 const gint32   image_id,
+                                 FILE          *f,
+                                 GError       **error);
 
-
 #endif /* __PSD_IMAGE_RES_LOAD_H__ */
Index: psd-layer-res-load.c
===================================================================
--- psd-layer-res-load.c	(revision 24558)
+++ psd-layer-res-load.c	(working copy)
@@ -92,6 +92,7 @@
 #include "config.h"
 
 #include <string.h>
+#include <errno.h>
 
 #include <glib/gstdio.h>
 #include <libgimp/gimp.h>
@@ -102,51 +103,59 @@
 
 #include "libgimp/stdplugins-intl.h"
 
-
 /*  Local function prototypes  */
 static gint     load_resource_unknown (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_ladj    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_lfil    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_lfx     (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_ltyp    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_luni    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_lyid    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 static gint     load_resource_lsct    (const PSDlayerres     *res_a,
                                        PSDlayer              *lyr_a,
-                                       FILE                  *f);
+                                       FILE                  *f,
+                                       GError               **error);
 
 
 /* Public Functions */
 gint
-get_layer_resource_header (PSDlayerres *res_a,
-                           FILE        *f)
+get_layer_resource_header (PSDlayerres  *res_a,
+                           FILE         *f,
+                           GError      **error)
 {
   if (fread (res_a->sig, 4, 1, f) < 1
       || fread (res_a->key, 4, 1, f) < 1
       || fread (&res_a->data_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading layer resource block header"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   res_a->data_len = GUINT32_FROM_BE (res_a->data_len);
@@ -159,65 +168,70 @@
 }
 
 gint
-load_layer_resource (PSDlayerres *res_a,
-                     PSDlayer    *lyr_a,
-                     FILE        *f)
+load_layer_resource (PSDlayerres  *res_a,
+                     PSDlayer     *lyr_a,
+                     FILE         *f,
+                     GError      **error)
 {
   gint  pad;
 
   /* Set file position to start of layer resource data block */
   if (fseek (f, res_a->data_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
    /* Process layer resource blocks */
   if (memcmp (res_a->sig, "8BIM", 4) != 0)
-      g_message (_("Unknown layer resource signature %.4s"), res_a->sig);
+    {
+      IFDBG(1) g_debug ("Unknown layer resource signature %.4s", res_a->sig);
+    }
+  else
+    {
+      if (memcmp (res_a->key, PSD_LADJ_LEVEL, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_CURVE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_BRIGHTNESS, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_BALANCE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_BLACK_WHITE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_HUE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_HUE2, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_SELECTIVE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_MIXER, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_GRAD_MAP, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_PHOTO_FILT, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_EXPOSURE, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_THRESHOLD, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_INVERT, 4) == 0
+          || memcmp (res_a->key, PSD_LADJ_POSTERIZE, 4) == 0)
+            load_resource_ladj (res_a, lyr_a, f, error);
 
-  if (memcmp (res_a->key, PSD_LADJ_LEVEL, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_CURVE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_BRIGHTNESS, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_BALANCE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_BLACK_WHITE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_HUE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_HUE2, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_SELECTIVE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_MIXER, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_GRAD_MAP, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_PHOTO_FILT, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_EXPOSURE, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_THRESHOLD, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_INVERT, 4) == 0
-      || memcmp (res_a->key, PSD_LADJ_POSTERIZE, 4) == 0)
-        load_resource_ladj (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LFIL_SOLID, 4) == 0
+          || memcmp (res_a->key, PSD_LFIL_PATTERN, 4) == 0
+          || memcmp (res_a->key, PSD_LFIL_GRADIENT, 4) == 0)
+            load_resource_lfil (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LFIL_SOLID, 4) == 0
-      || memcmp (res_a->key, PSD_LFIL_PATTERN, 4) == 0
-      || memcmp (res_a->key, PSD_LFIL_GRADIENT, 4) == 0)
-        load_resource_lfil (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LFX_FX, 4) == 0
+          || memcmp (res_a->key, PSD_LFX_FX2, 4) == 0)
+            load_resource_lfx (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LFX_FX, 4) == 0
-      || memcmp (res_a->key, PSD_LFX_FX2, 4) == 0)
-        load_resource_lfx (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LTYP_TYPE, 4) == 0
+          || memcmp (res_a->key, PSD_LTYP_TYPE2, 4) == 0)
+            load_resource_ltyp (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LTYP_TYPE, 4) == 0
-      || memcmp (res_a->key, PSD_LTYP_TYPE2, 4) == 0)
-        load_resource_ltyp (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LPRP_UNICODE, 4) == 0)
+            load_resource_luni (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LPRP_UNICODE, 4) == 0)
-        load_resource_luni (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LPRP_ID, 4) == 0)
+            load_resource_lyid (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LPRP_ID, 4) == 0)
-        load_resource_lyid (res_a, lyr_a, f);
+      else if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0)
+            load_resource_lsct (res_a, lyr_a, f, error);
 
-  else if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0)
-        load_resource_lsct (res_a, lyr_a, f);
+      else
+        load_resource_unknown (res_a, lyr_a, f, error);
+    }
 
-  else
-    load_resource_unknown (res_a, lyr_a, f);
-
   /* Layer blocks are null padded to even length */
   if (res_a->data_len % 2 == 0)
     pad = 0;
@@ -227,7 +241,7 @@
   /* Set file position to end of layer resource block */
   if (fseek (f, res_a->data_start + res_a->data_len + pad, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -237,9 +251,10 @@
 /* Private Functions */
 
 static gint
-load_resource_unknown (const PSDlayerres *res_a,
-                       PSDlayer          *lyr_a,
-                       FILE              *f)
+load_resource_unknown (const PSDlayerres  *res_a,
+                       PSDlayer           *lyr_a,
+                       FILE               *f,
+                       GError            **error)
 {
   IFDBG(2) g_debug ("Process unknown layer resource block: %.4s", res_a->key);
 
@@ -247,9 +262,10 @@
 }
 
 static gint
-load_resource_ladj (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_ladj (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load adjustment layer */
   static gboolean   msg_flag = FALSE;
@@ -258,10 +274,10 @@
   lyr_a->drop = TRUE;
   if (! msg_flag && CONVERSION_WARNINGS)
     {
-      g_message (_("Warning:\n"
-                   "The image file contains adjustment layers. "
-                   "These are not supported by the GIMP and will "
-                   "be dropped."));
+      g_message ("Warning:\n"
+                 "The image file contains adjustment layers. "
+                 "These are not supported by the GIMP and will "
+                 "be dropped.");
       msg_flag = TRUE;
     }
 
@@ -269,9 +285,10 @@
 }
 
 static gint
-load_resource_lfil (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_lfil (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load fill layer */
   static gboolean   msg_flag = FALSE;
@@ -279,10 +296,10 @@
   IFDBG(2) g_debug ("Process layer resource block %.4s: Fill layer", res_a->key);
   if (! msg_flag && CONVERSION_WARNINGS)
     {
-      g_message (_("Warning:\n"
-                   "The image file contains fill layers. "
-                   "These are not supported by the GIMP and will "
-                   "be rasterized."));
+      g_message ("Warning:\n"
+                 "The image file contains fill layers. "
+                 "These are not supported by the GIMP and will "
+                 "be rasterized.");
       msg_flag = TRUE;
     }
 
@@ -290,9 +307,10 @@
 }
 
 static gint
-load_resource_lfx (const PSDlayerres *res_a,
-                   PSDlayer          *lyr_a,
-                   FILE              *f)
+load_resource_lfx (const PSDlayerres  *res_a,
+                   PSDlayer           *lyr_a,
+                   FILE               *f,
+                   GError            **error)
 {
   /* Load layer effects */
   static gboolean   msg_flag = FALSE;
@@ -300,10 +318,10 @@
   IFDBG(2) g_debug ("Process layer resource block %.4s: Layer effects", res_a->key);
   if (! msg_flag && CONVERSION_WARNINGS)
     {
-      g_message (_("Warning:\n"
-                   "The image file contains layer effects. "
-                   "These are not supported by the GIMP and will "
-                   "be dropped."));
+      g_message ("Warning:\n"
+                 "The image file contains layer effects. "
+                 "These are not supported by the GIMP and will "
+                 "be dropped.");
       msg_flag = TRUE;
     }
 
@@ -311,36 +329,37 @@
 }
 
 static gint
-load_resource_ltyp (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_ltyp (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load type tool layer */
-  gint16            version,
-                    text_desc_vers;
+  gint16            version;
+  gint16            text_desc_vers;
   gint32            desc_version;
-  guint64           t_xx,
-                    t_xy,
-                    t_yx,
-                    t_yy,
-                    t_tx,
-                    t_ty;
-  gdouble           transform_xx,
-                    transform_xy,
-                    transform_yx,
-                    transform_yy,
-                    transform_tx,
-                    transform_ty;
+  guint64           t_xx;
+  guint64           t_xy;
+  guint64           t_yx;
+  guint64           t_yy;
+  guint64           t_tx;
+  guint64           t_ty;
+  gdouble           transform_xx;
+  gdouble           transform_xy;
+  gdouble           transform_yx;
+  gdouble           transform_yy;
+  gdouble           transform_tx;
+  gdouble           transform_ty;
 
   static gboolean   msg_flag = FALSE;
 
   IFDBG(2) g_debug ("Process layer resource block %.4s: Type tool layer", res_a->key);
   if (! msg_flag && CONVERSION_WARNINGS)
     {
-      g_message (_("Warning:\n"
-                   "The image file contains type tool layers. "
-                   "These are not supported by the GIMP and will "
-                   "be dropped."));
+      g_message ("Warning:\n"
+                 "The image file contains type tool layers. "
+                 "These are not supported by the GIMP and will "
+                 "be dropped.");
       msg_flag = TRUE;
     }
 
@@ -357,7 +376,7 @@
           || fread (&text_desc_vers, 2, 1, f) < 1
           || fread (&desc_version, 4, 1, f) < 1)
         {
-          g_message (_("Error reading text descriptor info"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
 
@@ -395,47 +414,52 @@
 }
 
 static gint
-load_resource_luni (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_luni (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load layer name in unicode (length padded to multiple of 4 bytes) */
-  gint32                read_len,
-                        write_len;
+  gint32        read_len;
+  gint32        write_len;
 
   IFDBG(2) g_debug ("Process layer resource block luni: Unicode Name");
   if (lyr_a->name)
     g_free (lyr_a->name);
 
-  lyr_a->name = fread_unicode_string (&read_len, &write_len, 4, f);
-  IFDBG(2) g_debug ("Unicode name: %s", lyr_a->name);
+  lyr_a->name = fread_unicode_string (&read_len, &write_len, 4, f, error);
+  if (*error)
+    return -1;
+  IFDBG(3) g_debug ("Unicode name: %s", lyr_a->name);
 
   return 0;
 }
 
 static gint
-load_resource_lyid (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_lyid (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load layer id (tattoo) */
 
   IFDBG(2) g_debug ("Process layer resource block lyid: Layer ID");
   if (fread (&lyr_a->id, 4, 1, f) < 1)
     {
-      g_message (_("Error reading layer ID"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   lyr_a->id = GUINT32_FROM_BE (lyr_a->id);
-  IFDBG(2) g_debug ("Layer id: %i", lyr_a->id);
+  IFDBG(3) g_debug ("Layer id: %i", lyr_a->id);
 
   return 0;
 }
 
 static gint
-load_resource_lsct (const PSDlayerres *res_a,
-                    PSDlayer          *lyr_a,
-                    FILE              *f)
+load_resource_lsct (const PSDlayerres  *res_a,
+                    PSDlayer           *lyr_a,
+                    FILE               *f,
+                    GError            **error)
 {
   /* Load adjustment layer */
   static gboolean   msg_flag = FALSE;
@@ -444,11 +468,11 @@
   IFDBG(2) g_debug ("Process layer resource block %.4s: Section divider", res_a->key);
   if (fread (&type, 4, 1, f) < 1)
     {
-      g_message (_("Error reading Section divider record"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   type = GUINT32_FROM_BE (type);
-  IFDBG(2) g_debug ("Section divider type: %i", type);
+  IFDBG(3) g_debug ("Section divider type: %i", type);
 
   if (type == 1 ||      /* Layer group start - open folder */
       type == 2)        /* Layer group start - closed folder */
@@ -456,10 +480,10 @@
       lyr_a->drop = TRUE;
       if (! msg_flag && CONVERSION_WARNINGS)
         {
-          g_message (_("Warning:\n"
-                       "The image file contains layer groups. "
-                       "These are not supported by the GIMP and will "
-                       "be dropped."));
+          g_message ("Warning:\n"
+                     "The image file contains layer groups. "
+                     "These are not supported by the GIMP and will "
+                     "be dropped.");
           msg_flag = TRUE;
         }
     }
Index: psd-layer-res-load.h
===================================================================
--- psd-layer-res-load.h	(revision 24558)
+++ psd-layer-res-load.h	(working copy)
@@ -23,12 +23,14 @@
 #define __PSD_LAYER_RES_LOAD_H__
 
 
-gint  get_layer_resource_header (PSDlayerres *res_a,
-                                 FILE        *f);
+gint  get_layer_resource_header (PSDlayerres  *res_a,
+                                 FILE         *f,
+                                 GError      **error);
 
-gint  load_layer_resource       (PSDlayerres *res_a,
-                                 PSDlayer    *lyr_a,
-                                 FILE        *f);
+gint  load_layer_resource       (PSDlayerres  *res_a,
+                                 PSDlayer     *lyr_a,
+                                 FILE         *f,
+                                 GError      **error);
 
 
 #endif /* __PSD_LAYER_RES_LOAD_H__ */
Index: psd-load.c
===================================================================
--- psd-load.c	(revision 24558)
+++ psd-load.c	(working copy)
@@ -35,22 +35,26 @@
 
 #include "libgimp/stdplugins-intl.h"
 
-
 /*  Local function prototypes  */
 static gint             read_header_block          (PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint             read_color_mode_block      (PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint             read_image_resource_block  (PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static PSDlayer **      read_layer_block           (PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint             read_merged_image_block    (PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint32           create_gimp_image          (PSDimage     *img_a,
                                                     const gchar  *filename);
@@ -60,18 +64,23 @@
 
 static gint             add_image_resources        (const gint32  image_id,
                                                     PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint             add_layers                 (const gint32  image_id,
                                                     PSDimage     *img_a,
                                                     PSDlayer    **lyr_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 static gint             add_merged_image           (const gint32  image_id,
                                                     PSDimage     *img_a,
-                                                    FILE         *f);
+                                                    FILE         *f,
+                                                    GError      **error);
 
 /*  Local utility function prototypes  */
+static gchar          * get_psd_color_mode_name    (PSDColorMode  mode);
+
 static void             psd_to_gimp_color_map      (guchar       *map256);
 
 static GimpImageType    get_gimp_image_type        (const GimpImageBaseType image_base_type,
@@ -81,11 +90,13 @@
                                                     const guint16   bps,
                                                     const guint16   compression,
                                                     const guint16  *rle_pack_len,
-                                                    FILE           *f);
+                                                    FILE           *f,
+                                                    GError        **error);
 
 static void             convert_16_bit             (const gchar *src,
                                                     gchar       *dst,
                                                     guint32      len);
+
 static void             convert_1_bit              (const gchar *src,
                                                     gchar       *dst,
                                                     guint32      rows,
@@ -101,14 +112,13 @@
   PSDimage              img_a;
   PSDlayer            **lyr_a;
   gint32                image_id = -1;
+  GError               *error = NULL;
 
-
   /* ----- Open PSD file ----- */
   if (g_stat (filename, &st) == -1)
     return -1;
 
   IFDBG(1) g_debug ("Open file %s", gimp_filename_to_utf8 (filename));
-
   f = g_fopen (filename, "rb");
   if (f == NULL)
     {
@@ -120,121 +130,103 @@
   gimp_progress_init_printf (_("Opening '%s'"),
                              gimp_filename_to_utf8 (filename));
 
+  /* ----- Read the PSD file Header block ----- */
   IFDBG(2) g_debug ("Read header block");
-  /* ----- Read the PSD file Header block ----- */
-  if (read_header_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  if (read_header_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.1);
 
+  /* ----- Read the PSD file Colour Mode block ----- */
   IFDBG(2) g_debug ("Read colour mode block");
-  /* ----- Read the PSD file Colour Mode block ----- */
-  if (read_color_mode_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  if (read_color_mode_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.2);
 
+  /* ----- Read the PSD file Image Resource block ----- */
   IFDBG(2) g_debug ("Read image resource block");
-  /* ----- Read the PSD file Image Resource block ----- */
-  if (read_image_resource_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  if (read_image_resource_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.3);
 
+  /* ----- Read the PSD file Layer & Mask block ----- */
   IFDBG(2) g_debug ("Read layer & mask block");
-  /* ----- Read the PSD file Layer & Mask block ----- */
-  lyr_a = read_layer_block (&img_a, f);
-  if (img_a.num_layers != 0)
-    if (lyr_a == NULL)
-      {
-        fclose(f);
-        return -1;
-      }
+  lyr_a = read_layer_block (&img_a, f, &error);
+  if (img_a.num_layers != 0 && lyr_a == NULL)
+    goto load_error;
   gimp_progress_update (0.4);
 
+  /* ----- Read the PSD file Merged Image Data block ----- */
   IFDBG(2) g_debug ("Read merged image and extra alpha channel block");
-  /* ----- Read the PSD file Merged Image Data block ----- */
-  if (read_merged_image_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  if (read_merged_image_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.5);
 
+  /* ----- Create GIMP image ----- */
   IFDBG(2) g_debug ("Create GIMP image");
-  /* ----- Create GIMP image ----- */
   image_id = create_gimp_image (&img_a, filename);
-  if (image_id == -1)
-    {
-      fclose(f);
-      return -1;
-    }
+  if (image_id < 0)
+    goto load_error;
   gimp_progress_update (0.6);
 
+  /* ----- Add colour map ----- */
   IFDBG(2) g_debug ("Add color map");
-  /* ----- Add colour map ----- */
   if (add_color_map (image_id, &img_a) < 0)
-    {
-      gimp_image_delete (image_id);
-      fclose(f);
-      return -1;
-    }
+    goto load_error;
   gimp_progress_update (0.7);
 
+  /* ----- Add image resources ----- */
   IFDBG(2) g_debug ("Add image resources");
-  /* ----- Add image resources ----- */
-  if (add_image_resources (image_id, &img_a, f) < 0)
-    {
-      gimp_image_delete (image_id);
-      fclose(f);
-      return -1;
-    }
+  if (add_image_resources (image_id, &img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.8);
 
+  /* ----- Add layers -----*/
   IFDBG(2) g_debug ("Add layers");
-  /* ----- Add layers -----*/
-  if (add_layers (image_id, &img_a, lyr_a, f) < 0)
-    {
-      gimp_image_delete (image_id);
-      fclose(f);
-      return -1;
-    }
+  if (add_layers (image_id, &img_a, lyr_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.9);
 
+  /* ----- Add merged image data and extra alpha channels ----- */
   IFDBG(2) g_debug ("Add merged image data and extra alpha channels");
-  /* ----- Add merged image data and extra alpha channels ----- */
-  if (add_merged_image (image_id, &img_a, f) < 0)
-    {
-      gimp_image_delete (image_id);
-      fclose(f);
-      return -1;
-    }
+  if (add_merged_image (image_id, &img_a, f, &error) < 0)
+    goto load_error;
+  gimp_progress_update (1.0);
 
-
   IFDBG(2) g_debug ("Close file & return, image id: %d", image_id);
   IFDBG(1) g_debug ("\n----------------------------------------"
                     "----------------------------------------\n");
 
-  gimp_progress_update (1.0);
-
   gimp_image_clean_all (image_id);
   gimp_image_undo_enable (image_id);
   fclose (f);
   return image_id;
+
+  /* ----- Process load errors ----- */
+ load_error:
+  if (error)
+    {
+      g_message (_("Error loading PSD file:\n\n%s"), error->message);
+      g_error_free (error);
+    }
+
+  /* Delete partially loaded image */
+  if (image_id > 0)
+    gimp_image_delete (image_id);
+
+  /* Close file if Open */
+  if (! (f == NULL))
+    fclose (f);
+
+  return -1;
 }
 
 
 /* Local functions */
 
 static gint
-read_header_block (PSDimage *img_a,
-                   FILE     *f)
+read_header_block (PSDimage  *img_a,
+                   FILE      *f,
+                   GError   **error)
 {
   guint16  version;
   gchar    sig[4];
@@ -249,7 +241,7 @@
       || fread (&img_a->bps, 2, 1, f) < 1
       || fread (&img_a->color_mode, 2, 1, f) < 1)
     {
-      g_message (_("Error reading file header"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   version = GUINT16_FROM_BE (version);
@@ -267,46 +259,53 @@
 
   if (memcmp (sig, "8BPS", 4) != 0)
     {
-      g_message (_("Incorrect file signature"));
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Not a valid photoshop document file"));
       return -1;
     }
 
   if (version != 1)
     {
-      g_message (_("Unsupported PSD file format version %d"), version);
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Unsupported file format version: %d"), version);
       return -1;
     }
 
   if (img_a->channels > MAX_CHANNELS)
     {
-      g_message (_("Too many channels in file (%d)"), img_a->channels);
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Too many channels in file: %d"), img_a->channels);
       return -1;
     }
 
-  if (img_a->rows == 0 || img_a->columns == 0)
+    /* Photoshop CS (version 8) supports 300000 x 300000, but this
+       is currently larger than GIMP_MAX_IMAGE_SIZE */
+
+  if (img_a->rows < 1 || img_a->rows > GIMP_MAX_IMAGE_SIZE)
     {
-      g_message (_("Unsupported PSD file version (< 2.5)")); /* FIXME - image size */
-                                                             /* in resource block 1000 */
-      return -1;                                             /* don't have PS2 file spec */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Unsupported or invalid image height: %d"),
+                  img_a->rows);
+      return -1;
     }
 
-    /* Photoshop CS (version 8) supports 300000 x 300000, but this
-       is currently larger than GIMP_MAX_IMAGE_SIZE */
+  if (img_a->columns < 1 || img_a->columns > GIMP_MAX_IMAGE_SIZE)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Unsupported or invalid image width: %d"),
+                  img_a->columns);
+      return -1;
+    }
 
-    if ((img_a->rows > GIMP_MAX_IMAGE_SIZE) ||
-        (img_a->columns > GIMP_MAX_IMAGE_SIZE))
-      {
-        g_message (_("Image size too large for GIMP."));
-      }
-
   if (img_a->color_mode != PSD_BITMAP
       && img_a->color_mode != PSD_GRAYSCALE
       && img_a->color_mode != PSD_INDEXED
       && img_a->color_mode != PSD_RGB
       && img_a->color_mode != PSD_DUOTONE)
     {
-      g_message (_("PSD color mode %d is not supported"),
-                   img_a->color_mode);
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Unsupported color mode: %s"),
+                  get_psd_color_mode_name (img_a->color_mode));
       return -1;
     }
 
@@ -316,10 +315,10 @@
       case 16:
         IFDBG(3) g_debug ("16 Bit Data");
         if (CONVERSION_WARNINGS)
-          g_message (_("Warning:\n"
-                        "The image you are loading has 16 bits per channel. GIMP "
-                        "can only handle 8 bit, so it will be converted for you. "
-                        "Information will be lost because of this conversion."));
+          g_message ("Warning:\n"
+                     "The image you are loading has 16 bits per channel. GIMP "
+                     "can only handle 8 bit, so it will be converted for you. "
+                     "Information will be lost because of this conversion.");
         break;
 
       case 8:
@@ -331,7 +330,8 @@
         break;
 
       default:
-        g_message (_("Unknown bit depth: %d."), img_a->bps);
+        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                    _("Unsupported bit depth: %d"), img_a->bps);
         return -1;
         break;
     }
@@ -340,8 +340,9 @@
 }
 
 static gint
-read_color_mode_block (PSDimage *img_a,
-                       FILE     *f)
+read_color_mode_block (PSDimage  *img_a,
+                       FILE      *f,
+                       GError   **error)
 {
   static guchar cmap[] = {0, 0, 0, 255, 255, 255};
   guint32       block_len;
@@ -350,7 +351,7 @@
   img_a->color_map_len = 0;
   if (fread (&block_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading color block"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   block_len = GUINT32_FROM_BE (block_len);
@@ -362,7 +363,9 @@
       if (img_a->color_mode == PSD_INDEXED ||
           img_a->color_mode == PSD_DUOTONE )
         {
-          g_message (_("No color block for indexed or duotone image"));
+          IFDBG(1) g_debug ("No color block for indexed or duotone image");
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                      _("The file is corrupt!"));
           return -1;
         }
     }
@@ -370,7 +373,9 @@
     {
       if (block_len != 768)
         {
-          g_message (_("Invalid color block size for indexed image"));
+          IFDBG(1) g_debug ("Invalid color block size for indexed image");
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                      _("The file is corrupt!"));
           return -1;
         }
       else
@@ -379,7 +384,7 @@
           img_a->color_map = g_malloc (img_a->color_map_len);
           if (fread (img_a->color_map, block_len, 1, f) < 1)
             {
-              g_message (_("Error reading color block"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
           else
@@ -391,13 +396,13 @@
     }
   else if (img_a->color_mode == PSD_DUOTONE)
     {
-       img_a->color_map_len = block_len;
-       img_a->color_map = g_malloc (img_a->color_map_len);
-       if (fread (img_a->color_map, block_len, 1, f) < 1)
-         {
-           g_message (_("Error reading color block"));
-           return -1;
-         }
+      img_a->color_map_len = block_len;
+      img_a->color_map = g_malloc (img_a->color_map_len);
+      if (fread (img_a->color_map, block_len, 1, f) < 1)
+        {
+          psd_set_error (feof (f), errno, error);
+          return -1;
+        }
     }
 
   /* Create color map for bitmap image */
@@ -414,15 +419,16 @@
 }
 
 static gint
-read_image_resource_block (PSDimage *img_a,
-                           FILE     *f)
+read_image_resource_block (PSDimage  *img_a,
+                           FILE      *f,
+                           GError   **error)
 {
   guint32 block_len;
   guint32 block_end;
 
   if (fread (&block_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   img_a->image_res_len = GUINT32_FROM_BE (block_len);
@@ -434,7 +440,7 @@
 
   if (fseek (f, block_end, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -442,21 +448,22 @@
 }
 
 static PSDlayer **
-read_layer_block (PSDimage *img_a,
-                  FILE     *f)
+read_layer_block (PSDimage  *img_a,
+                  FILE      *f,
+                  GError   **error)
 {
   PSDlayer **lyr_a;
-  guint32    block_len,
-             block_end,
-             block_rem;
-  gint32     read_len,
-             write_len;
-  gint       lidx,                  /* Layer index */
-             cidx;                  /* Channel index */
+  guint32    block_len;
+  guint32    block_end;
+  guint32    block_rem;
+  gint32     read_len;
+  gint32     write_len;
+  gint       lidx;                  /* Layer index */
+  gint       cidx;                  /* Channel index */
 
   if (fread (&block_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading layer and mask block"));
+      psd_set_error (feof (f), errno, error);
       img_a->num_layers = -1;
       return NULL;
     }
@@ -481,7 +488,7 @@
       if (fread (&block_len, 4, 1, f) < 1
           || fread (&img_a->num_layers, 2, 1, f) < 1)
         {
-          g_message (_("Error reading number of layers"));
+          psd_set_error (feof (f), errno, error);
           img_a->num_layers = -1;
           return NULL;
         }
@@ -516,7 +523,7 @@
                   || fread (&lyr_a[lidx]->right, 4, 1, f) < 1
                   || fread (&lyr_a[lidx]->num_channels, 2, 1, f) < 1)
                 {
-                  g_message (_("Error reading layer record (i)"));
+                  psd_set_error (feof (f), errno, error);
                   return NULL;
                 }
               lyr_a[lidx]->top = GUINT32_FROM_BE (lyr_a[lidx]->top);
@@ -527,18 +534,26 @@
 
               if (lyr_a[lidx]->num_channels > MAX_CHANNELS)
                 {
-                  g_message (_("Too many channels in layer (%d)"),
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                              _("Too many channels in layer: %d"),
                               lyr_a[lidx]->num_channels);
                   return NULL;
                 }
-              if ((lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE) ||
-                  (lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE))
+              if (lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE)
                 {
-                  g_message (_("Layer size too large for GIMP."));
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                              _("Unsupported or invalid layer height: %d"),
+                              lyr_a[lidx]->bottom - lyr_a[lidx]->top);
                   return NULL;
                 }
+              if (lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE)
+                {
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                              _("Unsupported or invalid layer width: %d"),
+                              lyr_a[lidx]->right - lyr_a[lidx]->left);
+                  return NULL;
+                }
 
-              IFDBG(2) g_debug (" ");
               IFDBG(2) g_debug ("Layer %d, Coords %d %d %d %d, channels %d, ",
                                  lidx, lyr_a[lidx]->left, lyr_a[lidx]->top,
                                  lyr_a[lidx]->right, lyr_a[lidx]->bottom,
@@ -550,7 +565,7 @@
                   if (fread (&lyr_a[lidx]->chn_info[cidx].channel_id, 2, 1, f) < 1
                       || fread (&lyr_a[lidx]->chn_info[cidx].data_len, 4, 1, f) < 1)
                     {
-                      g_message (_("Error reading layer - channel record"));
+                      psd_set_error (feof (f), errno, error);
                       return NULL;
                     }
                   lyr_a[lidx]->chn_info[cidx].channel_id =
@@ -558,7 +573,7 @@
                   lyr_a[lidx]->chn_info[cidx].data_len =
                     GUINT32_FROM_BE (lyr_a[lidx]->chn_info[cidx].data_len);
                   img_a->layer_data_len += lyr_a[lidx]->chn_info[cidx].data_len;
-                  IFDBG(2) g_debug ("Channel ID %d, data len %d",
+                  IFDBG(3) g_debug ("Channel ID %d, data len %d",
                                      lyr_a[lidx]->chn_info[cidx].channel_id,
                                      lyr_a[lidx]->chn_info[cidx].data_len);
                 }
@@ -571,13 +586,15 @@
                   || fread (&lyr_a[lidx]->filler, 1, 1, f) < 1
                   || fread (&lyr_a[lidx]->extra_len, 4, 1, f) < 1)
                 {
-                  g_message (_("Error reading layer record (ii)"));
+                  psd_set_error (feof (f), errno, error);
                   return NULL;
                 }
               if (memcmp (lyr_a[lidx]->mode_key, "8BIM", 4) != 0)
                 {
-                  g_message (_("Incorrect layer mode signature %.4s"),
-                              lyr_a[lidx]->mode_key);
+                  IFDBG(1) g_debug ("Incorrect layer mode signature %.4s",
+                                    lyr_a[lidx]->mode_key);
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                              _("The file is corrupt!"));
                   return NULL;
                 }
 
@@ -606,7 +623,7 @@
               /* Layer mask data */
               if (fread (&block_len, 4, 1, f) < 1)
                 {
-                  g_message (_("Error reading layer mask data length"));
+                  psd_set_error (feof (f), errno, error);
                   return NULL;
                 }
               block_len = GUINT32_FROM_BE (block_len);
@@ -642,7 +659,7 @@
                         || fread (&lyr_a[lidx]->layer_mask.extra_def_color, 1, 1, f) < 1
                         || fread (&lyr_a[lidx]->layer_mask.extra_flags, 1, 1, f) < 1)
                       {
-                        g_message (_("Error reading layer mask record"));
+                        psd_set_error (feof (f), errno, error);
                         return NULL;
                       }
                     lyr_a[lidx]->layer_mask.top =
@@ -674,7 +691,7 @@
                         || fread (&lyr_a[lidx]->layer_mask.bottom, 4, 1, f) < 1
                         || fread (&lyr_a[lidx]->layer_mask.right, 4, 1, f) < 1)
                       {
-                        g_message (_("Error reading layer mask extra record"));
+                        psd_set_error (feof (f), errno, error);
                         return NULL;
                       }
                     lyr_a[lidx]->layer_mask_extra.top =
@@ -702,10 +719,10 @@
                     break;
 
                   default:
-                    g_message ("Unknown layer mask size ... skipping");
+                    IFDBG(1) g_debug ("Unknown layer mask record size ... skipping");
                     if (fseek (f, block_len, SEEK_CUR) < 0)
                       {
-                        g_message (_("Error setting file position"));
+                        psd_set_error (feof (f), errno, error);
                         return NULL;
                       }
                 }
@@ -717,14 +734,14 @@
                                 lyr_a[lidx]->layer_mask.bottom,
                                 lyr_a[lidx]->layer_mask.mask_flags.relative_pos);
 
-              IFDBG(2) g_debug ("Default mask color, %d, %d",
+              IFDBG(3) g_debug ("Default mask color, %d, %d",
                                 lyr_a[lidx]->layer_mask.def_color,
                                 lyr_a[lidx]->layer_mask.extra_def_color);
 
               /* Layer blending ranges */           /* FIXME  */
               if (fread (&block_len, 4, 1, f) < 1)
                 {
-                  g_message (_("Error reading layer blending ranges length"));
+                  psd_set_error (feof (f), errno, error);
                   return NULL;
                 }
               block_len = GUINT32_FROM_BE (block_len);
@@ -734,12 +751,15 @@
                 {
                   if (fseek (f, block_len, SEEK_CUR) < 0)
                     {
-                      g_message (_("Error setting file position"));
+                      psd_set_error (feof (f), errno, error);
                       return NULL;
                     }
                 }
 
-              lyr_a[lidx]->name = fread_pascal_string (&read_len, &write_len, 4, f);
+              lyr_a[lidx]->name = fread_pascal_string (&read_len, &write_len,
+                                                       4, f, error);
+              if (*error)
+                return NULL;
               block_rem -= read_len;
               IFDBG(3) g_debug ("Remaining length %d", block_rem);
 
@@ -747,17 +767,19 @@
 
               while (block_rem > 7)
                 {
-                  if (get_layer_resource_header (&res_a, f) < 0)
+                  if (get_layer_resource_header (&res_a, f, error) < 0)
                     return NULL;
                   block_rem -= 12;
 
                   if (res_a.data_len > block_rem)
                     {
-                      g_message ("Unexpected end of layer resource data");
+                      IFDBG(1) g_debug ("Unexpected end of layer resource data");
+                      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                                  _("The file is corrupt!"));
                       return NULL;
                     }
 
-                  if (load_layer_resource (&res_a, lyr_a[lidx], f) < 0)
+                  if (load_layer_resource (&res_a, lyr_a[lidx], f, error) < 0)
                     return NULL;
                   block_rem -= res_a.data_len;
                 }
@@ -765,7 +787,7 @@
                 {
                   if (fseek (f, block_rem, SEEK_CUR) < 0)
                     {
-                      g_message (_("Error setting file position"));
+                      psd_set_error (feof (f), errno, error);
                       return NULL;
                     }
                 }
@@ -774,7 +796,7 @@
           img_a->layer_data_start = ftell(f);
           if (fseek (f, img_a->layer_data_len, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return NULL;
             }
 
@@ -789,7 +811,7 @@
       /* Skip to end of block */
       if (fseek (f, block_end, SEEK_SET) < 0)
         {
-          g_message (_("Error setting file position"));
+          psd_set_error (feof (f), errno, error);
           return NULL;
         }
     }
@@ -798,11 +820,17 @@
 }
 
 static gint
-read_merged_image_block (PSDimage *img_a,
-                         FILE     *f)
+read_merged_image_block (PSDimage  *img_a,
+                         FILE      *f,
+                         GError   **error)
 {
   img_a->merged_image_start = ftell(f);
-  fseek (f, 0, SEEK_END);
+  if (fseek (f, 0, SEEK_END) < 0)
+    {
+      psd_set_error (feof (f), errno, error);
+      return -1;
+    }
+
   img_a->merged_image_len = ftell(f) - img_a->merged_image_start;
 
   IFDBG(1) g_debug ("Merged image data block: Start: %d, len: %d",
@@ -834,22 +862,19 @@
         break;
 
       default:
-        g_message (_("PSD color mode %d not supported"), img_a->color_mode);
+        /* Color mode already validated - should not be here */
+        g_warning ("Invalid color mode");
         return -1;
         break;
     }
 
   /* Create gimp image */
   IFDBG(2) g_debug ("Create image");
-  if ((image_id = gimp_image_new (img_a->columns, img_a->rows,
-                                  img_a->base_type)) == -1)
-    {
-      g_message (_("Could not create a new image"));
-      return -1;
-    }
+  image_id = gimp_image_new (img_a->columns, img_a->rows, img_a->base_type);
 
+  gimp_image_set_filename (image_id, filename);
   gimp_image_undo_disable (image_id);
-  gimp_image_set_filename (image_id, filename);
+
   return image_id;
 }
 
@@ -881,13 +906,14 @@
 static gint
 add_image_resources (const gint32  image_id,
                      PSDimage     *img_a,
-                     FILE         *f)
+                     FILE         *f,
+                     GError      **error)
 {
   PSDimageres  res_a;
 
   if (fseek (f, img_a->image_res_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -903,17 +929,17 @@
 
   while (ftell (f) < img_a->image_res_start + img_a->image_res_len)
     {
-      if (get_image_resource_header (&res_a, f) < 0)
+      if (get_image_resource_header (&res_a, f, error) < 0)
         return -1;
 
       if (res_a.data_start + res_a.data_len >
           img_a->image_res_start + img_a->image_res_len)
         {
-          g_message ("Unexpected end of image resource data");
+          IFDBG(1) g_debug ("Unexpected end of image resource data");
           return 0;
         }
 
-      if (load_image_resource (&res_a, image_id, img_a,  f) < 0)
+      if (load_image_resource (&res_a, image_id, img_a, f, error) < 0)
         return -1;
     }
 
@@ -924,36 +950,37 @@
 add_layers (const gint32  image_id,
             PSDimage     *img_a,
             PSDlayer    **lyr_a,
-            FILE         *f)
+            FILE         *f,
+            GError      **error)
 {
   PSDchannel          **lyr_chn;
   guchar               *pixels;
-  guint16               comp_mode,
-                        alpha_chn,
-                        user_mask_chn,
-                        layer_channels,
-                        channel_idx[MAX_CHANNELS],
-                       *rle_pack_len;
-  gint32                l_x,                   /* Layer x */
-                        l_y,                   /* Layer y */
-                        l_w,                   /* Layer width */
-                        l_h,                   /* Layer height */
-                        lm_x,                  /* Layer mask x */
-                        lm_y,                  /* Layer mask y */
-                        lm_w,                  /* Layer mask width */
-                        lm_h,                  /* Layer mask height */
-                        layer_size,
-                        layer_id = -1,
-                        mask_id = -1;
-  gint                  lidx,                  /* Layer index */
-                        cidx,                  /* Channel index */
-                        rowi,                  /* Row index */
-                        coli,                  /* Column index */
-                        i;
-  gboolean              alpha,
-                        user_mask,
-                        empty,
-                        empty_mask;
+  guint16               comp_mode;
+  guint16               alpha_chn;
+  guint16               user_mask_chn;
+  guint16               layer_channels;
+  guint16               channel_idx[MAX_CHANNELS];
+  guint16              *rle_pack_len;
+  gint32                l_x;                   /* Layer x */
+  gint32                l_y;                   /* Layer y */
+  gint32                l_w;                   /* Layer width */
+  gint32                l_h;                   /* Layer height */
+  gint32                lm_x;                  /* Layer mask x */
+  gint32                lm_y;                  /* Layer mask y */
+  gint32                lm_w;                  /* Layer mask width */
+  gint32                lm_h;                  /* Layer mask height */
+  gint32                layer_size;
+  gint32                layer_id = -1;
+  gint32                mask_id = -1;
+  gint                  lidx;                  /* Layer index */
+  gint                  cidx;                  /* Channel index */
+  gint                  rowi;                  /* Row index */
+  gint                  coli;                  /* Column index */
+  gint                  i;
+  gboolean              alpha;
+  gboolean              user_mask;
+  gboolean              empty;
+  gboolean              empty_mask;
   GimpDrawable         *drawable;
   GimpPixelRgn          pixel_rgn;
   GimpImageType         image_type;
@@ -971,7 +998,7 @@
   /* Layered image - Photoshop 3 style */
   if (fseek (f, img_a->layer_data_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -985,8 +1012,13 @@
 
           /* Step past layer data */
           for (cidx = 0; cidx < lyr_a[lidx]->num_channels; ++cidx)
-              fseek (f, lyr_a[lidx]->chn_info[cidx].data_len, SEEK_CUR);
-
+            {
+              if (fseek (f, lyr_a[lidx]->chn_info[cidx].data_len, SEEK_CUR) < 0)
+                {
+                  psd_set_error (feof (f), errno, error);
+                  return -1;
+                }
+            }
           g_free (lyr_a[lidx]->chn_info);
           g_free (lyr_a[lidx]->name);
         }
@@ -1007,7 +1039,7 @@
           else
               empty_mask = FALSE;
 
-          IFDBG(2) g_debug ("Empty mask %d, size %d %d", empty_mask,
+          IFDBG(3) g_debug ("Empty mask %d, size %d %d", empty_mask,
                             lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top,
                             lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left);
 
@@ -1049,36 +1081,33 @@
                                            lyr_a[lidx]->layer_mask.left);
                 }
 
-              IFDBG(2) g_debug ("Channel id %d, %dx%d",
+              IFDBG(3) g_debug ("Channel id %d, %dx%d",
                                 lyr_chn[cidx]->id,
                                 lyr_chn[cidx]->columns,
                                 lyr_chn[cidx]->rows);
 
               if (fread (&comp_mode, 2, 1, f) < 1)
                 {
-                  g_message (_("Error reading layer compression mode"));
+                  psd_set_error (feof (f), errno, error);
                   return -1;
                 }
               comp_mode = GUINT16_FROM_BE (comp_mode);
-              IFDBG(2) g_debug ("Compression mode: %d", comp_mode);
+              IFDBG(3) g_debug ("Compression mode: %d", comp_mode);
 
               if (lyr_a[lidx]->chn_info[cidx].data_len - 2 > 0)
                 {
                   switch (comp_mode)
                     {
                       case PSD_COMP_RAW:        /* Planar raw data */
-                        IFDBG(2) g_debug ("Raw data length: %d",
+                        IFDBG(3) g_debug ("Raw data length: %d",
                                           lyr_a[lidx]->chn_info[cidx].data_len - 2);
-                        if (read_channel_data (lyr_chn[cidx],
-                            img_a->bps, PSD_COMP_RAW, NULL, f) < 1)
-                          {
-                            g_message (_("Error reading raw channel"));
-                            return -1;
-                          }
+                        if (read_channel_data (lyr_chn[cidx], img_a->bps,
+                            PSD_COMP_RAW, NULL, f, error) < 1)
+                          return -1;
                         break;
 
                       case PSD_COMP_RLE:        /* Packbits */
-                        IFDBG(2) g_debug ("RLE channel length %d, RLE length data: %d, "
+                        IFDBG(3) g_debug ("RLE channel length %d, RLE length data: %d, "
                                           "RLE data block: %d",
                                           lyr_a[lidx]->chn_info[cidx].data_len - 2,
                                           lyr_chn[cidx]->rows * 2,
@@ -1089,28 +1118,24 @@
                           {
                             if (fread (&rle_pack_len[rowi], 2, 1, f) < 1)
                               {
-                                g_message (_("Error reading packbits length"));
+                                psd_set_error (feof (f), errno, error);
                                 return -1;
                               }
                                 rle_pack_len[rowi] = GUINT16_FROM_BE (rle_pack_len[rowi]);
-                                IFDBG(3) g_debug ("Row %d, Packed length %d",
-                                                  rowi, rle_pack_len[rowi]);
                           }
 
                         IFDBG(3) g_debug ("RLE decode - data");
                         if (read_channel_data (lyr_chn[cidx], img_a->bps,
-                            PSD_COMP_RLE, rle_pack_len, f) < 1)
-                          {
-                            g_message (_("Error reading packbits channel"));
-                            return -1;
-                          }
+                            PSD_COMP_RLE, rle_pack_len, f, error) < 1)
+                          return -1;
 
                         g_free (rle_pack_len);
                         break;
 
                       case PSD_COMP_ZIP:                 /* ? */
                       case PSD_COMP_ZIP_PRED:
-                        g_message (_("Compression mode not supported %d"), comp_mode);
+                        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                                    _("Unsupported compression mode: %d"), comp_mode);
                         return -1;
                         break;
                     }
@@ -1130,7 +1155,7 @@
           l_w = img_a->columns;
           l_h = img_a->rows;
 
-          IFDBG(2) g_debug ("Re-hash channel indices");
+          IFDBG(3) g_debug ("Re-hash channel indices");
           for (cidx = 0; cidx < lyr_a[lidx]->num_channels; ++cidx)
             {
               if (lyr_chn[cidx]->id == PSD_CHANNEL_MASK)
@@ -1181,32 +1206,24 @@
               l_w = lyr_a[lidx]->right - lyr_a[lidx]->left;
               l_h = lyr_a[lidx]->bottom - lyr_a[lidx]->top;
 
-              IFDBG(2) g_debug ("Draw layer");
+              IFDBG(3) g_debug ("Draw layer");
               image_type = get_gimp_image_type (img_a->base_type, alpha);
-              IFDBG(2) g_debug ("Layer type %d", image_type);
+              IFDBG(3) g_debug ("Layer type %d", image_type);
               layer_size = l_w * l_h;
               pixels = g_malloc (layer_size * layer_channels);
-              IFDBG(2) g_debug ("Allocate Pixels %d x %d", layer_size, layer_channels);
               for (cidx = 0; cidx < layer_channels; ++cidx)
                 {
-                  IFDBG(2) g_debug ("Start channel %d", channel_idx[cidx]);
+                  IFDBG(3) g_debug ("Start channel %d", channel_idx[cidx]);
                   for (i = 0; i < layer_size; ++i)
-                    {
-                      pixels[(i * layer_channels) + cidx] = lyr_chn[channel_idx[cidx]]->data[i];
-                      IFDBG(3) g_debug ("Pixels, %d, %d", (i * layer_channels) + cidx,
-                                         pixels[(i * layer_channels) + cidx]);
-                    }
-                  IFDBG(2) g_debug ("Done channel %d, id %d", cidx,
-                                     lyr_chn[channel_idx[cidx]]->id);
+                    pixels[(i * layer_channels) + cidx] = lyr_chn[channel_idx[cidx]]->data[i];
                   g_free (lyr_chn[channel_idx[cidx]]->data);
-                  IFDBG(2) g_debug ("Free channel %d", channel_idx[cidx]);
                 }
 
               layer_mode = psd_to_gimp_blend_mode (lyr_a[lidx]->blend_mode);
               layer_id = gimp_layer_new (image_id, lyr_a[lidx]->name, l_w, l_h,
                                          image_type, lyr_a[lidx]->opacity * 100 / 255,
                                          layer_mode);
-              IFDBG(2) g_debug ("New layer %d", layer_id);
+              IFDBG(3) g_debug ("Layer tattoo: %d", layer_id);
               g_free (lyr_a[lidx]->name);
               gimp_image_add_layer (image_id, layer_id, -1);
               gimp_layer_set_offsets (layer_id, l_x, l_y);
@@ -1229,7 +1246,7 @@
             {
               if (empty_mask)
                 {
-                  IFDBG(2) g_debug ("Create empty mask");
+                  IFDBG(3) g_debug ("Create empty mask");
                   if (lyr_a[lidx]->layer_mask.def_color == 255)
                     mask_id = gimp_layer_create_mask (layer_id, GIMP_ADD_WHITE_MASK);
                   else
@@ -1255,23 +1272,23 @@
                       lm_w = lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left;
                       lm_h = lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top;
                     }
-                  IFDBG(2) g_debug ("Mask channel index %d", user_mask_chn);
-                  IFDBG(2) g_debug ("Relative pos %d",
+                  IFDBG(3) g_debug ("Mask channel index %d", user_mask_chn);
+                  IFDBG(3) g_debug ("Relative pos %d",
                                     lyr_a[lidx]->layer_mask.mask_flags.relative_pos);
                   layer_size = lm_w * lm_h;
                   pixels = g_malloc (layer_size);
-                  IFDBG(2) g_debug ("Allocate Pixels %d", layer_size);
+                  IFDBG(3) g_debug ("Allocate Pixels %d", layer_size);
                   /* Crop mask at layer boundry */
-                  IFDBG(2) g_debug ("Original Mask %d %d %d %d", lm_x, lm_y, lm_w, lm_h);
+                  IFDBG(3) g_debug ("Original Mask %d %d %d %d", lm_x, lm_y, lm_w, lm_h);
                   if (lm_x < 0
                       || lm_y < 0
                       || lm_w + lm_x > l_w
                       || lm_h + lm_y > l_h)
                     {
                       if (CONVERSION_WARNINGS)
-                        g_message (_("Warning\n"
-                                     "Layer mask partly lies outside layer boundry. The mask will be "
-                                     "cropped which may result in data loss."));
+                        g_message ("Warning\n"
+                                   "Layer mask partly lies outside layer boundry. The mask will be "
+                                   "cropped which may result in data loss.");
                       i = 0;
                       for (rowi = 0; rowi < lm_h; ++rowi)
                         {
@@ -1281,7 +1298,6 @@
                                 {
                                   if (coli + lm_x >= 0 && coli + lm_x < l_w)
                                     {
-                                      IFDBG(3) g_debug ("Row %d, col %d", rowi, coli);
                                       pixels[i] =
                                         lyr_chn[user_mask_chn]->data[(rowi * lm_w) + coli];
                                       i++;
@@ -1308,8 +1324,8 @@
                     memcpy (pixels, lyr_chn[user_mask_chn]->data, layer_size);
                   g_free (lyr_chn[user_mask_chn]->data);
                   /* Draw layer mask data */
-                  IFDBG(2) g_debug ("Layer %d %d %d %d", l_x, l_y, l_w, l_h);
-                  IFDBG(2) g_debug ("Mask %d %d %d %d", lm_x, lm_y, lm_w, lm_h);
+                  IFDBG(3) g_debug ("Layer %d %d %d %d", l_x, l_y, l_w, l_h);
+                  IFDBG(3) g_debug ("Mask %d %d %d %d", lm_x, lm_y, lm_w, lm_h);
 
                   if (lyr_a[lidx]->layer_mask.def_color == 255)
                     mask_id = gimp_layer_create_mask (layer_id, GIMP_ADD_WHITE_MASK);
@@ -1344,31 +1360,32 @@
 static gint
 add_merged_image (const gint32  image_id,
                   PSDimage     *img_a,
-                  FILE         *f)
+                  FILE         *f,
+                  GError      **error)
 {
   PSDchannel            chn_a[MAX_CHANNELS];
   gchar                *alpha_name;
   guchar               *pixels;
-  guint16               comp_mode,
-                        base_channels,
-                        extra_channels,
-                        total_channels,
-                       *rle_pack_len[MAX_CHANNELS];
-  guint32               block_len,
-                        block_start,
-                        block_end,
-                        alpha_id;
-  gint32                layer_size,
-                        layer_id = -1,
-                        channel_id = -1,
-                        active_layer;
+  guint16               comp_mode;
+  guint16               base_channels;
+  guint16               extra_channels;
+  guint16               total_channels;
+  guint16              *rle_pack_len[MAX_CHANNELS];
+  guint32               block_len;
+  guint32               block_start;
+  guint32               block_end;
+  guint32               alpha_id;
+  gint32                layer_size;
+  gint32                layer_id = -1;
+  gint32                channel_id = -1;
+  gint32                active_layer;
   gint16                alpha_opacity;
-  gint                 *lyr_lst,
-                        cidx,                  /* Channel index */
-                        rowi,                  /* Row index */
-                        lyr_count,
-                        offset,
-                        i;
+  gint                 *lyr_lst;
+  gint                  cidx;                  /* Channel index */
+  gint                  rowi;                  /* Row index */
+  gint                  lyr_count;
+  gint                  offset;
+  gint                  i;
   gboolean              alpha_visible;
   GimpDrawable         *drawable;
   GimpPixelRgn          pixel_rgn;
@@ -1412,7 +1429,7 @@
 
       if (fread (&comp_mode, 2, 1, f) < 1)
         {
-          g_message (_("Error reading layer compression mode"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       comp_mode = GUINT16_FROM_BE (comp_mode);
@@ -1420,23 +1437,21 @@
       switch (comp_mode)
         {
           case PSD_COMP_RAW:        /* Planar raw data */
-            IFDBG(2) g_debug ("Raw data length: %d", block_len);
+            IFDBG(3) g_debug ("Raw data length: %d", block_len);
             for (cidx = 0; cidx < total_channels; ++cidx)
               {
                 chn_a[cidx].columns = img_a->columns;
                 chn_a[cidx].rows = img_a->rows;
-                if (read_channel_data (&chn_a[cidx], img_a->bps, PSD_COMP_RAW, NULL, f) < 1)
-                  {
-                    g_message (_("Error reading raw channel"));
-                    return -1;
-                  }
+                if (read_channel_data (&chn_a[cidx], img_a->bps,
+                    PSD_COMP_RAW, NULL, f, error) < 1)
+                  return -1;
               }
             break;
 
           case PSD_COMP_RLE:        /* Packbits */
             /* Image data is stored as packed scanlines in planar order
                with all compressed length counters stored first */
-            IFDBG(2) g_debug ("RLE length data: %d, RLE data block: %d",
+            IFDBG(3) g_debug ("RLE length data: %d, RLE data block: %d",
                                total_channels * img_a->rows * 2,
                                block_len - (total_channels * img_a->rows * 2));
             for (cidx = 0; cidx < total_channels; ++cidx)
@@ -1448,29 +1463,27 @@
                   {
                     if (fread (&rle_pack_len[cidx][rowi], 2, 1, f) < 1)
                       {
-                        g_message (_("Error reading packbits length"));
+                        psd_set_error (feof (f), errno, error);
                         return -1;
                       }
                     rle_pack_len[cidx][rowi] = GUINT16_FROM_BE (rle_pack_len[cidx][rowi]);
                   }
               }
 
-            IFDBG(2) g_debug ("RLE decode - data");
+            IFDBG(3) g_debug ("RLE decode - data");
             for (cidx = 0; cidx < total_channels; ++cidx)
               {
                 if (read_channel_data (&chn_a[cidx], img_a->bps,
-                    PSD_COMP_RLE, rle_pack_len[cidx], f) < 1)
-                    {
-                      g_message (_("Error reading packbits channel"));
-                      return -1;
-                    }
+                    PSD_COMP_RLE, rle_pack_len[cidx], f, error) < 1)
+                  return -1;
                 g_free (rle_pack_len[cidx]);
               }
             break;
 
           case PSD_COMP_ZIP:                 /* ? */
           case PSD_COMP_ZIP_PRED:
-            g_message (_("Compression mode not supported %d"), comp_mode);
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                        _("Unsupported compression mode: %d"), comp_mode);
             return -1;
             break;
         }
@@ -1488,8 +1501,6 @@
           for (i = 0; i < layer_size; ++i)
             {
               pixels[(i * base_channels) + cidx] = chn_a[cidx].data[i];
-              IFDBG(3) g_debug ("Pixels, %d, %d",
-                (i * base_channels) + cidx, pixels[(i * base_channels) + cidx]);
             }
           g_free (chn_a[cidx].data);
         }
@@ -1511,13 +1522,16 @@
       g_free (pixels);
     }
   else
-    /* Free merged image data for layered image */
-    if (extra_channels)
-      for (cidx = 0; cidx < base_channels; ++cidx)
-        g_free (chn_a[cidx].data);
+    {
+      /* Free merged image data for layered image */
+      if (extra_channels)
+        for (cidx = 0; cidx < base_channels; ++cidx)
+          g_free (chn_a[cidx].data);
+    }
 
   /* ----- Draw extra alpha channels ----- */
-  if (extra_channels                    /* Extra alpha channels */
+  if ((extra_channels                   /* Extra alpha channels */
+      || img_a->transparency)           /* Transparency alpha channel */
       && image_id > -1)
     {
       IFDBG(2) g_debug ("Add extra channels");
@@ -1525,11 +1539,18 @@
 
       /* Get channel resource data */
       if (img_a->transparency)
-        offset = 1;
+        {
+          offset = 1;
+          /* Free "Transparency" channel name */
+          alpha_name = g_ptr_array_index (img_a->alpha_names, 0);
+          if (alpha_name)
+            g_free (alpha_name);
+        }
       else
         offset = 0;
 
       /* Draw channels */
+      IFDBG(2) g_debug ("Number of channels: %d", extra_channels);
       for (i = 0; i < extra_channels; ++i)
         {
           /* Alpha channel name */
@@ -1539,6 +1560,10 @@
           if (img_a->quick_mask_id)
             if (i == img_a->quick_mask_id - base_channels + offset)
               {
+                /* Free "Quick Mask" channel name */
+                alpha_name = g_ptr_array_index (img_a->alpha_names, i + offset);
+                if (alpha_name)
+                  g_free (alpha_name);
                 alpha_name = g_strdup (GIMP_IMAGE_QUICK_MASK_NAME);
                 alpha_visible = TRUE;
               }
@@ -1562,7 +1587,7 @@
             }
           else
             {
-              gimp_rgb_set (&alpha_rgb, 1.0, 0.0, 0.0);
+              gimp_rgba_set (&alpha_rgb, 1.0, 0.0, 0.0, 1.0);
               alpha_opacity = 50;
             }
 
@@ -1573,6 +1598,7 @@
                                          chn_a[cidx].columns, chn_a[cidx].rows,
                                          alpha_opacity, &alpha_rgb);
           gimp_image_add_channel (image_id, channel_id, 0);
+          g_free (alpha_name);
           drawable = gimp_drawable_get (channel_id);
           if (alpha_id)
             gimp_drawable_set_tattoo (drawable->drawable_id, alpha_id);
@@ -1619,7 +1645,34 @@
 
 
 /* Local utility functions */
+static gchar *
+get_psd_color_mode_name (PSDColorMode mode)
+{
+  static gchar *psd_color_mode_names[] =
+  {
+    "BITMAP",
+    "GRAYSCALE",
+    "INDEXED",
+    "RGB",
+    "CMYK",
+    "UNKNOWN (5)",
+    "UNKNOWN (6)",
+    "MULTICHANNEL",
+    "DUOTONE",
+    "LAB"
+  };
 
+  static gchar *err_name = NULL;
+  if (mode >= PSD_BITMAP && mode <= PSD_LAB)
+    {
+      return psd_color_mode_names[mode];
+    }
+  g_free (err_name);
+
+  err_name = g_strdup_printf ("UNKNOWN (%d)", mode);
+  return err_name;
+}
+
 static void
 psd_to_gimp_color_map (guchar *map256)
 {
@@ -1668,11 +1721,12 @@
 }
 
 static gint
-read_channel_data (PSDchannel    *channel,
-                   const guint16  bps,
-                   const guint16  compression,
-                   const guint16 *rle_pack_len,
-                   FILE          *f)
+read_channel_data (PSDchannel     *channel,
+                   const guint16   bps,
+                   const guint16   compression,
+                   const guint16  *rle_pack_len,
+                   FILE           *f,
+                   GError        **error)
 {
   gchar    *raw_data;
   gchar    *src;
@@ -1686,13 +1740,16 @@
     readline_len = (channel->columns * bps >> 3);
 
   IFDBG(3) g_debug ("raw data size %d x %d = %d", readline_len,
-   channel->rows, readline_len * channel->rows);
+                    channel->rows, readline_len * channel->rows);
   raw_data = g_malloc (readline_len * channel->rows);
   switch (compression)
     {
       case PSD_COMP_RAW:
         if (fread (raw_data, readline_len, channel->rows, f) < 1)
+          {
+            psd_set_error (feof (f), errno, error);
             return -1;
+          }
         break;
 
       case PSD_COMP_RLE:
@@ -1703,14 +1760,13 @@
 /*      FIXME check for over-run
             if (ftell (f) + rle_pack_len[i] > block_end)
               {
-                g_message (_("Unexpected end of file"));
+                psd_set_error (TRUE, errno, error);
                 return -1;
               }
 */
-            IFDBG(3) g_debug ("pack len %d", rle_pack_len[i]);
             if (fread (src, rle_pack_len[i], 1, f) < 1)
               {
-                g_message (_("Error reading packbits data"));
+                psd_set_error (feof (f), errno, error);
                 return -1;
               }
             /* FIXME check for errors returned from decode packbits */
@@ -1753,7 +1809,7 @@
 {
 /* Convert 16 bit to 8 bit dropping low byte
 */
-  int i;
+  gint      i;
 
   IFDBG(3)  g_debug ("Start 16 bit conversion");
 
Index: psd-thumb-load.c
===================================================================
--- psd-thumb-load.c	(revision 24558)
+++ psd-thumb-load.c	(working copy)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-
 #include "config.h"
 
 #include <string.h>
@@ -29,28 +28,32 @@
 #include <libgimp/gimp.h>
 
 #include "psd.h"
+#include "psd-util.h"
 #include "psd-image-res-load.h"
 #include "psd-thumb-load.h"
 
 #include "libgimp/stdplugins-intl.h"
 
-
 /*  Local function prototypes  */
-static gint     read_header_block         (PSDimage     *img_a,
-                                           FILE         *f);
+static gint             read_header_block          (PSDimage     *img_a,
+                                                    FILE         *f,
+                                                    GError      **error);
 
-static gint     read_color_mode_block     (PSDimage     *img_a,
-                                           FILE         *f);
+static gint             read_color_mode_block      (PSDimage     *img_a,
+                                                    FILE         *f,
+                                                    GError      **error);
 
-static gint     read_image_resource_block (PSDimage     *img_a,
-                                           FILE         *f);
+static gint             read_image_resource_block  (PSDimage     *img_a,
+                                                    FILE         *f,
+                                                    GError      **error);
 
-static gint32   create_gimp_image         (PSDimage     *img_a,
-                                           const gchar  *filename);
+static gint32           create_gimp_image          (PSDimage     *img_a,
+                                                    const gchar  *filename);
 
-static gint     add_image_resources       (const gint32  image_id,
-                                           PSDimage     *img_a,
-                                           FILE         *f);
+static gint             add_image_resources        (const gint32  image_id,
+                                                    PSDimage     *img_a,
+                                                    FILE         *f,
+                                                    GError      **error);
 
 /* Main file load function */
 gint32
@@ -58,12 +61,12 @@
                       gint        *width,
                       gint        *height)
 {
-  FILE        *f;
-  struct stat  st;
-  PSDimage     img_a;
-  gint32       image_id = -1;
+  FILE                 *f;
+  struct stat           st;
+  PSDimage              img_a;
+  gint32                image_id = -1;
+  GError               *error = NULL;
 
-
   /* ----- Open PSD file ----- */
   if (g_stat (filename, &st) == -1)
     return -1;
@@ -77,54 +80,37 @@
       return -1;
     }
 
-  gimp_progress_init_printf (_("Loading thumbnail for '%s'"),
+  gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                              gimp_filename_to_utf8 (filename));
 
-  IFDBG(2) g_debug ("Read header block");
   /* ----- Read the PSD file Header block ----- */
-  if (read_header_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  IFDBG(2) g_debug ("Read header block");
+  if (read_header_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.2);
 
-  IFDBG(2) g_debug ("Read colour mode block");
   /* ----- Read the PSD file Colour Mode block ----- */
-  if (read_color_mode_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  IFDBG(2) g_debug ("Read colour mode block");
+  if (read_color_mode_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.4);
 
-  IFDBG(2) g_debug ("Read image resource block");
   /* ----- Read the PSD file Image Resource block ----- */
-  if (read_image_resource_block (&img_a, f) < 0)
-    {
-      fclose(f);
-      return -1;
-    }
+  IFDBG(2) g_debug ("Read image resource block");
+  if (read_image_resource_block (&img_a, f, &error) < 0)
+    goto load_error;
   gimp_progress_update (0.6);
 
-  IFDBG(2) g_debug ("Create GIMP image");
   /* ----- Create GIMP image ----- */
+  IFDBG(2) g_debug ("Create GIMP image");
   image_id = create_gimp_image (&img_a, filename);
-  if (image_id == -1)
-    {
-      fclose(f);
-      return -1;
-    }
-  gimp_progress_update (0.8);
+  if (image_id < 0)
+    goto load_error;
 
-  IFDBG(2) g_debug ("Add image resources");
   /* ----- Add image resources ----- */
-  if (add_image_resources (image_id, &img_a, f) < 1)
-    {
-      gimp_image_delete (image_id);
-      fclose(f);
-      return -1;
-    }
+  IFDBG(2) g_debug ("Add image resources");
+  if (add_image_resources (image_id, &img_a, f, &error) < 1)
+    goto load_error;
   gimp_progress_update (1.0);
 
   gimp_image_clean_all (image_id);
@@ -134,14 +120,27 @@
   *width = img_a.columns;
   *height = img_a.rows;
   return image_id;
+
+  /* ----- Process load errors ----- */
+ load_error:
+  /* Delete partially loaded image */
+  if (image_id > 0)
+    gimp_image_delete (image_id);
+
+  /* Close file if Open */
+  if (! (f == NULL))
+    fclose (f);
+
+  return -1;
 }
 
 
 /* Local functions */
 
 static gint
-read_header_block (PSDimage *img_a,
-                   FILE     *f)
+read_header_block (PSDimage  *img_a,
+                   FILE      *f,
+                   GError   **error)
 {
   guint16  version;
   gchar    sig[4];
@@ -156,7 +155,7 @@
       || fread (&img_a->bps, 2, 1, f) < 1
       || fread (&img_a->color_mode, 2, 1, f) < 1)
     {
-      g_message (_("Error reading file header"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   version = GUINT16_FROM_BE (version);
@@ -173,36 +172,27 @@
                     img_a->bps, img_a->color_mode);
 
   if (memcmp (sig, "8BPS", 4) != 0)
-    {
-      g_message (_("Incorrect file signature"));
-      return -1;
-    }
+    return -1;
 
   if (version != 1)
-    {
-      g_message (_("Unsupported PSD file format version %d"), version);
-      return -1;
-    }
+    return -1;
 
   if (img_a->channels > MAX_CHANNELS)
-    {
-      g_message (_("Too many channels in file (%d)"), img_a->channels);
-      return -1;
-    }
+    return -1;
 
-  if (img_a->rows == 0 || img_a->columns == 0)
-    {
-      g_message (_("Unsupported PSD file version (< 2.5)")); /* FIXME - image size */
-                                                             /* in resource block 1000 */
-      return -1;                                             /* don't have PS2 file spec */
-    }
+  if (img_a->rows < 1 || img_a->rows > GIMP_MAX_IMAGE_SIZE)
+    return -1;
 
+  if (img_a->columns < 1 || img_a->columns > GIMP_MAX_IMAGE_SIZE)
+    return -1;
+
   return 0;
 }
 
 static gint
-read_color_mode_block (PSDimage *img_a,
-                       FILE     *f)
+read_color_mode_block (PSDimage  *img_a,
+                       FILE      *f,
+                       GError   **error)
 {
   guint32 block_len;
   guint32 block_start;
@@ -210,19 +200,17 @@
 
   if (fread (&block_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading color block"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   block_len = GUINT32_FROM_BE (block_len);
 
-  IFDBG(1) g_debug ("Color map block size = %d", block_len);
-
   block_start = ftell (f);
   block_end = block_start + block_len;
 
   if (fseek (f, block_end, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -230,15 +218,16 @@
 }
 
 static gint
-read_image_resource_block (PSDimage *img_a,
-                           FILE     *f)
+read_image_resource_block (PSDimage  *img_a,
+                           FILE      *f,
+                           GError   **error)
 {
   guint32 block_len;
   guint32 block_end;
 
   if (fread (&block_len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading image resource block"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
   img_a->image_res_len = GUINT32_FROM_BE (block_len);
@@ -250,7 +239,7 @@
 
   if (fseek (f, block_end, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
@@ -267,44 +256,39 @@
 
   /* Create gimp image */
   IFDBG(2) g_debug ("Create image");
-  if ((image_id = gimp_image_new (img_a->columns, img_a->rows,
-                                  img_a->base_type)) == -1)
-    {
-      g_message (_("Could not create a new image"));
-      return -1;
-    }
+  image_id = gimp_image_new (img_a->columns, img_a->rows, img_a->base_type);
 
-  gimp_image_undo_disable (image_id);
   gimp_image_set_filename (image_id, filename);
+  gimp_image_undo_disable (image_id);
+
   return image_id;
 }
 
 static gint
-add_image_resources (const gint32  image_id,
-                     PSDimage     *img_a,
-                     FILE         *f)
+add_image_resources (const gint32   image_id,
+                     PSDimage      *img_a,
+                     FILE          *f,
+                     GError       **error)
 {
   PSDimageres   res_a;
   gint          status;
 
   if (fseek (f, img_a->image_res_start, SEEK_SET) < 0)
     {
-      g_message (_("Error setting file position"));
+      psd_set_error (feof (f), errno, error);
       return -1;
     }
 
   while (ftell (f) < img_a->image_res_start + img_a->image_res_len)
     {
-      if (get_image_resource_header (&res_a, f) < 0)
+      if (get_image_resource_header (&res_a, f, error) < 0)
         return -1;
 
       if (res_a.data_start + res_a.data_len >
           img_a->image_res_start + img_a->image_res_len)
-        {
-          g_message ("Unexpected end of image resource data");
-          return 0;
-        }
-      status = load_thumbnail_resource (&res_a, image_id, f);
+        return 0;
+
+      status = load_thumbnail_resource (&res_a, image_id, f, error);
       /* Error */
       if (status < 0)
         return -1;
Index: psd-util.c
===================================================================
--- psd-util.c	(revision 24558)
+++ psd-util.c	(working copy)
@@ -19,10 +19,10 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-
 #include "config.h"
 
 #include <string.h>
+#include <errno.h>
 
 #include <glib/gstdio.h>
 #include <libgimp/gimp.h>
@@ -36,19 +36,43 @@
 #define MIN_RUN     3
 
 /*  Local function prototypes  */
+static gchar *          gimp_layer_mode_effects_name    (const GimpLayerModeEffects      mode);
 
 
 /* Utility function */
+void
+psd_set_error (const gboolean   file_eof,
+               const gint       err_no,
+               GError         **error)
+{
+  /*
+   *  Set error
+   */
+  if (file_eof)
+    *error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                          _("Unexpected end of file"));
+  else
+    *error = g_error_new (G_FILE_ERROR,
+                          g_file_error_from_errno (err_no),
+                          "%s", g_strerror (err_no));
+
+  return;
+}
+
 gchar *
-fread_pascal_string (gint32        *bytes_read,
-                     gint32        *bytes_written,
-                     const guint16  pad_len,
-                     FILE          *f)
+fread_pascal_string (gint32         *bytes_read,
+                     gint32         *bytes_written,
+                     const guint16   mod_len,
+                     FILE           *f,
+                     GError        **error)
 {
-  /* Reads a pascal string padded to a multiple of pad_len and converts to utf-8 */
+  /*
+   * Reads a pascal string from the file padded to a multiple of mod_len
+   * and returns a utf-8 string.
+   */
 
-  gchar        *str,
-               *utf8_str;
+  gchar        *str;
+  gchar        *utf8_str;
   guchar        len;
   gint32        padded_len;
 
@@ -57,7 +81,7 @@
 
   if (fread (&len, 1, 1, f) < 1)
     {
-      g_message (_("Error reading pascal string length"));
+      psd_set_error (feof (f), errno, error);
       return NULL;
     }
   (*bytes_read)++;
@@ -65,12 +89,12 @@
 
   if (len == 0)
     {
-      if (fseek (f, pad_len - 1, SEEK_CUR) < 0)
+      if (fseek (f, mod_len - 1, SEEK_CUR) < 0)
         {
-          g_message (_("Error setting file position"));
+          psd_set_error (feof (f), errno, error);
           return NULL;
         }
-      *bytes_read += (pad_len - 1);
+      *bytes_read += (mod_len - 1);
       *bytes_written = 0;
       return NULL;
     }
@@ -78,19 +102,19 @@
   str = g_malloc (len);
   if (fread (str, len, 1, f) < 1)
     {
-      g_message (_("Error reading pascal string"));
+      psd_set_error (feof (f), errno, error);
       return NULL;
     }
   *bytes_read += len;
 
-  if (pad_len > 0)
+  if (mod_len > 0)
     {
       padded_len = len + 1;
-      while (padded_len % pad_len != 0)
+      while (padded_len % mod_len != 0)
         {
           if (fseek (f, 1, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return NULL;
             }
           (*bytes_read)++;
@@ -98,27 +122,30 @@
         }
     }
 
-  utf8_str = gimp_any_to_utf8 (str, len, _("Invalid UTF-8 string in PSD file"));
+  utf8_str = gimp_any_to_utf8 (str, len, NULL);
   *bytes_written = strlen (utf8_str);
   g_free (str);
 
-  IFDBG(2) g_debug ("Pascal string: %s, bytes_read: %d, bytes_written: %d",
+  IFDBG(3) g_debug ("Pascal string: %s, bytes_read: %d, bytes_written: %d",
                     utf8_str, *bytes_read, *bytes_written);
 
   return utf8_str;
 }
 
 gint32
-fwrite_pascal_string (const gchar   *src,
-                      const guint16  pad_len,
-                      FILE          *f)
+fwrite_pascal_string (const gchar    *src,
+                      const guint16   mod_len,
+                      FILE           *f,
+                      GError        **error)
 {
-  /* Converts utf-8 string to current locale and writes as pascal string with
-     padding to pad width */
+  /*
+   *  Converts utf-8 string to current locale and writes as pascal
+   *  string with padding to a multiple of mod_len.
+   */
 
-  gchar        *str,
-               *pascal_str,
-                null_str = 0x0;
+  gchar        *str;
+  gchar        *pascal_str;
+  gchar         null_str = 0x0;
   guchar        pascal_len;
   gint32        bytes_written = 0;
   gsize         len;
@@ -129,7 +156,7 @@
       if (fwrite (&null_str, 1, 1, f) < 1
           || fwrite (&null_str, 1, 1, f) < 1)
         {
-          g_message (_("Error writing pascal string"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       bytes_written += 2;
@@ -146,7 +173,7 @@
       if (fwrite (&pascal_len, 1, 1, f) < 1
           || fwrite (pascal_str, pascal_len, 1, f) < 1)
         {
-          g_message (_("Error writing pascal string"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       bytes_written++;
@@ -156,13 +183,13 @@
     }
 
   /* Pad with nulls */
-  if (pad_len > 0)
+  if (mod_len > 0)
     {
-      while (bytes_written % pad_len != 0)
+      while (bytes_written % mod_len != 0)
         {
           if (fwrite (&null_str, 1, 1, f) < 1)
             {
-              g_message (_("Error writing pascal string"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
           bytes_written++;
@@ -173,18 +200,22 @@
 }
 
 gchar *
-fread_unicode_string (gint32        *bytes_read,
-                      gint32        *bytes_written,
-                      const guint16  pad_len,
-                      FILE          *f)
+fread_unicode_string (gint32         *bytes_read,
+                      gint32         *bytes_written,
+                      const guint16   mod_len,
+                      FILE           *f,
+                      GError        **error)
 {
-  /* Reads a utf-16 string padded to a multiple of pad_len and converts to utf-8 */
+  /*
+   * Reads a utf-16 string from the file padded to a multiple of mod_len
+   * and returns a utf-8 string.
+   */
 
   gchar        *utf8_str;
   gunichar2    *utf16_str;
-  gint32        len,
-                i,
-                padded_len;
+  gint32        len;
+  gint32        i;
+  gint32        padded_len;
   glong         utf8_str_len;
 
   *bytes_read = 0;
@@ -192,7 +223,7 @@
 
   if (fread (&len, 4, 1, f) < 1)
     {
-      g_message (_("Error reading unicode string length"));
+      psd_set_error (feof (f), errno, error);
       return NULL;
     }
   *bytes_read += 4;
@@ -201,12 +232,12 @@
 
   if (len == 0)
     {
-      if (fseek (f, pad_len - 1, SEEK_CUR) < 0)
+      if (fseek (f, mod_len - 1, SEEK_CUR) < 0)
         {
-          g_message (_("Error setting file position"));
+          psd_set_error (feof (f), errno, error);
           return NULL;
         }
-      *bytes_read += (pad_len - 1);
+      *bytes_read += (mod_len - 1);
       *bytes_written = 0;
       return NULL;
     }
@@ -216,21 +247,21 @@
     {
       if (fread (&utf16_str[i], 2, 1, f) < 1)
         {
-          g_message (_("Error reading unicode string"));
+          psd_set_error (feof (f), errno, error);
           return NULL;
         }
       *bytes_read += 2;
       utf16_str[i] = GINT16_FROM_BE (utf16_str[i]);
     }
 
-  if (pad_len > 0)
+  if (mod_len > 0)
     {
       padded_len = len + 1;
-      while (padded_len % pad_len != 0)
+      while (padded_len % mod_len != 0)
         {
           if (fseek (f, 1, SEEK_CUR) < 0)
             {
-              g_message (_("Error setting file position"));
+              psd_set_error (feof (f), errno, error);
               return NULL;
             }
           (*bytes_read)++;
@@ -249,17 +280,20 @@
 }
 
 gint32
-fwrite_unicode_string (const gchar   *src,
-                       const guint16  pad_len,
-                       FILE          *f)
+fwrite_unicode_string (const gchar    *src,
+                       const guint16   mod_len,
+                       FILE           *f,
+                       GError        **error)
 {
-  /* Converts utf-8 string to utf-16 and writes 4 byte length then string
-     padding to pad width */
+  /*
+   *  Converts utf-8 string to utf-16 and writes 4 byte length
+   *  then string padding to multiple of mod_len.
+   */
 
   gunichar2    *utf16_str;
   gchar         null_str = 0x0;
-  gint32        utf16_len = 0,
-                bytes_written = 0;
+  gint32        utf16_len = 0;
+  gint32        bytes_written = 0;
   gint          i;
   glong         len;
 
@@ -268,7 +302,7 @@
        /* Write null string as four byte 0 int32 */
       if (fwrite (&utf16_len, 4, 1, f) < 1)
         {
-          g_message (_("Error writing unicode string"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       bytes_written += 4;
@@ -285,7 +319,7 @@
       if (fwrite (&utf16_len, 4, 1, f) < 1
           || fwrite (utf16_str, 2, utf16_len + 1, f) < utf16_len + 1)
         {
-          g_message (_("Error writing unicode string"));
+          psd_set_error (feof (f), errno, error);
           return -1;
         }
       bytes_written += (4 + 2 * utf16_len + 2);
@@ -294,13 +328,13 @@
     }
 
   /* Pad with nulls */
-  if (pad_len > 0)
+  if (mod_len > 0)
     {
-      while (bytes_written % pad_len != 0)
+      while (bytes_written % mod_len != 0)
         {
           if (fwrite (&null_str, 1, 1, f) < 1)
             {
-              g_message (_("Error writing unicode string"));
+              psd_set_error (feof (f), errno, error);
               return -1;
             }
           bytes_written++;
@@ -319,16 +353,13 @@
 /*
  *  Decode a PackBits chunk.
  */
-  int    n;
-  gchar  dat;
-  gint32 unpack_left = unpacked_len,
-         pack_left = packed_len,
-         error_code = 0,
-         return_val = 0;
+  gint      n;
+  gchar     dat;
+  gint32    unpack_left = unpacked_len;
+  gint32    pack_left = packed_len;
+  gint32    error_code = 0;
+  gint32    return_val = 0;
 
-  IFDBG(3) g_debug ("Decode packbits");
-  IFDBG(3) g_debug ("Packed len %d, unpacked %d",packed_len, unpacked_len);
-
   while (unpack_left > 0 && pack_left > 0)
     {
       n = *src;
@@ -405,7 +436,6 @@
         }
     }
 
-  IFDBG(3) g_debug ("Pack left %d, unpack left %d", pack_left, unpack_left);
   if (unpack_left)
     {
       IFDBG(2) g_debug ("Packbits decode - unpack left %d", unpack_left);
@@ -582,8 +612,12 @@
   if (g_ascii_strncasecmp (psd_mode, "sat ", 4) == 0)           /* Saturation (ps3) */
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Gimp uses a different equation to photoshop for the "
-                     "saturation blend mode. Results will differ."));
+        {
+          static gchar  *mode_name = "SATURATION";
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     mode_name);
+        }
       return GIMP_SATURATION_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "colr", 4) == 0)           /* Color (ps3) */
@@ -591,8 +625,12 @@
   if (g_ascii_strncasecmp (psd_mode, "lum ", 4) == 0)           /* Luminosity (ps3) */
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Gimp uses a different equation to photoshop for the "
-                     "value (luminosity) blend mode. Results will differ."));
+        {
+          static gchar  *mode_name = "LUMINOSITY (VALUE)";
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     mode_name);
+        }
       return GIMP_VALUE_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "mul ", 4) == 0)           /* Multiply (ps3) */
@@ -604,8 +642,12 @@
   if (g_ascii_strncasecmp (psd_mode, "over", 4) == 0)           /* Overlay (ps3) */
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Gimp uses a different equation to photoshop for the "
-                     "overlay blend mode. Results will differ."));
+        {
+          static gchar  *mode_name = "OVERLAY";
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     mode_name);
+        }
       return GIMP_OVERLAY_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "hLit", 4) == 0)           /* Hard light (ps3) */
@@ -613,8 +655,12 @@
   if (g_ascii_strncasecmp (psd_mode, "sLit", 4) == 0)           /* Soft light (ps3) */
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Gimp uses a different equation to photoshop for the "
-                     "soft light blend mode. Results will differ."));
+        {
+          static gchar  *mode_name = "SOFT LIGHT";
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     mode_name);
+        }
     return GIMP_SOFTLIGHT_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "diff", 4) == 0)           /* Difference (ps3) */
@@ -622,8 +668,11 @@
   if (g_ascii_strncasecmp (psd_mode, "smud", 4) == 0)           /* Exclusion (ps6) */
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Exclusion blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "EXCLUSION";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "div ", 4) == 0)           /* Color dodge (ps6) */
@@ -633,8 +682,11 @@
   if (g_ascii_strncasecmp (psd_mode, "lbrn", 4) == 0)           /* Linear burn (ps7)*/
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Linear burn blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "LINEAR BURN";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "lddg", 4) == 0)           /* Linear dodge (ps7)*/
@@ -642,34 +694,51 @@
   if (g_ascii_strncasecmp (psd_mode, "lLit", 4) == 0)           /* Linear light (ps7)*/
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Linear light blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "LINEAR LIGHT";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "pLit", 4) == 0)           /* Pin light (ps7)*/
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Pin light blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "PIN LIGHT";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "vLit", 4) == 0)           /* Vivid light (ps7)*/
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Vivid light blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "VIVID LIGHT";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
   if (g_ascii_strncasecmp (psd_mode, "hMix", 4) == 0)           /* Hard Mix (CS)*/
     {
       if (CONVERSION_WARNINGS)
-        g_message (_("Hard mix blend mode not supported by GIMP. "
-                     "Blend mode reverts to normal."));
+        {
+          static gchar  *mode_name = "HARD MIX";
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     mode_name);
+        }
       return GIMP_NORMAL_MODE;
     }
 
   if (CONVERSION_WARNINGS)
-    g_message (_("Unknown blend mode %.4s. Blend mode reverts to normal."), psd_mode);
+    {
+      gchar  *mode_name = g_strndup (psd_mode, 4);
+      g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                 mode_name);
+      g_free (mode_name);
+    }
   return GIMP_NORMAL_MODE;
 }
 
@@ -688,8 +757,8 @@
         break;
       case GIMP_BEHIND_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Behind blend mode not supported in PSD file. "
-                       "Blend mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
       case GIMP_MULTIPLY_MODE:
@@ -700,8 +769,9 @@
         break;
       case GIMP_OVERLAY_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Gimp uses a different equation to photoshop for the "
-                       "overlay blend mode. Results will differ."));
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("over", 4);                       /* Overlay (ps3) */
         break;
       case GIMP_DIFFERENCE_MODE:
@@ -712,8 +782,8 @@
         break;
       case GIMP_SUBTRACT_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Photoshop does not support the subtract "
-                       "blend mode. Layer mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
       case GIMP_DARKEN_ONLY_MODE:
@@ -727,8 +797,9 @@
         break;
       case GIMP_SATURATION_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Gimp uses a different equation to photoshop for the "
-                       "saturation blend mode. Results will differ."));
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("sat ", 4);                       /* Saturation (ps3) */
         break;
       case GIMP_COLOR_MODE:
@@ -736,14 +807,15 @@
         break;
       case GIMP_VALUE_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Gimp uses a different equation to photoshop for the "
-                       "value (luminosity) blend mode. Results will differ."));
+          g_message ("Gimp uses a different equation to photoshop for "
+                     "blend mode: %s. Results will differ.",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("lum ", 4);                       /* Luminosity (ps3) */
         break;
       case GIMP_DIVIDE_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Photoshop does not support the divide "
-                       "blend mode. Layer mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
       case GIMP_DODGE_MODE:
@@ -757,35 +829,73 @@
         break;
       case GIMP_SOFTLIGHT_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Gimp uses a different equation to photoshop for the "
-                       "soft light blend mode. Results will differ."));
-        psd_mode = g_strndup ("sLit", 4);                       /* Soft Light (ps3) */
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
+         psd_mode = g_strndup ("sLit", 4);                       /* Soft Light (ps3) */
         break;
       case GIMP_GRAIN_EXTRACT_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Photoshop does not support the grain extract "
-                       "blend mode. Layer mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
       case GIMP_GRAIN_MERGE_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Photoshop does not support the grain merge "
-                       "blend mode. Layer mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
       case GIMP_COLOR_ERASE_MODE:
         if (CONVERSION_WARNINGS)
-          g_message (_("Photoshop does not support the color erase "
-                       "blend mode. Layer mode reverts to normal."));
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
         break;
 
       default:
         if (CONVERSION_WARNINGS)
-          g_message (_("Blend mode %d not supported. Blend mode reverts to normal.")
-                     , gimp_layer_mode);
+          g_message ("Unsupported blend mode: %s. Mode reverts to normal",
+                     gimp_layer_mode_effects_name (gimp_layer_mode));
         psd_mode = g_strndup ("norm", 4);
     }
 
   return psd_mode;
 }
+
+static gchar *
+gimp_layer_mode_effects_name (const GimpLayerModeEffects mode)
+{
+  static gchar *layer_mode_effects_names[] =
+  {
+    "NORMAL",
+    "DISSOLVE",
+    "BEHIND",
+    "MULTIPLY",
+    "SCREEN",
+    "OVERLAY",
+    "DIFFERENCE",
+    "ADD",
+    "SUBTRACT",
+    "DARKEN",
+    "LIGHTEN",
+    "HUE",
+    "SATURATION",
+    "COLOR",
+    "VALUE",
+    "DIVIDE",
+    "DODGE",
+    "BURN",
+    "HARD LIGHT",
+    "SOFT LIGHT",
+    "GRAIN EXTRACT",
+    "GRAIN MERGE",
+    "COLOR ERASE"
+  };
+  static gchar *err_name = NULL;
+  if (mode >= 0 && mode <= GIMP_COLOR_ERASE_MODE)
+    return layer_mode_effects_names[mode];
+  g_free (err_name);
+
+  err_name = g_strdup_printf ("UNKNOWN (%d)", mode);
+  return err_name;
+}
Index: psd-util.h
===================================================================
--- psd-util.h	(revision 24558)
+++ psd-util.h	(working copy)
@@ -22,36 +22,62 @@
 #ifndef __PSD_UTIL_H__
 #define __PSD_UTIL_H__
 
+/*
+ *  Set file read error
+ */
+void                    psd_set_error          (const gboolean  file_eof,
+                                                const gint      err_no,
+                                                GError        **error);
 
-gchar                * fread_pascal_string    (gint32        *bytes_read,
-                                               gint32        *bytes_written,
-                                               const guint16  pad_len,
-                                               FILE          *f);
+/*
+ * Reads a pascal string from the file padded to a multiple of mod_len
+ * and returns a utf-8 string.
+ */
+gchar                 * fread_pascal_string    (gint32         *bytes_read,
+                                                gint32         *bytes_written,
+                                                const guint16   mod_len,
+                                                FILE           *f,
+                                                GError        **error);
 
-gint32                 fwrite_pascal_string   (const gchar   *src,
-                                               const guint16  pad_len,
-                                               FILE          *f);
+/*
+ *  Converts utf-8 string to current locale and writes as pascal
+ *  string with padding to a multiple of mod_len.
+ */
+gint32                  fwrite_pascal_string   (const gchar    *src,
+                                                const guint16   mod_len,
+                                                FILE           *f,
+                                                GError        **error);
 
-gchar                * fread_unicode_string   (gint32        *bytes_read,
-                                               gint32        *bytes_written,
-                                               const guint16  pad_len,
-                                               FILE          *f);
+/*
+ * Reads a utf-16 string from the file padded to a multiple of mod_len
+ * and returns a utf-8 string.
+ */
+gchar                 * fread_unicode_string   (gint32         *bytes_read,
+                                                gint32         *bytes_written,
+                                                const guint16   mod_len,
+                                                FILE           *f,
+                                                GError        **error);
 
-gint32                 fwrite_unicode_string  (const gchar   *src,
-                                               const guint16  pad_len,
-                                               FILE          *f);
+/*
+ *  Converts utf-8 string to utf-16 and writes 4 byte length
+ *  then string padding to multiple of mod_len.
+ */
+gint32                  fwrite_unicode_string  (const gchar    *src,
+                                                const guint16   mod_len,
+                                                FILE           *f,
+                                                GError        **error);
 
-gint                   decode_packbits        (const gchar   *src,
-                                               gchar         *dst,
-                                               guint16        packed_len,
-                                               guint32        unpacked_len);
+gint                    decode_packbits        (const gchar    *src,
+                                                gchar          *dst,
+                                                guint16         packed_len,
+                                                guint32         unpacked_len);
 
-gchar                * encode_packbits        (const gchar   *src,
-                                               const guint32  unpacked_len,
-                                               guint16       *packed_len);
+gchar                 * encode_packbits        (const gchar    *src,
+                                                const guint32   unpacked_len,
+                                                guint16        *packed_len);
 
-GimpLayerModeEffects   psd_to_gimp_blend_mode (const gchar   *psd_mode);
+GimpLayerModeEffects    psd_to_gimp_blend_mode (const gchar    *psd_mode);
 
-gchar *                gimp_to_psd_blend_mode (const GimpLayerModeEffects gimp_layer_mode);
+gchar *                 gimp_to_psd_blend_mode (const GimpLayerModeEffects gimp_layer_mode);
 
 #endif /* __PSD_UTIL_H__ */
Index: psd.c
===================================================================
--- psd.c	(revision 24558)
+++ psd.c	(working copy)
@@ -200,8 +200,6 @@
         }
       else
         {
-          g_message (_("Could not open '%s' for reading"),
-                     gimp_filename_to_utf8 (param[1].data.d_string));
           status = GIMP_PDB_EXECUTION_ERROR;
         }
     }
Index: psd.h
===================================================================
--- psd.h	(revision 24558)
+++ psd.h	(working copy)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-
 #ifndef __PSD_H__
 #define __PSD_H__
 
@@ -133,7 +132,6 @@
 #define PSD_LFX_INNER_GLW       "iglw"          /* Effects layer - inner glow (PS5) */
 #define PSD_LFX_BEVEL           "bevl"          /* Effects layer - bevel (PS5) */
 
-
 /* PSD spec enums */
 
 /* Image colour modes */
