[gimp/gimp-2-10] app: add "alpha" propertry to gimp:mask-components



commit fe9c1732b962ff1772829130a5849559ce994023
Author: Ell <ell_se yahoo com>
Date:   Fri May 31 13:02:51 2019 -0400

    app: add "alpha" propertry to gimp:mask-components
    
    In gimp:mask-components, add an "alpha" property, which controls
    the masked-in alpha value in case there's no aux buffer.  Set it to
    0 by default, so that gimp:mask-components behaves normally in the
    absence of an aux buffer (as if the aux buffer was empty).  Set it
    to 1 in the image's visible-mask node, to maintain the current
    alpha-component visibility behavior.
    
    This fixes incorrect results when the output bounding box of a
    drawable filter is smaller than the drawable, which can lead to a
    NULL aux buffer being fed to the filter's gimp:mask-components
    node.
    
    (cherry picked from commit 6425bf820a6cb2e18dc19d71df28e4246f1f87cc)

 app/core/gimpimage.c                          |  1 +
 app/operations/gimpoperationmaskcomponents.cc | 70 ++++++++++++++++-----------
 app/operations/gimpoperationmaskcomponents.h  |  4 +-
 3 files changed, 46 insertions(+), 29 deletions(-)
---
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index ff97279096..97b6be0c69 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -1567,6 +1567,7 @@ gimp_image_get_graph (GimpProjectable *projectable)
     gegl_node_new_child (private->graph,
                          "operation", "gimp:mask-components",
                          "mask",      mask,
+                         "alpha",     1.0,
                          NULL);
 
   gegl_node_connect_to (layers_node,           "output",
diff --git a/app/operations/gimpoperationmaskcomponents.cc b/app/operations/gimpoperationmaskcomponents.cc
index 352267376f..b28171b8ca 100644
--- a/app/operations/gimpoperationmaskcomponents.cc
+++ b/app/operations/gimpoperationmaskcomponents.cc
@@ -35,7 +35,8 @@ extern "C"
 enum
 {
   PROP_0,
-  PROP_MASK
+  PROP_MASK,
+  PROP_ALPHA
 };
 
 
@@ -99,6 +100,17 @@ gimp_operation_mask_components_class_init (GimpOperationMaskComponentsClass *kla
                                                        (GParamFlags) (
                                                          G_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT)));
+
+  g_object_class_install_property (object_class, PROP_ALPHA,
+                                   g_param_spec_double ("alpha",
+                                                        "Alpha",
+                                                        "The masked-in alpha value when there's no aux 
input",
+                                                        -G_MAXDOUBLE,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        (GParamFlags) (
+                                                          G_PARAM_READWRITE |
+                                                          G_PARAM_CONSTRUCT)));
 }
 
 static void
@@ -120,6 +132,10 @@ gimp_operation_mask_components_get_property (GObject    *object,
       g_value_set_flags (value, self->mask);
       break;
 
+    case PROP_ALPHA:
+      g_value_set_double (value, self->alpha);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -140,30 +156,33 @@ gimp_operation_mask_components_set_property (GObject      *object,
       self->mask = (GimpComponentMask) g_value_get_flags (value);
       break;
 
-   default:
+    case PROP_ALPHA:
+      self->alpha = g_value_get_double (value);
+      break;
+
+    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
     }
 }
 
 static guint32
-get_opacity_value (const Babl *format)
+get_alpha_value (const Babl *format,
+                 gfloat      alpha)
 {
-  gfloat src_value = 1.0f;
-
   switch (babl_format_get_bytes_per_pixel (format))
     {
     #define DEF_CASE(bpp, type)                                            \
       case bpp:                                                            \
       {                                                                    \
-        type dst_value;                                                    \
+        type alpha_value;                                                  \
                                                                            \
         babl_process (                                                     \
           babl_fish (babl_format_n (babl_type ("float"),              1),  \
                      babl_format_n (babl_format_get_type (format, 0), 1)), \
-          &src_value, &dst_value, 1);                                      \
+          &alpha, &alpha_value, 1);                                        \
                                                                            \
-        return dst_value;                                                  \
+        return alpha_value;                                                \
       }
 
     DEF_CASE ( 4, guint8)
@@ -186,7 +205,7 @@ struct ProcessGeneric
            gpointer          out_buf,
            gint              n,
            GimpComponentMask mask,
-           T                 opacity_value)
+           T                 alpha_value)
   {
     T    *out = (T *) out_buf;
     gint  i;
@@ -231,7 +250,7 @@ struct ProcessGeneric
               }
 
             if (mask & (1 << 3))
-              out[3] = opacity_value;
+              out[3] = alpha_value;
             else
               out[3] = in[3];
 
@@ -258,7 +277,7 @@ struct Process<guint8>
            gpointer          out_buf,
            gint              n,
            GimpComponentMask mask,
-           guint8            opacity_value)
+           guint8            alpha_value)
   {
     const guint32 *in;
     guint32       *out;
@@ -269,7 +288,7 @@ struct Process<guint8>
     if (((guintptr) in_buf | (guintptr) aux_buf | (guintptr) out_buf) % 4)
       {
         ProcessGeneric<guint8>::process (in_buf, aux_buf, out_buf, n,
-                                         mask, opacity_value);
+                                         mask, alpha_value);
 
         return;
       }
@@ -299,7 +318,7 @@ struct Process<guint8>
       }
     else
       {
-        if (! (mask & GIMP_COMPONENT_MASK_ALPHA))
+        if (! (mask & GIMP_COMPONENT_MASK_ALPHA) || ! alpha_value)
           {
             for (i = 0; i < n; i++)
               {
@@ -311,11 +330,11 @@ struct Process<guint8>
           }
         else
           {
-            g_return_if_fail (opacity_value == 0xff);
+            guint32 alpha_mask = alpha_value << 24;
 
             for (i = 0; i < n; i++)
               {
-                *out = (*in & in_mask) | 0xff000000u;
+                *out = (*in & in_mask) | alpha_mask;
 
                 in++;
                 out++;
@@ -338,7 +357,7 @@ gimp_operation_mask_components_process (GimpOperationMaskComponents *self,
                                         gint                         level)
 {
   Process<T>::process (in_buf, aux_buf, out_buf, samples,
-                       self->mask, self->opacity_value);
+                       self->mask, self->alpha_value);
 
   return TRUE;
 }
@@ -360,7 +379,7 @@ gimp_operation_mask_components_prepare (GeglOperation *operation)
     {
       self->format = format;
 
-      self->opacity_value = get_opacity_value (format);
+      self->alpha_value = get_alpha_value (format, self->alpha);
 
       switch (babl_format_get_bytes_per_pixel (format))
         {
@@ -407,10 +426,10 @@ gimp_operation_mask_components_parent_process (GeglOperation        *operation,
       GObject *aux = gegl_operation_context_get_object (context, "aux");
 
       /* when there's no aux and the alpha component is masked-in, we set the
-       * result's alpha component to full opacity, rather than full
-       * transparency, so we can't just forward an empty aux in this case.
+       * result's alpha component to the value of the "alpha" property; if it
+       * doesn't equal 0, we can't forward an empty aux.
        */
-      if (aux)
+      if (aux || ! self->alpha_value)
         {
           gegl_operation_context_set_object (context, "output", aux);
 
@@ -508,28 +527,23 @@ gimp_operation_mask_components_process (const Babl        *format,
                                         gint               n,
                                         GimpComponentMask  mask)
 {
-  guint32 opacity_value = 0;
-
   g_return_if_fail (format != NULL);
   g_return_if_fail (in != NULL);
   g_return_if_fail (out != NULL);
   g_return_if_fail (n >= 0);
 
-  if (! aux && (mask & GIMP_COMPONENT_MASK_ALPHA))
-    opacity_value = get_opacity_value (format);
-
   switch (babl_format_get_bytes_per_pixel (format))
     {
     case 4:
-      Process<guint8>::process (in, aux, out, n, mask, opacity_value);
+      Process<guint8>::process (in, aux, out, n, mask, 0);
       break;
 
     case 8:
-      Process<guint16>::process (in, aux, out, n, mask, opacity_value);
+      Process<guint16>::process (in, aux, out, n, mask, 0);
       break;
 
     case 16:
-      Process<guint32>::process (in, aux, out, n, mask, opacity_value);
+      Process<guint32>::process (in, aux, out, n, mask, 0);
       break;
 
     default:
diff --git a/app/operations/gimpoperationmaskcomponents.h b/app/operations/gimpoperationmaskcomponents.h
index 9fa653824a..0919a3876f 100644
--- a/app/operations/gimpoperationmaskcomponents.h
+++ b/app/operations/gimpoperationmaskcomponents.h
@@ -40,7 +40,9 @@ struct _GimpOperationMaskComponents
   GeglOperationPointComposer  parent_instance;
 
   GimpComponentMask           mask;
-  guint32                     opacity_value;
+  gdouble                     alpha;
+
+  guint32                     alpha_value;
   gpointer                    process;
   const Babl                 *format;
 };


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