From cf0334b65426314da14c6ccc3f0871637663710f Mon Sep 17 00:00:00 2001 From: Ludger Sprenker Date: Fri, 25 Jan 2013 00:04:46 +0100 Subject: [PATCH] windowscodecs: Add tests for IPropertyBag2. --- dlls/windowscodecs/tests/Makefile.in | 3 +- dlls/windowscodecs/tests/propertybag.c | 298 +++++++++++++++++++++++++ include/wincodec.idl | 1 + 3 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 dlls/windowscodecs/tests/propertybag.c diff --git a/dlls/windowscodecs/tests/Makefile.in b/dlls/windowscodecs/tests/Makefile.in index 76db38a5d52..550bf6bd197 100644 --- a/dlls/windowscodecs/tests/Makefile.in +++ b/dlls/windowscodecs/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = windowscodecs.dll -IMPORTS = gdi32 user32 ole32 windowscodecs +IMPORTS = windowscodecs oleaut32 ole32 user32 gdi32 C_SRCS = \ bitmap.c \ @@ -11,6 +11,7 @@ C_SRCS = \ metadata.c \ palette.c \ pngformat.c \ + propertybag.c \ stream.c \ tiffformat.c diff --git a/dlls/windowscodecs/tests/propertybag.c b/dlls/windowscodecs/tests/propertybag.c new file mode 100644 index 00000000000..b7e515372ba --- /dev/null +++ b/dlls/windowscodecs/tests/propertybag.c @@ -0,0 +1,298 @@ +/* + * Copyright 2013 Ludger Sprenker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#define COBJMACROS +#define CONST_VTABLE + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wincodecsdk.h" +#include "wine/test.h" + +static const WCHAR wszTestProperty1[] = {'P','r','o','p','e','r','t','y','1',0}; +static const WCHAR wszTestProperty2[] = {'P','r','o','p','e','r','t','y','2',0}; +static const WCHAR wszTestInvalidProperty[] = {'I','n','v','a','l','i','d',0}; + +static void test_propertybag_getpropertyinfo(IPropertyBag2 *property, ULONG expected_count) +{ + HRESULT hr; + PROPBAG2 pb[2]; + ULONG out_count; + + /* iProperty: Out of bounce */ + hr = IPropertyBag2_GetPropertyInfo(property, expected_count, 1, pb, &out_count); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, + "GetPropertyInfo handled iProperty out of bounce wrong, hr=%x\n", hr); + + /* cProperty: Out of bounce */ + hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count+1, pb, &out_count); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, + "GetPropertyInfo handled cProperty out of bounce wrong, hr=%x\n", hr); + + /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */ + if (expected_count == 0) + return; + + hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count, pb, &out_count); + ok(hr == S_OK, "GetPropertyInfo failed, hr=%x\n", hr); + if (FAILED(hr)) + return; + + ok(expected_count == out_count, + "GetPropertyInfo returned unexpected property count, %i != %i)\n", + expected_count, out_count); + + if(expected_count != 2) + return; + + ok(pb[0].vt == VT_UI1, "Invalid variant type, pb[0].vt=%x\n", pb[0].vt); + ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%x\n", pb[0].dwType); + ok(lstrcmpW(pb[0].pstrName, wszTestProperty1) == 0, "Invalid property name, pb[0].pstrName=%s\n", wine_dbgstr_w(pb[0].pstrName)); + + ok(pb[1].vt == VT_R4, "Invalid variant type, pb[1].vt=%x\n", pb[1].vt); + ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%x\n", pb[1].dwType); + ok(lstrcmpW(pb[1].pstrName, wszTestProperty2) == 0, "Invalid property name, pb[1].pstrName=%s\n", wine_dbgstr_w(pb[1].pstrName)); +} + +static void test_propertybag_countproperties(IPropertyBag2 *property, ULONG expected_count) +{ + ULONG count = (ULONG)-1; + HRESULT hr; + + hr = IPropertyBag2_CountProperties(property, NULL); + ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%x\n", hr); + + hr = IPropertyBag2_CountProperties(property, &count); + ok(hr == S_OK, "CountProperties failed, hr=%x\n", hr); + + if (FAILED(hr)) + return; + + ok(count == expected_count, "CountProperties returned invalid value, count=%i\n", count); +} + +static void test_propertybag_read(IPropertyBag2 *property) +{ + HRESULT hr; + PROPBAG2 options[3] = {{0}}; + VARIANT values[3]; + HRESULT itm_hr[3] = {S_OK, S_OK, S_OK}; + + /* 1. One unknown property */ + options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; + hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); + ok(hr == E_FAIL, + "Read for an unknown property did not fail with expected code, hr=%x\n", hr); + + /* 2. One known property */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + itm_hr[0] = E_FAIL; + hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); + ok(hr == S_OK, "Read failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + ok(itm_hr[0] == S_OK, + "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + ok(V_VT(&values[0]) == VT_UI1, + "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); + ok(V_UNION(&values[0], bVal) == 12, + "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal)); + + VariantClear(&values[0]); + } + + /* 3. Two known properties */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + options[1].pstrName = (LPOLESTR)wszTestProperty2; + itm_hr[0] = E_FAIL; + itm_hr[1] = E_FAIL; + hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr); + ok(hr == S_OK, "Read failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); + ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal)); + + ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]); + ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1])); + ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal)); + + VariantClear(&values[0]); + VariantClear(&values[1]); + } + + + /* 4. One unknown property between two valid */ + + /* Exotic initializations so we can detect what is unchanged */ + itm_hr[0] = -1; itm_hr[1] = -1; itm_hr[2] = -1; + V_VT(&values[0]) = VT_NULL; + V_VT(&values[1]) = VT_NULL; + V_VT(&values[2]) = VT_NULL; + V_UNION(&values[0], bVal) = 254; + V_UNION(&values[1], bVal) = 254; + V_UNION(&values[2], bVal) = 254; + + options[0].pstrName = (LPOLESTR)wszTestProperty1; + options[1].pstrName = (LPOLESTR)wszTestInvalidProperty; + options[2].pstrName = (LPOLESTR)wszTestProperty2; + + hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr); + ok(hr == E_FAIL, "Read failed, hr=%x\n", hr); + if (hr == E_FAIL) + { + ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]); + ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]); + ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]); + + ok(V_VT(&values[0]) == VT_UI1, "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0])); + ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1])); + ok(V_VT(&values[2]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[2])=%x\n", V_VT(&values[2])); + + ok(V_UNION(&values[0], bVal) == 12, "Read variant has unexpected value, V_UNION(&values[0])=%i\n", V_UNION(&values[0], bVal)); + ok(V_UNION(&values[1], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[1])=%i\n", V_UNION(&values[1], bVal)); + ok(V_UNION(&values[2], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[2])=%i\n", V_UNION(&values[2], bVal)); + } +} + +static void test_propertybag_write(IPropertyBag2 *property) +{ + HRESULT hr; + PROPBAG2 options[2] = {{0}}; + VARIANT values[2]; + + VariantInit(&values[0]); + VariantInit(&values[1]); + + /* 1. One unknown property */ + options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; + hr = IPropertyBag2_Write(property, 1, options, values); + ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr); + + /* 2. One property without correct type */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + V_VT(&values[0]) = VT_UI1; + V_UNION(&values[0], bVal) = 1; + hr = IPropertyBag2_Write(property, 1, options, values); + ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr); + + /* 3. One property with mismatching type */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + V_VT(&values[0]) = VT_I1; + V_UNION(&values[0], bVal) = 2; + hr = IPropertyBag2_Write(property, 1, options, values); + ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, + "Write with mismatching type did not fail with expected code hr=%x\n", hr); + + /* 4. Reset one property to empty */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + VariantClear(&values[0]); + hr = IPropertyBag2_Write(property, 1, options, values); + ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, + "Write to reset to empty value does not fail with expected code, hr=%x\n", hr); + + /* 5. Set two properties */ + options[0].pstrName = (LPOLESTR)wszTestProperty1; + V_VT(&values[0]) = VT_UI1; + V_UNION(&values[0], bVal) = 12; + options[1].pstrName = (LPOLESTR)wszTestProperty2; + V_VT(&values[1]) = VT_R4; + V_UNION(&values[1], fltVal) = (float)3.14; + hr = IPropertyBag2_Write(property, 2, options, values); + ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr); +} + +static void test_empty_propertybag(void) +{ + HRESULT hr; + IWICComponentFactory *factory; + IPropertyBag2 *property; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void**)&factory); + ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + + hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, NULL, 0, &property); + +todo_wine + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + if (FAILED(hr)) return; + +todo_wine + test_propertybag_countproperties(property, 0); + +todo_wine + test_propertybag_getpropertyinfo(property, 0); + + IPropertyBag2_Release(property); + + IWICComponentFactory_Release(factory); +} + +static void test_filled_propertybag(void) +{ + HRESULT hr; + IWICComponentFactory *factory; + IPropertyBag2 *property; + PROPBAG2 opts[2]= { + {.pstrName = (LPOLESTR)wszTestProperty1, .vt=VT_UI1, .dwType=PROPBAG2_TYPE_DATA}, + {.pstrName = (LPOLESTR)wszTestProperty2, .vt=VT_R4, .dwType=PROPBAG2_TYPE_DATA} + }; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void**)&factory); + ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + + hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, opts, 2, &property); + +todo_wine + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + if (FAILED(hr)) return; + +todo_wine + test_propertybag_countproperties(property, 2); + +todo_wine + test_propertybag_getpropertyinfo(property, 2); + +todo_wine + test_propertybag_write(property); + +todo_wine + test_propertybag_read(property); + + IPropertyBag2_Release(property); + + IWICComponentFactory_Release(factory); +} + +START_TEST(propertybag) +{ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + test_empty_propertybag(); + + test_filled_propertybag(); + + CoUninitialize(); +} diff --git a/include/wincodec.idl b/include/wincodec.idl index ba58db790eb..9a2d3774622 100644 --- a/include/wincodec.idl +++ b/include/wincodec.idl @@ -219,6 +219,7 @@ cpp_quote("#define WINCODEC_ERR_BADMETADATAHEADER 0x88982f63") cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT 0x88982f80") cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDOPERATION 0x88982f81") cpp_quote("#define WINCODEC_ERR_INSUFFICIENTBUFFER 0x88982f8c") +cpp_quote("#define WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE 0x88982f8e") cpp_quote("#define WINCODEC_ERR_WIN32ERROR 0x88982f94") interface IWICPalette;