[gimp] Bug 679387 - Add "select pixels with this color" from colormap



commit 37a3d423e99bacb1d146cf59f220589b31b47263
Author: Michael Natterer <mitch gimp org>
Date:   Wed Aug 26 01:06:34 2015 +0200

    Bug 679387 - Add "select pixels with this color" from colormap
    
    Add gimp_gegl_index_to_mask() and gimp_channel_select_by_index() and
    around it actions, callbacks and GUI in the colormap dialog.

 app/actions/colormap-actions.c   |   68 +++++++++++++++++++++++++++++++++-----
 app/actions/colormap-commands.c  |   22 ++++++++++++
 app/actions/colormap-commands.h  |   13 ++++---
 app/core/gimpchannel-select.c    |   40 ++++++++++++++++++++++
 app/core/gimpchannel-select.h    |    7 ++++
 app/gegl/gimp-gegl-loops.c       |   37 ++++++++++++++++++++
 app/gegl/gimp-gegl-loops.h       |    7 ++++
 app/widgets/gimpcolormapeditor.c |   17 +++++++++
 app/widgets/gimphelp-ids.h       |    4 ++
 menus/colormap-menu.xml          |    5 +++
 10 files changed, 206 insertions(+), 14 deletions(-)
---
diff --git a/app/actions/colormap-actions.c b/app/actions/colormap-actions.c
index b814548..5e1f860 100644
--- a/app/actions/colormap-actions.c
+++ b/app/actions/colormap-actions.c
@@ -25,6 +25,7 @@
 #include "actions-types.h"
 
 #include "core/gimpcontext.h"
+#include "core/gimpdrawable.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-colormap.h"
 
@@ -66,6 +67,32 @@ static const GimpEnumActionEntry colormap_add_color_actions[] =
     GIMP_HELP_INDEXED_PALETTE_ADD }
 };
 
+static const GimpEnumActionEntry colormap_to_selection_actions[] =
+{
+  { "colormap-selection-replace", GIMP_STOCK_SELECTION_REPLACE,
+    NC_("colormap-action", "_Select this Color"), NULL,
+    NC_("colormap-action", "Select all pixels with this color"),
+    GIMP_CHANNEL_OP_REPLACE, FALSE,
+    GIMP_HELP_INDEXED_PALETTE_SELECTION_REPLACE },
+
+  { "colormap-selection-add", GIMP_STOCK_SELECTION_ADD,
+    NC_("colormap-action", "_Add to Selection"), NULL,
+    NC_("colormap-action", "Add all pixels with this color to the current selection"),
+    GIMP_CHANNEL_OP_ADD, FALSE,
+    GIMP_HELP_INDEXED_PALETTE_SELECTION_ADD },
+
+  { "colormap-selection-subtract", GIMP_STOCK_SELECTION_SUBTRACT,
+    NC_("colormap-action", "_Subtract from Selection"), NULL,
+    NC_("colormap-action", "Subtract all pixels with this color from the current selection"),
+    GIMP_CHANNEL_OP_SUBTRACT, FALSE,
+    GIMP_HELP_INDEXED_PALETTE_SELECTION_SUBTRACT },
+
+  { "colormap-selection-intersect", GIMP_STOCK_SELECTION_INTERSECT,
+    NC_("colormap-action", "_Intersect with Selection"), NULL,
+    NC_("colormap-action", "Intersect all pixels with this color with the current selection"),
+    GIMP_CHANNEL_OP_INTERSECT, FALSE,
+    GIMP_HELP_INDEXED_PALETTE_SELECTION_INTERSECT }
+};
 
 void
 colormap_actions_setup (GimpActionGroup *group)
@@ -78,23 +105,36 @@ colormap_actions_setup (GimpActionGroup *group)
                                       colormap_add_color_actions,
                                       G_N_ELEMENTS (colormap_add_color_actions),
                                       G_CALLBACK (colormap_add_color_cmd_callback));
+
+  gimp_action_group_add_enum_actions (group, "colormap-action",
+                                      colormap_to_selection_actions,
+                                      G_N_ELEMENTS (colormap_to_selection_actions),
+                                      G_CALLBACK (colormap_to_selection_cmd_callback));
 }
 
 void
 colormap_actions_update (GimpActionGroup *group,
                          gpointer         data)
 {
-  GimpImage   *image      = action_data_get_image (data);
-  GimpContext *context    = action_data_get_context (data);
-  gboolean     indexed    = FALSE;
-  gint         num_colors = 0;
+  GimpImage   *image            = action_data_get_image (data);
+  GimpContext *context          = action_data_get_context (data);
+  gboolean     indexed          = FALSE;
+  gboolean     drawable_indexed = FALSE;
+  gint         num_colors       = 0;
   GimpRGB      fg;
   GimpRGB      bg;
 
   if (image)
     {
-      indexed    = (gimp_image_get_base_type (image) == GIMP_INDEXED);
-      num_colors = gimp_image_get_colormap_size (image);
+      indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED);
+
+      if (indexed)
+        {
+          GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+
+          num_colors       = gimp_image_get_colormap_size (image);
+          drawable_indexed = gimp_drawable_is_indexed (drawable);
+        }
     }
 
   if (context)
@@ -109,15 +149,25 @@ colormap_actions_update (GimpActionGroup *group,
         gimp_action_group_set_action_color (group, action, color, FALSE);
 
   SET_SENSITIVE ("colormap-edit-color",
-                 image && indexed && num_colors > 0);
+                 indexed && num_colors > 0);
+
   SET_SENSITIVE ("colormap-add-color-from-fg",
-                 image && indexed && num_colors < 256);
+                 indexed && num_colors < 256);
   SET_SENSITIVE ("colormap-add-color-from-bg",
-                 image && indexed && num_colors < 256);
+                 indexed && num_colors < 256);
 
   SET_COLOR ("colormap-add-color-from-fg", context ? &fg : NULL);
   SET_COLOR ("colormap-add-color-from-bg", context ? &bg : NULL);
 
+  SET_SENSITIVE ("colormap-selection-replace",
+                 drawable_indexed && num_colors > 0);
+  SET_SENSITIVE ("colormap-selection-add",
+                 drawable_indexed && num_colors > 0);
+  SET_SENSITIVE ("colormap-selection-subtract",
+                 drawable_indexed && num_colors > 0);
+  SET_SENSITIVE ("colormap-selection-intersect",
+                 drawable_indexed && num_colors > 0);
+
 #undef SET_SENSITIVE
 #undef SET_COLOR
 }
diff --git a/app/actions/colormap-commands.c b/app/actions/colormap-commands.c
index 7ac5fa7..aeceb57 100644
--- a/app/actions/colormap-commands.c
+++ b/app/actions/colormap-commands.c
@@ -25,6 +25,7 @@
 
 #include "actions-types.h"
 
+#include "core/gimpchannel-select.h"
 #include "core/gimpcontext.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-colormap.h"
@@ -133,6 +134,27 @@ colormap_add_color_cmd_callback (GtkAction *action,
     }
 }
 
+void
+colormap_to_selection_cmd_callback (GtkAction *action,
+                                    gint       value,
+                                    gpointer   data)
+{
+  GimpColormapEditor *editor;
+  GimpImage          *image;
+  GimpChannelOps      op;
+  return_if_no_image (image, data);
+
+  editor = GIMP_COLORMAP_EDITOR (data);
+
+  op = (GimpChannelOps) value;
+
+  gimp_channel_select_by_index (gimp_image_get_mask (image),
+                                gimp_image_get_active_drawable (image),
+                                editor->col_index,
+                                op,
+                                FALSE, 0.0, 0.0);
+}
+
 
 /*  private functions  */
 
diff --git a/app/actions/colormap-commands.h b/app/actions/colormap-commands.h
index b8b529c..4cba353 100644
--- a/app/actions/colormap-commands.h
+++ b/app/actions/colormap-commands.h
@@ -19,11 +19,14 @@
 #define __COLORMAP_COMMANDS_H__
 
 
-void   colormap_edit_color_cmd_callback (GtkAction *action,
-                                         gpointer   data);
-void   colormap_add_color_cmd_callback  (GtkAction *action,
-                                         gint       value,
-                                         gpointer   data);
+void   colormap_edit_color_cmd_callback   (GtkAction *action,
+                                           gpointer   data);
+void   colormap_add_color_cmd_callback    (GtkAction *action,
+                                           gint       value,
+                                           gpointer   data);
+void   colormap_to_selection_cmd_callback (GtkAction *action,
+                                           gint       value,
+                                           gpointer   data);
 
 
 #endif /* __COLORMAP_COMMANDS_H__ */
diff --git a/app/core/gimpchannel-select.c b/app/core/gimpchannel-select.c
index de9c513..896f4a9 100644
--- a/app/core/gimpchannel-select.c
+++ b/app/core/gimpchannel-select.c
@@ -29,6 +29,7 @@
 #include "core-types.h"
 
 #include "gegl/gimp-gegl-apply-operation.h"
+#include "gegl/gimp-gegl-loops.h"
 #include "gegl/gimp-gegl-mask-combine.h"
 
 #include "gimpchannel.h"
@@ -579,3 +580,42 @@ gimp_channel_select_by_color (GimpChannel         *channel,
                               feather_radius_y);
   g_object_unref (add_on);
 }
+
+void
+gimp_channel_select_by_index (GimpChannel    *channel,
+                              GimpDrawable   *drawable,
+                              gint            index,
+                              GimpChannelOps  op,
+                              gboolean        feather,
+                              gdouble         feather_radius_x,
+                              gdouble         feather_radius_y)
+{
+  GeglBuffer *add_on;
+  gint        add_on_x = 0;
+  gint        add_on_y = 0;
+
+  g_return_if_fail (GIMP_IS_CHANNEL (channel));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_drawable_is_indexed (drawable));
+
+  add_on = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+                                            gimp_item_get_width  (GIMP_ITEM (drawable)),
+                                            gimp_item_get_height (GIMP_ITEM (drawable))),
+                            babl_format ("Y float"));
+
+  gimp_gegl_index_to_mask (gimp_drawable_get_buffer (drawable), NULL,
+                           gimp_drawable_get_format_without_alpha (drawable),
+                           add_on, NULL,
+                           index);
+
+  gimp_item_get_offset (GIMP_ITEM (drawable), &add_on_x, &add_on_y);
+
+  gimp_channel_select_buffer (channel, C_("undo-type", "Select by Indexed Color"),
+                              add_on, add_on_x, add_on_y,
+                              op,
+                              feather,
+                              feather_radius_x,
+                              feather_radius_y);
+  g_object_unref (add_on);
+}
diff --git a/app/core/gimpchannel-select.h b/app/core/gimpchannel-select.h
index c81f0de..e335380 100644
--- a/app/core/gimpchannel-select.h
+++ b/app/core/gimpchannel-select.h
@@ -147,6 +147,13 @@ void   gimp_channel_select_by_color     (GimpChannel         *channel,
                                          gboolean             feather,
                                          gdouble              feather_radius_x,
                                          gdouble              feather_radius_y);
+void   gimp_channel_select_by_index     (GimpChannel         *channel,
+                                         GimpDrawable        *drawable,
+                                         gint                 index,
+                                         GimpChannelOps       op,
+                                         gboolean             feather,
+                                         gdouble              feather_radius_x,
+                                         gdouble              feather_radius_y);
 
 
 #endif  /*  __GIMP_CHANNEL_SELECT_H__  */
diff --git a/app/gegl/gimp-gegl-loops.c b/app/gegl/gimp-gegl-loops.c
index 52c5359..5d6ac18 100644
--- a/app/gegl/gimp-gegl-loops.c
+++ b/app/gegl/gimp-gegl-loops.c
@@ -624,6 +624,43 @@ gimp_gegl_replace (GeglBuffer          *top_buffer,
     }
 }
 
+void
+gimp_gegl_index_to_mask (GeglBuffer          *indexed_buffer,
+                         const GeglRectangle *indexed_rect,
+                         const Babl          *indexed_format,
+                         GeglBuffer          *mask_buffer,
+                         const GeglRectangle *mask_rect,
+                         gint                 index)
+{
+  GeglBufferIterator *iter;
+
+  iter = gegl_buffer_iterator_new (indexed_buffer, indexed_rect, 0,
+                                   indexed_format,
+                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+
+  gegl_buffer_iterator_add (iter, mask_buffer, mask_rect, 0,
+                            babl_format ("Y float"),
+                            GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
+
+  while (gegl_buffer_iterator_next (iter))
+    {
+      const guchar *indexed = iter->data[0];
+      gfloat       *mask    = iter->data[1];
+      gint          count   = iter->length;
+
+      while (count--)
+        {
+          if (*indexed == index)
+            *mask = 1.0;
+          else
+            *mask = 0.0;
+
+          indexed++;
+          mask++;
+        }
+    }
+}
+
 static gboolean
 gimp_color_profile_can_gegl_copy (GimpColorProfile *src_profile,
                                   GimpColorProfile *dest_profile)
diff --git a/app/gegl/gimp-gegl-loops.h b/app/gegl/gimp-gegl-loops.h
index 1938af9..be6a87a 100644
--- a/app/gegl/gimp-gegl-loops.h
+++ b/app/gegl/gimp-gegl-loops.h
@@ -81,6 +81,13 @@ void   gimp_gegl_replace               (GeglBuffer               *top_buffer,
                                         gdouble                   opacity,
                                         const gboolean           *affect);
 
+void   gimp_gegl_index_to_mask         (GeglBuffer               *indexed_buffer,
+                                        const GeglRectangle      *indexed_rect,
+                                        const Babl               *indexed_format,
+                                        GeglBuffer               *mask_buffer,
+                                        const GeglRectangle      *mask_rect,
+                                        gint                      index);
+
 void   gimp_gegl_convert_color_profile (GeglBuffer               *src_buffer,
                                         const GeglRectangle      *src_rect,
                                         GimpColorProfile         *src_profile,
diff --git a/app/widgets/gimpcolormapeditor.c b/app/widgets/gimpcolormapeditor.c
index 05fb232..4c56076 100644
--- a/app/widgets/gimpcolormapeditor.c
+++ b/app/widgets/gimpcolormapeditor.c
@@ -222,9 +222,16 @@ static void
 gimp_colormap_editor_constructed (GObject *object)
 {
   GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (object);
+  GdkModifierType     extend_mask;
+  GdkModifierType     modify_mask;
 
   G_OBJECT_CLASS (parent_class)->constructed (object);
 
+  extend_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
+                                              GDK_MODIFIER_INTENT_EXTEND_SELECTION);
+  modify_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
+                                              GDK_MODIFIER_INTENT_MODIFY_SELECTION);
+
   gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
                                  "colormap-edit-color",
                                  NULL);
@@ -234,6 +241,16 @@ gimp_colormap_editor_constructed (GObject *object)
                                  "colormap-add-color-from-bg",
                                  gimp_get_toggle_behavior_mask (),
                                  NULL);
+
+  gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
+                                 "colormap-selection-replace",
+                                 "colormap-selection-add",
+                                 extend_mask,
+                                 "colormap-selection-subtract",
+                                 modify_mask,
+                                 "colormap-selection-intersect",
+                                 extend_mask | modify_mask,
+                                 NULL);
 }
 
 static void
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index e1fd38a..5531b48 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -504,6 +504,10 @@
 #define GIMP_HELP_INDEXED_PALETTE_DIALOG          "gimp-indexed-palette-dialog"
 #define GIMP_HELP_INDEXED_PALETTE_EDIT            "gimp-indexed-palette-edit"
 #define GIMP_HELP_INDEXED_PALETTE_ADD             "gimp-indexed-palette-add"
+#define GIMP_HELP_INDEXED_PALETTE_SELECTION_REPLACE "gimp-indexed-palette-selection-replace"
+#define GIMP_HELP_INDEXED_PALETTE_SELECTION_ADD   "gimp-indexed-palette-selection-add"
+#define GIMP_HELP_INDEXED_PALETTE_SELECTION_SUBTRACT "gimp-indexed-palette-selection-subtract"
+#define GIMP_HELP_INDEXED_PALETTE_SELECTION_INTERSECT "gimp-indexed-palette-selection-intersect"
 
 #define GIMP_HELP_POINTER_INFO_DIALOG             "gimp-pointer-info-dialog"
 #define GIMP_HELP_POINTER_INFO_SAMPLE_MERGED      "gimp-pointer-info-sample-merged"
diff --git a/menus/colormap-menu.xml b/menus/colormap-menu.xml
index bec068c..b984bf1 100644
--- a/menus/colormap-menu.xml
+++ b/menus/colormap-menu.xml
@@ -7,5 +7,10 @@
     <menuitem action="colormap-add-color-from-fg" />
     <menuitem action="colormap-add-color-from-bg" />
     <separator />
+    <menuitem action="colormap-selection-replace" />
+    <menuitem action="colormap-selection-add" />
+    <menuitem action="colormap-selection-subtract" />
+    <menuitem action="colormap-selection-intersect" />
+    <separator />
   </popup>
 </ui>


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