Alexandre Julliard : winex11: Add a helper to create a pixmap from an image .
Alexandre Julliard
julliard at winehq.org
Tue May 15 12:55:59 CDT 2012
Module: wine
Branch: master
Commit: 3e8ad9a064cfce36752233a7a7439b11dac01074
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3e8ad9a064cfce36752233a7a7439b11dac01074
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri May 11 13:48:19 2012 +0200
winex11: Add a helper to create a pixmap from an image.
---
dlls/winex11.drv/bitblt.c | 126 +++++++++++++++++++++++++++++++++++++++++++++
dlls/winex11.drv/x11drv.h | 2 +
2 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 413f4e4..6dec77f 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -937,6 +937,16 @@ static void free_ximage_bits( struct gdi_image_bits *bits )
wine_tsx11_unlock();
}
+/* only for use on sanitized BITMAPINFO structures */
+static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
+{
+ if (info->bmiHeader.biCompression == BI_BITFIELDS)
+ return sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
+ if (coloruse == DIB_PAL_COLORS)
+ return sizeof(BITMAPINFOHEADER) + info->bmiHeader.biClrUsed * sizeof(WORD);
+ return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
+}
+
/* store the palette or color mask data in the bitmap info structure */
static void set_color_info( const XVisualInfo *vis, BITMAPINFO *info )
{
@@ -1464,6 +1474,122 @@ DWORD X11DRV_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
/***********************************************************************
+ * put_pixmap_image
+ *
+ * Simplified equivalent of X11DRV_PutImage that writes directly to a pixmap.
+ */
+static DWORD put_pixmap_image( Pixmap pixmap, const XVisualInfo *vis,
+ BITMAPINFO *info, const struct gdi_image_bits *bits )
+{
+ DWORD ret;
+ XImage *image;
+ struct bitblt_coords coords;
+ struct gdi_image_bits dst_bits;
+ const XPixmapFormatValues *format = pixmap_formats[vis->depth];
+ const int *mapping = NULL;
+
+ if (!format) return ERROR_INVALID_PARAMETER;
+ if (info->bmiHeader.biPlanes != 1) goto update_format;
+ if (info->bmiHeader.biBitCount != format->bits_per_pixel) goto update_format;
+ /* FIXME: could try to handle 1-bpp using XCopyPlane */
+ if (!matching_color_info( vis, info )) goto update_format;
+ if (!bits) return ERROR_SUCCESS; /* just querying the format */
+
+ coords.x = 0;
+ coords.y = 0;
+ coords.width = info->bmiHeader.biWidth;
+ coords.height = abs( info->bmiHeader.biHeight );
+ SetRect( &coords.visrect, 0, 0, coords.width, coords.height );
+
+ wine_tsx11_lock();
+ image = XCreateImage( gdi_display, visual, vis->depth, ZPixmap, 0, NULL,
+ coords.width, coords.height, 32, 0 );
+ wine_tsx11_unlock();
+ if (!image) return ERROR_OUTOFMEMORY;
+
+ if (image->bits_per_pixel == 4 || image->bits_per_pixel == 8)
+ mapping = X11DRV_PALETTE_PaletteToXPixel;
+
+ if (!(ret = copy_image_bits( info, is_r8g8b8(vis), image, bits, &dst_bits, &coords, mapping, ~0u )))
+ {
+ image->data = dst_bits.ptr;
+ wine_tsx11_lock();
+ XPutImage( gdi_display, pixmap, get_bitmap_gc( vis->depth ),
+ image, 0, 0, 0, 0, coords.width, coords.height );
+ wine_tsx11_unlock();
+ image->data = NULL;
+ }
+
+ wine_tsx11_lock();
+ XDestroyImage( image );
+ wine_tsx11_unlock();
+ if (dst_bits.free) dst_bits.free( &dst_bits );
+ return ret;
+
+update_format:
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = format->bits_per_pixel;
+ if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
+ set_color_info( vis, info );
+ return ERROR_BAD_FORMAT;
+}
+
+
+/***********************************************************************
+ * create_pixmap_from_image
+ */
+Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const BITMAPINFO *info,
+ const struct gdi_image_bits *bits, UINT coloruse )
+{
+ static const RGBQUAD default_colortable[2] = { { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff } };
+ char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+ char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+ BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
+ BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
+ struct gdi_image_bits dst_bits;
+ Pixmap pixmap;
+ DWORD err;
+ HBITMAP dib;
+
+ wine_tsx11_lock();
+ pixmap = XCreatePixmap( gdi_display, root_window,
+ info->bmiHeader.biWidth, abs(info->bmiHeader.biHeight), vis->depth );
+ wine_tsx11_unlock();
+ if (!pixmap) return 0;
+
+ memcpy( src_info, info, get_dib_info_size( info, coloruse ));
+ memcpy( dst_info, info, get_dib_info_size( info, coloruse ));
+
+ if (coloruse == DIB_PAL_COLORS ||
+ (err = put_pixmap_image( pixmap, vis, dst_info, bits )) == ERROR_BAD_FORMAT)
+ {
+ if (dst_info->bmiHeader.biBitCount == 1) /* set a default color table for 1-bpp */
+ memcpy( dst_info->bmiColors, default_colortable, sizeof(default_colortable) );
+ dib = CreateDIBSection( hdc, dst_info, coloruse, &dst_bits.ptr, 0, 0 );
+ if (dib)
+ {
+ if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed)
+ memcpy( src_info->bmiColors, default_colortable, sizeof(default_colortable) );
+ SetDIBits( hdc, dib, 0, abs(info->bmiHeader.biHeight), bits->ptr, src_info, coloruse );
+ dst_bits.free = NULL;
+ dst_bits.is_copy = TRUE;
+ err = put_pixmap_image( pixmap, vis, dst_info, &dst_bits );
+ DeleteObject( dib );
+ }
+ else err = ERROR_OUTOFMEMORY;
+ }
+
+ if (!err) return pixmap;
+
+ wine_tsx11_lock();
+ XFreePixmap( gdi_display, pixmap );
+ wine_tsx11_unlock();
+ return 0;
+
+}
+
+
+/***********************************************************************
* get_pixmap_image
*
* Equivalent of X11DRV_GetImage that reads directly from a pixmap.
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index d17565b..7ed4bdd 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -229,6 +229,8 @@ extern Pixmap X11DRV_get_pixmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
struct bitblt_coords *coords, const int *mapping, unsigned int zeropad_mask ) DECLSPEC_HIDDEN;
+extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const BITMAPINFO *info,
+ const struct gdi_image_bits *bits, UINT coloruse ) DECLSPEC_HIDDEN;
extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list