From: Nikolay Sivov Subject: [PATCH] wincodecs: Recognize FilterOption property in PNG encoder Message-Id: <20161123094914.5041-1-nsivov@codeweavers.com> Date: Wed, 23 Nov 2016 12:49:14 +0300 Signed-off-by: Nikolay Sivov --- 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