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