[Gimp-developer] [Fwd: Gimp PSD plugin - SEGV when opening files]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi guys and gals,

Could someone with a good collection of .psd files please
test this against the PSD plugin to make sure it doesn't
break anything that was not broken before, and if it
checks out okay commit it to 1.2 and 1.3?  I'm afraid I
don't have the time for GIMPy stuff at the moment to test
it myself.

Cheers,
--Adam
-- 
Adam D. Moss    . ,,^^    adam@xxxxxxxx    http://www.foxbox.org/   co:3

"all cake everywhere has died"
--- 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 ---

[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux