2012-05-08 11 views
13

पर 32 बिट छवि को अपलोड करने के लिए मैं क्लाइंट-साइड बफर से सर्वर-साइड आरजीबीए पिक्समैप बनाने की कोशिश कर रहा हूं। CreatePixmap & CreateImage काम 32 और 24 बिट के लिए ठीक है, लेकिन मैच त्रुटि में XPutImage परिणाम सर्वर द्वारा लौटाएसर्वर-साइड पिक्समैप

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 (एक्स.ऑर्ग संस्करण: 1.11.3) और ओएसएक्स एक्स.एप (एक्स.ऑर्ग संस्करण: 1.10.3)

पर निम्नलिखित व्यवहार क्यों विफल रहता है?

#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 के बजाय पिक्समैप के साथ जुड़े (जो जड़ खिड़की की गहराई है)

#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 बिट छवियों के लिए कार्य करता है, तो आप सिर्फ एक जीसी तर्क जो 32 बिट है पर एक drawable गुजर पैदा करते हैं। XCreateGC (dpy, drawable, 0, 0), जहां ड्रॉबल 32 बिट गहराई के साथ एक पिक्समैप हो सकता है। यह मेरे साथ सही काम करता है।

+0

अब मेरे पास चिकन और अंडे की समस्या है - 32 बिट जीसी बनाने के लिए 32 बिट पिक्समैप और 32 बिट ड्रॉबल बनाने के लिए मुझे 32 बिट जीसी की आवश्यकता है। क्या आपके पास डिफ़ॉल्ट दृश्य के लिए 32 बिट गहराई है? –

+0

मैं अगले सप्ताह आपको जवाब दूंगा जब मैं फिर से काम पर वापस जाऊंगा, क्योंकि अब मैं छुट्टियों पर हूं। मैं ठीक हूँ? – filipehd

+0

धन्यवाद! इसका कोई मतलब नहीं है –

5

समस्या DefaultGC() साथ है जो एक वापसी सिस्टम डिफ़ॉल्ट स्क्रीन की बिट गहराई के साथ जीसी।

जड़ खिड़की की गहराई: आप लाइन को देखें, तो अपने सार के 53 आप देखते हैं कि यह 24 है पेस्ट 24 विमानों

लाइन 63 पर आप देखते हैं कि यह जो दिखाया गया है डिफ़ॉल्ट के रूप में 0x22 का उपयोग करता है लाइन में और अधिक विस्तार 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 

आप शायद इस एक सा अच्छे से कर सकता है, लेकिन एक शुरुआत के रूप में आप यह कोशिश कर सकते हैं:

नोट: यह प्रणाली दृश्यों का उपयोग करता है, इसलिए अधिकांश पी 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 बिट गहराई खिड़की) की आवश्यकता है, जो ओएसएक्स पर उपलब्ध नहीं है (मेरे dpyinfo देखें)। –

+0

@AndreySidorov: हाँ, मैं इसे पोस्ट करने के बारे में सोच रहा था क्योंकि मैंने आपकी जिंद को अधिक सावधानी से पढ़ा था। ओह। फिर कुछ और चाबुक करना है। वैसे भी: समस्या कम से कम निर्दिष्ट है। जहां तक ​​मुझे पता है, – Morpfh

+0

, जीसी गहराई के लिए विशिष्ट नहीं है (संभावित जीसी विशेषताओं में से कोई भी गहराई का संदर्भ नहीं देता है)। X11 प्रोटोकॉल PutImage अनुरोध विवरण से: जीसी घटक: फ़ंक्शन, प्लेन-मास्क, सबविंडो-मोड, क्लिप-एक्स-उत्पत्ति, क्लिप-वाई-उत्पत्ति, क्लिप-मास्क; जीसी मोड-निर्भर घटक: अग्रभूमि, पृष्ठभूमि –

संबंधित मुद्दे