changeset 1896:9604c72ac670

added more anaglyph modes
author Vladimir Nadvornik <nadvornik@suse.cz>
date Sun, 20 Mar 2011 19:16:07 +0100
parents 6e3edda945ae
children b1fe543de73a
files src/pixbuf-renderer.c src/pixbuf-renderer.h src/preferences.c src/renderer-tiles.c src/typedefs.h
diffstat 5 files changed, 124 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/pixbuf-renderer.c	Sun Mar 20 12:49:00 2011 +0100
+++ b/src/pixbuf-renderer.c	Sun Mar 20 19:16:07 2011 +0100
@@ -2272,7 +2272,7 @@
  */
 
 #define COLOR_BYTES 3   /* rgb */
-void pr_create_anaglyph(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
+static void pr_create_anaglyph_RC(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
 {
 	gint srs, drs;
 	guchar *s_pix, *d_pix;
@@ -2300,8 +2300,95 @@
 			}
 		}
 }
+
+static void pr_create_anaglyph_gray(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
+{
+	gint srs, drs;
+	guchar *s_pix, *d_pix;
+	guchar *sp, *dp;
+	guchar *spi, *dpi;
+	gint i, j;
+	const double gc[3] = {0.299, 0.587, 0.114};
+
+	srs = gdk_pixbuf_get_rowstride(right);
+	s_pix = gdk_pixbuf_get_pixels(right);
+	spi = s_pix + (x * COLOR_BYTES);
+
+	drs = gdk_pixbuf_get_rowstride(pixbuf);
+	d_pix = gdk_pixbuf_get_pixels(pixbuf);
+	dpi =  d_pix + x * COLOR_BYTES;
+
+	for (i = y; i < y + h; i++)
+		{
+		sp = spi + (i * srs);
+		dp = dpi + (i * drs);
+		for (j = 0; j < w; j++)
+			{
+			guchar g1 = dp[0] * gc[0] + dp[1] * gc[1] + dp[2] * gc[2];
+			guchar g2 = sp[0] * gc[0] + sp[1] * gc[1] + sp[2] * gc[2];
+			dp[0] = g2; /* red channel from sp */
+			dp[1] = g1; /* green and blue from dp */
+			dp[2] = g1;
+			sp += COLOR_BYTES;
+			dp += COLOR_BYTES;
+			}
+		}
+}
+
+const double pr_dubois_matrix[3][6] = {
+	{ 0.456,  0.500,  0.176, -0.043, -0.088, -0.002},
+	{-0.040, -0.038, -0.016,  0.378,  0.734, -0.018},
+	{-0.015, -0.021, -0.005, -0.072, -0.113,  1.226}
+	}; 
+
+static void pr_create_anaglyph_dubois(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
+{
+	gint srs, drs;
+	guchar *s_pix, *d_pix;
+	guchar *sp, *dp;
+	guchar *spi, *dpi;
+	gint i, j, k;
+
+	srs = gdk_pixbuf_get_rowstride(right);
+	s_pix = gdk_pixbuf_get_pixels(right);
+	spi = s_pix + (x * COLOR_BYTES);
+
+	drs = gdk_pixbuf_get_rowstride(pixbuf);
+	d_pix = gdk_pixbuf_get_pixels(pixbuf);
+	dpi =  d_pix + x * COLOR_BYTES;
+
+	for (i = y; i < y + h; i++)
+		{
+		sp = spi + (i * srs);
+		dp = dpi + (i * drs);
+		for (j = 0; j < w; j++)
+			{
+			double res[3];
+			for (k = 0; k < 3; k++) 
+				{
+				double *m = pr_dubois_matrix[k];
+				res[k] = sp[0] * m[0] + sp[1] * m[1] + sp[2] * m[2] + dp[0] * m[3] + dp[1] * m[4] + dp[2] * m[5];
+				if (res[k] < 0.0) res[k] = 0;
+				if (res[k] > 255.0) res[k] = 255.0;
+				}
+			dp[0] = res[0];
+			dp[1] = res[1];
+			dp[2] = res[2];
+			sp += COLOR_BYTES;
+			dp += COLOR_BYTES;
+			}
+		}
+}
  
- 
+void pr_create_anaglyph(guint mode, GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
+{
+	if (mode & PR_STEREO_ANAGLYPH_RC)
+		pr_create_anaglyph_RC(pixbuf, right, x, y, w, h);
+	else if (mode & PR_STEREO_ANAGLYPH_GRAY)
+		pr_create_anaglyph_gray(pixbuf, right, x, y, w, h);
+	else if (mode & PR_STEREO_ANAGLYPH_DB)
+		pr_create_anaglyph_dubois(pixbuf, right, x, y, w, h);
+}
 
 /*
  *-------------------------------------------------------------------
--- a/src/pixbuf-renderer.h	Sun Mar 20 12:49:00 2011 +0100
+++ b/src/pixbuf-renderer.h	Sun Mar 20 19:16:07 2011 +0100
@@ -361,6 +361,6 @@
 
 GList *pr_source_tile_compute_region(PixbufRenderer *pr, gint x, gint y, gint w, gint h, gboolean request);
 
-void pr_create_anaglyph(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h);
+void pr_create_anaglyph(guint mode, GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h);
 #endif
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/preferences.c	Sun Mar 20 12:49:00 2011 +0100
+++ b/src/preferences.c	Sun Mar 20 19:16:07 2011 +0100
@@ -566,21 +566,27 @@
 			*option = PR_STEREO_NONE;
 			break;
 		case 1:
-			*option = PR_STEREO_ANAGLYPH;
+			*option = PR_STEREO_ANAGLYPH_RC;
 			break;
 		case 2:
+			*option = PR_STEREO_ANAGLYPH_GRAY;
+			break;
+		case 3:
+			*option = PR_STEREO_ANAGLYPH_DB;
+			break;
+		case 4:
 			*option = PR_STEREO_HORIZ;
 			break;
-		case 3:
+		case 5:
 			*option = PR_STEREO_HORIZ | PR_STEREO_HALF;
 			break;
-		case 4:
+		case 6:
 			*option = PR_STEREO_VERT;
 			break;
-		case 5:
+		case 7:
 			*option = PR_STEREO_VERT | PR_STEREO_HALF;
 			break;
-		case 6:
+		case 8:
 			*option = PR_STEREO_FIXED;
 			break;
 		}
@@ -600,29 +606,33 @@
 
 	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Single image"));
 
-	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Anaglyph"));
-	if (option & PR_STEREO_ANAGLYPH) current = 1;
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Anaglyph Red-Cyan"));
+	if (option & PR_STEREO_ANAGLYPH_RC) current = 1;
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Anaglyph Gray Red-Cyan"));
+	if (option & PR_STEREO_ANAGLYPH_GRAY) current = 2;
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Anaglyph Dubois"));
+	if (option & PR_STEREO_ANAGLYPH_DB) current = 3;
 
 	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Side by Side"));
 	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Side by Side Half size"));
 	if (option & PR_STEREO_HORIZ) 
 		{
-		current = 2;
-		if (option & PR_STEREO_HALF) current = 3;
+		current = 4;
+		if (option & PR_STEREO_HALF) current = 5;
 		}
 
 	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Top - Bottom"));
 	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Top - Bottom Half size"));
 	if (option & PR_STEREO_VERT) 
 		{
-		current = 4;
-		if (option & PR_STEREO_HALF) current = 5;
+		current = 6;
+		if (option & PR_STEREO_HALF) current = 7;
 		}
 		
 	if (add_fixed)
 		{
 		gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Fixed position"));
-		if (option & PR_STEREO_FIXED) current = 6;
+		if (option & PR_STEREO_FIXED) current = 8;
 		}
 
 	gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
--- a/src/renderer-tiles.c	Sun Mar 20 12:49:00 2011 +0100
+++ b/src/renderer-tiles.c	Sun Mar 20 19:16:07 2011 +0100
@@ -1416,7 +1416,7 @@
 					   scale_x, scale_y,
 					   (fast) ? GDK_INTERP_NEAREST : pr->zoom_quality,
 					   it->x + pb_x, it->y + pb_y);
-			pr_create_anaglyph(it->pixbuf, right_pb, pb_x, pb_y, pb_w, pb_h);
+			pr_create_anaglyph(rt->stereo_mode, it->pixbuf, right_pb, pb_x, pb_y, pb_w, pb_h);
 			/* do not care about freeing spare_tile, it will be reused */
 			}
 		rt_tile_apply_orientation(rt, orientation, &it->pixbuf, pb_x, pb_y, pb_w, pb_h);
--- a/src/typedefs.h	Sun Mar 20 12:49:00 2011 +0100
+++ b/src/typedefs.h	Sun Mar 20 19:16:07 2011 +0100
@@ -193,19 +193,22 @@
 	PR_STEREO_HORIZ          = 1 << 2, /* side by side */
 	PR_STEREO_VERT           = 1 << 3, /* above below */
 	PR_STEREO_RIGHT          = 1 << 4, /* render right buffer */
-	PR_STEREO_ANAGLYPH       = 1 << 5, /* anaglyph */
+	PR_STEREO_ANAGLYPH_RC    = 1 << 5, /* anaglyph red-cyan */
+	PR_STEREO_ANAGLYPH_GRAY  = 1 << 6, /* anaglyph gray red-cyan*/
+	PR_STEREO_ANAGLYPH_DB    = 1 << 7, /* anaglyph dubois*/
+	PR_STEREO_ANAGLYPH       = PR_STEREO_ANAGLYPH_RC | PR_STEREO_ANAGLYPH_GRAY | PR_STEREO_ANAGLYPH_DB, /* anaglyph mask */
 
-	PR_STEREO_MIRROR_LEFT    = 1 << 6, /* mirror */
-	PR_STEREO_FLIP_LEFT      = 1 << 7, /* flip */
+	PR_STEREO_MIRROR_LEFT    = 1 << 8, /* mirror */
+	PR_STEREO_FLIP_LEFT      = 1 << 9, /* flip */
 
-	PR_STEREO_MIRROR_RIGHT   = 1 << 8, /* mirror */
-	PR_STEREO_FLIP_RIGHT     = 1 << 9, /* flip */
+	PR_STEREO_MIRROR_RIGHT   = 1 << 10, /* mirror */
+	PR_STEREO_FLIP_RIGHT     = 1 << 11, /* flip */
 
 	PR_STEREO_MIRROR         = PR_STEREO_MIRROR_LEFT | PR_STEREO_MIRROR_RIGHT, /* mirror mask*/
 	PR_STEREO_FLIP           = PR_STEREO_FLIP_LEFT | PR_STEREO_FLIP_RIGHT, /* flip mask*/
-	PR_STEREO_SWAP           = 1 << 10,  /* swap left and right buffers */
-	PR_STEREO_TEMP_DISABLE   = 1 << 11,  /* temporarily disable stereo mode if source image is not stereo */
-	PR_STEREO_HALF           = 1 << 12
+	PR_STEREO_SWAP           = 1 << 12,  /* swap left and right buffers */
+	PR_STEREO_TEMP_DISABLE   = 1 << 13,  /* temporarily disable stereo mode if source image is not stereo */
+	PR_STEREO_HALF           = 1 << 14
 } PixbufRendererStereoMode;
 
 typedef enum {