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



Final Patch.
Changed the mmx code to use the another layer than the current one for getting delta.

Please review.
If this is a useless patch since the request was too long ago, let me know.

-Karthik

On Thu, Dec 15, 2011 at 10:18 PM, Karthikeyan S <karthikdevel gmail com> wrote:
By "suggested above" I mean @ https://bugzilla.gnome.org/show_bug.cgi?id=312800


On Thu, Dec 15, 2011 at 10:16 PM, Karthikeyan S <karthikdevel gmail com> wrote:
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 dd101f228b3798ad42eaeed242d160c4f4170a26 Mon Sep 17 00:00:00 2001
From: Karthikeyan S <karthikdevel gmail com>
Date: Mon, 19 Dec 2011 21:49:32 +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.
---
 plug-ins/common/blur-gauss-selective.c |  160 +++++++++++++++++++++++---------
 1 files changed, 115 insertions(+), 45 deletions(-)

diff --git a/plug-ins/common/blur-gauss-selective.c b/plug-ins/common/blur-gauss-selective.c
index 1d589c9..0d88733 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);
@@ -323,6 +354,7 @@ init_matrix (gdouble  radius,
 static ALWAYS_INLINE void
 matrixmult_mmx (const guchar  *src,
                 guchar        *dest,
+                guchar        *del,
                 gint           width,
                 gint           height,
                 const gdouble *mat,
@@ -383,7 +415,7 @@ matrixmult_mmx (const guchar  *src,
           asm volatile (
             "movd         %0, %%mm6 \n\t"
             "punpcklbw %%mm7, %%mm6 \n\t" /* center pixel */
-            :: "m"(src[dix])
+            :: "m"(del[dix])
           );
 
           offset = rowstride * (y - numrad) + bytes * (x - numrad);
@@ -396,6 +428,7 @@ matrixmult_mmx (const guchar  *src,
               for (j = 1 - numrad; j < numrad; j++)
                 {
                   const guchar *src_b;
+                  const guchar *del_b;
                   guint         rowsum  = 0;
                   guint         rowfact = 0;
 
@@ -405,6 +438,7 @@ matrixmult_mmx (const guchar  *src,
                     continue;
 
                   src_b = src + offset - 3;
+                  del_b = del + offset - 3;
 
                   asm volatile (
                     "pxor  %%mm5, %%mm5 \n\t" /* row fact */
@@ -413,20 +447,27 @@ matrixmult_mmx (const guchar  *src,
                   );
 
                   for (i = 1 - numrad; i < numrad; i += 4)
-                    {
-                      src_b += 4;
-                      if (x + i < 0 || x + i >= width)
-                        continue;
+                  {
+                    src_b += 4;
+                    del_b += 4;
+                    if (x + i < 0 || x + i >= width)
+                      continue;
 
-                      asm volatile (
+                    asm volatile (
                         "movd         %0, %%mm0 \n\t"
                         "movq      %%mm6, %%mm1 \n\t"
-                        "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel      */
-                        "psubusw   %%mm0, %%mm1 \n\t" /* diff           */
+                        "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel       */
+                        "psubusw   %%mm0, %%mm1 \n\t" /* diff            */
                         "movq      %%mm0, %%mm2 \n\t"
                         "psubusw   %%mm6, %%mm2 \n\t"
-                        "por       %%mm2, %%mm1 \n\t" /* abs diff       */
-                        "pcmpgtw      %1, %%mm1 \n\t" /* threshold      */
+                        "por       %%mm2, %%mm1 \n\t" /* abs diff        */
+                        "pcmpgtw      %1, %%mm1 \n\t" /* threshold       */
+                        :: "m"(*del_b), "m"(maxdelta4)
+                        );
+
+                    asm volatile (
+                        "movd         %0, %%mm0 \n\t"
+                        "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel       */
                         "pandn        %2, %%mm1 \n\t" /* weight         */
                         "pmullw    %%mm1, %%mm0 \n\t" /* pixel * weight */
                         "paddusw   %%mm1, %%mm5 \n\t" /* fact           */
@@ -436,8 +477,8 @@ matrixmult_mmx (const guchar  *src,
                         "paddd     %%mm0, %%mm4 \n\t"
                         "paddd     %%mm2, %%mm4 \n\t" /* sum            */
                         :: "m"(*src_b), "m"(maxdelta4), "m"(imat[numrad + i])
-                      );
-                    }
+                        );
+                  }
 
                   asm volatile (
                     "pshufw $0xb1, %%mm5, %%mm3 \n\t"
@@ -463,6 +504,7 @@ matrixmult_mmx (const guchar  *src,
               for (j = 1 - numrad; j < numrad; j++)
                 {
                   const guchar *src_b;
+                  const guchar *del_b;
                   gushort       rf[4];
                   guint         rr, rg, rb;
 
@@ -471,6 +513,7 @@ matrixmult_mmx (const guchar  *src,
                     continue;
 
                   src_b = src + offset;
+                  del_b = del + offset;
 
                   asm volatile (
                     "pxor  %%mm5, %%mm5 \n\t" /* row fact   */
@@ -480,21 +523,29 @@ matrixmult_mmx (const guchar  *src,
                   );
 
                   for (i = 1 - numrad; i < numrad; i++)
-                    {
-                      src_b += bytes;
-                      if (x + i < 0 || x + i >= width)
-                        continue;
+                  {
+                    src_b += bytes;
+                    del_b += bytes;
+                    if (x + i < 0 || x + i >= width)
+                      continue;
 
-                      if (has_alpha)
-                        asm volatile (
+                    asm volatile (
+                        "movd         %0, %%mm0 \n\t"
+                        "movq      %%mm6, %%mm1 \n\t"
+                        "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel       */
+                        "psubusw   %%mm0, %%mm1 \n\t" /* diff            */
+                        "movq      %%mm0, %%mm2 \n\t"
+                        "psubusw   %%mm6, %%mm2 \n\t"
+                        "por       %%mm2, %%mm1 \n\t" /* abs diff        */
+                        "pcmpgtw      %1, %%mm1 \n\t" /* threshold       */
+                        :: "m"(*del_b), "m"(maxdelta4)
+                        );
+
+
+                    if (has_alpha)
+                      asm volatile (
                           "movd         %0, %%mm0 \n\t"
-                          "movq      %%mm6, %%mm1 \n\t"
                           "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel       */
-                          "psubusw   %%mm0, %%mm1 \n\t" /* diff            */
-                          "movq      %%mm0, %%mm2 \n\t"
-                          "psubusw   %%mm6, %%mm2 \n\t"
-                          "por       %%mm2, %%mm1 \n\t" /* abs diff        */
-                          "pcmpgtw      %1, %%mm1 \n\t" /* threshold       */
                           "pshufw   $0, %2, %%mm2 \n\t" /* weight          */
                           "pandn     %%mm2, %%mm1 \n\t"
                           "pshufw $0xff, %%mm0, %%mm2 \n\t" /* alpha       */
@@ -508,17 +559,11 @@ matrixmult_mmx (const guchar  *src,
                           "paddd     %%mm0, %%mm4 \n\t"
                           "paddd     %%mm2, %%mm3 \n\t"
                           :: "m"(*src_b), "m"(maxdelta4), "m"(imat[numrad + i])
-                        );
-                      else
-                        asm volatile (
+                          );
+                    else
+                      asm volatile (
                           "movd         %0, %%mm0 \n\t"
-                          "movq      %%mm6, %%mm1 \n\t"
                           "punpcklbw %%mm7, %%mm0 \n\t" /* one pixel       */
-                          "psubusw   %%mm0, %%mm1 \n\t" /* diff            */
-                          "movq      %%mm0, %%mm2 \n\t"
-                          "psubusw   %%mm6, %%mm2 \n\t"
-                          "por       %%mm2, %%mm1 \n\t" /* abs diff        */
-                          "pcmpgtw      %1, %%mm1 \n\t" /* threshold       */
                           "pshufw   $0, %2, %%mm2 \n\t" /* weight          */
                           "pandn     %%mm2, %%mm1 \n\t"
                           "pmullw    %%mm1, %%mm0 \n\t" /* pixel * weight  */
@@ -529,8 +574,8 @@ matrixmult_mmx (const guchar  *src,
                           "paddd     %%mm0, %%mm4 \n\t"
                           "paddd     %%mm2, %%mm3 \n\t"
                           :: "m"(*src_b), "m"(maxdelta4), "m"(imat[numrad + i])
-                        );
-                    }
+                          );
+                  }
 
                   asm volatile (
                     "movd    %%mm4, %0 \n\t"
@@ -583,6 +628,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,
@@ -604,7 +650,7 @@ matrixmult_int (const guchar  *src,
       GimpCpuAccelFlags cpu = gimp_cpu_accel_get_support ();
 
       if (cpu & (GIMP_CPU_ACCEL_X86_MMXEXT | GIMP_CPU_ACCEL_X86_SSE))
-        return matrixmult_mmx (src, dest, width, height, mat, numrad,
+        return matrixmult_mmx (src, dest, del, width, height, mat, numrad,
                                bytes, has_alpha, maxdelta, preview_mode);
     }
 #endif
@@ -632,6 +678,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 +688,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 +697,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 +749,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 +764,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 +782,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 +808,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 +845,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 +853,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 +876,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 +898,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]