gdi32: Implement GetImage in the DIB driver.

This commit is contained in:
Alexandre Julliard 2011-07-25 15:30:33 +02:00
parent bb3a1bdcac
commit dcfe0c48ea
2 changed files with 123 additions and 12 deletions

View File

@ -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;

View File

@ -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;
@ -312,6 +312,124 @@ static BOOL dibdrv_DeleteDC( PHYSDEV dev )
return 0;
}
/***********************************************************************
* 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
*/
@ -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 */