Alexandre Julliard : gdi32: Implement GetImage in the DIB driver.
Alexandre Julliard
julliard at winehq.org
Tue Jul 26 11:37:52 CDT 2011
Module: wine
Branch: master
Commit: dcfe0c48ead211c1d4cd30ae6ba4743d97c3f7e0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dcfe0c48ead211c1d4cd30ae6ba4743d97c3f7e0
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jul 25 15:30:33 2011 +0200
gdi32: Implement GetImage in the DIB driver.
---
dlls/gdi32/dib.c | 9 +---
dlls/gdi32/dibdrv/dc.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 123 insertions(+), 12 deletions(-)
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 4f5b970..94a69a7 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -1032,18 +1032,12 @@ INT WINAPI GetDIBits(
if (bits && lines)
{
- PHYSDEV physdev;
char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
struct gdi_image_bits src_bits;
struct bitblt_coords src;
DWORD err;
- /* FIXME: will need updating once the dib driver has pGetImage. */
- physdev = GET_DC_PHYSDEV( dc, pGetImage );
-
- if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
-
src.visrect.left = 0;
src.visrect.right = min( width, bmp->bitmap.bmWidth );
@@ -1062,8 +1056,7 @@ INT WINAPI GetDIBits(
src.width = src.visrect.right - src.visrect.left;
src.height = src.visrect.bottom - src.visrect.top;
- err = physdev->funcs->pGetImage( physdev, hbitmap, src_info, &src_bits, &src );
-
+ err = bmp->funcs->pGetImage( NULL, hbitmap, src_info, &src_bits, &src );
if(err)
{
lines = 0;
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index c78a111..eaa187f 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -27,6 +27,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(dib);
+static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
+static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
+
static void calc_shift_and_len(DWORD mask, int *shift, int *len)
{
int s, l;
@@ -66,9 +69,6 @@ static void init_bit_fields(dib_info *dib, const DWORD *bit_fields)
static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
RGBQUAD *color_table, int color_table_size, void *bits, enum dib_info_flags flags)
{
- static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
- static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
-
dib->bit_count = bi->biBitCount;
dib->width = bi->biWidth;
dib->height = bi->biHeight;
@@ -313,6 +313,124 @@ static BOOL dibdrv_DeleteDC( PHYSDEV dev )
}
/***********************************************************************
+ * dibdrv_GetImage
+ */
+static DWORD dibdrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
+ struct gdi_image_bits *bits, struct bitblt_coords *src )
+{
+ TRACE( "%p %p %p\n", dev, hbitmap, info );
+
+ info->bmiHeader.biSize = sizeof(info->bmiHeader);
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+
+ if (hbitmap)
+ {
+ BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
+
+ if (!bmp) return ERROR_INVALID_HANDLE;
+ assert(bmp->dib);
+
+ info->bmiHeader.biWidth = bmp->dib->dsBmih.biWidth;
+ info->bmiHeader.biHeight = bmp->dib->dsBmih.biHeight;
+ info->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
+ info->bmiHeader.biSizeImage = get_dib_image_size( (BITMAPINFO *)&bmp->dib->dsBmih );
+
+ switch (info->bmiHeader.biBitCount)
+ {
+ case 1:
+ case 4:
+ case 8:
+ if (bmp->color_table)
+ {
+ info->bmiHeader.biClrUsed = min( bmp->nb_colors, 1 << info->bmiHeader.biBitCount );
+ memcpy( info->bmiColors, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) );
+ }
+ break;
+ case 16:
+ if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS &&
+ memcmp( bmp->dib->dsBitfields, bit_fields_555, sizeof(bmp->dib->dsBitfields) ))
+ {
+ info->bmiHeader.biCompression = BI_BITFIELDS;
+ memcpy( info->bmiColors, bmp->dib->dsBitfields, sizeof(bmp->dib->dsBitfields) );
+ }
+ break;
+ case 32:
+ if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS &&
+ memcmp( bmp->dib->dsBitfields, bit_fields_888, sizeof(bmp->dib->dsBitfields) ))
+ {
+ info->bmiHeader.biCompression = BI_BITFIELDS;
+ memcpy( info->bmiColors, bmp->dib->dsBitfields, sizeof(bmp->dib->dsBitfields) );
+ }
+ break;
+ }
+ if (bits)
+ {
+ bits->ptr = bmp->dib->dsBm.bmBits;
+ bits->is_copy = FALSE;
+ bits->free = NULL;
+ }
+ GDI_ReleaseObj( hbitmap );
+ }
+ else
+ {
+ dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+
+ info->bmiHeader.biWidth = pdev->dib.width;
+ info->bmiHeader.biHeight = pdev->dib.stride > 0 ? -pdev->dib.height : pdev->dib.height;
+ info->bmiHeader.biBitCount = pdev->dib.bit_count;
+ info->bmiHeader.biSizeImage = pdev->dib.height * abs(pdev->dib.stride);
+
+ switch (info->bmiHeader.biBitCount)
+ {
+ case 1:
+ case 4:
+ case 8:
+ if (pdev->dib.color_table)
+ {
+ info->bmiHeader.biClrUsed = min( pdev->dib.color_table_size, 1 << pdev->dib.bit_count );
+ memcpy( info->bmiColors, pdev->dib.color_table,
+ info->bmiHeader.biClrUsed * sizeof(RGBQUAD) );
+ }
+ break;
+ case 16:
+ if (pdev->dib.funcs != &funcs_555)
+ {
+ DWORD *masks = (DWORD *)info->bmiColors;
+ masks[0] = pdev->dib.red_mask;
+ masks[1] = pdev->dib.green_mask;
+ masks[2] = pdev->dib.blue_mask;
+ info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ break;
+ case 32:
+ if (pdev->dib.funcs != &funcs_8888)
+ {
+ DWORD *masks = (DWORD *)info->bmiColors;
+ masks[0] = pdev->dib.red_mask;
+ masks[1] = pdev->dib.green_mask;
+ masks[2] = pdev->dib.blue_mask;
+ info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ break;
+ }
+ if (bits)
+ {
+ bits->ptr = pdev->dib.bits;
+ if (pdev->dib.stride < 0)
+ bits->ptr = (char *)bits->ptr + (pdev->dib.height - 1) * pdev->dib.stride;
+ bits->is_copy = FALSE;
+ bits->free = NULL;
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
* dibdrv_SelectBitmap
*/
static HBITMAP dibdrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
@@ -473,7 +591,7 @@ const DC_FUNCTIONS dib_driver =
NULL, /* pGetDeviceCaps */
NULL, /* pGetDeviceGammaRamp */
NULL, /* pGetICMProfile */
- NULL, /* pGetImage */
+ dibdrv_GetImage, /* pGetImage */
NULL, /* pGetNearestColor */
NULL, /* pGetPixel */
NULL, /* pGetPixelFormat */
More information about the wine-cvs
mailing list