plug-ins: port file-webp to GimpProcedureConfig

This commit is contained in:
Michael Natterer 2019-09-27 16:23:44 +02:00
parent 04280690b2
commit 1b48c687ca
5 changed files with 247 additions and 333 deletions

View file

@ -32,39 +32,31 @@
#include "libgimp/stdplugins-intl.h"
static void save_dialog_toggle_scale (GtkWidget *widget,
gpointer data);
static void save_dialog_toggle_minsize (GtkWidget *widget,
gpointer data);
static void show_maxkeyframe_hints (GtkAdjustment *adj,
GtkLabel *label);
static void
save_dialog_toggle_scale (GtkWidget *widget,
gpointer data)
save_dialog_toggle_scale (GObject *config,
const GParamSpec *pspec,
GtkAdjustment *adjustment)
{
gimp_scale_entry_set_sensitive (data,
! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
gboolean lossless;
g_object_get (config,
"lossless", &lossless,
NULL);
gimp_scale_entry_set_sensitive (adjustment, ! lossless);
}
static void
save_dialog_toggle_minsize (GtkWidget *widget,
gpointer data)
{
gtk_widget_set_sensitive (GTK_WIDGET (data),
! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
}
static void
show_maxkeyframe_hints (GtkAdjustment *adj,
GtkLabel *label)
show_maxkeyframe_hints (GObject *config,
const GParamSpec *pspec,
GtkLabel *label)
{
gint kmax;
kmax = (gint) gtk_adjustment_get_value (adj);
g_object_get (config,
"keyframe-distance", &kmax,
NULL);
if (kmax == 0)
{
gtk_label_set_text (label, _("(no keyframes)"));
@ -80,8 +72,9 @@ show_maxkeyframe_hints (GtkAdjustment *adj,
}
gboolean
save_dialog (WebPSaveParams *params,
GimpImage *image)
save_dialog (GimpImage *image,
GimpProcedure *procedure,
GObject *config)
{
GtkWidget *dialog;
GtkWidget *vbox;
@ -91,7 +84,7 @@ save_dialog (WebPSaveParams *params,
GtkWidget *vbox2;
GtkWidget *label;
GtkWidget *toggle;
GtkWidget *toggle_minsize;
GtkListStore *store;
GtkWidget *combo;
GtkAdjustment *quality_scale;
GtkAdjustment *alpha_quality_scale;
@ -105,17 +98,16 @@ save_dialog (WebPSaveParams *params,
animation_supported = nlayers > 1;
/* Create the dialog */
dialog = gimp_export_dialog_new (_("WebP"), PLUG_IN_BINARY, SAVE_PROC);
dialog = gimp_procedure_dialog_new (procedure,
GIMP_PROCEDURE_CONFIG (config),
_("Export Image as WebP"));
/* Create the vbox */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
/* Create the grid */
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
@ -123,71 +115,48 @@ save_dialog (WebPSaveParams *params,
gtk_widget_show (grid);
/* Create the lossless checkbox */
toggle = gtk_check_button_new_with_mnemonic (_("_Lossless"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
params->lossless);
toggle = gimp_prop_check_button_new (config, "lossless",
_("_Lossless"));
gtk_grid_attach (GTK_GRID (grid), toggle, 0, row, 3, 1);
gtk_widget_show (toggle);
row++;
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->lossless);
/* Create the slider for image quality */
quality_scale = gimp_scale_entry_new (GTK_GRID (grid),
0, row++,
_("Image _quality:"),
125,
0,
params->quality,
0.0, 100.0,
1.0, 10.0,
0, TRUE,
0.0, 0.0,
_("Image quality"),
NULL);
gimp_scale_entry_set_sensitive (quality_scale, ! params->lossless);
g_signal_connect (quality_scale, "value-changed",
G_CALLBACK (gimp_float_adjustment_update),
&params->quality);
quality_scale = gimp_prop_scale_entry_new (config, "quality",
GTK_GRID (grid), 0, row++,
_("Image _quality:"),
1.0, 10.0, 0,
FALSE, 0, 0);
/* Create the slider for alpha channel quality */
alpha_quality_scale = gimp_scale_entry_new (GTK_GRID (grid),
0, row++,
_("Alpha q_uality:"),
125,
0,
params->alpha_quality,
0.0, 100.0,
1.0, 10.0,
0, TRUE,
0.0, 0.0,
_("Alpha channel quality"),
NULL);
gimp_scale_entry_set_sensitive (alpha_quality_scale, ! params->lossless);
g_signal_connect (alpha_quality_scale, "value-changed",
G_CALLBACK (gimp_float_adjustment_update),
&params->alpha_quality);
alpha_quality_scale = gimp_prop_scale_entry_new (config, "alpha-quality",
GTK_GRID (grid), 0, row++,
_("Alpha q_uality:"),
1.0, 10.0, 0,
FALSE, 0, 0);
/* Enable and disable the sliders when the lossless option is selected */
g_signal_connect (toggle, "toggled",
g_signal_connect (config, "notify::lossless",
G_CALLBACK (save_dialog_toggle_scale),
quality_scale);
g_signal_connect (toggle, "toggled",
g_signal_connect (config, "notify::lossless",
G_CALLBACK (save_dialog_toggle_scale),
alpha_quality_scale);
save_dialog_toggle_scale (config, NULL, quality_scale);
save_dialog_toggle_scale (config, NULL, alpha_quality_scale);
/* Create the combobox containing the presets */
combo = gimp_int_combo_box_new ("Default", WEBP_PRESET_DEFAULT,
"Picture", WEBP_PRESET_PICTURE,
"Photo", WEBP_PRESET_PHOTO,
"Drawing", WEBP_PRESET_DRAWING,
"Icon", WEBP_PRESET_ICON,
"Text", WEBP_PRESET_TEXT,
NULL);
store = gimp_int_store_new ("Default", WEBP_PRESET_DEFAULT,
"Picture", WEBP_PRESET_PICTURE,
"Photo", WEBP_PRESET_PHOTO,
"Drawing", WEBP_PRESET_DRAWING,
"Icon", WEBP_PRESET_ICON,
"Text", WEBP_PRESET_TEXT,
NULL);
combo = gimp_prop_int_combo_box_new (config, "preset",
GIMP_INT_STORE (store));
g_object_unref (store);
label = gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
_("Source _type:"), 0.0, 0.5,
combo, 2);
@ -195,19 +164,12 @@ save_dialog (WebPSaveParams *params,
_("WebP encoder \"preset\""),
NULL);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
params->preset,
G_CALLBACK (gimp_int_combo_box_get_active),
&params->preset, NULL);
if (animation_supported)
{
GtkWidget *animation_box;
GtkAdjustment *adj;
GtkWidget *delay;
GtkWidget *hbox;
GtkWidget *label_kf;
GtkAdjustment *adj_kf;
GtkWidget *kf_distance;
GtkWidget *hbox_kf;
PangoAttrList *attrs;
@ -225,19 +187,13 @@ save_dialog (WebPSaveParams *params,
/* Create the top-level animation checkbox expander */
text = g_strdup_printf ("<b>%s</b>", _("As A_nimation"));
toggle = gtk_check_button_new_with_mnemonic (text);
toggle = gimp_prop_check_button_new (config, "animation",
text);
g_free (text);
gtk_label_set_use_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (toggle))),
TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
params->animation);
gtk_box_pack_start (GTK_BOX (vbox2), toggle, TRUE, TRUE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->animation);
frame = gimp_frame_new ("<expander>");
gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0);
@ -253,15 +209,10 @@ save_dialog (WebPSaveParams *params,
gtk_widget_show (animation_box);
/* loop animation checkbox */
toggle = gtk_check_button_new_with_mnemonic (_("Loop _forever"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->loop);
toggle = gimp_prop_check_button_new (config, "animation-loop",
_("Loop _forever"));
gtk_box_pack_start (GTK_BOX (animation_box), toggle,
FALSE, FALSE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->loop);
/* create a hbox for 'max key-frame distance */
hbox_kf = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
@ -276,17 +227,9 @@ save_dialog (WebPSaveParams *params,
gtk_widget_show (label_kf);
/* key-frame distance entry */
adj_kf = gtk_adjustment_new (params->kf_distance,
0.0, 10000.0,
1.0, 10.0, 0.0);
kf_distance = gimp_spin_button_new (adj_kf, 1, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (kf_distance), TRUE);
kf_distance = gimp_prop_spin_button_new (config, "keyframe-distance",
1.0, 1.0, 0);
gtk_box_pack_start (GTK_BOX (hbox_kf), kf_distance, FALSE, FALSE, 0);
gtk_widget_show (kf_distance);
g_signal_connect (adj_kf, "value-changed",
G_CALLBACK (gimp_int_adjustment_update),
&params->kf_distance);
/* Add some hinting text for special values of key-frame distance. */
label_kf = gtk_label_new (NULL);
@ -299,28 +242,25 @@ save_dialog (WebPSaveParams *params,
gtk_label_set_attributes (GTK_LABEL (label_kf), attrs);
pango_attr_list_unref (attrs);
g_signal_connect (adj_kf, "value-changed",
g_signal_connect (config, "notify::keyframe-distance",
G_CALLBACK (show_maxkeyframe_hints),
label_kf);
show_maxkeyframe_hints (adj_kf, GTK_LABEL (label_kf));
show_maxkeyframe_hints (config, NULL, GTK_LABEL (label_kf));
/* minimize-size checkbox */
toggle_minsize = gtk_check_button_new_with_mnemonic (_("_Minimize output size (slower)"));
gtk_box_pack_start (GTK_BOX (animation_box), toggle_minsize,
toggle = gimp_prop_check_button_new (config, "minimize-size",
_("_Minimize output size "
"(slower)"));
gtk_box_pack_start (GTK_BOX (animation_box), toggle,
FALSE, FALSE, 0);
gtk_widget_show (toggle_minsize);
g_signal_connect (toggle_minsize, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->minimize_size);
/* Enable and disable the kf-distance box when the 'minimize size' option is selected */
g_signal_connect (toggle_minsize, "toggled",
G_CALLBACK (save_dialog_toggle_minsize),
hbox_kf);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_minsize), params->minimize_size);
/* Enable and disable the kf-distance box when the 'minimize size'
* option is selected
*/
g_object_bind_property (config, "minimize-size",
hbox_kf, "sensitive",
G_BINDING_SYNC_CREATE |
G_BINDING_INVERT_BOOLEAN);
/* create a hbox for delay */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
@ -334,15 +274,9 @@ save_dialog (WebPSaveParams *params,
gtk_widget_show (label);
/* default delay */
adj = gtk_adjustment_new (params->delay, 1, 10000, 1, 10, 0);
delay = gimp_spin_button_new (adj, 1, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (delay), TRUE);
delay = gimp_prop_spin_button_new (config, "default-delay",
1, 10, 0);
gtk_box_pack_start (GTK_BOX (hbox), delay, FALSE, FALSE, 0);
gtk_widget_show (delay);
g_signal_connect (adj, "value-changed",
G_CALLBACK (gimp_int_adjustment_update),
&params->delay);
/* label for 'ms' adjustment */
label = gtk_label_new (_("milliseconds"));
@ -350,50 +284,30 @@ save_dialog (WebPSaveParams *params,
gtk_widget_show (label);
/* Create the force-delay checkbox */
toggle = gtk_check_button_new_with_mnemonic (_("Use _delay entered above for all frames"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
params->force_delay);
toggle = gimp_prop_check_button_new (config, "force-delay",
_("Use _delay entered above for "
"all frames"));
gtk_box_pack_start (GTK_BOX (animation_box), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->force_delay);
}
/* Save EXIF data */
toggle = gtk_check_button_new_with_mnemonic (_("_Save Exif data"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->save_exif);
toggle = gimp_prop_check_button_new (config, "save-exif",
_("_Save Exif data"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->save_exif);
/* XMP metadata */
toggle = gtk_check_button_new_with_mnemonic (_("Save _XMP data"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->save_xmp);
toggle = gimp_prop_check_button_new (config, "save-xmp",
_("Save _XMP data"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->save_xmp);
/* Color profile */
toggle = gtk_check_button_new_with_mnemonic (_("Save color _profile"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), params->save_profile);
toggle = gimp_prop_check_button_new (config, "save-color-profile",
_("Save color _profile"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->save_profile);
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
gtk_widget_destroy (dialog);

View file

@ -23,11 +23,9 @@
#define __WEBP_DIALOG_H__
#include "file-webp-save.h"
gboolean save_dialog (WebPSaveParams *params,
GimpImage *image);
gboolean save_dialog (GimpImage *image,
GimpProcedure *procedure,
GObject *config);
#endif /* __WEBP_DIALOG_H__ */

View file

@ -53,7 +53,7 @@ int webp_file_progress (int percent,
const gchar * webp_error_string (WebPEncodingError error_code);
static void webp_decide_output (GimpImage *image,
WebPSaveParams *params,
GObject *config,
GimpColorProfile **profile,
gboolean *out_linear);
@ -125,11 +125,11 @@ webp_error_string (WebPEncodingError error_code)
}
gboolean
save_layer (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error)
save_layer (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GObject *config,
GError **error)
{
gboolean status = FALSE;
FILE *outfile = NULL;
@ -152,8 +152,19 @@ save_layer (GFile *file,
WebPData chunk;
gboolean out_linear = FALSE;
int res;
WebPPreset preset;
gboolean lossless;
gdouble quality;
gdouble alpha_quality;
webp_decide_output (image, params, &profile, &out_linear);
g_object_get (config,
"preset", &preset,
"lossless", &lossless,
"quality", &quality,
"alpha-quality", &alpha_quality,
NULL);
webp_decide_output (image, config, &profile, &out_linear);
if (profile)
{
space = gimp_color_profile_get_space (profile,
@ -229,11 +240,11 @@ save_layer (GFile *file,
/* Initialize the WebP configuration with a preset and fill in the
* remaining values */
WebPConfigPreset (&webp_config, params->preset, params->quality);
WebPConfigPreset (&webp_config, preset, quality);
webp_config.lossless = params->lossless;
webp_config.lossless = lossless;
webp_config.method = 6; /* better quality */
webp_config.alpha_quality = params->alpha_quality;
webp_config.alpha_quality = alpha_quality;
/* Prepare the WebP structure */
WebPPictureInit (&picture);
@ -489,17 +500,17 @@ combine_buffers (GeglBuffer *layer_buffer,
}
gboolean
save_animation (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error)
save_animation (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GObject *config,
GError **error)
{
GList *layers;
gint32 n_layers;
gboolean status = TRUE;
FILE *outfile = NULL;
guchar *buffer = NULL;
gboolean status = TRUE;
FILE *outfile = NULL;
guchar *buffer = NULL;
gint buffer_size = 0;
gint w, h;
gint bpp;
@ -514,6 +525,29 @@ save_animation (GFile *file,
WebPAnimEncoder *enc = NULL;
GeglBuffer *prev_frame = NULL;
gboolean out_linear = FALSE;
WebPPreset preset;
gboolean lossless;
gboolean animation;
gboolean loop;
gboolean minimize_size;
gint keyframe_distance;
gdouble quality;
gdouble alpha_quality;
gint default_delay;
gboolean force_delay;
g_object_get (config,
"preset", &preset,
"lossless", &lossless,
"animation", &animation,
"animation-loop", &loop,
"minimize-size", &minimize_size,
"keyframe-distance", &keyframe_distance,
"quality", &quality,
"alpha-quality", &alpha_quality,
"default-delay", &default_delay,
"force-delay", &force_delay,
NULL);
layers = gimp_image_list_layers (image);
@ -523,7 +557,7 @@ save_animation (GFile *file,
layers = g_list_reverse (layers);
n_layers = g_list_length (layers);
webp_decide_output (image, params, &profile, &out_linear);
webp_decide_output (image, config, &profile, &out_linear);
if (profile)
{
space = gimp_color_profile_get_space (profile,
@ -549,11 +583,9 @@ save_animation (GFile *file,
do
{
gchar *filename;
GList *list;
gint loop;
gint default_delay = params->delay;
gboolean force_delay = params->force_delay;
gchar *filename;
GList *list;
gint i;
/* Begin displaying export progress */
gimp_progress_init_printf (_("Saving '%s'"),
@ -562,7 +594,7 @@ save_animation (GFile *file,
/* Attempt to open the output file */
filename = g_file_get_path (file);
outfile = g_fopen (filename, "wb");
g_free (file);
g_free (filename);
if (! outfile)
{
@ -583,21 +615,21 @@ save_animation (GFile *file,
}
enc_options.anim_params.loop_count = 0;
if (! params->loop)
if (! loop)
enc_options.anim_params.loop_count = 1;
enc_options.allow_mixed = params->lossless ? 0 : 1;
enc_options.minimize_size = params->minimize_size ? 1 : 0;
if (! params->minimize_size)
enc_options.allow_mixed = lossless ? 0 : 1;
enc_options.minimize_size = minimize_size ? 1 : 0;
if (! minimize_size)
{
enc_options.kmax = params->kf_distance;
enc_options.kmax = keyframe_distance;
/* explicitly force minimum key-frame distance too, for good measure */
enc_options.kmin = params->kf_distance - 1;
enc_options.kmin = keyframe_distance - 1;
}
for (list = layers, loop = 0;
for (list = layers, i = 0;
list;
list = g_list_next (list), loop++)
list = g_list_next (list), i++)
{
GeglBuffer *geglbuffer;
GeglBuffer *current_frame;
@ -642,7 +674,7 @@ save_animation (GFile *file,
w = extent.width;
h = extent.height;
if (loop == 0)
if (i == 0)
{
enc = WebPAnimEncoderNew (w, h, &enc_options);
if (! enc)
@ -670,11 +702,11 @@ save_animation (GFile *file,
}
}
WebPConfigPreset (&webp_config, params->preset, params->quality);
WebPConfigPreset (&webp_config, preset, quality);
webp_config.lossless = params->lossless;
webp_config.lossless = lossless;
webp_config.method = 6; /* better quality */
webp_config.alpha_quality = params->alpha_quality;
webp_config.alpha_quality = alpha_quality;
webp_config.exact = 1;
WebPMemoryWriterInit (&mw);
@ -688,7 +720,7 @@ save_animation (GFile *file,
picture.custom_ptr = &mw;
picture.writer = WebPMemoryWrite;
if (loop == 0 || ! needs_combine)
if (i == 0 || ! needs_combine)
{
g_clear_object (&prev_frame);
current_frame = geglbuffer;
@ -726,8 +758,8 @@ save_animation (GFile *file,
else if (! WebPAnimEncoderAdd (enc, &picture, frame_timestamp,
&webp_config))
{
g_printerr ("ERROR[%d]: %s\n",
picture.error_code,
g_printerr ("ERROR[%d]: line %d: %s\n",
picture.error_code, __LINE__,
webp_error_string (picture.error_code));
status = FALSE;
}
@ -738,9 +770,10 @@ save_animation (GFile *file,
if (status == FALSE)
break;
gimp_progress_update ((loop + 1.0) / n_layers);
gimp_progress_update ((i + 1.0) / n_layers);
frame_timestamp += (delay <= 0 || force_delay) ? default_delay : delay;
}
g_free (buffer);
if (status == FALSE)
@ -811,15 +844,21 @@ save_animation (GFile *file,
static void
webp_decide_output (GimpImage *image,
WebPSaveParams *params,
GObject *config,
GimpColorProfile **profile,
gboolean *out_linear)
{
gboolean save_profile;
g_return_if_fail (profile && *profile == NULL);
g_object_get (config,
"save-color-profile", &save_profile,
NULL);
*out_linear = FALSE;
if (params->save_profile)
if (save_profile)
{
*profile = gimp_image_get_color_profile (image);

View file

@ -23,36 +23,17 @@
#define __WEBP_SAVE_H__
typedef struct
{
WebPPreset preset;
gboolean lossless;
gboolean animation;
gboolean loop;
gboolean minimize_size;
gint kf_distance;
gfloat quality;
gfloat alpha_quality;
gboolean save_exif;
gboolean save_iptc;
gboolean save_xmp;
gboolean save_profile;
gint delay;
gboolean force_delay;
} WebPSaveParams;
gboolean save_layer (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GObject *config,
GError **error);
gboolean save_layer (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error);
gboolean save_animation (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error);
gboolean save_animation (GFile *file,
GimpImage *image,
GimpDrawable *drawable,
GObject *config,
GError **error);
#endif /* __WEBP_SAVE_H__ */

View file

@ -202,9 +202,9 @@ webp_create_procedure (GimpPlugIn *plug_in,
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "kf-distance",
"KF distance",
"Maximum distance between key-frames",
GIMP_PROC_ARG_INT (procedure, "keyframe-distance",
"Keyframe distance",
"Maximum distance between keyframes",
0, G_MAXINT, 50,
G_PARAM_READWRITE);
@ -226,8 +226,14 @@ webp_create_procedure (GimpPlugIn *plug_in,
gimp_export_xmp (),
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "delay",
"Delay",
GIMP_PROC_ARG_BOOLEAN (procedure, "save-color-profile",
"Save color profle",
"Toggle saving the color profile",
gimp_export_color_profile (),
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "default-delay",
"Default delay",
"Delay to use when timestamps are not available "
"or forced",
0, G_MAXINT, 200,
@ -245,15 +251,14 @@ webp_create_procedure (GimpPlugIn *plug_in,
static GimpValueArray *
webp_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
{
GimpValueArray *return_vals;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpImage *image;
GError *error = NULL;
GimpValueArray *return_vals;
GimpImage *image;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
@ -261,7 +266,9 @@ webp_load (GimpProcedure *procedure,
image = load_image (file, FALSE, &error);
if (! image)
return gimp_procedure_new_return_values (procedure, status, error);
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
error);
return_vals = gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
@ -281,81 +288,47 @@ webp_save (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer run_data)
{
GimpProcedureConfig *config;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GimpMetadata *metadata = NULL;
GimpMetadataSaveFlags metadata_flags;
WebPSaveParams params;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
gboolean animation;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
config = gimp_procedure_create_config (procedure);
gimp_procedure_config_begin_run (config, image, run_mode, args);
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
gimp_ui_init (PLUG_IN_BINARY);
/* Default settings */
params.preset = WEBP_PRESET_DEFAULT;
params.lossless = FALSE;
params.animation = FALSE;
params.loop = TRUE;
params.minimize_size = TRUE;
params.kf_distance = 50;
params.quality = 90.0f;
params.alpha_quality = 100.0f;
params.save_exif = FALSE;
params.save_iptc = FALSE;
params.save_xmp = FALSE;
params.delay = 200;
params.force_delay = FALSE;
/* Override the defaults with preferences. */
metadata = gimp_image_metadata_save_prepare (image,
"image/webp",
&metadata_flags);
#if 0
params.save_exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
params.save_xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
params.save_iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
params.save_profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
#endif
switch (run_mode)
if (run_mode == GIMP_RUN_INTERACTIVE)
{
case GIMP_RUN_WITH_LAST_VALS:
/* Possibly override with session data */
gimp_get_data (SAVE_PROC, &params);
break;
case GIMP_RUN_INTERACTIVE:
/* Possibly override with session data */
gimp_get_data (SAVE_PROC, &params);
if (! save_dialog (&params, image))
if (! save_dialog (image, procedure, G_OBJECT (config)))
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
break;
case GIMP_RUN_NONINTERACTIVE:
params.preset = GIMP_VALUES_GET_INT (args, 0);
params.lossless = GIMP_VALUES_GET_BOOLEAN (args, 1);
params.quality = GIMP_VALUES_GET_DOUBLE (args, 2);
params.alpha_quality = GIMP_VALUES_GET_DOUBLE (args, 3);
params.animation = GIMP_VALUES_GET_BOOLEAN (args, 4);
params.loop = GIMP_VALUES_GET_BOOLEAN (args, 5);
params.minimize_size = GIMP_VALUES_GET_BOOLEAN (args, 6);
params.kf_distance = GIMP_VALUES_GET_INT (args, 7);
params.save_exif = GIMP_VALUES_GET_BOOLEAN (args, 8);
params.save_iptc = GIMP_VALUES_GET_BOOLEAN (args, 9);
params.save_xmp = GIMP_VALUES_GET_BOOLEAN (args, 10);
params.delay = GIMP_VALUES_GET_INT (args, 11);
params.force_delay = GIMP_VALUES_GET_BOOLEAN (args, 12);
break;
default:
break;
}
g_object_get (config,
"animation", &animation,
NULL);
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
{
@ -364,7 +337,7 @@ webp_save (GimpProcedure *procedure,
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
if (params.animation)
if (animation)
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION;
export = gimp_export_image (&image, &drawable, "WebP",
@ -376,9 +349,9 @@ webp_save (GimpProcedure *procedure,
NULL);
}
if (params.animation)
if (animation)
{
if (! save_animation (file, image, drawable, &params,
if (! save_animation (file, image, drawable, G_OBJECT (config),
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
@ -386,7 +359,7 @@ webp_save (GimpProcedure *procedure,
}
else
{
if (! save_layer (file, image, drawable, &params,
if (! save_layer (file, image, drawable, G_OBJECT (config),
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
@ -395,27 +368,39 @@ webp_save (GimpProcedure *procedure,
if (status == GIMP_PDB_SUCCESS && metadata)
{
gboolean save_exif;
gboolean save_xmp;
gboolean save_iptc;
gboolean save_profile;
g_object_get (config,
"save-exif", &save_exif,
"save-xmp", &save_xmp,
"save-iptc", &save_iptc,
"save-profile", &save_profile,
NULL);
/* WebP doesn't support iptc natively and sets it via xmp */
save_iptc = save_xmp;
gimp_metadata_set_bits_per_sample (metadata, 8);
if (params.save_exif)
if (save_exif)
metadata_flags |= GIMP_METADATA_SAVE_EXIF;
else
metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
/* WebP doesn't support iptc natively and sets it via xmp
*/
if (params.save_xmp)
{
metadata_flags |= GIMP_METADATA_SAVE_XMP;
metadata_flags |= GIMP_METADATA_SAVE_IPTC;
}
if (save_xmp)
metadata_flags |= GIMP_METADATA_SAVE_XMP;
else
{
metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
}
metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
if (params.save_profile)
if (save_iptc)
metadata_flags |= GIMP_METADATA_SAVE_IPTC;
else
metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
if (save_profile)
metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE;
else
metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
@ -426,17 +411,14 @@ webp_save (GimpProcedure *procedure,
file, NULL);
}
gimp_procedure_config_end_run (config, status);
g_object_unref (config);
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image);
if (metadata)
g_object_unref (metadata);
if (status == GIMP_PDB_SUCCESS)
{
/* save parameters for later */
gimp_set_data (SAVE_PROC, &params, sizeof (params));
}
return gimp_procedure_new_return_values (procedure, status, error);
}