[gimp] Bug 789981 - Wrong layer structure in PSDs with deeply nested layer groups



commit 54ec9373fb2441ac215dbe4200e0d671e9dfa5d0
Author: Ell <ell_se yahoo com>
Date:   Sat Nov 11 17:20:57 2017 -0500

    Bug 789981 - Wrong layer structure in PSDs with deeply nested layer groups
    
    Photoshop CS5 adds support for layer groups whose nesting depth is
    above 5.  The end markers of these groups use an undocumented
    "lsdk" key for their section dividers, rather than the usual
    "lsct".  This caused the PSD plugin to treat them as regular
    layers, resulting in wrong layer-tree structure.
    
    Add support for "lsdk" section dividers upon loading, and also
    generate "lsdk" section dividers upon saving sufficiently-deep
    groups.

 plug-ins/file-psd/psd-layer-res-load.c |    4 +++-
 plug-ins/file-psd/psd-save.c           |   28 +++++++++++++++++++++++++---
 plug-ins/file-psd/psd.h                |    1 +
 3 files changed, 29 insertions(+), 4 deletions(-)
---
diff --git a/plug-ins/file-psd/psd-layer-res-load.c b/plug-ins/file-psd/psd-layer-res-load.c
index c2c6982..58ed570 100644
--- a/plug-ins/file-psd/psd-layer-res-load.c
+++ b/plug-ins/file-psd/psd-layer-res-load.c
@@ -76,6 +76,7 @@
   PSD_LOTH_PATTERN        "Patt"        -       * Patterns (PS6) *
   PSD_LOTH_GRADIENT       "grdm"        -       * Gradient settings (PS6) *
   PSD_LOTH_SECTION        "lsct"     Loaded     * Section divider setting (PS6) (Layer Groups) *
+  PSD_LOTH_SECTION2       "lsdk"     Loaded     * Nested section divider setting (CS5) (Layer Groups) *
   PSD_LOTH_RESTRICT       "brst"        -       * Channel blending restriction setting (PS6) *
   PSD_LOTH_FOREIGN_FX     "ffxi"        -       * Foreign effect ID (PS6) *
   PSD_LOTH_PATT_DATA      "shpa"        -       * Pattern data (PS6) *
@@ -275,7 +276,8 @@ load_layer_resource (PSDlayerres  *res_a,
       else if (memcmp (res_a->key, PSD_LPRP_COLOR, 4) == 0)
         load_resource_lclr (res_a, lyr_a, f, error);
 
-      else if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0)
+      else if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0
+               || memcmp (res_a->key, PSD_LOTH_SECTION2, 4) == 0) /* bug #789981 */
         load_resource_lsct (res_a, lyr_a, f, error);
 
       else if (memcmp (res_a->key, PSD_LFX_FX, 4) == 0)
diff --git a/plug-ins/file-psd/psd-save.c b/plug-ins/file-psd/psd-save.c
index 7057ad0..1182ca4 100644
--- a/plug-ins/file-psd/psd-save.c
+++ b/plug-ins/file-psd/psd-save.c
@@ -877,6 +877,7 @@ save_layer_and_mask (FILE   *fd,
   gint32        ChanSize;               /* Data length for a channel */
   gchar        *layerName;              /* Layer name */
   gint          mask;                   /* Layer mask */
+  gint          depth;                  /* Layer group nesting depth */
 
   glong         eof_pos;                /* Position: End of file */
   glong         ExtraDataPos;           /* Position: Extra data length */
@@ -908,6 +909,8 @@ save_layer_and_mask (FILE   *fd,
   else
     write_gint16 (fd, PSDImageData.nLayers, "Layer structure count");
 
+  depth = 0;
+
   /* Layer records section */
   /* GIMP layers must be written in reverse order */
 
@@ -1082,13 +1085,32 @@ save_layer_and_mask (FILE   *fd,
           size = 12;
 
           if (PSDImageData.lLayers[i].type == PSD_LAYER_TYPE_GROUP_START)
-            type = gimp_item_get_expanded (PSDImageData.lLayers[i].id) ? 1 : 2;
+            {
+              type = gimp_item_get_expanded (PSDImageData.lLayers[i].id) ? 1 : 2;
+
+              depth--;
+            }
           else
-            type = 3;
+            {
+              type = 3;
+
+              depth++;
+            }
 
           blendMode = psd_lmode_layer (PSDImageData.lLayers[i].id, TRUE);
 
-          xfwrite (fd, "8BIMlsct", 8, "section divider");
+          if (type < 3 || depth <= 5)
+            {
+              xfwrite (fd, "8BIMlsct", 8, "section divider");
+            }
+          else
+            {
+              /* layer groups whose nesting depth is above 5 are only supported
+               * by Photoshop CS5 and up, and their end markers use the
+               * (undocumented) "lsdk" key, instead of "lsct".
+               */
+              xfwrite (fd, "8BIMlsdk", 8, "nested section divider");
+            }
           write_gint32 (fd, size, "section divider size");
           write_gint32 (fd, type, "section divider type");
           xfwrite (fd, "8BIM", 4, "section divider blend mode signature");
diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h
index 29c056c..5f3195b 100644
--- a/plug-ins/file-psd/psd.h
+++ b/plug-ins/file-psd/psd.h
@@ -105,6 +105,7 @@
 
 /* Other */
 #define PSD_LOTH_SECTION        "lsct"          /* Section divider setting - Layer groups (PS6) */
+#define PSD_LOTH_SECTION2       "lsdk"          /* Nested section divider setting - Layer groups (CS5) */
 #define PSD_LOTH_PATTERN        "Patt"          /* Patterns (PS6) */
 #define PSD_LOTH_PATTERN_2      "Pat2"          /* Patterns 2nd key (PS6) */
 #define PSD_LOTH_PATTERN_3      "Pat3"          /* Patterns 3rd key (PS6) */


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