[gegl] webp: Port webp-save operation to GIO
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] webp: Port webp-save operation to GIO
- Date: Sun, 20 Mar 2016 21:25:41 +0000 (UTC)
commit ff766f23e3bb792c86b45be602c6d5a7976b53f4
Author: Martin Blanchard <tchaik gmx com>
Date: Sun Mar 20 17:32:53 2016 +0100
webp: Port webp-save operation to GIO
Make use of gegl_gio_open_output_stream() service. No more direct
fopen() call for output.
https://bugzilla.gnome.org/show_bug.cgi?id=763577
operations/external/webp-save.c | 169 +++++++++++++++++++++++++++++----------
1 files changed, 125 insertions(+), 44 deletions(-)
---
diff --git a/operations/external/webp-save.c b/operations/external/webp-save.c
index 1433025..a48462e 100644
--- a/operations/external/webp-save.c
+++ b/operations/external/webp-save.c
@@ -19,10 +19,11 @@
#include "config.h"
#include <glib/gi18n-lib.h>
+
#ifdef GEGL_PROPERTIES
property_file_path (path, _("File"), "")
- description (_("Target file path."))
+ description (_("Target path and filename, use '-' for stdout"))
property_int (quality, _("Quality"), 90)
description (_("WebP compression quality"))
@@ -33,69 +34,149 @@ property_int (quality, _("Quality"), 90)
#define GEGL_OP_SINK
#define GEGL_OP_C_SOURCE webp-save.c
-#include "gegl-op.h"
+#include <gegl-op.h>
+#include <gegl-gio-private.h>
#include <webp/encode.h>
-#include <stdio.h>
static int
-write_func (const uint8_t* data, size_t data_size, const WebPPicture* const pic)
+write_to_stream (const uint8_t* data,
+ size_t size,
+ const WebPPicture* picture)
+{
+ GOutputStream *stream = (GOutputStream *) picture->custom_ptr;
+ GError *error = NULL;
+ gboolean success;
+ gsize written;
+
+ g_assert (stream);
+
+ success = g_output_stream_write_all (G_OUTPUT_STREAM (stream),
+ (const void *) data, size, &written,
+ NULL, &error);
+ if (!success || error != NULL)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return 0;
+ }
+
+ return 1;
+}
+
+static gint
+save_RGBA (WebPPicture *picture,
+ GeglBuffer *input,
+ const GeglRectangle *result,
+ const Babl *format)
{
- FILE* const out = (FILE*) pic->custom_ptr;
+ gint bytes_per_pixel, bytes_per_row;
+ uint8_t *buffer;
+
+ bytes_per_pixel = babl_format_get_bytes_per_pixel (format);
+ bytes_per_row = bytes_per_pixel * result->width;
+
+ buffer = g_try_new (uint8_t, bytes_per_row * result->height);
+
+ g_assert (buffer != NULL);
- if (!data_size) return 1;
- return fwrite (data, data_size, 1, out) == 1;
+ gegl_buffer_get (input, result, 1.0, format, buffer,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+ WebPPictureImportRGBA (picture, buffer, bytes_per_row);
+
+ g_free (buffer);
+ return 0;
}
static gboolean
-process (GeglOperation *operation,
- GeglBuffer *input,
- const GeglRectangle *result,
- gint level)
+export_webp (GeglOperation *operation,
+ GeglBuffer *input,
+ const GeglRectangle *result,
+ GOutputStream *stream)
{
GeglProperties *o = GEGL_PROPERTIES (operation);
- const GeglRectangle *bounds = gegl_buffer_get_extent (input);
-
- FILE* file;
- int status;
-
WebPConfig config;
- WebPPicture pic;
+ WebPPicture picture;
+ const Babl *format;
+ gint status;
- if (!WebPConfigPreset (&config, WEBP_PRESET_DEFAULT, o->quality))
- return FALSE;
+ g_return_val_if_fail (stream != NULL, FALSE);
- if (!WebPValidateConfig (&config))
- return FALSE;
+ if (!WebPConfigInit (&config) || !WebPPictureInit (&picture))
+ {
+ g_warning ("could not initialize WebP encoder");
+ return FALSE;
+ }
- if (!WebPPictureInit (&pic))
- return FALSE;
+ if (!WebPConfigPreset (&config, WEBP_PRESET_DEFAULT, o->quality))
+ {
+ g_warning("could not load WebP default preset");
+ return FALSE;
+ }
- pic.width = bounds->width;
- pic.height = bounds->height;
+ picture.width = result->width;
+ picture.height = result->height;
- file = fopen (o->path, "wb");
- pic.writer = write_func;
- pic.custom_ptr = file;
+ format = babl_format ("R'G'B'A u8");
- {
- gint rowstride = bounds->width * sizeof (char) * 4;
- gpointer temp = g_malloc (rowstride * bounds->height);
+ if (!WebPValidateConfig (&config))
+ {
+ g_warning ("WebP encoder configuration is invalid");
+ return FALSE;
+ }
- gegl_buffer_get (input, bounds, 1.0, babl_format ("R'G'B'A u8"), temp,
- rowstride, GEGL_ABYSS_NONE);
+ picture.writer = write_to_stream;
+ picture.custom_ptr = stream;
- WebPPictureImportRGBA (&pic, temp, rowstride);
+ if (save_RGBA (&picture, input, result, format))
+ {
+ g_warning ("could not pass pixels data to WebP encoder");
+ return FALSE;
+ }
- g_free (temp);
- }
+ status = WebPEncode (&config, &picture);
- status = WebPEncode (&config, &pic);
- WebPPictureFree (&pic);
- fclose (file);
+ WebPPictureFree (&picture);
return status ? TRUE : FALSE;
}
+static gboolean
+process (GeglOperation *operation,
+ GeglBuffer *input,
+ const GeglRectangle *result,
+ gint level)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ GOutputStream *stream;
+ GFile *file = NULL;
+ GError *error = NULL;
+ gboolean status = TRUE;
+
+ stream = gegl_gio_open_output_stream (NULL, o->path, &file, &error);
+ if (stream == NULL)
+ {
+ status = FALSE;
+ g_warning ("%s", error->message);
+ goto cleanup;
+ }
+
+ if (!export_webp (operation, input, result, stream))
+ {
+ status = FALSE;
+ g_warning ("could not export WebP file");
+ goto cleanup;
+ }
+
+cleanup:
+ if (stream != NULL)
+ g_object_unref (stream);
+
+ if (file != NULL)
+ g_object_unref (file);
+
+ return status;
+}
static void
gegl_op_class_init (GeglOpClass *klass)
@@ -110,11 +191,11 @@ gegl_op_class_init (GeglOpClass *klass)
sink_class->needs_full = TRUE;
gegl_operation_class_set_keys (operation_class,
- "name", "gegl:webp-save",
- "title", _("WebP File Saver"),
- "categories" , "output",
- "description", _("WebP image saver."),
- NULL);
+ "name", "gegl:webp-save",
+ "title", _("WebP File Saver"),
+ "categories", "output",
+ "description", _("WebP image saver"),
+ NULL);
gegl_extension_handler_register_saver (".webp", "gegl:webp-save");
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]