[gdk-pixbuf] Async version of gdk_pixbuf_new_from_stream
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdk-pixbuf] Async version of gdk_pixbuf_new_from_stream
- Date: Mon, 13 Dec 2010 12:11:52 +0000 (UTC)
commit 92e27ca8178265bcc1329f73a04ad5b21b5b822b
Author: Philip Withnall <philip tecnocode co uk>
Date: Fri Dec 10 17:07:33 2010 +0000
Async version of gdk_pixbuf_new_from_stream
Add async versions of gdk_pixbuf_new_from_stream
and gdk_pixbuf_new_from_stream_at_scale.
https://bugzilla.gnome.org/show_bug.cgi?id=575900
gdk-pixbuf/gdk-pixbuf-core.h | 27 ++++
gdk-pixbuf/gdk-pixbuf-io.c | 275 +++++++++++++++++++++++++++++++++++++++++
gdk-pixbuf/gdk-pixbuf.symbols | 5 +
3 files changed, 307 insertions(+), 0 deletions(-)
---
diff --git a/gdk-pixbuf/gdk-pixbuf-core.h b/gdk-pixbuf/gdk-pixbuf-core.h
index b256380..35d3f97 100644
--- a/gdk-pixbuf/gdk-pixbuf-core.h
+++ b/gdk-pixbuf/gdk-pixbuf-core.h
@@ -223,6 +223,14 @@ GdkPixbuf *gdk_pixbuf_new_from_stream (GInputStream *stream,
GCancellable *cancellable,
GError **error);
+void gdk_pixbuf_new_from_stream_async (GInputStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GdkPixbuf *gdk_pixbuf_new_from_stream_finish (GAsyncResult *async_result,
+ GError **error);
+
GdkPixbuf *gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream,
gint width,
gint height,
@@ -230,6 +238,14 @@ GdkPixbuf *gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream,
GCancellable *cancellable,
GError **error);
+void gdk_pixbuf_new_from_stream_at_scale_async (GInputStream *stream,
+ gint width,
+ gint height,
+ gboolean preserve_aspect_ratio,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
gboolean gdk_pixbuf_save_to_stream (GdkPixbuf *pixbuf,
GOutputStream *stream,
const char *type,
@@ -237,6 +253,17 @@ gboolean gdk_pixbuf_save_to_stream (GdkPixbuf *pixbuf,
GError **error,
...);
+void gdk_pixbuf_save_to_stream_async (GdkPixbuf *pixbuf,
+ GOutputStream *stream,
+ const gchar *type,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ ...);
+
+gboolean gdk_pixbuf_save_to_stream_finish (GAsyncResult *async_result,
+ GError **error);
+
/* Adding an alpha channel */
GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color,
guchar r, guchar g, guchar b);
diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c
index 6a5dbce..ff96f53 100644
--- a/gdk-pixbuf/gdk-pixbuf-io.c
+++ b/gdk-pixbuf/gdk-pixbuf-io.c
@@ -1445,6 +1445,81 @@ gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream,
return pixbuf;
}
+static void
+new_from_stream_thread (GSimpleAsyncResult *result,
+ GInputStream *stream,
+ GCancellable *cancellable)
+{
+ GdkPixbuf *pixbuf;
+ AtScaleData *data;
+ GError *error = NULL;
+
+ /* If data != NULL, we're scaling the pixbuf while loading it */
+ data = g_simple_async_result_get_op_res_gpointer (result);
+ if (data != NULL)
+ pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, data->width, data->height, data->preserve_aspect_ratio, cancellable, &error);
+ else
+ pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, &error);
+
+ g_free (data); /* GSimpleAsyncResult doesn't destroy result pointers when setting a new value over the top */
+ g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
+
+ /* Set the new pixbuf as the result, or error out */
+ if (pixbuf == NULL) {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ } else {
+ g_simple_async_result_set_op_res_gpointer (result, pixbuf, g_object_unref);
+ }
+}
+
+/**
+ * gdk_pixbuf_new_from_stream_at_scale_async:
+ * @stream: a #GInputStream from which to load the pixbuf
+ * @width: the width the image should have or -1 to not constrain the width
+ * @height: the height the image should have or -1 to not constrain the height
+ * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded
+ * @user_data: the data to pass to the callback function
+ *
+ * Creates a new pixbuf by asynchronously loading an image from an input stream.
+ *
+ * For more details see gdk_pixbuf_new_from_stream_at_scale(), which is the synchronous
+ * version of this function.
+ *
+ * When the operation is finished, @callback will be called in the main thread.
+ * You can then call gdk_pixbuf_new_from_stream_finish() to get the result of the operation.
+ *
+ * Since: 2.24
+ **/
+void
+gdk_pixbuf_new_from_stream_at_scale_async (GInputStream *stream,
+ gint width,
+ gint height,
+ gboolean preserve_aspect_ratio,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ AtScaleData *data;
+
+ g_return_if_fail (G_IS_INPUT_STREAM (stream));
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ data = g_new (AtScaleData, 1);
+ data->width = width;
+ data->height = height;
+ data->preserve_aspect_ratio = preserve_aspect_ratio;
+
+ result = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, gdk_pixbuf_new_from_stream_at_scale_async);
+ g_simple_async_result_set_op_res_gpointer (result, data, (GDestroyNotify) g_free);
+ g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc) new_from_stream_thread, G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (result);
+}
+
/**
* gdk_pixbuf_new_from_stream:
* @stream: a #GInputStream to load the pixbuf from
@@ -1483,6 +1558,75 @@ gdk_pixbuf_new_from_stream (GInputStream *stream,
return pixbuf;
}
+/**
+ * gdk_pixbuf_new_from_stream_async:
+ * @stream: a #GInputStream from which to load the pixbuf
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded
+ * @user_data: the data to pass to the callback function
+ *
+ * Creates a new pixbuf by asynchronously loading an image from an input stream.
+ *
+ * For more details see gdk_pixbuf_new_from_stream(), which is the synchronous
+ * version of this function.
+ *
+ * When the operation is finished, @callback will be called in the main thread.
+ * You can then call gdk_pixbuf_new_from_stream_finish() to get the result of the operation.
+ *
+ * Since: 2.24
+ **/
+void
+gdk_pixbuf_new_from_stream_async (GInputStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ g_return_if_fail (G_IS_INPUT_STREAM (stream));
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ result = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, gdk_pixbuf_new_from_stream_async);
+ g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc) new_from_stream_thread, G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (result);
+}
+
+/**
+ * gdk_pixbuf_new_from_stream_finish:
+ * @async_result: a #GAsyncResult
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous pixbuf creation operation started with
+ * gdk_pixbuf_new_from_stream_async().
+ *
+ * Return value: a #GdkPixbuf or %NULL on error. Free the returned
+ * object with g_object_unref().
+ *
+ * Since: 2.24
+ **/
+GdkPixbuf *
+gdk_pixbuf_new_from_stream_finish (GAsyncResult *async_result,
+ GError **error)
+{
+ GdkPixbuf *pixbuf;
+ GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (async_result);
+
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (async_result), NULL);
+ g_return_val_if_fail (!error || (error && !*error), NULL);
+ g_warn_if_fail (g_simple_async_result_get_source_tag (result) == gdk_pixbuf_new_from_stream_async ||
+ g_simple_async_result_get_source_tag (result) == gdk_pixbuf_new_from_stream_at_scale_async);
+
+ if (g_simple_async_result_propagate_error (result, error))
+ return NULL;
+
+ pixbuf = g_simple_async_result_get_op_res_gpointer (result);
+ if (pixbuf != NULL)
+ return g_object_ref (pixbuf);
+
+ return NULL;
+}
+
static void
info_cb (GdkPixbufLoader *loader,
int width,
@@ -2452,6 +2596,137 @@ gdk_pixbuf_save_to_stream (GdkPixbuf *pixbuf,
return res;
}
+typedef struct {
+ GOutputStream *stream;
+ gchar *type;
+ gchar **keys;
+ gchar **values;
+} SaveToStreamAsyncData;
+
+static void
+save_to_stream_async_data_free (SaveToStreamAsyncData *data)
+{
+ g_strfreev (data->keys);
+ g_strfreev (data->values);
+ g_free (data->type);
+ g_free (data);
+}
+
+static void
+save_to_stream_thread (GSimpleAsyncResult *result,
+ GdkPixbuf *pixbuf,
+ GCancellable *cancellable)
+{
+ SaveToStreamAsyncData *data;
+ SaveToStreamData sync_data;
+ gboolean retval;
+ GError *error = NULL;
+
+ data = g_simple_async_result_get_op_res_gpointer (result);
+ sync_data.stream = data->stream;
+ sync_data.cancellable = cancellable;
+
+ retval = gdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream,
+ &sync_data, data->type,
+ data->keys, data->values,
+ &error);
+
+ save_to_stream_async_data_free (data); /* GSimpleAsyncResult doesn't destroy result pointers when setting a new value over the top */
+
+ /* Set the new pixbuf as the result, or error out */
+ if (retval == FALSE) {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ } else {
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ }
+}
+
+/**
+ * gdk_pixbuf_save_to_stream_async:
+ * @pixbuf: a #GdkPixbuf
+ * @stream: a #GOutputStream to which to save the pixbuf
+ * @type: name of file format
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded
+ * @user_data: the data to pass to the callback function
+ * @Varargs: list of key-value save options
+ *
+ * Saves @pixbuf to an output stream asynchronously.
+ *
+ * For more details see gdk_pixbuf_save_to_stream(), which is the synchronous
+ * version of this function.
+ *
+ * When the operation is finished, @callback will be called in the main thread.
+ * You can then call gdk_pixbuf_save_to_stream_finish() to get the result of the operation.
+ *
+ * Since: 2.24
+ **/
+void
+gdk_pixbuf_save_to_stream_async (GdkPixbuf *pixbuf,
+ GOutputStream *stream,
+ const gchar *type,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ ...)
+{
+ GSimpleAsyncResult *result;
+ gchar **keys = NULL;
+ gchar **values = NULL;
+ va_list args;
+ SaveToStreamAsyncData *data;
+
+ g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+ g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
+ g_return_if_fail (type != NULL);
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ va_start (args, user_data);
+ collect_save_options (args, &keys, &values);
+ va_end (args);
+
+ data = g_new (SaveToStreamAsyncData, 1);
+ data->stream = g_object_ref (stream);
+ data->type = g_strdup (type);
+ data->keys = keys;
+ data->values = values;
+
+ result = g_simple_async_result_new (G_OBJECT (pixbuf), callback, user_data, gdk_pixbuf_save_to_stream_async);
+ g_simple_async_result_set_op_res_gpointer (result, data, (GDestroyNotify) save_to_stream_async_data_free);
+ g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc) save_to_stream_thread, G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (result);
+}
+
+/**
+ * gdk_pixbuf_save_to_stream_finish:
+ * @async_result: a #GAsyncResult
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous pixbuf save operation started with
+ * gdk_pixbuf_save_to_stream_async().
+ *
+ * Return value: %TRUE if the pixbuf was saved successfully, %FALSE if an error was set.
+ *
+ * Since: 2.24
+ **/
+gboolean
+gdk_pixbuf_save_to_stream_finish (GAsyncResult *async_result,
+ GError **error)
+{
+ GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (async_result);
+
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (async_result), FALSE);
+ g_return_val_if_fail (!error || (error && !*error), FALSE);
+ g_warn_if_fail (g_simple_async_result_get_source_tag (result) == gdk_pixbuf_save_to_stream_async);
+
+ if (g_simple_async_result_propagate_error (result, error))
+ return FALSE;
+
+ return g_simple_async_result_get_op_res_gboolean (result);
+}
+
/**
* gdk_pixbuf_format_get_name:
* @format: a #GdkPixbufFormat
diff --git a/gdk-pixbuf/gdk-pixbuf.symbols b/gdk-pixbuf/gdk-pixbuf.symbols
index 54d426f..ad13135 100644
--- a/gdk-pixbuf/gdk-pixbuf.symbols
+++ b/gdk-pixbuf/gdk-pixbuf.symbols
@@ -55,7 +55,10 @@ gdk_pixbuf_new_from_file_at_scale_utf8
#endif
gdk_pixbuf_new_from_xpm_data
gdk_pixbuf_new_from_stream
+gdk_pixbuf_new_from_stream_async
+gdk_pixbuf_new_from_stream_finish
gdk_pixbuf_new_from_stream_at_scale
+gdk_pixbuf_new_from_stream_at_scale_async
gdk_pixbuf_save PRIVATE G_GNUC_NULL_TERMINATED
#ifdef G_OS_WIN32
gdk_pixbuf_save_utf8
@@ -69,6 +72,8 @@ gdk_pixbuf_savev PRIVATE
gdk_pixbuf_savev_utf8
#endif
gdk_pixbuf_save_to_stream
+gdk_pixbuf_save_to_stream_async
+gdk_pixbuf_save_to_stream_finish
#endif
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]