Huw Davies : gdi32: Export a bitmap conversion function.

Alexandre Julliard julliard at winehq.org
Mon Jul 18 12:47:00 CDT 2011


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Mon Jul 18 15:27:43 2011 +0100

gdi32: Export a bitmap conversion function.

---

 dlls/gdi32/dibdrv/dc.c      |   47 +++++++++++++++++++++++-------------------
 dlls/gdi32/dibdrv/objects.c |   16 +++++++++++++-
 dlls/gdi32/gdi_private.h    |    3 ++
 3 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 3ec44d1..1122579 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -200,6 +200,20 @@ BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD u
     return init_dib_info(dib, bi, masks, color_table, num_colors, ptr, private_color_table);
 }
 
+BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags)
+{
+    unsigned int colors = 0;
+    void *colorptr = (char *)&info->bmiHeader + info->bmiHeader.biSize;
+    const DWORD *bitfields = (info->bmiHeader.biCompression == BI_BITFIELDS) ? (DWORD *)colorptr : NULL;
+
+    if (info->bmiHeader.biBitCount <= 8)
+    {
+        colors = 1 << info->bmiHeader.biBitCount;
+        if (info->bmiHeader.biClrUsed) colors = info->bmiHeader.biClrUsed;
+    }
+    return init_dib_info( dib, &info->bmiHeader, bitfields, colors ? colorptr : NULL, colors, bits, flags );
+}
+
 static void clear_dib_info(dib_info *dib)
 {
     dib->color_table = NULL;
@@ -252,32 +266,23 @@ void copy_dib_color_info(dib_info *dst, const dib_info *src)
     }
 }
 
-/**************************************************************
- *            convert_dib
- *
- * Converts src into the format specified in dst.
- *
- * FIXME: At the moment this always creates a top-down dib,
- * do we want to give the option of bottom-up?
- */
-BOOL convert_dib(dib_info *dst, const dib_info *src)
+DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, const RECT *src_rect,
+                          const BITMAPINFO *dst_info, void *dst_bits )
 {
-    BOOL ret;
-    RECT src_rect;
+    dib_info src_dib, dst_dib;
+    DWORD ret;
 
-    dst->height = src->height;
-    dst->width = src->width;
-    dst->stride = ((dst->width * dst->bit_count + 31) >> 3) & ~3;
-    dst->ptr_to_free = dst->bits = HeapAlloc(GetProcessHeap(), 0, dst->height * dst->stride);
+    if ( !init_dib_info_from_bitmapinfo( &src_dib, src_info, src_bits, 0 ) )
+        return ERROR_BAD_FORMAT;
+    if ( !init_dib_info_from_bitmapinfo( &dst_dib, dst_info, dst_bits, 0 ) )
+        return ERROR_BAD_FORMAT;
 
-    src_rect.left = src_rect.top = 0;
-    src_rect.right = src->width;
-    src_rect.bottom = src->height;
+    ret = dst_dib.funcs->convert_to( &dst_dib, &src_dib, src_rect );
 
-    ret = dst->funcs->convert_to(dst, src, &src_rect);
+    /* We shared the color tables, so there's no need to free the dib_infos here */
 
-    if(!ret) free_dib_info(dst);
-    return ret;
+    if(!ret) return ERROR_BAD_FORMAT;
+    return ERROR_SUCCESS;
 }
 
 static void update_fg_colors( dibdrv_physdev *pdev )
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 75b63fa..a977bd4 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1285,16 +1285,30 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
         dib_info orig_dib;
         WORD usage = LOWORD(logbrush.lbColor);
         HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL;
+        RECT rect;
 
         if(!bi) return NULL;
         if(init_dib_info_from_packed(&orig_dib, bi, usage, pal))
         {
             copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
-            if(convert_dib(&pdev->brush_dib, &orig_dib))
+
+            pdev->brush_dib.height = orig_dib.height;
+            pdev->brush_dib.width  = orig_dib.width;
+            pdev->brush_dib.stride = ((pdev->brush_dib.width * pdev->brush_dib.bit_count + 31) >> 3) & ~3;
+            pdev->brush_dib.ptr_to_free = HeapAlloc( GetProcessHeap(), 0, pdev->brush_dib.height * pdev->brush_dib.stride );
+            pdev->brush_dib.bits = pdev->brush_dib.ptr_to_free;
+
+            rect.left = rect.top = 0;
+            rect.right = orig_dib.width;
+            rect.bottom = orig_dib.height;
+
+            if(pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, &orig_dib, &rect))
             {
                 pdev->brush_rects = pattern_brush;
                 pdev->defer &= ~DEFER_BRUSH;
             }
+            else
+                free_dib_info(&pdev->brush_dib);
             free_dib_info(&orig_dib);
         }
         GlobalUnlock((HGLOBAL)logbrush.lbHatch);
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index a48ac87..8c3e9ac 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -338,6 +338,9 @@ extern int DIB_GetDIBImageBytes( int width, int height, int depth ) DECLSPEC_HID
 extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
 extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
                               LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ) DECLSPEC_HIDDEN;
+extern DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, const RECT *src_rect,
+                                 const BITMAPINFO *dst_info, void *dst_bits ) DECLSPEC_HIDDEN;
+
 
 /* driver.c */
 extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list