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