LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to change the bit-depth of XGetImage, Xlib ? (https://www.linuxquestions.org/questions/programming-9/how-to-change-the-bit-depth-of-xgetimage-xlib-722207/)

noob1 04-28-2009 05:50 AM

How to change the bit-depth of XGetImage, Xlib ?
 
Hello, I am trying to use Xlib to capture the screen, this is what I have so far and it's working fine:

PHP Code:

Display *dpy XOpenDisplay(NULL);
Window root DefaultRootWindow(dpy);        
XImage *img=XGetImage(dpyroot00WIDTHHEIGHTAllPlanesZPixmap);    
printf("bpp %d depth %d\n"img->bits_per_pixelimg->depth); 

However, I need to control the depth, for example, I need to capture a 8, 16, 24, 32 bit image, I think I need to change the plane-mask, the problem is I don't really understand what a plane-mask is (tried the manual, google no luck), so can anyone explain to me what a plane-mask is and how to use it to change the depth ?


P.S.

The above code prints
PHP Code:

bpp 32 depth 24 

Which I don't understand either, because I thought that the bpp and depth are the same, right ?

fantas 04-29-2009 10:52 AM

I'm not pretending to be an expert here, but from what the Xlib programming manual hints at, the plane_mask (if used with the XYPixmap format), specifies the number of bits. So for example, if you want a 24-bit image, you use

XGetImage(display, pixmap, 0, 0, w, h, 0x00ffffff, XYPixmap);

where 24 bits of the plane_mask parameter are set.
The bits per pixels will probably be filled out automatically and rounded up to a value that is usable for the X11 server. This should be quite easy and fun to try out ! :)

noob1 04-29-2009 01:40 PM

Quote:

Originally Posted by fantas (Post 3524852)
the plane_mask (if used with the XYPixmap format), specifies the number of bits.

Thanks for the reply :), I did some experiments like you said, I tried 0x00f0f0f0 for 12 bits and seems okay, except that when I use XYPixmap the image is all scrambled up (I'm using opengl to draw the image), here's all the code I have so far:


PHP Code:

#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/freeglut.h>
#include <unistd.h>
#include <stdio.h>

#define WIDTH    800
#define HEIGHT    600
#define DEPTH    4
#define DEPTH8    0x00e0e0c0
#define DEPTH12    0x00f0f0f0
#define DEPTH16    0x00f1f1f1
#define DEPTH24    0x00ffffff
#define DEPTH32    0xffffffff

void render();

int main(int argcchar **argv)
{
    
glutInit(&argcargv);
    
glutInitDisplayMode(GLUT_RGB GLUT_DOUBLE);
    
glutInitWindowSize(WIDTHHEIGHT);
    
glClearColor(0.0f0.0f0.0f0.0f);

    
glutCreateWindow("GLUT");

    
glutDisplayFunc(&render);
    
    
glutMainLoop();
    
//while(1)
    //{
    //    usleep(100);
    //    glutMainLoopEvent();
    //}
    
return 0;
}

void render(void)
{
    
Display *dpy XOpenDisplay(NULL);
    
Window root DefaultRootWindow(dpy);    
    
XImage *img=XGetImage(dpyroot00WIDTHHEIGHTDEPTH12ZPixmap);
    
    
printf("bpp %d depth %d\n"img->bits_per_pixelimg->depth);    

    
    
glClear(GL_COLOR_BUFFER_BIT);
    
glRasterPos2i(-1,1);        
    
glPixelZoom(1.0f, -1.0f); 
    
glDrawPixels(WIDTHHEIGHTGL_BGRAGL_UNSIGNED_BYTEimg->data);
    
glutSwapBuffers();
    
    
XDestroyImage(img);
    
XCloseDisplay(dpy);



fantas 04-29-2009 02:22 PM

If you are requesting an 12-bit image, the data may actually only consist of 16-bit data (rounded by X11), so be careful if you pass this to OpenGL, which will expect the data type you are specifying (like B8G8R8A8 in your example), and this can be quite different and lead to memory corruption.

So best to check the bytes_per_line (= bytes per one row of bytes in the image) of the returned XImage. If this is less than you need to pass to GL, you may have to work on a temporary buffer and pass this to OpenGL for rendering. For >= 24-bit images this is probably not necessary.

noob1 04-29-2009 04:38 PM

Quote:

Originally Posted by fantas (Post 3525036)
If you are requesting an 12-bit image, the data may actually only consist of 16-bit data (rounded by X11), so be careful if you pass this to OpenGL

I am not sure about the rounding up, but anyway, that's true if you use a XYPixmap, however, if you use a ZPixmap you get all of the 32 bits (the ones you don't set in the plane-mask are zeros), which I think I can live with, because I plan to compress the data anyways.


Thanks again for the help :)

fantas 04-29-2009 07:56 PM

So the scrambling with the XYPixmap you mentioned before should be expĺained now, or not ? :)

noob1 04-30-2009 04:22 PM

Quote:

Originally Posted by fantas (Post 3525246)
So the scrambling with the XYPixmap you mentioned before should be expĺained now, or not ? :)

Yes it's very clear now, I just hate doing stuff without really understanding what I'm doing :).

I've been reading about the XYPixmap, I'm not sure, but, it seems that it stores all red pixels first then all green pixels then all blue pixels.


All times are GMT -5. The time now is 03:48 PM.