*/
#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;
}
}
}
+
+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);
+}
/*
*-------------------------------------------------------------------
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: */
*option = PR_STEREO_NONE;
break;
case 1:
- *option = PR_STEREO_ANAGLYPH;
+ *option = PR_STEREO_ANAGLYPH_RC;
break;
case 2:
- *option = PR_STEREO_HORIZ;
+ *option = PR_STEREO_ANAGLYPH_GRAY;
break;
case 3:
- *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
+ *option = PR_STEREO_ANAGLYPH_DB;
break;
case 4:
- *option = PR_STEREO_VERT;
+ *option = PR_STEREO_HORIZ;
break;
case 5:
- *option = PR_STEREO_VERT | PR_STEREO_HALF;
+ *option = PR_STEREO_HORIZ | PR_STEREO_HALF;
break;
case 6:
+ *option = PR_STEREO_VERT;
+ break;
+ case 7:
+ *option = PR_STEREO_VERT | PR_STEREO_HALF;
+ break;
+ case 8:
*option = PR_STEREO_FIXED;
break;
}
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);
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);
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 {