Alexandre Julliard : gdi32: Implement GetImage in the DIB driver.

Alexandre Julliard julliard at winehq.org
Tue Jul 26 11:37:52 CDT 2011


Module: wine
Branch: master
Commit: dcfe0c48ead211c1d4cd30ae6ba4743d97c3f7e0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dcfe0c48ead211c1d4cd30ae6ba4743d97c3f7e0

Author: Alexandre Julliard <julliard at 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 */




More information about the wine-cvs mailing list