summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2017-07-26 17:01:57 +0200
committerBastien Nocera <hadess@hadess.net>2017-07-28 13:03:18 +0100
commitc1a969045c056f0180b108a0abeff8b0febce960 (patch)
treea8121e22a443fc882e6dabd30d0e00c9054d8203
parente6c22e2c46417feb9b73c9937ff8a6a9e04d7046 (diff)
downloadgdk-pixbuf-c1a969045c056f0180b108a0abeff8b0febce960.tar.gz
gdk-pixbuf: Add gdk_pixbuf_calculate_rowstride()
To calculate the rowstride without allocating memory! https://bugzilla.gnome.org/show_bug.cgi?id=765094
-rw-r--r--configure.ac2
-rw-r--r--gdk-pixbuf/gdk-pixbuf-core.h7
-rw-r--r--gdk-pixbuf/gdk-pixbuf.c59
3 files changed, 54 insertions, 14 deletions
diff --git a/configure.ac b/configure.ac
index f28755ce2..da86b420a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,7 @@ AC_PREREQ([2.63])
m4_define([gdk_pixbuf_major_version], [2])
m4_define([gdk_pixbuf_minor_version], [36])
m4_define([gdk_pixbuf_micro_version], [7])
-m4_define([gdk_pixbuf_interface_age], [7])
+m4_define([gdk_pixbuf_interface_age], [0])
m4_define([gdk_pixbuf_binary_age],
[m4_eval(100 * gdk_pixbuf_minor_version + gdk_pixbuf_micro_version)])
m4_define([gdk_pixbuf_version],
diff --git a/gdk-pixbuf/gdk-pixbuf-core.h b/gdk-pixbuf/gdk-pixbuf-core.h
index a99cf4e72..f4c928d89 100644
--- a/gdk-pixbuf/gdk-pixbuf-core.h
+++ b/gdk-pixbuf/gdk-pixbuf-core.h
@@ -270,6 +270,13 @@ GDK_PIXBUF_AVAILABLE_IN_ALL
GdkPixbuf *gdk_pixbuf_new (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample,
int width, int height);
+GDK_PIXBUF_AVAILABLE_IN_2_36
+gint gdk_pixbuf_calculate_rowstride (GdkColorspace colorspace,
+ gboolean has_alpha,
+ int bits_per_sample,
+ int width,
+ int height);
+
/* Copy a pixbuf */
GDK_PIXBUF_AVAILABLE_IN_ALL
GdkPixbuf *gdk_pixbuf_copy (const GdkPixbuf *pixbuf);
diff --git a/gdk-pixbuf/gdk-pixbuf.c b/gdk-pixbuf/gdk-pixbuf.c
index 2ee0b2a43..8fe4b0c89 100644
--- a/gdk-pixbuf/gdk-pixbuf.c
+++ b/gdk-pixbuf/gdk-pixbuf.c
@@ -422,6 +422,46 @@ free_buffer (guchar *pixels, gpointer data)
}
/**
+ * gdk_pixbuf_calculate_rowstride:
+ * @colorspace: Color space for image
+ * @has_alpha: Whether the image should have transparency information
+ * @bits_per_sample: Number of bits per color sample
+ * @width: Width of image in pixels, must be > 0
+ * @height: Height of image in pixels, must be > 0
+ *
+ * Calculates the rowstride that an image created with those values would
+ * have. This is useful for front-ends and backends that want to sanity
+ * check image values without needing to create them.
+ *
+ * Return value: the rowstride for the given values, or -1 in case of error.
+ *
+ * Since: 2.36.8
+ */
+gint
+gdk_pixbuf_calculate_rowstride (GdkColorspace colorspace,
+ gboolean has_alpha,
+ int bits_per_sample,
+ int width,
+ int height)
+{
+ unsigned int channels;
+
+ g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, -1);
+ g_return_val_if_fail (bits_per_sample == 8, -1);
+ g_return_val_if_fail (width > 0, -1);
+ g_return_val_if_fail (height > 0, -1);
+
+ channels = has_alpha ? 4 : 3;
+
+ /* Overflow? */
+ if (width > (G_MAXINT - 3) / channels)
+ return -1;
+
+ /* Always align rows to 32-bit boundaries */
+ return (width * channels + 3) & ~3;
+}
+
+/**
* gdk_pixbuf_new:
* @colorspace: Color space for image
* @has_alpha: Whether the image should have transparency information
@@ -444,23 +484,16 @@ gdk_pixbuf_new (GdkColorspace colorspace,
int height)
{
guchar *buf;
- unsigned int channels;
int rowstride;
- g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL);
- g_return_val_if_fail (bits_per_sample == 8, NULL);
- g_return_val_if_fail (width > 0, NULL);
- g_return_val_if_fail (height > 0, NULL);
-
- channels = has_alpha ? 4 : 3;
-
- /* Overflow? */
- if (width > (G_MAXINT - 3) / channels)
+ rowstride = gdk_pixbuf_calculate_rowstride (colorspace,
+ has_alpha,
+ bits_per_sample,
+ width,
+ height);
+ if (rowstride <= 0)
return NULL;
- /* Always align rows to 32-bit boundaries */
- rowstride = (width * channels + 3) & ~3;
-
buf = g_try_malloc_n (height, rowstride);
if (!buf)
return NULL;