From: Vladimir Nadvornik Date: Fri, 28 Jan 2011 13:34:57 +0000 (+0100) Subject: anaglyph support X-Git-Tag: 1.1~83 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=0a5ec68af089d4b79c3816d3e7df0434ea0ad5e8 anaglyph support --- diff --git a/src/pixbuf-renderer.c b/src/pixbuf-renderer.c index ce27ecfc..82249d9a 100644 --- a/src/pixbuf-renderer.c +++ b/src/pixbuf-renderer.c @@ -428,11 +428,11 @@ static void pixbuf_renderer_init(PixbufRenderer *pr) pr->norm_center_x = 0.5; pr->norm_center_y = 0.5; - pr->stereo_mode = PR_STEREO_HORIZ; + pr->stereo_mode = PR_STEREO_ANAGLYPH; pr->renderer = (void *)renderer_tiles_new(pr, pr->stereo_mode); - pr->renderer2 = (pr->stereo_mode && (PR_STEREO_HORIZ || PR_STEREO_VERT)) ? + pr->renderer2 = (pr->stereo_mode & (PR_STEREO_HORIZ | PR_STEREO_VERT)) ? (void *)renderer_tiles_new(pr, pr->stereo_mode | PR_STEREO_RIGHT) : NULL; gtk_widget_set_double_buffered(box, FALSE); @@ -2247,6 +2247,44 @@ static void pr_signals_connect(PixbufRenderer *pr) } +/* + *------------------------------------------------------------------- + * stereo support + *------------------------------------------------------------------- + */ + +#define COLOR_BYTES 3 /* rgb */ +void pr_create_anaglyph(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; + + 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++) + { + *dp = *sp; /* copy red channel */ + sp += COLOR_BYTES; + dp += COLOR_BYTES; + } + } +} + + + /* *------------------------------------------------------------------- * public diff --git a/src/pixbuf-renderer.h b/src/pixbuf-renderer.h index 77593f87..4c88aad8 100644 --- a/src/pixbuf-renderer.h +++ b/src/pixbuf-renderer.h @@ -354,5 +354,7 @@ void pr_coords_map_orientation_reverse(gint orientation, gint *res_w, gint *res_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); #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/renderer-tiles.c b/src/renderer-tiles.c index 8b199562..27f7b0cc 100644 --- a/src/renderer-tiles.c +++ b/src/renderer-tiles.c @@ -1263,7 +1263,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, GtkWidget *box; gboolean has_alpha; gboolean draw = FALSE; - gint stereo_pixbuf_off; + gint stereo_right_pixbuf_off; if (it->render_todo == TILE_RENDER_NONE && it->pixmap && !new_data) return; @@ -1288,7 +1288,7 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, rt_tile_prepare(rt, it); has_alpha = (pr->pixbuf && gdk_pixbuf_get_has_alpha(pr->pixbuf)); - stereo_pixbuf_off = (rt->stereo_mode & PR_STEREO_RIGHT) ? pr->stereo_pixbuf_off : 0; + stereo_right_pixbuf_off = (rt->stereo_mode & PR_STEREO_RIGHT) ? pr->stereo_pixbuf_off : 0; box = GTK_WIDGET(pr); /* FIXME checker colors for alpha should be configurable, @@ -1308,17 +1308,18 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, else if ((pr->zoom == 1.0 || pr->scale == 1.0) && !has_alpha && pr->orientation == EXIF_ORIENTATION_TOP_LEFT && - !(pr->func_post_process && !(pr->post_process_slow && fast))) + !(pr->func_post_process && !(pr->post_process_slow && fast)) && + !(rt->stereo_mode & PR_STEREO_ANAGLYPH)) { /* special case: faster, simple, scale 1.0, base orientation, no postprocessing */ - gdk_draw_pixbuf(it->pixmap, + gdk_draw_pixbuf(it->pixmap, #if GTK_CHECK_VERSION(2,20,0) box->style->fg_gc[gtk_widget_get_state(box)], #else box->style->fg_gc[GTK_WIDGET_STATE(box)], #endif pr->pixbuf, - it->x + x + stereo_pixbuf_off, it->y + y, + it->x + x + stereo_right_pixbuf_off, it->y + y, x, y, w, h, pr->dither_quality, it->x + x, it->y + y); @@ -1360,7 +1361,6 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, /* nothing to do */ break; } - src_x += stereo_pixbuf_off * scale_x; /* HACK: The pixbuf scalers get kinda buggy(crash) with extremely * small sizes for anything but GDK_INTERP_NEAREST @@ -1369,11 +1369,24 @@ static void rt_tile_render(RendererTiles *rt, ImageTile *it, rt_tile_get_region(has_alpha, pr->pixbuf, it->pixbuf, pb_x, pb_y, pb_w, pb_h, - (gdouble) 0.0 - src_x, + (gdouble) 0.0 - src_x - stereo_right_pixbuf_off * scale_x, (gdouble) 0.0 - src_y, scale_x, scale_y, (fast) ? GDK_INTERP_NEAREST : pr->zoom_quality, it->x + pb_x, it->y + pb_y); + if (rt->stereo_mode & PR_STEREO_ANAGLYPH && pr->stereo_pixbuf_off > 0) + { + GdkPixbuf *right_pb = rt_get_spare_tile(rt); + rt_tile_get_region(has_alpha, + pr->pixbuf, right_pb, pb_x, pb_y, pb_w, pb_h, + (gdouble) 0.0 - src_x - pr->stereo_pixbuf_off * scale_x, + (gdouble) 0.0 - src_y, + 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); + /* do not care about freeing spare_tile, it will be reused */ + } rt_tile_apply_orientation(rt, &it->pixbuf, pb_x, pb_y, pb_w, pb_h); draw = TRUE; }