diff options
Diffstat (limited to 'plug-ins/file-webp/file-webp.c')
-rw-r--r-- | plug-ins/file-webp/file-webp.c | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/plug-ins/file-webp/file-webp.c b/plug-ins/file-webp/file-webp.c new file mode 100644 index 0000000..219e6a6 --- /dev/null +++ b/plug-ins/file-webp/file-webp.c @@ -0,0 +1,384 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * file-webp - WebP file format plug-in for the GIMP + * Copyright (C) 2015 Nathan Osman + * Copyright (C) 2016 Ben Touchette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include <webp/encode.h> + +#include "file-webp-dialog.h" +#include "file-webp-load.h" +#include "file-webp-save.h" +#include "file-webp.h" + +#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); + + +const GimpPlugInInfo PLUG_IN_INFO = +{ + NULL, + NULL, + query, + run +}; + + +MAIN() + +static void +query (void) +{ + 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" } + }; + + 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" } + }; + + static const GimpParamDef save_arguments2[] = + { + { 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, "thumbnail", "Toggle saving thumbnail (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", ""); + + gimp_install_procedure (SAVE_PROC2, + "Saves files in the WebP image format", + "Saves files in the WebP image format " + "with additional metadata control", + "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_arguments2), + 0, + save_arguments2, + NULL); + + gimp_register_file_handler_mime (SAVE_PROC2, "image/webp"); + gimp_register_save_handler (SAVE_PROC2, "webp", ""); +} + +static void +run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[2]; + GimpRunMode run_mode; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + gint32 image_ID; + gint32 drawable_ID; + GError *error = NULL; + + INIT_I18N (); + gegl_init (NULL, NULL); + + run_mode = param[0].data.d_int32; + + *nreturn_vals = 1; + *return_vals = values; + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; + + if (! strcmp (name, LOAD_PROC)) + { + image_ID = load_image (param[1].data.d_string, 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) || + ! strcmp (name, SAVE_PROC2)) + { + 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; + params.thumbnail = 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; + if (! strcmp (name, SAVE_PROC2)) + params.thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0; + + switch (run_mode) + { + case GIMP_RUN_WITH_LAST_VALS: + /* Possibly override with session data */ + if (! strcmp (name, SAVE_PROC)) + gimp_get_data (SAVE_PROC, ¶ms); + else if (! strcmp (name, SAVE_PROC2)) + gimp_get_data (SAVE_PROC2, ¶ms); + break; + + case GIMP_RUN_INTERACTIVE: + /* Possibly override with session data */ + if (! strcmp (name, SAVE_PROC)) + gimp_get_data (SAVE_PROC, ¶ms); + else if (! strcmp (name, SAVE_PROC2)) + gimp_get_data (SAVE_PROC2, ¶ms); + + if (! save_dialog (¶ms, image_ID)) + { + status = GIMP_PDB_CANCEL; + } + break; + + case GIMP_RUN_NONINTERACTIVE: + if ((! strcmp (name, SAVE_PROC) && nparams != 18) || + (! strcmp (name, SAVE_PROC2) && nparams != 19)) + { + 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; + if (! strcmp (name, SAVE_PROC)) + { + params.delay = param[16].data.d_int32; + params.force_delay = param[17].data.d_int32; + } + else + { + params.thumbnail = param[16].data.d_int32; + params.delay = param[17].data.d_int32; + params.force_delay = param[18].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 (param[3].data.d_string, + image_ID, + drawable_ID, + metadata, metadata_flags, + ¶ms, + &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 */ + if (! strcmp (name, SAVE_PROC)) + gimp_set_data (SAVE_PROC, ¶ms, sizeof (params)); + else if (! strcmp (name, SAVE_PROC2)) + gimp_set_data (SAVE_PROC2, ¶ms, 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; +} |