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@xxxxxxxxx> wrote:
By "suggested above" I mean @ https://bugzilla.gnome.org/show_bug.cgi?id=312800On Thu, Dec 15, 2011 at 10:16 PM, Karthikeyan S <karthikdevel@xxxxxxxxx> 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@xxxxxxxxx> 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@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gimp-developer-list