Commit e4ecba58 authored by Michael Natterer's avatar Michael Natterer 😴
Browse files

plug-ins: lots of cleanup and fixes in file-webp

- handle all sorts of image types, gegl_buffer_get() will convert to u8
- specify GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION
- modify the export duplicate, not the original image
- fix handling of the drawable type and only save "R'G'B'A u8"
  or "R'G'B' u8", fixes bug 770664.
- completely redo run(SAVE_PROC) to deal with export correctly
- turn global variables into the standard SAVE_PROC, PLUG_IN_BINARY etc
  defines
- simplify the save dialog
parent 3ab1389b
......@@ -98,7 +98,7 @@ save_dialog (WebPSaveParams *params,
GtkWidget *table;
GtkWidget *expander;
GtkWidget *frame;
GtkWidget *table2;
GtkWidget *vbox2;
GtkWidget *save_exif;
GtkWidget *save_xmp;
GtkWidget *preset_label;
......@@ -117,8 +117,7 @@ save_dialog (WebPSaveParams *params,
animation_supported = n_layers > 1;
/* Create the dialog */
dialog = gimp_export_dialog_new (_("WebP"),BINARY_NAME,
SAVE_PROCEDURE);
dialog = gimp_export_dialog_new (_("WebP"), PLUG_IN_BINARY, SAVE_PROC);
/* Create the vbox */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
......@@ -272,18 +271,14 @@ save_dialog (WebPSaveParams *params,
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
table2 = gtk_table_new (2, 1, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table2), 6);
gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
gtk_table_set_col_spacing (GTK_TABLE (table2), 1, 12);
gtk_container_add (GTK_CONTAINER (frame), table2);
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox2);
gtk_widget_show (vbox2);
/* Save EXIF data */
save_exif = gtk_check_button_new_with_mnemonic (_("Save _Exif data"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (save_exif), params->exif);
gtk_widget_set_sensitive (save_exif, TRUE);
gtk_table_attach (GTK_TABLE (table2), save_exif, 0, 1,
0, 1, GTK_FILL, 0, 0, 0);
gtk_box_pack_start (GTK_BOX (vbox2), save_exif, FALSE, FALSE, 0);
gtk_widget_show (save_exif);
g_signal_connect (save_exif, "toggled",
......@@ -293,18 +288,13 @@ save_dialog (WebPSaveParams *params,
/* XMP metadata */
save_xmp = gtk_check_button_new_with_mnemonic (_("Save _XMP data"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (save_xmp), params->xmp);
gtk_table_attach (GTK_TABLE (table2), save_xmp, 0, 1,
1, 2, GTK_FILL, 0, 0, 0);
gtk_box_pack_start (GTK_BOX (vbox2), save_xmp, FALSE, FALSE, 0);
gtk_widget_show (save_xmp);
g_signal_connect (save_xmp, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&params->xmp);
gtk_widget_set_sensitive (save_xmp, TRUE);
gtk_widget_show (table2);
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
......
......@@ -25,15 +25,15 @@
#include <stdlib.h>
#include <stdint.h>
#include <webp/decode.h>
#include <webp/demux.h>
#include <webp/mux.h>
#include <gegl.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include <webp/decode.h>
#include <webp/demux.h>
#include <webp/mux.h>
#include "file-webp-load.h"
#include "libgimp/stdplugins-intl.h"
......@@ -106,12 +106,12 @@ load_image (const gchar *filename,
return -1;
}
g_printerr ("Loading WebP file %s\n", filename);
/* Validate WebP data */
if (! WebPGetInfo (indata, indatalen, &width, &height))
{
g_printerr ("Invalid WebP file\n");
g_set_error (error, G_FILE_ERROR, 0,
"Invalid WebP file '%s'",
gimp_filename_to_utf8 (filename));
return -1;
}
......
......@@ -179,9 +179,10 @@ save_layer (const gchar *filename,
WebPPicture picture = {0};
guchar *buffer = NULL;
gint w, h;
gboolean has_alpha;
const Babl *format;
gint bpp;
GimpColorProfile *profile;
GimpImageType drawable_type;
GeglBuffer *geglbuffer = NULL;
GeglRectangle extent;
gchar *indata;
......@@ -213,12 +214,18 @@ save_layer (const gchar *filename,
}
/* Obtain the drawable type */
drawable_type = gimp_drawable_type (drawable_ID);
has_alpha = gimp_drawable_has_alpha (drawable_ID);
if (has_alpha)
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
bpp = babl_format_get_bytes_per_pixel (format);
/* Retrieve the buffer for the layer */
geglbuffer = gimp_drawable_get_buffer (drawable_ID);
extent = *gegl_buffer_get_extent (geglbuffer);
bpp = gimp_drawable_bpp (drawable_ID);
w = extent.width;
h = extent.height;
......@@ -247,11 +254,11 @@ save_layer (const gchar *filename,
break;
/* Read the region into the buffer */
gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
gegl_buffer_get (geglbuffer, &extent, 1.0, format, buffer,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
/* Use the appropriate function to import the data from the buffer */
if (drawable_type == GIMP_RGB_IMAGE)
if (! has_alpha)
{
WebPPictureImportRGB (&picture, buffer, w * bpp);
}
......@@ -374,8 +381,10 @@ save_animation (const gchar *filename,
gboolean status = FALSE;
FILE *outfile = NULL;
guchar *buffer = NULL;
gint w, h, bpp;
GimpImageType drawable_type;
gint w, h;
gint bpp;
gboolean has_alpha;
const Babl *format;
GimpColorProfile *profile;
WebPAnimEncoderOptions enc_options;
WebPData webp_data;
......@@ -423,7 +432,14 @@ save_animation (const gchar *filename,
WebPMemoryWriter mw = { 0 };
/* Obtain the drawable type */
drawable_type = gimp_drawable_type (allLayers[loop]);
has_alpha = gimp_drawable_has_alpha (allLayers[loop]);
if (has_alpha)
format = babl_format ("R'G'B'A u8");
else
format = babl_format ("R'G'B' u8");
bpp = babl_format_get_bytes_per_pixel (format);
/* fix layers to avoid offset errors */
gimp_layer_resize_to_image_size (allLayers[loop]);
......@@ -431,7 +447,6 @@ save_animation (const gchar *filename,
/* Retrieve the buffer for the layer */
geglbuffer = gimp_drawable_get_buffer (allLayers[loop]);
extent = *gegl_buffer_get_extent (geglbuffer);
bpp = gimp_drawable_bpp (allLayers[loop]);
w = extent.width;
h = extent.height;
......@@ -477,11 +492,11 @@ save_animation (const gchar *filename,
picture.progress_hook = webp_file_progress;
/* Read the region into the buffer */
gegl_buffer_get (geglbuffer, &extent, 1.0, NULL, buffer,
gegl_buffer_get (geglbuffer, &extent, 1.0, format, buffer,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
/* Use the appropriate function to import the data from the buffer */
if (drawable_type == GIMP_RGB_IMAGE)
if (! has_alpha)
{
WebPPictureImportRGB (&picture, buffer, w * bpp);
}
......
......@@ -36,19 +36,14 @@
#include "libgimp/stdplugins-intl.h"
const char BINARY_NAME[] = "file-webp";
const char LOAD_PROCEDURE[] = "file-webp-load";
const char SAVE_PROCEDURE[] = "file-webp-save";
/* Predeclare our entrypoints. */
static void query (void);
static void run (const gchar *,
gint,
const GimpParam *,
gint *,
GimpParam **);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
/* Declare our plugin entry points. */
GimpPlugInInfo PLUG_IN_INFO =
{
NULL,
......@@ -57,9 +52,9 @@ GimpPlugInInfo PLUG_IN_INFO =
run
};
MAIN()
/* This function registers our load and save handlers. */
static void
query (void)
{
......@@ -93,7 +88,7 @@ query (void)
{ GIMP_PDB_INT32, "xmp", "Toggle saving xmp data (0/1)" }
};
gimp_install_procedure (LOAD_PROCEDURE,
gimp_install_procedure (LOAD_PROC,
"Loads images in the WebP file format",
"Loads images in the WebP file format",
"Nathan Osman, Ben Touchette",
......@@ -107,29 +102,29 @@ query (void)
load_arguments,
load_return_values);
gimp_register_file_handler_mime (LOAD_PROCEDURE, "image/webp");
gimp_register_load_handler (LOAD_PROCEDURE, "webp", "");
gimp_register_magic_load_handler (LOAD_PROCEDURE,
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_PROCEDURE,
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*",
"RGB*, GRAY*, INDEXED*",
GIMP_PLUGIN,
G_N_ELEMENTS (save_arguments),
0,
save_arguments,
NULL);
gimp_register_file_handler_mime (SAVE_PROCEDURE, "image/webp");
gimp_register_save_handler (SAVE_PROCEDURE, "webp", "");
gimp_register_file_handler_mime (SAVE_PROC, "image/webp");
gimp_register_save_handler (SAVE_PROC, "webp", "");
}
static void
......@@ -157,14 +152,11 @@ run (const gchar *name,
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
if (! strcmp (name, LOAD_PROCEDURE))
if (! strcmp (name, LOAD_PROC))
{
/* No need to determine whether the plugin is being invoked
* interactively here since we don't need a UI for loading
*/
image_ID = load_image (param[1].data.d_string, FALSE, &error);
if(image_ID != -1)
if (image_ID != -1)
{
/* Return the new image that was loaded */
*nreturn_vals = 2;
......@@ -176,10 +168,10 @@ run (const gchar *name,
status = GIMP_PDB_EXECUTION_ERROR;
}
}
else if (! strcmp (name, SAVE_PROCEDURE))
else if (! strcmp (name, SAVE_PROC))
{
WebPSaveParams params;
GimpExportReturn export_ret = GIMP_EXPORT_CANCEL;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
gint32 *layers;
gint32 n_layers;
......@@ -194,75 +186,84 @@ run (const gchar *name,
params.iptc = TRUE;
params.xmp = TRUE;
/* Load the image and drawable IDs */
image_ID = param[1].data.d_int32;
drawable_ID = param[2].data.d_int32;
layers = gimp_image_get_layers (image_ID, &n_layers);
/* What happens next depends on the run mode */
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
gimp_ui_init (BINARY_NAME, FALSE);
gimp_ui_init (PLUG_IN_BINARY, FALSE);
/* Attempt to export the image */
export_ret = gimp_export_image (&image_ID, &drawable_ID,
"WebP",
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
export = gimp_export_image (&image_ID, &drawable_ID, "WebP",
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA |
GIMP_EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION);
/* Return immediately if canceled */
if (export_ret == GIMP_EXPORT_CANCEL)
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
return;
}
break;
/* Display the dialog */
default:
break;
}
layers = gimp_image_get_layers (image_ID, &n_layers);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
if (! save_dialog (&params, image_ID, n_layers))
{
values[0].data.d_status = GIMP_PDB_CANCEL;
return;
}
status = GIMP_PDB_CANCEL;
break;
case GIMP_RUN_NONINTERACTIVE:
/* Ensure the correct number of parameters were supplied */
if (nparams != 10)
{
status = GIMP_PDB_CALLING_ERROR;
break;
}
else
{
g_free (params.preset);
params.preset = g_strdup (param[5].data.d_string);
params.lossless = param[6].data.d_int32;
params.quality = param[7].data.d_float;
params.alpha_quality = param[8].data.d_float;
params.animation = param[9].data.d_int32;
params.loop = param[10].data.d_int32;
params.exif = param[11].data.d_int32;
params.iptc = param[12].data.d_int32;
params.xmp = param[13].data.d_int32;
}
break;
/* Load the parameters */
g_free (params.preset);
params.preset = g_strdup (param[5].data.d_string);
params.lossless = param[6].data.d_int32;
params.quality = param[7].data.d_float;
params.alpha_quality = param[8].data.d_float;
params.animation = param[9].data.d_int32;
params.loop = param[10].data.d_int32;
params.exif = param[11].data.d_int32;
params.iptc = param[12].data.d_int32;
params.xmp = param[13].data.d_int32;
default:
break;
}
/* Attempt to save the image */
if (! save_image (param[3].data.d_string,
n_layers, layers,
image_ID,
drawable_ID,
&params,
&error))
if (status == GIMP_PDB_SUCCESS)
{
status = GIMP_PDB_EXECUTION_ERROR;
if (! save_image (param[3].data.d_string,
n_layers, layers,
image_ID,
drawable_ID,
&params,
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
g_free (params.preset);
g_free (layers);
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image_ID);
}
/* If an error was supplied, include it in the return values */
......
......@@ -19,10 +19,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEBP_H__
#define __WEBP_H__
#ifndef __FILE_WEBP_H__
#define __FILE_WEBP_H__
extern const char BINARY_NAME[];
extern const char SAVE_PROCEDURE[];
#endif /* __WEBP_H__ */
#define LOAD_PROC "file-webp-load"
#define SAVE_PROC "file-webp-save"
#define PLUG_IN_BINARY "file-webp"
#define PLUG_IN_ROLE "gimp-file-webp"
#endif /* __FILE_WEBP_H__ */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment