[PATCH] wincodecs: Recognize FilterOption property in PNG encoder

Nikolay Sivov nsivov at codeweavers.com
Wed Nov 23 03:49:14 CST 2016


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/windowscodecs/pngformat.c       | 29 ++++++++++++++++++++++-------
 dlls/windowscodecs/tests/converter.c | 21 +++++++++++++++++++--
 include/wincodec.idl                 | 11 +++++++++++
 3 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index bb2aef9..0011262 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -40,6 +40,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
 
 static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
+static const WCHAR wszPngFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
 
 static inline ULONG read_ulong_be(BYTE* data)
 {
@@ -1356,6 +1357,7 @@ typedef struct PngEncoder {
     BOOL committed;
     CRITICAL_SECTION lock;
     BOOL interlace;
+    WICPngFilterOption filter;
     BYTE *data;
     UINT stride;
     UINT passes;
@@ -1411,25 +1413,34 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
 {
     PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
     BOOL interlace;
-    PROPBAG2 opts[1]= {{0}};
-    VARIANT opt_values[1];
-    HRESULT opt_hres[1];
+    PROPBAG2 opts[2]= {{0}};
+    VARIANT opt_values[2];
+    HRESULT opt_hres[2];
     HRESULT hr;
 
     TRACE("(%p,%p)\n", iface, pIEncoderOptions);
 
     opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption;
     opts[0].vt = VT_BOOL;
+    opts[1].pstrName = (LPOLESTR)wszPngFilterOption;
+    opts[1].vt = VT_UI1;
 
     if (pIEncoderOptions)
     {
-        hr = IPropertyBag2_Read(pIEncoderOptions, 1, opts, NULL, opt_values, opt_hres);
+        hr = IPropertyBag2_Read(pIEncoderOptions, sizeof(opts)/sizeof(opts[0]), opts, NULL, opt_values, opt_hres);
 
         if (FAILED(hr))
             return hr;
     }
     else
-        memset(opt_values, 0, sizeof(opt_values));
+    {
+        /* InterlaceOption */
+        V_VT(&opt_values[0]) = VT_BOOL;
+        V_BOOL(&opt_values[0]) = FALSE;
+        /* FilterOption */
+        V_VT(&opt_values[1]) = VT_UI1;
+        V_UI1(&opt_values[1]) = WICPngFilterUnspecified;
+    }
 
     if (V_VT(&opt_values[0]) == VT_EMPTY)
         interlace = FALSE;
@@ -1445,6 +1456,7 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
     }
 
     This->interlace = interlace;
+    This->filter = V_UI1(&opt_values[1]);
 
     This->frame_initialized = TRUE;
 
@@ -1926,7 +1938,7 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
 {
     PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
     HRESULT hr;
-    PROPBAG2 opts[1]= {{0}};
+    PROPBAG2 opts[2]= {{0}};
 
     TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
 
@@ -1947,8 +1959,11 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
     opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption;
     opts[0].vt = VT_BOOL;
     opts[0].dwType = PROPBAG2_TYPE_DATA;
+    opts[1].pstrName = (LPOLESTR)wszPngFilterOption;
+    opts[1].vt = VT_UI1;
+    opts[1].dwType = PROPBAG2_TYPE_DATA;
 
-    hr = CreatePropertyBag2(opts, 1, ppIEncoderOptions);
+    hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
     if (FAILED(hr))
     {
         LeaveCriticalSection(&This->lock);
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c
index 7ca201a..17a1789 100644
--- a/dlls/windowscodecs/tests/converter.c
+++ b/dlls/windowscodecs/tests/converter.c
@@ -418,11 +418,13 @@ typedef struct property_opt_test_data
     VARTYPE initial_var_type;
     int i_init_val;
     float f_init_val;
+    BOOL skippable;
 } property_opt_test_data;
 
 static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0};
 static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
 static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
+static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
 
 static const struct property_opt_test_data testdata_tiff_props[] = {
     { wszTiffCompressionMethod, VT_UI1,         VT_UI1,  WICTiffCompressionDontCare },
@@ -430,6 +432,12 @@ static const struct property_opt_test_data testdata_tiff_props[] = {
     { NULL }
 };
 
+static const struct property_opt_test_data testdata_png_props[] = {
+    { wszInterlaceOption, VT_BOOL, VT_BOOL, 0 },
+    { wszFilterOption,    VT_UI1,  VT_UI1, WICPngFilterUnspecified, 0.0f, TRUE /* not supported on XP/2k3 */},
+    { NULL }
+};
+
 static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
 {
     int i;
@@ -456,8 +464,15 @@ static void test_specific_encoder_properties(IPropertyBag2 *options, const prope
 
         hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);
 
+        if (data[i].skippable && idx == -1)
+        {
+            win_skip("Property %s is not supported on this machine.\n", wine_dbgstr_w(data[i].name));
+            i++;
+            continue;
+        }
+
         ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
-           wine_dbgstr_w(data[i].name));
+            wine_dbgstr_w(data[i].name));
         if (idx >= 0)
         {
             ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
@@ -543,8 +558,10 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o
            (int)cProperties, (int)cProperties2);
     }
 
-    if (clsid_encoder == &CLSID_WICTiffEncoder)
+    if (IsEqualCLSID(clsid_encoder, &CLSID_WICTiffEncoder))
         test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
+    else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder))
+        test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2);
 
     for (i=0; i < cProperties2; i++)
     {
diff --git a/include/wincodec.idl b/include/wincodec.idl
index 83daba8..406fe6b 100644
--- a/include/wincodec.idl
+++ b/include/wincodec.idl
@@ -168,6 +168,17 @@ typedef enum WICTiffCompressionOption {
     WICTIFFCOMPRESSIONOPTION_FORCE_DWORD = CODEC_FORCE_DWORD
 } WICTiffCompressionOption;
 
+typedef enum WICPngFilterOption {
+    WICPngFilterUnspecified = 0,
+    WICPngFilterNone = 1,
+    WICPngFilterSub = 2,
+    WICPngFilterUp = 3,
+    WICPngFilterAverage = 4,
+    WICPngFilterPaeth = 5,
+    WICPngFilterAdaptive = 6,
+    WICPNFFILTEROPTION_FORCE_DWORD = CODEC_FORCE_DWORD
+} WICPngFilterOption;
+
 typedef GUID WICPixelFormatGUID;
 typedef REFGUID REFWICPixelFormatGUID;
 
-- 
2.10.2




More information about the wine-patches mailing list