[PATCH 08/10] Added a method to create new GdkPixbufs from in-memory data

David Shea dshea at redhat.com
Mon Jun 30 19:41:14 UTC 2014


This is handy, for example, for creating small transparent overlays.
Creating GdkPixbuf objects from any source other than a file is
broken in the gobject-introspection bindings, so this saves us from
keeping track of more files.
---
 widgets/src/widgets-common.c | 51 +++++++++++++++++++++++++++++++++++++++++++-
 widgets/src/widgets-common.h |  3 +++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/widgets/src/widgets-common.c b/widgets/src/widgets-common.c
index 60ad6a9..459289a 100644
--- a/widgets/src/widgets-common.c
+++ b/widgets/src/widgets-common.c
@@ -20,8 +20,10 @@
  *
  */
 
-#include <glib.h>
+#include "widgets-common.h"
+
 #include <stdlib.h>
+#include <string.h>
 
 /**
  * anaconda_get_widgets_datadir:
@@ -44,3 +46,50 @@ const gchar *anaconda_get_widgets_datadir(void) {
     else
         return env_value;
 }
+
+static void free_pixbuf(guchar *pixels, gpointer data) {
+    g_free(pixels);
+}
+
+/**
+ * anaconda_make_pixbuf:
+ * @data: (array): The data that would be passed to gdk_pixbuf_new_from_data() were
+ * that actually possible
+ * @has_alpha: Whether the data has an opacity channel
+ * @width: Width of the image in pixels, must be > 0
+ * @height: Height of the image in pixels, must be > 0
+ * @rowstride: Distance in bytes between row starts
+ *
+ * Create a GdkPixbuf in a way that actually works in gobject-introspection bindings.
+ *
+ * See also: https://bugzilla.gnome.org/show_bug.cgi?id=732297
+ *
+ * colorspace and bits_per_sample are not provided as parameters because it would break
+ * something if they were ever not GDK_COLORSPACE_RGB and 8, respectively.
+ *
+ * Returns: (transfer full): A new GdkPixbuf
+ *
+ * Since: 3.0
+ */
+GdkPixbuf * anaconda_make_pixbuf(const guint8 *data, gboolean has_alpha,
+        int width, int height, int rowstride) {
+    guchar *data_copy;
+
+    /* Length of the data is max_y * rowstride + max_x * n_channels */
+    size_t data_len = (width * rowstride) + (height * (has_alpha ? 4 : 3));
+
+    /* Create a copy of the data because whoever wrote gdk-pixbuf doesn't understand
+     * reference ownership. */
+    data_copy = g_malloc(data_len);
+    memcpy(data_copy, data, data_len);
+    return gdk_pixbuf_new_from_data(data_copy,
+            GDK_COLORSPACE_RGB,
+            has_alpha,
+            8,
+            width,
+            height,
+            rowstride,
+            free_pixbuf,
+            NULL
+            );
+}
diff --git a/widgets/src/widgets-common.h b/widgets/src/widgets-common.h
index 941ef83..d3aa488 100644
--- a/widgets/src/widgets-common.h
+++ b/widgets/src/widgets-common.h
@@ -21,10 +21,13 @@
 #define _WIDGETS_COMMON_H
 
 #include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
 
 G_BEGIN_DECLS
 
 const gchar *anaconda_get_widgets_datadir(void);
+GdkPixbuf * anaconda_make_pixbuf(const guint8 *data, gboolean has_alpha,
+        int width, int height, int rowstride);
 
 G_END_DECLS
 
-- 
2.0.0



More information about the anaconda-patches mailing list