gimp r24572 - in trunk: . plug-ins/psd
- From: neo svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r24572 - in trunk: . plug-ins/psd
- Date: Tue, 8 Jan 2008 21:02:56 +0000 (GMT)
Author: neo
Date: Tue Jan 8 21:02:56 2008
New Revision: 24572
URL: http://svn.gnome.org/viewvc/gimp?rev=24572&view=rev
Log:
2008-01-08 Sven Neumann <sven gimp org>
* plug-ins/psd/psd-image-res-load.[ch]
* plug-ins/psd/psd-layer-res-load.[ch]
* plug-ins/psd/psd-load.c
* plug-ins/psd/psd-thumb-load.c
* plug-ins/psd/psd-util.[ch]
* plug-ins/psd/psd.[ch]: applied a patch from John Marshall that
improves error handling of the new PSD load plug-in (bug
#448181).
Modified:
trunk/ChangeLog
trunk/plug-ins/psd/psd-image-res-load.c
trunk/plug-ins/psd/psd-image-res-load.h
trunk/plug-ins/psd/psd-layer-res-load.c
trunk/plug-ins/psd/psd-layer-res-load.h
trunk/plug-ins/psd/psd-load.c
trunk/plug-ins/psd/psd-thumb-load.c
trunk/plug-ins/psd/psd-util.c
trunk/plug-ins/psd/psd-util.h
trunk/plug-ins/psd/psd.c
trunk/plug-ins/psd/psd.h
Modified: trunk/plug-ins/psd/psd-image-res-load.c
==============================================================================
--- trunk/plug-ins/psd/psd-image-res-load.c (original)
+++ trunk/plug-ins/psd/psd-image-res-load.c Tue Jan 8 21:02:56 2008
@@ -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;
}
}
Modified: trunk/plug-ins/psd/psd-image-res-load.h
==============================================================================
--- trunk/plug-ins/psd/psd-image-res-load.h (original)
+++ trunk/plug-ins/psd/psd-image-res-load.h Tue Jan 8 21:02:56 2008
@@ -24,16 +24,18 @@
gint get_image_resource_header (PSDimageres *res_a,
- FILE *f);
-
-gint load_image_resource (PSDimageres *res_a,
- const gint32 image_id,
- PSDimage *img_a,
- FILE *f);
-
-gint load_thumbnail_resource (PSDimageres *res_a,
- const gint32 image_id,
- FILE *f);
+ FILE *f,
+ GError **error);
+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,
+ GError **error);
#endif /* __PSD_IMAGE_RES_LOAD_H__ */
Modified: trunk/plug-ins/psd/psd-layer-res-load.c
==============================================================================
--- trunk/plug-ins/psd/psd-layer-res-load.c (original)
+++ trunk/plug-ins/psd/psd-layer-res-load.c Tue Jan 8 21:02:56 2008
@@ -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,64 +168,69 @@
}
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);
-
- 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);
-
- 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);
-
- else if (memcmp (res_a->key, PSD_LPRP_UNICODE, 4) == 0)
- load_resource_luni (res_a, lyr_a, f);
+ {
+ 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);
+
+ 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_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_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_LPRP_UNICODE, 4) == 0)
+ load_resource_luni (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_LPRP_ID, 4) == 0)
+ load_resource_lyid (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 if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0)
+ load_resource_lsct (res_a, lyr_a, f, error);
- else
- load_resource_unknown (res_a, lyr_a, f);
+ else
+ load_resource_unknown (res_a, lyr_a, f, error);
+ }
/* Layer blocks are null padded to even length */
if (res_a->data_len % 2 == 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;
}
}
Modified: trunk/plug-ins/psd/psd-layer-res-load.h
==============================================================================
--- trunk/plug-ins/psd/psd-layer-res-load.h (original)
+++ trunk/plug-ins/psd/psd-layer-res-load.h Tue Jan 8 21:02:56 2008
@@ -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__ */
Modified: trunk/plug-ins/psd/psd-load.c
==============================================================================
--- trunk/plug-ins/psd/psd-load.c (original)
+++ trunk/plug-ins/psd/psd-load.c Tue Jan 8 21:02:56 2008
@@ -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));
- 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.1);
- 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.2);
- 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.3);
- 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;
- }
+ IFDBG(2) g_debug ("Read layer & mask block");
+ 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);
- 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;
- }
+ IFDBG(2) g_debug ("Read merged image and extra alpha channel block");
+ if (read_merged_image_block (&img_a, f, &error) < 0)
+ goto load_error;
gimp_progress_update (0.5);
- 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;
- }
+ if (image_id < 0)
+ goto load_error;
gimp_progress_update (0.6);
- IFDBG(2) g_debug ("Add color map");
/* ----- Add colour map ----- */
+ IFDBG(2) g_debug ("Add color 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);
- 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;
- }
+ IFDBG(2) g_debug ("Add image resources");
+ if (add_image_resources (image_id, &img_a, f, &error) < 0)
+ goto load_error;
gimp_progress_update (0.8);
- 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;
- }
+ IFDBG(2) g_debug ("Add layers");
+ if (add_layers (image_id, &img_a, lyr_a, f, &error) < 0)
+ goto load_error;
gimp_progress_update (0.9);
- 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;
- }
-
+ IFDBG(2) g_debug ("Add merged image data and extra alpha channels");
+ 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,37 +259,43 @@
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)
- {
- g_message (_("Unsupported PSD file version (< 2.5)")); /* FIXME - image size */
- /* in resource block 1000 */
- return -1; /* don't have PS2 file spec */
- }
-
/* Photoshop CS (version 8) supports 300000 x 300000, but this
is currently larger than GIMP_MAX_IMAGE_SIZE */
- 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->rows < 1 || img_a->rows > GIMP_MAX_IMAGE_SIZE)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Unsupported or invalid image height: %d"),
+ img_a->rows);
+ return -1;
+ }
+
+ 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->color_mode != PSD_BITMAP
&& img_a->color_mode != PSD_GRAYSCALE
@@ -305,8 +303,9 @@
&& 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_undo_disable (image_id);
gimp_image_set_filename (image_id, filename);
+ gimp_image_undo_disable (image_id);
+
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,6 +1645,33 @@
/* 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");
Modified: trunk/plug-ins/psd/psd-thumb-load.c
==============================================================================
--- trunk/plug-ins/psd/psd-thumb-load.c (original)
+++ trunk/plug-ins/psd/psd-thumb-load.c Tue Jan 8 21:02:56 2008
@@ -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_color_mode_block (PSDimage *img_a,
- FILE *f);
-
-static gint read_image_resource_block (PSDimage *img_a,
- FILE *f);
-
-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 read_header_block (PSDimage *img_a,
+ FILE *f,
+ GError **error);
+
+static gint read_color_mode_block (PSDimage *img_a,
+ FILE *f,
+ GError **error);
+
+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 gint add_image_resources (const gint32 image_id,
+ PSDimage *img_a,
+ FILE *f,
+ GError **error);
/* Main file load function */
gint32
@@ -58,11 +61,11 @@
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)
@@ -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;
Modified: trunk/plug-ins/psd/psd-util.c
==============================================================================
--- trunk/plug-ins/psd/psd-util.c (original)
+++ trunk/plug-ins/psd/psd-util.c Tue Jan 8 21:02:56 2008
@@ -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,15 +353,12 @@
/*
* Decode a PackBits chunk.
*/
- int n;
- gchar dat;
- gint32 unpack_left = unpacked_len,
- pack_left = packed_len,
- error_code = 0,
- return_val = 0;
-
- IFDBG(3) g_debug ("Decode packbits");
- IFDBG(3) g_debug ("Packed len %d, unpacked %d",packed_len, unpacked_len);
+ gint n;
+ gchar dat;
+ gint32 unpack_left = unpacked_len;
+ gint32 pack_left = packed_len;
+ gint32 error_code = 0;
+ gint32 return_val = 0;
while (unpack_left > 0 && pack_left > 0)
{
@@ -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;
+}
Modified: trunk/plug-ins/psd/psd-util.h
==============================================================================
--- trunk/plug-ins/psd/psd-util.h (original)
+++ trunk/plug-ins/psd/psd-util.h Tue Jan 8 21:02:56 2008
@@ -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);
+
+/*
+ * 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);
+
+/*
+ * 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);
+
+/*
+ * 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);
+
+/*
+ * 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);
+
+gchar * encode_packbits (const gchar *src,
+ const guint32 unpacked_len,
+ guint16 *packed_len);
-gchar * fread_pascal_string (gint32 *bytes_read,
- gint32 *bytes_written,
- const guint16 pad_len,
- FILE *f);
-
-gint32 fwrite_pascal_string (const gchar *src,
- const guint16 pad_len,
- FILE *f);
-
-gchar * fread_unicode_string (gint32 *bytes_read,
- gint32 *bytes_written,
- const guint16 pad_len,
- FILE *f);
-
-gint32 fwrite_unicode_string (const gchar *src,
- const guint16 pad_len,
- FILE *f);
-
-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);
+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__ */
Modified: trunk/plug-ins/psd/psd.c
==============================================================================
--- trunk/plug-ins/psd/psd.c (original)
+++ trunk/plug-ins/psd/psd.c Tue Jan 8 21:02:56 2008
@@ -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;
}
}
Modified: trunk/plug-ins/psd/psd.h
==============================================================================
--- trunk/plug-ins/psd/psd.h (original)
+++ trunk/plug-ins/psd/psd.h Tue Jan 8 21:02:56 2008
@@ -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 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]