added a preview.

* plug-ins/common/edge.c: added a preview.
This commit is contained in:
David Odin 2004-08-12 17:14:25 +00:00
parent 45d77a3aaa
commit 6b4d16e03b
2 changed files with 252 additions and 30 deletions

View file

@ -1,3 +1,7 @@
2004-08-12 DindinX <david@dindinx.org>
* plug-ins/common/edge.c: added a preview.
2004-08-12 Sven Neumann <sven@gimp.org>
* plug-ins/common/sel_gauss.c

View file

@ -92,15 +92,19 @@ typedef struct
* Function prototypes.
*/
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void edge (GimpDrawable *drawable);
static gboolean edge_dialog (GimpDrawable *drawable);
static void edge (GimpDrawable *drawable);
static gboolean edge_dialog (GimpDrawable *drawable);
static GtkWidget *edge_preview_new (GimpDrawable *drawable);
static void edge_preview_update (GimpDrawable *drawable);
static void edge_radio_button_update (GtkWidget *widget,
gpointer data);
static gint edge_detect (guchar *data);
static gint prewitt (guchar *data);
@ -122,11 +126,18 @@ GimpPlugInInfo PLUG_IN_INFO =
static EdgeVals evals =
{
2.0, /* amount */
SOBEL, /* Edge detection algorithm */
2.0, /* amount */
SOBEL, /* Edge detection algorithm */
GIMP_PIXEL_FETCHER_EDGE_SMEAR /* wrapmode */
};
/* Preview stuff */
#define PREVIEW_SIZE 128
static GimpDrawable *drawable;
static GtkWidget *preview;
static gint delta_x = 0;
static gint delta_y = 0;
/***** Functions *****/
MAIN ()
@ -175,7 +186,6 @@ run (const gchar *name,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpDrawable *drawable;
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
@ -263,21 +273,21 @@ run (const gchar *name,
static void
edge (GimpDrawable *drawable)
{
GimpPixelRgn src_rgn, dest_rgn;
gpointer pr;
GimpPixelRgn src_rgn, dest_rgn;
gpointer pr;
GimpPixelFetcher *pft;
guchar *srcrow, *src;
guchar *destrow, *dest;
guchar pix00[4], pix01[4], pix02[4];
guchar pix10[4], pix11[4], pix12[4];
guchar pix20[4], pix21[4], pix22[4];
glong width, height;
gint alpha, has_alpha, chan;
gint x, y;
gint x1, y1, x2, y2;
gint maxval;
gint cur_progress;
gint max_progress;
guchar *srcrow, *src;
guchar *destrow, *dest;
guchar pix00[4], pix01[4], pix02[4];
guchar pix10[4], pix11[4], pix12[4];
guchar pix20[4], pix21[4], pix22[4];
glong width, height;
gint alpha, has_alpha, chan;
gint x, y;
gint x1, y1, x2, y2;
gint maxval;
gint cur_progress;
gint max_progress;
if (evals.amount < 1.0)
evals.amount = 1.0;
@ -458,7 +468,7 @@ sobel (guchar *data)
h_grad += h_kernel[i] * data[i];
}
return sqrt (v_grad * v_grad * evals.amount +
h_grad * h_grad * evals.amount);
h_grad * h_grad * evals.amount);
}
/*
@ -530,7 +540,7 @@ gradient (guchar *data)
}
return sqrt (v_grad * v_grad * evals.amount +
h_grad * h_grad * evals.amount);
h_grad * h_grad * evals.amount);
}
/*
@ -559,7 +569,7 @@ roberts (guchar *data)
}
return sqrt (v_grad * v_grad * evals.amount +
h_grad * h_grad * evals.amount);
h_grad * h_grad * evals.amount);
}
/*
@ -589,7 +599,7 @@ differential (guchar *data)
}
return sqrt (v_grad * v_grad * evals.amount +
h_grad * h_grad * evals.amount);
h_grad * h_grad * evals.amount);
}
/*
@ -653,9 +663,17 @@ edge_dialog (GimpDrawable *drawable)
gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox);
gtk_widget_show (vbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
table = edge_preview_new (drawable);
gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
/* compression */
frame = gimp_int_radio_group_new (TRUE, _("Algorithm"),
G_CALLBACK (gimp_radio_button_update),
G_CALLBACK (edge_radio_button_update),
&evals.edgemode, evals.edgemode,
_("_Sobel"), SOBEL, NULL,
@ -688,6 +706,9 @@ edge_dialog (GimpDrawable *drawable)
g_signal_connect (scale_data, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&evals.amount);
g_signal_connect_swapped (scale_data, "value_changed",
G_CALLBACK (edge_preview_update),
drawable);
/* Radio buttons WRAP, SMEAR, BLACK */
@ -705,6 +726,9 @@ edge_dialog (GimpDrawable *drawable)
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&use_wrap);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (edge_preview_update),
drawable);
toggle = gtk_radio_button_new_with_mnemonic (group, _("_Smear"));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle));
@ -715,6 +739,9 @@ edge_dialog (GimpDrawable *drawable)
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&use_smear);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (edge_preview_update),
drawable);
toggle = gtk_radio_button_new_with_mnemonic (group, _("_Black"));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle));
@ -725,9 +752,14 @@ edge_dialog (GimpDrawable *drawable)
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&use_black);
g_signal_connect_swapped (toggle, "toggled",
G_CALLBACK (edge_preview_update),
drawable);
gtk_widget_show (dlg);
edge_preview_update (drawable);
run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
gtk_widget_destroy (dlg);
@ -741,3 +773,189 @@ edge_dialog (GimpDrawable *drawable)
return run;
}
static void
edge_radio_button_update (GtkWidget *widget,
gpointer data)
{
gint *toggle_val;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
toggle_val = (gint *) data;
*toggle_val = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gimp-item-data"));
}
gimp_toggle_button_sensitive_update (GTK_TOGGLE_BUTTON (widget));
edge_preview_update (drawable);
}
/* Preview stuff */
static GtkWidget *
edge_preview_new (GimpDrawable *drawable)
{
GtkWidget *table;
GtkWidget *frame;
GtkObject *adj;
GtkWidget *scrollbar;
gint sel_width;
gint sel_height;
gint x1, y1, x2, y2;
gint preview_width;
gint preview_height;
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
sel_width = x2 - x1;
sel_height = y2 - y1;
preview_width = MIN (sel_width, PREVIEW_SIZE);
preview_height = MIN (sel_height, PREVIEW_SIZE);
table = gtk_table_new (2, 2, FALSE);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table), frame, 0, 1, 0, 1, 0, 0, 0, 0);
gtk_widget_show (frame);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview, preview_width, preview_height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
adj = gtk_adjustment_new (0, 0, sel_width - 1, 1.0,
MIN (preview_width, sel_width),
MIN (preview_width, sel_width));
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_int_adjustment_update),
&delta_x);
g_signal_connect_swapped (adj, "value_changed",
G_CALLBACK (edge_preview_update),
drawable);
scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
gtk_range_set_update_policy (GTK_RANGE (scrollbar),
GTK_UPDATE_CONTINUOUS);
gtk_table_attach (GTK_TABLE (table), scrollbar, 0, 1, 1, 2,
GTK_FILL, 0, 0, 0);
gtk_widget_show (scrollbar);
adj = gtk_adjustment_new (0, 0, sel_height - 1, 1.0,
MIN (preview_height, sel_height),
MIN (preview_height, sel_height));
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_int_adjustment_update),
&delta_y);
g_signal_connect_swapped (adj, "value_changed",
G_CALLBACK (edge_preview_update),
drawable);
scrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (adj));
gtk_range_set_update_policy (GTK_RANGE (scrollbar),
GTK_UPDATE_CONTINUOUS);
gtk_table_attach (GTK_TABLE (table), scrollbar, 1, 2, 0, 1,
0, GTK_FILL, 0, 0);
gtk_widget_show (scrollbar);
return table;
}
static void
edge_preview_update (GimpDrawable *drawable)
{
/* drawable */
glong width, height;
glong bytes;
gint x1, y1, x2, y2;
gint alpha;
gboolean has_alpha;
/* preview */
guchar *src = NULL; /* Buffer to hold source image */
guchar *render_buffer = NULL; /* Buffer to hold rendered image */
guchar *dest;
gint preview_width; /* Width of preview widget */
gint preview_height; /* Height of preview widget */
gint preview_x1; /* Upper-left X of preview */
gint preview_y1; /* Upper-left Y of preview */
gint preview_x2; /* Lower-right X of preview */
gint preview_y2; /* Lower-right Y of preview */
GimpPixelRgn srcPR; /* Pixel regions */
/* algorithm */
gint x, y;
/* Get drawable info */
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
width = drawable->width;
height = drawable->height;
bytes = gimp_drawable_bpp (drawable->drawable_id);
alpha = bytes;
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
if (has_alpha)
alpha--;
/*
* Setup for filter...
*/
preview_x1 = x1 + delta_x;
preview_y1 = y1 + delta_y;
preview_x2 = preview_x1 + MIN (PREVIEW_SIZE, x2 - x1);
preview_y2 = preview_y1 + MIN (PREVIEW_SIZE, y2 - y1);
preview_width = preview_x2 - preview_x1;
preview_height = preview_y2 - preview_y1;
/* initialize pixel regions */
gimp_pixel_rgn_init (&srcPR, drawable,
preview_x1,preview_y1,
preview_width, preview_height, FALSE, FALSE);
src = g_new (guchar, preview_width * preview_height * bytes);
render_buffer = g_new (guchar, preview_width * preview_height * bytes);
/* render image */
gimp_pixel_rgn_get_rect(&srcPR, src,
preview_x1, preview_y1,
preview_width, preview_height);
dest = render_buffer;
/* render algorithm */
for (y = 0 ; y < preview_height ; y++)
for (x = 0 ; x < preview_width ; x++)
{
gint chan;
for (chan = 0; chan < alpha; chan++)
{
guchar kernel[9];
#define SRC(X,Y) src[bytes * ( CLAMP((X),0,preview_width) + preview_width * CLAMP((Y),0,preview_height) )+chan]
kernel[0] = SRC(x-1, y-1);
kernel[1] = SRC(x-1, y );
kernel[2] = SRC(x-1, y+1);
kernel[3] = SRC(x , y-1);
kernel[4] = SRC(x , y );
kernel[5] = SRC(x , y+1);
kernel[6] = SRC(x+1, y-1);
kernel[7] = SRC(x+1, y );
kernel[8] = SRC(x+1, y+1);
#undef SRC
dest[chan] = edge_detect(kernel);
}
if (has_alpha)
dest[alpha] = src[bytes * (x + preview_width * y) + alpha];
dest += bytes;
}
/*
* Draw the preview image on the screen...
*/
gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
0, 0, preview_width, preview_height,
gimp_drawable_type (drawable->drawable_id),
render_buffer,
preview_width * bytes);
g_free (render_buffer);
g_free (src);
}