Commit 4d55359f authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

windowscodecs: Use the BMP decoder to decode ICO frames.

parent 870afcdd
...@@ -68,8 +68,7 @@ typedef struct { ...@@ -68,8 +68,7 @@ typedef struct {
typedef struct { typedef struct {
const IWICBitmapFrameDecodeVtbl *lpVtbl; const IWICBitmapFrameDecodeVtbl *lpVtbl;
LONG ref; LONG ref;
ICONDIRENTRY entry; UINT width, height;
IcoDecoder *parent;
BYTE *bits; BYTE *bits;
} IcoFrameDecode; } IcoFrameDecode;
...@@ -116,7 +115,6 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface) ...@@ -116,7 +115,6 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
if (ref == 0) if (ref == 0)
{ {
IUnknown_Release((IUnknown*)This->parent);
HeapFree(GetProcessHeap(), 0, This->bits); HeapFree(GetProcessHeap(), 0, This->bits);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
...@@ -129,8 +127,8 @@ static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface, ...@@ -129,8 +127,8 @@ static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
{ {
IcoFrameDecode *This = (IcoFrameDecode*)iface; IcoFrameDecode *This = (IcoFrameDecode*)iface;
*puiWidth = This->entry.bWidth ? This->entry.bWidth : 256; *puiWidth = This->width;
*puiHeight = This->entry.bHeight ? This->entry.bHeight : 256; *puiHeight = This->height;
TRACE("(%p) -> (%i,%i)\n", iface, *puiWidth, *puiHeight); TRACE("(%p) -> (%i,%i)\n", iface, *puiWidth, *puiHeight);
...@@ -158,378 +156,13 @@ static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, ...@@ -158,378 +156,13 @@ static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
return WINCODEC_ERR_PALETTEUNAVAILABLE; return WINCODEC_ERR_PALETTEUNAVAILABLE;
} }
static inline void pixel_set_trans(DWORD* pixel, BOOL transparent)
{
if (transparent) *pixel = 0;
else *pixel |= 0xff000000;
}
static HRESULT IcoFrameDecode_ReadPixels(IcoFrameDecode *This)
{
BITMAPINFOHEADER bih;
DWORD colors[256];
UINT colorcount=0;
LARGE_INTEGER seek;
ULONG bytesread;
HRESULT hr;
BYTE *tempdata = NULL;
BYTE *bits = NULL;
UINT bitsStride;
UINT bitsSize;
UINT width, height;
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
/* read the BITMAPINFOHEADER */
seek.QuadPart = This->entry.dwDIBOffset;
hr = IStream_Seek(This->parent->stream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
hr = IStream_Read(This->parent->stream, &bih, sizeof(BITMAPINFOHEADER), &bytesread);
if (FAILED(hr) || bytesread != sizeof(BITMAPINFOHEADER)) goto fail;
if (bih.biBitCount <= 8)
{
/* read the palette */
colorcount = bih.biClrUsed ? bih.biClrUsed : 1 << bih.biBitCount;
hr = IStream_Read(This->parent->stream, colors, sizeof(RGBQUAD)*colorcount, &bytesread);
if (FAILED(hr) || bytesread != sizeof(RGBQUAD)*colorcount) goto fail;
}
bitsStride = width * 4;
bitsSize = bitsStride * height;
/* read the XOR data */
switch (bih.biBitCount)
{
case 1:
{
UINT xorBytesPerRow = (width+31)/32*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 1-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>7];
if (x+1 < width) *bitsPixel++ = colors[xorVal>>6&1];
if (x+2 < width) *bitsPixel++ = colors[xorVal>>5&1];
if (x+3 < width) *bitsPixel++ = colors[xorVal>>4&1];
if (x+4 < width) *bitsPixel++ = colors[xorVal>>3&1];
if (x+5 < width) *bitsPixel++ = colors[xorVal>>2&1];
if (x+6 < width) *bitsPixel++ = colors[xorVal>>1&1];
if (x+7 < width) *bitsPixel++ = colors[xorVal&1];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 4:
{
UINT xorBytesPerRow = (width+7)/8*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 4-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=2) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>4];
if (x+1 < width) *bitsPixel++ = colors[xorVal&0xf];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 8:
{
UINT xorBytesPerRow = (width+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 8-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x++)
*bitsPixel++ = colors[*xorByte++];
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 24:
{
UINT xorBytesPerRow = (width*3+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* copy BGR->BGRA */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
BYTE *bitsByte=bitsRow;
for (x=0; x<width; x++)
{
*bitsByte++ = *xorByte++; /* blue */
*bitsByte++ = *xorByte++; /* green */
*bitsByte++ = *xorByte++; /* red */
bitsByte++; /* alpha */
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 32:
{
UINT xorBytesPerRow = width*4;
UINT xorBytes = xorBytesPerRow * height;
bits = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!bits)
{
hr = E_OUTOFMEMORY;
goto fail;
}
if (bih.biHeight > 0) /* bottom-up DIB */
{
/* read the rows backwards so we get a top-down DIB */
UINT i;
BYTE *xorRow = bits + xorBytesPerRow * (height-1);
for (i=0; i<height; i++)
{
hr = IStream_Read(This->parent->stream, xorRow, xorBytesPerRow, &bytesread);
if (FAILED(hr) || bytesread != xorBytesPerRow) goto fail;
xorRow -= xorBytesPerRow;
}
}
else /* top-down DIB */
{
hr = IStream_Read(This->parent->stream, bits, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
}
break;
}
default:
FIXME("unsupported bitcount: %u\n", bih.biBitCount);
goto fail;
}
if (bih.biBitCount < 32)
{
/* set alpha data based on the AND mask */
UINT andBytesPerRow = (width+31)/32*4;
UINT andBytes = andBytesPerRow * height;
INT andStride;
BYTE *andRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, andBytes, &bytesread);
if (FAILED(hr) || bytesread != andBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
andStride = -andBytesPerRow;
andRow = tempdata + (height-1)*andBytesPerRow;
}
else /* top-down DIB */
{
andStride = andBytesPerRow;
andRow = tempdata;
}
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *andByte=andRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE andVal=*andByte++;
pixel_set_trans(bitsPixel++, andVal>>7&1);
if (x+1 < width) pixel_set_trans(bitsPixel++, andVal>>6&1);
if (x+2 < width) pixel_set_trans(bitsPixel++, andVal>>5&1);
if (x+3 < width) pixel_set_trans(bitsPixel++, andVal>>4&1);
if (x+4 < width) pixel_set_trans(bitsPixel++, andVal>>3&1);
if (x+5 < width) pixel_set_trans(bitsPixel++, andVal>>2&1);
if (x+6 < width) pixel_set_trans(bitsPixel++, andVal>>1&1);
if (x+7 < width) pixel_set_trans(bitsPixel++, andVal&1);
}
andRow += andStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
}
This->bits = bits;
return S_OK;
fail:
HeapFree(GetProcessHeap(), 0, tempdata);
HeapFree(GetProcessHeap(), 0, bits);
if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr);
return hr;
}
static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{ {
IcoFrameDecode *This = (IcoFrameDecode*)iface; IcoFrameDecode *This = (IcoFrameDecode*)iface;
HRESULT hr=S_OK;
UINT width, height, stride;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
EnterCriticalSection(&This->parent->lock); return copy_pixels(32, This->bits, This->width, This->height, This->width * 4,
if (!This->bits)
{
hr = IcoFrameDecode_ReadPixels(This);
}
LeaveCriticalSection(&This->parent->lock);
if (FAILED(hr)) return hr;
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
stride = width * 4;
return copy_pixels(32, This->bits, width, height, stride,
prc, cbStride, cbBufferSize, pbBuffer); prc, cbStride, cbBufferSize, pbBuffer);
} }
...@@ -568,6 +201,148 @@ static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = { ...@@ -568,6 +201,148 @@ static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = {
IcoFrameDecode_GetThumbnail IcoFrameDecode_GetThumbnail
}; };
static inline void pixel_set_trans(DWORD* pixel, BOOL transparent)
{
if (transparent) *pixel = 0;
else *pixel |= 0xff000000;
}
static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result)
{
HRESULT hr;
IWICBitmapDecoder *decoder;
IWICBitmapFrameDecode *framedecode;
WICPixelFormatGUID pixelformat;
IWICBitmapSource *source;
int has_alpha=FALSE; /* if TRUE, alpha data might be in the image data */
WICRect rc;
hr = IcoDibDecoder_CreateInstance(NULL, &IID_IWICBitmapDecoder, (void**)&decoder);
if (SUCCEEDED(hr))
{
hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
if (SUCCEEDED(hr))
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
if (SUCCEEDED(hr))
{
hr = IWICBitmapFrameDecode_GetSize(framedecode, &result->width, &result->height);
if (SUCCEEDED(hr))
{
result->bits = HeapAlloc(GetProcessHeap(), 0, result->width * result->height * 4);
if (!result->bits) hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat);
if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat32bppBGR) ||
IsEqualGUID(&pixelformat, &GUID_WICPixelFormat32bppBGRA))
{
source = (IWICBitmapSource*)framedecode;
IWICBitmapSource_AddRef(source);
has_alpha = TRUE;
}
else
{
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
(IWICBitmapSource*)framedecode, &source);
has_alpha = FALSE;
}
if (SUCCEEDED(hr))
{
rc.X = 0;
rc.Y = 0;
rc.Width = result->width;
rc.Height = result->height;
hr = IWICBitmapSource_CopyPixels(source, &rc, result->width * 4,
result->width * result->height * 4, result->bits);
IWICBitmapSource_Release(source);
}
IWICBitmapFrameDecode_Release(framedecode);
}
if (SUCCEEDED(hr) && !has_alpha)
{
/* set alpha data based on the AND mask */
UINT andBytesPerRow = (result->width+31)/32*4;
UINT andBytes = andBytesPerRow * result->height;
INT andStride;
BYTE *tempdata=NULL;
BYTE *andRow;
BYTE *bitsRow;
UINT bitsStride = result->width * 4;
UINT x, y;
ULONG offset;
ULONG bytesread;
LARGE_INTEGER seek;
int topdown;
BmpDecoder_FindIconMask(decoder, &offset, &topdown);
if (offset)
{
seek.QuadPart = offset;
hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, 0);
if (SUCCEEDED(hr))
{
tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes);
if (!tempdata) hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
hr = IStream_Read(stream, tempdata, andBytes, &bytesread);
if (SUCCEEDED(hr) && bytesread == andBytes)
{
if (topdown)
{
andStride = andBytesPerRow;
andRow = tempdata;
}
else
{
andStride = -andBytesPerRow;
andRow = tempdata + (result->height-1)*andBytesPerRow;
}
bitsRow = result->bits;
for (y=0; y<result->height; y++) {
BYTE *andByte=andRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<result->width; x+=8) {
BYTE andVal=*andByte++;
pixel_set_trans(bitsPixel++, andVal>>7&1);
if (x+1 < result->width) pixel_set_trans(bitsPixel++, andVal>>6&1);
if (x+2 < result->width) pixel_set_trans(bitsPixel++, andVal>>5&1);
if (x+3 < result->width) pixel_set_trans(bitsPixel++, andVal>>4&1);
if (x+4 < result->width) pixel_set_trans(bitsPixel++, andVal>>3&1);
if (x+5 < result->width) pixel_set_trans(bitsPixel++, andVal>>2&1);
if (x+6 < result->width) pixel_set_trans(bitsPixel++, andVal>>1&1);
if (x+7 < result->width) pixel_set_trans(bitsPixel++, andVal&1);
}
andRow += andStride;
bitsRow += bitsStride;
}
}
HeapFree(GetProcessHeap(), 0, tempdata);
}
}
IWICBitmapDecoder_Release(decoder);
}
return hr;
}
static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv) void **ppv)
{ {
...@@ -736,8 +511,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, ...@@ -736,8 +511,12 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
IcoDecoder *This = (IcoDecoder*)iface; IcoDecoder *This = (IcoDecoder*)iface;
IcoFrameDecode *result=NULL; IcoFrameDecode *result=NULL;
LARGE_INTEGER seek; LARGE_INTEGER seek;
ULARGE_INTEGER offset, length;
HRESULT hr; HRESULT hr;
ULONG bytesread; ULONG bytesread;
ICONDIRENTRY entry;
IWICStream *substream=NULL;
DWORD magic;
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
EnterCriticalSection(&This->lock); EnterCriticalSection(&This->lock);
...@@ -763,7 +542,6 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, ...@@ -763,7 +542,6 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
result->lpVtbl = &IcoFrameDecode_Vtbl; result->lpVtbl = &IcoFrameDecode_Vtbl;
result->ref = 1; result->ref = 1;
result->parent = This;
result->bits = NULL; result->bits = NULL;
/* read the icon entry */ /* read the icon entry */
...@@ -771,10 +549,42 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, ...@@ -771,10 +549,42 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, 0); hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, 0);
if (FAILED(hr)) goto fail; if (FAILED(hr)) goto fail;
hr = IStream_Read(This->stream, &result->entry, sizeof(ICONDIRENTRY), &bytesread); hr = IStream_Read(This->stream, &entry, sizeof(ICONDIRENTRY), &bytesread);
if (FAILED(hr) || bytesread != sizeof(ICONDIRENTRY)) goto fail; if (FAILED(hr) || bytesread != sizeof(ICONDIRENTRY)) goto fail;
IWICBitmapDecoder_AddRef(iface); /* create a stream object for this icon */
hr = StreamImpl_Create(&substream);
if (FAILED(hr)) goto fail;
offset.QuadPart = entry.dwDIBOffset;
length.QuadPart = entry.dwDIBSize;
hr = IWICStream_InitializeFromIStreamRegion(substream, This->stream, offset, length);
if (FAILED(hr)) goto fail;
/* read the bitmapinfo size or magic number */
hr = IWICStream_Read(substream, &magic, sizeof(magic), &bytesread);
if (FAILED(hr) || bytesread != sizeof(magic)) goto fail;
/* forward to the appropriate decoding function based on the magic number */
switch (magic)
{
case sizeof(BITMAPCOREHEADER):
case 64: /* sizeof(BITMAPCOREHEADER2) */
case sizeof(BITMAPINFOHEADER):
case sizeof(BITMAPV4HEADER):
case sizeof(BITMAPV5HEADER):
hr = ReadIcoDib((IStream*)substream, result);
break;
case 0x474e5089:
FIXME("PNG decoding not supported\n");
hr = E_FAIL;
break;
default:
FIXME("Unrecognized ICO frame magic: %x\n", magic);
hr = E_FAIL;
break;
}
if (FAILED(hr)) goto fail;
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result; *ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
...@@ -785,6 +595,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, ...@@ -785,6 +595,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
fail: fail:
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, result); HeapFree(GetProcessHeap(), 0, result);
if (substream) IStream_Release(substream);
if (SUCCEEDED(hr)) hr = E_FAIL; if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr); TRACE("<-- %x\n", hr);
return hr; return hr;
......
...@@ -136,7 +136,7 @@ static void test_bad_icondirentry_size(void) ...@@ -136,7 +136,7 @@ static void test_bad_icondirentry_size(void)
UINT width = 0, height = 0; UINT width = 0, height = 0;
hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr); ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr);
todo_wine ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height); ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height);
IWICBitmapFrameDecode_Release(framedecode); IWICBitmapFrameDecode_Release(framedecode);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment