[gimp] Bug 791519 - Unexpected selection from channel



commit 3f95dc52d3232cac64283d9514e6d8bcf32df951
Author: Michael Natterer <mitch gimp org>
Date:   Tue Apr 10 02:00:23 2018 +0200

    Bug 791519 - Unexpected selection from channel
    
    Make sure a channel -> selection -> channel roundtrip never does any
    gamma conversion.
    
    In gimp_channel_duplicate(), make sure a created channel has the
    right format, and the right data. Fixes selection -> channel.
    
    When switching off quick mask, call gimp_item_to_selection() instead
    if gimp_selection_load(), the latter was implementing a shortcut which
    is now wrong.
    
    Remove gimp_selection_load() which is now unused.
    
    Unrelated: also remove gimp_selection_save(), it was an obvious
    3-liner used only twice.

 app/actions/select-commands.c   |   14 ++++++++--
 app/core/gimpchannel.c          |   32 +++++++++++++++++++++++
 app/core/gimpimage-quick-mask.c |    6 ++--
 app/core/gimpselection.c        |   53 ---------------------------------------
 app/core/gimpselection.h        |    4 ---
 app/pdb/selection-cmds.c        |   13 ++++++++-
 pdb/groups/selection.pdb        |   13 ++++++++-
 7 files changed, 68 insertions(+), 67 deletions(-)
---
diff --git a/app/actions/select-commands.c b/app/actions/select-commands.c
index 99df95f..acf90f3 100644
--- a/app/actions/select-commands.c
+++ b/app/actions/select-commands.c
@@ -386,12 +386,20 @@ void
 select_save_cmd_callback (GtkAction *action,
                           gpointer   data)
 {
-  GimpImage *image;
-  GtkWidget *widget;
+  GimpImage   *image;
+  GimpChannel *channel;
+  GtkWidget   *widget;
   return_if_no_image (image, data);
   return_if_no_widget (widget, data);
 
-  gimp_selection_save (GIMP_SELECTION (gimp_image_get_mask (image)));
+  channel = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (gimp_image_get_mask (image)),
+                                               GIMP_TYPE_CHANNEL));
+
+  /*  saved selections are not visible by default  */
+  gimp_item_set_visible (GIMP_ITEM (channel), FALSE, FALSE);
+
+  gimp_image_add_channel (image, channel,
+                          GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
   gimp_image_flush (image);
 
   gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (image->gimp)),
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index f78add2..6934c96 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -529,6 +529,38 @@ gimp_channel_duplicate (GimpItem *item,
       new_channel->y1           = channel->y1;
       new_channel->x2           = channel->x2;
       new_channel->y2           = channel->y2;
+
+      if (new_type == GIMP_TYPE_CHANNEL)
+        {
+          /*  8-bit channel hack: make sure pixels between all sorts
+           *  of channels of an image is always copied without any
+           *  gamma conversion
+           */
+          GimpDrawable *new_drawable = GIMP_DRAWABLE (new_item);
+          GimpImage    *image        = gimp_item_get_image (item);
+          const Babl   *format       = gimp_image_get_channel_format (image);
+
+          if (format != gimp_drawable_get_format (new_drawable))
+            {
+              GeglBuffer *new_buffer;
+
+              new_buffer =
+                gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+                                                 gimp_item_get_width  (new_item),
+                                                 gimp_item_get_height (new_item)),
+                                 format);
+
+              gegl_buffer_set_format (new_buffer,
+                                      gimp_drawable_get_format (new_drawable));
+              gegl_buffer_copy (gimp_drawable_get_buffer (new_drawable), NULL,
+                                GEGL_ABYSS_NONE,
+                                new_buffer, NULL);
+              gegl_buffer_set_format (new_buffer, NULL);
+
+              gimp_drawable_set_buffer (new_drawable, FALSE, NULL, new_buffer);
+              g_object_unref (new_buffer);
+            }
+        }
     }
 
   return new_item;
diff --git a/app/core/gimpimage-quick-mask.c b/app/core/gimpimage-quick-mask.c
index babaa91..55ebcaa 100644
--- a/app/core/gimpimage-quick-mask.c
+++ b/app/core/gimpimage-quick-mask.c
@@ -34,7 +34,6 @@
 #include "gimpimage-undo-push.h"
 #include "gimplayer.h"
 #include "gimplayer-floating-selection.h"
-#include "gimpselection.h"
 
 #include "gimp-intl.h"
 
@@ -127,8 +126,9 @@ gimp_image_set_quick_mask_state (GimpImage *image,
               gimp_layer_get_floating_sel_drawable (floating_sel) == GIMP_DRAWABLE (mask))
             floating_sel_anchor (floating_sel);
 
-          gimp_selection_load (GIMP_SELECTION (gimp_image_get_mask (image)),
-                               mask);
+          gimp_item_to_selection (GIMP_ITEM (mask),
+                                  GIMP_CHANNEL_OP_REPLACE,
+                                  TRUE, FALSE, 0.0, 0.0);
           gimp_image_remove_channel (image, mask, TRUE, NULL);
 
           if (! channel_was_active)
diff --git a/app/core/gimpselection.c b/app/core/gimpselection.c
index 4bfe1c2..1f69301 100644
--- a/app/core/gimpselection.c
+++ b/app/core/gimpselection.c
@@ -634,59 +634,6 @@ gimp_selection_resume (GimpSelection *selection)
   return selection->suspend_count;
 }
 
-void
-gimp_selection_load (GimpSelection *selection,
-                     GimpChannel   *channel)
-{
-  gint width;
-  gint height;
-
-  g_return_if_fail (GIMP_IS_SELECTION (selection));
-  g_return_if_fail (GIMP_IS_CHANNEL (channel));
-
-  width  = gimp_item_get_width  (GIMP_ITEM (selection));
-  height = gimp_item_get_height (GIMP_ITEM (selection));
-
-  g_return_if_fail (width  == gimp_item_get_width  (GIMP_ITEM (channel)));
-  g_return_if_fail (height == gimp_item_get_height (GIMP_ITEM (channel)));
-
-  gimp_channel_push_undo (GIMP_CHANNEL (selection),
-                          C_("undo-type", "Channel to Selection"));
-
-  /*  copy the channel to the mask  */
-  gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
-                    NULL,
-                    GEGL_ABYSS_NONE,
-                    gimp_drawable_get_buffer (GIMP_DRAWABLE (selection)),
-                    NULL);
-
-  GIMP_CHANNEL (selection)->bounds_known = FALSE;
-
-  gimp_drawable_update (GIMP_DRAWABLE (selection), 0, 0, -1, -1);
-}
-
-GimpChannel *
-gimp_selection_save (GimpSelection *selection)
-{
-  GimpImage   *image;
-  GimpChannel *new_channel;
-
-  g_return_val_if_fail (GIMP_IS_SELECTION (selection), NULL);
-
-  image = gimp_item_get_image (GIMP_ITEM (selection));
-
-  new_channel = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (selection),
-                                                   GIMP_TYPE_CHANNEL));
-
-  /*  saved selections are not visible by default  */
-  gimp_item_set_visible (GIMP_ITEM (new_channel), FALSE, FALSE);
-
-  gimp_image_add_channel (image, new_channel,
-                          GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
-
-  return new_channel;
-}
-
 GeglBuffer *
 gimp_selection_extract (GimpSelection *selection,
                         GimpPickable  *pickable,
diff --git a/app/core/gimpselection.h b/app/core/gimpselection.h
index f7de1ec..b0936a2 100644
--- a/app/core/gimpselection.h
+++ b/app/core/gimpselection.h
@@ -54,10 +54,6 @@ GimpChannel * gimp_selection_new      (GimpImage     *image,
 gint          gimp_selection_suspend  (GimpSelection *selection);
 gint          gimp_selection_resume   (GimpSelection *selection);
 
-void          gimp_selection_load     (GimpSelection *selection,
-                                       GimpChannel   *channel);
-GimpChannel * gimp_selection_save     (GimpSelection *selection);
-
 GeglBuffer  * gimp_selection_extract  (GimpSelection *selection,
                                        GimpPickable  *pickable,
                                        GimpContext   *context,
diff --git a/app/pdb/selection-cmds.c b/app/pdb/selection-cmds.c
index 4f48e5c..43f9d97 100644
--- a/app/pdb/selection-cmds.c
+++ b/app/pdb/selection-cmds.c
@@ -516,9 +516,18 @@ selection_save_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
-      channel = gimp_selection_save (GIMP_SELECTION (gimp_image_get_mask (image)));
+      channel = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (gimp_image_get_mask (image)),
+                                                   GIMP_TYPE_CHANNEL));
 
-      if (! channel)
+      if (channel)
+        {
+          /*  saved selections are not visible by default  */
+          gimp_item_set_visible (GIMP_ITEM (channel), FALSE, FALSE);
+
+          gimp_image_add_channel (image, channel,
+                                  GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
+        }
+      else
         success = FALSE;
     }
 
diff --git a/pdb/groups/selection.pdb b/pdb/groups/selection.pdb
index 7622726..1d8e33f 100644
--- a/pdb/groups/selection.pdb
+++ b/pdb/groups/selection.pdb
@@ -547,9 +547,18 @@ HELP
         headers => [qw("core/gimpselection.h") ],
        code    => <<'CODE'
 {
-  channel = gimp_selection_save (GIMP_SELECTION (gimp_image_get_mask (image)));
+  channel = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (gimp_image_get_mask (image)),
+                                               GIMP_TYPE_CHANNEL));
 
-  if (! channel)
+  if (channel)
+    {
+      /*  saved selections are not visible by default  */
+      gimp_item_set_visible (GIMP_ITEM (channel), FALSE, FALSE);
+
+      gimp_image_add_channel (image, channel,
+                              GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
+    }
+  else
     success = FALSE;
 }
 CODE


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