/*
 * Unit test suite for bitmaps
 *
 * Copyright 2004 Huw Davies
 * Copyright 2006 Dmitry Timoshkov
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <assert.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmsystem.h"

#include "wine/test.h"

static BOOL is_win9x;

static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
{
    switch(bpp)
    {
    case 1:
	return 2 * ((bmWidth+15) >> 4);

    case 24:
	bmWidth *= 3; /* fall through */
    case 8:
        return bmWidth + (bmWidth & 1);

    case 32:
        return bmWidth * 4;

    case 16:
    case 15:
        return bmWidth * 2;

    case 4:
        return 2 * ((bmWidth+3) >> 2);

    default:
        trace("Unknown depth %d, please report.\n", bpp );
        assert(0);
    }
    return -1;
}

static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
{
    BITMAP bm;
    INT ret, width_bytes;
    char buf[512], buf_cmp[512];

    ret = GetObject(hbm, sizeof(bm), &bm);
    ok(ret == sizeof(bm), "GetObject returned %d\n", ret);

    ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
    ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
    ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
    width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
    ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
    ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
    ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
    ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);

    assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
    assert(sizeof(buf) == sizeof(buf_cmp));

    ret = GetBitmapBits(hbm, 0, NULL);
    ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);

    memset(buf_cmp, 0xAA, sizeof(buf_cmp));
    memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);

    memset(buf, 0xAA, sizeof(buf));
    ret = GetBitmapBits(hbm, sizeof(buf), buf);
    ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
    ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");

    /* test various buffer sizes for GetObject */
    ret = GetObject(hbm, 0, NULL);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    ret = GetObject(hbm, sizeof(bm) * 2, &bm);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    ret = GetObject(hbm, sizeof(bm) / 2, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbm, 0, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbm, 1, &bm);
    ok(ret == 0, "%d != 0\n", ret);
}

static void test_createdibitmap(void)
{
    HDC hdc, hdcmem;
    BITMAPINFOHEADER bmih;
    HBITMAP hbm, hbm_colour, hbm_old;
    INT screen_depth;

    hdc = GetDC(0);
    screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
    memset(&bmih, 0, sizeof(bmih));
    bmih.biSize = sizeof(bmih);
    bmih.biWidth = 10;
    bmih.biHeight = 10;
    bmih.biPlanes = 1;
    bmih.biBitCount = 32;
    bmih.biCompression = BI_RGB;
 
    /* First create an un-initialised bitmap.  The depth of the bitmap
       should match that of the hdc and not that supplied in bmih.
    */

    /* First try 32 bits */
    hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);
    
    /* Then 16 */
    bmih.biBitCount = 16;
    hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);

    /* Then 1 */
    bmih.biBitCount = 1;
    hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);

    /* Now with a monochrome dc we expect a monochrome bitmap */
    hdcmem = CreateCompatibleDC(hdc);

    /* First try 32 bits */
    bmih.biBitCount = 32;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, 1, &bmih);
    DeleteObject(hbm);
    
    /* Then 16 */
    bmih.biBitCount = 16;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, 1, &bmih);
    DeleteObject(hbm);
    
    /* Then 1 */
    bmih.biBitCount = 1;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, 1, &bmih);
    DeleteObject(hbm);

    /* Now select a polychrome bitmap into the dc and we expect
       screen_depth bitmaps again */
    hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
    hbm_old = SelectObject(hdcmem, hbm_colour);

    /* First try 32 bits */
    bmih.biBitCount = 32;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);
    
    /* Then 16 */
    bmih.biBitCount = 16;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);
    
    /* Then 1 */
    bmih.biBitCount = 1;
    hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
    ok(hbm != NULL, "CreateDIBitmap failed\n");
    test_bitmap_info(hbm, screen_depth, &bmih);
    DeleteObject(hbm);

    SelectObject(hdcmem, hbm_old);
    DeleteObject(hbm_colour);
    DeleteDC(hdcmem);

    /* If hdc == 0 then we get a 1 bpp bitmap */
    if (!is_win9x) {
        bmih.biBitCount = 32;
        hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
        ok(hbm != NULL, "CreateDIBitmap failed\n");
        test_bitmap_info(hbm, 1, &bmih);
        DeleteObject(hbm);
    }
    
    ReleaseDC(0, hdc);
}

static INT DIB_GetWidthBytes( int width, int bpp )
{
    int words;

    switch (bpp)
    {
	case 1:  words = (width + 31) / 32; break;
	case 4:  words = (width + 7) / 8; break;
	case 8:  words = (width + 3) / 4; break;
	case 15:
	case 16: words = (width + 1) / 2; break;
	case 24: words = (width * 3 + 3)/4; break;
	case 32: words = width; break;

        default:
            words=0;
            trace("Unknown depth %d, please report.\n", bpp );
            assert(0);
            break;
    }
    return 4 * words;
}

static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
{
    BITMAP bm;
    DIBSECTION ds;
    INT ret, width_bytes;
    BYTE *buf;

    ret = GetObject(hbm, sizeof(bm), &bm);
    ok(ret == sizeof(bm), "GetObject returned %d\n", ret);

    ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
    ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
    ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
    width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
    ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
    ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
    ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
    ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);

    buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);

    width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);

    /* GetBitmapBits returns not 32-bit aligned data */
    ret = GetBitmapBits(hbm, 0, NULL);
    ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);

    memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
    ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
    ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);

    HeapFree(GetProcessHeap(), 0, buf);

    /* test various buffer sizes for GetObject */
    memset(&ds, 0xAA, sizeof(ds));
    ret = GetObject(hbm, sizeof(bm) * 2, &bm);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);
    ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
    ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
    ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);

    ret = GetObject(hbm, sizeof(bm) / 2, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbm, 0, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbm, 1, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    /* test various buffer sizes for GetObject */
    ret = GetObject(hbm, 0, NULL);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    memset(&ds, 0xAA, sizeof(ds));
    ret = GetObject(hbm, sizeof(ds) * 2, &ds);
    ok(ret == sizeof(ds), "wrong size %d\n", ret);

    ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
    ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%lu != %u\n",
       ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
    ok(bmih->biSizeImage == 0, "%lu != 0\n", bmih->biSizeImage);
    ds.dsBmih.biSizeImage = 0;

    ok(ds.dsBmih.biSize == bmih->biSize, "%lu != %lu\n", ds.dsBmih.biSize, bmih->biSize);
    ok(ds.dsBmih.biWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth);
    ok(ds.dsBmih.biHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight);
    ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
    ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
    ok(ds.dsBmih.biCompression == bmih->biCompression, "%lu != %lu\n", ds.dsBmih.biCompression, bmih->biCompression);
    ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%lu != %lu\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
    ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
    ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%lu != %lu\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);

    memset(&ds, 0xAA, sizeof(ds));
    ret = GetObject(hbm, sizeof(ds) - 4, &ds);
    ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
    ok(ds.dsBm.bmWidth == bmih->biWidth, "%lu != %lu\n", ds.dsBmih.biWidth, bmih->biWidth);
    ok(ds.dsBm.bmHeight == bmih->biHeight, "%lu != %lu\n", ds.dsBmih.biHeight, bmih->biHeight);
    ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);

    ret = GetObject(hbm, 0, &ds);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbm, 1, &ds);
    ok(ret == 0, "%d != 0\n", ret);
}

#define test_color_todo(got, exp, txt, todo) \
    if (!todo && got != exp && screen_depth < 24) { \
      todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
                   screen_depth, (UINT)got, (UINT)exp); \
      return; \
    } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
    else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \

#define test_color(hdc, color, exp, todo_setp, todo_getp) \
{ \
    COLORREF c; \
    c = SetPixel(hdc, 0, 0, color); \
    if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
    c = GetPixel(hdc, 0, 0); \
    test_color_todo(c, exp, GetPixel, todo_getp); \
}

static void test_dibsections(void)
{
    HDC hdc, hdcmem, hdcmem2;
    HBITMAP hdib, oldbm, hdib2, oldbm2;
    char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
    char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
    BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
    BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
    HBITMAP hcoredib;
    char coreBits[256];
    BYTE *bits;
    RGBQUAD rgb[256];
    int ret;
    char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
    LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
    WORD *index;
    DWORD *bits32;
    HPALETTE hpal, oldpal;
    DIBSECTION dibsec;
    COLORREF c0, c1;
    int i;
    int screen_depth;
    MEMORY_BASIC_INFORMATION info;

    hdc = GetDC(0);
    screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);

    memset(pbmi, 0, sizeof(bmibuf));
    pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
    pbmi->bmiHeader.biHeight = 100;
    pbmi->bmiHeader.biWidth = 512;
    pbmi->bmiHeader.biBitCount = 24;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biCompression = BI_RGB;

    SetLastError(0xdeadbeef);
    hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError());
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
    ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);

    /* test the DIB memory */
    ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
        "VirtualQuery failed\n");
    ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
    ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
    ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect);
    ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
    ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
    ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
    ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);

    test_dib_info(hdib, bits, &pbmi->bmiHeader);
    DeleteObject(hdib);

    pbmi->bmiHeader.biBitCount = 8;
    pbmi->bmiHeader.biCompression = BI_RLE8;
    SetLastError(0xdeadbeef);
    hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
    ok(GetLastError() == 0xdeadbeef, "wrong error %ld\n", GetLastError());

    pbmi->bmiHeader.biBitCount = 16;
    pbmi->bmiHeader.biCompression = BI_BITFIELDS;
    ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
    ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
    ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
    SetLastError(0xdeadbeef);
    hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection error %ld\n", GetLastError());

    /* test the DIB memory */
    ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
        "VirtualQuery failed\n");
    ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
    ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
    ok(info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect);
    ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
    ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
    ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
    ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);

    test_dib_info(hdib, bits, &pbmi->bmiHeader);
    DeleteObject(hdib);

    memset(pbmi, 0, sizeof(bmibuf));
    pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
    pbmi->bmiHeader.biHeight = 16;
    pbmi->bmiHeader.biWidth = 16;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biCompression = BI_RGB;
    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0;
    pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[1].rgbRed = 0;
    pbmi->bmiColors[1].rgbGreen = 0;
    pbmi->bmiColors[1].rgbBlue = 0xff;

    hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
    ok(dibsec.dsBmih.biClrUsed == 2,
        "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);

    /* Test if the old BITMAPCOREINFO structure is supported */    
        
    pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
    pbci->bmciHeader.bcBitCount = 0;

    if (!is_win9x) {
        ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
        ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
        ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
            && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
        "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");

        ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
        ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
        ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
            (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
            (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
            "The color table has not been translated to the old BITMAPCOREINFO format\n");

        hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
        ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");

        ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
        ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
        ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
        ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
            (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
            (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
            "The color table has not been translated to the old BITMAPCOREINFO format\n");

        DeleteObject(hcoredib);
    }

    hdcmem = CreateCompatibleDC(hdc);
    oldbm = SelectObject(hdcmem, hdib);

    ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
    ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
    ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
       "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
       rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
       rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);

    c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
    c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);

    test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
    test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
    test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
    test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
    test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
    test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
        pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
        pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
    test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);

    SelectObject(hdcmem, oldbm);
    DeleteObject(hdib);

    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0xff;
    pbmi->bmiColors[0].rgbBlue = 0xff;
    pbmi->bmiColors[1].rgbRed = 0;
    pbmi->bmiColors[1].rgbGreen = 0;
    pbmi->bmiColors[1].rgbBlue = 0;

    hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");

    test_dib_info(hdib, bits, &pbmi->bmiHeader);

    oldbm = SelectObject(hdcmem, hdib);

    ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
    ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
    ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
       "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
       rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
       rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);

    SelectObject(hdcmem, oldbm);
    test_dib_info(hdib, bits, &pbmi->bmiHeader);
    DeleteObject(hdib);

    pbmi->bmiHeader.biBitCount = 4;
    for (i = 0; i < 16; i++) {
        pbmi->bmiColors[i].rgbRed = i;
        pbmi->bmiColors[i].rgbGreen = 16-i;
        pbmi->bmiColors[i].rgbBlue = 0;
    }
    hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
    ok(dibsec.dsBmih.biClrUsed == 16,
       "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
    test_dib_info(hdib, bits, &pbmi->bmiHeader);
    DeleteObject(hdib);

    pbmi->bmiHeader.biBitCount = 8;

    for (i = 0; i < 128; i++) {
        pbmi->bmiColors[i].rgbRed = 255 - i * 2;
        pbmi->bmiColors[i].rgbGreen = i * 2;
        pbmi->bmiColors[i].rgbBlue = 0;
        pbmi->bmiColors[255 - i].rgbRed = 0;
        pbmi->bmiColors[255 - i].rgbGreen = i * 2;
        pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
    }
    hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
    ok(dibsec.dsBmih.biClrUsed == 256,
        "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);

    oldbm = SelectObject(hdcmem, hdib);

    for (i = 0; i < 256; i++) {
        test_color(hdcmem, DIBINDEX(i), 
            RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
        test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
            RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
    }

    SelectObject(hdcmem, oldbm);
    test_dib_info(hdib, bits, &pbmi->bmiHeader);
    DeleteObject(hdib);

    pbmi->bmiHeader.biBitCount = 1;

    /* Now create a palette and a palette indexed dib section */
    memset(plogpal, 0, sizeof(logpalbuf));
    plogpal->palVersion = 0x300;
    plogpal->palNumEntries = 2;
    plogpal->palPalEntry[0].peRed = 0xff;
    plogpal->palPalEntry[0].peBlue = 0xff;
    plogpal->palPalEntry[1].peGreen = 0xff;

    index = (WORD*)pbmi->bmiColors;
    *index++ = 0;
    *index = 1;
    hpal = CreatePalette(plogpal);
    ok(hpal != NULL, "CreatePalette failed\n");
    oldpal = SelectPalette(hdc, hpal, TRUE);
    hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
    ok(dibsec.dsBmih.biClrUsed == 2,
        "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);

    /* The colour table has already been grabbed from the dc, so we select back the
       old palette */

    SelectPalette(hdc, oldpal, TRUE);
    oldbm = SelectObject(hdcmem, hdib);
    oldpal = SelectPalette(hdcmem, hpal, TRUE);

    ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
    ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
    ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
       rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
       "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
       rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
       rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);

    c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
    c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);

    test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
    test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
    test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
    test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
    test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
    test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
        plogpal->palPalEntry[0].peBlue), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
        plogpal->palPalEntry[1].peBlue), c1, 1, 1);
    test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
    test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
    test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
    test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
    test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);

    /* Bottom and 2nd row from top green, everything else magenta */
    bits[0] = bits[1] = 0xff;
    bits[13 * 4] = bits[13*4 + 1] = 0xff;

    test_dib_info(hdib, bits, &pbmi->bmiHeader);

    pbmi->bmiHeader.biBitCount = 32;

    hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
    ok(hdib2 != NULL, "CreateDIBSection failed\n");
    hdcmem2 = CreateCompatibleDC(hdc);
    oldbm2 = SelectObject(hdcmem2, hdib2);

    BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);

    ok(bits32[0] == 0xff00, "lower left pixel is %08lx\n", bits32[0]);
    ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]);

    SelectObject(hdcmem2, oldbm2);
    test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
    DeleteObject(hdib2);

    SelectObject(hdcmem, oldbm);
    SelectObject(hdcmem, oldpal);
    DeleteObject(hdib);
    DeleteObject(hpal);


    pbmi->bmiHeader.biBitCount = 8;

    memset(plogpal, 0, sizeof(logpalbuf));
    plogpal->palVersion = 0x300;
    plogpal->palNumEntries = 256;

    for (i = 0; i < 128; i++) {
        plogpal->palPalEntry[i].peRed = 255 - i * 2;
        plogpal->palPalEntry[i].peBlue = i * 2;
        plogpal->palPalEntry[i].peGreen = 0;
        plogpal->palPalEntry[255 - i].peRed = 0;
        plogpal->palPalEntry[255 - i].peGreen = i * 2;
        plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
    }

    index = (WORD*)pbmi->bmiColors;
    for (i = 0; i < 256; i++) {
        *index++ = i;
    }

    hpal = CreatePalette(plogpal);
    ok(hpal != NULL, "CreatePalette failed\n");
    oldpal = SelectPalette(hdc, hpal, TRUE);
    hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
    ok(hdib != NULL, "CreateDIBSection failed\n");
    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
    ok(dibsec.dsBmih.biClrUsed == 256,
        "created DIBSection: wrong biClrUsed field: %lu, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);

    test_dib_info(hdib, bits, &pbmi->bmiHeader);

    SelectPalette(hdc, oldpal, TRUE);
    oldbm = SelectObject(hdcmem, hdib);
    oldpal = SelectPalette(hdcmem, hpal, TRUE);

    ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
    ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
    for (i = 0; i < 256; i++) {
        ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
            rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
            rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
            "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
            i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
    }

    for (i = 0; i < 256; i++) {
        test_color(hdcmem, DIBINDEX(i), 
            RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
        test_color(hdcmem, PALETTEINDEX(i), 
            RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
        test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
            RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
    }

    SelectPalette(hdcmem, oldpal, TRUE);
    SelectObject(hdcmem, oldbm);
    DeleteObject(hdib);
    DeleteObject(hpal);


    DeleteDC(hdcmem);
    ReleaseDC(0, hdc);
}    

void test_mono_dibsection(void)
{
    HDC hdc, memdc;
    HBITMAP old_bm, mono_ds;
    char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
    BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
    BYTE bits[10 * 4];
    BYTE *ds_bits;
    int num;

    hdc = GetDC(0);

    memdc = CreateCompatibleDC(hdc);

    memset(pbmi, 0, sizeof(bmibuf));
    pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
    pbmi->bmiHeader.biHeight = 10;
    pbmi->bmiHeader.biWidth = 10;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biCompression = BI_RGB;
    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0xff;
    pbmi->bmiColors[0].rgbBlue = 0xff;
    pbmi->bmiColors[1].rgbRed = 0x0;
    pbmi->bmiColors[1].rgbGreen = 0x0;
    pbmi->bmiColors[1].rgbBlue = 0x0;

    /*
     * First dib section is 'inverted' ie color[0] is white, color[1] is black
     */

    mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
    ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
    old_bm = SelectObject(memdc, mono_ds);

    /* black border, white interior */
    Rectangle(memdc, 0, 0, 10, 10);
    ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
    ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);

    /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */

    memset(bits, 0, sizeof(bits));
    bits[0] = 0xaa;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);

    /* SetDIBitsToDevice with a normal bmi -> inverted dib section */

    pbmi->bmiColors[0].rgbRed = 0x0;
    pbmi->bmiColors[0].rgbGreen = 0x0;
    pbmi->bmiColors[0].rgbBlue = 0x0;
    pbmi->bmiColors[1].rgbRed = 0xff;
    pbmi->bmiColors[1].rgbGreen = 0xff;
    pbmi->bmiColors[1].rgbBlue = 0xff;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);

    SelectObject(memdc, old_bm);
    DeleteObject(mono_ds);

    /*
     * Next dib section is 'normal' ie color[0] is black, color[1] is white
     */

    pbmi->bmiColors[0].rgbRed = 0x0;
    pbmi->bmiColors[0].rgbGreen = 0x0;
    pbmi->bmiColors[0].rgbBlue = 0x0;
    pbmi->bmiColors[1].rgbRed = 0xff;
    pbmi->bmiColors[1].rgbGreen = 0xff;
    pbmi->bmiColors[1].rgbBlue = 0xff;

    mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
    ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
    old_bm = SelectObject(memdc, mono_ds);

    /* black border, white interior */
    Rectangle(memdc, 0, 0, 10, 10);
    ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
    ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);

    /* SetDIBitsToDevice with a normal bmi -> normal dib section */

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);

    /* SetDIBitsToDevice with a inverted bmi -> normal dib section */

    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0xff;
    pbmi->bmiColors[0].rgbBlue = 0xff;
    pbmi->bmiColors[1].rgbRed = 0x0;
    pbmi->bmiColors[1].rgbGreen = 0x0;
    pbmi->bmiColors[1].rgbBlue = 0x0;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);

    /*
     * Take that 'normal' dibsection and change its colour table to an 'inverted' one
     */

    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0xff;
    pbmi->bmiColors[0].rgbBlue = 0xff;
    pbmi->bmiColors[1].rgbRed = 0x0;
    pbmi->bmiColors[1].rgbGreen = 0x0;
    pbmi->bmiColors[1].rgbBlue = 0x0;
    num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
    ok(num == 2, "num = %d\n", num);

    /* black border, white interior */
    Rectangle(memdc, 0, 0, 10, 10);
todo_wine {
    ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
    ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
 }
    /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */

    memset(bits, 0, sizeof(bits));
    bits[0] = 0xaa;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);

    /* SetDIBitsToDevice with a normal bmi -> inverted dib section */

    pbmi->bmiColors[0].rgbRed = 0x0;
    pbmi->bmiColors[0].rgbGreen = 0x0;
    pbmi->bmiColors[0].rgbBlue = 0x0;
    pbmi->bmiColors[1].rgbRed = 0xff;
    pbmi->bmiColors[1].rgbGreen = 0xff;
    pbmi->bmiColors[1].rgbBlue = 0xff;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);

    SelectObject(memdc, old_bm);
    DeleteObject(mono_ds);

    /*
     * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
     */
 
    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0x0;
    pbmi->bmiColors[0].rgbBlue = 0x0;
    pbmi->bmiColors[1].rgbRed = 0xfe;
    pbmi->bmiColors[1].rgbGreen = 0x0;
    pbmi->bmiColors[1].rgbBlue = 0x0;

    mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
    ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
    old_bm = SelectObject(memdc, mono_ds);

    /* black border, white interior */
    Rectangle(memdc, 0, 0, 10, 10);
    ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
    ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);

    /* SetDIBitsToDevice with a normal bmi -> inverted dib section */

    pbmi->bmiColors[0].rgbRed = 0x0;
    pbmi->bmiColors[0].rgbGreen = 0x0;
    pbmi->bmiColors[0].rgbBlue = 0x0;
    pbmi->bmiColors[1].rgbRed = 0xff;
    pbmi->bmiColors[1].rgbGreen = 0xff;
    pbmi->bmiColors[1].rgbBlue = 0xff;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);

    /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */

    pbmi->bmiColors[0].rgbRed = 0xff;
    pbmi->bmiColors[0].rgbGreen = 0xff;
    pbmi->bmiColors[0].rgbBlue = 0xff;
    pbmi->bmiColors[1].rgbRed = 0x0;
    pbmi->bmiColors[1].rgbGreen = 0x0;
    pbmi->bmiColors[1].rgbBlue = 0x0;

    SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
    ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);

    SelectObject(memdc, old_bm);
    DeleteObject(mono_ds);

    DeleteDC(memdc);
    ReleaseDC(0, hdc);
}

static void test_bitmap(void)
{
    char buf[256], buf_cmp[256];
    HBITMAP hbmp, hbmp_old;
    HDC hdc;
    BITMAP bm;
    INT ret;

    hdc = CreateCompatibleDC(0);
    assert(hdc != 0);

    hbmp = CreateBitmap(15, 15, 1, 1, NULL);
    assert(hbmp != NULL);

    ret = GetObject(hbmp, sizeof(bm), &bm);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
    ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
    ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
    ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
    ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
    ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
    ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);

    assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
    assert(sizeof(buf) == sizeof(buf_cmp));

    ret = GetBitmapBits(hbmp, 0, NULL);
    ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);

    memset(buf_cmp, 0xAA, sizeof(buf_cmp));
    memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);

    memset(buf, 0xAA, sizeof(buf));
    ret = GetBitmapBits(hbmp, sizeof(buf), buf);
    ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
    ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");

    hbmp_old = SelectObject(hdc, hbmp);

    ret = GetObject(hbmp, sizeof(bm), &bm);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
    ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
    ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
    ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
    ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
    ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
    ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);

    memset(buf, 0xAA, sizeof(buf));
    ret = GetBitmapBits(hbmp, sizeof(buf), buf);
    ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
    ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");

    hbmp_old = SelectObject(hdc, hbmp_old);
    ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);

    /* test various buffer sizes for GetObject */
    ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
    ok(ret == sizeof(bm), "wrong size %d\n", ret);

    ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbmp, 0, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    ret = GetObject(hbmp, 1, &bm);
    ok(ret == 0, "%d != 0\n", ret);

    DeleteObject(hbmp);
    DeleteDC(hdc);
}

static void test_bmBits(void)
{
    BYTE bits[4];
    HBITMAP hbmp;
    BITMAP bmp;

    memset(bits, 0, sizeof(bits));
    hbmp = CreateBitmap(2, 2, 1, 4, bits);
    ok(hbmp != NULL, "CreateBitmap failed\n");

    memset(&bmp, 0xFF, sizeof(bmp));
    ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
       "GetObject failed or returned a wrong structure size\n");
    ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");

    DeleteObject(hbmp);
}

static void test_GetDIBits_selected_DIB(UINT bpp)
{
    HBITMAP dib;
    BITMAPINFO * info;
    BITMAPINFO * info2;
    void * bits;
    void * bits2;
    UINT dib_size;
    HDC dib_dc, dc;
    HBITMAP old_bmp;
    BOOL equalContents;
    UINT i;
    int res;

    /* Create a DIB section with a color table */

    info  = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
    info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
    assert(info);
    assert(info2);

    info->bmiHeader.biSize = sizeof(info->bmiHeader);

    /* Choose width and height such that the row length (in bytes)
       is a multiple of 4 (makes things easier) */
    info->bmiHeader.biWidth = 32;
    info->bmiHeader.biHeight = 32;
    info->bmiHeader.biPlanes = 1;
    info->bmiHeader.biBitCount = bpp;
    info->bmiHeader.biCompression = BI_RGB;

    for (i=0; i < (1 << bpp); i++)
    {
        BYTE c = i * (1 << (8 - bpp));
        info->bmiColors[i].rgbRed = c;
        info->bmiColors[i].rgbGreen = c;
        info->bmiColors[i].rgbBlue = c;
        info->bmiColors[i].rgbReserved = 0;
    }

    dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
    assert(dib);
    dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;

    /* Set the bits of the DIB section */
    for (i=0; i < dib_size; i++)
    {
        ((BYTE *)bits)[i] = i % 256;
    }

    /* Select the DIB into a DC */
    dib_dc = CreateCompatibleDC(NULL);
    old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
    dc = CreateCompatibleDC(NULL);
    bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
    assert(bits2);

    /* Copy the DIB attributes but not the color table */
    memcpy(info2, info, sizeof(BITMAPINFOHEADER));

    res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
    ok(res, "GetDIBits failed\n");

    /* Compare the color table and the bits */
    equalContents = TRUE;
    for (i=0; i < (1 << bpp); i++)
    {
        if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
            || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
            || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
            || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
        {
            equalContents = FALSE;
            break;
        }
    }
    todo_wine
    {
        ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
    }

    equalContents = TRUE;
    for (i=0; i < dib_size / sizeof(DWORD); i++)
    {
        if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
        {
            equalContents = FALSE;
            break;
        }
    }
    todo_wine
    {
        ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB bits\n");
    }

    HeapFree(GetProcessHeap(), 0, bits2);
    DeleteDC(dc);

    SelectObject(dib_dc, old_bmp);
    DeleteDC(dib_dc);
    DeleteObject(dib);

    HeapFree(GetProcessHeap(), 0, info2);
    HeapFree(GetProcessHeap(), 0, info);
}

static void test_GetDIBits_selected_DDB(BOOL monochrome)
{
    HBITMAP ddb;
    BITMAPINFO * info;
    BITMAPINFO * info2;
    void * bits;
    void * bits2;
    HDC ddb_dc, dc;
    HBITMAP old_bmp;
    BOOL equalContents;
    UINT width, height;
    UINT bpp;
    UINT i, j;
    int res;

    width = height = 16;

    /* Create a DDB (device-dependent bitmap) */
    if (monochrome)
    {
        bpp = 1;
        ddb = CreateBitmap(width, height, 1, 1, NULL);
    }
    else
    {
        HDC screen_dc = GetDC(NULL);
        bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
        ddb = CreateCompatibleBitmap(screen_dc, width, height);
        ReleaseDC(NULL, screen_dc);
    }

    /* Set the pixels */
    ddb_dc = CreateCompatibleDC(NULL);
    old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
    for (i = 0; i < width; i++)
    {
        for (j=0; j < height; j++)
        {
            BYTE c = (i * width + j) % 256;
            SetPixelV(ddb_dc, i, j, RGB(c, c, c));
        }
    }
    SelectObject(ddb_dc, old_bmp);

    info  = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    assert(info);
    assert(info2);

    info->bmiHeader.biSize = sizeof(info->bmiHeader);
    info->bmiHeader.biWidth = width;
    info->bmiHeader.biHeight = height;
    info->bmiHeader.biPlanes = 1;
    info->bmiHeader.biBitCount = bpp;
    info->bmiHeader.biCompression = BI_RGB;

    dc = CreateCompatibleDC(NULL);

    /* Fill in biSizeImage */
    GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
    ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");

    bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
    bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
    assert(bits);
    assert(bits2);

    /* Get the bits */
    res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
    ok(res, "GetDIBits failed\n");

    /* Copy the DIB attributes but not the color table */
    memcpy(info2, info, sizeof(BITMAPINFOHEADER));

    /* Select the DDB into another DC */
    old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);

    /* Get the bits */
    res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
    ok(res, "GetDIBits failed\n");

    /* Compare the color table and the bits */
    if (bpp <= 8)
    {
        equalContents = TRUE;
        for (i=0; i < (1 << bpp); i++)
        {
            if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
                || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
                || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
                || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
            {
                equalContents = FALSE;
                break;
            }
        }
        ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
    }

    equalContents = TRUE;
    for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
    {
        if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
        {
            equalContents = FALSE;
        }
    }
    ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");

    HeapFree(GetProcessHeap(), 0, bits2);
    HeapFree(GetProcessHeap(), 0, bits);
    DeleteDC(dc);

    SelectObject(ddb_dc, old_bmp);
    DeleteDC(ddb_dc);
    DeleteObject(ddb);

    HeapFree(GetProcessHeap(), 0, info2);
    HeapFree(GetProcessHeap(), 0, info);
}

START_TEST(bitmap)
{
    is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;

    test_createdibitmap();
    test_dibsections();
    test_mono_dibsection();
    test_bitmap();
    test_bmBits();
    test_GetDIBits_selected_DIB(1);
    test_GetDIBits_selected_DIB(4);
    test_GetDIBits_selected_DIB(8);
    test_GetDIBits_selected_DDB(TRUE);
    test_GetDIBits_selected_DDB(FALSE);
}
