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 <karthikde...@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 <karthikde...@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 <karthikde...@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

_______________________________________________
gimp-developer-list mailing list
gimp-developer-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gimp-developer-list

Reply via email to