[PATCH 1/3] windowscodecs: Implement IWICBitmapFrameEncode::SetPalette in PNG encoder.

Nikolay Sivov nsivov at codeweavers.com
Thu Jan 26 15:35:08 CST 2017


From: Dmitry Timoshkov <dmitry at baikal.ru>

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/windowscodecs/pngformat.c       | 23 ++++++++++++++---
 dlls/windowscodecs/tests/converter.c | 48 ++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 9a841626ab..990dcf6ecf 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -1363,6 +1363,8 @@ typedef struct PngEncoder {
     BYTE *data;
     UINT stride;
     UINT passes;
+    WICColor palette[256];
+    UINT colors;
 } PngEncoder;
 
 static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
@@ -1554,10 +1556,24 @@ static HRESULT WINAPI PngFrameEncode_SetColorContexts(IWICBitmapFrameEncode *ifa
 }
 
 static HRESULT WINAPI PngFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
-    IWICPalette *pIPalette)
+    IWICPalette *palette)
 {
-    FIXME("(%p,%p): stub\n", iface, pIPalette);
-    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+    PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
+    HRESULT hr;
+
+    TRACE("(%p,%p)\n", iface, palette);
+
+    if (!palette) return E_INVALIDARG;
+
+    EnterCriticalSection(&This->lock);
+
+    if (This->frame_initialized)
+        hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
+    else
+        hr = WINCODEC_ERR_NOTINITIALIZED;
+
+    LeaveCriticalSection(&This->lock);
+    return hr;
 }
 
 static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
@@ -2081,6 +2097,7 @@ HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv)
     This->frame_committed = FALSE;
     This->committed = FALSE;
     This->data = NULL;
+    This->colors = 0;
     InitializeCriticalSection(&This->lock);
     This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
 
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c
index 2af985785c..9da82f1665 100644
--- a/dlls/windowscodecs/tests/converter.c
+++ b/dlls/windowscodecs/tests/converter.c
@@ -25,6 +25,7 @@
 #include "windef.h"
 #include "objbase.h"
 #include "wincodec.h"
+#include "wincodecsdk.h"
 #include "wine/test.h"
 
 typedef struct bitmap_data {
@@ -577,6 +578,50 @@ struct setting {
     void *value;
 };
 
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
+static void _expect_ref(IUnknown* obj, ULONG ref, int line)
+{
+    ULONG rc;
+    IUnknown_AddRef(obj);
+    rc = IUnknown_Release(obj);
+    ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
+}
+
+static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode)
+{
+    IWICComponentFactory *factory;
+    IWICPalette *palette;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IWICComponentFactory, (void **)&factory);
+    ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
+
+    hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
+    ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
+
+    hr = IWICComponentFactory_CreatePalette(factory, &palette);
+    ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr);
+
+    hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
+todo_wine
+    ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr);
+
+    hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE);
+    ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr);
+
+    EXPECT_REF(palette, 1);
+    hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
+    ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr);
+    EXPECT_REF(palette, 1);
+
+    hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
+    ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
+
+    IWICPalette_Release(palette);
+    IWICComponentFactory_Release(factory);
+}
+
 static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
     const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc,
     const struct setting *settings, const char *name)
@@ -655,6 +700,9 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls
                     hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height);
                     ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr);
 
+                    if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
+                        test_set_frame_palette(frameencode);
+
                     hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc);
                     if (rc && (rc->Width <= 0 || rc->Height <= 0))
                     {
-- 
2.11.0




More information about the wine-patches mailing list