[gimp-gap/gap-2-8] LAYER GROUP Support in animated filtercalls and filtermacros
- From: Wolfgang Hofer <wolfgangh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp-gap/gap-2-8] LAYER GROUP Support in animated filtercalls and filtermacros
- Date: Sat, 22 Feb 2014 08:30:18 +0000 (UTC)
commit 4b1cd364a37a28e76e484d64bb805895cc9e234d
Author: Wolfgang Hofer <wolfgangh svn gnome org>
Date: Sat Feb 22 09:29:50 2014 +0100
LAYER GROUP Support in animated filtercalls and filtermacros
ChangeLog | 85 ++++++
gap/gap_blend_fill_main.c | 2 +-
gap/gap_dbbrowser_utils.c | 305 +++++++++++++++------
gap/gap_dbbrowser_utils.h | 14 +-
gap/gap_edge_detection.c | 2 +-
gap/gap_fg_matting_dialog.c | 8 +-
gap/gap_filter_foreach.c | 296 ++++++++++++++-------
gap/gap_filter_iterators.c | 54 +++-
gap/gap_fire_pattern.c | 20 +-
gap/gap_fmac_base.c | 2 +-
gap/gap_fmac_context.c | 94 +++++--
gap/gap_fmac_context.h | 8 +-
gap/gap_frame_fetcher.c | 205 ++++++++-------
gap/gap_frame_fetcher.h | 18 +-
gap/gap_image.c | 267 ++++++++++++++++++-
gap/gap_image.h | 9 +
gap/gap_mod_layer.c | 352 +++++++++++++++++++-----
gap/gap_player_cache.c | 3 -
gap/gap_water_pattern.c | 16 +-
gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc | 43 ++--
20 files changed, 1357 insertions(+), 446 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 169984b..021cdfa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,88 @@
+2014-02-22 Wolfgang Hofer <hof gimp org>
+- extended filtermacro reference sidecar filformat (.fmref)
+ .fmref files do describe persistent layer ids and
+ allow succesful applying a filter that requires additional layers
+ (such as bumpmap that needs a layer for the map)
+ with recorded lastvlues buffer in the next gimp session.
+
+ The old format describes layer rference by imagname and stackposition.
+ In case of nested layer this is not sufficient.
+
+ Therefore the fileformat was exteded with keyword "parentstack:",
+ followed by a list of integer stack positions of all parent group layers
+ concatenated by the "/" delimiter character.
+
+ Note that toplevel layers are still refered without the new parentstack
+ (== compatible to the old format)
+
+ id:800003 frameNr:000000 stack:02 track:-1 mtime:01392968915 type:3 file:"/home/hof/testimage.xcf"
parentstack:2/0
+
+
+
+- replaced deprecated gimp_drawable_is_valid calls by gimp_item_is_valid
+
+- Filter All Layers feature now has options how to handle applying a filter to a group layer.
+ The GAP filter db browser dialog provides radio buttons how to handle group layers.
+ - normal mode (enables filter calls on group layer items)
+ - merge group items before calling a filter
+ - skip filtercalls on group items
+
+ This feature is mainly a workaround for the fact, that many plug-in filters
+ of the GIMP-2.8.10 release fail on attempt to process a group layer.
+
+ Example: the whirl-pinch plugin fails with the message:
+ Calling error for procedure 'gimp-drawable-merge-shadow':
+ Item 'GR-1' (20) cannot be modified because it is a group item
+
+- fixed issuses for the "FramesModify" feature
+ when function "Apply filter on layer(s)" is selected.
+ Support skip and automatical merge on selected group layers in the processed frames
+ for this modify function.
+ Notes:
+ for filter apply with constant values (acceleration characteristic value == 0)
+ the first processed frame must contain at least one layer
+ that matches the selection criteria.
+
+ for filter apply with varying values both
+ the first and the last processed frame
+ must contain at least one layer
+ that matches the selection criteria.
+
+ This is required for the interactive filtercalls to record the
+ last values buffer(s) for the called filter pdb procedure.
+
+
+- dropped support for GAP_FILTER_PITSTOP environment variable
+ the pitstop dialog is now configurable via gimprc parameters:
+ (gap-filterall-enable-pitstop-dialog "no")
+ (gap-modify-enable-pitstop-dialog "no")
+
+ Both pitstop dialogs now have an option "do not show this dialog again"
+ to disable those (optional) dialogs in the future (in this and further sessions).
+
+
+ * gap/gap_blend_fill_main.c
+ * gap/gap_dbbrowser_utils.c
+ * gap/gap_dbbrowser_utils.h
+ * gap/gap_edge_detection.c
+ * gap/gap_fg_matting_dialog.c
+ * gap/gap_filter_foreach.c
+ * gap/gap_filter_iterators.c
+ * gap/gap_fire_pattern.c
+ * gap/gap_fmac_base.c
+ * gap/gap_fmac_context.c
+ * gap/gap_fmac_context.h
+ * gap/gap_frame_fetcher.c
+ * gap/gap_frame_fetcher.h
+ * gap/gap_image.c
+ * gap/gap_image.h
+ * gap/gap_mod_layer.c
+ * gap/gap_player_cache.c
+ * gap/gap_water_pattern.c
+ * gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc
+
+
+
2014-02-15 Wolfgang Hofer <hof gimp org>
- applied fix for the foreground matting feature as suggested at bug #723818
diff --git a/gap/gap_blend_fill_main.c b/gap/gap_blend_fill_main.c
index bb5b0ac..a054767 100644
--- a/gap/gap_blend_fill_main.c
+++ b/gap/gap_blend_fill_main.c
@@ -1935,7 +1935,7 @@ gap_blend_fill_dialog (FilterVals *fiVals, gint32 drawable_id)
{
initalComboElem = SELECTION_FROM_SVG_FILE;
}
- else if(gimp_drawable_is_valid(fiVals->altSelection) == TRUE)
+ else if(gimp_item_is_valid(fiVals->altSelection) == TRUE)
{
initalComboElem = fiVals->altSelection;
}
diff --git a/gap/gap_dbbrowser_utils.c b/gap/gap_dbbrowser_utils.c
index cab0eba..afdd283 100644
--- a/gap/gap_dbbrowser_utils.c
+++ b/gap/gap_dbbrowser_utils.c
@@ -1,5 +1,5 @@
-/*
- * gap_dbbrowser_utils.c (most parts of the code are copied from
+/*
+ * gap_dbbrowser_utils.c (most parts of the code are copied from
* GIMP DB-Browser Code by Thomas NOEL <thomas minet net>
*/
/* The GIMP -- an image manipulation program
@@ -34,10 +34,10 @@
* 27. jan .1999 hof: update for GIMP 1.1.1 (show help)
* 09. dec .1998 hof: update for GIMP 1.1
* 12. jan .1998 hof: added "Gen Code" button
- *
+ *
* 23. dec .1997 hof: created GAP specific variant of DBbrowser
* removed apply_callback
- * added constraint_procedure,
+ * added constraint_procedure,
* added 2 buttons
* added return type
*/
@@ -96,7 +96,7 @@ typedef struct
gint selected_nparams;
gint selected_nreturn_vals;
GimpParamDef *selected_params;
- GimpParamDef *selected_return_vals;
+ GimpParamDef *selected_return_vals;
/* GAP DB-Browser specific items */
gchar *selected_menu_path;
@@ -105,6 +105,10 @@ typedef struct
GtkObject *accel_adj;
GtkWidget *accel_spinbutton;
GtkWidget *accel_hbox;
+ GtkWidget *radio_grp_hbox;
+ GtkWidget *radio_grp_process;
+ GtkWidget *radio_grp_skip;
+ GtkWidget *radio_grp_merge;
GtkWidget* menupath_button;
@@ -113,7 +117,7 @@ typedef struct
t_constraint_func constraint_func_sel1;
t_constraint_func constraint_func_sel2;
GapDbBrowserResult *result;
-
+
gint codegen_flag;
gint32 current_image_id;
const char *help_id;
@@ -127,18 +131,20 @@ typedef struct
static void procedure_select_callback (GtkTreeSelection *sel,
dbbrowser_t *dbbrowser);
-static void dialog_search_callback (GtkWidget *widget,
+static void dialog_search_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser);
-static void dialog_select (dbbrowser_t *dbbrowser,
+static void dialog_select (dbbrowser_t *dbbrowser,
gchar *proc_name);
-static void dialog_close_callback (GtkWidget *widget,
+static void dialog_close_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser);
-static void dialog_help_callback (GtkWidget *widget,
+static void dialog_help_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser);
static void convert_string (gchar *str);
/* GAP specific extra callbacks */
-static void dialog_num_button_callback (dbbrowser_t* dbbrowser,
+static void p_radio_callback(GtkWidget *wgt, gpointer user_data);
+
+static void dialog_num_button_callback (dbbrowser_t* dbbrowser,
gint button_nr);
static void dialog_button_1_callback (GtkWidget *widget,
dbbrowser_t* dbbrowser);
@@ -146,6 +152,8 @@ static void dialog_button_3_callback (GtkWidget *widget,
dbbrowser_t* dbbrowser);
static void p_accel_spinbutton_callback (GtkObject *obj, dbbrowser_t* dbbrowser);
+static void p_create_radio_group_handling_widgets (dbbrowser_t *dbbrowser, gboolean
showGroupHandling);
+
static void p_create_action_area_buttons (dbbrowser_t *dbbrowser,
char *button_1_txt,
gboolean showAccelerationCharacteristic,
@@ -153,7 +161,7 @@ static void p_create_action_area_buttons (dbbrowser_t *dbbrowser,
);
/* create and perform the dialog */
-int
+int
gap_db_browser_dialog(char *title_txt,
char *button_1_txt,
gboolean showAccelerationCharacteristic,
@@ -175,19 +183,24 @@ gap_db_browser_dialog(char *title_txt,
gimp_ui_init ("gap-animated-filter-apply", FALSE);
dbbrowser = g_new0 (dbbrowser_t, 1);
-
- /* store pointers to gap constraint procedures */
+
+ /* store pointers to gap constraint procedures */
dbbrowser->constraint_func = constraint_func;
dbbrowser->constraint_func_sel1 = constraint_func_sel1;
dbbrowser->constraint_func_sel2 = constraint_func_sel2;
dbbrowser->result = result;
dbbrowser->codegen_flag = 0; /* default: no code generation */
dbbrowser->current_image_id = image_id;
-
+
+ dbbrowser->radio_grp_hbox = NULL;
+ dbbrowser->radio_grp_process = NULL;
+ dbbrowser->radio_grp_skip = NULL;
+ dbbrowser->radio_grp_merge = NULL;
+
/* the dialog box */
dbbrowser->dialog = gtk_dialog_new ();
-
+
gtk_window_set_title (GTK_WINDOW (dbbrowser->dialog), title_txt);
gtk_window_set_position (GTK_WINDOW (dbbrowser->dialog), GTK_WIN_POS_MOUSE);
g_signal_connect (dbbrowser->dialog, "destroy",
@@ -197,18 +210,18 @@ gap_db_browser_dialog(char *title_txt,
/* hpaned : left=list ; right=description */
hpaned = gtk_hpaned_new ();
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dialog)->vbox),
hpaned, TRUE, TRUE, 0);
gtk_widget_show (hpaned);
/* left = vbox : the list and the search entry */
-
+
vbox = gtk_vbox_new (FALSE, 4);
gtk_paned_pack1 (GTK_PANED (hpaned), vbox, FALSE, TRUE);
gtk_widget_show (vbox);
/* list : list in a scrolled_win */
-
+
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_SHADOW_IN);
@@ -262,7 +275,7 @@ gap_db_browser_dialog(char *title_txt,
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request (scrolled_window, DBL_WIDTH - DBL_LIST_WIDTH, -1);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC,
GTK_POLICY_ALWAYS);
gtk_paned_pack2 (GTK_PANED (hpaned), scrolled_window, TRUE, TRUE);
gtk_widget_show (scrolled_window);
@@ -274,9 +287,6 @@ gap_db_browser_dialog(char *title_txt,
gtk_widget_show (dbbrowser->descr_vbox);
-
-
-
/* GAP specific buttons in dialog->action_aera */
p_create_action_area_buttons(dbbrowser, button_1_txt, showAccelerationCharacteristic, help_id);
@@ -315,8 +325,9 @@ gap_db_browser_dialog(char *title_txt,
if(gap_debug)
{
- printf("gap_db_browser_dialog: result accelCharacteristic:%d\n"
+ printf("gap_db_browser_dialog: result accelCharacteristic:%d groupFilterHandlingMode:%d\n"
, (int)dbbrowser->result->accelCharacteristic
+ , (int)dbbrowser->result->groupFilterHandlingMode
);
}
@@ -324,6 +335,79 @@ gap_db_browser_dialog(char *title_txt,
} /* end gap_db_browser_dialog */
+/* ---------------------------------------
+ * p_create_radio_group_handling_widgets
+ * ---------------------------------------
+ */
+static void
+p_create_radio_group_handling_widgets (dbbrowser_t *dbbrowser, gboolean showGroupHandling)
+{
+ GtkWidget *hbox1;
+ GtkWidget *label1;
+ GSList *grp_handling_group = NULL;
+ GtkWidget *radiobutton1;
+ GtkWidget *radiobutton2;
+ GtkWidget *radiobutton3;
+
+ hbox1 = gtk_hbox_new (FALSE, 0);
+
+ if(showGroupHandling)
+ {
+ gtk_widget_show (hbox1);
+ }
+ gtk_container_set_border_width (GTK_CONTAINER (hbox1), 4);
+
+
+ /* Layer Group handling mode the label */
+ label1 = gtk_label_new (_("Layer Group:"));
+
+ gtk_widget_show (label1);
+ gtk_box_pack_start (GTK_BOX (hbox1), label1, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);
+
+
+ /* GroupLayer handling mode the radio buttons */
+ radiobutton1 = gtk_radio_button_new_with_label (grp_handling_group, _("Process"));
+ grp_handling_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1));
+ gtk_widget_show (radiobutton1);
+ gimp_help_set_help_data(radiobutton1
+ , _("group layers are processed the same way as normal layers."
+ " (this typically keeps the group structure, but the filter call will fail "
+ " for all filters that are not capable to process a group layer)")
+ , NULL);
+ gtk_box_pack_start (GTK_BOX (hbox1), radiobutton1, FALSE, FALSE, 0);
+
+ radiobutton2 = gtk_radio_button_new_with_label (grp_handling_group, _("Skip"));
+ grp_handling_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2));
+ gtk_widget_show (radiobutton2);
+ gimp_help_set_help_data(radiobutton2
+ , _("skip processing of the selected filter for group layers.")
+ , NULL);
+ gtk_box_pack_start (GTK_BOX (hbox1), radiobutton2, FALSE, FALSE, 0);
+
+ radiobutton3 = gtk_radio_button_new_with_label (grp_handling_group, _("Merge"));
+ grp_handling_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3));
+ gtk_widget_show (radiobutton3);
+ gimp_help_set_help_data(radiobutton3
+ , _("group layers are merged before the selected filter is applied.")
+ , NULL);
+ gtk_box_pack_start (GTK_BOX (hbox1), radiobutton3, FALSE, FALSE, 0);
+
+
+ dbbrowser->radio_grp_hbox = hbox1;
+ dbbrowser->radio_grp_process = radiobutton1;
+ dbbrowser->radio_grp_skip = radiobutton2;
+ dbbrowser->radio_grp_merge = radiobutton3;
+
+
+ /* signals */
+ g_signal_connect (G_OBJECT (dbbrowser->radio_grp_process), "clicked", G_CALLBACK (p_radio_callback),
dbbrowser);
+ g_signal_connect (G_OBJECT (dbbrowser->radio_grp_skip), "clicked", G_CALLBACK (p_radio_callback),
dbbrowser);
+ g_signal_connect (G_OBJECT (dbbrowser->radio_grp_merge), "clicked", G_CALLBACK (p_radio_callback),
dbbrowser);
+
+} /* end p_create_radio_group_handling_widgets */
+
+
static void
p_create_action_area_buttons(dbbrowser_t *dbbrowser,
char *button_1_txt,
@@ -335,8 +419,10 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
GtkWidget *button;
gint row;
gint cof;
-
+ gboolean showGroupHandling;
cof = 2;
+
+ showGroupHandling = showAccelerationCharacteristic;
/* 5 cols, 3rows */
table = gtk_table_new(1,1,TRUE);
@@ -346,8 +432,9 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
row = 0;
+
/* Button GenCode (conditional in DEBUG mode only for developers) */
- if (gap_debug)
+ if (gap_debug)
{
button = gtk_button_new_with_label ( _("Gen Code by name"));
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
@@ -362,13 +449,19 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
row++;
}
+ /* GAP specific radio buttons for group layer handling */
+ p_create_radio_group_handling_widgets (dbbrowser, showGroupHandling);
+ gtk_table_attach (GTK_TABLE (table), dbbrowser->radio_grp_hbox ,
+ 0, cof, row, row + 1,
+ GTK_FILL, 0, 0, 0);
+
/* Button Search by Name */
dbbrowser->name_button = gtk_button_new_with_label ( _("Search by Name"));
GTK_WIDGET_SET_FLAGS (dbbrowser->name_button, GTK_CAN_DEFAULT);
g_signal_connect (G_OBJECT (dbbrowser->name_button), "clicked",
G_CALLBACK (dialog_search_callback), dbbrowser);
gtk_table_attach (GTK_TABLE (table), dbbrowser->name_button,
- cof, cof+1, row, row + 1,
+ cof, cof+1, row, row + 1,
GTK_FILL, 0, 0, 0);
gtk_widget_show(dbbrowser->name_button);
@@ -378,7 +471,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
g_signal_connect (G_OBJECT (dbbrowser->blurb_button), "clicked",
G_CALLBACK (dialog_search_callback), dbbrowser);
gtk_table_attach (GTK_TABLE (table), dbbrowser->blurb_button,
- cof+1, cof+2, row, row + 1,
+ cof+1, cof+2, row, row + 1,
GTK_FILL, 0, 0, 0);
gtk_widget_show(dbbrowser->blurb_button);
@@ -388,7 +481,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
g_signal_connect (G_OBJECT (dbbrowser->menupath_button), "clicked",
G_CALLBACK (dialog_search_callback), dbbrowser);
gtk_table_attach (GTK_TABLE (table), dbbrowser->menupath_button,
- cof+2, cof+3, row, row + 1,
+ cof+2, cof+3, row, row + 1,
GTK_FILL, 0, 0, 0);
gtk_widget_show(dbbrowser->menupath_button);
@@ -396,7 +489,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
row++;
/* the Acceleration characteristic value spinbutton and graph */
- if (showAccelerationCharacteristic)
+ if (showAccelerationCharacteristic)
{
GapAccelWidget *accel_wgt;
GtkObject *adj;
@@ -421,7 +514,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
accel_wgt = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
gtk_box_pack_start (GTK_BOX (dbbrowser->accel_hbox), accel_wgt->da_widget, FALSE, FALSE, 1);
gtk_widget_show (accel_wgt->da_widget);
-
+
adj = accel_wgt->adj;
/* the Acceleration characteristic value spinbutton */
@@ -430,7 +523,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
dbbrowser->accel_spinbutton = spinbutton;
gtk_widget_show (spinbutton);
-
+
gtk_box_pack_start (GTK_BOX (dbbrowser->accel_hbox), spinbutton, TRUE, TRUE, 1);
gtk_widget_set_size_request (spinbutton, 50, -1);
gimp_help_set_help_data (spinbutton, _("acceleration characteristic for filter apply 0=constant, 1
varying with constant speed, positive accelerate, negative decelerate"), NULL);
@@ -443,16 +536,16 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
dbbrowser->accel_wgt = accel_wgt;
- }
+ }
else
- {
+ {
dbbrowser->accel_adj = NULL;
dbbrowser->accel_spinbutton = NULL;
-
+
dbbrowser->accel_hbox = gtk_hbox_new (FALSE, 1);
gtk_widget_show (dbbrowser->accel_hbox);
gtk_table_attach_defaults (GTK_TABLE(table), dbbrowser->accel_hbox, cof, cof+1, row, row + 1);
-
+
}
/* Button1 (Apply Constant) */
@@ -462,7 +555,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
g_signal_connect (G_OBJECT (dbbrowser->app_const_button), "clicked",
G_CALLBACK (dialog_button_1_callback), dbbrowser );
gtk_table_attach (GTK_TABLE (table), dbbrowser->app_const_button,
- cof+1, cof+2, row, row + 1,
+ cof+1, cof+2, row, row + 1,
GTK_FILL, 0, 0, 0);
gtk_widget_set_sensitive (dbbrowser->app_const_button, FALSE);
gtk_widget_show (dbbrowser->app_const_button);
@@ -475,7 +568,7 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (dialog_close_callback), dbbrowser);
gtk_table_attach (GTK_TABLE (table), button,
- cof+2, cof+3, row, row + 1,
+ cof+2, cof+3, row, row + 1,
GTK_FILL, 0, 0, 0);
gtk_widget_show (button);
@@ -489,13 +582,13 @@ p_create_action_area_buttons(dbbrowser_t *dbbrowser,
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (dialog_help_callback), dbbrowser);
gtk_table_attach (GTK_TABLE (table), button,
- 0, 1, row, row + 1,
+ 0, 1, row, row + 1,
GTK_FILL, 0, 0, 0);
}
gtk_widget_show (table);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dialog)->action_area),
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dialog)->action_area),
table, TRUE, TRUE, 0);
} /* end p_create_action_area_buttons */
@@ -526,8 +619,8 @@ procedure_select_callback (GtkTreeSelection *sel,
}
/* update the description box (right) */
-static void
-dialog_select (dbbrowser_t *dbbrowser,
+static void
+dialog_select (dbbrowser_t *dbbrowser,
gchar *proc_name)
{
GtkWidget *old_description;
@@ -547,13 +640,13 @@ dialog_select (dbbrowser_t *dbbrowser,
g_free (dbbrowser->selected_params);
g_free (dbbrowser->selected_return_vals);
- g_free (dbbrowser->selected_menu_path);
+ g_free (dbbrowser->selected_menu_path);
dbbrowser->selected_menu_path = gap_db_get_plugin_menupath(proc_name);
if(dbbrowser->selected_menu_path == NULL)
dbbrowser->selected_menu_path = g_strdup(_("** not available **"));
-
- gimp_procedural_db_proc_info (proc_name,
+
+ gimp_procedural_db_proc_info (proc_name,
&dbbrowser->selected_proc_blurb,
&dbbrowser->selected_proc_help,
&dbbrowser->selected_proc_author,
@@ -569,7 +662,7 @@ dialog_select (dbbrowser_t *dbbrowser,
old_description = dbbrowser->description;
/* render the new description */
- dbbrowser->description =
+ dbbrowser->description =
gimp_proc_view_new (proc_name,
dbbrowser->selected_menu_path,
dbbrowser->selected_proc_blurb,
@@ -582,7 +675,7 @@ dialog_select (dbbrowser_t *dbbrowser,
dbbrowser->selected_nreturn_vals,
dbbrowser->selected_params,
dbbrowser->selected_return_vals);
-
+
if (old_description)
@@ -592,32 +685,42 @@ dialog_select (dbbrowser_t *dbbrowser,
gtk_box_pack_start (GTK_BOX (dbbrowser->descr_vbox),
dbbrowser->description, FALSE, FALSE, 0);
gtk_widget_show (dbbrowser->description);
-
- /* call GAP constraint functions to check sensibility for the apply buttons */
+
+ /* call GAP constraint functions to check sensibility for the apply buttons */
if(dbbrowser->app_const_button != NULL)
{
if(0 != (dbbrowser->constraint_func_sel1)(dbbrowser->selected_proc_name, dbbrowser->current_image_id))
- {
+ {
gtk_widget_set_sensitive (dbbrowser->app_const_button, TRUE);
}
- else
+ else
{
gtk_widget_set_sensitive (dbbrowser->app_const_button, FALSE);
}
}
- if(dbbrowser->accel_spinbutton != NULL)
+ if((dbbrowser->accel_spinbutton != NULL) && (dbbrowser->accel_wgt != NULL))
{
+
if(0 != (dbbrowser->constraint_func_sel2)(dbbrowser->selected_proc_name, dbbrowser->current_image_id))
- {
+ {
gtk_widget_set_sensitive (dbbrowser->accel_spinbutton, TRUE);
+ if(dbbrowser->accel_wgt->da_widget != NULL)
+ {
+ gtk_widget_set_sensitive (dbbrowser->accel_wgt->da_widget, TRUE);
+ }
}
else
{
gtk_widget_set_sensitive (dbbrowser->accel_spinbutton, FALSE);
- }
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(dbbrowser->accel_adj), (gfloat)0.0);
+ if(dbbrowser->accel_wgt->da_widget != NULL)
+ {
+ gtk_widget_set_sensitive (dbbrowser->accel_wgt->da_widget, FALSE);
+ }
+ }
}
-
+
}
static void
@@ -646,7 +749,7 @@ dialog_show_message (dbbrowser_t *dbbrowser,
/* the HELP dialog */
static void
-dialog_help_callback (GtkWidget *widget,
+dialog_help_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser)
{
if(dbbrowser)
@@ -660,11 +763,11 @@ dialog_help_callback (GtkWidget *widget,
/* end of the dialog */
static void
-dialog_close_callback (GtkWidget *widget,
+dialog_close_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser)
{
GtkWidget *dlg;
-
+
if(dbbrowser)
{
dlg = dbbrowser->dialog;
@@ -681,27 +784,55 @@ dialog_close_callback (GtkWidget *widget,
}
}
+/* ---------------------------------------
+ * p_radio_callback
+ * ---------------------------------------
+ */
+static void
+p_radio_callback(GtkWidget *wgt, gpointer user_data)
+{
+ dbbrowser_t *dbbrowser;
+
+ if(gap_debug) printf("p_radio_callback: START\n");
+ dbbrowser = (dbbrowser_t *)user_data;
+ if(dbbrowser != NULL)
+ {
+ if(dbbrowser->result != NULL)
+ {
+ if(wgt == dbbrowser->radio_grp_process) { dbbrowser->result->groupFilterHandlingMode =
GAP_GROUP_FILTER_HANDLING_NORMAL; }
+ if(wgt == dbbrowser->radio_grp_skip) { dbbrowser->result->groupFilterHandlingMode =
GAP_GROUP_FILTER_HANDLING_SKIP; }
+ if(wgt == dbbrowser->radio_grp_merge) { dbbrowser->result->groupFilterHandlingMode =
GAP_GROUP_FILTER_HANDLING_MERGE; }
+
+ if(gap_debug)
+ {
+ printf("p:radio_callback: value: %d\n", (int)dbbrowser->result->groupFilterHandlingMode);
+ }
+ }
+ }
+} /* end p_radio_callback */
+
+
/* GAP dialog_num_button_callback (end of the dialog) */
-static void
-dialog_num_button_callback (dbbrowser_t* dbbrowser,
+static void
+dialog_num_button_callback (dbbrowser_t* dbbrowser,
gint button_nr)
{
- if (dbbrowser->selected_proc_name==NULL)
+ if (dbbrowser->selected_proc_name==NULL)
{
return;
}
strcpy(dbbrowser->result->selected_proc_name, dbbrowser->selected_proc_name);
dbbrowser->result->button_nr = button_nr;
-
+
gtk_widget_hide(dbbrowser->dialog);
dialog_close_callback(NULL, dbbrowser);
-
+
} /* end dialog_num_button_callback */
/* GAP APPLY const callback */
-static void
+static void
dialog_button_1_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
{
dialog_num_button_callback(dbbrowser, 0);
@@ -709,7 +840,7 @@ dialog_button_1_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
/* CODEGEN callback (does not close the dialog) */
-static void
+static void
dialog_button_3_callback (GtkWidget *widget, dbbrowser_t* dbbrowser)
{
gap_codegen_remove_codegen_files(); /* remove old versions of generated CODE */
@@ -744,8 +875,8 @@ p_accel_spinbutton_callback(GtkObject *obj, dbbrowser_t* dbbrowser)
/* search in the whole db */
-static void
-dialog_search_callback (GtkWidget *widget,
+static void
+dialog_search_callback (GtkWidget *widget,
dbbrowser_t *dbbrowser)
{
gchar **proc_list;
@@ -780,7 +911,7 @@ dialog_search_callback (GtkWidget *widget,
}
gimp_procedural_db_query (query->str,
- ".*", ".*", ".*", ".*", ".*", ".*",
+ ".*", ".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
g_string_free (query, TRUE);
@@ -789,7 +920,7 @@ dialog_search_callback (GtkWidget *widget,
{
dialog_show_message (dbbrowser, _("Searching by blurb - please wait"));
- gimp_procedural_db_query (".*",
+ gimp_procedural_db_query (".*",
(gchar *) gtk_entry_get_text
(GTK_ENTRY (dbbrowser->search_entry)),
".*", ".*", ".*", ".*", ".*",
@@ -806,7 +937,7 @@ dialog_search_callback (GtkWidget *widget,
dialog_show_message (dbbrowser, _("Searching - please wait"));
}
- gimp_procedural_db_query (".*", ".*", ".*", ".*", ".*", ".*", ".*",
+ gimp_procedural_db_query (".*", ".*", ".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
}
@@ -815,7 +946,7 @@ dialog_search_callback (GtkWidget *widget,
GTK_TREE_MODEL (dbbrowser->store));
g_object_unref (dbbrowser->store);
-
+
pattern = NULL;
query_text = gtk_entry_get_text (GTK_ENTRY (dbbrowser->search_entry));
if (query_text && strlen (query_text))
@@ -825,12 +956,12 @@ dialog_search_callback (GtkWidget *widget,
for (i = 0; i < num_procs; i++)
{
gboolean pre_selection;
-
+
pre_selection = FALSE;
if (widget == dbbrowser->menupath_button)
{
gchar *menu_path;
-
+
menu_path = gap_db_get_plugin_menupath(proc_list[i]);
if(menu_path)
{
@@ -854,12 +985,12 @@ dialog_search_callback (GtkWidget *widget,
}
else
{
- /* for all other cases than menupath_button
- * the pre_selection was already done at gimp_procedural_db_query
+ /* for all other cases than menupath_button
+ * the pre_selection was already done at gimp_procedural_db_query
*/
- pre_selection = TRUE;
+ pre_selection = TRUE;
}
-
+
if (pre_selection)
{
/* the filter constraint_function checks if the
@@ -869,7 +1000,7 @@ dialog_search_callback (GtkWidget *widget,
if (0 != (dbbrowser->constraint_func)((char *)proc_list[i], dbbrowser->current_image_id))
{
i_added++;
-
+
if((dbbrowser->codegen_flag != 0) && (gap_debug))
{
gap_codegen_gen_forward_iter_ALT(proc_list[i]);
@@ -891,10 +1022,10 @@ dialog_search_callback (GtkWidget *widget,
g_free (proc_list);
- /* now sort the store */
+ /* now sort the store */
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dbbrowser->store),
0, GTK_SORT_ASCENDING);
-
+
if (i_added > 0)
{
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dbbrowser->store), &iter);
@@ -908,7 +1039,7 @@ dialog_search_callback (GtkWidget *widget,
/* utils ... */
-static void
+static void
convert_string (gchar *str)
{
while (*str)
@@ -952,8 +1083,8 @@ convert_string (gchar *str)
// default: return "UNKNOWN?";
// }
// }
-//
-//
+//
+//
// static const gchar *
// GimpPDBProcType_to_string (GimpPDBProcType type)
// {
@@ -984,11 +1115,11 @@ gap_db_get_plugin_menupath (const gchar *search_text)
gchar **types_strs;
gchar **realname_strs;
gint *time_ints;
-
+
gchar *menu_path;
menu_path = NULL;
-
+
if (!initialized)
{
/* query for all elements (only at 1.st call in this process)
@@ -1005,14 +1136,14 @@ gap_db_get_plugin_menupath (const gchar *search_text)
{
initialized = TRUE;
}
-
+
}
if (initialized)
{
int loop;
int num_plugins;
-
+
num_plugins = return_vals[1].data.d_int32;
menu_strs = return_vals[2].data.d_stringarray;
accel_strs = return_vals[4].data.d_stringarray;
diff --git a/gap/gap_dbbrowser_utils.h b/gap/gap_dbbrowser_utils.h
index 03c09bb..e85e68f 100644
--- a/gap/gap_dbbrowser_utils.h
+++ b/gap/gap_dbbrowser_utils.h
@@ -17,17 +17,17 @@
*/
-/*
+/*
gap_dbbrowser_utils.h (original code dbbrowser_utils.h by Thomas NOEL <thomas minet net>
-
+
09. dec .1998 hof: update for GIMP 1.1
20. dec .1997 hof: GAP variant of DBbrowser
removed apply_callback
- added constraint_procedure,
+ added constraint_procedure,
added 2 buttons
added return type
- 0.08 26th sept 97 by Thomas NOEL <thomas minet net>
+ 0.08 26th sept 97 by Thomas NOEL <thomas minet net>
*/
#ifndef _GAP_DB_BROWSER_UTILS_H
@@ -35,10 +35,16 @@
#include "libgimp/gimp.h"
+#define GAP_GROUP_FILTER_HANDLING_NORMAL 0
+#define GAP_GROUP_FILTER_HANDLING_SKIP 1
+#define GAP_GROUP_FILTER_HANDLING_MERGE 2
+
+
typedef struct {
char selected_proc_name[256];
int button_nr; /* -1 on cancel, 0 .. n */
gint32 accelCharacteristic;
+ gint32 groupFilterHandlingMode;
} GapDbBrowserResult;
/* proc to check if to add or not to add the procedure to the browsers listbox
diff --git a/gap/gap_edge_detection.c b/gap/gap_edge_detection.c
index 7695acc..cc6994f 100644
--- a/gap/gap_edge_detection.c
+++ b/gap/gap_edge_detection.c
@@ -119,7 +119,7 @@ p_get_debug_coords_from_guides(gint32 image_id, gint *cx, gint *cy)
*cx = guideCol;
*cy = guideRow;
- //if(gap_debug)
+ if(gap_debug)
{
printf("image_id:%d guideCol:%d :%d\n"
,(int)image_id
diff --git a/gap/gap_fg_matting_dialog.c b/gap/gap_fg_matting_dialog.c
index 7c5c830..3f5992b 100644
--- a/gap/gap_fg_matting_dialog.c
+++ b/gap/gap_fg_matting_dialog.c
@@ -123,7 +123,7 @@ p_init_widget_values(FgExtractDialogGuiStuff *guiStuffPtr)
{
comboInitalValue = GAP_FG_USE_LAYER_MASK;
}
- else if(gimp_drawable_is_valid(guiStuffPtr->vals->tri_map_drawable_id))
+ else if(gimp_item_is_valid(guiStuffPtr->vals->tri_map_drawable_id))
{
comboInitalValue = guiStuffPtr->vals->tri_map_drawable_id;
}
@@ -282,11 +282,11 @@ p_tri_map_combo_constrain(gint32 image_id, gint32 drawable_id, FgExtractDialogGu
return(TRUE);
}
- if(gimp_drawable_is_valid(drawable_id) != TRUE)
+ if(gimp_item_is_valid(drawable_id) != TRUE)
{
if(gap_debug)
{
- printf("-- drawable_id:%d gimp_drawable_is_valid --\n", (int)drawable_id);
+ printf("-- drawable_id:%d gimp_item_is_valid --\n", (int)drawable_id);
}
return(FALSE);
}
@@ -455,7 +455,7 @@ do_dialog (FgExtractDialogGuiStuff *guiStuffPtr, GapFgExtractValues *cuvals)
gint comboInitalValue;
comboInitalValue = -1;
- if(gimp_drawable_is_valid(guiStuffPtr->vals->tri_map_drawable_id))
+ if(gimp_item_is_valid(guiStuffPtr->vals->tri_map_drawable_id))
{
comboInitalValue = guiStuffPtr->vals->tri_map_drawable_id;
}
diff --git a/gap/gap_filter_foreach.c b/gap/gap_filter_foreach.c
index 0034489..6a07968 100644
--- a/gap/gap_filter_foreach.c
+++ b/gap/gap_filter_foreach.c
@@ -71,10 +71,14 @@
#include "gap_filter_pdb.h"
#include "gap_dbbrowser_utils.h"
#include "gap_lib.h"
+#include "gap_base.h"
+#include "gap_image.h"
#include "gap_accel_char.h"
#define GAP_DB_BROWSER_FILTERALL_HELP_ID "gap-filterall-db-browser"
+#define GAP_FILTERALL_LAYERS_ENABLE_PITSTOP_DIALOG "gap-filterall-enable-pitstop-dialog"
+
/* ------------------------
* global gap DEBUG switch
* ------------------------
@@ -93,10 +97,14 @@ static gint p_pitstop(GimpRunMode run_mode, char *plugin_name, gint text_flag,
static void p_visibilty_restore(gint32 image_id, gint nlayers, int *visible_tab, char *plugin_name);
static gint32 p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_name);
+
+static gint p_call_pdb_filter_plugin(char *canonical_plugin_name, gint32 image_id, gint32 layer_id,
GimpRunMode run_mode
+ , gint32 groupFilterHandlingMode);
+
static int p_foreach_multilayer(GimpRunMode run_mode, gint32 image_id,
- const char *plugin_name, gint32 accelCharacteristic);
+ const char *plugin_name, gint32 accelCharacteristic, gint32
groupFilterHandlingMode);
static int p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
- char *canonical_plugin_name, gint32 accelCharacteristic);
+ char *canonical_plugin_name, gint32 accelCharacteristic, gint32
groupFilterHandlingMode);
/* ------------------------
* p_gdisplays_update_full
@@ -118,24 +126,35 @@ p_pitstop(GimpRunMode run_mode, char *plugin_name, gint text_flag,
char *step_backup_file, gint len_step_backup_file,
gint32 layer_idx)
{
- const gchar *l_env;
gchar *l_msg;
static GapArrButtonArg l_but_argv[3];
gint l_but_argc;
gint l_argc;
- static GapArrArg l_argv[1];
+ static GapArrArg l_argv[2];
int l_continue;
char l_skip_txt[32];
-
-
-
- gap_arr_arg_init(&l_argv[0], GAP_ARR_WGT_FILESEL);
- l_argv[0].label_txt = _("Backup to file");
- l_argv[0].entry_width = 140; /* pixel */
- l_argv[0].help_txt = _("Make backup of the image after each step");
- l_argv[0].text_buf_len = len_step_backup_file;
- l_argv[0].text_buf_ret = step_backup_file;
-
+ int l_ii;
+ int l_ii_gimprc;
+
+
+ l_ii = 0;
+ l_ii_gimprc = l_ii;
+ gap_arr_arg_init(&l_argv[l_ii], GAP_ARR_WGT_TOGGLE);
+ l_argv[l_ii].label_txt = _("do not show this dialog again");
+ l_argv[l_ii].help_txt = g_strdup_printf(_("add %s to gimprc configuration to disable this dialog in all
further sessions")
+ ,GAP_FILTERALL_LAYERS_ENABLE_PITSTOP_DIALOG );
+ l_argv[l_ii].int_ret = FALSE;
+ l_argv[l_ii].int_default = FALSE;
+ l_argv[l_ii].has_default = TRUE;
+
+ l_ii = 1;
+ gap_arr_arg_init(&l_argv[l_ii], GAP_ARR_WGT_FILESEL);
+ l_argv[l_ii].label_txt = _("Backup to file");
+ l_argv[l_ii].entry_width = 140; /* pixel */
+ l_argv[l_ii].help_txt = _("Make backup of the image after each step");
+ l_argv[l_ii].text_buf_len = len_step_backup_file;
+ l_argv[l_ii].text_buf_ret = step_backup_file;
+
l_but_argv[0].but_txt = _("Continue");
l_but_argv[0].but_val = 0;
l_but_argv[1].but_txt = GTK_STOCK_CANCEL;
@@ -145,18 +164,15 @@ p_pitstop(GimpRunMode run_mode, char *plugin_name, gint text_flag,
l_but_argv[2].but_val = 1;
l_but_argc = 2;
- l_argc = 0;
+ l_argc = 1;
/* optional dialog between both calls (to see the effect of 1.call) */
if(run_mode == GIMP_RUN_INTERACTIVE)
{
- l_env = g_getenv("GAP_FILTER_PITSTOP");
- if(l_env != NULL)
+ if(!gap_base_get_gimprc_gboolean_value(GAP_FILTERALL_LAYERS_ENABLE_PITSTOP_DIALOG, TRUE))
{
- if((*l_env == 'N') || (*l_env == 'n'))
- {
- return 0; /* continue without question */
- }
+ return 0; /* continue without question */
}
+
if(text_flag == 0)
{
l_msg = g_strdup_printf (_("2nd call of %s\n(define end-settings)"), plugin_name);
@@ -165,12 +181,17 @@ p_pitstop(GimpRunMode run_mode, char *plugin_name, gint text_flag,
{
l_msg = g_strdup_printf (_("Non-Interactive call of %s\n(for all layers in between)"), plugin_name);
l_but_argc = 3;
- l_argc = 1;
+ l_argc = 2;
}
l_continue = gap_arr_std_dialog (_("Animated Filter Apply"), l_msg,
l_argc, l_argv,
l_but_argc, l_but_argv, 0);
g_free (l_msg);
+
+ if ((l_argv[l_ii_gimprc].int_ret != FALSE) && (l_continue ==0))
+ {
+ gimp_gimprc_set(GAP_FILTERALL_LAYERS_ENABLE_PITSTOP_DIALOG, "no");
+ }
if(l_continue < 0) return -1;
else return l_continue;
@@ -193,23 +214,29 @@ p_visibilty_restore(gint32 image_id, gint nlayers, int *visible_tab, char *plugi
gint l_nlayers2;
gint32 l_idx;
- l_layers_list = gimp_image_get_layers(image_id, &l_nlayers2);
- if(l_nlayers2 == nlayers)
- {
- for(l_idx = 0; l_idx < nlayers; l_idx++)
- {
- gimp_item_set_visible(l_layers_list[l_idx], visible_tab[l_idx]);
- if(gap_debug) printf("visibilty restore [%d] %d\n", (int)l_idx, (int)visible_tab[l_idx]);
- }
- p_gdisplays_update_full(image_id);
- }
- else
+ l_layers_list = gimp_image_get_layers(image_id, &l_nlayers2);
+ if(l_nlayers2 == nlayers)
+ {
+ for(l_idx = 0; l_idx < nlayers; l_idx++)
+ {
+ gimp_item_set_visible(l_layers_list[l_idx], visible_tab[l_idx]);
+ if(gap_debug)
{
- printf ("Error: Plugin %s has changed Nr. of layers from %d to %d\ncould not restore Layer
visibilty.\n",
- plugin_name, (int)nlayers, (int)l_nlayers2);
+ printf("visibilty restore [%d] %d\n"
+ , (int)l_idx
+ , (int)visible_tab[l_idx]
+ );
}
+ }
+ p_gdisplays_update_full(image_id);
+ }
+ else
+ {
+ g_message(_("Error: Plugin %s has changed the number of layers from %d to %d\ncould not restore Layer
visibilty.\n"),
+ plugin_name, (int)nlayers, (int)l_nlayers2);
+ }
- g_free (l_layers_list);
+ g_free (l_layers_list);
}
/* ------------------------
@@ -242,6 +269,76 @@ p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_n
return (l_layer_id);
}
+/* ---------------------------------------
+ * p_call_pdb_filter_plugin
+ * ---------------------------------------
+ * apply the given filter (canonical_plugin_name) on the specified layer_id
+ * In case the specified layer_id is a group layer
+ * the groupFilterHandlingMode
+ */
+static gint
+p_call_pdb_filter_plugin(char *canonical_plugin_name, gint32 image_id, gint32 layer_id, GimpRunMode run_mode
+ , gint32 groupFilterHandlingMode)
+{
+ gint32 l_resulting_item_id;
+
+ if(gap_debug)
+ {
+ printf("p_call_pdb_filter_plugin: %s image_id:%d layer_id:%d (%s), run_mode:%d,
groupFilterHandlingMode:%d\n"
+ , canonical_plugin_name
+ , (int)image_id
+ , (int)layer_id
+ , gimp_item_get_name(layer_id)
+ , (int)run_mode
+ , (int)groupFilterHandlingMode
+ );
+ }
+
+ l_resulting_item_id = layer_id;
+ if (gimp_item_is_group(layer_id))
+ {
+ if(groupFilterHandlingMode == GAP_GROUP_FILTER_HANDLING_SKIP)
+ {
+ if (run_mode == GIMP_RUN_INTERACTIVE)
+ {
+ /* fail because skipping of the interactive calls
+ * is not allowed (those calls are required to setup the last values buffer)
+ */
+ return (-1);
+ }
+ return (0); /* fake OK to skip processing of this group layer */
+ }
+
+ if(groupFilterHandlingMode == GAP_GROUP_FILTER_HANDLING_MERGE)
+ {
+ l_resulting_item_id = gap_image_merge_group_layer( image_id
+ , layer_id
+ , GIMP_EXPAND_AS_NECESSARY
+ );
+ }
+ }
+ if (l_resulting_item_id < 0)
+ {
+ return (-1);
+ }
+
+ if(gap_debug)
+ {
+ printf("p_call_pdb_filter_plugin: %s image_id:%d l_resulting_item_id:%d (%s), run_mode:%d,
groupFilterHandlingMode:%d\n"
+ , canonical_plugin_name
+ , (int)image_id
+ , (int)l_resulting_item_id
+ , gimp_item_get_name(l_resulting_item_id)
+ , (int)run_mode
+ , (int)groupFilterHandlingMode
+ );
+ }
+ return (gap_filt_pdb_call_plugin(canonical_plugin_name, image_id, l_resulting_item_id, run_mode));
+
+
+} /* end p_call_pdb_filter_plugin */
+
+
/* ----------------------
* p_foreach_multilayer
* ----------------------
@@ -251,31 +348,33 @@ p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_n
*/
static int
p_foreach_multilayer(GimpRunMode run_mode, gint32 image_id,
- const char *plugin_name, gint32 accelCharacteristic)
+ const char *plugin_name, gint32 accelCharacteristic, gint32 groupFilterHandlingMode)
{
char *canonical_plugin_name;
int rc;
-
+
canonical_plugin_name = gimp_canonicalize_identifier(plugin_name);
- rc = p_foreach_multilayer2(run_mode, image_id, canonical_plugin_name, accelCharacteristic);
-
+ gimp_image_undo_group_start (image_id);
+ rc = p_foreach_multilayer2(run_mode, image_id, canonical_plugin_name, accelCharacteristic,
groupFilterHandlingMode);
+ gimp_image_undo_group_end (image_id);
+
g_free(canonical_plugin_name);
return (rc);
-
+
} /* ennd p_foreach_multilayer */
/* ----------------------
* p_foreach_multilayer2
* ----------------------
- * apply the given plugin to each layer of the image.
+ * apply the given plugin to each toplevel layer of the image.
* returns image_id of the new created multilayer image
* (or -1 on error)
*/
static int
p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
- char *canonical_plugin_name, gint32 accelCharacteristic)
+ char *canonical_plugin_name, gint32 accelCharacteristic, gint32
groupFilterHandlingMode)
{
static char l_key_from[512];
static char l_key_to[512];
@@ -287,8 +386,6 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
gdouble l_percentage, l_percentage_step;
int l_rc;
gint l_plugin_data_len;
- long l_child_pid;
- /* int l_status; */
int *l_visible_tab;
char l_step_backup_file[120];
gint l_pit_rc;
@@ -331,7 +428,9 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
/* allocate a table to store the visibility attributes for each layer */
l_visible_tab = (gint*) g_malloc((l_nlayers +1) * sizeof (gint));
if(l_visible_tab == NULL)
+ {
return -1;
+ }
/* save the visibility of all layers */
for(l_idx = 0; l_idx < l_nlayers; l_idx++)
@@ -350,54 +449,52 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
if((l_plugin_iterator != NULL) && (l_nlayers > 1) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE ))
{
- l_child_pid = 0; /* fork(); */
- if(l_child_pid < 0)
+ /* call plugin Interactive for background layer[n] */
+ if(gap_debug)
{
- printf("ERROR: fork failed !\n");
- return -1;
+ printf("DEBUG start 1.st Interactive call (_FROM values)\n");
}
- /* if(l_child_pid != 0) */
+ l_idx = l_nlayers -1;
+ l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_idx, canonical_plugin_name);
+ if(l_layer_id < 0)
+ {
+ l_rc = -1;
+ }
+ else
{
- /* parent process: call plugin Interactive for background layer[n] */
- /* if(gap_debug) printf("forked child process pid=%ld\n", l_child_pid); */
if(gap_debug)
{
- printf("DEBUG start 1.st Interactive call (_FROM values)\n");
- }
-
- l_idx = l_nlayers -1;
- l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_idx, canonical_plugin_name);
- if(l_layer_id < 0)
+ printf("DEBUG: applying %s on Layerstack %d id=%d\n", canonical_plugin_name, (int)l_idx,
(int)l_layer_id);
+ }
+ l_rc = p_call_pdb_filter_plugin(canonical_plugin_name, image_id, l_layer_id
+ , GIMP_RUN_INTERACTIVE, groupFilterHandlingMode);
+
+ /* get values, then store with suffix "-ITER-FROM" */
+ l_plugin_data_len = gap_filt_pdb_get_data(canonical_plugin_name);
+ if(l_plugin_data_len > 0)
{
- l_rc = -1;
+ g_snprintf(l_key_from, sizeof(l_key_from), "%s%s", canonical_plugin_name, GAP_ITER_FROM_SUFFIX);
+ gap_filt_pdb_set_data(l_key_from, l_plugin_data_len);
}
else
{
- if(gap_debug) printf("DEBUG: apllying %s on Layerstack %d id=%d\n", canonical_plugin_name,
(int)l_idx, (int)l_layer_id);
- l_rc = gap_filt_pdb_call_plugin(canonical_plugin_name, image_id, l_layer_id,
GIMP_RUN_INTERACTIVE);
-
- /* get values, then store with suffix "-ITER-FROM" */
- l_plugin_data_len = gap_filt_pdb_get_data(canonical_plugin_name);
- if(l_plugin_data_len > 0)
- {
- g_snprintf(l_key_from, sizeof(l_key_from), "%s%s", canonical_plugin_name,
GAP_ITER_FROM_SUFFIX);
- gap_filt_pdb_set_data(l_key_from, l_plugin_data_len);
- }
- else l_rc = -1;
+ l_rc = -1;
+ }
- if(run_mode == GIMP_RUN_INTERACTIVE)
- {
- l_percentage += l_percentage_step;
- gimp_progress_update (l_percentage);
- }
+ if(run_mode == GIMP_RUN_INTERACTIVE)
+ {
+ l_percentage += l_percentage_step;
+ gimp_progress_update (l_percentage);
}
}
- /* else */
+
if((l_rc >= 0) && (l_nlayers > 1))
{
- /* child process: call plugin Interactive for top layer [0] */
- if(gap_debug) printf("DEBUG start 2.nd Interactive call (_TO values)\n");
+ if(gap_debug)
+ {
+ printf("DEBUG start 2.nd Interactive call (_TO values)\n");
+ }
/* optional dialog between both calls (to see the effect of 1.call) */
if(p_pitstop(run_mode, canonical_plugin_name, 0,
@@ -425,7 +522,8 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
p_gdisplays_update_full(image_id);
if(gap_debug) printf("DEBUG: apllying %s on Layerstack 0 id=%d\n", canonical_plugin_name,
(int)l_layer_id);
- l_rc = gap_filt_pdb_call_plugin(canonical_plugin_name, image_id, l_layer_id,
GIMP_RUN_INTERACTIVE);
+ l_rc = p_call_pdb_filter_plugin(canonical_plugin_name, image_id, l_layer_id
+ , GIMP_RUN_INTERACTIVE, groupFilterHandlingMode);
/* get values, then store with suffix "-ITER-TO" */
l_plugin_data_len = gap_filt_pdb_get_data(canonical_plugin_name);
@@ -434,7 +532,10 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
g_snprintf(l_key_to, sizeof(l_key_to), "%s%s", canonical_plugin_name, GAP_ITER_TO_SUFFIX);
gap_filt_pdb_set_data(l_key_to, l_plugin_data_len);
}
- else l_rc = -1;
+ else
+ {
+ l_rc = -1;
+ }
if(run_mode == GIMP_RUN_INTERACTIVE)
{
@@ -450,9 +551,6 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
}
l_top_layer = 1;
-
- /* wait until exit of childprocess */
- /* waitpid(l_child_pid, &l_status, 0); */
}
else
{
@@ -468,7 +566,8 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
else
{
if(gap_debug) printf("DEBUG: NO Varying, applying %s on Layer id=%d\n", canonical_plugin_name,
(int)l_layer_id);
- l_rc = gap_filt_pdb_call_plugin(canonical_plugin_name, image_id, l_layer_id,
GIMP_RUN_INTERACTIVE);
+ l_rc = p_call_pdb_filter_plugin(canonical_plugin_name, image_id, l_layer_id
+ , GIMP_RUN_INTERACTIVE, groupFilterHandlingMode);
l_top_layer = 0;
if(run_mode == GIMP_RUN_INTERACTIVE)
{
@@ -514,7 +613,7 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
, canonical_plugin_name
, (int)l_idx
, (int)l_layer_id
- , (int)l_nlayers -1
+ , (int)l_nlayers -1
, (int)l_idx
);
}
@@ -523,8 +622,8 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
if((l_plugin_iterator != NULL) && (accelCharacteristic != GAP_ACCEL_CHAR_NONE ))
{
gdouble accelStep;
-
-
+
+
accelStep = gap_calculate_current_step_with_acceleration((gdouble)l_idx, l_nlayers -1,
accelCharacteristic);
/* call plugin-specific iterator (or the common iterator), to modify
* the plugin's last_values
@@ -540,12 +639,16 @@ p_foreach_multilayer2(GimpRunMode run_mode, gint32 image_id,
}
}
- if(l_rc < 0) break;
+ if(l_rc < 0)
+ {
+ break;
+ }
if(l_pit_rc == 0) /* 0 == continue without further dialogs */
{
/* call the plugin itself with runmode RUN_WITH_LAST_VALUES */
- l_rc = gap_filt_pdb_call_plugin(canonical_plugin_name, image_id, l_layer_id,
GIMP_RUN_WITH_LAST_VALS);
+ l_rc = p_call_pdb_filter_plugin(canonical_plugin_name, image_id, l_layer_id
+ , GIMP_RUN_WITH_LAST_VALS, groupFilterHandlingMode);
/* check if to save each step to backup file */
if((l_step_backup_file[0] != '\0') && (l_step_backup_file[0] != ' '))
{
@@ -589,7 +692,9 @@ gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *plugin_name
, gint32 accelCharacteristic)
{
GapDbBrowserResult l_browser_result;
+ gint l_rc;
l_browser_result.accelCharacteristic = GAP_ACCEL_CHAR_LINEAR;
+ l_browser_result.groupFilterHandlingMode = GAP_GROUP_FILTER_HANDLING_NORMAL;
if(run_mode == GIMP_RUN_INTERACTIVE)
{
@@ -610,13 +715,13 @@ gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *plugin_name
}
strcpy(plugin_name, l_browser_result.selected_proc_name);
-
+
/* invert acceleration to deceleration and vice versa
- * (because processing layer indexes is done from high to low values)
+ * (because processing layer indexes is done from high to low values)
*/
accelCharacteristic = (-1 * l_browser_result.accelCharacteristic);
- if(gap_debug)
+ if(gap_debug)
{
printf("DEBUG: gap_db_browser_dialog SELECTED:%s accelCharacteristic:%d\n"
, plugin_name
@@ -626,9 +731,10 @@ gap_proc_anim_apply(GimpRunMode run_mode, gint32 image_id, char *plugin_name
}
- return(p_foreach_multilayer(run_mode,
+ l_rc = p_foreach_multilayer(run_mode,
image_id,
plugin_name,
- accelCharacteristic ));
-
+ accelCharacteristic,
+ l_browser_result.groupFilterHandlingMode);
+ return(l_rc);
}
diff --git a/gap/gap_filter_iterators.c b/gap/gap_filter_iterators.c
index 882e0c0..1af857e 100644
--- a/gap/gap_filter_iterators.c
+++ b/gap/gap_filter_iterators.c
@@ -98,6 +98,7 @@
#include "gap_frame_fetcher.h"
#include "gap_drawable_vref_parasite.h"
#include "gap_lib.h"
+#include "gap_image.h"
#include "gap/gap_layer_copy.h"
@@ -447,6 +448,7 @@ p_delta_drawable_simple(gint32 *val, gint32 val_from, gint32 val_to, gint32 tota
gint l_nlayers;
gint32 *l_layers_list;
gint32 l_tmp_image_id;
+ gint32 l_parent_id;
gint l_idx, l_idx_from, l_idx_to;
if(gap_debug)
@@ -461,25 +463,36 @@ p_delta_drawable_simple(gint32 *val, gint32 val_from, gint32 val_to, gint32 tota
{
return;
}
- if(gimp_drawable_is_valid(val_from) != TRUE)
+ if(gimp_item_is_valid(val_from) != TRUE)
{
return;
}
- if(gimp_drawable_is_valid(val_to) != TRUE)
+ if(gimp_item_is_valid(val_to) != TRUE)
{
return;
}
l_tmp_image_id = gimp_item_get_image(val_from);
+ l_parent_id = gimp_item_get_parent(val_from);
- /* check if from and to values are both valid drawables within the same image */
+ /* check if from and to values are both valid drawables
+ * within the same image at same level
+ */
if ((l_tmp_image_id > 0)
- && (l_tmp_image_id = gimp_item_get_image(val_to)))
+ && (l_tmp_image_id == gimp_item_get_image(val_to))
+ && (l_parent_id == gimp_item_get_parent(val_to)))
{
l_idx_from = -1;
l_idx_to = -1;
/* check the layerstack index of from and to drawable */
- l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers);
+ if (l_parent_id > 0)
+ {
+ l_layers_list = gimp_item_get_children(l_parent_id, &l_nlayers);
+ }
+ else
+ {
+ l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers);
+ }
for (l_idx = l_nlayers -1; l_idx >= 0; l_idx--)
{
if( l_layers_list[l_idx] == val_from ) l_idx_from = l_idx;
@@ -498,6 +511,7 @@ p_delta_drawable_simple(gint32 *val, gint32 val_from, gint32 val_to, gint32 tota
} /* end p_delta_drawable_simple */
+
/* --------------------------------------------
* p_capture_image_name_and_assign_pesistent_id
* --------------------------------------------
@@ -525,6 +539,7 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
gint32 stackposition;
gint32 track;
char *filename;
+ char *parentpositions;
if(gap_debug)
@@ -534,7 +549,7 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
);
}
- if(gimp_drawable_is_valid(drawable_id) != TRUE)
+ if(gimp_item_is_valid(drawable_id) != TRUE)
{
/* drawable is no longer valid and can not be mapped.
* This may happen if the layer was removed or the refered image was closed
@@ -546,6 +561,7 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
persistent_drawable_id = drawable_id;
filename = NULL;
+ parentpositions = NULL;
dvref = gap_dvref_get_drawable_video_reference_via_parasite(drawable_id);
if (dvref != NULL)
@@ -570,6 +586,7 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
image_id = gimp_item_get_image(drawable_id);
filename = gimp_image_get_filename(image_id);
+ parentpositions = gap_image_get_parentpositions_as_int_stringlist(drawable_id);
ainfo_type = GAP_AINFO_ANIMIMAGE;
stackposition = gap_layer_get_stackposition(image_id, drawable_id);
track = 1;
@@ -616,6 +633,7 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
persistent_drawable_id = gap_fmct_add_GapFmacRefEntry(ainfo_type
, frame_nr
, stackposition
+ , parentpositions
, track
, drawable_id
, filename
@@ -625,6 +643,10 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
g_free(filename);
}
+ if(parentpositions != NULL)
+ {
+ g_free(parentpositions);
+ }
if(gap_debug)
{
@@ -638,6 +660,8 @@ p_capture_image_name_and_assign_pesistent_id(GapFmacContext *fmacContext, gint32
} /* end p_capture_image_name_and_assign_pesistent_id */
+
+
/* -------------------------------------
* p_iteration_by_pesistent_id
* -------------------------------------
@@ -704,16 +728,26 @@ p_iteration_by_pesistent_id(GapFmacContext *fmacContext
if (fmref_entry_from->ainfo_type == GAP_AINFO_ANIMIMAGE)
{
- /* iterate stackposition */
+ /* iterate stackposition (restriction: this is only possible when from and to value are at same
level) */
gint32 stackposition;
+ gboolean isSameLevel;
+
+ isSameLevel = FALSE;
+ if(strcmp(fmref_entry_from->parentpositions, fmref_entry_to->parentpositions) == 0)
+ {
+ isSameLevel = TRUE;
+ }
stackposition = fmref_entry_from->stackposition;
- p_delta_gint32(&stackposition, fmref_entry_from->stackposition, fmref_entry_to->stackposition
+ if (isSameLevel)
+ {
+ p_delta_gint32(&stackposition, fmref_entry_from->stackposition, fmref_entry_to->stackposition
,total_steps, current_step);
-
+ }
fetched_layer_id = gap_frame_fetch_dup_image(fmacContext->ffetch_user_id
,fmref_entry_from->filename /* full filename of the image */
,stackposition /* pick layer by stackposition */
+ ,fmref_entry_from->parentpositions
,TRUE /* enable caching */
);
}
@@ -740,6 +774,7 @@ p_iteration_by_pesistent_id(GapFmacContext *fmacContext
fetched_layer_id = gap_frame_fetch_dup_image(fmacContext->ffetch_user_id
,fmref_entry_from->filename /* full filename of the image */
,-1 /* 0 pick layer on top of stack, -1 merge
visible layers */
+ ,NULL
,TRUE /* enable caching */
);
}
@@ -772,6 +807,7 @@ p_iteration_by_pesistent_id(GapFmacContext *fmacContext
} /* end p_iteration_by_pesistent_id */
+
static void
p_delta_gintdrawable(gint *val, gint val_from, gint val_to, gint32 total_steps, gdouble current_step)
{
diff --git a/gap/gap_fire_pattern.c b/gap/gap_fire_pattern.c
index 64718aa..069f8cd 100644
--- a/gap/gap_fire_pattern.c
+++ b/gap/gap_fire_pattern.c
@@ -299,11 +299,11 @@ p_init_default_cuvals(firepattern_val_t *cuvals)
static void
p_check_for_valid_cloud_layers(firepattern_val_t *cuvals)
{
- if(gimp_drawable_is_valid(cuvals->cloudLayer1) != TRUE)
+ if(gimp_item_is_valid(cuvals->cloudLayer1) != TRUE)
{
cuvals->cloudLayer1 = -1;
}
- if(gimp_drawable_is_valid(cuvals->fireShapeLayer) != TRUE)
+ if(gimp_item_is_valid(cuvals->fireShapeLayer) != TRUE)
{
cuvals->fireShapeLayer = -1;
}
@@ -785,7 +785,7 @@ p_init_context_and_cloud_and_shape_layers(gint32 drawable_id, firepattern_val_t
ctxt->ref_image_id = -1;
/* check if cloud layer (the pattern) is already available */
- if(!gimp_drawable_is_valid(cuvals->cloudLayer1))
+ if(!gimp_item_is_valid(cuvals->cloudLayer1))
{
/* create both cloud layers */
GRand *gr;
@@ -845,7 +845,7 @@ p_init_context_and_cloud_and_shape_layers(gint32 drawable_id, firepattern_val_t
}
- if(!gimp_drawable_is_valid(cuvals->fireShapeLayer))
+ if(!gimp_item_is_valid(cuvals->fireShapeLayer))
{
if((cuvals->createImage != TRUE) || (ctxt->ref_image_id < 0))
{
@@ -1011,7 +1011,7 @@ p_drawable_get_name(gint32 drawable_id)
{
const char *invalidName = "(invalid)";
- if(gimp_drawable_is_valid(drawable_id))
+ if(gimp_item_is_valid(drawable_id))
{
return(gimp_item_get_name(drawable_id));
}
@@ -1434,11 +1434,11 @@ p_init_widget_values(FirePatternDialog *wcd)
}
countClouds = 0;
- if(gimp_drawable_is_valid(wcd->existingCloud1Id))
+ if(gimp_item_is_valid(wcd->existingCloud1Id))
{
countClouds++;
}
- if(gimp_drawable_is_valid(wcd->existingFireShapeLayerId))
+ if(gimp_item_is_valid(wcd->existingFireShapeLayerId))
{
countClouds++;
}
@@ -1621,7 +1621,7 @@ p_pattern_layer_constrain(gint32 image_id, gint32 drawable_id, FirePatternDialog
return(TRUE);
}
- if(gimp_drawable_is_valid(drawable_id) != TRUE)
+ if(gimp_item_is_valid(drawable_id) != TRUE)
{
return(FALSE);
}
@@ -1688,12 +1688,12 @@ do_dialog (FirePatternDialog *wcd, firepattern_val_t *cuvals)
wcd->existingFireShapeLayerId = -1;
wcd->countPotentialCloudLayers = 0;
- if(gimp_drawable_is_valid(cuvals->cloudLayer1))
+ if(gimp_item_is_valid(cuvals->cloudLayer1))
{
wcd->existingCloud1Id = cuvals->cloudLayer1;
wcd->createNewPatternDefault = FALSE;
}
- if(gimp_drawable_is_valid(cuvals->fireShapeLayer))
+ if(gimp_item_is_valid(cuvals->fireShapeLayer))
{
wcd->existingFireShapeLayerId = cuvals->fireShapeLayer;
}
diff --git a/gap/gap_fmac_base.c b/gap/gap_fmac_base.c
index a82c5b8..ccbeb0e 100644
--- a/gap/gap_fmac_base.c
+++ b/gap/gap_fmac_base.c
@@ -804,7 +804,7 @@ p_fmac_execute(GimpRunMode run_mode, gint32 image_id, gint32 drawable_id
*/
gap_frame_fetch_delete_list_of_duplicated_images(fmacContext->ffetch_user_id);
- if(gimp_drawable_is_valid(l_drawable_id) != TRUE)
+ if(gimp_item_is_valid(l_drawable_id) != TRUE)
{
/* the filter ha made the processed drawable_id invalid
* (probably by merging with another layer)
diff --git a/gap/gap_fmac_context.c b/gap/gap_fmac_context.c
index 9fbe4ca..6993cda 100644
--- a/gap/gap_fmac_context.c
+++ b/gap/gap_fmac_context.c
@@ -2,7 +2,7 @@
*
*
* This module handles the filtermacro context.
- * The filtermacro context is used for itration of "persistent drawable ids"
+ * The filtermacro context is used for itration of "persistent drawable ids"
* for animated (or constant) filter apply.
* If gap controlled filterapply is done via a filtermacro
* the iteration is done within a filtermacro context.
@@ -11,7 +11,7 @@
* In this case the "persitent_drawable_id" is used to open the referenced
* image, frame or videoframe at apply time (this may happen in another gimp
* session than the recording of the filtermacro was done).
- *
+ *
*
* Copyright (C) 2008 Wolfgang Hofer <hof gimp org>
*
@@ -77,7 +77,7 @@ gap_fmct_set_derived_lookup_filename(GapFmacContext *fmacContext, const char *fi
* This procedure registers a new frame fetcher resource user_id if playback (e.g NOT recording_mode)
* is used. The drawable_iteration will refere to this ffetch_user_id when fetching
* frames via mapped persistent drawable ids.
- *
+ *
* The current implementation can NOT handle parallell processing of multiple filtermacros
* because there is only ONE context that will be overwritten in case of concurrent calls.
*/
@@ -111,7 +111,7 @@ void
gap_fmct_disable_GapFmacContext(void)
{
gint sizeFmacContext;
-
+
sizeFmacContext = gimp_get_data_size(GAP_FMAC_CONTEXT_KEYWORD);
if(sizeFmacContext == sizeof(GapFmacContext))
@@ -176,7 +176,7 @@ p_parse_string_raw(char **scan_ptr)
{
char *ptr;
char *result_ptr;
-
+
result_ptr = NULL;
ptr = *scan_ptr;
@@ -197,8 +197,8 @@ p_parse_string_raw(char **scan_ptr)
}
ptr++; /* skip white space and continue */
}
-
-
+
+
while(ptr)
{
ptr++;
@@ -231,7 +231,7 @@ p_parse_string_raw(char **scan_ptr)
}
}
}
-
+
return (result_ptr);
} /* end p_parse_string_raw */
@@ -296,6 +296,7 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
long track;
long mtime;
char *filename;
+ char *parentpositions;
id = -1;
ainfo_type = -1;
@@ -304,7 +305,8 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
track = -1;
mtime = -1;
filename = NULL;
-
+ parentpositions = NULL;
+
scan_ptr = line_ptr;
while (scan_ptr != NULL)
{
@@ -319,11 +321,11 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
g_free(l_key);
break;
}
-
+
if (strcmp(l_key, GAP_FMREF_ID) == 0)
{
id = atol(l_value);
- }
+ }
else if (strcmp(l_key, GAP_FMREF_FRAME_NR) == 0)
{
frame_nr = atol(l_value);
@@ -348,7 +350,7 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
{
int len;
char *l_raw_filename;
-
+
l_raw_filename = l_value;
if(gap_debug)
{
@@ -368,6 +370,10 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
}
filename = g_strdup(l_raw_filename);
}
+ else if (strcmp(l_key, GAP_FMREF_PARENTSTACK) == 0)
+ {
+ parentpositions = g_strdup(l_value);
+ }
else
{
printf("WARNING: unkonwn token: %s\n", l_key);
@@ -408,6 +414,7 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
gap_fmct_add_GapFmacRefEntry(ainfo_type
, frame_nr
, stackposition
+ , parentpositions
, track
, id
, filename
@@ -419,6 +426,11 @@ p_parse_and_add_GapFmacRefEntry(GapFmacContext *fmacContext, char *line_ptr)
{
g_free(filename);
}
+ if (parentpositions != NULL)
+ {
+ g_free(parentpositions);
+ }
+
} /* end p_parse_and_add_GapFmacRefEntry */
@@ -456,7 +468,7 @@ gap_fmct_load_GapFmacContext(GapFmacContext *fmacContext)
{
printf("line:%s:\n", txf_ptr->line);
}
-
+
if (line_nr == 1)
{
if (strncmp(txf_ptr->line, GAP_FMREF_FILEHEADER, strlen(GAP_FMREF_FILEHEADER)) != 0)
@@ -482,7 +494,7 @@ gap_fmct_load_GapFmacContext(GapFmacContext *fmacContext)
{
gap_val_free_textfile_lines(txf_ptr_root);
}
-
+
if(gap_debug)
{
gap_fmct_debug_print_GapFmacContext(fmacContext);
@@ -511,17 +523,17 @@ gap_fmct_save_GapFmacContext(GapFmacContext *fmacContext)
printf("ERROR: could not open write file:%s\n", fmacContext->persistent_id_lookup_filename);
return;
}
-
+
fprintf(fp, "%s\n", GAP_FMREF_FILEHEADER);
fprintf(fp, "# type: %d=IMAGE,%d=ANIMIMAGE,%d=FRAMES,%d=MOVIE\n"
, GAP_AINFO_IMAGE, GAP_AINFO_ANIMIMAGE, GAP_AINFO_FRAMES, GAP_AINFO_MOVIE);
- /* write all reference entries in the following format:
+ /* write all reference entries in the following format:
* id:800000 frameNr:000001 stack:-1 file:"frame_000001.xcf" mtime:123455678
*/
for(fmref_entry = fmacContext->fmref_list; fmref_entry != NULL; fmref_entry = fmref_entry->next)
{
- fprintf(fp, "%s%06d %s%06d %s%02d %s%d %s%011d %s%d %s\"%s\"\n"
+ fprintf(fp, "%s%06d %s%06d %s%02d %s%d %s%011d %s%d %s\"%s\""
, GAP_FMREF_ID , fmref_entry->persistent_drawable_id
, GAP_FMREF_FRAME_NR , fmref_entry->frame_nr
, GAP_FMREF_STACK , fmref_entry->stackposition
@@ -530,8 +542,15 @@ gap_fmct_save_GapFmacContext(GapFmacContext *fmacContext)
, GAP_FMREF_TYPE , fmref_entry->ainfo_type
, GAP_FMREF_FILE , fmref_entry->filename
);
+ if (*fmref_entry->parentpositions != '\0')
+ {
+ fprintf(fp, " %s%s"
+ , GAP_FMREF_PARENTSTACK, fmref_entry->parentpositions
+ );
+ }
+ fprintf(fp, "\n");
}
-
+
fclose(fp);
} /* end gap_fmct_save_GapFmacContext */
@@ -554,11 +573,11 @@ gap_fmct_debug_print_GapFmacContext(GapFmacContext *fmacContext)
, fmacContext->recording_mode
, fmacContext->enabled
, fmacContext->ffetch_user_id
- );
+ );
for(fmref_entry = fmacContext->fmref_list; fmref_entry != NULL; fmref_entry = fmref_entry->next)
{
- printf("%s%06d %s%06d %s%02d %s%d %s%011d %s%d %s\"%s\"\n"
+ printf("%s%06d %s%06d %s%02d %s%d %s%011d %s%d %s\"%s\" %s%s\n"
, GAP_FMREF_ID , fmref_entry->persistent_drawable_id
, GAP_FMREF_FRAME_NR , fmref_entry->frame_nr
, GAP_FMREF_STACK , fmref_entry->stackposition
@@ -566,6 +585,7 @@ gap_fmct_debug_print_GapFmacContext(GapFmacContext *fmacContext)
, GAP_FMREF_MTIME , fmref_entry->mtime
, GAP_FMREF_TYPE , fmref_entry->ainfo_type
, GAP_FMREF_FILE , fmref_entry->filename
+ , GAP_FMREF_PARENTSTACK , fmref_entry->parentpositions
);
}
@@ -594,7 +614,7 @@ gap_fmct_get_GapFmacRefEntry_by_persitent_id(GapFmacContext *fmacContext, gint32
}
}
return (NULL);
-
+
} /* end gap_fmct_get_GapFmacRefEntry_by_persitent_id */
/* --------------------------------------------
@@ -605,6 +625,7 @@ gint32
gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
, gint32 frame_nr
, gint32 stackposition
+ , char *parentpositions
, gint32 track
, gint32 drawable_id
, const char *filename
@@ -614,11 +635,12 @@ gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
GapFmacRefEntry *new_fmref_entry;
GapFmacRefEntry *fmref_entry;
gint32 l_max_persistent_drawable_id;
-
+ char l_parentpositions[300];
+
if(filename == NULL)
{
return (drawable_id);
- }
+ }
if(!g_file_test(filename, G_FILE_TEST_EXISTS))
{
return (drawable_id);
@@ -626,9 +648,17 @@ gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
if(fmacContext == NULL)
{
return (drawable_id);
- }
-
+ }
+ l_parentpositions[0] = '\0';
+ if (parentpositions != NULL)
+ {
+ g_snprintf(l_parentpositions
+ , sizeof(l_parentpositions)
+ , "%s"
+ , parentpositions
+ );
+ }
l_max_persistent_drawable_id = GAP_FMCT_MIN_PERSISTENT_DRAWABLE_ID;
/* check if entry already present in the list */
@@ -638,7 +668,8 @@ gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
&& (fmref_entry->frame_nr == frame_nr)
&& (fmref_entry->stackposition == stackposition)
&& (fmref_entry->track == track)
- && (strcmp(fmref_entry->filename, filename) == 0))
+ && (strcmp(fmref_entry->filename, filename) == 0)
+ && (strcmp(fmref_entry->parentpositions, l_parentpositions) == 0))
{
/* the list already contains an equal entry, nothing left to do.. */
return(fmref_entry->persistent_drawable_id);
@@ -663,8 +694,17 @@ gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
new_fmref_entry->track = track;
new_fmref_entry->mtime = gap_file_get_mtime(filename);
g_snprintf(new_fmref_entry->filename, sizeof(new_fmref_entry->filename), "%s", filename);
+ new_fmref_entry->parentpositions[0] = '\0';
+ if(parentpositions != NULL)
+ {
+ g_snprintf(new_fmref_entry->parentpositions
+ , sizeof(new_fmref_entry->parentpositions)
+ , "%s"
+ , parentpositions
+ );
+ }
+
-
new_fmref_entry->next = fmacContext->fmref_list;
fmacContext->fmref_list = new_fmref_entry;
diff --git a/gap/gap_fmac_context.h b/gap/gap_fmac_context.h
index 27fe25f..48e57f2 100644
--- a/gap/gap_fmac_context.h
+++ b/gap/gap_fmac_context.h
@@ -2,7 +2,7 @@
*
*
* This module handles the filtermacro context.
- * The filtermacro context is used for itration of "persistent drawable ids"
+ * The filtermacro context is used for itration of "persistent drawable ids"
* for animated (or constant) filter apply.
* If gap controlled filterapply is done via a filtermacro
* the iteration is done within a filtermacro context.
@@ -11,7 +11,7 @@
* In this case the "persitent_drawable_id" is used to open the referenced
* image, frame or videoframe at apply time (this may happen in another gimp
* session than the recording of the filtermacro was done).
- *
+ *
*
* Copyright (C) 2008 Wolfgang Hofer <hof gimp org>
*
@@ -38,6 +38,7 @@
#include "libgimp/gimp.h"
#include "gap_lib_common_defs.h"
+
typedef struct GapFmacRefEntry {
GapLibAinfoType ainfo_type;
gint32 persistent_drawable_id;
@@ -46,6 +47,7 @@ typedef struct GapFmacRefEntry {
gint32 track;
gint32 mtime;
char filename[1024];
+ char parentpositions[300];
struct GapFmacRefEntry *next;
} GapFmacRefEntry;
@@ -69,6 +71,7 @@ typedef struct GapFmacContext {
#define GAP_FMREF_MTIME "mtime:"
#define GAP_FMREF_TYPE "type:"
#define GAP_FMREF_FILE "file:"
+#define GAP_FMREF_PARENTSTACK "parentstack:"
#define GAP_FMAC_CONTEXT_KEYWORD "GAP_FMAC_CONTEXT_KEYWORD"
@@ -87,6 +90,7 @@ void gap_fmct_free_GapFmacRefList(GapFmacContext *fmacContext);
gint32 gap_fmct_add_GapFmacRefEntry(GapLibAinfoType ainfo_type
, gint32 frame_nr
, gint32 stackposition
+ , char *parentpositions /* list of integers as string "1/2/3/" */
, gint32 track
, gint32 drawable_id
, const char *filename
diff --git a/gap/gap_frame_fetcher.c b/gap/gap_frame_fetcher.c
index 8435696..f8670f4 100644
--- a/gap/gap_frame_fetcher.c
+++ b/gap/gap_frame_fetcher.c
@@ -2,18 +2,18 @@
*
*
* The FrameFetcher provides access to frames both from imagefiles and videofiles.
- *
+ *
* It holds a global image cache of temporary gimp images intended for
* read only access in various gimp-gap render processings.
* (those cached images are marked with an image parasite)
- *
- * There are methods to get the temporary image
+ *
+ * There are methods to get the temporary image
* or to get a duplicate that has only one layer at imagesize.
* (merged or picked via desired stackposition)
*
* For videofiles it holds a cache of open videofile handles.
* (note that caching of videoframes is already available in the videohandle)
- *
+ *
* The current implementation of the frame fetcher is NOT multithread save !
* (the procedures may drop cached images that are still in use by a concurrent thread
* further the cache lists can be messed up if they are modified by concurrent threads
@@ -21,7 +21,7 @@
*
* Currently there is no support to keep track of cached images during the full length
* of a gimp session. Therefore unregister of the last user does NOT drop all resources
- *
+ *
* (If there are still registrated users at exit time, the cached images are still
* loaded in the gimp session)
*
@@ -96,13 +96,13 @@
#define GAP_FFETCH_GVA_FRAMES_TO_KEEP_CACHED 36
#define GAP_FFETCH_MAX_IMG_CACHE_ELEMENTS_GIMPRC_KEY "gap_ffetch_max_img_cache_elements"
-#define GAP_FFETCH_MAX_GVC_CACHE_ELEMENTS_GIMPRC_KEY "gap_ffetch_max_gvc_cache_elements"
+#define GAP_FFETCH_MAX_GVC_CACHE_ELEMENTS_GIMPRC_KEY "gap_ffetch_max_gvc_cache_elements"
#define GAP_FFETCH_GVA_FRAMES_TO_KEEP_CACHED_GIMPRC_KEY "gap_ffetch_gva_frames_to_keep_cached"
/* the lists of cached images and duplicates are implemented via GIMP image parasites,
* where images are simply loaded by GIMP without adding a display and marked with a non persistent parasite.
- * the GAP_IMAGE_CACHE_PARASITE
+ * the GAP_IMAGE_CACHE_PARASITE
* holds the modification timestamp (mtime), gint32 ffetch_user_id
* gint32 type (GAP_IMAGE_CACHE_TYPE_ORIGINAL_SIZE or GAP_IMAGE_CACHE_TYPE_PRESCALE_ENABLED)
* gint32 orig_width, gint32 orig_height (the unscaled original size of the image)
@@ -237,7 +237,7 @@ p_get_ffetch_max_img_cache_elements()
{
static gint32 value = -1;
static char *gimprc_key = GAP_FFETCH_MAX_IMG_CACHE_ELEMENTS_GIMPRC_KEY;
-
+
if(value == -1)
{
if(gap_debug)
@@ -271,7 +271,7 @@ p_get_ffetch_max_gvc_cache_elements()
{
static gint32 value = -1;
static char *gimprc_key = GAP_FFETCH_MAX_GVC_CACHE_ELEMENTS_GIMPRC_KEY;
-
+
if(value == -1)
{
if(gap_debug)
@@ -305,7 +305,7 @@ p_get_ffetch_gva_frames_to_keep_cached()
{
static gint32 value = -1;
static char *gimprc_key = GAP_FFETCH_GVA_FRAMES_TO_KEEP_CACHED_GIMPRC_KEY;
-
+
if(value == -1)
{
if(gap_debug)
@@ -334,7 +334,7 @@ p_get_ffetch_gva_frames_to_keep_cached()
/* ----------------------------------------------------
* p_find_cache_image
* ----------------------------------------------------
- * find an image with filename and matching cachedImageType
+ * find an image with filename and matching cachedImageType
* GAP_IMAGE_CACHE_TYPE_ORIGINAL_SIZE or
* GAP_IMAGE_CACHE_TYPE_PRESCALE_ENABLED
* in the cache.
@@ -387,23 +387,23 @@ p_find_cache_image(const char* filename, gint32 ffetch_user_id
{
GapImageCacheParasitePointers para;
GapImageCacheParasitePointers *paraPtr;
-
+
paraPtr = ¶
p_init_GapImageCacheParasitePointers(paraPtr, l_parasite->data);
-
+
cinf->number_of_cached_images++;
if (cinf->number_of_old_cached_images < MAX_OLD_IMAGE_IDS)
{
cinf->old_cached_image_ids[cinf->number_of_old_cached_images] = images[l_idi];
cinf->number_of_old_cached_images++;
}
-
+
if ((*(paraPtr->type_ptr) == cachedImageType)
&& (strcmp(filename, paraPtr->filename_ptr) == 0))
{
gint32 mtimefile;
-
+
mtimefile = gap_file_get_mtime(filename);
if(mtimefile == *(paraPtr->mtime_ptr))
{
@@ -439,8 +439,8 @@ p_find_cache_image(const char* filename, gint32 ffetch_user_id
{
g_free(images);
}
-
-
+
+
if (l_image_id >= 0)
{
if(gap_debug)
@@ -457,7 +457,7 @@ p_find_cache_image(const char* filename, gint32 ffetch_user_id
,filename
);
}
-
+
return (-1); /* indicates image not found in cache */
} /* end p_find_cache_image */
@@ -505,7 +505,7 @@ p_load_image_and_add_to_cache(const char* filename, gint32 ffetch_user_id
{
*originalWidthPtr = gimp_image_width(l_image_id);
*originalHeightPtr = gimp_image_height(l_image_id);
-
+
if(addToCache == TRUE)
{
guchar *parasite_data;
@@ -514,7 +514,7 @@ p_load_image_and_add_to_cache(const char* filename, gint32 ffetch_user_id
GapImageCacheParasitePointers para;
GapImageCacheParasitePointers *paraPtr;
gint ii;
-
+
if(gap_debug)
{
printf("(L2) number_of_cached_images:%d first_cached_image_id:%d\n"
@@ -522,7 +522,7 @@ p_load_image_and_add_to_cache(const char* filename, gint32 ffetch_user_id
, (int)cinf->old_cached_image_ids[0]
);
}
-
+
ii = 0;
while ((cinf->number_of_cached_images >= p_get_ffetch_max_img_cache_elements())
&& (cinf->old_cached_image_ids[ii] >= 0))
@@ -548,10 +548,10 @@ p_load_image_and_add_to_cache(const char* filename, gint32 ffetch_user_id
break;
}
}
-
+
/* build parasite data including mtime and full filename with terminating 0 byte */
len_filename0 = strlen(filename) + 1;
- parasite_size = 5 * sizeof(gint32) + len_filename0;
+ parasite_size = 5 * sizeof(gint32) + len_filename0;
parasite_data = g_malloc0(parasite_size);
paraPtr = ¶
@@ -563,25 +563,25 @@ p_load_image_and_add_to_cache(const char* filename, gint32 ffetch_user_id
*(paraPtr->orig_width_ptr) = gimp_image_width(l_image_id);
*(paraPtr->orig_height_ptr) = gimp_image_height(l_image_id);
memcpy(paraPtr->filename_ptr, filename, len_filename0);
-
+
/* attach a parasite to mark the image as part of the gap image cache */
l_parasite = gimp_parasite_new(GAP_IMAGE_CACHE_PARASITE
,0 /* GIMP_PARASITE_PERSISTENT 0 for non persistent */
,parasite_size
,parasite_data
);
-
+
if(l_parasite)
{
gimp_image_parasite_attach(l_image_id, l_parasite);
gimp_parasite_free(l_parasite);
}
g_free(parasite_data);
-
+
}
-
+
}
-
+
g_free(l_filename);
@@ -635,9 +635,9 @@ p_load_cache_image(const char* filename, gint32 ffetch_user_id, gboolean addToCa
, filename
);
}
-
+
return (retImgageId);
-
+
} /* end p_load_cache_image */
@@ -653,7 +653,7 @@ p_drop_image_cache(void)
gint32 *images;
gint nimages;
gint l_idi;
-
+
if(gap_debug)
{
printf("p_drop_image_cache START pid:%d\n", (int) gap_base_getpid());
@@ -663,7 +663,7 @@ p_drop_image_cache(void)
for(l_idi=0; l_idi < nimages; l_idi++)
{
GimpParasite *l_parasite;
-
+
l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_CACHE_PARASITE);
if(gap_debug)
@@ -763,7 +763,7 @@ p_drop_vidhandle_cache(void)
{
printf("p_drop_vidhandle_cache END\n");
}
-
+
} /* end p_drop_vidhandle_cache */
#endif
@@ -837,7 +837,7 @@ p_ffetch_get_open_gvahand(const char* filename, gint32 seltrack, const char *pre
,1 /* aud_track */
);
}
-
+
if(l_gvahand)
{
GVA_set_fcache_size(l_gvahand, p_get_ffetch_gva_frames_to_keep_cached());
@@ -914,7 +914,7 @@ gap_frame_fetch_delete_list_of_duplicated_images(gint32 ffetch_user_id)
for(l_idi=0; l_idi < nimages; l_idi++)
{
GimpParasite *l_parasite;
-
+
l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_DUP_CACHE_PARASITE);
if(gap_debug)
@@ -929,7 +929,7 @@ gap_frame_fetch_delete_list_of_duplicated_images(gint32 ffetch_user_id)
if(l_parasite)
{
gint32 *ffetch_user_id_ptr;
-
+
ffetch_user_id_ptr = (gint32 *) l_parasite->data;
if((*ffetch_user_id_ptr == ffetch_user_id) || (ffetch_user_id < 0))
{
@@ -987,7 +987,7 @@ gap_frame_fetch_image_scale(gint32 imageId, gint32 prescaleWidth, gint32 prescal
{
char *l_filename;
l_filename = gimp_image_get_filename(imageId);
-
+
printf("gap_frame_fetch_image_SCALE id:%d (%dx%d) to newSize ==> (%dx%d) %s\n"
,(int)imageId
,(int)gimp_image_width(imageId)
@@ -1019,7 +1019,7 @@ gap_frame_fetch_image_duplicate(gint32 imageId)
{
char *l_filename;
l_filename = gimp_image_get_filename(imageId);
-
+
printf("gap_frame_fetch_image_DUPLICATE id:%d (%dx%d) %s\n"
,(int)imageId
,(int)gimp_image_width(imageId)
@@ -1032,7 +1032,7 @@ gap_frame_fetch_image_duplicate(gint32 imageId)
g_free(l_filename);
}
}
-
+
dupImageId = gimp_image_duplicate(imageId);
return (dupImageId);
}
@@ -1042,7 +1042,7 @@ gap_frame_fetch_image_duplicate(gint32 imageId)
* p_duplicate_image_for_prescale
* -------------------------------
* duplicate the specified image
- * and mark the duplicate as "prescaleEnabled"
+ * and mark the duplicate as "prescaleEnabled"
*/
static gint32
p_duplicate_image_for_prescale(gint32 origsizeImageId)
@@ -1070,7 +1070,7 @@ p_duplicate_image_for_prescale(gint32 origsizeImageId)
gimp_parasite_free(l_parasite);
}
return (retImageId);
-
+
} /* end p_duplicate_image_for_prescale */
@@ -1122,15 +1122,15 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
&& (*originalWidthPtr > pWidth))
{
retImageId = -1;
- }
-
+ }
+
/* check height for re-upscale attempt */
if ((prescaleHeight > pHeight)
&& (*originalHeightPtr > pHeight))
{
retImageId = -1;
}
-
+
if (retImageId >= 0)
{
if ((pWidth != prescaleWidth)
@@ -1145,7 +1145,7 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
return(retImageId);
}
-
+
if(gap_debug)
{
printf("gap_frame_fetch_prescaled_image DELETE img: %d from cache %s\n"
@@ -1201,8 +1201,8 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
{
return (origsizeImageId);
}
-
-
+
+
retImageId = p_duplicate_image_for_prescale(origsizeImageId);
}
}
@@ -1221,7 +1221,7 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
}
return (retImageId);
-
+
} /* end gap_frame_fetch_prescaled_image */
@@ -1230,7 +1230,7 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
/* ----------------------------
* gap_frame_fetch_dup_image
* ----------------------------
- * returns merged or selected layer_id
+ * returns merged or selected layer_id
* (that is the only visible layer in temporary created scratch image)
* the caller is resonsible to delete the scratch image when processing is done.
* this can be done by calling gap_frame_fetch_delete_list_of_duplicated_images()
@@ -1239,6 +1239,10 @@ gint32
gap_frame_fetch_dup_image(gint32 ffetch_user_id
,const char *filename /* full filename of the image (already contains framenr) */
,gint32 stackpos /* 0 pick layer on top of stack, -1 merge visible layers */
+ ,const char *parentpositions /* int list of parent stackpositions as string
+ * where NULL refers to image toplevel
+ * example: 2/1/2
+ */
,gboolean addToCache /* enable caching */
)
{
@@ -1253,7 +1257,7 @@ gap_frame_fetch_dup_image(gint32 ffetch_user_id
{
return(-1);
}
-
+
if (stackpos < 0)
{
dup_image_id = gap_frame_fetch_image_duplicate(image_id);
@@ -1265,9 +1269,24 @@ gap_frame_fetch_dup_image(gint32 ffetch_user_id
{
gint l_nlayers;
gint32 *l_layers_list;
-
+ gboolean l_has_parents;
- l_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
+ l_has_parents = FALSE;
+ if(parentpositions != NULL)
+ {
+ if (*parentpositions != '\0')
+ {
+ l_has_parents = TRUE;
+ }
+ }
+ if (l_has_parents)
+ {
+ l_layers_list = gap_image_get_layers_at_parentpositions(image_id, &l_nlayers, parentpositions);
+ }
+ else
+ {
+ l_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
+ }
if(l_layers_list != NULL)
{
if (stackpos < l_nlayers)
@@ -1286,10 +1305,10 @@ gap_frame_fetch_dup_image(gint32 ffetch_user_id
l_unit = gimp_image_get_unit(image_id);
gimp_image_set_unit(dup_image_id, l_unit);
-
+
resulting_layer = gap_layer_copy_to_image (dup_image_id, src_layer_id);
}
-
+
g_free (l_layers_list);
}
}
@@ -1314,7 +1333,7 @@ gap_frame_fetch_dup_image(gint32 ffetch_user_id
*/
gap_image_delete_immediate(image_id);
}
-
+
}
return(resulting_layer);
@@ -1342,7 +1361,7 @@ gap_frame_fetch_dup_video(gint32 ffetch_user_id
#ifdef GAP_ENABLE_VIDEOAPI_SUPPORT
t_GVA_Handle *gvahand;
t_GVA_RetCode l_fcr;
-
+
gvahand = p_ffetch_get_open_gvahand(filename, seltrack, preferred_decoder);
if (gvahand == NULL)
{
@@ -1365,7 +1384,7 @@ gap_frame_fetch_dup_video(gint32 ffetch_user_id
if(((gvahand->current_seek_nr + p_get_ffetch_gva_frames_to_keep_cached()) > framenr)
&& (gvahand->current_seek_nr < framenr ) )
{
- /* near forward seek is performed by dummyreads to fill up the
+ /* near forward seek is performed by dummyreads to fill up the
* handles internal framecache
*/
while(gvahand->current_seek_nr < framenr)
@@ -1393,15 +1412,15 @@ gap_frame_fetch_dup_video(gint32 ffetch_user_id
/* return the newly created layer from the temporary image in the gvahand stucture.
*/
l_layer_id = gvahand->layer_id;
-
+
p_add_image_to_list_of_duplicated_images(gvahand->image_id, ffetch_user_id);
gvahand->image_id = -1;
gvahand->layer_id = -1;
-#endif
+#endif
return (l_layer_id);
-} /* end gap_frame_fetch_dup_video */
+} /* end gap_frame_fetch_dup_video */
/* -------------------------------------------------
@@ -1434,14 +1453,14 @@ gap_frame_fetch_register_user(const char *caller_name)
gint32 max_ffetch_user_id;
GapFFetchResourceUserElem *usr_ptr;
GapFFetchResourceUserElem *new_usr_ptr;
-
+
max_ffetch_user_id = 0;
new_usr_ptr = NULL;
-
+
for(usr_ptr = global_rsource_users; usr_ptr != NULL; usr_ptr = (GapFFetchResourceUserElem *)usr_ptr->next)
{
/* printf("usr_ptr->ffetch_user_id: %d usr_ptr:%d\n", usr_ptr->ffetch_user_id, usr_ptr); */
-
+
if (usr_ptr->ffetch_user_id >= 0)
{
max_ffetch_user_id = MAX(max_ffetch_user_id, usr_ptr->ffetch_user_id);
@@ -1451,7 +1470,7 @@ gap_frame_fetch_register_user(const char *caller_name)
new_usr_ptr = usr_ptr; /* reuse inactive element */
}
}
-
+
max_ffetch_user_id++;
if (new_usr_ptr == NULL)
{
@@ -1460,7 +1479,7 @@ gap_frame_fetch_register_user(const char *caller_name)
global_rsource_users = new_usr_ptr;
}
new_usr_ptr->ffetch_user_id = max_ffetch_user_id;
-
+
if(gap_debug)
{
printf("gap_frame_fetch_register_user: REGISTRATED ffetch_user_id:%d caller_name:%s new_usr_ptr:%d
pid:%d\n"
@@ -1518,7 +1537,7 @@ gap_frame_fetch_unregister_user(gint32 ffetch_user_id)
count_active_users++;
}
}
-
+
if(count_active_users == 0)
{
if(gap_debug)
@@ -1545,7 +1564,7 @@ gboolean
gap_frame_fetch_is_image_in_cache(gint32 image_id)
{
GimpParasite *l_parasite;
-
+
l_parasite = gimp_image_parasite_find(image_id, GAP_IMAGE_CACHE_PARASITE);
if(l_parasite)
@@ -1553,9 +1572,9 @@ gap_frame_fetch_is_image_in_cache(gint32 image_id)
gimp_parasite_free(l_parasite);
return(TRUE); /* isCacheMember */
}
-
+
return (FALSE);
-
+
} /* end gap_frame_fetch_is_image_in_cache */
@@ -1569,7 +1588,7 @@ void
gap_frame_fetch_remove_parasite(gint32 image_id)
{
GimpParasite *l_parasite;
-
+
l_parasite = gimp_image_parasite_find(image_id, GAP_IMAGE_CACHE_PARASITE);
if(l_parasite)
@@ -1611,9 +1630,9 @@ p_dump_resources_gvahand()
for(gvc_ptr = gvcache->gvc_list; gvc_ptr != NULL; gvc_ptr = (GapFFetchGvahandCacheElem *)gvc_ptr->next)
{
t_GVA_Handle *gvahand;
-
+
gvahand = gvc_ptr->gvahand;
-
+
count++;
printf("FrameFetcher GVA_handle: %s currFrameNr:%d fcache elemSize:%d byteSize:%d\n"
, gvahand->filename
@@ -1629,7 +1648,7 @@ p_dump_resources_gvahand()
,(int)p_get_ffetch_max_gvc_cache_elements()
,(int)p_get_ffetch_gva_frames_to_keep_cached
);
-
+
}
else
{
@@ -1651,13 +1670,13 @@ p_dump_resources_gvahand()
* ----------------------------------------------------
* print memory resources used (in case sysinfo was available on compiletime)
*
- * NOTE:
+ * NOTE:
* getrusage did not work in 1st test on linux (and is not available on windows)
* while sysinfo worked on my linux development environment, but was not availabe
* on Windows MinGW environment.
* therefore the configure script cheks for the sysinfo header and
* sets the GAP_HAVE_SYSINFO define constant to 1 when available.
- *
+ *
*/
static void
p_dump_process_resource_usage()
@@ -1666,7 +1685,7 @@ p_dump_process_resource_usage()
int rc;
struct sysinfo info;
-
+
rc = sysinfo(&info);
if(rc == 0)
{
@@ -1688,7 +1707,7 @@ p_dump_process_resource_usage()
, (info.mem_unit * info.totalhigh)
, (info.mem_unit * info.freehigh)
);
-
+
}
else
{
@@ -1706,10 +1725,10 @@ p_dump_process_resource_usage()
* gap_frame_fetch_dump_resources
* ----------------------------------------------------
* print current resource usage to stdout
- * this includes information about
+ * this includes information about
* - ALL images currently loaded
* - all video filehandles with memory cache sizes
- *
+ *
*/
void
gap_frame_fetch_dump_resources()
@@ -1725,17 +1744,17 @@ gap_frame_fetch_dump_resources()
l_number_of_cached_images = 0;
images = gimp_image_list(&nimages);
-
-
-
+
+
+
for(l_idi=0; l_idi < nimages; l_idi++)
{
GimpParasite *l_parasite;
char *l_filename;
char *l_cacheInfoString;
gint32 image_id;
-
-
+
+
image_id = images[l_idi];
l_filename = gimp_image_get_filename(image_id);
l_parasite = gimp_image_parasite_find(image_id, GAP_IMAGE_CACHE_PARASITE);
@@ -1744,11 +1763,11 @@ gap_frame_fetch_dump_resources()
{
GapImageCacheParasitePointers para;
GapImageCacheParasitePointers *paraPtr;
-
+
paraPtr = ¶
p_init_GapImageCacheParasitePointers(paraPtr, l_parasite->data);
-
+
l_number_of_cached_images++;
l_cacheInfoString = g_strdup_printf("Cache member: mtime:%d ffetchId:%d %s"
@@ -1756,7 +1775,7 @@ gap_frame_fetch_dump_resources()
,*(paraPtr->ffetch_id_ptr)
,paraPtr->filename_ptr
);
-
+
gimp_parasite_free(l_parasite);
}
else
@@ -1768,11 +1787,11 @@ gap_frame_fetch_dump_resources()
ffetch_user_id_ptr = (gint32 *) l_parasite->data;
l_number_of_cached_images++;
-
+
l_cacheInfoString = g_strdup_printf("Cache member (merged duplicate): ffetchId:%d"
,*ffetch_user_id_ptr
);
-
+
gimp_parasite_free(l_parasite);
}
else
@@ -1781,7 +1800,7 @@ gap_frame_fetch_dump_resources()
}
}
-
+
printf(" FrameFetcher ImgId:%d (%d x %d) %s %s\n"
,(int)image_id
,(int)gimp_image_width(image_id)
@@ -1789,7 +1808,7 @@ gap_frame_fetch_dump_resources()
,l_filename
,l_cacheInfoString
);
-
+
g_free(l_cacheInfoString);
if(l_filename != NULL)
{
@@ -1797,12 +1816,12 @@ gap_frame_fetch_dump_resources()
}
l_parasite = NULL;
}
-
+
if(images)
{
g_free(images);
}
-
+
printf(" Number of images currently loaded in gimp total: %d gap_ffetch_max_img_cache_elements:%d marked
as cache member:%d\n"
,(int)nimages
,(int)p_get_ffetch_max_img_cache_elements()
diff --git a/gap/gap_frame_fetcher.h b/gap/gap_frame_fetcher.h
index ecb99aa..ba9f0a9 100644
--- a/gap/gap_frame_fetcher.h
+++ b/gap/gap_frame_fetcher.h
@@ -2,17 +2,17 @@
*
*
* The FrameFetcher provides access to frames both from imagefiles and videofiles.
- *
+ *
* It holds a global image cache of temporary gimp images intended for
* read only access in various gimp-gap render processings.
- *
- * There are methods to get the temporary image
+ *
+ * There are methods to get the temporary image
* or to get a duplicate that has only one layer at imagesize.
* (merged or picked via desired stackposition)
*
* For videofiles it holds a cache of open videofile handles.
* (note that caching of videoframes is already available in the videohandle)
- *
+ *
*
* Copyright (C) 2008 Wolfgang Hofer <hof gimp org>
*
@@ -119,7 +119,7 @@ gap_frame_fetch_prescaled_image(gint32 ffetch_user_id
/* ----------------------------
* gap_frame_fetch_dup_image
* ----------------------------
- * returns merged or selected layer_id
+ * returns merged or selected layer_id
* (that is the only visible layer in temporary created scratch image)
* the caller is resonsible to delete the scratch image when processing is done.
* this can be done by calling gap_frame_fetch_delete_list_of_duplicated_images()
@@ -128,6 +128,10 @@ gint32
gap_frame_fetch_dup_image(gint32 ffetch_user_id
,const char *filename /* full filename of the image (already contains framenr) */
,gint32 stackpos /* 0 pick layer on top of stack, -1 merge visible layers */
+ ,const char *parentpositions /* int list of parent stackpositions as string
+ * where NULL refers to image toplevel
+ * example: 2/1/2
+ */
,gboolean addToCache /* enable caching */
);
@@ -187,10 +191,10 @@ gap_frame_fetch_remove_parasite(gint32 image_id);
* gap_frame_fetch_dump_resources
* ----------------------------------------------------
* print current resource usage to stdout
- * this includes information about
+ * this includes information about
* - ALL images currently loaded in gimp
* - all video filehandles with memory cache sizes
- *
+ *
*/
void
gap_frame_fetch_dump_resources();
diff --git a/gap/gap_image.c b/gap/gap_image.c
index 4100eca..49c9e6c 100644
--- a/gap/gap_image.c
+++ b/gap/gap_image.c
@@ -1114,7 +1114,7 @@ gap_image_reorder_layer(gint32 image_id, gint32 layer_id,
l_name = g_strdup(new_layername);
}
}
-
+
if (l_name == NULL)
{
l_name = gimp_item_get_name(layer_id);
@@ -1128,3 +1128,268 @@ gap_image_reorder_layer(gint32 image_id, gint32 layer_id,
return (0); /* OK */
} /* end gap_image_reorder_layer */
+
+/* ------------------------------------
+ * gap_image_merge_group_layer
+ * ------------------------------------
+ * merge the specified group layer and return the id of the resulting layer.
+ *
+ * The merge strategy
+ * o) create a temporary image of same size/type (l_tmp_img_id)
+ * o) copy the specified grouplayer to the temporary image (l_tmp_img_id)
+ * o) call gimp_image_merge_visible_layers on the temporary image (l_tmp_img_id, mode)
+ * o) copy the merged layer back to the original image
+ * to the same group at the position of the original layergroup
+ * o) remove the temporary image
+ * o) remove original layergroup
+ * o) rename the resuling merged layer.
+ *
+ * returns 0 if all done OK
+ * (or -1 on error)
+ */
+gint32
+gap_image_merge_group_layer(gint32 image_id,
+ gint32 group_layer_id,
+ gint merge_mode)
+{
+ gint32 l_tmp_img_id;
+ gint32 l_new_layer_id;
+ gint32 l_merged_layer_id;
+ gint32 l_parent_id;
+ gint32 l_position;
+ gint l_src_offset_x;
+ gint l_src_offset_y;
+ gboolean l_visible;
+ char *l_name;
+
+ if (!gimp_item_is_group(group_layer_id))
+ {
+ /* the specified group_layer_id is not a group
+ * -- no merge is done, return its id as result --
+ */
+ return(group_layer_id);
+ }
+ l_visible = gimp_item_get_visible(group_layer_id);
+ l_name = gimp_item_get_name(group_layer_id);
+
+ /* create a temporary image */
+ l_tmp_img_id = gap_image_new_of_samesize(image_id);
+
+ /* copy the grouplayer to the temporary image */
+ l_new_layer_id = gap_layer_copy_to_dest_image(l_tmp_img_id,
+ group_layer_id,
+ 100.0, /* full opacity */
+ 0, /* NORMAL paintmode */
+ &l_src_offset_x,
+ &l_src_offset_y
+ );
+
+ gimp_image_insert_layer (l_tmp_img_id, l_new_layer_id, 0, 0);
+ gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);
+ gimp_item_set_visible(l_new_layer_id, TRUE);
+
+
+ /* merge visible layers in the temporary image */
+ l_merged_layer_id = gimp_image_merge_visible_layers (l_tmp_img_id, merge_mode);
+ l_new_layer_id = gap_layer_copy_to_dest_image(image_id,
+ l_merged_layer_id,
+ gimp_layer_get_opacity(group_layer_id),
+ gimp_layer_get_mode(group_layer_id),
+ &l_src_offset_x,
+ &l_src_offset_y
+ );
+ l_position = gimp_image_get_item_position (image_id, group_layer_id);
+ l_parent_id = gimp_item_get_parent(group_layer_id);
+ if (l_parent_id < 0)
+ {
+ l_parent_id = 0;
+ }
+ gimp_image_insert_layer (image_id, l_new_layer_id, l_parent_id, l_position);
+ gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);
+
+ /* remove the original group layer from the original image */
+ gimp_image_remove_layer(image_id, group_layer_id);
+
+ /* restore the original layer name */
+ if (l_name != NULL)
+ {
+ gimp_item_set_name(l_new_layer_id, l_name);
+ g_free(l_name);
+ }
+ gimp_item_set_visible(l_new_layer_id, l_visible);
+
+ /* remove the temporary image */
+ gap_image_delete_immediate(l_tmp_img_id);
+ return(l_new_layer_id);
+
+} /* end gap_image_merge_group_layer */
+
+
+/* -----------------------------------------------
+ * gap_image_get_parentpositions_as_int_stringlist
+ * -----------------------------------------------
+ * returns the list of parent stackpositions as list of integer numbers
+ * separated by the "/" delimiter.
+ * example 2/3/2
+ * return NULL in case the specified drawable is invalid or has no perent item
+ */
+char *
+gap_image_get_parentpositions_as_int_stringlist(gint32 drawable_id)
+{
+ char *parentpositions;
+ gint32 l_parent_id;
+ gint32 l_image_id;
+
+ parentpositions = NULL;
+ l_parent_id = gimp_item_get_parent(drawable_id);
+ if (l_parent_id > 0)
+ {
+ gint l_position;
+
+ l_image_id = gimp_item_get_image(drawable_id);
+ l_position = gimp_image_get_item_position (l_image_id, l_parent_id);
+
+
+ parentpositions = g_strdup_printf("%d", l_position);
+ while(l_parent_id > 0)
+ {
+ l_parent_id = gimp_item_get_parent(l_parent_id);
+ if (l_parent_id > 0)
+ {
+ char *new_parentpositions;
+
+ l_position = gimp_image_get_item_position (l_image_id, l_parent_id);
+ new_parentpositions = g_strdup_printf("%d/%s"
+ , (int)l_position
+ , parentpositions
+ );
+ g_free(parentpositions);
+ parentpositions = new_parentpositions;
+ }
+ }
+ }
+
+ if(gap_debug)
+ {
+ printf("parentpositions_as_int_stringlist: %s\n"
+ , parentpositions == NULL ? "null" : parentpositions
+ );
+ }
+ return (parentpositions);
+
+} /* end gap_image_get_parentpositions_as_int_stringlist */
+
+
+/* -----------------------------------------------
+ * gap_image_get_layers_at_parentpositions
+ * -----------------------------------------------
+ * returns the list layers at toplevel image (when parentpositions == NULL)
+ * otherwise return the list of layers of the nested group
+ * where parentpositions specifies a list of integer stackpositions
+ * from toplevel to the deepest nested group delimited by "/"
+ * note that all specified parentpositions MUST refere to group layers.
+ * return NULL in case no matching layerstack was found in the image.
+ */
+gint32 *
+gap_image_get_layers_at_parentpositions(gint32 image_id, gint *nlayers, const char *parentpositions)
+{
+ gint l_nlayers;
+ gint32 *l_toplevel_layers_list;
+ gint32 *l_layers_list;
+ gboolean l_has_parents;
+
+ *nlayers = 0;
+ l_toplevel_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
+ if (l_toplevel_layers_list == NULL)
+ {
+ return (NULL);
+ }
+ l_layers_list = l_toplevel_layers_list;
+
+
+ l_has_parents = FALSE;
+ if(parentpositions != NULL)
+ {
+ if (*parentpositions != '\0')
+ {
+ l_has_parents = TRUE;
+ }
+ }
+ if (l_has_parents == TRUE)
+ {
+ gchar **posValueArray;
+ gint l_ii;
+ posValueArray = g_strsplit(parentpositions
+ , "/"
+ , -1 /* max_tokens less than 1 splits the string completely. */
+ );
+ for(l_ii = 0; posValueArray[l_ii] != NULL; l_ii++)
+ {
+ long l_pos;
+
+
+ l_pos = atol(posValueArray[l_ii]);
+ if ((l_pos >= 0) && (l_pos < l_nlayers))
+ {
+ gint32 l_layer_id;
+
+ l_layer_id == l_layers_list[l_pos];
+ if (gimp_item_is_group(l_layer_id))
+ {
+ g_free(l_layers_list);
+ l_layers_list = gimp_item_get_children(l_layer_id, &l_nlayers);
+ }
+ else
+ /* error: position is not a group */
+ if(gap_debug)
+ {
+ printf("gap_image_get_layers_at_parentpositions: position %d is no GROUP"
+ "(l_nlayers:%d) l_layer_id:%d (%s) parentpositions: %s \n"
+ , (int) l_pos
+ , (int) l_nlayers
+ , (int) l_layer_id
+ , gimp_item_get_name(l_layer_id)
+ , parentpositions
+ );
+ }
+ g_strfreev(posValueArray);
+ g_free(l_layers_list);
+ return (NULL);
+ {
+ }
+ }
+ else
+ {
+ /* error: position is invalid (not an integer within valid stackposition range */
+ if(gap_debug)
+ {
+ printf("gap_image_get_layers_at_parentpositions: position %d not in valid range"
+ " (l_nlayers:%d) parentpositions: %s \n"
+ , (int) l_pos
+ , (int) l_nlayers
+ , parentpositions
+ );
+ }
+ g_strfreev(posValueArray);
+ g_free(l_layers_list);
+ return (NULL);
+ }
+
+
+ }
+
+ g_strfreev(posValueArray);
+
+ *nlayers = l_nlayers;
+ return (l_layers_list);
+
+ }
+
+ /* has no parents: deliver toplevel layers list */
+
+ *nlayers = l_nlayers;
+ return (l_toplevel_layers_list);
+
+
+} /* end gap_image_get_layers_at_parentpositions */
+
diff --git a/gap/gap_image.h b/gap/gap_image.h
index 40b46ad..4512863 100644
--- a/gap/gap_image.h
+++ b/gap/gap_image.h
@@ -91,5 +91,14 @@ gint32 gap_image_reorder_layer(gint32 image_id, gint32 layer_id,
gboolean enableGroupCreation,
char *new_layername);
+gint32 gap_image_merge_group_layer(gint32 image_id,
+ gint32 group_layer_id,
+ gint merge_mode);
+
+
+char * gap_image_get_parentpositions_as_int_stringlist(gint32 drawable_id);
+gint32 * gap_image_get_layers_at_parentpositions(gint32 image_id, gint *nlayers, const char
*parentpositions);
+
+
#endif
diff --git a/gap/gap_mod_layer.c b/gap/gap_mod_layer.c
index 976fa13..55a645f 100644
--- a/gap/gap_mod_layer.c
+++ b/gap/gap_mod_layer.c
@@ -84,6 +84,7 @@ extern int gap_debug; /* ==0 ... dont print debug infos */
#define GAP_DB_BROWSER_MODFRAMES_HELP_ID "gap-modframes-db-browser"
+#define GAP_MODIFY_LAYERS_ENABLE_PITSTOP_DIALOG "gap-modify-enable-pitstop-dialog"
static int p_merge_selected_toplevel_layers(gint32 image_id,
gint merge_mode,
@@ -102,16 +103,15 @@ static int p_merge_selected_group_member_layers(gint32 image_id,
char *new_layername
);
-/* ============================================================================
+/* ------------------
* p_pitstop_dialog
+ * ------------------
* return -1 on CANCEL
* 0 on Continue (OK)
- * ============================================================================
*/
static gint
p_pitstop_dialog(gint text_flag, char *filter_procname)
{
- const gchar *l_env;
gchar *l_msg;
static GapArrButtonArg l_but_argv[2];
gint l_but_argc;
@@ -121,6 +121,13 @@ p_pitstop_dialog(gint text_flag, char *filter_procname)
+ gap_arr_arg_init(&l_argv[0], GAP_ARR_WGT_TOGGLE);
+ l_argv[0].label_txt = _("do not show this dialog again");
+ l_argv[0].help_txt = g_strdup_printf(_("add %s to gimprc configuration to disable this dialog in all
further sessions")
+ ,GAP_MODIFY_LAYERS_ENABLE_PITSTOP_DIALOG );
+ l_argv[0].int_ret = FALSE;
+ l_argv[0].int_default = FALSE;
+ l_argv[0].has_default = TRUE;
l_but_argv[0].but_txt = _("Continue");
l_but_argv[0].but_val = 0;
@@ -128,17 +135,15 @@ p_pitstop_dialog(gint text_flag, char *filter_procname)
l_but_argv[1].but_val = -1;
l_but_argc = 2;
- l_argc = 0;
+ l_argc = 1;
/* optional dialog between both calls (to see the effect of 1.call) */
- l_env = g_getenv("GAP_FILTER_PITSTOP");
- if(l_env != NULL)
+ if(!gap_base_get_gimprc_gboolean_value(GAP_MODIFY_LAYERS_ENABLE_PITSTOP_DIALOG, TRUE))
{
- if((*l_env == 'N') || (*l_env == 'n'))
- {
- return 0; /* continue without question */
- }
+ return 0; /* continue without question */
}
+
+
if(text_flag == 0)
{
l_msg = g_strdup_printf (_("2nd call of %s\n(define end-settings)"), filter_procname);
@@ -151,6 +156,10 @@ p_pitstop_dialog(gint text_flag, char *filter_procname)
l_argc, l_argv,
l_but_argc, l_but_argv, 0);
g_free (l_msg);
+ if ((l_argv[0].int_ret != FALSE) && (l_continue ==0))
+ {
+ gimp_gimprc_set(GAP_MODIFY_LAYERS_ENABLE_PITSTOP_DIALOG, "no");
+ }
return (l_continue);
@@ -222,6 +231,34 @@ gap_mod_get_1st_selected (GapModLayliElem * layli_ptr, gint nlayers)
return(-1);
} /* end gap_mod_get_1st_selected */
+/* ---------------------------------------
+ * p_get_layer_according_to_group_handling
+ * ---------------------------------------
+ */
+static gint32
+p_get_layer_according_to_group_handling(gint32 l_drawable_id, gint32 groupFilterHandlingMode)
+{
+ gint32 l_resulting_item_id;
+
+ l_resulting_item_id = l_drawable_id;
+ if (gimp_item_is_group(l_drawable_id))
+ {
+ if(groupFilterHandlingMode == GAP_GROUP_FILTER_HANDLING_SKIP)
+ {
+ l_resulting_item_id = -1;
+ } else if(groupFilterHandlingMode == GAP_GROUP_FILTER_HANDLING_MERGE)
+ {
+ l_resulting_item_id = gap_image_merge_group_layer( gimp_item_get_image(l_drawable_id)
+ , l_drawable_id
+ , GIMP_EXPAND_AS_NECESSARY
+ );
+ }
+ }
+ return (l_resulting_item_id);
+
+} /* end p_get_layer_according_to_group_handling */
+
+
/* -----------------------------
* gap_mod_alloc_layli_group
* -----------------------------
@@ -541,7 +578,7 @@ p_apply_selection_action(gint32 image_id, gint32 action_mode
* ---------------------------------
* perform merge of selcted toplevel layer(s)
*
- * This merge strategy
+ * This merge strategy
* o) hides all unselected layers (at top image level)
* o) calls the merge visible layers procedure of the GIMP core
* o) (optionally) sets a new name for the merged layer
@@ -561,7 +598,6 @@ p_merge_selected_toplevel_layers(gint32 image_id,
)
{
int l_idx;
- int l_rc;
gint l_vis_result;
char l_name_buff[MAX_LAYERNAME];
gint32 l_layer_id;
@@ -616,17 +652,17 @@ p_merge_selected_toplevel_layers(gint32 image_id,
}
return(0);
-
+
} /* end p_merge_selected_toplevel_layers */
/* ------------------------------------
* p_merge_selected_group_member_layers
* ------------------------------------
- * perform merge of selcted layer(s) that are all members of
+ * perform merge of selcted layer(s) that are all members of
* the same layergroup.
*
- * This merge strategy
+ * This merge strategy
* o) creates a temporary image of same size/type (l_tmp_img_id)
* o) copies all selected layers to the temporary image (l_tmp_img_id)
* o) calls gimp_image_merge_visible_layers on the temporary image (l_tmp_img_id, mode)
@@ -648,7 +684,6 @@ p_merge_selected_group_member_layers(gint32 image_id,
char *new_layername)
{
int l_idx;
- int l_rc;
char l_name_buff[MAX_LAYERNAME];
gint32 l_tmp_img_id;
gint32 l_layer_id;
@@ -660,12 +695,12 @@ p_merge_selected_group_member_layers(gint32 image_id,
gint l_src_offset_x;
gint l_src_offset_y;
char *l_name;
-
+
/* create a temporary image */
l_tmp_img_id = gap_image_new_of_samesize(image_id);
l_name = NULL;
-
+
/* copy all selected layers to the temporary image */
l_last_selected_layer_id = -1;
for(l_idx = nlayers; l_idx >= 0; l_idx--)
@@ -678,7 +713,7 @@ p_merge_selected_group_member_layers(gint32 image_id,
l_last_selected_layer_id = l_layer_id;
l_name = gimp_item_get_name(l_last_selected_layer_id);
}
-
+
/* copy the layer from the temp image to the preview multilayer image */
l_new_layer_id = gap_layer_copy_to_dest_image(l_tmp_img_id,
l_layer_id,
@@ -687,12 +722,12 @@ p_merge_selected_group_member_layers(gint32 image_id,
&l_src_offset_x,
&l_src_offset_y
);
-
+
gimp_image_insert_layer (l_tmp_img_id, l_new_layer_id, 0, 0);
gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);
}
}
-
+
/* merge visible layers in the temporary image */
l_merged_layer_id = gimp_image_merge_visible_layers (l_tmp_img_id, merge_mode);
l_new_layer_id = gap_layer_copy_to_dest_image(image_id,
@@ -704,6 +739,10 @@ p_merge_selected_group_member_layers(gint32 image_id,
);
l_position = gimp_image_get_item_position (image_id, l_last_selected_layer_id);
l_parent_id = gimp_item_get_parent(l_last_selected_layer_id);
+ if (l_parent_id < 0)
+ {
+ l_parent_id = 0;
+ }
gimp_image_insert_layer (image_id, l_new_layer_id, l_parent_id, l_position);
gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);
@@ -729,12 +768,12 @@ p_merge_selected_group_member_layers(gint32 image_id,
{
gimp_item_set_name(l_new_layer_id, l_name);
}
-
+
if (l_name != NULL)
{
g_free(l_name);
}
-
+
/* remove the temporary image */
gap_image_delete_immediate(l_tmp_img_id);
@@ -771,7 +810,8 @@ p_apply_action2(gint32 image_id,
gint32 master_image_id,
gint32 new_position,
char *new_groupname,
- char *delimiter
+ char *delimiter,
+ gint32 groupFilterHandlingMode
)
{
int l_idx;
@@ -788,7 +828,7 @@ p_apply_action2(gint32 image_id,
l_merge_mode = -44; /* none of the flatten modes */
-
+
if(action_mode == GAP_MOD_ACM_MERGE_EXPAND) l_merge_mode = GAP_RANGE_OPS_FLAM_MERG_EXPAND;
if(action_mode == GAP_MOD_ACM_MERGE_IMG) l_merge_mode = GAP_RANGE_OPS_FLAM_MERG_CLIP_IMG;
if(action_mode == GAP_MOD_ACM_MERGE_BG) l_merge_mode = GAP_RANGE_OPS_FLAM_MERG_CLIP_BG;
@@ -843,9 +883,9 @@ p_apply_action2(gint32 image_id,
{
return(0); /* there is only one layer selected that is not a group, nothing to merge */
}
-
+
}
-
+
l_parent_id = gimp_item_get_parent(l_first_selected_layer_id);
if (l_parent_id > 0)
{
@@ -919,10 +959,18 @@ p_apply_action2(gint32 image_id,
p_lower_layer(image_id, l_layer_id, layli_ptr, nlayers, TRUE);
break;
case GAP_MOD_ACM_APPLY_FILTER:
- l_rc = gap_filt_pdb_call_plugin(filter_procname,
+ {
+ gint32 l_relevant_item_id;
+ l_relevant_item_id = p_get_layer_according_to_group_handling(l_layer_id,
groupFilterHandlingMode);
+
+ if (l_relevant_item_id >= 0)
+ {
+ l_rc = gap_filt_pdb_call_plugin(filter_procname,
image_id,
- l_layer_id,
+ l_relevant_item_id,
GIMP_RUN_WITH_LAST_VALS);
+ }
+ }
if(gap_debug) printf("gap: p_apply_action2 FILTER:%s rc =%d\n",
filter_procname, (int)l_rc);
break;
@@ -939,7 +987,7 @@ p_apply_action2(gint32 image_id,
{
gint32 l_parent_id;
gint32 l_position;
-
+
l_parent_id = gimp_item_get_parent(l_layer_id);
l_position = gimp_image_get_item_position(image_id, l_layer_id);
l_new_layer_id = gimp_layer_copy(l_layer_id);
@@ -1316,7 +1364,7 @@ p_apply_action2(gint32 image_id,
}
return (l_rc);
-} /* end p_apply_action2 */
+} /* end p_apply_action2 */
/* ---------------------------------
@@ -1338,13 +1386,14 @@ p_apply_action(gint32 image_id,
gint32 master_image_id,
gint32 new_position,
char *new_groupname,
- char *delimiter
+ char *delimiter,
+ gint32 groupFilterHandlingMode
)
{
int l_rc;
-
+
gimp_image_undo_group_start (image_id);
-
+
l_rc = p_apply_action2(image_id,
action_mode,
layli_ptr,
@@ -1358,7 +1407,8 @@ p_apply_action(gint32 image_id,
master_image_id,
new_position,
new_groupname,
- delimiter
+ delimiter,
+ groupFilterHandlingMode
);
gimp_image_undo_group_end (image_id);
return l_rc;
@@ -1381,6 +1431,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
char *filter_procname, int filt_len,
gint *plugin_data_len,
gint32 *accelCharacteristic,
+ gint32 *groupFilterHandlingMode,
gboolean operate_on_layermask
)
{
@@ -1392,6 +1443,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
static char *canonical_proc_name;
l_browser_result.accelCharacteristic = GAP_ACCEL_CHAR_LINEAR;
+ l_browser_result.groupFilterHandlingMode = GAP_GROUP_FILTER_HANDLING_NORMAL;
/* GAP-PDB-Browser Dialog */
/* ---------------------- */
@@ -1419,6 +1471,7 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
* (because processing runs backwards from total_frames down to 0)
*/
*accelCharacteristic = (-1 * l_browser_result.accelCharacteristic);
+ *groupFilterHandlingMode = l_browser_result.groupFilterHandlingMode;
/* 1.st INTERACTIV Filtercall dialog */
/* --------------------------------- */
@@ -1438,7 +1491,14 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
printf("ERROR: No layer selected in 1.st handled frame\n");
return (-1);
}
- l_drawable_id = layli_ptr[l_idx].layer_id;
+ l_drawable_id = p_get_layer_according_to_group_handling(layli_ptr[l_idx].layer_id,
*groupFilterHandlingMode);
+ if (l_drawable_id < 0)
+ {
+ g_message (_("Modify Layers cancelled: No normal layer selected in 1.st handled frame"));
+ return (-1);
+ }
+
+
if(operate_on_layermask)
{
l_drawable_id = gimp_layer_get_mask(layli_ptr[l_idx].layer_id);
@@ -1483,22 +1543,23 @@ p_do_filter_dialogs(GapAnimInfo *ainfo_ptr,
} /* end p_do_filter_dialogs */
-/* ============================================================================
+/* -------------------------
* p_do_2nd_filter_dialogs
+ * -------------------------
* d) [ 2nd interactive filtercall
* e) 2nd pitstop dialog ]
*
* (temporary) open the last frame of the range
- * get its 1.st selected laye
+ * get its 1.st selected layer
* and do the Interctive Filtercall (to get the end-values)
*
* then close everything (without save).
* (the last frame will be processed later, with all its selected layers)
- * ============================================================================
*/
static gint
p_do_2nd_filter_dialogs(char *filter_procname,
gint32 accelCharacteristic,
+ gint32 groupFilterHandlingMode,
char *last_frame_filename,
gint32 sel_mode, gint32 sel_case,
gint32 sel_invert, char *sel_pattern,
@@ -1527,38 +1588,100 @@ p_do_2nd_filter_dialogs(char *filter_procname,
/* --------------------------------- */
if(last_frame_filename == NULL)
{
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs last_frame_filename is NULL\n");
+ }
return (-1); /* there is no 2.nd frame for 2.nd filter call */
}
if(p_pitstop_dialog(0, filter_procname) < 0)
- goto cleanup;
-
+ {
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs Cancelled via pitstop dialog l_rc:%d\n"
+ , (int)l_rc
+ );
+ }
+ goto cleanup;
+ }
+
/* load last frame into temporary image */
l_last_image_id = gap_lib_load_image(last_frame_filename);
if (l_last_image_id < 0)
- goto cleanup;
-
+ {
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs load latst image FAILED l_rc:%d last_frame_filename:%s\n"
+ , (int)l_rc
+ , last_frame_filename
+ );
+ }
+ goto cleanup;
+ }
+
/* get informations (id, visible, selected) about all layers */
l_layli_ptr = gap_mod_alloc_layli_group(l_last_image_id, &l_sel_cnt, &l_nlayers,
sel_mode, sel_case, sel_invert, sel_pattern,
sel_groupname, delimiter);
if (l_layli_ptr == NULL)
- goto cleanup;
-
+ {
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs l_layli_ptr is NULL l_rc:%d, sel_groupname:%s \n"
+ , (int)l_rc
+ , sel_groupname
+ );
+ }
+ g_message(_("No selected layer for group:%s in last handled frame"), sel_groupname);
+ goto cleanup;
+ }
+
/* get 1.st selected layer (of last handled frame in range ) */
l_idx = gap_mod_get_1st_selected(l_layli_ptr, l_nlayers);
if(l_idx < 0)
{
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs No layer selected in last handled frame l_rc:%d, sel_groupname:%s
l_idx:%d\n"
+ , (int)l_rc
+ , sel_groupname
+ , (int)l_idx
+ );
+ }
g_message (_("Modify Layers cancelled: No layer selected in last handled frame"));
goto cleanup;
}
- l_drawable_id = l_layli_ptr[l_idx].layer_id;
+ l_drawable_id = p_get_layer_according_to_group_handling(l_layli_ptr[l_idx].layer_id,
groupFilterHandlingMode);
+ if (l_drawable_id < 0)
+ {
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs No layer selected in last handled frame l_rc:%d, sel_groupname:%s
l_drawable_id:%d layer:%d (%s) is a GROUPLAYER\n"
+ , (int)l_rc
+ , sel_groupname
+ , (int)l_drawable_id
+ , (int)l_layli_ptr[l_idx].layer_id
+ , gimp_item_get_name(l_layli_ptr[l_idx].layer_id)
+ );
+ }
+ g_message (_("Modify Layers cancelled: No normal layer selected in last handled frame"));
+ goto cleanup;
+ }
if(operate_on_layermask)
{
l_drawable_id = gimp_layer_get_mask(l_layli_ptr[l_idx].layer_id);
if(l_drawable_id < 0)
{
+ if(gap_debug)
+ {
+ printf("p_do_2nd_filter_dialogs first selected layer in last handled frame has no layermask l_rc:%d,
l_drawable_id:%d (%s)\n"
+ , (int)l_rc
+ , (int)l_drawable_id
+ , gimp_item_get_name(l_drawable_id)
+ );
+ }
g_message (_("Modify Layers cancelled: first selected layer \"%s\"\nin last frame has no layermask"),
gimp_item_get_name(l_layli_ptr[l_idx].layer_id)
);
@@ -1576,15 +1699,16 @@ p_do_2nd_filter_dialogs(char *filter_procname,
/* get values, then store with suffix "-ITER-TO" */
l_plugin_data_len = gap_filt_pdb_get_data(filter_procname);
if(l_plugin_data_len <= 0)
+ {
goto cleanup;
+ }
+ g_snprintf(l_key_to, sizeof(l_key_to), "%s%s", filter_procname, GAP_ITER_TO_SUFFIX);
+ gap_filt_pdb_set_data(l_key_to, l_plugin_data_len);
- g_snprintf(l_key_to, sizeof(l_key_to), "%s%s", filter_procname, GAP_ITER_TO_SUFFIX);
- gap_filt_pdb_set_data(l_key_to, l_plugin_data_len);
-
- /* get FROM values */
- g_snprintf(l_key_from, sizeof(l_key_from), "%s%s", filter_procname, GAP_ITER_FROM_SUFFIX);
- l_plugin_data_len = gap_filt_pdb_get_data(l_key_from);
- gap_filt_pdb_set_data(filter_procname, l_plugin_data_len);
+ /* get FROM values */
+ g_snprintf(l_key_from, sizeof(l_key_from), "%s%s", filter_procname, GAP_ITER_FROM_SUFFIX);
+ l_plugin_data_len = gap_filt_pdb_get_data(l_key_from);
+ gap_filt_pdb_set_data(filter_procname, l_plugin_data_len);
l_rc = p_pitstop_dialog(1, filter_procname);
@@ -1656,6 +1780,7 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
gdouble l_cur_step;
gint l_total_steps;
gint32 accelCharacteristic;
+ gint32 groupFilterHandlingMode;
char *l_last_frame_filename;
gint l_count;
gboolean l_operating_on_current_image;
@@ -1731,12 +1856,18 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
}
/* build the frame name */
- if(ainfo_ptr->new_filename != NULL) g_free(ainfo_ptr->new_filename);
+ if(ainfo_ptr->new_filename != NULL)
+ {
+ g_free(ainfo_ptr->new_filename);
+ }
ainfo_ptr->new_filename = gap_lib_alloc_fname(ainfo_ptr->basename,
l_cur_frame_nr,
ainfo_ptr->extension);
if(ainfo_ptr->new_filename == NULL)
{
+ printf("gap_mod_frames_modify Failed to allocate filename at l_cur_frame_nr:%d filename is NULL \n"
+ , (int)l_cur_frame_nr
+ );
goto error;
}
@@ -1760,6 +1891,10 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
}
if(l_tmp_image_id < 0)
{
+ printf("gap_mod_frames_modify Failed to load frame l_cur_frame_nr:%d l_tmp_image_id:%d \n"
+ , (int)l_cur_frame_nr
+ , (int)l_tmp_image_id
+ );
goto error;
}
@@ -1768,16 +1903,23 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
sel_mode, sel_case, sel_invert, sel_pattern,
sel_groupname, delimiter);
- if(l_layli_ptr == NULL)
- {
- printf("gap: gap_mod_frames_modify: cant alloc layer info list\n");
- goto error;
- }
if((l_cur_frame_nr == l_begin)
&& ((action_mode == GAP_MOD_ACM_APPLY_FILTER) || (action_mode == GAP_MOD_ACM_APPLY_FILTER_ON_LAYERMASK)))
{
/* ------------- 1.st frame: extra dialogs for APPLY_FILTER ---------- */
+ if(l_layli_ptr == NULL)
+ {
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify: l_layli_ptr is NULL (no relevant layer available in this
frame) l_cur_frame_nr:%d sel_groupname:%s\n"
+ , (int)l_cur_frame_nr
+ , sel_groupname
+ );
+ }
+ g_message(_("No selected layer for group:%s in start frame"), sel_groupname);
+ goto error;
+ }
if(l_sel_cnt < 1)
{
@@ -1814,14 +1956,23 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
* e) 2nd pitstop dialog ]
*/
+ gimp_image_undo_group_start (l_tmp_image_id);
l_rc = p_do_filter_dialogs(ainfo_ptr,
l_tmp_image_id, &l_dpy_id,
l_layli_ptr, l_nlayers,
&l_filter_procname[0], sizeof(l_filter_procname),
&l_plugin_data_len,
&accelCharacteristic,
+ &groupFilterHandlingMode,
l_operate_on_layermask
);
+ gimp_image_undo_group_end (l_tmp_image_id);
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify p_do_filter_dialogs (1) l_rc:%d\n"
+ , (int)l_rc
+ );
+ }
if(l_last_frame_filename != NULL)
{
@@ -1829,11 +1980,18 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
{
l_rc = p_do_2nd_filter_dialogs(&l_filter_procname[0],
accelCharacteristic,
+ groupFilterHandlingMode,
l_last_frame_filename,
sel_mode, sel_case, sel_invert, sel_pattern,
l_operate_on_layermask,
sel_groupname, delimiter
);
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify p_do_2nd_filter_dialogs (2) l_rc:%d\n"
+ , (int)l_rc
+ );
+ }
}
g_free(l_last_frame_filename);
@@ -1857,15 +2015,36 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
{
l_plugin_iterator = gap_filt_pdb_get_iterator_proc(&l_filter_procname[0], &l_count);
}
- }
+ } /* -- END -- 1.st extra dialog stuff -- */
+
if(l_rc != 0)
{
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify failed. rc=%d l_cur_frame_nr:%d\n"
+ , (int)l_rc
+ , (int)l_cur_frame_nr
+ );
+ }
goto error;
}
- /* perform function (defined by action_mode) on selcted layer(s) */
- l_rc = p_apply_action(l_tmp_image_id,
+ if(l_layli_ptr == NULL)
+ {
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify: l_layli_ptr is NULL (no layer relevant layer available in this
frame) l_cur_frame_nr:%d sel_groupname:%s\n"
+ , (int)l_cur_frame_nr
+ , sel_groupname
+ );
+ }
+ /* continue with next frame */
+ }
+ else
+ {
+ /* perform function (defined by action_mode) on selcted layer(s) */
+ l_rc = p_apply_action(l_tmp_image_id,
action_mode,
l_layli_ptr,
l_nlayers,
@@ -1876,11 +2055,18 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
ainfo_ptr->image_id, /* MASTER_image_id */
new_position,
new_groupname,
- delimiter
+ delimiter,
+ groupFilterHandlingMode
);
+ }
+
+
if(l_rc != 0)
{
- if(gap_debug) printf("gap: gap_mod_frames_modify p_apply-action failed. rc=%d\n", (int)l_rc);
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify p_apply-action failed. rc=%d\n", (int)l_rc);
+ }
goto error;
}
@@ -1901,7 +2087,10 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
printf("gap: gap_mod_frames_modify save frame %d failed.\n", (int)l_cur_frame_nr);
goto error;
}
- else l_rc = 0;
+ else
+ {
+ l_rc = 0;
+ }
/* iterator call (for filter apply with varying values) */
if((action_mode == GAP_MOD_ACM_APPLY_FILTER)
@@ -1973,6 +2162,12 @@ gap_mod_frames_modify(GapAnimInfo *ainfo_ptr,
if(l_rc != 0)
{
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify p_apply-action failed with rc=%d\n"
+ , (int)l_rc
+ );
+ }
goto error;
}
@@ -2051,12 +2246,18 @@ modify_advance_to_next_frame:
}
}
- if(gap_debug) printf("gap_mod_frames_modify End OK\n");
+ if(gap_debug)
+ {
+ printf("gap_mod_frames_modify End OK\n");
+ }
return 0;
error:
- if(gap_debug) printf("gap: gap_mod_frames_modify exit with Error\n");
+ if(gap_debug)
+ {
+ printf("gap: gap_mod_frames_modify exit with Error\n");
+ }
if((l_tmp_image_id >= 0) && (l_operating_on_current_image == FALSE))
{
@@ -2067,15 +2268,21 @@ error:
gimp_display_delete(l_dpy_id);
l_dpy_id = -1;
}
- if(l_layli_ptr != NULL) g_free(l_layli_ptr);
- if(l_plugin_iterator != NULL) g_free(l_plugin_iterator);
+ if(l_layli_ptr != NULL)
+ {
+ g_free(l_layli_ptr);
+ }
+ if(l_plugin_iterator != NULL)
+ {
+ g_free(l_plugin_iterator);
+ }
return -1;
} /* end gap_mod_frames_modify */
-/* ============================================================================
+/* ---------------
* gap_mod_layer
- * ============================================================================
+ * ---------------
*/
gint gap_mod_layer(GimpRunMode run_mode, gint32 image_id,
gint32 range_from, gint32 range_to,
@@ -2118,6 +2325,7 @@ gint gap_mod_layer(GimpRunMode run_mode, gint32 image_id,
if (0 == gap_lib_dir_ainfo(ainfo_ptr))
{
+
if(run_mode == GIMP_RUN_INTERACTIVE)
{
/* note: for interactive call the processing is already done
@@ -2156,7 +2364,7 @@ gint gap_mod_layer(GimpRunMode run_mode, gint32 image_id,
if(l_rc >= 0)
{
gboolean run_flag;
-
+
run_flag = TRUE;
/* no need to save the current image before processing
* because the gap_mod_frames_modify procedure operates directly on the current frame
diff --git a/gap/gap_player_cache.c b/gap/gap_player_cache.c
index 95ac5a5..3fd8b75 100644
--- a/gap/gap_player_cache.c
+++ b/gap/gap_player_cache.c
@@ -104,9 +104,6 @@
extern int gap_debug; /* 1 == print debug infos , 0 dont print debug infos */
-// local debug setting
-//static gint gap_debug = 1; /* 1 == print debug infos , 0 dont print debug infos */
-
typedef struct GapPlayerCacheElem {
gchar *ckey;
diff --git a/gap/gap_water_pattern.c b/gap/gap_water_pattern.c
index f0809a4..0e3434e 100644
--- a/gap/gap_water_pattern.c
+++ b/gap/gap_water_pattern.c
@@ -224,11 +224,11 @@ p_int_default_cuvals(waterpattern_val_t *cuvals)
static void
p_check_for_valid_cloud_layers(waterpattern_val_t *cuvals)
{
- if(gimp_drawable_is_valid(cuvals->cloudLayer1) != TRUE)
+ if(gimp_item_is_valid(cuvals->cloudLayer1) != TRUE)
{
cuvals->cloudLayer1 = -1;
}
- if(gimp_drawable_is_valid(cuvals->cloudLayer2) != TRUE)
+ if(gimp_item_is_valid(cuvals->cloudLayer2) != TRUE)
{
cuvals->cloudLayer2 = -1;
}
@@ -305,7 +305,7 @@ p_init_context_and_cloud_layers(gint32 drawable_id, waterpattern_val_t *cuvals,
/* check if both cloud layers are already available */
- if((!gimp_drawable_is_valid(cuvals->cloudLayer1)) || (!gimp_drawable_is_valid(cuvals->cloudLayer2)))
+ if((!gimp_item_is_valid(cuvals->cloudLayer1)) || (!gimp_item_is_valid(cuvals->cloudLayer2)))
{
/* create both cloud layers */
GRand *gr;
@@ -792,11 +792,11 @@ p_init_widget_values(WaterPatternDialog *wcd)
}
countClouds = 0;
- if(gimp_drawable_is_valid(wcd->existingCloud1Id))
+ if(gimp_item_is_valid(wcd->existingCloud1Id))
{
countClouds++;
}
- if(gimp_drawable_is_valid(wcd->existingCloud2Id))
+ if(gimp_item_is_valid(wcd->existingCloud2Id))
{
countClouds++;
}
@@ -946,7 +946,7 @@ p_pattern_layer_constrain(gint32 image_id, gint32 drawable_id, WaterPatternDialo
return(TRUE);
}
- if(gimp_drawable_is_valid(drawable_id) != TRUE)
+ if(gimp_item_is_valid(drawable_id) != TRUE)
{
return(FALSE);
}
@@ -1012,12 +1012,12 @@ do_dialog (WaterPatternDialog *wcd, waterpattern_val_t *cuvals)
wcd->existingCloud2Id = -1;
countClouds = 0;
wcd->countPotentialCloudLayers = 0;
- if(gimp_drawable_is_valid(cuvals->cloudLayer1))
+ if(gimp_item_is_valid(cuvals->cloudLayer1))
{
countClouds++;
wcd->existingCloud1Id = cuvals->cloudLayer1;
}
- if(gimp_drawable_is_valid(cuvals->cloudLayer2))
+ if(gimp_item_is_valid(cuvals->cloudLayer2))
{
countClouds++;
wcd->existingCloud2Id = cuvals->cloudLayer2;
diff --git a/gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc b/gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc
index 1cf824a..ece022c 100644
--- a/gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc
+++ b/gap/iter_ALT/mod/plug_in_bump_map_iter_ALT.inc
@@ -6,20 +6,23 @@ gint p_plug_in_bump_map_iter_ALT(GimpRunMode run_mode, gint32 total_steps, gdoub
{
typedef struct t_plug_in_bump_map_Vals
{
- gint32 bumpmap;
- gdouble azimuth;
- gdouble elevation;
- long depth;
- long xofs;
- long yofs;
- long waterlevel;
- long ambient;
- long compensate;
- long invert;
- long type;
- long tiled;
+ gint32 bumpmap_id;
+ gdouble azimuth;
+ gdouble elevation;
+ gint depth;
+ gint xofs;
+ gint yofs;
+ gint waterlevel;
+ gint ambient;
+ gboolean compensate;
+ gboolean invert;
+ gint type;
+ gboolean tiled;
} t_plug_in_bump_map_Vals;
+
+
+
t_plug_in_bump_map_Vals buf, *buf_from, *buf_to;
if(len_struct != sizeof(t_plug_in_bump_map_Vals))
@@ -36,17 +39,15 @@ gint p_plug_in_bump_map_iter_ALT(GimpRunMode run_mode, gint32 total_steps, gdoub
buf_to = (t_plug_in_bump_map_Vals *)&g_plugin_data_to[0];
memcpy(&buf, buf_from, sizeof(buf));
- p_delta_drawable(&buf.bumpmap, buf_from->bumpmap, buf_to->bumpmap, total_steps, current_step);
+ p_delta_drawable(&buf.bumpmap_id, buf_from->bumpmap_id, buf_to->bumpmap_id, total_steps, current_step);
p_delta_gdouble(&buf.azimuth, buf_from->azimuth, buf_to->azimuth, total_steps, current_step);
p_delta_gdouble(&buf.elevation, buf_from->elevation, buf_to->elevation, total_steps, current_step);
- p_delta_long(&buf.depth, buf_from->depth, buf_to->depth, total_steps, current_step);
- p_delta_long(&buf.xofs, buf_from->xofs, buf_to->xofs, total_steps, current_step);
- p_delta_long(&buf.yofs, buf_from->yofs, buf_to->yofs, total_steps, current_step);
- p_delta_long(&buf.waterlevel, buf_from->waterlevel, buf_to->waterlevel, total_steps, current_step);
- p_delta_long(&buf.ambient, buf_from->ambient, buf_to->ambient, total_steps, current_step);
- p_delta_long(&buf.compensate, buf_from->compensate, buf_to->compensate, total_steps, current_step);
- p_delta_long(&buf.invert, buf_from->invert, buf_to->invert, total_steps, current_step);
- p_delta_long(&buf.type, buf_from->type, buf_to->type, total_steps, current_step);
+ p_delta_gint(&buf.depth, buf_from->depth, buf_to->depth, total_steps, current_step);
+ p_delta_gint(&buf.xofs, buf_from->xofs, buf_to->xofs, total_steps, current_step);
+ p_delta_gint(&buf.yofs, buf_from->yofs, buf_to->yofs, total_steps, current_step);
+ p_delta_gint(&buf.waterlevel, buf_from->waterlevel, buf_to->waterlevel, total_steps, current_step);
+ p_delta_gint(&buf.ambient, buf_from->ambient, buf_to->ambient, total_steps, current_step);
+ p_delta_gint(&buf.type, buf_from->type, buf_to->type, total_steps, current_step);
gimp_set_data("plug-in-bump-map", &buf, sizeof(buf));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]