[Gimp-developer] Bug 312800: Selective gaussian blur should be able to read delta and blur from different sources



I took the patch given earlier by Luis de* and
made the changes suggested above along with code for updating preview.

Attaching the patch. This currently does not work on mmx since we totally
ignore the delta layer when calling mmx routine. But doesn;t break mmx.

Working on mmx code changes...

-karthik
From ab770a8bfa3514205fc1cf06c71eb1c2a2ad03eb Mon Sep 17 00:00:00 2001
From: Karthikeyan S <karthikdevel gmail com>
Date: Thu, 15 Dec 2011 19:08:18 +0530
Subject: [PATCH] Bug 312800: Selective gaussian delta from  another layer

New combo box in the selective gaussian filter dialog box.
This combo box lets you select the layer to be used for delta
values.
As of this patch, machines with MMX will not be able to use
this feature. MMX is _not_ broken by this change.
---
 plug-ins/common/blur-gauss-selective.c |   74 ++++++++++++++++++++++++++++----
 1 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/plug-ins/common/blur-gauss-selective.c b/plug-ins/common/blur-gauss-selective.c
index 1d589c9..0b3838e 100644
--- a/plug-ins/common/blur-gauss-selective.c
+++ b/plug-ins/common/blur-gauss-selective.c
@@ -53,6 +53,7 @@ typedef struct
 {
   gdouble  radius;
   gint     maxdelta;
+  gint     deltalayer_id;
 } BlurValues;
 
 
@@ -71,6 +72,8 @@ static void      sel_gauss        (GimpDrawable     *drawable,
 static gboolean  sel_gauss_dialog (GimpDrawable     *drawable);
 static void      preview_update   (GimpPreview      *preview);
 
+static void      dialog_deltalayer_callback (GtkWidget     *widget,
+                                             GimpPreview   *preview);
 
 const GimpPlugInInfo PLUG_IN_INFO =
 {
@@ -83,7 +86,8 @@ const GimpPlugInInfo PLUG_IN_INFO =
 static BlurValues bvals =
 {
   5.0, /* radius   */
-  50   /* maxdelta */
+  50,   /* maxdelta */
+  -1   /* delta layer id */
 };
 
 MAIN ()
@@ -161,12 +165,20 @@ run (const gchar      *name,
 
     case GIMP_RUN_NONINTERACTIVE:
       /* Make sure all the arguments are there! */
-      if (nparams != 5)
+      if (nparams != 5 && nparams != 6)
         status = GIMP_PDB_CALLING_ERROR;
       if (status == GIMP_PDB_SUCCESS)
         {
           bvals.radius   = param[3].data.d_float;
           bvals.maxdelta = CLAMP (param[4].data.d_int32, 0, 255);
+          if (nparams == 5)
+          {
+            bvals.deltalayer_id = param[2].data.d_drawable;
+          }
+          else
+          {
+            bvals.deltalayer_id = param[5].data.d_drawable;
+          }
 
           if (bvals.radius <= 0.0)
             status = GIMP_PDB_CALLING_ERROR;
@@ -216,6 +228,15 @@ run (const gchar      *name,
   values[0].data.d_status = status;
 }
 
+static void
+dialog_deltalayer_callback (GtkWidget   *widget,
+                         GimpPreview *preview)
+{
+  gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget),
+                                 &bvals.deltalayer_id);
+  gimp_preview_invalidate (preview);
+}
+
 static gboolean
 sel_gauss_dialog (GimpDrawable *drawable)
 {
@@ -226,6 +247,7 @@ sel_gauss_dialog (GimpDrawable *drawable)
   GtkWidget *spinbutton;
   GtkObject *adj;
   gboolean   run;
+  GtkWidget *deltalayer_id;
 
   gimp_ui_init (PLUG_IN_BINARY, FALSE);
 
@@ -259,7 +281,7 @@ sel_gauss_dialog (GimpDrawable *drawable)
                     G_CALLBACK (preview_update),
                     NULL);
 
-  table = gtk_table_new (2, 3, FALSE);
+  table = gtk_table_new (3, 3, FALSE);
   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
   gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
@@ -290,6 +312,15 @@ sel_gauss_dialog (GimpDrawable *drawable)
                             G_CALLBACK (gimp_preview_invalidate),
                             preview);
 
+  deltalayer_id = gimp_layer_combo_box_new (NULL, NULL);
+  /* Default delta layer: The layer that is being blurred */
+  bvals.deltalayer_id = drawable->drawable_id;
+  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX(deltalayer_id), bvals.deltalayer_id,
+                              G_CALLBACK (dialog_deltalayer_callback), preview);
+  gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
+                             _("Delta Layer:"), 0.0, 0.0,
+                             deltalayer_id, 4, TRUE);
+
   gtk_widget_show (dialog);
 
   run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
@@ -583,6 +614,7 @@ matrixmult_mmx (const guchar  *src,
 static ALWAYS_INLINE void
 matrixmult_int (const guchar  *src,
                 guchar        *dest,
+                guchar        *del,
                 gint           width,
                 gint           height,
                 const gdouble *mat,
@@ -632,6 +664,7 @@ matrixmult_int (const guchar  *src,
           for (b = 0; b < nb; b++)
             {
               const guchar *src_db = src + dix + b;
+              const guchar *del_db = del + dix + b;
               guint         sum    = 0;
               guint         fact   = 0;
               gint          offset;
@@ -641,6 +674,7 @@ matrixmult_int (const guchar  *src,
               for (j = 1 - numrad; j < numrad; j++)
                 {
                   const guchar *src_b;
+                  const guchar *del_b;
                   guint         rowsum  = 0;
                   guint         rowfact = 0;
 
@@ -649,17 +683,19 @@ matrixmult_int (const guchar  *src,
                     continue;
 
                   src_b = src + offset + b;
+                  del_b = del + offset + b;
 
                   for (i = 1 - numrad; i < numrad; i++)
                     {
                       gint tmp;
 
                       src_b += bytes;
+                      del_b += bytes;
 
                       if (x + i < 0 || x + i >= width)
                         continue;
 
-                      tmp = *src_db - *src_b;
+                      tmp = *del_db - *del_b;
                       if (tmp > maxdelta || tmp < -maxdelta)
                         continue;
 
@@ -699,6 +735,7 @@ matrixmult_int (const guchar  *src,
 static void
 matrixmult (const guchar  *src,
             guchar        *dest,
+            guchar        *del,
             gint           width,
             gint           height,
             const gdouble *mat,
@@ -713,7 +750,7 @@ matrixmult (const guchar  *src,
 #define EXPAND(BYTES, ALPHA)\
   if (bytes == BYTES && has_alpha == ALPHA)\
     {\
-      matrixmult_int (src, dest, width, height, mat, numrad,\
+      matrixmult_int (src, dest, del, width, height, mat, numrad,\
                       BYTES, ALPHA, maxdelta, preview_mode);\
       return;\
     }
@@ -731,11 +768,13 @@ sel_gauss (GimpDrawable *drawable,
            gdouble       radius,
            gint          maxdelta)
 {
-  GimpPixelRgn src_rgn, dest_rgn;
+  GimpPixelRgn src_rgn, dest_rgn, del_rgn;
+  GimpDrawable *delta;
   gint         bytes;
   gboolean     has_alpha;
   guchar      *dest;
   guchar      *src;
+  guchar      *del;
   gint         x, y;
   gint         width, height;
   gdouble     *mat;
@@ -755,14 +794,22 @@ sel_gauss (GimpDrawable *drawable,
   /*  allocate with extra padding because MMX instructions may read
       more than strictly necessary  */
   src  = g_new (guchar, width * height * bytes + 16);
+  del = g_new (guchar, width * height * bytes + 16);
   dest = g_new (guchar, width * height * bytes);
 
   gimp_pixel_rgn_init (&src_rgn,
                        drawable, x, y, width, height, FALSE, FALSE);
   gimp_pixel_rgn_get_rect (&src_rgn, src, x, y, width, height);
 
-  matrixmult (src, dest, width, height, mat, numrad,
-              bytes, has_alpha, maxdelta, FALSE);
+  delta = gimp_drawable_get (bvals.deltalayer_id);
+
+  gimp_pixel_rgn_init (&del_rgn, delta, x, y, width, height, FALSE, FALSE);
+
+  gimp_pixel_rgn_get_rect (&del_rgn, del, x, y, width, height);
+
+  matrixmult (src, dest, del, width, height, mat, numrad,
+               bytes, has_alpha, maxdelta, FALSE);
+ 
   gimp_progress_update (1.0);
 
   gimp_pixel_rgn_init (&dest_rgn,
@@ -784,6 +831,7 @@ static void
 preview_update (GimpPreview *preview)
 {
   GimpDrawable  *drawable;
+  GimpDrawable  *delta;
   glong          bytes;
   gint           x, y;
   guchar        *render_buffer;  /* Buffer to hold rendered image */
@@ -791,7 +839,9 @@ preview_update (GimpPreview *preview)
   gint           height;         /* Height of preview widget */
 
   GimpPixelRgn   srcPR;           /* Pixel region */
+  GimpPixelRgn   delPR;           /* Pixel region */
   guchar        *src;
+  guchar        *del;
   gboolean       has_alpha;
   gint           numrad;
   gdouble       *mat;
@@ -812,14 +862,20 @@ preview_update (GimpPreview *preview)
   gimp_pixel_rgn_init (&srcPR, drawable,
                        x, y, width, height,
                        FALSE, FALSE);
+  delta = gimp_drawable_get (bvals.deltalayer_id);
+  gimp_pixel_rgn_init (&delPR, delta,
+                       x, y, width, height,
+                       FALSE, FALSE);
   render_buffer = g_new (guchar, width * height * bytes);
 
   /*  allocate with extra padding because MMX instructions may read
       more than strictly necessary  */
   src = g_new (guchar, width * height * bytes + 16);
+  del = g_new (guchar, width * height * bytes + 16);
 
   /* render image */
   gimp_pixel_rgn_get_rect (&srcPR, src, x, y, width, height);
+  gimp_pixel_rgn_get_rect (&delPR, del, x, y, width, height);
   has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
 
   radius = fabs (bvals.radius) + 1.0;
@@ -828,7 +884,7 @@ preview_update (GimpPreview *preview)
   mat = g_new (gdouble, numrad);
   init_matrix (radius, mat, numrad);
 
-  matrixmult (src, render_buffer,
+  matrixmult (src, render_buffer, del,
               width, height,
               mat, numrad,
               bytes, has_alpha, bvals.maxdelta, TRUE);
-- 
1.7.0.4



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