Vincent Povirk : windowscodecs: Implement CopyPalette for BMP decoder.
Alexandre Julliard
julliard at winehq.org
Tue Jul 7 08:08:18 CDT 2009
Module: wine
Branch: master
Commit: 3899c3e2472b22156ab2a2e7aeff65ef0212cfe3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3899c3e2472b22156ab2a2e7aeff65ef0212cfe3
Author: Vincent Povirk <vincent at 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;
More information about the wine-cvs
mailing list