[gimp] app: future-proof XCF layer blend/composite props



commit e7d781ff0e40ffc3f85c99156956cfee15262652
Author: Ell <ell_se yahoo com>
Date:   Sun May 21 08:01:39 2017 -0400

    app: future-proof XCF layer blend/composite props
    
    The layer blend space, composite space, and composite mode
    properties have a special AUTO value, which may map to different
    concrete values based on the layer mode.  Make sure we can change
    this mapping in the future, without affecting existing XCFs (saved
    after this commit), by encoding these properties as follows:
    
    When saving an XCF, if the property has a concrete (non-AUTO)
    value, which is always positive, encode it as is.  If the property
    is AUTO, which is always 0, encode it as the negative of the value
    it actually maps to at the time of saving (note that in some cases
    AUTO may map to AUTO, in which case it's encoded as 0).
    
    When loading an XCF, if the encoded property (stored in the file)
    is nonnegative, use it as is.  Otherwise, compare the negative of
    the encoded property to the value AUTO maps to at the time of
    loading.  If the values are equal, set the property to AUTO;
    otherwise, use the concrete value (i.e., the negative of the value
    stored in the XCF).
    
    Note that XCFs saved prior to this commit still load fine, it's
    simply that if we change the AUTO mapping in the future, all their
    AUTO properties will keep being loaded as AUTO, even if the
    resulting concrete values will have changed.

 app/xcf/xcf-load.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++--
 app/xcf/xcf-save.c |   41 +++++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 6 deletions(-)
---
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index b73ecaf..5cc9304 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -55,6 +55,8 @@
 #include "core/gimpselection.h"
 #include "core/gimptemplate.h"
 
+#include "operations/layer-modes/gimp-layer-modes.h"
+
 #include "text/gimptextlayer.h"
 #include "text/gimptextlayer-xcf.h"
 
@@ -1106,30 +1108,81 @@ xcf_load_layer_props (XcfInfo    *info,
 
         case PROP_BLEND_SPACE:
           {
-            GimpLayerColorSpace blend_space;
+            gint32 blend_space;
 
             xcf_read_int32 (info, (guint32 *) &blend_space, 1);
 
+            /* if blend_space < 0 it was originally AUTO, and its negative is
+             * the actual value AUTO used to map to at the time the file was
+             * saved.  if AUTO still maps to the same value, keep using AUTO
+             * for the property; otherwise, use the concrete value.
+             */
+            if (blend_space < 0)
+              {
+                GimpLayerMode mode = gimp_layer_get_mode (*layer);
+
+                blend_space = -blend_space;
+
+                if (blend_space == gimp_layer_mode_get_blend_space (mode))
+                  blend_space = GIMP_LAYER_COLOR_SPACE_AUTO;
+                else
+                  GIMP_LOG (XCF, "BLEND_SPACE: AUTO => %d", blend_space);
+              }
+
             gimp_layer_set_blend_space (*layer, blend_space, FALSE);
           }
           break;
 
         case PROP_COMPOSITE_SPACE:
           {
-            GimpLayerColorSpace composite_space;
+            gint32 composite_space;
 
             xcf_read_int32 (info, (guint32 *) &composite_space, 1);
 
+            /* if composite_space < 0 it was originally AUTO, and its negative
+             * is the actual value AUTO used to map to at the time the file was
+             * saved.  if AUTO still maps to the same value, keep using AUTO
+             * for the property; otherwise, use the concrete value.
+             */
+            if (composite_space < 0)
+              {
+                GimpLayerMode mode = gimp_layer_get_mode (*layer);
+
+                composite_space = -composite_space;
+
+                if (composite_space == gimp_layer_mode_get_composite_space (mode))
+                  composite_space = GIMP_LAYER_COLOR_SPACE_AUTO;
+                else
+                  GIMP_LOG (XCF, "COMPOSITE_SPACE: AUTO => %d", composite_space);
+              }
+
             gimp_layer_set_composite_space (*layer, composite_space, FALSE);
           }
           break;
 
         case PROP_COMPOSITE_MODE:
           {
-            GimpLayerCompositeMode composite_mode;
+            gint32 composite_mode;
 
             xcf_read_int32 (info, (guint32 *) &composite_mode, 1);
 
+            /* if composite_mode < 0 it was originally AUTO, and its negative
+             * is the actual value AUTO used to map to at the time the file was
+             * saved.  if AUTO still maps to the same value, keep using AUTO
+             * for the property; otherwise, use the concrete value.
+             */
+            if (composite_mode < 0)
+              {
+                GimpLayerMode mode = gimp_layer_get_mode (*layer);
+
+                composite_mode = -composite_mode;
+
+                if (composite_mode == gimp_layer_mode_get_composite_mode (mode))
+                  composite_mode = GIMP_LAYER_COMPOSITE_AUTO;
+                else
+                  GIMP_LOG (XCF, "COMPOSITE_MODE: AUTO => %d", composite_mode);
+              }
+
             gimp_layer_set_composite_mode (*layer, composite_mode, FALSE);
           }
           break;
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index eeee9e9..82c384c 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -51,6 +51,8 @@
 #include "core/gimpprogress.h"
 #include "core/gimpsamplepoint.h"
 
+#include "operations/layer-modes/gimp-layer-modes.h"
+
 #include "text/gimptextlayer.h"
 #include "text/gimptextlayer-xcf.h"
 
@@ -518,10 +520,13 @@ xcf_save_layer_props (XcfInfo    *info,
   xcf_check_error (xcf_save_prop (info, image, PROP_MODE, error,
                                   gimp_layer_get_mode (layer)));
   xcf_check_error (xcf_save_prop (info, image, PROP_BLEND_SPACE, error,
+                                  gimp_layer_get_mode (layer),
                                   gimp_layer_get_blend_space (layer)));
   xcf_check_error (xcf_save_prop (info, image, PROP_COMPOSITE_SPACE, error,
+                                  gimp_layer_get_mode (layer),
                                   gimp_layer_get_composite_space (layer)));
   xcf_check_error (xcf_save_prop (info, image, PROP_COMPOSITE_MODE, error,
+                                  gimp_layer_get_mode (layer),
                                   gimp_layer_get_composite_mode (layer)));
   xcf_check_error (xcf_save_prop (info, image, PROP_TATTOO, error,
                                   gimp_item_get_tattoo (GIMP_ITEM (layer))));
@@ -716,7 +721,17 @@ xcf_save_prop (XcfInfo    *info,
 
     case PROP_BLEND_SPACE:
       {
-        gint32 blend_space = va_arg (args, gint32);
+        GimpLayerMode mode        = va_arg (args, GimpLayerMode);
+        gint32        blend_space = va_arg (args, gint32);
+
+        G_STATIC_ASSERT (GIMP_LAYER_COLOR_SPACE_AUTO == 0);
+
+        /* if blend_space is AUTO, save the negative of the actual value AUTO
+         * maps to for the given mode, so that we can correctly load it even if
+         * the mapping changes in the future.
+         */
+        if (blend_space == GIMP_LAYER_COLOR_SPACE_AUTO)
+          blend_space = -gimp_layer_mode_get_blend_space (mode);
 
         size = 4;
 
@@ -729,7 +744,17 @@ xcf_save_prop (XcfInfo    *info,
 
     case PROP_COMPOSITE_SPACE:
       {
-        gint32 composite_space = va_arg (args, gint32);
+        GimpLayerMode mode            = va_arg (args, GimpLayerMode);
+        gint32        composite_space = va_arg (args, gint32);
+
+        G_STATIC_ASSERT (GIMP_LAYER_COLOR_SPACE_AUTO == 0);
+
+        /* if composite_space is AUTO, save the negative of the actual value
+         * AUTO maps to for the given mode, so that we can correctly load it
+         * even if the mapping changes in the future.
+         */
+        if (composite_space == GIMP_LAYER_COLOR_SPACE_AUTO)
+          composite_space = -gimp_layer_mode_get_composite_space (mode);
 
         size = 4;
 
@@ -742,7 +767,17 @@ xcf_save_prop (XcfInfo    *info,
 
     case PROP_COMPOSITE_MODE:
       {
-        gint32 composite_mode = va_arg (args, gint32);
+        GimpLayerMode mode           = va_arg (args, GimpLayerMode);
+        gint32        composite_mode = va_arg (args, gint32);
+
+        G_STATIC_ASSERT (GIMP_LAYER_COMPOSITE_AUTO == 0);
+
+        /* if composite_mode is AUTO, save the negative of the actual value
+         * AUTO maps to for the given mode, so that we can correctly load it
+         * even if the mapping changes in the future.
+         */
+        if (composite_mode == GIMP_LAYER_COMPOSITE_AUTO)
+          composite_mode = -gimp_layer_mode_get_composite_mode (mode);
 
         size = 4;
 


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