[PATCH 1/2] gdi32/tests: Move out common functions into a separate file named misc.c|h

Ralf Habacker ralf.habacker at freenet.de
Mon Feb 8 03:27:32 CST 2021


This is used to avoid code duplication for adding an 'advanced' gdi32 test.

Signed-off-by: Ralf Habacker <ralf.habacker at freenet.de>
---
 dlls/gdi32/tests/Makefile.in |   1 +
 dlls/gdi32/tests/dib.c       | 338 +---------------------------
 dlls/gdi32/tests/misc.c      | 425 +++++++++++++++++++++++++++++++++++
 dlls/gdi32/tests/misc.h      |  31 +++
 4 files changed, 460 insertions(+), 335 deletions(-)
 create mode 100644 dlls/gdi32/tests/misc.c
 create mode 100644 dlls/gdi32/tests/misc.h

diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 876f6a376a2..ad8f0ce8bad 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -14,6 +14,7 @@ C_SRCS = \
 	icm.c \
 	mapping.c \
 	metafile.c \
+	misc.c \
 	palette.c \
 	path.c \
 	pen.c
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index bdc3d9ed55b..96ac0b69271 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -31,7 +31,9 @@
 
 #include "wine/test.h"
 
-static HCRYPTPROV crypt_prov;
+#include "misc.h"
+
+static const char *dst_format;
 
 static const DWORD rop3[256] =
 {
@@ -1263,217 +1265,6 @@ static const char *sha1_graphics_1_ddb_inverted[] =
     NULL
 };
 
-static const RECT graphics_bounds[] =
-{
-    { 0, 0, 0, 0 },
-    { 10, 3, 219, 101 },
-    { 100, 100, 301, 301 },
-    { 0, 0, 201, 201 },
-    { 10, 10, 110, 320 },
-    { 10, 99, 300, 200 },
-    { 99, 12, 201, 200 },
-    { 90, 110, 300, 200 },
-    { 90, 90, 210, 200 },
-    { 10, 99, 300, 200 },
-    { 10, 99, 300, 200 },
-    { 99, 12, 201, 200 },
-    { 99, 11, 201, 200 },
-    { 90, 110, 300, 200 },
-    { 90, 110, 300, 200 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 365, 405 },
-    { 10, 10, 350, 251 },
-    { 10, 10, 300, 200 },
-    { 300, 10, 9, 260 },
-    { 10, 10, 435, 405 },
-    { 10, 10, 120, 120 },
-    { 10, 10, 110, 110 },
-    { 10, 10, 120, 110 },
-    { 10, 10, 110, 120 },
-    { 10, 10, 120, 120 },
-    { 10, 10, 110, 110 },
-    { 10, 10, 120, 110 },
-    { 10, 10, 110, 120 },
-    { 0, 4, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 50, 50, 306, 306 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 10, 10, 356, 356 },
-    { 100, 100, 356, 356 },
-    { 0, 0, 260, 39 },
-    { 0, 0, 16, 16 },
-    { 10, 10, 416, 26 },
-    { 10, 8, 60, 104 },
-    { 0, 0, 512, 512 },
-    { 0, 10, 511, 306 },
-    { 0, 0, 512, 336 },
-    { 1, 1, 300, 512 },
-    { 0, 0, 500, 512 },
-    { 5, 5, 206, 206 },
-    { 45, 45, 256, 256 },
-    { 86, 86, 215, 215 },
-    { 45, 45, 256, 256 },
-    { 8, 0, 392, 231 },
-    { 8, 0, 392, 231 },
-    { 0, 0, 60, 20 },
-    { 0, 0, 512, 512 },
-    { -1, -1, -1, -1 }  /* the end */
-};
-
-static const char **current_sha1;
-static const RECT *current_bounds;
-static const char *dst_format;
-
-static inline DWORD get_stride(const BITMAPINFO *bmi)
-{
-    return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
-}
-
-static inline DWORD get_dib_size(const BITMAPINFO *bmi)
-{
-    return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
-}
-
-static void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits )
-{
-    DWORD size = get_dib_size( bmi );
-    if (bits) memset( bits, 0xcc, size );
-    else
-    {
-        void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, size );
-        memset( ddb_bits, 0xcc, size );
-        SetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), size, ddb_bits );
-        HeapFree( GetProcessHeap(), 0, ddb_bits );
-    }
-}
-
-static char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits)
-{
-    DWORD dib_size = get_dib_size(bmi);
-    HCRYPTHASH hash;
-    char *buf;
-    BYTE hash_buf[20];
-    DWORD hash_size = sizeof(hash_buf);
-    int i;
-    static const char *hex = "0123456789abcdef";
-
-    if(!crypt_prov) return NULL;
-
-    if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
-
-    if (!bits)
-    {
-        void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, dib_size );
-        GetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), dib_size, ddb_bits );
-        CryptHashData(hash, ddb_bits, dib_size, 0);
-        HeapFree( GetProcessHeap(), 0, ddb_bits );
-    }
-    else CryptHashData(hash, bits, dib_size, 0);
-
-    CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
-    if(hash_size != sizeof(hash_buf)) return NULL;
-
-    CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
-    CryptDestroyHash(hash);
-
-    buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
-
-    for(i = 0; i < hash_size; i++)
-    {
-        buf[i * 2] = hex[hash_buf[i] >> 4];
-        buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
-    }
-    buf[i * 2] = '\0';
-
-    return buf;
-}
-
-static void reset_bounds( HDC hdc )
-{
-    current_bounds = graphics_bounds;
-    SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
-}
-
-static void compare_bounds( HDC hdc, const char *info )
-{
-    RECT rect;
-
-    GetBoundsRect( hdc, &rect, DCB_RESET );
-
-    if (current_bounds->left == -1 &&
-        current_bounds->top == -1 &&
-        current_bounds->right == -1 &&
-        current_bounds->bottom == -1)
-    {
-        ok( 0, "missing bounds, got %s,\n", wine_dbgstr_rect( &rect ));
-        return;
-    }
-
-    ok( EqualRect( current_bounds, &rect ), "%s: %s: expected bounds %s got %s\n", dst_format, info,
-        wine_dbgstr_rect( current_bounds ), wine_dbgstr_rect( &rect ));
-    current_bounds++;
-}
-
-static void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo)
-{
-    char *hash = hash_dib(hdc, bmi, bits);
-    BOOL ok_cond;
-    int i;
-
-    /* reset the bits for the next test */
-    reset_bits( hdc, bmi, bits );
-
-    if(!hash)
-    {
-        skip("SHA1 hashing unavailable on this platform\n");
-        return;
-    }
-
-    for(i = 0; i <= num_broken; i++)
-    {
-        if(current_sha1[i] == NULL)
-        {
-            ok(current_sha1[i] != NULL, "missing hash, got \"%s\",\n", hash);
-            HeapFree(GetProcessHeap(), 0, hash);
-            return;
-        }
-    }
-
-    ok_cond = !strcmp(hash, *current_sha1);
-
-    for(i = 1; i <= num_broken; i++)
-        ok_cond = ok_cond || broken( !strcmp(hash, current_sha1[i]) );
-
-    todo_wine_if(todo)
-        ok( ok_cond, "%s: %s: expected hash %s got %s\n",
-            dst_format, info, *current_sha1, hash );
-
-    current_sha1 += num_broken + 1;
-
-    HeapFree(GetProcessHeap(), 0, hash);
-
-    compare_bounds( hdc, info );
-}
-
-static void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info)
-{
-    compare_hash_broken_todo(hdc, bmi, bits, info, 0, FALSE);
-}
-
 static const RECT bias_check[] =
 {
     {100, 100, 200, 150},
@@ -1621,129 +1412,6 @@ static const DWORD four_by_four_data[16] = { 0x000000, 0xff0000, 0x00ff00, 0x000
 static const DWORD ddb_brush_bits[8] = { 0x11112222, 0x33334444, 0x55556666, 0x77778888,
                                          0xaaaaaaaa, 0x00000000, 0x98765432, 0xabcdef00 };
 
-static const RGBQUAD default_palette_1[2] =
-{
-    { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff }
-};
-
-static const RGBQUAD default_palette_4[16] =
-{
-    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
-    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 },
-    { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
-    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
-};
-
-static const RGBQUAD default_palette_8[256] =
-{
-    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
-    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 },
-    { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 },
-    { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 },
-    { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 },
-    { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 },
-    { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 },
-    { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 },
-    { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 },
-    { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 },
-    { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 },
-    { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 },
-    { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 },
-    { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 },
-    { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 },
-    { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 },
-    { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 },
-    { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 },
-    { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 },
-    { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 },
-    { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 },
-    { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 },
-    { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 },
-    { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 },
-    { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 },
-    { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 },
-    { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 },
-    { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 },
-    { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 },
-    { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 },
-    { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 },
-    { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 },
-    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 },
-    { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 },
-    { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 },
-    { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 },
-    { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 },
-    { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 },
-    { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 },
-    { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 },
-    { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 },
-    { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 },
-    { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 },
-    { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 },
-    { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 },
-    { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 },
-    { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 },
-    { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 },
-    { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 },
-    { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 },
-    { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 },
-    { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 },
-    { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 },
-    { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 },
-    { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 },
-    { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 },
-    { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 },
-    { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 },
-    { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 },
-    { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 },
-    { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 },
-    { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 },
-    { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
-    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }
-};
-
-static HPALETTE create_default_palette( int bpp )
-{
-    char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
-    LOGPALETTE *pal = (LOGPALETTE *)pal_buffer;
-    PALETTEENTRY *entries = pal->palPalEntry;
-    int i;
-
-    pal->palVersion = 0x300;
-    pal->palNumEntries = 1 << bpp;
-    switch (bpp)
-    {
-    case 1:
-        for (i = 0; i < 2; i++)
-        {
-            entries[i].peRed   = default_palette_1[i].rgbRed;
-            entries[i].peGreen = default_palette_1[i].rgbGreen;
-            entries[i].peBlue  = default_palette_1[i].rgbBlue;
-            entries[i].peFlags = 0;
-        }
-        break;
-    case 4:
-        for (i = 0; i < 16; i++)
-        {
-            entries[i].peRed   = default_palette_4[i].rgbRed;
-            entries[i].peGreen = default_palette_4[i].rgbGreen;
-            entries[i].peBlue  = default_palette_4[i].rgbBlue;
-            entries[i].peFlags = 0;
-        }
-        break;
-    case 8:
-        for (i = 0; i < 256; i++)
-        {
-            entries[i].peRed   = default_palette_8[i].rgbRed;
-            entries[i].peGreen = default_palette_8[i].rgbGreen;
-            entries[i].peBlue  = default_palette_8[i].rgbBlue;
-            entries[i].peFlags = 0;
-        }
-        break;
-    }
-    return CreatePalette( pal );
-}
-
 static inline void solid_patblt( HDC hdc, int x, int y, int width, int height, COLORREF color )
 {
     HBRUSH brush = CreateSolidBrush( color );
diff --git a/dlls/gdi32/tests/misc.c b/dlls/gdi32/tests/misc.c
new file mode 100644
index 00000000000..828be2745a0
--- /dev/null
+++ b/dlls/gdi32/tests/misc.c
@@ -0,0 +1,425 @@
+
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wincrypt.h"
+#include "mmsystem.h" /* DIBINDEX */
+
+#include "wine/test.h"
+#include "misc.h"
+
+const char **current_sha1;
+const RECT *current_bounds;
+const char *dst_format;
+HCRYPTPROV crypt_prov;
+
+static const RECT graphics_bounds[] =
+{
+    { 0, 0, 0, 0 },
+    { 10, 3, 219, 101 },
+    { 100, 100, 301, 301 },
+    { 0, 0, 201, 201 },
+    { 10, 10, 110, 320 },
+    { 10, 99, 300, 200 },
+    { 99, 12, 201, 200 },
+    { 90, 110, 300, 200 },
+    { 90, 90, 210, 200 },
+    { 10, 99, 300, 200 },
+    { 10, 99, 300, 200 },
+    { 99, 12, 201, 200 },
+    { 99, 11, 201, 200 },
+    { 90, 110, 300, 200 },
+    { 90, 110, 300, 200 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 365, 405 },
+    { 10, 10, 350, 251 },
+    { 10, 10, 300, 200 },
+    { 300, 10, 9, 260 },
+    { 10, 10, 435, 405 },
+    { 10, 10, 120, 120 },
+    { 10, 10, 110, 110 },
+    { 10, 10, 120, 110 },
+    { 10, 10, 110, 120 },
+    { 10, 10, 120, 120 },
+    { 10, 10, 110, 110 },
+    { 10, 10, 120, 110 },
+    { 10, 10, 110, 120 },
+    { 0, 4, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 50, 50, 306, 306 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 10, 10, 356, 356 },
+    { 100, 100, 356, 356 },
+    { 0, 0, 260, 39 },
+    { 0, 0, 16, 16 },
+    { 10, 10, 416, 26 },
+    { 10, 8, 60, 104 },
+    { 0, 0, 512, 512 },
+    { 0, 10, 511, 306 },
+    { 0, 0, 512, 336 },
+    { 1, 1, 300, 512 },
+    { 0, 0, 500, 512 },
+    { 5, 5, 206, 206 },
+    { 45, 45, 256, 256 },
+    { 86, 86, 215, 215 },
+    { 45, 45, 256, 256 },
+    { 8, 0, 392, 231 },
+    { 8, 0, 392, 231 },
+    { 0, 0, 60, 20 },
+    { 0, 0, 512, 512 },
+    { -1, -1, -1, -1 }  /* the end */
+};
+
+static const RGBQUAD default_palette_1[2] =
+{
+    { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+static const RGBQUAD default_palette_4[16] =
+{
+    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 },
+    { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
+};
+
+static const RGBQUAD default_palette_8[256] =
+{
+    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 },
+    { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 },
+    { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 },
+    { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 },
+    { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 },
+    { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 },
+    { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 },
+    { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 },
+    { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 },
+    { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 },
+    { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 },
+    { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 },
+    { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 },
+    { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 },
+    { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 },
+    { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 },
+    { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 },
+    { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 },
+    { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 },
+    { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 },
+    { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 },
+    { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 },
+    { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 },
+    { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 },
+    { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 },
+    { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 },
+    { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 },
+    { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 },
+    { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 },
+    { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 },
+    { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 },
+    { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 },
+    { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 },
+    { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 },
+    { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 },
+    { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 },
+    { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 },
+    { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 },
+    { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 },
+    { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 },
+    { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 },
+    { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 },
+    { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 },
+    { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 },
+    { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 },
+    { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 },
+    { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 },
+    { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 },
+    { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 },
+    { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 },
+    { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 },
+    { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 },
+    { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 },
+    { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 },
+    { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 },
+    { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 },
+    { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 },
+    { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 },
+    { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 },
+    { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 },
+    { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+HPALETTE create_default_palette( int bpp )
+{
+    char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
+    LOGPALETTE *pal = (LOGPALETTE *)pal_buffer;
+    PALETTEENTRY *entries = pal->palPalEntry;
+    int i;
+
+    pal->palVersion = 0x300;
+    pal->palNumEntries = 1 << bpp;
+    switch (bpp)
+    {
+    case 1:
+        for (i = 0; i < 2; i++)
+        {
+            entries[i].peRed   = default_palette_1[i].rgbRed;
+            entries[i].peGreen = default_palette_1[i].rgbGreen;
+            entries[i].peBlue  = default_palette_1[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    case 4:
+        for (i = 0; i < 16; i++)
+        {
+            entries[i].peRed   = default_palette_4[i].rgbRed;
+            entries[i].peGreen = default_palette_4[i].rgbGreen;
+            entries[i].peBlue  = default_palette_4[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    case 8:
+        for (i = 0; i < 256; i++)
+        {
+            entries[i].peRed   = default_palette_8[i].rgbRed;
+            entries[i].peGreen = default_palette_8[i].rgbGreen;
+            entries[i].peBlue  = default_palette_8[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    }
+    return CreatePalette( pal );
+}
+
+void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits )
+{
+    DWORD size = get_dib_size( bmi );
+    if (bits) memset( bits, 0xcc, size );
+    else
+    {
+        void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, size );
+        memset( ddb_bits, 0xcc, size );
+        SetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), size, ddb_bits );
+        HeapFree( GetProcessHeap(), 0, ddb_bits );
+    }
+}
+
+char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits)
+{
+    DWORD dib_size = get_dib_size(bmi);
+    HCRYPTHASH hash;
+    char *buf;
+    BYTE hash_buf[20];
+    DWORD hash_size = sizeof(hash_buf);
+    int i;
+    static const char *hex = "0123456789abcdef";
+
+    if(!crypt_prov) return NULL;
+
+    if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
+
+    if (!bits)
+    {
+        void *ddb_bits = HeapAlloc( GetProcessHeap(), 0, dib_size );
+        GetBitmapBits( GetCurrentObject(hdc, OBJ_BITMAP), dib_size, ddb_bits );
+        CryptHashData(hash, ddb_bits, dib_size, 0);
+        HeapFree( GetProcessHeap(), 0, ddb_bits );
+    }
+    else CryptHashData(hash, bits, dib_size, 0);
+
+    CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
+    if(hash_size != sizeof(hash_buf)) return NULL;
+
+    CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
+    CryptDestroyHash(hash);
+
+    buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
+
+    for(i = 0; i < hash_size; i++)
+    {
+        buf[i * 2] = hex[hash_buf[i] >> 4];
+        buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
+    }
+    buf[i * 2] = '\0';
+
+    return buf;
+}
+
+void reset_bounds( HDC hdc )
+{
+    current_bounds = graphics_bounds;
+    SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
+}
+
+void compare_bounds( HDC hdc, const char *info )
+{
+    RECT rect;
+
+    GetBoundsRect( hdc, &rect, DCB_RESET );
+
+    if (current_bounds->left == -1 &&
+        current_bounds->top == -1 &&
+        current_bounds->right == -1 &&
+        current_bounds->bottom == -1)
+    {
+        ok( 0, "missing bounds, got %s,\n", wine_dbgstr_rect( &rect ));
+        return;
+    }
+
+    ok( EqualRect( current_bounds, &rect ), "%s: %s: expected bounds %s got %s\n", dst_format, info,
+        wine_dbgstr_rect( current_bounds ), wine_dbgstr_rect( &rect ));
+    current_bounds++;
+}
+
+void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo)
+{
+    char *hash = hash_dib(hdc, bmi, bits);
+    BOOL ok_cond;
+    int i;
+
+    /* reset the bits for the next test */
+    reset_bits( hdc, bmi, bits );
+
+    if(!hash)
+    {
+        skip("SHA1 hashing unavailable on this platform\n");
+        return;
+    }
+
+    for(i = 0; i <= num_broken; i++)
+    {
+        if(current_sha1[i] == NULL)
+        {
+            ok(current_sha1[i] != NULL, "missing hash, got \"%s\",\n", hash);
+            HeapFree(GetProcessHeap(), 0, hash);
+            return;
+        }
+    }
+
+    ok_cond = !strcmp(hash, *current_sha1);
+
+    for(i = 1; i <= num_broken; i++)
+        ok_cond = ok_cond || broken( !strcmp(hash, current_sha1[i]) );
+
+    todo_wine_if(todo)
+        ok( ok_cond, "%s: %s: expected hash %s got %s\n",
+            dst_format, info, *current_sha1, hash );
+
+    current_sha1 += num_broken + 1;
+
+    HeapFree(GetProcessHeap(), 0, hash);
+
+    compare_bounds( hdc, info );
+}
+
+void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info)
+{
+    compare_hash_broken_todo(hdc, bmi, bits, info, 0, FALSE);
+}
+
+BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPSTR lpszFileName)
+{
+    HDC hDC;
+    int iBits;
+    WORD wBitCount;
+    DWORD dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0;
+    BITMAP Bitmap0;
+    BITMAPFILEHEADER bmfHdr;
+    BITMAPINFOHEADER bi;
+    LPBITMAPINFOHEADER lpbi;
+    HANDLE fh, hDib, hPal, hOldPal2 = NULL;
+    hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
+    iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
+    DeleteDC(hDC);
+    if (iBits <= 1)
+        wBitCount = 1;
+    else if (iBits <= 4)
+        wBitCount = 4;
+    else if (iBits <= 8)
+        wBitCount = 8;
+    else
+        wBitCount = 24;
+    GetObjectA(hBitmap, sizeof(Bitmap0), (LPSTR)&Bitmap0);
+    bi.biSize = sizeof(BITMAPINFOHEADER);
+    bi.biWidth = Bitmap0.bmWidth;
+    bi.biHeight = -Bitmap0.bmHeight;
+    bi.biPlanes = 1;
+    bi.biBitCount = wBitCount;
+    bi.biCompression = BI_RGB;
+    bi.biSizeImage = 0;
+    bi.biXPelsPerMeter = 0;
+    bi.biYPelsPerMeter = 0;
+    bi.biClrImportant = 0;
+    bi.biClrUsed = 256;
+    dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount + 31) & ~31) / 8
+        * Bitmap0.bmHeight;
+    hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
+    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
+    *lpbi = bi;
+
+    hPal = GetStockObject(DEFAULT_PALETTE);
+    if (hPal)
+    {
+        hDC = GetDC(NULL);
+        hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
+        RealizePalette(hDC);
+    }
+
+
+    GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+        + dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
+
+    if (hOldPal2)
+    {
+        SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE);
+        RealizePalette(hDC);
+        ReleaseDC(NULL, hDC);
+    }
+
+    fh = CreateFileA(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+
+    if (fh == INVALID_HANDLE_VALUE)
+        return FALSE;
+
+    bmfHdr.bfType = 0x4D42; // "BM"
+    dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
+    bmfHdr.bfSize = dwDIBSize;
+    bmfHdr.bfReserved1 = 0;
+    bmfHdr.bfReserved2 = 0;
+    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
+
+    WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
+
+    WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
+    GlobalUnlock(hDib);
+    GlobalFree(hDib);
+    CloseHandle(fh);
+    return TRUE;
+}
+
+void func_misc()
+{
+}
diff --git a/dlls/gdi32/tests/misc.h b/dlls/gdi32/tests/misc.h
new file mode 100644
index 00000000000..719a360d23d
--- /dev/null
+++ b/dlls/gdi32/tests/misc.h
@@ -0,0 +1,31 @@
+
+#ifndef MISC_H
+#define MISC_H
+
+#include "windef.h"
+
+extern const char **current_sha1;
+extern const RECT *current_bounds;
+extern HCRYPTPROV crypt_prov;
+
+HPALETTE create_default_palette( int bpp );
+
+static inline DWORD get_stride(const BITMAPINFO *bmi)
+{
+    return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
+}
+
+static inline DWORD get_dib_size(const BITMAPINFO *bmi)
+{
+    return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
+}
+
+void reset_bits( HDC hdc, const BITMAPINFO *bmi, BYTE *bits );
+char *hash_dib(HDC hdc, const BITMAPINFO *bmi, const void *bits);
+void reset_bounds( HDC hdc );
+void compare_bounds( HDC hdc, const char *info );
+void compare_hash_broken_todo(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info, int num_broken, BOOL todo);
+void compare_hash(HDC hdc, const BITMAPINFO *bmi, BYTE *bits, const char *info);
+
+BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPSTR lpszFileName);
+#endif
-- 
2.26.2




More information about the wine-devel mailing list