From: Vladimir Nadvornik Date: Sun, 20 Mar 2011 18:16:07 +0000 (+0100) Subject: added more anaglyph modes X-Git-Tag: 1.1~66 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=8a3733bbabbca537e1f741984fa8b5e94cca08c6 added more anaglyph modes --- diff --git a/src/pixbuf-renderer.c b/src/pixbuf-renderer.c index f074e2b7..5482e127 100644 --- a/src/pixbuf-renderer.c +++ b/src/pixbuf-renderer.c @@ -2272,7 +2272,7 @@ static void pr_signals_connect(PixbufRenderer *pr) */ #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 @@ void pr_create_anaglyph(GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gin } } } + +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); +} /* *------------------------------------------------------------------- diff --git a/src/pixbuf-renderer.h b/src/pixbuf-renderer.h index b5086dd1..1c756da4 100644 --- a/src/pixbuf-renderer.h +++ b/src/pixbuf-renderer.h @@ -361,6 +361,6 @@ void pr_coords_map_orientation_reverse(gint orientation, 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: */ diff --git a/src/preferences.c b/src/preferences.c index 83a2cfef..ecca75f5 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -566,21 +566,27 @@ static void stereo_mode_menu_cb(GtkWidget *combo, gpointer data) *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; } @@ -600,29 +606,33 @@ static void add_stereo_mode_menu(GtkWidget *table, gint column, gint row, const 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); diff --git a/src/renderer-tiles.c b/src/renderer-tiles.c index 886bfd2e..c665e49f 100644 --- a/src/renderer-tiles.c +++ b/src/renderer-tiles.c @@ -1416,7 +1416,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, 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); diff --git a/src/typedefs.h b/src/typedefs.h index cdc2205b..7f88b94b 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -193,19 +193,22 @@ typedef enum { 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 {