[gimp] app: cleanup in GimpImageMap



commit 6eba4c716b41f4d43c358f081da7c1424f0d1499
Author: Michael Natterer <mitch gimp org>
Date:   Wed Jun 25 18:16:52 2014 +0200

    app: cleanup in GimpImageMap
    
    - don't allow to create a GimpImageMap of an operation without output
    - make "region", "mode" and "gamma-hack" settable on a map that
      already has a graph
    - don't insert a useless "over" if the operation is a source op
    - do the gamma-hack always on formats with alpha, so we don't lose
      intermediate alpha results on source ops
    - simplify graph connection a lot
    - in GimpImageMap tool, don't recreate the map when reconfiguring
      "region" and "gamma-hack"

 app/core/gimpimagemap.c      |  263 ++++++++++++++++++++++--------------------
 app/core/gimpimagemap.h      |    6 +-
 app/tools/gimpimagemaptool.c |   18 +---
 3 files changed, 142 insertions(+), 145 deletions(-)
---
diff --git a/app/core/gimpimagemap.c b/app/core/gimpimagemap.c
index d3d947b..d6f72fe 100644
--- a/app/core/gimpimagemap.c
+++ b/app/core/gimpimagemap.c
@@ -86,6 +86,10 @@ struct _GimpImageMap
 static void       gimp_image_map_dispose         (GObject             *object);
 static void       gimp_image_map_finalize        (GObject             *object);
 
+static void       gimp_image_map_sync_region     (GimpImageMap        *image_map);
+static void       gimp_image_map_sync_mode       (GimpImageMap        *image_map);
+static void       gimp_image_map_sync_gamma_hack (GimpImageMap        *image_map);
+
 static gboolean   gimp_image_map_is_filtering    (GimpImageMap        *image_map);
 static gboolean   gimp_image_map_add_filter      (GimpImageMap        *image_map);
 static gboolean   gimp_image_map_remove_filter   (GimpImageMap        *image_map);
@@ -194,6 +198,7 @@ gimp_image_map_new (GimpDrawable *drawable,
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (GEGL_IS_NODE (operation), NULL);
+  g_return_val_if_fail (gegl_node_has_pad (operation, "output"), NULL);
 
   image_map = g_object_new (GIMP_TYPE_IMAGE_MAP, NULL);
 
@@ -214,16 +219,12 @@ gimp_image_map_set_region (GimpImageMap       *image_map,
 {
   g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
 
-  image_map->region = region;
-}
-
-void
-gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
-                               gboolean      gamma_hack)
-{
-  g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
+  if (region != image_map->region)
+    {
+      image_map->region = region;
 
-  image_map->gamma_hack = gamma_hack;
+      gimp_image_map_sync_region (image_map);
+    }
 }
 
 void
@@ -239,10 +240,21 @@ gimp_image_map_set_mode (GimpImageMap         *image_map,
       image_map->opacity    = opacity;
       image_map->paint_mode = paint_mode;
 
-      if (image_map->applicator)
-        gimp_applicator_set_mode (image_map->applicator,
-                                  image_map->opacity,
-                                  image_map->paint_mode);
+      gimp_image_map_sync_mode (image_map);
+    }
+}
+
+void
+gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
+                               gboolean      gamma_hack)
+{
+  g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
+
+  if (gamma_hack != image_map->gamma_hack)
+    {
+      image_map->gamma_hack = gamma_hack;
+
+      gimp_image_map_sync_gamma_hack (image_map);
     }
 }
 
@@ -300,8 +312,6 @@ gimp_image_map_apply (GimpImageMap        *image_map,
   if (! image_map->filter)
     {
       GeglNode *filter_node;
-      GeglNode *filter_output;
-      GeglNode *input;
 
       image_map->filter = gimp_filter_new (image_map->undo_desc);
       gimp_viewable_set_icon_name (GIMP_VIEWABLE (image_map->filter),
@@ -326,131 +336,35 @@ gimp_image_map_apply (GimpImageMap        *image_map,
                                              "operation", "gegl:crop",
                                              NULL);
 
-      if (image_map->gamma_hack)
-        {
-          const Babl *drawable_format;
-          const Babl *cast_format;
+      image_map->cast_before = gegl_node_new_child (filter_node,
+                                                    "operation", "gegl:nop",
+                                                    NULL);
+      image_map->cast_after = gegl_node_new_child (filter_node,
+                                                   "operation", "gegl:nop",
+                                                   NULL);
 
-          drawable_format = gimp_drawable_get_format (image_map->drawable);
+      gimp_image_map_sync_region (image_map);
+      gimp_image_map_sync_mode (image_map);
+      gimp_image_map_sync_gamma_hack (image_map);
 
-          cast_format =
-            gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
-                              gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
-                                                   ! gimp_babl_format_get_linear (drawable_format)),
-                              babl_format_has_alpha (drawable_format));
-
-          image_map->cast_before = gegl_node_new_child (filter_node,
-                                                        "operation",     "gegl:cast-format",
-                                                        "input-format",  drawable_format,
-                                                        "output-format", cast_format,
-                                                        NULL);
-          image_map->cast_after = gegl_node_new_child (filter_node,
-                                                       "operation",     "gegl:cast-format",
-                                                       "input-format",  cast_format,
-                                                       "output-format", drawable_format,
-                                                        NULL);
-        }
-      else
+      if (gegl_node_has_pad (image_map->operation, "input"))
         {
-          image_map->cast_before = gegl_node_new_child (filter_node,
-                                                        "operation", "gegl:nop",
-                                                        NULL);
-          image_map->cast_after = gegl_node_new_child (filter_node,
-                                                       "operation", "gegl:nop",
-                                                       NULL);
-        }
-
-      input = gegl_node_get_input_proxy (filter_node, "input");
+          GeglNode *input = gegl_node_get_input_proxy (filter_node, "input");
 
-      if (gegl_node_has_pad (image_map->operation, "input") &&
-          gegl_node_has_pad (image_map->operation, "output"))
-        {
-          /*  if there are input and output pads we probably have a
-           *  filter OP, connect it on both ends.
-           */
           gegl_node_link_many (input,
                                image_map->translate,
                                image_map->crop,
                                image_map->cast_before,
                                image_map->operation,
-                               image_map->cast_after,
                                NULL);
-
-          filter_output = image_map->cast_after;
         }
-      else if (gegl_node_has_pad (image_map->operation, "output"))
-        {
-          /*  if there is only an output pad we probably have a
-           *  source OP, blend its result on top of the original
-           *  pixels.
-           */
-          GeglNode *over = gegl_node_new_child (filter_node,
-                                                "operation", "gegl:over",
-                                                NULL);
-
-          gegl_node_link_many (input,
-                               image_map->translate,
-                               image_map->crop,
-                               over,
-                               NULL);
-
-          gegl_node_link_many (image_map->operation,
-                               image_map->cast_after,
-                               NULL);
 
-          gegl_node_connect_to (image_map->cast_after, "output",
-                                over,                  "aux");
-
-          filter_output = over;
-        }
-      else
-        {
-          /* otherwise we just construct a silly nop pipleline
-           */
-          gegl_node_link_many (input,
-                               image_map->translate,
-                               image_map->crop,
-                               image_map->cast_before,
-                               image_map->cast_after,
-                               NULL);
+      gegl_node_link_many (image_map->operation,
+                           image_map->cast_after,
+                           NULL);
 
-          filter_output = image_map->cast_after;
-        }
-
-      gegl_node_connect_to (filter_output, "output",
-                            filter_node,   "aux");
-
-      gimp_applicator_set_mode (image_map->applicator,
-                                image_map->opacity,
-                                image_map->paint_mode);
-    }
-
-  if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
-    {
-      gegl_node_set (image_map->translate,
-                     "x", (gdouble) -image_map->filter_area.x,
-                     "y", (gdouble) -image_map->filter_area.y,
-                     NULL);
-
-      gegl_node_set (image_map->crop,
-                     "width",  (gdouble) image_map->filter_area.width,
-                     "height", (gdouble) image_map->filter_area.height,
-                     NULL);
-
-      gimp_applicator_set_apply_offset (image_map->applicator,
-                                        image_map->filter_area.x,
-                                        image_map->filter_area.y);
-    }
-  else
-    {
-      GimpItem *item   = GIMP_ITEM (image_map->drawable);
-      gdouble   width  = gimp_item_get_width (item);
-      gdouble   height = gimp_item_get_height (item);
-
-      gegl_node_set (image_map->crop,
-                     "width",  width,
-                     "height", height,
-                     NULL);
+      gegl_node_connect_to (image_map->cast_after, "output",
+                            filter_node,           "aux");
     }
 
   active_mask = gimp_drawable_get_active_mask (image_map->drawable);
@@ -522,6 +436,101 @@ gimp_image_map_abort (GimpImageMap *image_map)
 
 /*  private functions  */
 
+static void
+gimp_image_map_sync_region (GimpImageMap *image_map)
+{
+  if (image_map->applicator)
+    {
+      if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
+        {
+          gegl_node_set (image_map->translate,
+                         "x", (gdouble) -image_map->filter_area.x,
+                         "y", (gdouble) -image_map->filter_area.y,
+                         NULL);
+
+          gegl_node_set (image_map->crop,
+                         "width",  (gdouble) image_map->filter_area.width,
+                         "height", (gdouble) image_map->filter_area.height,
+                         NULL);
+
+          gimp_applicator_set_apply_offset (image_map->applicator,
+                                            image_map->filter_area.x,
+                                            image_map->filter_area.y);
+        }
+      else
+        {
+          GimpItem *item   = GIMP_ITEM (image_map->drawable);
+          gdouble   width  = gimp_item_get_width (item);
+          gdouble   height = gimp_item_get_height (item);
+
+          gegl_node_set (image_map->translate,
+                         "x", (gdouble) 0.0,
+                         "y", (gdouble) 0.0,
+                         NULL);
+
+          gegl_node_set (image_map->crop,
+                         "width",  width,
+                         "height", height,
+                         NULL);
+
+          gimp_applicator_set_apply_offset (image_map->applicator, 0, 0);
+        }
+    }
+}
+
+static void
+gimp_image_map_sync_mode (GimpImageMap *image_map)
+{
+  if (image_map->applicator)
+    gimp_applicator_set_mode (image_map->applicator,
+                              image_map->opacity,
+                              image_map->paint_mode);
+}
+
+static void
+gimp_image_map_sync_gamma_hack (GimpImageMap *image_map)
+{
+  if (image_map->applicator)
+    {
+      if (image_map->gamma_hack)
+        {
+          const Babl *drawable_format;
+          const Babl *cast_format;
+
+          drawable_format =
+            gimp_drawable_get_format_with_alpha (image_map->drawable);
+
+          cast_format =
+            gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
+                              gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
+                                                   ! gimp_babl_format_get_linear (drawable_format)),
+                              TRUE);
+
+          gegl_node_set (image_map->cast_before,
+                         "operation",     "gegl:cast-format",
+                         "input-format",  drawable_format,
+                         "output-format", cast_format,
+                         NULL);
+
+          gegl_node_set (image_map->cast_after,
+                         "operation",     "gegl:cast-format",
+                         "input-format",  cast_format,
+                         "output-format", drawable_format,
+                         NULL);
+        }
+      else
+        {
+          gegl_node_set (image_map->cast_before,
+                         "operation", "gegl:nop",
+                         NULL);
+
+          gegl_node_set (image_map->cast_after,
+                         "operation", "gegl:nop",
+                         NULL);
+        }
+    }
+}
+
 static gboolean
 gimp_image_map_is_filtering (GimpImageMap *image_map)
 {
diff --git a/app/core/gimpimagemap.h b/app/core/gimpimagemap.h
index d06ae52..ed69d08 100644
--- a/app/core/gimpimagemap.h
+++ b/app/core/gimpimagemap.h
@@ -56,13 +56,13 @@ GimpImageMap * gimp_image_map_new        (GimpDrawable         *drawable,
 
 void           gimp_image_map_set_region (GimpImageMap         *image_map,
                                           GimpImageMapRegion    region);
-void       gimp_image_map_set_gamma_hack (GimpImageMap         *image_map,
-                                          gboolean              gamma_hack);
-
 void           gimp_image_map_set_mode   (GimpImageMap         *image_map,
                                           gdouble               opacity,
                                           GimpLayerModeEffects  paint_mode);
 
+void       gimp_image_map_set_gamma_hack (GimpImageMap         *image_map,
+                                          gboolean              gamma_hack);
+
 void           gimp_image_map_apply      (GimpImageMap         *image_map,
                                           const GeglRectangle  *area);
 
diff --git a/app/tools/gimpimagemaptool.c b/app/tools/gimpimagemaptool.c
index 438f263..fedcdc1 100644
--- a/app/tools/gimpimagemaptool.c
+++ b/app/tools/gimpimagemaptool.c
@@ -277,16 +277,9 @@ gamma_hack (GtkToggleButton  *button,
 {
   if (image_map_tool->image_map)
     {
-      GimpTool *tool = GIMP_TOOL (image_map_tool);
-
-      gimp_tool_control_push_preserve (tool->control, TRUE);
-
-      gimp_image_map_tool_create_map (image_map_tool);
       gimp_image_map_set_gamma_hack (image_map_tool->image_map,
                                      gtk_toggle_button_get_active (button));
       gimp_image_map_tool_preview (image_map_tool);
-
-      gimp_tool_control_pop_preserve (tool->control);
     }
 }
 
@@ -523,13 +516,12 @@ gimp_image_map_tool_options_notify (GimpTool         *tool,
                                     GimpToolOptions  *options,
                                     const GParamSpec *pspec)
 {
-  GimpImageMapTool *image_map_tool = GIMP_IMAGE_MAP_TOOL (tool);
+  GimpImageMapTool    *image_map_tool = GIMP_IMAGE_MAP_TOOL (tool);
+  GimpImageMapOptions *im_options     = GIMP_IMAGE_MAP_OPTIONS (options);
 
   if (! strcmp (pspec->name, "preview") &&
       image_map_tool->image_map)
     {
-      GimpImageMapOptions *im_options = GIMP_IMAGE_MAP_OPTIONS (options);
-
       if (im_options->preview)
         {
           gimp_tool_control_push_preserve (tool->control, TRUE);
@@ -550,12 +542,8 @@ gimp_image_map_tool_options_notify (GimpTool         *tool,
   else if (! strcmp (pspec->name, "region") &&
            image_map_tool->image_map)
     {
-      gimp_tool_control_push_preserve (tool->control, TRUE);
-
-      gimp_image_map_tool_create_map (image_map_tool);
+      gimp_image_map_set_region (image_map_tool->image_map, im_options->region);
       gimp_image_map_tool_preview (image_map_tool);
-
-      gimp_tool_control_pop_preserve (tool->control);
     }
 }
 


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