Module: wine Branch: master Commit: 3899c3e2472b22156ab2a2e7aeff65ef0212cfe3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3899c3e2472b22156ab2a2e7ae...
Author: Vincent Povirk vincent@codeweavers.com Date: Mon Jul 6 11:39:29 2009 -0500
windowscodecs: Implement CopyPalette for BMP decoder.
---
dlls/windowscodecs/bmpdecode.c | 102 ++++++++++++++++++++++++++++++++- dlls/windowscodecs/tests/bmpformat.c | 24 ++++++++ include/wincodec.idl | 1 + 3 files changed, 123 insertions(+), 4 deletions(-)
diff --git a/dlls/windowscodecs/bmpdecode.c b/dlls/windowscodecs/bmpdecode.c index b81987c..61d68c1 100644 --- a/dlls/windowscodecs/bmpdecode.c +++ b/dlls/windowscodecs/bmpdecode.c @@ -189,8 +189,101 @@ static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { - FIXME("(%p,%p): stub\n", iface, pIPalette); - return E_NOTIMPL; + HRESULT hr; + BmpFrameDecode *This = (BmpFrameDecode*)iface; + TRACE("(%p,%p)\n", iface, pIPalette); + + if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) + { + BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; + if (bch->bcBitCount <= 8) + { + /* 2**n colors in BGR format after the header */ + int count = 1 << bch->bcBitCount; + WICColor *wiccolors; + ULONG tablesize, bytesread; + RGBTRIPLE *bgrcolors; + LARGE_INTEGER offset; + int i; + + wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); + tablesize = sizeof(RGBTRIPLE) * count; + bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + if (!wiccolors || !bgrcolors) + { + HeapFree(GetProcessHeap(), 0, wiccolors); + HeapFree(GetProcessHeap(), 0, bgrcolors); + return E_OUTOFMEMORY; + } + + offset.QuadPart = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER); + hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) return hr; + + hr = IStream_Read(This->stream, bgrcolors, tablesize, &bytesread); + if (FAILED(hr)) return hr; + if (bytesread != tablesize) return E_FAIL; + + for (i=0; i<count; i++) + { + wiccolors[i] = 0xff000000| + (bgrcolors[i].rgbtRed<<16)| + (bgrcolors[i].rgbtGreen<<8)| + bgrcolors[i].rgbtBlue; + } + + hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); + + HeapFree(GetProcessHeap(), 0, wiccolors); + HeapFree(GetProcessHeap(), 0, bgrcolors); + return hr; + } + else + { + return WINCODEC_ERR_PALETTEUNAVAILABLE; + } + } + else + { + if (This->bih.bV5BitCount <= 8) + { + int count; + WICColor *wiccolors; + ULONG tablesize, bytesread; + LARGE_INTEGER offset; + int i; + + if (This->bih.bV5ClrUsed == 0) + count = 1 << This->bih.bV5BitCount; + else + count = This->bih.bV5ClrUsed; + + tablesize = sizeof(WICColor) * count; + wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + if (!wiccolors) return E_OUTOFMEMORY; + + offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size; + hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) return hr; + + hr = IStream_Read(This->stream, wiccolors, tablesize, &bytesread); + if (FAILED(hr)) return hr; + if (bytesread != tablesize) return E_FAIL; + + /* convert from BGR to BGRA by setting alpha to 100% */ + for (i=0; i<count; i++) + wiccolors[i] |= 0xff000000; + + hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); + + HeapFree(GetProcessHeap(), 0, wiccolors); + return hr; + } + else + { + return WINCODEC_ERR_PALETTEUNAVAILABLE; + } + } }
static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, @@ -536,8 +629,9 @@ static HRESULT WINAPI BmpDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, static HRESULT WINAPI BmpDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette *pIPalette) { - FIXME("(%p,%p): stub\n", iface, pIPalette); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, pIPalette); + + return WINCODEC_ERR_PALETTEUNAVAILABLE; }
static HRESULT WINAPI BmpDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, diff --git a/dlls/windowscodecs/tests/bmpformat.c b/dlls/windowscodecs/tests/bmpformat.c index fb6f491..d312e80 100644 --- a/dlls/windowscodecs/tests/bmpformat.c +++ b/dlls/windowscodecs/tests/bmpformat.c @@ -98,6 +98,9 @@ static void test_decode_24bpp(void) ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { + IWICImagingFactory *factory; + IWICPalette *palette; + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); ok(width == 2, "expected width=2, got %u\n", width); @@ -112,6 +115,27 @@ static void test_decode_24bpp(void) ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
+ hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void**)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + + IWICPalette_Release(palette); + } + + IWICImagingFactory_Release(factory); + } + rc.X = 0; rc.Y = 0; rc.Width = 3; diff --git a/include/wincodec.idl b/include/wincodec.idl index e5f22e3..d8712b8 100644 --- a/include/wincodec.idl +++ b/include/wincodec.idl @@ -95,6 +95,7 @@ typedef UINT32 WICColor;
cpp_quote("#define WINCODEC_ERR_WRONGSTATE 0x88982f04") cpp_quote("#define WINCODEC_ERR_CODECNOTHUMBNAIL 0x88982f44") +cpp_quote("#define WINCODEC_ERR_PALETTEUNAVAILABLE 0x88982f45")
interface IWICBitmap; interface IWICComponentInfo;