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