diff options
| author | Manolo Gouy <Manolo> | 2016-04-03 06:51:09 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2016-04-03 06:51:09 +0000 |
| commit | f1ffe2f1fee001ffb3c9327c6c09f5e5d9dc91de (patch) | |
| tree | 58a67c3e8a8f8d651e358efc70d04747321c251b /src/drivers | |
| parent | c88af210e775d90d2537f4277909bb081a9c064a (diff) | |
Rewrite fl_read_image.cxx under the driver model.
Files fl_read_image_mac.cxx and fl_read_image_win32.cxx are no longer used;
their content is now in Fl_XXX_Screen_Driver.cxx
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11516 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 45 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 100 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 456 |
6 files changed, 604 insertions, 0 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H index 59cd6ce1e..3f475a637 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H @@ -86,6 +86,7 @@ public: int insertion_point_location(int *px, int *py, int *pheight); virtual int dnd(int use_selection); virtual int compose(int &del); + virtual uchar *read_image(uchar *p, int x, int y, int w, int h, int alpha); }; diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index 2c9f693fc..c23046e30 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -325,6 +325,51 @@ void Fl_Screen_Driver::font_name(int num, const char *name) { s->first = 0; } +uchar * // O - Pixel buffer or NULL if failed +Fl_Cocoa_Screen_Driver::read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int x, // I - Left position + int y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) // I - Alpha value for image (0 for none) +{ + uchar *base; + int rowBytes, delta; + if (fl_window == NULL) { // reading from an offscreen buffer + CGContextRef src = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc(); // get bitmap context + base = (uchar *)CGBitmapContextGetData(src); // get data + if(!base) return NULL; + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + rowBytes = CGBitmapContextGetBytesPerRow(src); + delta = CGBitmapContextGetBitsPerPixel(src)/8; + if( (sw - x < w) || (sh - y < h) ) return NULL; + } + else { // reading from current window + base = Fl_X::bitmap_from_window_rect(Fl_Window::current(),x,y,w,h,&delta); + if (!base) return NULL; + rowBytes = delta*w; + x = y = 0; + } + // Allocate the image data array as needed... + int d = alpha ? 4 : 3; + if (!p) p = new uchar[w * h * d]; + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + // Copy the image from the off-screen buffer to the memory buffer. + int idx, idy; // Current X & Y in image + uchar *pdst, *psrc; + for (idy = y, pdst = p; idy < h + y; idy ++) { + for (idx = 0, psrc = base + idy * rowBytes + x * delta; idx < w; idx ++, psrc += delta, pdst += d) { + pdst[0] = psrc[0]; // R + pdst[1] = psrc[1]; // G + pdst[2] = psrc[2]; // B + } + } + if(fl_window != NULL) delete[] base; + return p; +} + // // End of "$Id$". // diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H index f874750a7..a8c530fbe 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H @@ -71,6 +71,7 @@ public: virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp); virtual int dnd(int unused); virtual int compose(int &del); + virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); }; diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index 7dd7df843..bf49eebd8 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -553,6 +553,106 @@ void Fl_Screen_Driver::font_name(int num, const char *name) { s->first = 0; } + +uchar * // O - Pixel buffer or NULL if failed +Fl_WinAPI_Screen_Driver::read_win_rectangle(uchar *p, // I - Pixel buffer or NULL to allocate + int X, // I - Left position + int Y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) // I - Alpha value for image (0 for none) +{ + int d; // Depth of image + + // Allocate the image data array as needed... + d = alpha ? 4 : 3; + + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Grab all of the pixels in the image... + + // Assure that we are not trying to read non-existing data. If it is so, the + // function should still work, but the out-of-bounds part of the image is + // untouched (initialized with the alpha value or 0 (black), resp.). + + int ww = w; // We need the original width for output data line size + + int shift_x = 0; // X target shift if X modified + int shift_y = 0; // Y target shift if X modified + + if (X < 0) { + shift_x = -X; + w += X; + X = 0; + } + if (Y < 0) { + shift_y = -Y; + h += Y; + Y = 0; + } + + if (h < 1 || w < 1) return p; // nothing to copy + + int line_size = ((3*w+3)/4) * 4; // each line is aligned on a DWORD (4 bytes) + uchar *dib = new uchar[line_size*h]; // create temporary buffer to read DIB + + // fill in bitmap info for GetDIBits + + BITMAPINFO bi; + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = w; + bi.bmiHeader.biHeight = -h; // negative => top-down DIB + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 24; // 24 bits RGB + bi.bmiHeader.biCompression = BI_RGB; + bi.bmiHeader.biSizeImage = 0; + bi.bmiHeader.biXPelsPerMeter = 0; + bi.bmiHeader.biYPelsPerMeter = 0; + bi.bmiHeader.biClrUsed = 0; + bi.bmiHeader.biClrImportant = 0; + + // copy bitmap from original DC (Window, Fl_Offscreen, ...) + HDC gc = (HDC)fl_graphics_driver->gc(); + HDC hdc = CreateCompatibleDC(gc); + HBITMAP hbm = CreateCompatibleBitmap(gc,w,h); + + int save_dc = SaveDC(hdc); // save context for cleanup + SelectObject(hdc,hbm); // select bitmap + BitBlt(hdc,0,0,w,h,gc,X,Y,SRCCOPY); // copy image section to DDB + + // copy RGB image data to the allocated DIB + + GetDIBits(hdc, hbm, 0, h, dib, (BITMAPINFO *)&bi, DIB_RGB_COLORS); + + // finally copy the image data to the user buffer + + for (int j = 0; j<h; j++) { + const uchar *src = dib + j * line_size; // source line + uchar *tg = p + (j + shift_y) * d * ww + shift_x * d; // target line + for (int i = 0; i<w; i++) { + uchar b = *src++; + uchar g = *src++; + *tg++ = *src++; // R + *tg++ = g; // G + *tg++ = b; // B + if (alpha) + *tg++ = alpha; // alpha + } + } + + // free used GDI and other structures + + RestoreDC(hdc,save_dc); // reset DC + DeleteDC(hdc); + DeleteObject(hbm); + delete[] dib; // delete DIB temporary buffer + + return p; +} + // // End of "$Id$". //
\ No newline at end of file diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H index 2f89eaabf..f639fd6cb 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.H +++ b/src/drivers/X11/Fl_X11_Screen_Driver.H @@ -77,6 +77,7 @@ public: virtual int compose(int &del); virtual void compose_reset(); virtual int text_display_can_leak(); + virtual uchar *read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha); }; diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index 50623664e..9e7c68af4 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -34,6 +34,17 @@ #include <X11/extensions/Xdbe.h> #endif +# include <X11/Xutil.h> +# ifdef __sgi +# include <X11/extensions/readdisplay.h> +# else +# include <stdlib.h> +# endif // __sgi + +#ifdef DEBUG +# include <stdio.h> +#endif // DEBUG + extern Atom fl_NET_WORKAREA; extern XIC fl_xim_ic; // in Fl_x.cxx @@ -666,5 +677,450 @@ void Fl_Screen_Driver::font_name(int num, const char *name) { } // +// 'fl_subimage_offsets()' - Calculate subimage offsets for an axis +static inline int +fl_subimage_offsets(int a, int aw, int b, int bw, int &obw) +{ + int off; + int ob; + + if (b >= a) { + ob = b; + off = 0; + } else { + ob = a; + off = a - b; + } + + bw -= off; + + if (ob + bw <= a + aw) { + obw = bw; + } else { + obw = (a + aw) - ob; + } + + return off; +} + +// this handler will catch and ignore exceptions during XGetImage +// to avoid an application crash +extern "C" { + static int xgetimageerrhandler(Display *display, XErrorEvent *error) { + return 0; + } +} + +uchar *Fl_X11_Screen_Driver::read_win_rectangle(uchar *p, int X, int Y, int w, int h, int alpha) +{ + XImage *image; // Captured image + int i, maxindex; // Looping vars + int x, y; // Current X & Y in image + int d; // Depth of image + unsigned char *line, // Array to hold image row + *line_ptr; // Pointer to current line image + unsigned char *pixel; // Current color value + XColor colors[4096]; // Colors from the colormap... + unsigned char cvals[4096][3]; // Color values from the colormap... + unsigned index_mask, + index_shift, + red_mask, + red_shift, + green_mask, + green_shift, + blue_mask, + blue_shift; + // + // Under X11 we have the option of the XGetImage() interface or SGI's + // ReadDisplay extension which does all of the really hard work for + // us... + // + int allow_outside = w < 0; // negative w allows negative X or Y, that is, window frame + if (w < 0) w = - w; + +# ifdef __sgi + if (XReadDisplayQueryExtension(fl_display, &i, &i)) { + image = XReadDisplay(fl_display, fl_window, X, Y, w, h, 0, NULL); + } else +# else + image = 0; +# endif // __sgi + + if (!image) { + // fetch absolute coordinates + int dx, dy, sx, sy, sw, sh; + Window child_win; + + Fl_Window *win; + if (allow_outside) win = (Fl_Window*)1; + else win = fl_find(fl_window); + if (win) { + XTranslateCoordinates(fl_display, fl_window, + RootWindow(fl_display, fl_screen), X, Y, &dx, &dy, &child_win); + // screen dimensions + Fl::screen_xywh(sx, sy, sw, sh, fl_screen); + } + if (!win || (dx >= sx && dy >= sy && dx + w <= sx+sw && dy + h <= sy+sh)) { + // the image is fully contained, we can use the traditional method + // however, if the window is obscured etc. the function will still fail. Make sure we + // catch the error and continue, otherwise an exception will be thrown. + XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); + image = XGetImage(fl_display, fl_window, X, Y, w, h, AllPlanes, ZPixmap); + XSetErrorHandler(old_handler); + } else { + // image is crossing borders, determine visible region + int nw, nh, noffx, noffy; + noffx = fl_subimage_offsets(sx, sw, dx, w, nw); + noffy = fl_subimage_offsets(sy, sh, dy, h, nh); + if (nw <= 0 || nh <= 0) return 0; + + // allocate the image + int bpp = fl_visual->depth + ((fl_visual->depth / 8) % 2) * 8; + char* buf = (char*)malloc(bpp / 8 * w * h); + image = XCreateImage(fl_display, fl_visual->visual, + fl_visual->depth, ZPixmap, 0, buf, w, h, bpp, 0); + if (!image) { + if (buf) free(buf); + return 0; + } + + XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); + XImage *subimg = XGetSubImage(fl_display, fl_window, X + noffx, Y + noffy, + nw, nh, AllPlanes, ZPixmap, image, noffx, noffy); + XSetErrorHandler(old_handler); + if (!subimg) { + XDestroyImage(image); + return 0; + } + } + } + + if (!image) return 0; + +#ifdef DEBUG + printf("width = %d\n", image->width); + printf("height = %d\n", image->height); + printf("xoffset = %d\n", image->xoffset); + printf("format = %d\n", image->format); + printf("data = %p\n", image->data); + printf("byte_order = %d\n", image->byte_order); + printf("bitmap_unit = %d\n", image->bitmap_unit); + printf("bitmap_bit_order = %d\n", image->bitmap_bit_order); + printf("bitmap_pad = %d\n", image->bitmap_pad); + printf("depth = %d\n", image->depth); + printf("bytes_per_line = %d\n", image->bytes_per_line); + printf("bits_per_pixel = %d\n", image->bits_per_pixel); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); + printf("map_entries = %d\n", fl_visual->visual->map_entries); +#endif // DEBUG + + d = alpha ? 4 : 3; + + // Allocate the image data array as needed... + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Check that we have valid mask/shift values... + if (!image->red_mask && image->bits_per_pixel > 12) { + // Greater than 12 bits must be TrueColor... + image->red_mask = fl_visual->visual->red_mask; + image->green_mask = fl_visual->visual->green_mask; + image->blue_mask = fl_visual->visual->blue_mask; + +#ifdef DEBUG + // Defined in Fl_Xlib_Graphics_Driver_color.cxx + extern uchar fl_redmask, fl_greenmask, fl_bluemask; + extern int fl_redshift, fl_greenshift, fl_blueshift; + puts("\n---- UPDATED ----"); + printf("fl_redmask = %08x\n", fl_redmask); + printf("fl_redshift = %d\n", fl_redshift); + printf("fl_greenmask = %08x\n", fl_greenmask); + printf("fl_greenshift = %d\n", fl_greenshift); + printf("fl_bluemask = %08x\n", fl_bluemask); + printf("fl_blueshift = %d\n", fl_blueshift); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); +#endif // DEBUG + } + + // Check if we have colormap image... + if (!image->red_mask) { + // Get the colormap entries for this window... + maxindex = fl_visual->visual->map_entries; + + for (i = 0; i < maxindex; i ++) colors[i].pixel = i; + + XQueryColors(fl_display, fl_colormap, colors, maxindex); + + for (i = 0; i < maxindex; i ++) { + cvals[i][0] = colors[i].red >> 8; + cvals[i][1] = colors[i].green >> 8; + cvals[i][2] = colors[i].blue >> 8; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 1 : + for (x = image->width, line_ptr = line, index_mask = 128; + x > 0; + x --, line_ptr += d) { + if (*pixel & index_mask) { + line_ptr[0] = cvals[1][0]; + line_ptr[1] = cvals[1][1]; + line_ptr[2] = cvals[1][2]; + } else { + line_ptr[0] = cvals[0][0]; + line_ptr[1] = cvals[0][1]; + line_ptr[2] = cvals[0][2]; + } + + if (index_mask > 1) { + index_mask >>= 1; + } else { + index_mask = 128; + pixel ++; + } + } + break; + + case 2 : + for (x = image->width, line_ptr = line, index_shift = 6; + x > 0; + x --, line_ptr += d) { + i = (*pixel >> index_shift) & 3; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_mask >>= 2; + index_shift -= 2; + } else { + index_mask = 192; + index_shift = 6; + pixel ++; + } + } + break; + + case 4 : + for (x = image->width, line_ptr = line, index_shift = 4; + x > 0; + x --, line_ptr += d) { + if (index_shift == 4) i = (*pixel >> 4) & 15; + else i = *pixel & 15; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_shift = 0; + } else { + index_shift = 4; + pixel ++; + } + } + break; + + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + line_ptr[0] = cvals[*pixel][0]; + line_ptr[1] = cvals[*pixel][1]; + line_ptr[2] = cvals[*pixel][2]; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + } + } + } else { + // RGB(A) image, so figure out the shifts & masks... + red_mask = image->red_mask; + red_shift = 0; + + while ((red_mask & 1) == 0) { + red_mask >>= 1; + red_shift ++; + } + + green_mask = image->green_mask; + green_shift = 0; + + while ((green_mask & 1) == 0) { + green_mask >>= 1; + green_shift ++; + } + + blue_mask = image->blue_mask; + blue_shift = 0; + + while ((blue_mask & 1) == 0) { + blue_mask >>= 1; + blue_shift ++; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + i = *pixel; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + + case 16 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[1] << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[0] << 8) | pixel[1]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 24 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[2] << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 32 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[3] << 8) | pixel[2]) << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]) << 8) | pixel[3]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + } + } + } + + // Destroy the X image we've read and return the RGB(A) image... + XDestroyImage(image); + + return p; +} + +// // End of "$Id$". // |
