Mercurial > hg > forks > geeqie
changeset 1879:880d06578486
anaglyph support
author | Vladimir Nadvornik <nadvornik@suse.cz> |
---|---|
date | Fri, 28 Jan 2011 14:34:57 +0100 |
parents | 11850512dbdd |
children | b69a33a93ace |
files | src/pixbuf-renderer.c src/pixbuf-renderer.h src/renderer-tiles.c |
diffstat | 3 files changed, 62 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/pixbuf-renderer.c Fri Jan 28 13:13:27 2011 +0100 +++ b/src/pixbuf-renderer.c Fri Jan 28 14:34:57 2011 +0100 @@ -428,11 +428,11 @@ 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); @@ -2249,6 +2249,44 @@ /* *------------------------------------------------------------------- + * 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 *------------------------------------------------------------------- */
--- a/src/pixbuf-renderer.h Fri Jan 28 13:13:27 2011 +0100 +++ b/src/pixbuf-renderer.h Fri Jan 28 14:34:57 2011 +0100 @@ -354,5 +354,7 @@ 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: */
--- a/src/renderer-tiles.c Fri Jan 28 13:13:27 2011 +0100 +++ b/src/renderer-tiles.c Fri Jan 28 14:34:57 2011 +0100 @@ -1263,7 +1263,7 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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; }