Alexandre Julliard : gdi32: Reimplement GetBitmapBits using the GetImage driver function.
Alexandre Julliard
julliard at winehq.org
Tue Jul 26 11:37:52 CDT 2011
Module: wine
Branch: master
Commit: 1724c735344c211462c603a3b2342ef8d5fd958d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1724c735344c211462c603a3b2342ef8d5fd958d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jul 25 15:31:46 2011 +0200
gdi32: Reimplement GetBitmapBits using the GetImage driver function.
---
dlls/gdi32/bitmap.c | 103 +++++++++++++++++++-------------------------------
1 files changed, 39 insertions(+), 64 deletions(-)
diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 2e23f6e..a1838fd 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -382,83 +382,58 @@ LONG WINAPI GetBitmapBits(
LONG count, /* [in] Number of bytes to copy */
LPVOID bits) /* [out] Pointer to buffer to receive bits */
{
+ char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+ BITMAPINFO *info = (BITMAPINFO *)buffer;
+ struct gdi_image_bits src_bits;
+ struct bitblt_coords src;
+ int dst_stride, max, ret;
BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP );
- LONG height, ret;
if (!bmp) return 0;
- if (bmp->dib) /* simply copy the bits from the DIB */
- {
- DIBSECTION *dib = bmp->dib;
- const char *src = dib->dsBm.bmBits;
- INT width_bytes = get_bitmap_stride(dib->dsBm.bmWidth, dib->dsBm.bmBitsPixel);
- LONG max = width_bytes * bmp->bitmap.bmHeight;
-
- if (!bits)
- {
- ret = max;
- goto done;
- }
+ if (bmp->dib) dst_stride = get_bitmap_stride( bmp->dib->dsBmih.biWidth, bmp->dib->dsBmih.biBitCount );
+ else dst_stride = get_bitmap_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
- if (count > max) count = max;
- ret = count;
+ ret = max = dst_stride * bmp->bitmap.bmHeight;
+ if (!bits) goto done;
+ if (count > max) count = max;
+ ret = count;
+
+ src.visrect.left = 0;
+ src.visrect.right = bmp->bitmap.bmWidth;
+ src.visrect.top = 0;
+ src.visrect.bottom = (count + dst_stride - 1) / dst_stride;
+ src.x = src.y = 0;
+ src.width = src.visrect.right - src.visrect.left;
+ src.height = src.visrect.bottom - src.visrect.top;
+
+ if (!bmp->funcs->pGetImage( NULL, hbitmap, info, &src_bits, &src ))
+ {
+ const char *src_ptr = src_bits.ptr;
+ int src_stride = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
- /* GetBitmapBits returns not 32-bit aligned data */
+ /* GetBitmapBits returns 16-bit aligned data */
- if (bmp->dib->dsBmih.biHeight >= 0) /* not top-down, need to flip contents vertically */
+ if (info->bmiHeader.biHeight > 0)
{
- src += dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
- while (count > 0)
- {
- src -= dib->dsBm.bmWidthBytes;
- memcpy( bits, src, min( count, width_bytes ) );
- bits = (char *)bits + width_bytes;
- count -= width_bytes;
- }
+ src_ptr += (info->bmiHeader.biHeight - 1) * src_stride;
+ src_stride = -src_stride;
}
- else
+ src_ptr += src.visrect.top * src_stride;
+
+ if (src_stride == dst_stride) memcpy( bits, src_ptr, count );
+ else while (count > 0)
{
- while (count > 0)
- {
- memcpy( bits, src, min( count, width_bytes ) );
- src += dib->dsBm.bmWidthBytes;
- bits = (char *)bits + width_bytes;
- count -= width_bytes;
- }
+ memcpy( bits, src_ptr, min( count, dst_stride ) );
+ src_ptr += src_stride;
+ bits = (char *)bits + dst_stride;
+ count -= dst_stride;
}
- goto done;
+ if (src_bits.free) src_bits.free( &src_bits );
}
+ else ret = 0;
- /* If the bits vector is null, the function should return the read size */
- if(bits == NULL)
- {
- ret = bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
- goto done;
- }
-
- if (count < 0) {
- WARN("(%d): Negative number of bytes passed???\n", count );
- count = -count;
- }
-
- /* Only get entire lines */
- height = count / bmp->bitmap.bmWidthBytes;
- if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
- count = height * bmp->bitmap.bmWidthBytes;
- if (count == 0)
- {
- WARN("Less than one entire line requested\n");
- ret = 0;
- goto done;
- }
-
-
- TRACE("(%p, %d, %p) %dx%d %d colors fetched height: %d\n",
- hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
- 1 << bmp->bitmap.bmBitsPixel, height );
-
- ret = bmp->funcs->pGetBitmapBits( hbitmap, bits, count );
- done:
+done:
GDI_ReleaseObj( hbitmap );
return ret;
}
More information about the wine-cvs
mailing list