Module: wine Branch: master Commit: dcfe0c48ead211c1d4cd30ae6ba4743d97c3f7e0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=dcfe0c48ead211c1d4cd30ae6b...
Author: Alexandre Julliard julliard@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 */