plug-ins: port file-webp to GimpPlugIn and libgimp objects

This commit is contained in:
Michael Natterer 2019-08-24 11:45:01 +02:00
parent 9f3bc2bd7a
commit 3636541b42
8 changed files with 430 additions and 346 deletions

View File

@ -22,7 +22,6 @@ AM_LDFLAGS = $(mwindows)
libexecdir = $(gimpplugindir)/plug-ins/file-webp
AM_CPPFLAGS = \
-DGIMP_DEPRECATED_REPLACE_NEW_API \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(EXIF_CFLAGS) \

View File

@ -81,7 +81,7 @@ show_maxkeyframe_hints (GtkAdjustment *adj,
gboolean
save_dialog (WebPSaveParams *params,
gint32 image_ID)
GimpImage *image)
{
GtkWidget *dialog;
GtkWidget *vbox;
@ -95,13 +95,17 @@ save_dialog (WebPSaveParams *params,
GtkWidget *combo;
GtkAdjustment *quality_scale;
GtkAdjustment *alpha_quality_scale;
GList *list;
gint32 nlayers;
gboolean animation_supported = FALSE;
gboolean run;
gchar *text;
gint row = 0;
g_free (gimp_image_get_layers (image_ID, &nlayers));
list = gimp_image_get_layers (image);
nlayers = g_list_length (list);
g_list_free (list);
animation_supported = nlayers > 1;
/* Create the dialog */

View File

@ -27,7 +27,7 @@
gboolean save_dialog (WebPSaveParams *params,
gint32 image_ID);
GimpImage *image);
#endif /* __WEBP_DIALOG_H__ */

View File

@ -40,27 +40,27 @@
static void
create_layer (gint32 image_ID,
uint8_t *layer_data,
gint32 position,
gchar *name,
gint width,
gint height)
create_layer (GimpImage *image,
uint8_t *layer_data,
gint32 position,
gchar *name,
gint width,
gint height)
{
gint32 layer_ID;
GimpLayer *layer;
GeglBuffer *buffer;
GeglRectangle extent;
layer_ID = gimp_layer_new (image_ID, name,
width, height,
GIMP_RGBA_IMAGE,
100,
gimp_image_get_default_new_layer_mode (image_ID));
layer = gimp_layer_new (image, name,
width, height,
GIMP_RGBA_IMAGE,
100,
gimp_image_get_default_new_layer_mode (image));
gimp_image_insert_layer (image_ID, layer_ID, -1, position);
gimp_image_insert_layer (image, layer, NULL, position);
/* Retrieve the buffer for the layer */
buffer = gimp_drawable_get_buffer (layer_ID);
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
/* Copy the image data to the region */
gegl_rectangle_set (&extent, 0, 0, width, height);
@ -72,7 +72,7 @@ create_layer (gint32 image_ID,
g_object_unref (buffer);
}
gint32
GimpImage *
load_image (const gchar *filename,
gboolean interactive,
GError **error)
@ -81,7 +81,7 @@ load_image (const gchar *filename,
gsize indatalen;
gint width;
gint height;
gint32 image_ID;
GimpImage *image;
WebPMux *mux;
WebPData wp_data;
GimpColorProfile *profile = NULL;
@ -97,7 +97,7 @@ load_image (const gchar *filename,
&indatalen,
error))
{
return -1;
return NULL;
}
/* Validate WebP data */
@ -106,7 +106,7 @@ load_image (const gchar *filename,
g_set_error (error, G_FILE_ERROR, 0,
_("Invalid WebP file '%s'"),
gimp_filename_to_utf8 (filename));
return -1;
return NULL;
}
wp_data.bytes = indata;
@ -114,7 +114,7 @@ load_image (const gchar *filename,
mux = WebPMuxCreate (&wp_data, 1);
if (! mux)
return -1;
return NULL;
WebPMuxGetFeatures (mux, &flags);
@ -134,7 +134,7 @@ load_image (const gchar *filename,
/* TODO: check if an alpha channel is present */
/* Create the new image and associated layer */
image_ID = gimp_image_new (width, height, GIMP_RGB);
image = gimp_image_new (width, height, GIMP_RGB);
if (icc)
{
@ -144,7 +144,7 @@ load_image (const gchar *filename,
profile = gimp_color_profile_new_from_icc_profile (icc_profile.bytes,
icc_profile.size, NULL);
if (profile)
gimp_image_set_color_profile (image_ID, profile);
gimp_image_set_color_profile (image, profile);
}
if (! animation)
@ -158,10 +158,10 @@ load_image (const gchar *filename,
if (! outdata)
{
WebPMuxDelete (mux);
return -1;
return NULL;
}
create_layer (image_ID, outdata, 0, _("Background"),
create_layer (image, outdata, 0, _("Background"),
width, height);
/* Free the image data */
@ -189,7 +189,7 @@ load_image (const gchar *filename,
}
WebPMuxDelete (mux);
return -1;
return NULL;
}
/* dec_options.color_mode is MODE_RGBA by default here */
@ -230,7 +230,7 @@ load_image (const gchar *filename,
}
name = g_strdup_printf (_("Frame %d (%dms)"), frame_num, iter.duration);
create_layer (image_ID, outdata, 0, name, width, height);
create_layer (image, outdata, 0, name, width, height);
g_free (name);
frame_num++;
@ -265,7 +265,7 @@ load_image (const gchar *filename,
}
file = g_file_new_for_path (filename);
metadata = gimp_image_metadata_load_prepare (image_ID, "image/webp",
metadata = gimp_image_metadata_load_prepare (image, "image/webp",
file, NULL);
if (metadata)
{
@ -274,7 +274,7 @@ load_image (const gchar *filename,
if (profile)
flags &= ~GIMP_METADATA_LOAD_COLORSPACE;
gimp_image_metadata_load_finish (image_ID, "image/webp",
gimp_image_metadata_load_finish (image, "image/webp",
metadata, flags,
interactive);
g_object_unref (metadata);
@ -285,10 +285,10 @@ load_image (const gchar *filename,
WebPMuxDelete (mux);
gimp_image_set_filename (image_ID, filename);
gimp_image_set_filename (image, filename);
if (profile)
g_object_unref (profile);
return image_ID;
return image;
}

View File

@ -23,9 +23,9 @@
#define __WEBP_LOAD_H__
gint32 load_image (const gchar *filename,
gboolean interactive,
GError **error);
GimpImage * load_image (const gchar *filename,
gboolean interactive,
GError **error);
#endif /* __WEBP_LOAD_H__ */

View File

@ -54,20 +54,20 @@ const gchar * webp_error_string (WebPEncodingError error_code);
gboolean save_layer (const gchar *filename,
gint32 nLayers,
gint32 image_ID,
gint32 drawable_ID,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error);
gboolean save_animation (const gchar *filename,
gint32 nLayers,
gint32 *allLayers,
gint32 image_ID,
gint32 drawable_ID,
GList *layers,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error);
static void webp_decide_output (gint32 image_ID,
static void webp_decide_output (GimpImage *image,
WebPSaveParams *params,
GimpColorProfile **profile,
gboolean *out_linear);
@ -142,8 +142,8 @@ webp_error_string (WebPEncodingError error_code)
gboolean
save_layer (const gchar *filename,
gint32 nLayers,
gint32 image_ID,
gint32 drawable_ID,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error)
{
@ -169,7 +169,7 @@ save_layer (const gchar *filename,
gboolean out_linear = FALSE;
int res;
webp_decide_output (image_ID, params, &profile, &out_linear);
webp_decide_output (image, params, &profile, &out_linear);
if (profile)
{
space = gimp_color_profile_get_space (profile,
@ -186,7 +186,7 @@ save_layer (const gchar *filename,
}
if (! space)
space = gimp_drawable_get_format (drawable_ID);
space = gimp_drawable_get_format (drawable);
/* The do...while() loop is a neat little trick that makes it easier
* to jump to error handling code while still ensuring proper
@ -211,7 +211,7 @@ save_layer (const gchar *filename,
}
/* Obtain the drawable type */
has_alpha = gimp_drawable_has_alpha (drawable_ID);
has_alpha = gimp_drawable_has_alpha (drawable);
if (has_alpha)
{
@ -232,7 +232,7 @@ save_layer (const gchar *filename,
bpp = babl_format_get_bytes_per_pixel (format);
/* Retrieve the buffer for the layer */
geglbuffer = gimp_drawable_get_buffer (drawable_ID);
geglbuffer = gimp_drawable_get_buffer (drawable);
extent = *gegl_buffer_get_extent (geglbuffer);
w = extent.width;
h = extent.height;
@ -413,12 +413,12 @@ parse_ms_tag (const gchar *str)
}
static gint
get_layer_delay (gint32 layer)
get_layer_delay (GimpLayer *layer)
{
gchar *layer_name;
gint delay_ms;
layer_name = gimp_item_get_name (layer);
layer_name = gimp_item_get_name (GIMP_ITEM (layer));
delay_ms = parse_ms_tag (layer_name);
g_free (layer_name);
@ -446,12 +446,12 @@ parse_combine (const char* str)
}
static gint
get_layer_needs_combine (gint32 layer)
get_layer_needs_combine (GimpLayer *layer)
{
gchar *layer_name;
gboolean needs_combine;
layer_name = gimp_item_get_name (layer);
layer_name = gimp_item_get_name (GIMP_ITEM (layer));
needs_combine = parse_combine (layer_name);
g_free (layer_name);
@ -501,9 +501,9 @@ combine_buffers (GeglBuffer *layer_buffer,
gboolean
save_animation (const gchar *filename,
gint32 nLayers,
gint32 *allLayers,
gint32 image_ID,
gint32 drawable_ID,
GList *layers,
GimpImage *image,
GimpDrawable *drawable,
WebPSaveParams *params,
GError **error)
{
@ -528,7 +528,7 @@ save_animation (const gchar *filename,
if (nLayers < 1)
return FALSE;
webp_decide_output (image_ID, params, &profile, &out_linear);
webp_decide_output (image, params, &profile, &out_linear);
if (profile)
{
space = gimp_color_profile_get_space (profile,
@ -545,14 +545,15 @@ save_animation (const gchar *filename,
}
if (! space)
space = gimp_drawable_get_format (drawable_ID);
space = gimp_drawable_get_format (drawable);
gimp_image_undo_freeze (image_ID);
gimp_image_undo_freeze (image);
WebPDataInit (&webp_data);
do
{
GList *list;
gint loop;
gint default_delay = params->delay;
gboolean force_delay = params->force_delay;
@ -593,17 +594,22 @@ save_animation (const gchar *filename,
enc_options.kmin = params->kf_distance - 1;
}
for (loop = 0; loop < nLayers; loop++)
for (list = g_list_last (layers), loop = 0;
list && loop < nLayers;
list = g_list_previous (list), loop++)
{
GeglBuffer *geglbuffer;
GeglBuffer *current_frame;
GeglRectangle extent;
WebPConfig config;
WebPPicture picture;
WebPMemoryWriter mw = { 0 };
gint32 drawable = allLayers[nLayers - 1 - loop];
gint delay = get_layer_delay (drawable);
gboolean needs_combine = get_layer_needs_combine (drawable);
WebPMemoryWriter mw = { 0 };
GimpDrawable *drawable = list->data;
gint delay;
gboolean needs_combine;
delay = get_layer_delay (GIMP_LAYER (drawable));
needs_combine = get_layer_needs_combine (GIMP_LAYER (drawable));
/* Obtain the drawable type */
has_alpha = gimp_drawable_has_alpha (drawable);
@ -627,7 +633,7 @@ save_animation (const gchar *filename,
bpp = babl_format_get_bytes_per_pixel (format);
/* fix layers to avoid offset errors */
gimp_layer_resize_to_image_size (drawable);
gimp_layer_resize_to_image_size (GIMP_LAYER (drawable));
/* Retrieve the buffer for the layer */
geglbuffer = gimp_drawable_get_buffer (drawable);
@ -802,8 +808,8 @@ save_animation (const gchar *filename,
gboolean
save_image (const gchar *filename,
gint32 image_ID,
gint32 drawable_ID,
GimpImage *image,
GimpDrawable *drawable,
GimpMetadata *metadata,
GimpMetadataSaveFlags metadata_flags,
WebPSaveParams *params,
@ -811,29 +817,27 @@ save_image (const gchar *filename,
{
GFile *file;
gboolean status = FALSE;
gint32 *layers;
gint nlayers;
GList *layers;
layers = gimp_image_get_layers (image_ID, &nlayers);
layers = gimp_image_get_layers (image);
if (nlayers == 0)
{
g_free (layers);
return FALSE;
}
if (! layers)
return FALSE;
g_printerr ("Saving WebP file %s\n", filename);
if (params->animation)
{
status = save_animation (filename,
nlayers, layers, image_ID, drawable_ID, params,
g_list_length (layers), layers,
image, drawable, params,
error);
}
else
{
status = save_layer (filename,
nlayers, image_ID, drawable_ID, params, error);
g_list_length (layers),
image, drawable, params, error);
}
g_free (layers);
@ -866,7 +870,7 @@ save_image (const gchar *filename,
metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
file = g_file_new_for_path (filename);
gimp_image_metadata_save_finish (image_ID,
gimp_image_metadata_save_finish (image,
"image/webp",
metadata, metadata_flags,
file, NULL);
@ -878,7 +882,7 @@ save_image (const gchar *filename,
}
static void
webp_decide_output (gint32 image_ID,
webp_decide_output (GimpImage *image,
WebPSaveParams *params,
GimpColorProfile **profile,
gboolean *out_linear)
@ -888,7 +892,7 @@ webp_decide_output (gint32 image_ID,
*out_linear = FALSE;
if (params->profile)
{
*profile = gimp_image_get_color_profile (image_ID);
*profile = gimp_image_get_color_profile (image);
/* If a profile is explicitly set, follow its TRC, whatever the
* storage format.
@ -905,11 +909,11 @@ webp_decide_output (gint32 image_ID,
if (! *profile)
{
/* There is always an effective profile. */
*profile = gimp_image_get_effective_color_profile (image_ID);
*profile = gimp_image_get_effective_color_profile (image);
if (gimp_color_profile_is_linear (*profile))
{
if (gimp_image_get_precision (image_ID) != GIMP_PRECISION_U8_LINEAR)
if (gimp_image_get_precision (image) != GIMP_PRECISION_U8_LINEAR)
{
/* If stored data was linear, let's convert the profile. */
GimpColorProfile *saved_profile;

View File

@ -43,8 +43,8 @@ typedef struct
gboolean save_image (const gchar *filename,
gint32 image_ID,
gint32 drawable_ID,
GimpImage *image,
GimpDrawable *drawable,
GimpMetadata *metadata,
GimpMetadataSaveFlags metadata_flags,
WebPSaveParams *params,

View File

@ -36,288 +36,365 @@
#include "libgimp/stdplugins-intl.h"
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
typedef struct _Webp Webp;
typedef struct _WebpClass WebpClass;
const GimpPlugInInfo PLUG_IN_INFO =
struct _Webp
{
NULL,
NULL,
query,
run
GimpPlugIn parent_instance;
};
struct _WebpClass
{
GimpPlugInClass parent_class;
};
MAIN()
#define WEBP_TYPE (webp_get_type ())
#define WEBP (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBP_TYPE, Webp))
GType webp_get_type (void) G_GNUC_CONST;
static GList * webp_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * webp_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * webp_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data);
static GimpValueArray * webp_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
GFile *file,
const GimpValueArray *args,
gpointer run_data);
G_DEFINE_TYPE (Webp, webp, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (WEBP_TYPE)
static void
query (void)
webp_class_init (WebpClass *klass)
{
static const GimpParamDef load_arguments[] =
{
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
{ GIMP_PDB_STRING, "raw-filename", "The name entered" }
};
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
static const GimpParamDef load_return_values[] =
{
{ GIMP_PDB_IMAGE, "image", "Output image" }
};
static const GimpParamDef save_arguments[] =
{
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image" },
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
{ GIMP_PDB_STRING, "filename", "The name of the file to save the image to" },
{ GIMP_PDB_STRING, "raw-filename", "The name entered" },
{ GIMP_PDB_INT32, "preset", "preset (Default=0, Picture=1, Photo=2, Drawing=3, Icon=4, Text=5)" },
{ GIMP_PDB_INT32, "lossless", "Use lossless encoding (0/1)" },
{ GIMP_PDB_FLOAT, "quality", "Quality of the image (0 <= quality <= 100)" },
{ GIMP_PDB_FLOAT, "alpha-quality", "Quality of the image's alpha channel (0 <= alpha-quality <= 100)" },
{ GIMP_PDB_INT32, "animation", "Use layers for animation (0/1)" },
{ GIMP_PDB_INT32, "anim-loop", "Loop animation infinitely (0/1)" },
{ GIMP_PDB_INT32, "minimize-size", "Minimize animation size (0/1)" },
{ GIMP_PDB_INT32, "kf-distance", "Maximum distance between key-frames (>=0)" },
{ 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, "delay", "Delay to use when timestamps are not available or forced" },
{ GIMP_PDB_INT32, "force-delay", "Force delay on all frames" }
};
gimp_install_procedure (LOAD_PROC,
"Loads images in the WebP file format",
"Loads images in the WebP file format",
"Nathan Osman, Ben Touchette",
"(C) 2015-2016 Nathan Osman, (C) 2016 Ben Touchette",
"2015,2016",
N_("WebP image"),
NULL,
GIMP_PLUGIN,
G_N_ELEMENTS (load_arguments),
G_N_ELEMENTS (load_return_values),
load_arguments,
load_return_values);
gimp_register_file_handler_mime (LOAD_PROC, "image/webp");
gimp_register_load_handler (LOAD_PROC, "webp", "");
gimp_register_magic_load_handler (LOAD_PROC,
"webp",
"",
"8,string,WEBP");
gimp_install_procedure (SAVE_PROC,
"Saves files in the WebP image format",
"Saves files in the WebP image format",
"Nathan Osman, Ben Touchette",
"(C) 2015-2016 Nathan Osman, (C) 2016 Ben Touchette",
"2015,2016",
N_("WebP image"),
"RGB*, GRAY*, INDEXED*",
GIMP_PLUGIN,
G_N_ELEMENTS (save_arguments),
0,
save_arguments,
NULL);
gimp_register_file_handler_mime (SAVE_PROC, "image/webp");
gimp_register_save_handler (SAVE_PROC, "webp", "");
plug_in_class->query_procedures = webp_query_procedures;
plug_in_class->create_procedure = webp_create_procedure;
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
webp_init (Webp *webp)
{
static GimpParam values[2];
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 image_ID;
gint32 drawable_ID;
GError *error = NULL;
}
static GList *
webp_query_procedures (GimpPlugIn *plug_in)
{
GList *list = NULL;
list = g_list_append (list, g_strdup (LOAD_PROC));
list = g_list_append (list, g_strdup (SAVE_PROC));
return list;
}
static GimpProcedure *
webp_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
if (! strcmp (name, LOAD_PROC))
{
procedure = gimp_load_procedure_new (plug_in, name, GIMP_PLUGIN,
webp_load, NULL, NULL);
gimp_procedure_set_menu_label (procedure, N_("WebP image"));
gimp_procedure_set_documentation (procedure,
"Loads images in the WebP file format",
"Loads images in the WebP file format",
name);
gimp_procedure_set_attribution (procedure,
"Nathan Osman, Ben Touchette",
"(C) 2015-2016 Nathan Osman, "
"(C) 2016 Ben Touchette",
"2015,2016");
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/webp");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"webp");
gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
"8,string,WEBP");
}
else if (! strcmp (name, SAVE_PROC))
{
procedure = gimp_save_procedure_new (plug_in, name, GIMP_PLUGIN,
webp_save, NULL, NULL);
gimp_procedure_set_image_types (procedure, "*");
gimp_procedure_set_menu_label (procedure, N_("WebP image"));
gimp_procedure_set_documentation (procedure,
"Saves files in the WebP image format",
"Saves files in the WebP image format",
name);
gimp_procedure_set_attribution (procedure,
"Nathan Osman, Ben Touchette",
"(C) 2015-2016 Nathan Osman, "
"(C) 2016 Ben Touchette",
"2015,2016");
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/webp");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"webp");
GIMP_PROC_ARG_INT (procedure, "preset",
"Preset",
"Preset (Default=0, Picture=1, Photo=2, Drawing=3, "
"Icon=4, Text=5)",
0, 5, WEBP_PRESET_DEFAULT,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "lossless",
"Lossless",
"Use lossless encoding",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "quality",
"Quality",
"Quality of the image",
0, 100, 90,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "alpha-quality",
"Alpha quality",
"Quality of the image's alpha channel",
0, 100, 100,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "animation",
"Animation",
"Use layers for animation",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "animation-loop",
"Animation loop",
"Loop animation infinitely",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "minimize-size",
"Minimize size",
"Minimize animation size",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "kf-distance",
"KF distance",
"Maximum distance between key-frames",
0, G_MAXINT, 50,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "exif",
"EXIF",
"Toggle saving exif data",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "iptc",
"IPTC",
"Toggle saving iptc data",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "xmp",
"XMP",
"Toggle saving xmp data",
FALSE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "delay",
"Delay",
"Delay to use when timestamps are not available "
"or forced",
0, G_MAXINT, 200,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "force-delay",
"Force delay",
"Force delay on all frames",
FALSE,
G_PARAM_READWRITE);
}
return procedure;
}
static GimpValueArray *
webp_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
{
GimpValueArray *return_vals;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpImage *image;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
run_mode = param[0].data.d_int32;
image = load_image (g_file_get_path (file), FALSE, &error);
*nreturn_vals = 1;
*return_vals = values;
if (! image)
return gimp_procedure_new_return_values (procedure, status, error);
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
return_vals = gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
NULL);
if (! strcmp (name, LOAD_PROC))
{
GFile *file = g_file_new_for_uri (param[1].data.d_string);
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
image_ID = load_image (g_file_get_path (file), FALSE, &error);
if (image_ID != -1)
{
/* Return the new image that was loaded */
*nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE;
values[1].data.d_image = image_ID;
}
else
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
else if (! strcmp (name, SAVE_PROC))
{
GFile *file = g_file_new_for_uri (param[3].data.d_string);
GimpMetadata *metadata = NULL;
GimpMetadataSaveFlags metadata_flags;
WebPSaveParams params;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
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;
/* 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.exif = FALSE;
params.iptc = FALSE;
params.xmp = FALSE;
params.delay = 200;
params.force_delay = FALSE;
/* Override the defaults with preferences. */
metadata = gimp_image_metadata_save_prepare (image_ID,
"image/webp",
&metadata_flags);
params.exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
params.xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
params.iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
params.profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
switch (run_mode)
{
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_ID))
{
status = GIMP_PDB_CANCEL;
}
break;
case GIMP_RUN_NONINTERACTIVE:
if (nparams != 18)
{
status = GIMP_PDB_CALLING_ERROR;
}
else
{
if (param[5].data.d_int32 < WEBP_PRESET_DEFAULT ||
param[5].data.d_int32 > WEBP_PRESET_TEXT)
params.preset = WEBP_PRESET_DEFAULT;
else
params.preset = param[5].data.d_int32;
params.lossless = param[6].data.d_int32;
params.quality = param[7].data.d_float;
params.alpha_quality = param[8].data.d_float;
params.animation = param[9].data.d_int32;
params.loop = param[10].data.d_int32;
params.minimize_size = param[11].data.d_int32;
params.kf_distance = param[12].data.d_int32;
params.exif = param[13].data.d_int32;
params.iptc = param[14].data.d_int32;
params.xmp = param[15].data.d_int32;
params.delay = param[16].data.d_int32;
params.force_delay = param[17].data.d_int32;
}
break;
default:
break;
}
if (status == GIMP_PDB_SUCCESS && (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS))
{
GimpExportCapabilities capabilities =
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA;
if (params.animation)
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION;
export = gimp_export_image (&image_ID, &drawable_ID, "WebP",
capabilities);
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
status = GIMP_PDB_CANCEL;
}
}
if (status == GIMP_PDB_SUCCESS)
{
if (! save_image (g_file_get_path (file),
image_ID,
drawable_ID,
metadata, metadata_flags,
&params,
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image_ID);
if (metadata)
g_object_unref (metadata);
if (status == GIMP_PDB_SUCCESS)
{
/* save parameters for later */
gimp_set_data (SAVE_PROC, &params, sizeof (params));
}
}
/* If an error was supplied, include it in the return values */
if (status != GIMP_PDB_SUCCESS && error)
{
*nreturn_vals = 2;
values[1].type = GIMP_PDB_STRING;
values[1].data.d_string = error->message;
}
values[0].data.d_status = status;
return return_vals;
}
static GimpValueArray *
webp_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
{
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpMetadata *metadata = NULL;
GimpMetadataSaveFlags metadata_flags;
WebPSaveParams params;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
gimp_ui_init (PLUG_IN_BINARY, FALSE);
/* 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.exif = FALSE;
params.iptc = FALSE;
params.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);
params.exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
params.xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
params.iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
params.profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
switch (run_mode)
{
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))
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.exif = GIMP_VALUES_GET_BOOLEAN (args, 8);
params.iptc = GIMP_VALUES_GET_BOOLEAN (args, 9);
params.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;
}
if (run_mode == GIMP_RUN_INTERACTIVE ||
run_mode == GIMP_RUN_WITH_LAST_VALS)
{
GimpExportCapabilities capabilities = (GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
if (params.animation)
capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION;
export = gimp_export_image (&image, &drawable, "WebP",
capabilities);
if (export == GIMP_EXPORT_CANCEL)
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
}
if (! save_image (g_file_get_path (file),
image,
drawable,
metadata, metadata_flags,
&params,
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
}
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);
}