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