2004-02-12 / v3.0.14 / Adam D. Moss Fix a twisted utf8-obsessive bug

*  2004-02-12 / v3.0.14 / Adam D. Moss
 *       Fix a twisted utf8-obsessive bug diagnosed by
 *       Piotr Krysiuk <KrysiukP@prokom.pl>
 *
 *  2004-01-06 / v3.0.13 / Adam D. Moss
 *       Disable one of the PanoTools fixes by default, since it causes
 *       regressions in some ordinary PSD file loading.
 *
 *  2004-01-06 / v3.0.12 / Adam D. Moss
 *       Try to avoid 0-sized drawables (including channels) in all
 *       circumstances under GIMP 2.
 *
 *  2004-01-01 / v3.0.11 / Daniel Rogers <dsrogers@phaseveloctiy.org>
 *       GIMP crashes on 0x0 layers, so we skip them.
This commit is contained in:
Adam D. Moss 2004-02-12 15:24:11 +00:00
parent 8091f46f71
commit c8fa27daa6
2 changed files with 107 additions and 47 deletions

View file

@ -1,3 +1,13 @@
2004-02-12 Adam D. Moss <adam@gimp.org>
* plug-ins/common/psd.c:
- Disable one of the PanoTools fixes by default, since it causes
regressions in some ordinary PSD file loading.
- Fix a twisted utf8-obsessive bug diagnosed by Piotr Krysiuk
- Fix another one...
- Fix from Daniel Rogers: GIMP crashes on 0x0 layers, so we skip them.
- Also try to avoid 0-sized drawables (including channels)
2004-02-12 Michael Natterer <mitch@gimp.org>
* app/core/gimpimage-convert.c (gimp_image_convert): call

View file

@ -1,15 +1,15 @@
/*
* PSD Plugin version 3.0.10
* PSD Plugin version 3.0.14
* This GIMP plug-in is designed to load Adobe Photoshop(tm) files (.PSD)
*
* Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
*
* If this plug-in fails to load a file which you think it should,
* please tell me what seemed to go wrong, and anything you know
* about the image you tried to load. Please don't send big PSD
* files to me without asking first.
* please file a Bugzilla bug describing what seemed to go wrong,
* and anything you know about the image you tried to load. Attach a
* problematic PSD file to the bug report.
*
* Copyright (C) 1997-2003 Adam D. Moss
* Copyright (C) 1997-2004 Adam D. Moss
* Copyright (C) 1996 Torsten Martinsen
*
* This program is free software; you can redistribute it and/or modify
@ -35,6 +35,21 @@
/*
* Revision history:
*
* 2004-02-12 / v3.0.14 / Adam D. Moss
* Fix a twisted utf8-obsessive bug diagnosed by
* Piotr Krysiuk <KrysiukP@prokom.pl>
*
* 2004-01-06 / v3.0.13 / Adam D. Moss
* Disable one of the PanoTools fixes by default, since it causes
* regressions in some ordinary PSD file loading.
*
* 2004-01-06 / v3.0.12 / Adam D. Moss
* Try to avoid 0-sized drawables (including channels) in all
* circumstances under GIMP 2.
*
* 2004-01-01 / v3.0.11 / Daniel Rogers <dsrogers@phaseveloctiy.org>
* GIMP crashes on 0x0 layers, so we skip them.
*
* 2003-11-27 / v3.0.10 / Adam D. Moss
* GIMP 1.3/2.0 needs its layer/channel names to be UTF8 or it
* fails wackily, so convert the strings from the PSD file to
@ -154,6 +169,11 @@
/* the max number of channels that this plugin should let a layer have */
#define MAX_CHANNELS 30
/* set to TRUE to allow a fix for transparency in PSD files
generated by PanoTools that unfortunately causes regressions
in some other ordinary files saved by Photoshop. */
#define PANOTOOLS_FIX FALSE
/* *** END OF USER DEFINES *** */
@ -619,7 +639,6 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size)
do
{
guchar slen;
gchar* sname;
slen = getguchar (fd, "alpha channel name length");
(*offset)++;
@ -636,41 +655,31 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size)
if (slen)
{
sname = getstring(slen, fd, "alpha channel name");
guint32 alpha_name_len;
gchar* sname = getstring(slen, fd, "alpha channel name");
alpha_name_len = strlen(sname);
(*offset) += alpha_name_len;
remaining -= alpha_name_len;
sname = sanitise_string(sname);
psd_image.aux_channel[psd_image.num_aux_channels].name =
sname;
IFDBG printf("\t\t\tname: \"%s\"\n",
psd_image.aux_channel[psd_image.num_aux_channels].name);
}
else
{
psd_image.aux_channel[psd_image.num_aux_channels].name =
NULL;
}
if (psd_image.aux_channel[psd_image.num_aux_channels].name
== NULL)
{
IFDBG
{printf("\t\t\tNull channel name %d.\n",
psd_image.num_aux_channels);fflush(stdout);}
}
if (psd_image.aux_channel[psd_image.num_aux_channels].name)
{
guint32 alpha_name_len;
alpha_name_len =
strlen(psd_image.aux_channel[psd_image.num_aux_channels].name);
IFDBG printf("\t\t\tname: \"%s\"\n",
psd_image.aux_channel[psd_image.num_aux_channels].name);
(*offset) += alpha_name_len;
remaining -= alpha_name_len;
}
psd_image.num_aux_channels++;
if (psd_image.num_aux_channels > MAX_CHANNELS)
@ -964,23 +973,28 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
IFDBG printf("\t\t\t\tNumber of channels: %d\n",
(int)layer->num_channels);
layer->channel = g_new(PSDchannel, layer->num_channels);
for (i = 0; i < layer->num_channels; i++)
if (layer->num_channels)
{
PSDchannel *channel = layer->channel + i;
/* table 11-13 */
IFDBG printf("\t\t\t\tCHANNEL LENGTH INFO (%d)\n", i);
channel->type = getgshort(fd, "channel id");
(*offset)+=2;
IFDBG printf("\t\t\t\t\tChannel TYPE: %d\n", channel->type);
channel->compressedsize = getglong(fd, "channeldatalength");
(*offset)+=4;
IFDBG printf("\t\t\t\t\tChannel Data Length: %d\n",
channel->compressedsize);
layer->channel = g_new(PSDchannel, layer->num_channels);
for (i = 0; i < layer->num_channels; i++)
{
PSDchannel *channel = layer->channel + i;
/* table 11-13 */
IFDBG printf("\t\t\t\tCHANNEL LENGTH INFO (%d)\n", i);
channel->type = getgshort(fd, "channel id");
(*offset)+=2;
IFDBG printf("\t\t\t\t\tChannel TYPE: %d\n", channel->type);
channel->compressedsize = getglong(fd, "channeldatalength");
(*offset)+=4;
IFDBG printf("\t\t\t\t\tChannel Data Length: %d\n",
channel->compressedsize);
}
} else {
IFDBG printf("\t\t\t\tOo-er, layer has no channels. Hmm.\n");
}
xfread(fd, sig, 4, "layer blend sig");
@ -988,6 +1002,7 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
if (strncmp(sig, "8BIM", 4)!=0)
{
IFDBG printf("\t\t\t(layer blend signature '%c%c%c%c' is incorrect: quitting)\n", sig[0], sig[1], sig[2], sig[3]);
g_message ("Error: layer blend signature is incorrect. :-(");
gimp_quit();
}
@ -1076,13 +1091,13 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
}
layer->name = getpascalstring(fd, "layer name");
layer->name = sanitise_string(layer->name);
(*offset)++;
if (layer->name)
{
(*offset) += strlen(layer->name);
IFDBG printf("\t\t\t\t\t\tLAYER NAME: '%s'\n", layer->name);
layer->name = sanitise_string(layer->name);
}
else
{
@ -1415,6 +1430,7 @@ do_image_resources(FILE *fd)
}
#if PANOTOOLS_FIX
/* Convert RGB data to RGBA data */
static guchar*
RGB_to_RGBA (const guchar* rgb_data, gint numpix)
@ -1441,6 +1457,7 @@ RGB_to_RGBA (const guchar* rgb_data, gint numpix)
return rtn;
}
#endif /* PANOTOOLS_FIX */
static guchar*
@ -1565,6 +1582,13 @@ void extract_data_and_channels(guchar* src, gint gimpstep, gint psstep,
IFDBG printf("Extracting primary channel data (%d channels)\n"
"\tand %d auxiliary channels.\n", gimpstep, psstep-gimpstep);
/* gimp doesn't like 0 width/height drawables. */
if ((width == 0) || (height == 0))
{
IFDBG printf("(bad channel dimensions -- skipping)");
return;
}
primary_data = g_malloc(width * height * gimpstep);
{
int pix,chan;
@ -1602,7 +1626,6 @@ void extract_data_and_channels(guchar* src, gint gimpstep, gint psstep,
{
aux_data [pix] = src [pix * psstep + chan];
}
channel_ID = gimp_channel_new (image_ID,
psd_image.aux_channel[chan-gimpstep].name,
width, height,
@ -1637,6 +1660,13 @@ extract_channels(guchar* src, gint num_wanted, gint psstep,
IFDBG printf("Extracting %d/%d auxiliary channels.\n", num_wanted, psstep);
/* gimp doesn't like 0 width/height drawables. */
if ((width == 0) || (height == 0))
{
IFDBG printf("(bad channel dimensions -- skipping)");
return;
}
aux_data = g_malloc(width * height);
{
int pix, chan;
@ -1775,9 +1805,20 @@ load_image (const gchar *name)
gint numc;
guchar* merged_data = NULL;
PSDlayer *layer = psd_image.layer + lnum;
/*
* since ps supports sloppy bounding boxes it is possible to
* have a 0x0 or Xx0 or 0xY layer. Gimp doesn't support a
* 0x0 layer so we will just skip these. We might be able
* to do something better here.
*/
if ((layer->width == 0) || (layer->height == 0))
{
IFDBG printf("(bad layer dimensions -- skipping)");
continue;
}
numc = layer->num_channels;
IFDBG printf("Hey, it's a LAYER with %d channels!\n", numc);
switch (gimagetype)
@ -1952,6 +1993,7 @@ load_image (const gchar *name)
/* give it to GIMP */
mask_id = gimp_layer_create_mask(layer_ID, 0);
#if PANOTOOLS_FIX
/* Convert the layer RGB data (not the mask) to RGBA */
tmp = merged_data;
merged_data = RGB_to_RGBA (tmp,
@ -1964,7 +2006,7 @@ load_image (const gchar *name)
/* Add layer mask */
gimp_layer_add_mask (layer_ID, mask_id);
#endif /* PANOTOOLS_FIX */
drawable = gimp_drawable_get (mask_id);
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
@ -2106,6 +2148,14 @@ load_image (const gchar *name)
if (!want_aux)
{
/* gimp doesn't like 0 width/height drawables. */
if ((PSDheader.columns == 0) || (PSDheader.rows == 0))
{
IFDBG printf("(bad psd2-style image dimensions -- skipping)");
image_ID = -1;
goto finish_up;
}
image_ID = gimp_image_new (PSDheader.columns, PSDheader.rows,
psd_type_to_gimp_base_type(imagetype));
gimp_image_set_filename (image_ID, name);