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>>