windowscodecs: Implement CreateBitmapFromHICON.
This commit is contained in:
parent
d7687bed6a
commit
4ba27f7930
|
@ -1,6 +1,6 @@
|
|||
MODULE = windowscodecs.dll
|
||||
IMPORTLIB = windowscodecs
|
||||
IMPORTS = uuid ole32 oleaut32 shlwapi advapi32 rpcrt4
|
||||
IMPORTS = uuid ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32
|
||||
EXTRAINCL = @PNGINCL@
|
||||
EXTRADEFS = -DENTRY_PREFIX=WIC_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL
|
||||
EXTRALIBS = @APPLICATIONSERVICESLIB@
|
||||
|
|
|
@ -597,10 +597,142 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFact
|
|||
}
|
||||
|
||||
static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface,
|
||||
HICON hIcon, IWICBitmap **ppIBitmap)
|
||||
HICON hicon, IWICBitmap **bitmap)
|
||||
{
|
||||
FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap);
|
||||
return E_NOTIMPL;
|
||||
IWICBitmapLock *lock;
|
||||
ICONINFO info;
|
||||
BITMAP bm;
|
||||
int width, height, x, y;
|
||||
UINT stride, size;
|
||||
BYTE *buffer;
|
||||
DWORD *bits;
|
||||
BITMAPINFO bi;
|
||||
HDC hdc;
|
||||
BOOL has_alpha;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, hicon, bitmap);
|
||||
|
||||
if (!bitmap) return E_INVALIDARG;
|
||||
|
||||
if (!GetIconInfo(hicon, &info))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm);
|
||||
|
||||
width = bm.bmWidth;
|
||||
height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
|
||||
stride = width * 4;
|
||||
size = stride * height;
|
||||
|
||||
hr = BitmapImpl_Create(width, height, stride, size, NULL,
|
||||
&GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap);
|
||||
if (hr != S_OK) goto failed;
|
||||
|
||||
hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
IWICBitmap_Release(*bitmap);
|
||||
goto failed;
|
||||
}
|
||||
IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
||||
bi.bmiHeader.biWidth = width;
|
||||
bi.bmiHeader.biHeight = -height;
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 32;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
has_alpha = FALSE;
|
||||
|
||||
if (info.hbmColor)
|
||||
{
|
||||
GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS);
|
||||
|
||||
if (bm.bmBitsPixel == 32)
|
||||
{
|
||||
/* If any pixel has a non-zero alpha, ignore hbmMask */
|
||||
bits = (DWORD *)buffer;
|
||||
for (x = 0; x < width && !has_alpha; x++, bits++)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
if (*bits & 0xff000000)
|
||||
{
|
||||
has_alpha = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS);
|
||||
|
||||
if (!has_alpha)
|
||||
{
|
||||
DWORD *rgba;
|
||||
|
||||
if (info.hbmMask)
|
||||
{
|
||||
BYTE *mask;
|
||||
|
||||
mask = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (!mask)
|
||||
{
|
||||
IWICBitmapLock_Release(lock);
|
||||
IWICBitmap_Release(*bitmap);
|
||||
DeleteDC(hdc);
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* read alpha data from the mask */
|
||||
GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS);
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
rgba = (DWORD *)(buffer + y * stride);
|
||||
bits = (DWORD *)(mask + y * stride);
|
||||
|
||||
for (x = 0; x < width; x++, rgba++, bits++)
|
||||
{
|
||||
if (!info.hbmColor) *rgba = ~*rgba;
|
||||
|
||||
if (*bits)
|
||||
*rgba = 0;
|
||||
else
|
||||
*rgba |= 0xff000000;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set constant alpha of 255 */
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
rgba = (DWORD *)(buffer + y * stride);
|
||||
for (x = 0; x < width; x++, rgba++)
|
||||
*rgba |= 0xff000000;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IWICBitmapLock_Release(lock);
|
||||
DeleteDC(hdc);
|
||||
|
||||
failed:
|
||||
DeleteObject(info.hbmColor);
|
||||
DeleteObject(info.hbmMask);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface,
|
||||
|
|
|
@ -529,19 +529,15 @@ static void test_CreateBitmapFromHICON(void)
|
|||
DeleteObject(info.hbmMask);
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, NULL);
|
||||
todo_wine
|
||||
ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, &bitmap);
|
||||
todo_wine
|
||||
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#x\n", hr);
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, NULL);
|
||||
todo_wine
|
||||
ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr);
|
||||
DestroyIcon(icon);
|
||||
if (hr != S_OK) return;
|
||||
|
|
Loading…
Reference in New Issue