2012-05-08 1 views
13

클라이언트 측 버퍼에서 서버 측 RGBA 픽스맵을 만들려고합니다. 일치 오류 32 및 24 비트에 대한 확인 CreatePixmap & createImage의 작업,하지만 XPutImage 결과는 서버에서 반환32 비트 이미지를 서버 측 픽스맵에 업로드하는 방법

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 

서버 지원 32 비트 픽스맵 (출력 xdpyinfo : https://gist.github.com/2582961)한다. 우분투 12.04 (X.Org 버전 : 1.11.3)와 X.app (X.Org 버전 : 1.10.3)를 사용하는 OSX에서 동일한 동작

왜 다음 코드가 실패합니까?

#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); 
    } 
} 

업데이트 : 내가 마지막으로 가지고 같은 대답을 보이는 : (루트 윈도우의 깊이) 대신 DefaultGC의 픽스맵과 관련된 사용 GC을 반환하는

#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); 
    } 
} 

답변

2

음의 robably 만 지원 깊이 코드는 32 개 비트 이미지를 사용할 수 있습니다. XCreateGC (dpy, drawable, 0, 0). drawable은 32 비트 깊이의 픽스맵이 될 수 있습니다. 그것은 나와 함께 완벽하게 작동합니다.

+0

이제 닭고기와 달걀 문제가 생겼습니다. 32 비트 그래픽을 만들기 위해서는 32 비트 gc가 필요하고 32 비트 gc를 만들려면 32 비트 드로어 블이 필요합니다. 기본 시각적으로 32 비트 깊이가 있습니까? –

+0

다음 주에 내가 다시 일하러 갈 때 나는 당신에게 대답 할 것이고, 이제 나는 휴가 중이다. 나는 그걸 찾을거야? – filipehd

+0

감사! 그게 절대로 급한 일이 아니야 –

5

문제는 DefaultGC()로입니다 시스템 기본 화면의 비트 심도가있는 GC 이 표시됩니다 기본값으로 0x22을 사용하는 24면 63 행에

당신이 볼 : 루트 창의

깊이 : 당신이 라인을 보면 당신의 요점의 (53)이 24 것을 볼 붙여 넣기 라인에서 더 자세히 64 ~ 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 

당신은 아마 조금 더 좋은이 작업을 수행 할 수 있지만, 시작 당신이 시도 할 수 있습니다 :

주 : 이것은 대부분의 페이지 수 있도록 시스템의 영상을 사용 당신은 단지 32 비트 인수에 드로어 블을 통과하는 GC를 만들 경우 24 또는 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

고마워요! 불행히도, 당신의 접근 방식은 32 비트 비쥬얼 (그리고 더미 32 비트 심도 윈도우)을 필요로합니다. OSX에서는 사용할 수 없습니다 (내 dpyinfo 참조). –

+0

@AndreySidorov : 예, 나는 당신의 요지를 더 조심스럽게 읽으면서 그것을 게시하려하고있었습니다. 파머. 그때 다른 것을 채찍질해야합니다. 어쨌든 : 문제는 적어도 지정되어 있습니다. – Morpfh

+0

내가 아는 한 GC는 깊이와 관련이 없습니다 (가능한 GC 속성 중 어느 것도 깊이를 참조하지 않습니다). x11 프로토콜에서 PutImage 요청 설명 : GC 구성 요소 : 기능, 플레인 마스크, 서브 윈도우 모드, 클립 -x- 원점, 클립 -y- 원점, 클립 마스크. GC 모드 종속 구성 요소 : 전경, 배경 –

관련 문제