mirror of https://github.com/GNOME/gimp.git
Bug 773450 - Animated WEBP images should be able to set frame delay.
animated webp saving: parse time-stamp from layer_name (instead of using default value of '100') also: - add a default delay field to UI, in case time-stamps are not present. - add a 'force delay' checkbox - revamp the whole UI to look like the GIF saving UI.
This commit is contained in:
parent
87d38194d7
commit
d516f9bef8
plug-ins/file-webp
|
@ -92,27 +92,25 @@ save_dialog (WebPSaveParams *params,
|
|||
gint32 image_ID,
|
||||
gint32 n_layers)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *table;
|
||||
GtkWidget *expander;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *save_exif;
|
||||
GtkWidget *save_xmp;
|
||||
GtkWidget *preset_label;
|
||||
GtkListStore *preset_list;
|
||||
GtkWidget *preset_combo;
|
||||
GtkWidget *lossless_checkbox;
|
||||
GtkWidget *animation_checkbox;
|
||||
GtkWidget *loop_anim_checkbox;
|
||||
GtkObject *quality_scale;
|
||||
GtkObject *alpha_quality_scale;
|
||||
gboolean animation_supported = FALSE;
|
||||
gint slider1 , slider2;
|
||||
gboolean run;
|
||||
gchar *text;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *table;
|
||||
GtkWidget *expander;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *save_exif;
|
||||
GtkWidget *save_xmp;
|
||||
GtkWidget *preset_label;
|
||||
GtkListStore *preset_list;
|
||||
GtkWidget *preset_combo;
|
||||
GtkWidget *lossless_checkbox;
|
||||
GtkWidget *animation_checkbox;
|
||||
GtkObject *quality_scale;
|
||||
GtkObject *alpha_quality_scale;
|
||||
gboolean animation_supported = FALSE;
|
||||
gboolean run;
|
||||
gchar *text;
|
||||
|
||||
animation_supported = n_layers > 1;
|
||||
|
||||
|
@ -127,7 +125,11 @@ save_dialog (WebPSaveParams *params,
|
|||
gtk_widget_show (vbox);
|
||||
|
||||
/* Create the descriptive label at the top */
|
||||
label = gtk_label_new (_("Use the options below to customize the image."));
|
||||
text = g_strdup_printf ("<b>%s</b>", _("WebP Options"));
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup(GTK_LABEL(label), text);
|
||||
g_free (text);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
|
@ -138,80 +140,9 @@ save_dialog (WebPSaveParams *params,
|
|||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
||||
gtk_widget_show (table);
|
||||
|
||||
/* Create the label for the selecting a preset */
|
||||
preset_label = gtk_label_new (_("Preset:"));
|
||||
gtk_label_set_xalign (GTK_LABEL (preset_label), 0.0);
|
||||
gtk_table_attach (GTK_TABLE (table), preset_label,
|
||||
0, 1, 0, 1,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (preset_label);
|
||||
|
||||
/* Create the combobox containing the presets */
|
||||
preset_list = save_dialog_presets ();
|
||||
preset_combo = gimp_string_combo_box_new (GTK_TREE_MODEL (preset_list), 0, 1);
|
||||
g_object_unref (preset_list);
|
||||
|
||||
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (preset_combo),
|
||||
params->preset);
|
||||
gtk_table_attach (GTK_TABLE (table), preset_combo,
|
||||
1, 3, 0, 1,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (preset_combo);
|
||||
|
||||
g_signal_connect (preset_combo, "changed",
|
||||
G_CALLBACK (save_dialog_preset_changed),
|
||||
¶ms->preset);
|
||||
|
||||
/* Create the lossless checkbox */
|
||||
lossless_checkbox = gtk_check_button_new_with_label (_("Lossless"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lossless_checkbox),
|
||||
params->lossless);
|
||||
gtk_table_attach (GTK_TABLE (table), lossless_checkbox,
|
||||
1, 3, 1, 2,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (lossless_checkbox);
|
||||
|
||||
g_signal_connect (lossless_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->lossless);
|
||||
|
||||
slider1 = 2;
|
||||
slider2 = 3;
|
||||
if (animation_supported)
|
||||
{
|
||||
slider1 = 4;
|
||||
slider2 = 5;
|
||||
|
||||
/* Create the animation checkbox */
|
||||
animation_checkbox = gtk_check_button_new_with_label (_("Use animation"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (animation_checkbox),
|
||||
params->animation);
|
||||
gtk_table_attach (GTK_TABLE (table), animation_checkbox,
|
||||
1, 3, 2, 3,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (animation_checkbox);
|
||||
|
||||
g_signal_connect (animation_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->animation);
|
||||
|
||||
/* Create the loop animation checkbox */
|
||||
loop_anim_checkbox = gtk_check_button_new_with_label (_("Loop infinitely"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (loop_anim_checkbox),
|
||||
params->loop);
|
||||
gtk_table_attach (GTK_TABLE (table), loop_anim_checkbox,
|
||||
1, 3, 3, 4,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (loop_anim_checkbox);
|
||||
|
||||
g_signal_connect (loop_anim_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->loop);
|
||||
}
|
||||
|
||||
/* Create the slider for image quality */
|
||||
quality_scale = gimp_scale_entry_new (GTK_TABLE (table),
|
||||
0, slider1,
|
||||
0, 0,
|
||||
_("Image quality:"),
|
||||
125,
|
||||
0,
|
||||
|
@ -230,7 +161,7 @@ save_dialog (WebPSaveParams *params,
|
|||
|
||||
/* Create the slider for alpha channel quality */
|
||||
alpha_quality_scale = gimp_scale_entry_new (GTK_TABLE (table),
|
||||
0, slider2,
|
||||
0, 1,
|
||||
_("Alpha quality:"),
|
||||
125,
|
||||
0,
|
||||
|
@ -247,6 +178,43 @@ save_dialog (WebPSaveParams *params,
|
|||
G_CALLBACK (gimp_float_adjustment_update),
|
||||
¶ms->alpha_quality);
|
||||
|
||||
/* Create the label for the selecting a preset */
|
||||
preset_label = gtk_label_new (_("Preset:"));
|
||||
gtk_label_set_xalign (GTK_LABEL (preset_label), 0.0);
|
||||
gtk_table_attach (GTK_TABLE (table), preset_label,
|
||||
0, 1, 2, 3,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (preset_label);
|
||||
|
||||
/* Create the combobox containing the presets */
|
||||
preset_list = save_dialog_presets ();
|
||||
preset_combo = gimp_string_combo_box_new (GTK_TREE_MODEL (preset_list), 0, 1);
|
||||
g_object_unref (preset_list);
|
||||
|
||||
gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (preset_combo),
|
||||
params->preset);
|
||||
gtk_table_attach (GTK_TABLE (table), preset_combo,
|
||||
1, 3, 2, 3,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (preset_combo);
|
||||
|
||||
g_signal_connect (preset_combo, "changed",
|
||||
G_CALLBACK (save_dialog_preset_changed),
|
||||
¶ms->preset);
|
||||
|
||||
/* Create the lossless checkbox */
|
||||
lossless_checkbox = gtk_check_button_new_with_label (_("Lossless"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lossless_checkbox),
|
||||
params->lossless);
|
||||
gtk_table_attach (GTK_TABLE (table), lossless_checkbox,
|
||||
0, 4, 3, 4,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (lossless_checkbox);
|
||||
|
||||
g_signal_connect (lossless_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->lossless);
|
||||
|
||||
/* Enable and disable the sliders when the lossless option is selected */
|
||||
g_signal_connect (lossless_checkbox, "toggled",
|
||||
G_CALLBACK (save_dialog_toggle_scale),
|
||||
|
@ -255,6 +223,113 @@ save_dialog (WebPSaveParams *params,
|
|||
G_CALLBACK (save_dialog_toggle_scale),
|
||||
alpha_quality_scale);
|
||||
|
||||
if (animation_supported)
|
||||
{
|
||||
GtkWidget *animation_box;
|
||||
GtkWidget *animation_box2;
|
||||
GtkWidget *animation_label;
|
||||
GtkWidget *loop_anim_checkbox;
|
||||
GtkWidget *animation_expander;
|
||||
GtkWidget *animation_frame;
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *delay;
|
||||
GtkWidget *delay_label;
|
||||
GtkWidget *delay_label2;
|
||||
GtkWidget *delay_hbox;
|
||||
GtkWidget *delay_checkbox;
|
||||
|
||||
/* Create the top-level animation checkbox */
|
||||
animation_checkbox = gtk_check_button_new_with_label (_("As animation"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (animation_checkbox),
|
||||
params->animation);
|
||||
gtk_table_attach (GTK_TABLE (table), animation_checkbox,
|
||||
0, 4, 4, 5,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_set_sensitive (animation_checkbox, TRUE);
|
||||
g_signal_connect (animation_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->animation);
|
||||
gtk_widget_show (animation_checkbox);
|
||||
|
||||
text = g_strdup_printf ("<b>%s</b>", _("Animated WebP Options"));
|
||||
animation_expander = gtk_expander_new_with_mnemonic (text);
|
||||
gtk_expander_set_use_markup (GTK_EXPANDER (animation_expander), TRUE);
|
||||
g_free (text);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), animation_expander, TRUE, TRUE, 0);
|
||||
gtk_widget_show (animation_expander);
|
||||
|
||||
/* animation options box */
|
||||
animation_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (animation_box), 6);
|
||||
gtk_container_add (GTK_CONTAINER (animation_expander), animation_box);
|
||||
gtk_widget_show (animation_box);
|
||||
|
||||
animation_frame = gimp_frame_new ("<expander>");
|
||||
gtk_box_pack_start (GTK_BOX (animation_box), animation_frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (animation_frame);
|
||||
|
||||
animation_box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
gtk_container_add (GTK_CONTAINER (animation_frame), animation_box2);
|
||||
gtk_widget_show (animation_box2);
|
||||
|
||||
/* loop animation checkbox */
|
||||
loop_anim_checkbox = gtk_check_button_new_with_label (_("Loop forever"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (loop_anim_checkbox),
|
||||
params->loop);
|
||||
gtk_box_pack_start (GTK_BOX (animation_box2), loop_anim_checkbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (loop_anim_checkbox);
|
||||
|
||||
g_signal_connect (loop_anim_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->loop);
|
||||
|
||||
/* create a hbox for delay */
|
||||
delay_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
gtk_box_pack_start (GTK_BOX (animation_box2), delay_hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (delay_hbox);
|
||||
|
||||
/* label for 'delay' adjustment */
|
||||
delay_label = gtk_label_new (_("Delay between frames where unspecified:"));
|
||||
gtk_label_set_xalign (GTK_LABEL (delay_label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (delay_hbox), delay_label, FALSE, FALSE, 0);
|
||||
gtk_widget_show (delay_label);
|
||||
|
||||
/* default delay */
|
||||
adj = (GtkAdjustment *) gtk_adjustment_new (params->delay, 1, 10000, 1, 10, 0);
|
||||
delay = gtk_spin_button_new (adj, 1, 0);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (delay), TRUE);
|
||||
gtk_box_pack_start (GTK_BOX (delay_hbox), delay, FALSE, FALSE, 0);
|
||||
gtk_widget_show (delay);
|
||||
|
||||
g_signal_connect (adj, "value-changed",
|
||||
G_CALLBACK (gimp_int_adjustment_update),
|
||||
¶ms->delay);
|
||||
|
||||
/* label for 'ms' adjustment */
|
||||
delay_label2 = gtk_label_new (_("milliseconds"));
|
||||
gtk_box_pack_start (GTK_BOX (delay_hbox), delay_label2, FALSE, FALSE, 0);
|
||||
gtk_widget_show (delay_label2);
|
||||
|
||||
/* Create the force-delay checkbox */
|
||||
delay_checkbox = gtk_check_button_new_with_label (_("Use delay entered above for all frames"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (delay_checkbox),
|
||||
params->force_delay);
|
||||
gtk_box_pack_start (GTK_BOX (animation_box2), delay_checkbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (delay_checkbox);
|
||||
|
||||
g_signal_connect (delay_checkbox, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->force_delay);
|
||||
|
||||
|
||||
|
||||
/* bind the animation checkbox to the parameters */
|
||||
g_object_bind_property (animation_checkbox, "active",
|
||||
animation_expander, "sensitive",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
}
|
||||
|
||||
/* Advanced options */
|
||||
text = g_strdup_printf ("<b>%s</b>", _("_Advanced Options"));
|
||||
expander = gtk_expander_new_with_mnemonic (text);
|
||||
gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
|
||||
|
@ -295,6 +370,7 @@ save_dialog (WebPSaveParams *params,
|
|||
G_CALLBACK (gimp_toggle_button_update),
|
||||
¶ms->xmp);
|
||||
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
||||
|
|
|
@ -368,6 +368,53 @@ save_layer (const gchar *filename,
|
|||
return status;
|
||||
}
|
||||
|
||||
static gint
|
||||
parse_ms_tag (const gchar *str)
|
||||
{
|
||||
gint sum = 0;
|
||||
gint offset = 0;
|
||||
gint length;
|
||||
|
||||
length = strlen (str);
|
||||
|
||||
find_another_bra:
|
||||
|
||||
while ((offset < length) && (str[offset] != '('))
|
||||
offset++;
|
||||
|
||||
if (offset >= length)
|
||||
return(-1);
|
||||
|
||||
if (! g_ascii_isdigit (str[++offset]))
|
||||
goto find_another_bra;
|
||||
|
||||
do
|
||||
{
|
||||
sum *= 10;
|
||||
sum += str[offset] - '0';
|
||||
offset++;
|
||||
}
|
||||
while ((offset < length) && (g_ascii_isdigit (str[offset])));
|
||||
|
||||
if (length - offset <= 2)
|
||||
return(-3);
|
||||
|
||||
if ((g_ascii_toupper (str[offset]) != 'M') ||
|
||||
(g_ascii_toupper (str[offset + 1]) != 'S'))
|
||||
return -4;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_layer_delay(gint32 layer)
|
||||
{
|
||||
gchar *layer_name = gimp_item_get_name (layer);
|
||||
gint delay_ms = parse_ms_tag (layer_name);
|
||||
g_free (layer_name);
|
||||
return delay_ms;
|
||||
}
|
||||
|
||||
gboolean
|
||||
save_animation (const gchar *filename,
|
||||
gint32 nLayers,
|
||||
|
@ -399,7 +446,9 @@ save_animation (const gchar *filename,
|
|||
|
||||
do
|
||||
{
|
||||
gint loop;
|
||||
gint loop;
|
||||
gint default_delay = params->delay;
|
||||
gboolean force_delay = params->force_delay;
|
||||
|
||||
/* Begin displaying export progress */
|
||||
gimp_progress_init_printf (_("Saving '%s'"),
|
||||
|
@ -438,6 +487,7 @@ save_animation (const gchar *filename,
|
|||
WebPPicture picture;
|
||||
WebPMemoryWriter mw = { 0 };
|
||||
gint32 drawable = allLayers[nLayers - 1 - loop];
|
||||
gint delay = get_layer_delay (drawable);
|
||||
|
||||
/* Obtain the drawable type */
|
||||
has_alpha = gimp_drawable_has_alpha (drawable);
|
||||
|
@ -537,7 +587,7 @@ save_animation (const gchar *filename,
|
|||
g_object_unref (geglbuffer);
|
||||
|
||||
gimp_progress_update ((loop + 1.0) / nLayers);
|
||||
frame_timestamp += 100; /* TODO: should extract the real time stamp from layer */
|
||||
frame_timestamp += (delay <= 0 || force_delay) ? default_delay : delay;
|
||||
}
|
||||
|
||||
if (status == FALSE)
|
||||
|
|
|
@ -34,6 +34,8 @@ typedef struct
|
|||
gboolean exif;
|
||||
gboolean iptc;
|
||||
gboolean xmp;
|
||||
gint delay;
|
||||
gboolean force_delay;
|
||||
} WebPSaveParams;
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static void run (const gchar *name,
|
|||
GimpParam **return_vals);
|
||||
|
||||
|
||||
GimpPlugInInfo PLUG_IN_INFO =
|
||||
const GimpPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -85,7 +85,9 @@ query (void)
|
|||
{ GIMP_PDB_INT32, "anim-loop", "Loop animation infinitely (0/1)" },
|
||||
{ GIMP_PDB_INT32, "exif", "Toggle saving exif data (0/1)" },
|
||||
{ GIMP_PDB_INT32, "iptc", "Toggle saving iptc data (0/1)" },
|
||||
{ GIMP_PDB_INT32, "xmp", "Toggle saving xmp data (0/1)" }
|
||||
{ GIMP_PDB_INT32, "xmp", "Toggle saving xmp data (0/1)" },
|
||||
{ GIMP_PDB_INT32, "delay", "Delay to use when timestamp are not available or forced" },
|
||||
{ GIMP_PDB_INT32, "force-delay", "Toggle to for delay" }
|
||||
};
|
||||
|
||||
gimp_install_procedure (LOAD_PROC,
|
||||
|
@ -172,28 +174,23 @@ run (const gchar *name,
|
|||
{
|
||||
WebPSaveParams params;
|
||||
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
||||
gint32 *layers;
|
||||
gint32 *layers = NULL;
|
||||
gint32 n_layers;
|
||||
|
||||
/* Initialize the parameters to their defaults */
|
||||
params.preset = g_strdup ("default");
|
||||
params.lossless = FALSE;
|
||||
params.animation = FALSE;
|
||||
params.loop = TRUE;
|
||||
params.quality = 90.0f;
|
||||
params.alpha_quality = 100.0f;
|
||||
params.exif = TRUE;
|
||||
params.iptc = TRUE;
|
||||
params.xmp = TRUE;
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE ||
|
||||
run_mode == GIMP_RUN_WITH_LAST_VALS)
|
||||
gimp_ui_init (PLUG_IN_BINARY, FALSE);
|
||||
|
||||
image_ID = param[1].data.d_int32;
|
||||
drawable_ID = param[2].data.d_int32;
|
||||
|
||||
switch (run_mode)
|
||||
{
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
case GIMP_RUN_WITH_LAST_VALS:
|
||||
gimp_ui_init (PLUG_IN_BINARY, FALSE);
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
/* Possibly retrieve data */
|
||||
gimp_get_data (SAVE_PROC, ¶ms);
|
||||
params.preset = g_strdup ("default"); /* can't serialize strings, so restore default */
|
||||
|
||||
export = gimp_export_image (&image_ID, &drawable_ID, "WebP",
|
||||
GIMP_EXPORT_CAN_HANDLE_RGB |
|
||||
|
@ -205,31 +202,19 @@ run (const gchar *name,
|
|||
if (export == GIMP_EXPORT_CANCEL)
|
||||
{
|
||||
values[0].data.d_status = GIMP_PDB_CANCEL;
|
||||
return;
|
||||
status = GIMP_PDB_CANCEL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
layers = gimp_image_get_layers (image_ID, &n_layers);
|
||||
|
||||
switch (run_mode)
|
||||
{
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
if (! save_dialog (¶ms, image_ID, n_layers))
|
||||
status = GIMP_PDB_CANCEL;
|
||||
break;
|
||||
|
||||
case GIMP_RUN_NONINTERACTIVE:
|
||||
if (nparams != 10)
|
||||
if (nparams != 16)
|
||||
{
|
||||
status = GIMP_PDB_CALLING_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (params.preset);
|
||||
params.preset = g_strdup (param[5].data.d_string);
|
||||
params.lossless = param[6].data.d_int32;
|
||||
params.quality = param[7].data.d_float;
|
||||
|
@ -239,6 +224,8 @@ run (const gchar *name,
|
|||
params.exif = param[11].data.d_int32;
|
||||
params.iptc = param[12].data.d_int32;
|
||||
params.xmp = param[13].data.d_int32;
|
||||
params.delay = param[14].data.d_int32;
|
||||
params.force_delay = param[15].data.d_int32;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -246,24 +233,50 @@ run (const gchar *name,
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
if (! save_image (param[3].data.d_string,
|
||||
n_layers, layers,
|
||||
image_ID,
|
||||
drawable_ID,
|
||||
¶ms,
|
||||
&error))
|
||||
layers = gimp_image_get_layers (image_ID, &n_layers);
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||
{
|
||||
status = GIMP_PDB_EXECUTION_ERROR;
|
||||
if (! save_dialog (¶ms, image_ID, n_layers))
|
||||
{
|
||||
status = GIMP_PDB_CANCEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != GIMP_PDB_SUCCESS)
|
||||
{
|
||||
g_free(params.preset);
|
||||
g_free (layers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! save_image (param[3].data.d_string,
|
||||
n_layers, layers,
|
||||
image_ID,
|
||||
drawable_ID,
|
||||
¶ms,
|
||||
&error))
|
||||
{
|
||||
status = GIMP_PDB_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
g_free (params.preset);
|
||||
params.preset = NULL;
|
||||
|
||||
g_free (layers);
|
||||
|
||||
if (export == GIMP_EXPORT_EXPORT)
|
||||
gimp_image_delete (image_ID);
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
/* save parameters for later */
|
||||
/* we can't serialize strings this way. params.preset isn't saved. */
|
||||
gimp_set_data (SAVE_PROC, ¶ms, sizeof (params));
|
||||
}
|
||||
}
|
||||
|
||||
/* If an error was supplied, include it in the return values */
|
||||
|
|
Loading…
Reference in New Issue