summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2012-03-14 18:34:03 +0100
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2012-03-14 18:34:03 +0100
commit7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66 (patch)
tree96bc15a3c45881d80c05034e6f424f90ef0979a4 /util.c
downloadcv-7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66.tar.gz
cv-7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66.tar.bz2
cv-7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66.zip
Add initial wimmel program
Diffstat (limited to 'util.c')
-rw-r--r--util.c131
1 files changed, 131 insertions, 0 deletions
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 <glib.h>
+#include <gtk/gtk.h>
+
+#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);
+}