plug-ins: port file-webp to GimpProcedureConfig
This commit is contained in:
parent
04280690b2
commit
1b48c687ca
5 changed files with 247 additions and 333 deletions
|
|
@ -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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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),
|
||||
¶ms->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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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, ¶ms);
|
||||
break;
|
||||
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
/* Possibly override with session data */
|
||||
gimp_get_data (SAVE_PROC, ¶ms);
|
||||
|
||||
if (! save_dialog (¶ms, 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, ¶ms,
|
||||
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, ¶ms,
|
||||
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, ¶ms, sizeof (params));
|
||||
}
|
||||
|
||||
return gimp_procedure_new_return_values (procedure, status, error);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue