Maybe the format for 32-bit bitmaps should be determined by the alpha channel options?<br><br>On Monday, September 16, 2013, Dmitry Timoshkov <<a href="mailto:dmitry@baikal.ru">dmitry@baikal.ru</a>> wrote:<br>> Based on a gdiplus implementation.<br>
> ---<br>>  dlls/windowscodecs/imgfactory.c   | 149 +++++++++++++++++++++++++++++++++++++-<br>>  dlls/windowscodecs/tests/bitmap.c |  14 ++--<br>>  2 files changed, 154 insertions(+), 9 deletions(-)<br>><br>
> diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c<br>> index e5f2125..bb4cf67 100644<br>> --- a/dlls/windowscodecs/imgfactory.c<br>> +++ b/dlls/windowscodecs/imgfactory.c<br>> @@ -603,12 +603,153 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto<br>
>      return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);<br>>  }<br>><br>> +static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)<br>> +{<br>
> +    BOOL ret = TRUE;<br>> +    BITMAPV4HEADER bmh;<br>> +    HDC hdc;<br>> +<br>> +    hdc = CreateCompatibleDC(0);<br>> +<br>> +    memset(&bmh, 0, sizeof(bmh));<br>> +    bmh.bV4Size = sizeof(bmh);<br>
> +    bmh.bV4Width = 1;<br>> +    bmh.bV4Height = 1;<br>> +    bmh.bV4V4Compression = BI_BITFIELDS;<br>> +    bmh.bV4BitCount = 16;<br>> +<br>> +    GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO *)&ji, DIB_RGB_COLORS);<br>
> +<br>> +    if (bmh.bV4RedMask == 0x7c00 &&<br>> +        bmh.bV4GreenMask == 0x3e0 &&<br>> +        bmh.bV4BlueMask == 0x1f)<br>> +    {<br>> +        *format = GUID_WICPixelFormat16bppBGR555;<br>
> +    }<br>> +    else if (bmh.bV4RedMask == 0xf800 &&<br>> +        bmh.bV4GreenMask == 0x7e0 &&<br>> +        bmh.bV4BlueMask == 0x1f)<br>> +    {<br>> +        *format = GUID_WICPixelFormat16bppBGR565;<br>
> +    }<br>> +    else<br>> +    {<br>> +        FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask,<br>> +            bmh.bV4GreenMask, bmh.bV4BlueMask);<br>> +        ret = FALSE;<br>
> +    }<br>> +<br>> +    DeleteDC(hdc);<br>> +    return ret;<br>> +}<br>> +<br>>  static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,<br>> -    HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options,<br>
> -    IWICBitmap **ppIBitmap)<br>> +    HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)<br>>  {<br>> -    FIXME("(%p,%p,%p,%u,%p): stub\n", iface, hBitmap, hPalette, options, ppIBitmap);<br>
> -    return E_NOTIMPL;<br>> +    BITMAP bm;<br>> +    HRESULT hr;<br>> +    WICPixelFormatGUID format;<br>> +    IWICBitmapLock *lock;<br>> +    UINT size, num_palette_entries = 0;<br>> +    PALETTEENTRY entry[256];<br>
> +<br>> +    TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap);<br>> +<br>> +    if (!bitmap) return E_INVALIDARG;<br>> +<br>> +    if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm))<br>
> +        return WINCODEC_ERR_WIN32ERROR;<br>> +<br>> +    if (hpal)<br>> +    {<br>> +        num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry);<br>> +        if (!num_palette_entries)<br>> +            return WINCODEC_ERR_WIN32ERROR;<br>
> +    }<br>> +<br>> +    /* TODO: Figure out the correct format for 16, 32, 64 bpp */<br>> +    switch(bm.bmBitsPixel)<br>> +    {<br>> +    case 1:<br>> +        format = GUID_WICPixelFormat1bppIndexed;<br>
> +        break;<br>> +    case 4:<br>> +        format = GUID_WICPixelFormat4bppIndexed;<br>> +        break;<br>> +    case 8:<br>> +        format = GUID_WICPixelFormat8bppIndexed;<br>> +        break;<br>
> +    case 16:<br>> +        if (!get_16bpp_format(hbm, &format))<br>> +            return E_INVALIDARG;<br>> +        break;<br>> +    case 24:<br>> +        format = GUID_WICPixelFormat24bppBGR;<br>
> +        break;<br>> +    case 32:<br>> +        format = GUID_WICPixelFormat32bppBGR;<br>> +        break;<br>> +    case 48:<br>> +        format = GUID_WICPixelFormat48bppRGB;<br>> +        break;<br>
> +    default:<br>> +        FIXME("unsupported %d bpp\n", bm.bmBitsPixel);<br>> +        return E_INVALIDARG;<br>> +    }<br>> +<br>> +    hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, option, bitmap);<br>
> +    if (hr != S_OK) return hr;<br>> +<br>> +    hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);<br>> +    if (hr == S_OK)<br>> +    {<br>> +        BYTE *buffer;<br>> +        HDC hdc;<br>
> +        char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];<br>> +        BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;<br>> +<br>> +        IWICBitmapLock_GetDataPointer(lock, &size, &buffer);<br>> +<br>
> +        hdc = CreateCompatibleDC(0);<br>> +<br>> +        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);<br>> +        bmi->bmiHeader.biBitCount = 0;<br>> +        GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS);<br>
> +        bmi->bmiHeader.biHeight = -bm.bmHeight;<br>> +        GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS);<br>> +<br>> +        DeleteDC(hdc);<br>> +        IWICBitmapLock_Release(lock);<br>
> +<br>> +        if (num_palette_entries)<br>> +        {<br>> +            IWICPalette *palette;<br>> +            WICColor colors[256];<br>> +            UINT i;<br>> +<br>> +            hr = PaletteImpl_Create(&palette);<br>
> +            if (hr == S_OK)<br>> +            {<br>> +                for (i = 0; i < num_palette_entries; i++)<br>> +                    colors[i] = 0xff000000 | entry[i].peRed << 16 |<br>> +                                entry[i].peGreen << 8 | entry[i].peBlue;<br>
> +<br>> +                hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries);<br>> +                if (hr == S_OK)<br>> +                    hr = IWICBitmap_SetPalette(*bitmap, palette);<br>
> +<br>> +                IWICPalette_Release(palette);<br>> +            }<br>> +        }<br>> +    }<br>> +<br>> +    if (hr != S_OK)<br>> +    {<br>> +        IWICBitmap_Release(*bitmap);<br>
> +        *bitmap = NULL;<br>> +    }<br>> +<br>> +    return hr;<br>>  }<br>><br>>  static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface,<br>> diff --git a/dlls/windowscodecs/tests/bitmap.c b/dlls/windowscodecs/tests/bitmap.c<br>
> index 8795048..3c79ce8 100644<br>> --- a/dlls/windowscodecs/tests/bitmap.c<br>> +++ b/dlls/windowscodecs/tests/bitmap.c<br>> @@ -727,17 +727,13 @@ static void test_CreateBitmapFromHBITMAP(void)<br>>      ok(hbmp != 0, "failed to create bitmap\n");<br>
><br>>      hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapIgnoreAlpha, &bitmap);<br>> -todo_wine<br>>      ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr);<br>
><br>>      hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, NULL);<br>> -todo_wine<br>>      ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);<br>
><br>>      hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, &bitmap);<br>> -todo_wine<br>>      ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);<br>
> -    if (hr != S_OK) return;<br>><br>>      IWICBitmap_GetPixelFormat(bitmap, &format);<br>>      ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),<br>> @@ -770,6 +766,7 @@ todo_wine<br>
>      ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);<br>><br>>      IWICBitmap_GetPixelFormat(bitmap, &format);<br>> +todo_wine<br>>      ok(IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed),<br>
>         "unexpected pixel format %s\n", debugstr_guid(&format));<br>><br>> @@ -789,6 +786,7 @@ todo_wine<br>><br>>      hr = IWICPalette_GetColorCount(palette, &count);<br>>      ok(hr == S_OK, "GetColorCount error %#x\n", hr);<br>
> +todo_wine<br>>      ok(count == 16, "expected 16, got %u\n", count);<br>><br>>      IWICPalette_Release(palette);<br>> @@ -837,7 +835,13 @@ todo_wine<br>>      hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data);<br>
>      ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);<br>>      for (i = 0; i < sizeof(data); i++)<br>> -        ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]);<br>
> +    {<br>> +        if (data[i] != data_8bpp_pal_wic[i])<br>> +todo_wine<br>> +            ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]);<br>
> +        else<br>> +            ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]);<br>> +    }<br>><br>>      IWICBitmap_Release(bitmap);<br>>      DeleteObject(hbmp);<br>
> --<br>> 1.8.3.4<br>><br>><br>><br>>