Re: [Gimp-developer] Bug 312800: Selective gaussian blur should be able to read delta and blur from different sources
- From: Karthikeyan S <karthikdevel gmail com>
- To: gimp-developer-list gnome org
- Cc: Luis de Bethencourt Guimera <bethencourt gmail com>
- Subject: Re: [Gimp-developer] Bug 312800: Selective gaussian blur should be able to read delta and blur from different sources
- Date: Mon, 19 Dec 2011 22:08:42 +0530
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]