create empty layers of image size instead of skipping empty layers in PSD

2006-03-09  Sven Neumann  <sven@gimp.org>

	* plug-ins/common/psd.c: create empty layers of image size instead
	of skipping empty layers in PSD files (bug #317044).
This commit is contained in:
Sven Neumann
2006-03-09 11:17:02 +00:00
committed by Sven Neumann
parent 28944ec183
commit 37848a53ec
2 changed files with 118 additions and 94 deletions

View File

@ -1,3 +1,8 @@
2006-03-09 Sven Neumann <sven@gimp.org>
* plug-ins/common/psd.c: create empty layers of image size instead
of skipping empty layers in PSD files (bug #317044).
2006-03-09 Sven Neumann <sven@gimp.org> 2006-03-09 Sven Neumann <sven@gimp.org>
* libgimp/gimpexport.c (gimp_export_image): offer the choice to * libgimp/gimpexport.c (gimp_export_image): offer the choice to

View File

@ -1924,18 +1924,24 @@ load_image (const gchar *name)
gint numc; gint numc;
guchar *merged_data = NULL; guchar *merged_data = NULL;
PSDlayer *layer = psd_image.layer + lnum; PSDlayer *layer = psd_image.layer + lnum;
gboolean empty = FALSE;
/* /*
* since ps supports sloppy bounding boxes it is possible to * Since PS supports sloppy bounding boxes it is possible to
* have a 0x0 or Xx0 or 0xY layer. Gimp doesn't support a * 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 * 0x0 layer so we insert an empty layer of image size
* to do something better here. * instead.
*/ */
if ((layer->width == 0) || (layer->height == 0)) if ((layer->width == 0) || (layer->height == 0))
{ {
IFDBG printf ("(bad layer dimensions -- skipping)"); empty = TRUE;
continue;
layer->x = 0;
layer->y = 0;
layer->width = gimp_image_width (image_ID);
layer->height = gimp_image_height (image_ID);
} }
numc = layer->num_channels; numc = layer->num_channels;
IFDBG printf ("Hey, it's a LAYER with %d channels!\n", numc); IFDBG printf ("Hey, it's a LAYER with %d channels!\n", numc);
@ -1945,27 +1951,30 @@ load_image (const gchar *name)
case GIMP_GRAY: case GIMP_GRAY:
{ {
IFDBG printf("It's GRAY.\n"); IFDBG printf("It's GRAY.\n");
if (!psd_layer_has_alpha (layer)) if (! empty)
{ {
merged_data = g_malloc (layer->width * layer->height); if (!psd_layer_has_alpha (layer))
seek_to_and_unpack_pixeldata (fd, lnum, 0); {
memcpy (merged_data, layer->channel[0].data, merged_data = g_malloc (layer->width * layer->height);
layer->width * layer->height); seek_to_and_unpack_pixeldata (fd, lnum, 0);
memcpy (merged_data, layer->channel[0].data,
layer->width * layer->height);
g_free (layer->channel[0].data); g_free (layer->channel[0].data);
} }
else else
{ {
seek_to_and_unpack_pixeldata (fd, lnum, 0); seek_to_and_unpack_pixeldata (fd, lnum, 0);
seek_to_and_unpack_pixeldata (fd, lnum, 1); seek_to_and_unpack_pixeldata (fd, lnum, 1);
merged_data = merged_data = chans_to_GRAYA (layer->channel[1].data,
chans_to_GRAYA (layer->channel[1].data, layer->channel[0].data,
layer->channel[0].data, layer->width *
layer->width * layer->height); layer->height);
g_free (layer->channel[0].data); g_free (layer->channel[0].data);
g_free (layer->channel[1].data); g_free (layer->channel[1].data);
} }
}
layer_ID = gimp_layer_new (image_ID, layer_ID = gimp_layer_new (image_ID,
layer->name, layer->name,
@ -1982,74 +1991,77 @@ load_image (const gchar *name)
{ {
IFDBG printf ("It's RGB, %dx%d.\n", layer->width, IFDBG printf ("It's RGB, %dx%d.\n", layer->width,
layer->height); layer->height);
if (!psd_layer_has_alpha (layer))
{
seek_to_and_unpack_pixeldata (fd, lnum, 0);
seek_to_and_unpack_pixeldata (fd, lnum, 1);
seek_to_and_unpack_pixeldata (fd, lnum, 2);
merged_data =
chans_to_RGB (layer->channel[0].data,
layer->channel[1].data,
layer->channel[2].data,
layer->width *
layer->height);
g_free (layer->channel[0].data); if (! empty)
g_free (layer->channel[1].data); {
g_free (layer->channel[2].data); if (!psd_layer_has_alpha (layer))
IFDBG fprintf (stderr, "YAH0a\n");
}
else
{
seek_to_and_unpack_pixeldata (fd, lnum, 0);
seek_to_and_unpack_pixeldata (fd, lnum, 1);
seek_to_and_unpack_pixeldata (fd, lnum, 2);
seek_to_and_unpack_pixeldata (fd, lnum, 3);
/* Fix for unexpected layer data order for files
* from PS files created by PanoTools. Rather
* than assuming an order, we find the actual order.
*/
red_chan = grn_chan = blu_chan = alpha_chan = -1;
for (ichan = 0; ichan < numc; ichan++)
{ {
switch (psd_image.layer[lnum].channel[ichan].type) seek_to_and_unpack_pixeldata (fd, lnum, 0);
seek_to_and_unpack_pixeldata (fd, lnum, 1);
seek_to_and_unpack_pixeldata (fd, lnum, 2);
merged_data = chans_to_RGB (layer->channel[0].data,
layer->channel[1].data,
layer->channel[2].data,
layer->width *
layer->height);
g_free (layer->channel[0].data);
g_free (layer->channel[1].data);
g_free (layer->channel[2].data);
IFDBG fprintf (stderr, "YAH0a\n");
}
else
{
seek_to_and_unpack_pixeldata (fd, lnum, 0);
seek_to_and_unpack_pixeldata (fd, lnum, 1);
seek_to_and_unpack_pixeldata (fd, lnum, 2);
seek_to_and_unpack_pixeldata (fd, lnum, 3);
/* Fix for unexpected layer data order for files
* from PS files created by PanoTools. Rather
* than assuming an order, we find the actual order.
*/
red_chan = grn_chan = blu_chan = alpha_chan = -1;
for (ichan = 0; ichan < numc; ichan++)
{ {
case 0: red_chan = ichan; break; switch (psd_image.layer[lnum].channel[ichan].type)
case 1: grn_chan = ichan; break; {
case 2: blu_chan = ichan; break; case 0: red_chan = ichan; break;
case -1: alpha_chan = ichan; break; case 1: grn_chan = ichan; break;
case 2: blu_chan = ichan; break;
case -1: alpha_chan = ichan; break;
}
} }
if ((red_chan < 0) ||
(grn_chan < 0) ||
(blu_chan < 0) ||
(alpha_chan < 0))
{
g_message ("Error: Cannot identify required RGBA channels");
gimp_quit ();
break;
}
merged_data =
chans_to_RGBA (psd_image.layer[lnum].channel[red_chan].data,
psd_image.layer[lnum].channel[grn_chan].data,
psd_image.layer[lnum].channel[blu_chan].data,
psd_image.layer[lnum].channel[alpha_chan].data,
psd_image.layer[lnum].width *
psd_image.layer[lnum].height);
g_free (layer->channel[0].data);
g_free (layer->channel[1].data);
g_free (layer->channel[2].data);
g_free (layer->channel[3].data);
IFDBG fprintf (stderr, "YAH0b\n");
} }
}
if ((red_chan < 0) ||
(grn_chan < 0) ||
(blu_chan < 0) ||
(alpha_chan < 0))
{
g_message ("Error: Cannot identify required RGBA channels");
gimp_quit ();
break;
}
merged_data =
chans_to_RGBA (psd_image.layer[lnum].channel[red_chan].data,
psd_image.layer[lnum].channel[grn_chan].data,
psd_image.layer[lnum].channel[blu_chan].data,
psd_image.layer[lnum].channel[alpha_chan].data,
psd_image.layer[lnum].width *
psd_image.layer[lnum].height);
g_free (layer->channel[0].data);
g_free (layer->channel[1].data);
g_free (layer->channel[2].data);
g_free (layer->channel[3].data);
IFDBG fprintf (stderr, "YAH0b\n");
}
IFDBG fprintf (stderr, "YAH1\n"); IFDBG fprintf (stderr, "YAH1\n");
@ -2077,7 +2089,7 @@ load_image (const gchar *name)
IFDBG fprintf (stderr, "YAH3\n"); IFDBG fprintf (stderr, "YAH3\n");
/* Do a layer mask if it exists */ /* Do a layer mask if it exists */
for (iter = 0; iter < layer->num_channels; iter++) for (iter = 0; !empty && iter < layer->num_channels; iter++)
{ {
if (layer->channel[iter].type == -2) /* is mask */ if (layer->channel[iter].type == -2) /* is mask */
{ {
@ -2157,13 +2169,20 @@ load_image (const gchar *name)
drawable->height, drawable->height,
drawable->bpp); drawable->bpp);
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, if (empty)
layer->width, layer->height, {
TRUE, FALSE); gimp_drawable_fill (layer_ID, GIMP_TRANSPARENT_FILL);
gimp_pixel_rgn_set_rect (&pixel_rgn, merged_data, 0, 0, }
layer->width, layer->height); else
{
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
layer->width, layer->height,
TRUE, FALSE);
gimp_pixel_rgn_set_rect (&pixel_rgn, merged_data, 0, 0,
layer->width, layer->height);
IFDBG fprintf(stderr, "YAH6\n"); IFDBG fprintf(stderr, "YAH6\n");
}
gimp_drawable_flush (drawable); gimp_drawable_flush (drawable);
gimp_drawable_detach (drawable); gimp_drawable_detach (drawable);