From 7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 14 Mar 2012 18:34:03 +0100 Subject: Add initial wimmel program --- util.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 util.c (limited to 'util.c') diff --git a/util.c b/util.c new file mode 100644 index 0000000..03551b5 --- /dev/null +++ b/util.c @@ -0,0 +1,131 @@ +#include +#include + +#include "util.h" + +/* + * derived from http://www.gnu.org/software/guile-gnome/docs/gdk/html/The-GdkPixbuf-Structure.html + */ +guchar *pixbuf_point(GdkPixbuf *pixbuf, point_t point) +{ + g_assert(point.x >= 0 && point.x < gdk_pixbuf_get_width (pixbuf)); + g_assert(point.y >= 0 && point.y < gdk_pixbuf_get_height(pixbuf)); + g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); + + return gdk_pixbuf_get_pixels(pixbuf) + + point.y * gdk_pixbuf_get_rowstride (pixbuf) + + point.x * gdk_pixbuf_get_n_channels(pixbuf); +} + +void put_pixel(GdkPixbuf *pixbuf, point_t point, color_t color) +{ + const gint n_channels = gdk_pixbuf_get_n_channels(pixbuf); + g_assert(n_channels == 4 || n_channels == 3); + g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB); + g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); + + guchar *p = pixbuf_point(pixbuf, point); + + p[0] = color.r; + p[1] = color.g; + p[2] = color.b; + if (n_channels == 4) + p[3] = color.a; +} + +color_t get_pixel(GdkPixbuf *pixbuf, point_t point) +{ + const gint n_channels = gdk_pixbuf_get_n_channels(pixbuf); + g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB); + g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); + g_assert(n_channels == 4 || n_channels == 3); + + guchar *p = pixbuf_point(pixbuf, point); + + return COLOR(p[0], p[1], p[2], n_channels == 4 ? p[3] : COL_MAX); +} + +void color_to_yiq(color_t color, guint8 *y, guint8 *i, guint8 *q) +{ + if (y) + *y = 0.299 * color.r + 0.587 * color.g + 0.115 * color.b; + if (i) + *i = 0.595716 * color.r - 0.274453 * color.g - 0.321263 * color.b; + if (q) + *q = 0.211456 * color.r - 0.522591 * color.g + 0.311135 * color.b; +} + +/* + * http://en.wikipedia.org/wiki/Digital_compositing + */ +color_t tint(color_t src, color_t tint_color) +{ + return COLOR( + (tint_color.a * tint_color.r + (255 - tint_color.a) * src.r) / 255, + (tint_color.a * tint_color.g + (255 - tint_color.a) * src.g) / 255, + (tint_color.a * tint_color.b + (255 - tint_color.a) * src.b) / 255, + src.a); +} + + +color32_t color32_add(color32_t a, color32_t b) +{ + return COLOR32( + a.r + b.r, + a.g + b.g, + a.b + b.b + ); +} + +color32_t color32_mult(color32_t a, gint multiplier) +{ + return COLOR32( + multiplier * a.r, + multiplier * a.g, + multiplier * a.b + ); +} +color32_t to_color32(color_t a) +{ + return COLOR32(a.r, a.g, a.b); +} + +colord_t colord_add(colord_t a, colord_t b) +{ + return COLORD( + a.r + b.r, + a.g + b.g, + a.b + b.b, + a.a + b.a + ); +} +colord_t colord_mult(colord_t a, gdouble multiplier) +{ + return COLORD( + multiplier * a.r, + multiplier * a.g, + multiplier * a.b, + multiplier * a.a + ); +} +colord_t to_colord(color_t a) +{ + return COLORD(a.r, a.g, a.b, a.a); +} + + +void ring_shift(void *_pntr, gint num, size_t size) +{ + g_assert(num >= 2); + + guint8 *pntr = (guint8*) _pntr; + + char *tmp = g_malloc(size); + g_memmove(tmp, pntr, size); + + for (gint i = 0; i < (num-1)*size; i+=size) + g_memmove(pntr+i, pntr+i+size, size); + + g_memmove(pntr + (num-1)*size, tmp, size); + g_free(tmp); +} -- cgit