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