2012-05-08 15 views
13

Estoy intentando crear un mapa de puntos RGBA del lado del servidor desde el búfer del lado del cliente. CreatePixmap trabajo & CreateImage bien para 32 y 24 bits, pero XPutImage resultado de un error de ajuste devueltos por el servidorCómo cargar imágenes de 32 bits en el mapa de puntos del lado del servidor

X Error of failed request: BadMatch (invalid parameter attributes) 
    Major opcode of failed request: 72 (X_PutImage) 
    Serial number of failed request: 8 
    Current serial number in output stream: 8 

servidor hace de soporte de 32 bits mapas de píxeles (xdpyinfo de salida: https://gist.github.com/2582961). Mismo comportamiento en ubuntu 12.04 (versión X.Org: 1.11.3) y OSX con X.app (versión X.Org: 1.10.3)

¿Por qué falla el siguiente código?

#include  <stdlib.h> 
#include  <X11/Xlib.h> 

int main(int argc, char **argv) 
{ 
    int width = 100; 
    int height = 100; 
    int depth = 32; // works fine with depth = 24 
    int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16 
    int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next 
    Display *display=XOpenDisplay(0); 
    unsigned char *image32=(unsigned char *)malloc(width*height*4); 
    XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line); 
    Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth); 
    XPutImage(display, p, DefaultGC(display, 0), img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y 
    XEvent ev; 
    while (1) { 
     XNextEvent(display, &ev); 
    } 
} 

Actualización: Parece respuesta como finalmente conseguí: el uso de GC asociado con mapa de píxeles en lugar de DefaultGC (que tiene una profundidad de ventana raíz)

#include  <stdlib.h> 
#include  <X11/Xlib.h> 

int main(int argc, char **argv) 
{ 
    int width = 100; 
    int height = 100; 
    int depth = 32; // works fine with depth = 24 
    int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16 
    int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next 
    Display *display=XOpenDisplay(0); 
    unsigned char *image32=(unsigned char *)malloc(width*height*4); 
    XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line); 
    Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth); 
    XGCValues gcvalues; 
    GC gc = XCreateGC(display, p, 0, &gcvalues); 
    XPutImage(display, p, gc, img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y 
    XEvent ev; 
    while (1) { 
     XNextEvent(display, &ev); 
    } 
} 

Respuesta

2

Bueno, el código funciona para 32 bits de imágenes si usted acaba de crear un GC pasar un estirable sobre el argumento, que es de 32 bits. XCreateGC (dpy, dibujable, 0, 0), donde dibujable puede ser un mapa de píxeles con 32 bits de profundidad. Funciona perfecto conmigo.

+0

Ahora tengo un problema con el huevo y la gallina. Necesito 32 g de gc para crear un mapa de bits de 32 bits y un dibujo de 32 para crear 32 g de gc. ¿Tiene 32 bits de profundidad para el visual predeterminado? –

+0

Te responderé la próxima semana cuando vuelva a trabajar, porque ahora estoy de vacaciones. Voy a buscar eso está bien? – filipehd

+0

Gracias! Eso de ninguna manera es urgente –

5

El problema es con DefaultGC() que devuelven una GC con profundidad de bits de la pantalla predeterminada del sistema. Si nos fijamos en la línea 53 de la GIST pegar ves que esto es 24:

profundidad de la ventana raíz: 24 aviones

En la línea 63 se ve que se utiliza 0x22 como predeterminado que se muestra con más detalle en la línea 64 a 70:

visual: 
    visual id: 0x22 
    class: TrueColor 
    depth: 24 planes 
    available colormap entries: 256 per subfield 
    red, green, blue masks: 0xff0000, 0xff00, 0xff 
    significant bits in color specification: 8 bits 

que probablemente podría hacer esto un poco más agradable, sino como un inicio se puede probar esto:

Nota: este sistema utiliza imágenes de manera más p robably única profundidad apoyo de 24 o 32.

#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 


#ifdef DEBUG 
int dbg = 1; 
#else 
int dbg = 0; 
#endif 

/* Return a GC based on depth */ 
int gc_depth(int depth, Display *dpy, Window scr, Window root, GC *gc) 
{ 
     Window win; 
     Visual *visual; 
     XVisualInfo vis_info; 
     XSetWindowAttributes win_attr; 
     unsigned long win_mask; 

     if(!XMatchVisualInfo(dpy, scr, depth, TrueColor, &vis_info)) { 
       fprintf(stderr, 
         " * ERR: %d depth not supported\n", 
         depth 
       ); 
       return 1; 
     } 

     visual = vis_info.visual; 

     win_attr.colormap = XCreateColormap(dpy, root, visual, AllocNone); 
     win_attr.background_pixel = 0; 
     win_attr.border_pixel = 0; 

     win_mask = CWBackPixel | CWColormap | CWBorderPixel; 

     win = XCreateWindow(
         dpy, root, 
         0, 0, 
         100, 100,  /* dummy size */ 
         0, depth, 
         InputOutput, visual, 
         win_mask, &win_attr); 
     /* To flush out any errors */ 
     if (dbg) XSync(dpy, True); 

     *gc = XCreateGC(dpy, win, 0, 0); 
     if (dbg) XSync(dpy, True); 

     XDestroyWindow(dpy, win); 
     if (dbg) XSync(dpy, True); 

     return 0; 
} 

int main(void) 
{ 
     int w = 100; 
     int h = 100; 
     int depth = 32; 
     int bitmap_pad = 32; 
     int bpl = 0; 

     Display *dpy; 
     Window root; 
     Window scr; 
     GC gc; 
     int root_depth; 

     Pixmap pm; 
     XImage *img; 
     unsigned char *buf_img; 

     if(!(dpy = XOpenDisplay(NULL))) { 
       fprintf(stderr, 
         " * ERR: Failed to open display.\n"); 
       return 1; 
     } 

#ifdef DEBUG 
     /* To get errors in order, slows down 
     * One can also define int _Xdebug = 1; 
     * */ 
     XSynchronize(dpy, True); 
#endif 

     root = XDefaultRootWindow(dpy); 
     scr = XDefaultScreen(dpy); 

     if ((buf_img = malloc(w * h * 4)) == NULL) { 
       fprintf(stderr, 
         " * ERR: Unable to alloacte %d bytes\n", 
         w * h * 4); 
       return 1; 
     } 

     root_depth = DefaultDepth(dpy, scr); 

     fprintf(stderr, 
       "Default depth: %d\n", 
       root_depth); 

     /* This should be doen more nice */ 
     if (depth != root_depth) { 
       if (gc_depth(depth, dpy, scr, root, &gc) != 0) 
         return 1; 
     } else { 
       gc = DefaultGC(dpy, 0); 
     } 

     img = XCreateImage(
         dpy, CopyFromParent, 
         depth, ZPixmap, 
         0, (char *)buf_img, 
         w, h, 
         bitmap_pad, bpl); 
     /* To flush out any errors */ 
     if (dbg) XSync(dpy, True); 

     pm = XCreatePixmap(
         dpy, root, 
         w, h, 
         depth); 
     if (dbg) XSync(dpy, True); 

     XPutImage(
       dpy, pm, 
       gc, img, 
       0, 0, 
       0, 0, 
       w, h); 
     if (dbg) XSync(dpy, True); 

     XFreePixmap(dpy, pm); 
     XDestroyImage(img); 
     XFreeGC(dpy, gc); 
     if (dbg) XSync(dpy, True); 

     fprintf(stderr, 
       "OK!\n"); 

     return 0; 
} 
+0

Gracias! Desafortunadamente, su enfoque requiere una ventana visual de 32 bits (y una ventana ficticia de 32 bits de profundidad), que no está disponible en OSX (consulte mi dpyinfo). –

+0

@AndreySidorov: Sí, estaba a punto de publicarlo mientras leo su esencia con más cuidado. Gorrón. Tienes que preparar algo más entonces. De todos modos: el problema es más específico al menos. – Morpfh

+0

hasta donde yo sé, el GC no es específico para la profundidad (ninguno de los posibles atributos del GC se refiere a la profundidad). Desde el protocolo x11 Descripción de la solicitud de PutImage: componentes de GC: función, máscara de plano, modo de subventana, origen de clip-x, origen de clip y, clip-mask; Componentes dependientes del modo GC: primer plano, fondo –

Cuestiones relacionadas