Hi! I've been also affected by this bug. xzgv crashes when it tries to render 32bit pixels (alpha+rgb, 8bits each) to 24bits visuals.
There's a common workaround against this bug: http://www.x.org/archive/X11R6.8.0/doc/RELNOTES5.html So if you call $ XLIB_SKIP_ARGB_VISUALS=1 xzgv /some/path/ it should be working. Nevertheless, I do not propose to do this, because xzgv could be changed instead. With the help of gdb, I've traced down the problem to main.c:2560: In xvpic2pixmap, the call to gdk_draw_image() causes the error. This is exactly the place where the 32bit-to-24bit rendering takes places. According to http://mail.gnome.org/archives/gtk-app-devel-list/2001-September/msg00089.html it's not a good idea to use this function, as it involves handling every special case like byte ordering, color depth and so on. The link above refers to http://developer.gnome.org/doc/GGAD/z132.html#SEC-GDKRGB where the details of GdkRGB are described. I'm not common with GTK/GDK programming, but with the help of the API reference manual I've replaced the critical code by a GdkRGB buffer. The the attached patch corrects the problem. HTH -- mail: [EMAIL PROTECTED] http://adi.thur.de PGP/GPG: key via keyserver Eigentlich sieht dein ganzes Zimmer aus wie ein Tempverzeichnis. (Mitbewohner Michael)
diff -u -r xzgv-0.9+svn34/src/main.c xzgv-new/src/main.c --- xzgv-0.9+svn34/src/main.c 2007-12-18 13:55:59.000000000 +0100 +++ xzgv-new/src/main.c 2008-05-20 15:23:15.000000000 +0200 @@ -38,6 +38,7 @@ #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include <gdk/gdkx.h> /* needed for iconify stuff */ +#include <gdk/gdkrgb.h> /* http://bugs.debian.org/457252 */ #include <X11/Xlib.h> /* ditto */ #include "backend.h" @@ -105,7 +106,7 @@ GtkWidget *mainwin; -gint xvpic_pal[256]; /* palette for thumbnails */ +guint8 xvpic_pal[256][3]; /* palette for thumbnails */ /* image & rendered pixmap for currently-loaded image */ xzgv_image *theimage=NULL; @@ -2514,77 +2515,92 @@ */ void find_xvpic_cols(void) { -GdkColor col; -int r,g,b; -int n; - -for(n=0,r=0;r<8;r++) - for(g=0;g<8;g++) /* colours are 3:3:2 */ - for(b=0;b<4;b++,n++) - { - col.red=r*0xffff/7; col.green=g*0xffff/7; col.blue=b*0xffff/3; - backend_get_closest_colour(&col); - xvpic_pal[n]=col.pixel; - } + int r,g,b; + int n; + + for(n=0,r=0;r<8;r++) { + for(g=0;g<8;g++) {/* colours are 3:3:2 */ + for(b=0;b<4;b++,n++) { + xvpic_pal[n][0]=r*0xff/7; + xvpic_pal[n][1]=g*0xff/7; + xvpic_pal[n][2]=b*0xff/3; + } + } + } } GdkPixmap *xvpic2pixmap(unsigned char *xvpic,int w,int h,GdkPixmap **smallp) { GdkPixmap *pixmap,*small_pixmap; -GdkImage *image; +guint8 *buffer; unsigned char *ptr=xvpic; int x,y; int small_w,small_h; if(w==0 || h==0) return(NULL); -/* we allocate pixmap and image, draw into image, copy to pixmap, - * and ditch the image. - */ - -if((image=gdk_image_new(GDK_IMAGE_FASTEST,backend_get_visual(),w,h))==NULL) - return(NULL); - -if((pixmap=gdk_pixmap_new(mainwin->window,w,h, - gdk_visual_get_best_depth()))==NULL) - { - gdk_image_destroy(image); - return(NULL); - } -for(y=0;y<h;y++) - for(x=0;x<w;x++) - gdk_image_put_pixel(image,x,y,xvpic_pal[*ptr++]); - -gdk_draw_image(pixmap,clist->style->white_gc,image,0,0,0,0,w,h); -gdk_flush(); +if (NULL == (pixmap=gdk_pixmap_new(mainwin->window,w,h, -1))) { + return(NULL); +} -/* reuse image to draw scaled-down version for thin rows */ small_w=w/ROW_HEIGHT_DIV; small_h=h/ROW_HEIGHT_DIV; if(small_w==0) small_w=1; if(small_h==0) small_h=1; -if((small_pixmap=gdk_pixmap_new(mainwin->window,small_w,small_h, - gdk_visual_get_best_depth()))==NULL) - { - gdk_pixmap_unref(pixmap); - gdk_image_destroy(image); - return(NULL); +if((small_pixmap=gdk_pixmap_new(mainwin->window,small_w,small_h,-1))==NULL) +{ + gdk_pixmap_unref(pixmap); + return(NULL); +} + +buffer = malloc (w * h * sizeof (guint8) * 3); + +if (NULL == buffer) { + /* malloc failed */ + gdk_pixmap_unref(pixmap); + gdk_pixmap_unref(small_pixmap); + return NULL; +} + + +for(y=0;y<h;y++) { + for(x=0;x<w;x++) { + buffer[3*(y*w + x)+0] = xvpic_pal[*ptr][0]; /* red */ + buffer[3*(y*w + x)+1] = xvpic_pal[*ptr][1]; /* green */ + buffer[3*(y*w + x)+2] = xvpic_pal[*ptr][2]; /* blue */ + ptr++; } +} + +gdk_draw_rgb_image(pixmap,clist->style->white_gc,0,0,w,h, + GDK_RGB_DITHER_NORMAL, + (guchar*)buffer, w * 3); +gdk_flush(); + +/* reuse image to draw scaled-down version for thin rows */ -for(y=0;y<small_h;y++) - for(x=0;x<small_w;x++) - gdk_image_put_pixel(image,x,y, - xvpic_pal[xvpic[(y*w+x)*ROW_HEIGHT_DIV]]); -gdk_draw_image(small_pixmap,clist->style->white_gc,image, - 0,0,0,0,small_w,small_h); +for(y=0;y<small_h;y++) { + for(x=0;x<small_w;x++) { + buffer[3*(y*w + x)+0] = xvpic_pal[xvpic[(y*w+x)*ROW_HEIGHT_DIV]][0]; + buffer[3*(y*w + x)+1] = xvpic_pal[xvpic[(y*w+x)*ROW_HEIGHT_DIV]][1]; + buffer[3*(y*w + x)+2] = xvpic_pal[xvpic[(y*w+x)*ROW_HEIGHT_DIV]][2]; + } +} -gdk_image_destroy(image); +gdk_draw_rgb_image(small_pixmap,clist->style->white_gc,0,0,small_w, small_h, + GDK_RGB_DITHER_NORMAL, + (guchar*)buffer, small_w * 3); *smallp=small_pixmap; + +if (NULL != buffer) { + free (buffer); +} + return(pixmap); } @@ -3649,7 +3665,11 @@ }; +gtk_widget_push_visual(gdk_rgb_get_visual()); +gtk_widget_push_colormap(gdk_rgb_get_cmap()); mainwin=gtk_window_new(GTK_WINDOW_TOPLEVEL); +gtk_widget_pop_visual(); +gtk_widget_pop_colormap(); GTK_WIDGET_UNSET_FLAGS(mainwin,GTK_CAN_FOCUS); gtk_signal_connect(GTK_OBJECT(mainwin),"destroy", GTK_SIGNAL_FUNC(cb_quit),NULL);