--- Begin Message ---
Dear Adam D. Moss (PSD plugin maintainer)
Attached is a set of context diffs for a work-around for an issue with psd.c
(PSD Plugin version 2.0.6) and PSD files generated by PanoTools. The problem
was reported by Marco Nierlich <mani@xxxxxxxxxxxxxxx> in the
comp.graphics.apps.gimp newsgroup, and he supplied a sample of a problem image
http://home.nierlich.org/avifile/pano_psd.psd
I think that the possible problems are:
1) no layermask data
2) the resize_mask() function introduces a 1 pixel down-right shift
3) The RGBA channels arrive in an unexpected order
4) some confusion (probably on my part) about 4-layer (RGB + mask) files
and when to add the mask layer
PS: I have not got a full copy Photoshop so I may have broken the opening of
some photoshop files without realising it. I think that having applied the fix,
some files generqated by PhotoShop 6 may get their masks incorrectly set when
loaded into Gimp. It also seems quite possible that PanoTools might be
generating invalid files - but without a full copy of Photoshop I cannot
test this.
--
Regards
Andy Wallis
======================================================
Andy Wallis Email: andy@xxxxxxxxxxxxxx
Shillito and Company Web: http://www.shillito.co.uk
======================================================
*** psd.c.STD Thu Jan 17 10:08:58 2002
--- psd.c Thu Jan 17 10:08:55 2002
***************
*** 130,135 ****
--- 130,141 ----
/* *** USER DEFINES *** */
+ /* set to TRUE if you want Andy Wallis fixes for reading files from PanoTools, FALSE otherwise.
+ * There is probably a better way of fixing the problem. Note that these fixes are not tested
+ * against files from Photoshop apart from a few Photoshop 4.0 LE files and may cause problems
+ * with files from more recent versions of Photoshop */
+ #define AFW_FIXES TRUE
+
/* set to TRUE if you want debugging, FALSE otherwise */
#define PSD_DEBUG FALSE
***************
*** 1068,1073 ****
--- 1074,1090 ----
/* throwchunk(layermaskdatasize, fd, "layer mask data throw");
(*offset) += layermaskdatasize;*/
}
+ #if AFW_FIXES
+ /* If no layermask data - set offset and size from layer data */
+ if(!layermaskdatasize) {
+ IFDBG
+ fprintf(stderr, "Setting layer mask data layer\n");
+ psd_image.layer[layernum].lm_x = psd_image.layer[layernum].x;
+ psd_image.layer[layernum].lm_y = psd_image.layer[layernum].y;
+ psd_image.layer[layernum].lm_width = psd_image.layer[layernum].width;
+ psd_image.layer[layernum].lm_height = psd_image.layer[layernum].height;
+ }
+ #endif
layerrangesdatasize = getglong(fd, "layer ranges data size");
***************
*** 1473,1479 ****
printf("NULL channel - eep!");
return NULL;
}
-
rtn = xmalloc(numpix * 3);
for (i=0; i<numpix; i++)
--- 1490,1495 ----
***************
*** 1693,1700 ****
--- 1709,1722 ----
{
for (x=0; x<dest_w; x++)
{
+ #if AFW_FIXES
+ /* Avoid a 1-pixel border top-left */
+ if ((x>=src_x) && (x<src_x+src_w) &&
+ (y>=src_y) && (y<src_y+src_h))
+ #else
if ((x>src_x) && (x<src_x+src_w) &&
(y>src_y) && (y<src_y+src_h))
+ #endif
{
dest[dest_w * y + x] =
src[src_w * (y-src_y) + (x-src_x)];
***************
*** 1726,1731 ****
--- 1748,1758 ----
gint32 iter;
fpos_t tmpfpos;
+ #if AFW_FIXES
+ gint32 mask_id = -1; /* ie not set */
+ int red_chan, grn_chan, blu_chan, alpha_chan, ichan;
+ #endif
+
IFDBG printf("------- %s ---------------------------------\n",name);
name_buf = g_strdup_printf( _("Loading %s:"), name);
***************
*** 1848,1853 ****
--- 1875,1911 ----
seek_to_and_unpack_pixeldata(fd, lnum, 1);
seek_to_and_unpack_pixeldata(fd, lnum, 2);
seek_to_and_unpack_pixeldata(fd, lnum, 3);
+ #if AFW_FIXES
+ /* 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) {
+ case 0: red_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)) {
+ IFDBG {printf("\nCannot identify required RGBA channels!\n");fflush(stdout);}
+ g_message ("Cannot identify required RGBA channels\n");
+ 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);
+ #else
merged_data =
chans_to_RGBA (psd_image.layer[lnum].channel[1].data,
psd_image.layer[lnum].channel[2].data,
***************
*** 1855,1861 ****
psd_image.layer[lnum].channel[0].data,
psd_image.layer[lnum].width *
psd_image.layer[lnum].height);
!
if (psd_image.layer[lnum].channel[0].data)
g_free(psd_image.layer[lnum].channel[0].data);
if (psd_image.layer[lnum].channel[1].data)
--- 1913,1919 ----
psd_image.layer[lnum].channel[0].data,
psd_image.layer[lnum].width *
psd_image.layer[lnum].height);
! #endif
if (psd_image.layer[lnum].channel[0].data)
g_free(psd_image.layer[lnum].channel[0].data);
if (psd_image.layer[lnum].channel[1].data)
***************
*** 1872,1877 ****
--- 1930,1946 ----
IFDBG
fprintf(stderr, "YAH1\n");
+ #if AFW_FIXES
+ /* This is a fix for files that contain 4-layers (RGB + mask). The original code created a GIMP_RGBA_IMAGE for such files */
+
+ layer_ID = gimp_layer_new (image_ID,
+ psd_image.layer[lnum].name,
+ psd_image.layer[lnum].width,
+ psd_image.layer[lnum].height,
+ psd_layer_has_alpha(&psd_image.layer[lnum]) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE,
+ (100.0*(double)psd_image.layer[lnum].opacity)/255.0,
+ psd_lmode_to_gimp_lmode(psd_image.layer[lnum].blendkey));
+ #else
layer_ID = gimp_layer_new (image_ID,
psd_image.layer[lnum].name,
psd_image.layer[lnum].width,
***************
*** 1879,1885 ****
(numc==3) ? GIMP_RGB_IMAGE : GIMP_RGBA_IMAGE,
(100.0*(double)psd_image.layer[lnum].opacity)/255.0,
psd_lmode_to_gimp_lmode(psd_image.layer[lnum].blendkey));
!
IFDBG
fprintf(stderr, "YAH2\n");
--- 1948,1954 ----
(numc==3) ? GIMP_RGB_IMAGE : GIMP_RGBA_IMAGE,
(100.0*(double)psd_image.layer[lnum].opacity)/255.0,
psd_lmode_to_gimp_lmode(psd_image.layer[lnum].blendkey));
! #endif
IFDBG
fprintf(stderr, "YAH2\n");
***************
*** 1902,1908 ****
--- 1971,1979 ----
{
if (psd_image.layer[lnum].channel[iter].type == -2) /* is mask */
{
+ #if !AFW_FIXES
gint32 mask_id;
+ #endif
guchar* lm_data;
IFDBG
***************
*** 1930,1940 ****
g_free(psd_image.layer[lnum].channel[iter].data);
/* give it to GIMP */
mask_id = gimp_layer_create_mask(layer_ID, 0);
gimp_image_add_layer_mask(image_ID, layer_ID, mask_id);
!
drawable = gimp_drawable_get (mask_id);
!
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0,
psd_image.layer[lnum].width,
--- 2001,2013 ----
g_free(psd_image.layer[lnum].channel[iter].data);
/* give it to GIMP */
+
mask_id = gimp_layer_create_mask(layer_ID, 0);
+ #if !AFW_FIXES
gimp_image_add_layer_mask(image_ID, layer_ID, mask_id);
! #endif
drawable = gimp_drawable_get (mask_id);
!
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0,
psd_image.layer[lnum].width,
***************
*** 1978,1984 ****
psd_image.layer[lnum].width,
psd_image.layer[lnum].height,
TRUE, FALSE);
-
gimp_pixel_rgn_set_rect (&pixel_rgn,
merged_data,
0, 0,
--- 2051,2056 ----
***************
*** 1988,1993 ****
--- 2060,2072 ----
IFDBG
fprintf(stderr, "YAH6\n");
+ #if AFW_FIXES
+ /* Delay adding layer mask until now */
+ if(mask_id != -1) {
+ gimp_layer_add_alpha(layer_ID);
+ gimp_image_add_layer_mask(image_ID, layer_ID, mask_id);
+ }
+ #endif
gimp_drawable_flush (drawable);
gimp_drawable_detach (drawable);
drawable = NULL;
--- End Message ---