26
26
(self == min && (! modified_flag)) ; modified_flag holds history of update
27
27
In other word, pixel itself is not a neighbor of it.
30
in response to bug #156545, after lengthy discussion, the meanings of "dilate"
31
and "erode" are being swapped -- 19 May 2006.
30
34
#include "config.h"
33
36
#include <stdlib.h>
34
37
#include <string.h>
38
39
#include <libgimp/gimp.h>
39
40
#include <libgimp/gimpui.h>
41
42
#include "libgimp/stdplugins-intl.h"
44
#define DEFAULT_PLUG_IN_NAME "plug_in_vpropagate"
45
#define VPROPAGATE_PROC "plug-in-vpropagate"
46
#define ERODE_PROC "plug-in-erode"
47
#define DILATE_PROC "plug-in-dilate"
48
#define PLUG_IN_BINARY "vpropagate"
45
49
#define PLUG_IN_IMAGE_TYPES "RGB*, GRAY*"
46
#define SHORT_NAME "vpropagate"
47
#define HELP_ID "plug-in-vpropagate"
48
#define ERODE_PLUG_IN_NAME "plug_in_erode"
49
#define DILATE_PLUG_IN_NAME "plug_in_dilate"
52
51
#define VP_RGB (1 << 0)
53
52
#define VP_GRAY (1 << 1)
223
static GimpParamDef args[] =
221
static const GimpParamDef args[] =
225
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
226
{ GIMP_PDB_IMAGE, "image", "Input image (not used)" },
227
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
228
{ GIMP_PDB_INT32, "propagate-mode", "propagate 0:white, 1:black, 2:middle value 3:foreground to peak, 4:foreground, 5:background, 6:opaque, 7:transparent" },
229
{ GIMP_PDB_INT32, "propagating-channel", "channels which values are propagated" },
230
{ GIMP_PDB_FLOAT, "propagating-rate", "0.0 <= propagatating_rate <= 1.0" },
231
{ GIMP_PDB_INT32, "direction-mask", "0 <= direction-mask <= 15" },
232
{ GIMP_PDB_INT32, "lower-limit", "0 <= lower-limit <= 255" },
233
{ GIMP_PDB_INT32, "upper-limit", "0 <= upper-limit <= 255" }
223
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
224
{ GIMP_PDB_IMAGE, "image", "Input image (not used)" },
225
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
226
{ GIMP_PDB_INT32, "propagate-mode", "propagate 0:white, 1:black, 2:middle value 3:foreground to peak, 4:foreground, 5:background, 6:opaque, 7:transparent" },
227
{ GIMP_PDB_INT32, "propagating-channel", "channels which values are propagated" },
228
{ GIMP_PDB_FLOAT, "propagating-rate", "0.0 <= propagatating_rate <= 1.0" },
229
{ GIMP_PDB_INT32, "direction-mask", "0 <= direction-mask <= 15" },
230
{ GIMP_PDB_INT32, "lower-limit", "0 <= lower-limit <= 255" },
231
{ GIMP_PDB_INT32, "upper-limit", "0 <= upper-limit <= 255" }
236
gimp_install_procedure (DEFAULT_PLUG_IN_NAME,
237
"Propagate values of the layer",
234
gimp_install_procedure (VPROPAGATE_PROC,
235
N_("Propagate certain colors to neighboring pixels"),
238
236
"Propagate values of the layer",
239
237
"Shuji Narazaki (narazaki@InetQ.or.jp)",
240
238
"Shuji Narazaki",
269
267
G_N_ELEMENTS (args), 0,
272
gimp_plugin_menu_register (DEFAULT_PLUG_IN_NAME, "<Image>/Filters/Distorts");
273
gimp_plugin_menu_register (ERODE_PLUG_IN_NAME, "<Image>/Filters/Generic");
274
gimp_plugin_menu_register (DILATE_PLUG_IN_NAME, "<Image>/Filters/Generic");
270
gimp_plugin_menu_register (VPROPAGATE_PROC, "<Image>/Filters/Distorts");
271
gimp_plugin_menu_register (ERODE_PROC, "<Image>/Filters/Generic");
272
gimp_plugin_menu_register (DILATE_PROC, "<Image>/Filters/Generic");
300
298
switch (run_mode)
302
300
case GIMP_RUN_INTERACTIVE:
303
if (strcmp (name, DEFAULT_PLUG_IN_NAME) == 0)
301
if (strcmp (name, VPROPAGATE_PROC) == 0)
305
gimp_get_data (DEFAULT_PLUG_IN_NAME, &vpvals);
303
gimp_get_data (VPROPAGATE_PROC, &vpvals);
306
304
/* building the values of dialog variables from vpvals. */
307
305
propagate_alpha =
308
306
(vpvals.propagating_channel & PROPAGATING_ALPHA) ? TRUE : FALSE;
319
317
if (! vpropagate_dialog (drawable))
322
else if (strcmp (name, ERODE_PLUG_IN_NAME) == 0 ||
323
strcmp (name, DILATE_PLUG_IN_NAME) == 0)
320
else if (strcmp (name, ERODE_PROC) == 0 ||
321
strcmp (name, DILATE_PROC) == 0)
325
323
vpvals.propagating_channel = PROPAGATING_VALUE;
326
324
vpvals.propagating_rate = 1.0;
328
326
vpvals.lower_limit = 0;
329
327
vpvals.upper_limit = 255;
331
if (strcmp (name, ERODE_PLUG_IN_NAME) == 0)
329
if (strcmp (name, ERODE_PROC) == 0)
330
vpvals.propagate_mode = 1;
331
else if (strcmp (name, DILATE_PROC) == 0)
332
332
vpvals.propagate_mode = 0;
333
else if (strcmp (name, DILATE_PLUG_IN_NAME) == 0)
334
vpvals.propagate_mode = 1;
338
336
case GIMP_RUN_NONINTERACTIVE:
339
if (strcmp (name, DEFAULT_PLUG_IN_NAME) == 0)
337
if (strcmp (name, VPROPAGATE_PROC) == 0)
341
339
vpvals.propagate_mode = param[3].data.d_int32;
342
340
vpvals.propagating_channel = param[4].data.d_int32;
345
343
vpvals.lower_limit = param[7].data.d_int32;
346
344
vpvals.upper_limit = param[8].data.d_int32;
348
else if (strcmp (name, ERODE_PLUG_IN_NAME) == 0 ||
349
strcmp (name, DILATE_PLUG_IN_NAME) == 0)
346
else if (strcmp (name, ERODE_PROC) == 0 ||
347
strcmp (name, DILATE_PROC) == 0)
351
349
vpvals.propagating_channel = PROPAGATING_VALUE;
352
350
vpvals.propagating_rate = 1.0;
354
352
vpvals.lower_limit = 0;
355
353
vpvals.upper_limit = 255;
357
if (strcmp (name, ERODE_PLUG_IN_NAME) == 0)
355
if (strcmp (name, ERODE_PROC) == 0)
356
vpvals.propagate_mode = 1;
357
else if (strcmp (name, DILATE_PROC) == 0)
358
358
vpvals.propagate_mode = 0;
359
else if (strcmp (name, DILATE_PLUG_IN_NAME) == 0)
360
vpvals.propagate_mode = 1;
482
481
for (y = begy ; y < endy ; y++)
484
483
prepare_row (&srcRgn, nr, begx, ((y+1) < endy) ? y+1 : endy, endx-begx);
485
485
for (index = 0; index < (endx - begx) * bytes; index++)
486
486
dest_row[index] = cr[index];
487
488
for (x = 0 ; x < endx - begx; x++)
489
490
dest = dest_row + (x * bytes);
490
491
here = cr + (x * bytes);
491
493
/* *** copy source value to best value holder *** */
492
memcpy ((void *)best, (void *)here, bytes);
494
memcpy (best, here, bytes);
493
496
if (operation.initializer)
494
497
(* operation.initializer)(dtype, bytes, best, here, &tmp);
495
499
/* *** gather neighbors' values: loop-unfolded version *** */
496
500
if (up_index == -1)
497
501
for (dx = left_index ; dx <= right_index ; dx++)
505
509
/* *** store it to dest_row*** */
506
510
(* operation.finalizer)(dtype, bytes, best, here, dest, tmp);
508
513
/* now store destline to destRgn */
509
514
gimp_pixel_rgn_set_row (&destRgn, dest_row, begx, y, endx - begx);
510
516
/* shift the row pointers */
515
/* update each UPDATE_STEP (optimizer must generate cheap code) */
516
if (((y % 5) == 0) && !preview) /*(y % (int) ((endy - begy) / UPDATE_STEP)) == 0 */
517
gimp_progress_update ((double)y / (double)(endy - begy));
523
if (((y % 5) == 0) && !preview)
524
gimp_progress_update ((gdouble) y / (gdouble) (endy - begy));
1053
1060
gint index = 0;
1056
gimp_ui_init ("vpropagate", FALSE);
1063
gimp_ui_init (PLUG_IN_BINARY, FALSE);
1058
dialog = gimp_dialog_new (_("Value Propagate"), "vpropagate",
1065
dialog = gimp_dialog_new (_("Value Propagate"), PLUG_IN_BINARY,
1060
gimp_standard_help_func, HELP_ID,
1067
gimp_standard_help_func, VPROPAGATE_PROC,
1062
1069
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1063
1070
GTK_STOCK_OK, GTK_RESPONSE_OK,
1074
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
1076
GTK_RESPONSE_CANCEL,
1079
gimp_window_set_transient (GTK_WINDOW (dialog));
1067
1081
main_vbox = gtk_vbox_new (FALSE, 12);
1068
1082
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
1069
1083
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
1130
1144
vpvals.lower_limit, 0, 255, 1, 8, 0,
1133
g_signal_connect (adj, "value_changed",
1147
g_signal_connect (adj, "value-changed",
1134
1148
G_CALLBACK (gimp_int_adjustment_update),
1135
1149
&vpvals.lower_limit);
1136
g_signal_connect_swapped (adj, "value_changed",
1150
g_signal_connect_swapped (adj, "value-changed",
1137
1151
G_CALLBACK (gimp_preview_invalidate),
1142
1156
vpvals.upper_limit, 0, 255, 1, 8, 0,
1145
g_signal_connect (adj, "value_changed",
1159
g_signal_connect (adj, "value-changed",
1146
1160
G_CALLBACK (gimp_int_adjustment_update),
1147
1161
&vpvals.upper_limit);
1148
g_signal_connect_swapped (adj, "value_changed",
1162
g_signal_connect_swapped (adj, "value-changed",
1149
1163
G_CALLBACK (gimp_preview_invalidate),
1154
1168
vpvals.propagating_rate, 0, 1, 0.01, 0.1, 2,
1157
g_signal_connect (adj, "value_changed",
1171
g_signal_connect (adj, "value-changed",
1158
1172
G_CALLBACK (gimp_double_adjustment_update),
1159
1173
&vpvals.propagating_rate);
1160
g_signal_connect_swapped (adj, "value_changed",
1174
g_signal_connect_swapped (adj, "value-changed",
1161
1175
G_CALLBACK (gimp_preview_invalidate),
1179
1193
GtkWidget *toggle;
1182
gtk_table_add_toggle (table, _("Propagating _Alpha Channel"),
1196
gtk_table_add_toggle (table, _("Propagating _alpha channel"),
1184
1198
G_CALLBACK (vpropagate_toggle_button_update),
1185
1199
&propagate_alpha);
1187
if (gimp_layer_get_preserve_trans (drawable->drawable_id))
1201
if (gimp_layer_get_lock_alpha (drawable->drawable_id))
1189
1203
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), 0);
1190
1204
gtk_widget_set_sensitive (toggle, FALSE);
1193
gtk_table_add_toggle (table, _("Propagating Value Channel"), 0, 3, 7,
1207
gtk_table_add_toggle (table, _("Propagating value channel"), 0, 3, 7,
1194
1208
G_CALLBACK (vpropagate_toggle_button_update),
1195
1209
&propagate_value);