Commit 10784991 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Reimplement SetBitmapBits using the PutImage driver entry point.

parent 76b5c1dc
...@@ -518,8 +518,13 @@ LONG WINAPI SetBitmapBits( ...@@ -518,8 +518,13 @@ LONG WINAPI SetBitmapBits(
LONG count, /* [in] Number of bytes in bitmap array */ LONG count, /* [in] Number of bytes in bitmap array */
LPCVOID bits) /* [in] Address of array with bitmap bits */ LPCVOID bits) /* [in] Address of array with bitmap bits */
{ {
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
BITMAPOBJ *bmp; BITMAPOBJ *bmp;
LONG height, ret; DWORD err;
int i, src_stride, dst_stride;
struct bitblt_coords src, dst;
struct gdi_image_bits src_bits;
if (!bits) return 0; if (!bits) return 0;
...@@ -531,43 +536,71 @@ LONG WINAPI SetBitmapBits( ...@@ -531,43 +536,71 @@ LONG WINAPI SetBitmapBits(
count = -count; count = -count;
} }
if (bmp->dib) /* simply copy the bits into the DIB */ if (bmp->dib) src_stride = get_bitmap_stride( bmp->dib->dsBmih.biWidth, bmp->dib->dsBmih.biBitCount );
{ else src_stride = get_bitmap_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
DIBSECTION *dib = bmp->dib;
char *dest = dib->dsBm.bmBits; dst_stride = get_dib_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
LONG max = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
if (count > max) count = max; src.visrect.left = src.x = 0;
ret = count; src.visrect.top = src.y = 0;
src.visrect.right = src.width = bmp->bitmap.bmWidth;
src.visrect.bottom = src.height = min( count / src_stride, bmp->bitmap.bmHeight );
dst = src;
/* Only set entire lines */
count = src.height * src_stride;
if (bmp->dib->dsBmih.biHeight >= 0) /* not top-down, need to flip contents vertically */ TRACE("(%p, %d, %p) %dx%d %d bpp fetched height: %d\n",
hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
bmp->bitmap.bmBitsPixel, src.height );
if (src_stride == dst_stride)
{
src_bits.ptr = (void *)bits;
src_bits.is_copy = FALSE;
src_bits.free = NULL;
}
else
{
if (!(src_bits.ptr = HeapAlloc( GetProcessHeap(), 0, dst.height * dst_stride )))
{ {
dest += dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight; GDI_ReleaseObj( hbitmap );
while (count > 0) return 0;
{
dest -= dib->dsBm.bmWidthBytes;
memcpy( dest, bits, min( count, dib->dsBm.bmWidthBytes ) );
bits = (const char *)bits + dib->dsBm.bmWidthBytes;
count -= dib->dsBm.bmWidthBytes;
}
} }
else memcpy( dest, bits, count ); src_bits.is_copy = TRUE;
src_bits.free = free_heap_bits;
GDI_ReleaseObj( hbitmap ); for (i = 0; i < dst.height; i++)
return ret; memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, src_stride );
} }
/* Only get entire lines */ /* query the color info */
height = count / bmp->bitmap.bmWidthBytes; info->bmiHeader.biSize = sizeof(info->bmiHeader);
if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; info->bmiHeader.biPlanes = 1;
count = height * bmp->bitmap.bmWidthBytes; info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
info->bmiHeader.biCompression = BI_RGB;
info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrUsed = 0;
info->bmiHeader.biClrImportant = 0;
info->bmiHeader.biWidth = 0;
info->bmiHeader.biHeight = 0;
info->bmiHeader.biSizeImage = 0;
err = bmp->funcs->pPutImage( NULL, hbitmap, 0, info, NULL, NULL, NULL, SRCCOPY );
TRACE("(%p, %d, %p) %dx%d %d colors fetched height: %d\n", if (!err || err == ERROR_BAD_FORMAT)
hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, {
1 << bmp->bitmap.bmBitsPixel, height ); info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
info->bmiHeader.biHeight = -dst.height;
info->bmiHeader.biSizeImage = dst.height * dst_stride;
err = bmp->funcs->pPutImage( NULL, hbitmap, 0, info, &src_bits, &src, &dst, SRCCOPY );
}
if (err) count = 0;
ret = bmp->funcs->pSetBitmapBits( hbitmap, bits, count ); if (src_bits.free) src_bits.free( &src_bits );
GDI_ReleaseObj( hbitmap ); GDI_ReleaseObj( hbitmap );
return ret; return count;
} }
/********************************************************************** /**********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment