Author: akhaldi Date: Sun Jun 4 01:48:23 2017 New Revision: 74863
URL: http://svn.reactos.org/svn/reactos?rev=74863&view=rev Log: [WINDOWSCODECS_WINETEST] Sync with Wine Staging 2.9. CORE-13362
Modified: trunk/rostests/winetests/windowscodecs/CMakeLists.txt trunk/rostests/winetests/windowscodecs/converter.c trunk/rostests/winetests/windowscodecs/metadata.c trunk/rostests/winetests/windowscodecs/pngformat.c trunk/rostests/winetests/windowscodecs/tiffformat.c
Modified: trunk/rostests/winetests/windowscodecs/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/windowscodecs/CM... ============================================================================== --- trunk/rostests/winetests/windowscodecs/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/windowscodecs/CMakeLists.txt [iso-8859-1] Sun Jun 4 01:48:23 2017 @@ -18,7 +18,7 @@
add_executable(windowscodecs_winetest ${SOURCE}) set_module_type(windowscodecs_winetest win32cui) -add_importlibs(windowscodecs_winetest windowscodecs oleaut32 ole32 user32 gdi32 msvcrt kernel32) +add_importlibs(windowscodecs_winetest windowscodecs oleaut32 ole32 user32 gdi32 shlwapi msvcrt kernel32)
if(MSVC) add_importlibs(windowscodecs_winetest ntdll)
Modified: trunk/rostests/winetests/windowscodecs/converter.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/windowscodecs/co... ============================================================================== --- trunk/rostests/winetests/windowscodecs/converter.c [iso-8859-1] (original) +++ trunk/rostests/winetests/windowscodecs/converter.c [iso-8859-1] Sun Jun 4 01:48:23 2017 @@ -296,6 +296,21 @@ if (!equal && expect->alt_data) equal = compare_bits(expect->alt_data, buffersize, converted_bits);
+ if (!equal && winetest_debug > 1) + { + UINT i, bps; + bps = expect->bpp / 8; + if (!bps) bps = buffersize; + printf("converted_bits (%u bytes):\n ", buffersize); + for (i = 0; i < buffersize; i++) + { + printf("%u,", converted_bits[i]); + if (!((i + 1) % 32)) printf("\n "); + else if (!((i+1) % bps)) printf(" "); + } + printf("\n"); + } + return equal; }
@@ -443,6 +458,10 @@ 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80}; static const struct bitmap_data testdata_32bppBGR = { &GUID_WICPixelFormat32bppBGR, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; +static const struct bitmap_data testdata_32bppBGRA80 = { + &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; +static const struct bitmap_data testdata_32bppRGBA80 = { + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
static const BYTE bits_32bppBGRA[] = { 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, @@ -455,6 +474,24 @@ 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255}; static const struct bitmap_data testdata_32bppBGRA = { &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; +static const struct bitmap_data testdata_32bppRGBA = { + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; +static const struct bitmap_data testdata_32bppRGB = { + &GUID_WICPixelFormat32bppRGB, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; + +static const BYTE bits_32bppPBGRA[] = { + 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, + 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, + 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, + 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80}; +static const struct bitmap_data testdata_32bppPBGRA = { + &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0}; +static const struct bitmap_data testdata_32bppPRGBA = { + &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
/* XP and 2003 use linear color conversion, later versions use sRGB gamma */ static const float bits_32bppGrayFloat_xp[] = { @@ -520,7 +557,7 @@ hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap); todo_wine_if (todo) ok(hr == S_OK || - broken(hr == E_INVALIDARG) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); + broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
if (hr == S_OK) { @@ -587,11 +624,13 @@ 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 }, @@ -599,6 +638,12 @@ { 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; @@ -624,6 +669,13 @@ pb.pstrName = (LPOLESTR)data[i].name;
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)); @@ -712,8 +764,10 @@ (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++) { @@ -727,9 +781,9 @@ HRESULT hr; IWICPersistStream *persist; #ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionsBigEndian; + DWORD persist_options = WICPersistOptionBigEndian; #else - DWORD persist_options = WICPersistOptionsLittleEndian; + DWORD persist_options = WICPersistOptionLittleEndian; #endif
hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); @@ -1117,6 +1171,50 @@ 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, IWICPalette *palette) @@ -1219,6 +1317,9 @@
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);
if (palette) { @@ -1680,7 +1781,7 @@
test_converter_8bppIndexed();
- test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 1bppIndexed", TRUE); + test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE); test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE); test_conversion(&testdata_24bppRGB, &testdata_4bppIndexed, "24bppRGB -> 4bppIndexed", TRUE); test_conversion(&testdata_24bppRGB, &testdata_8bppIndexed, "24bppRGB -> 8bppIndexed", FALSE); @@ -1693,6 +1794,12 @@ test_conversion(&testdata_32bppBGRA, &testdata_32bppBGR, "BGRA -> BGR", FALSE); test_conversion(&testdata_32bppBGR, &testdata_32bppBGRA, "BGR -> BGRA", FALSE); test_conversion(&testdata_32bppBGRA, &testdata_32bppBGRA, "BGRA -> BGRA", FALSE); + test_conversion(&testdata_32bppBGRA80, &testdata_32bppPBGRA, "BGRA -> PBGRA", FALSE); + + test_conversion(&testdata_32bppRGBA, &testdata_32bppRGB, "RGBA -> RGB", FALSE); + test_conversion(&testdata_32bppRGB, &testdata_32bppRGBA, "RGB -> RGBA", FALSE); + test_conversion(&testdata_32bppRGBA, &testdata_32bppRGBA, "RGBA -> RGBA", FALSE); + test_conversion(&testdata_32bppRGBA80, &testdata_32bppPRGBA, "RGBA -> PRGBA", FALSE);
test_conversion(&testdata_24bppBGR, &testdata_24bppBGR, "24bppBGR -> 24bppBGR", FALSE); test_conversion(&testdata_24bppBGR, &testdata_24bppRGB, "24bppBGR -> 24bppRGB", FALSE);
Modified: trunk/rostests/winetests/windowscodecs/metadata.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/windowscodecs/me... ============================================================================== --- trunk/rostests/winetests/windowscodecs/metadata.c [iso-8859-1] (original) +++ trunk/rostests/winetests/windowscodecs/metadata.c [iso-8859-1] Sun Jun 4 01:48:23 2017 @@ -1,6 +1,6 @@ /* * Copyright 2011 Vincent Povirk for CodeWeavers - * Copyright 2012 Dmitry Timoshkov + * Copyright 2012,2017 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -267,7 +267,7 @@ ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return;
- load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionsDefault); + load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault);
hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); @@ -334,7 +334,7 @@ ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); ok(count == 0, "unexpected count %i\n", count);
- load_stream((IUnknown*)reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionsDefault); + load_stream((IUnknown*)reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault);
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); @@ -445,7 +445,7 @@ ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return;
- load_stream((IUnknown*)reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionsDefault); + load_stream((IUnknown*)reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault);
hr = IWICMetadataReader_GetMetadataFormat(reader, &format); ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); @@ -503,7 +503,7 @@ ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return;
- load_stream((IUnknown*)reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionsDefault); + load_stream((IUnknown*)reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionDefault);
hr = IWICMetadataReader_GetMetadataFormat(reader, &format); ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); @@ -797,9 +797,9 @@ GUID format; char *IFD_data_swapped; #ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionsBigEndian; + DWORD persist_options = WICPersistOptionBigEndian; #else - DWORD persist_options = WICPersistOptionsLittleEndian; + DWORD persist_options = WICPersistOptionLittleEndian; #endif
hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, @@ -822,10 +822,10 @@ compare_metadata(reader, td, count);
/* test IFD data with different endianness */ - if (persist_options == WICPersistOptionsLittleEndian) - persist_options = WICPersistOptionsBigEndian; + if (persist_options == WICPersistOptionLittleEndian) + persist_options = WICPersistOptionBigEndian; else - persist_options = WICPersistOptionsLittleEndian; + persist_options = WICPersistOptionLittleEndian;
IFD_data_swapped = HeapAlloc(GetProcessHeap(), 0, sizeof(IFD_data)); memcpy(IFD_data_swapped, &IFD_data, sizeof(IFD_data)); @@ -969,22 +969,22 @@ stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt));
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - NULL, NULL, WICPersistOptionsDefault, + NULL, NULL, WICPersistOptionDefault, stream, &reader); ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, + &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, NULL, &reader); ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, + &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, NULL); ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, + &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, &reader); ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
@@ -1002,7 +1002,7 @@ }
hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatWmp, NULL, WICPersistOptionsDefault, + &GUID_ContainerFormatWmp, NULL, WICPersistOptionDefault, stream, &reader); ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
@@ -1965,10 +1965,300 @@ IStream_Release(stream); }
+static void test_WICMapGuidToShortName(void) +{ + static const WCHAR unkW[] = { 'u','n','k',0 }; + static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; + HRESULT hr; + UINT len; + WCHAR name[16]; + + name[0] = 0; + len = 0xdeadbeef; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 8, "got %u\n", len); + ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + + name[0] = 0; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, NULL); + ok(hr == S_OK, "got %#x\n", hr); + ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + + len = 0xdeadbeef; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 8, "got %u\n", len); + + len = 0xdeadbeef; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 8, "got %u\n", len); + + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, NULL); + ok(hr == S_OK, "got %#x\n", hr); + + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, NULL); + ok(hr == S_OK, "got %#x\n", hr); + + hr = WICMapGuidToShortName(&GUID_NULL, 0, NULL, NULL); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + + name[0] = 0; + len = 0xdeadbeef; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 4, name, &len); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(!lstrcmpW(name, unkW), "got %s\n", wine_dbgstr_w(name)); + + name[0] = 0; + len = 0xdeadbeef; + hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, name, &len); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(!name[0], "got %s\n", wine_dbgstr_w(name)); + + hr = WICMapGuidToShortName(NULL, 8, name, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); +} + +static void test_WICMapShortNameToGuid(void) +{ + static const WCHAR unkW[] = { 'u','n','k',0 }; + static const WCHAR xmpW[] = { 'x','m','p',0 }; + static const WCHAR XmPW[] = { 'X','m','P',0 }; + static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; + HRESULT hr; + GUID guid; + + hr = WICMapShortNameToGuid(NULL, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapShortNameToGuid(NULL, &guid); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapShortNameToGuid(unknownW, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapShortNameToGuid(unkW, &guid); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + + hr = WICMapShortNameToGuid(unknownW, &guid); + ok(hr == S_OK, "got %#x\n", hr); + ok(IsEqualGUID(&guid, &GUID_MetadataFormatUnknown), "got %s\n", wine_dbgstr_guid(&guid)); + + hr = WICMapShortNameToGuid(xmpW, &guid); + ok(hr == S_OK, "got %#x\n", hr); + ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); + + guid = GUID_NULL; + hr = WICMapShortNameToGuid(XmPW, &guid); + ok(hr == S_OK, "got %#x\n", hr); + ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); +} + +static const GUID *guid_list[] = +{ + &GUID_ContainerFormatBmp, + &GUID_ContainerFormatPng, + &GUID_ContainerFormatIco, + &GUID_ContainerFormatJpeg, + &GUID_ContainerFormatTiff, + &GUID_ContainerFormatGif, + &GUID_ContainerFormatWmp, + &GUID_MetadataFormatUnknown, + &GUID_MetadataFormatIfd, + &GUID_MetadataFormatSubIfd, + &GUID_MetadataFormatExif, + &GUID_MetadataFormatGps, + &GUID_MetadataFormatInterop, + &GUID_MetadataFormatApp0, + &GUID_MetadataFormatApp1, + &GUID_MetadataFormatApp13, + &GUID_MetadataFormatIPTC, + &GUID_MetadataFormatIRB, + &GUID_MetadataFormat8BIMIPTC, + &GUID_MetadataFormat8BIMResolutionInfo, + &GUID_MetadataFormat8BIMIPTCDigest, + &GUID_MetadataFormatXMP, + &GUID_MetadataFormatThumbnail, + &GUID_MetadataFormatChunktEXt, + &GUID_MetadataFormatXMPStruct, + &GUID_MetadataFormatXMPBag, + &GUID_MetadataFormatXMPSeq, + &GUID_MetadataFormatXMPAlt, + &GUID_MetadataFormatLSD, + &GUID_MetadataFormatIMD, + &GUID_MetadataFormatGCE, + &GUID_MetadataFormatAPE, + &GUID_MetadataFormatJpegChrominance, + &GUID_MetadataFormatJpegLuminance, + &GUID_MetadataFormatJpegComment, + &GUID_MetadataFormatGifComment, + &GUID_MetadataFormatChunkgAMA, + &GUID_MetadataFormatChunkbKGD, + &GUID_MetadataFormatChunkiTXt, + &GUID_MetadataFormatChunkcHRM, + &GUID_MetadataFormatChunkhIST, + &GUID_MetadataFormatChunkiCCP, + &GUID_MetadataFormatChunksRGB, + &GUID_MetadataFormatChunktIME +}; + +static WCHAR rdf_scheme[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/','1','9','9','9','/','0','2','/','2','2','-','r','d','f','-','s','y','n','t','a','x','-','n','s','#',0 }; +static WCHAR dc_scheme[] = { 'h','t','t','p',':','/','/','p','u','r','l','.','o','r','g','/','d','c','/','e','l','e','m','e','n','t','s','/','1','.','1','/',0 }; +static WCHAR xmp_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; +static WCHAR xmpidq_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','I','d','e','n','t','i','f','i','e','r','/','q','u','a','l','/','1','.','0','/',0 }; +static WCHAR xmpRights_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','r','i','g','h','t','s','/',0 }; +static WCHAR xmpMM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','m','m','/',0 }; +static WCHAR xmpBJ_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','b','j','/',0 }; +static WCHAR xmpTPg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','t','/','p','g','/',0 }; +static WCHAR pdf_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','d','f','/','1','.','3','/',0 }; +static WCHAR photoshop_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','h','o','t','o','s','h','o','p','/','1','.','0','/',0 }; +static WCHAR tiff_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','t','i','f','f','/','1','.','0','/',0 }; +static WCHAR exif_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/',0 }; +static WCHAR stDim_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','D','i','m','e','n','s','i','o','n','s','#',0 }; +static WCHAR xapGImg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','g','/','i','m','g','/',0 }; +static WCHAR stEvt_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','E','v','e','n','t','#',0 }; +static WCHAR stRef_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','R','e','f','#',0 }; +static WCHAR stVer_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','V','e','r','s','i','o','n','#',0 }; +static WCHAR stJob_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','J','o','b','#',0 }; +static WCHAR aux_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/','a','u','x','/',0 }; +static WCHAR crs_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','c','a','m','e','r','a','-','r','a','w','-','s','e','t','t','i','n','g','s','/','1','.','0','/',0 }; +static WCHAR xmpDM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','1','.','0','/','D','y','n','a','m','i','c','M','e','d','i','a','/',0 }; +static WCHAR Iptc4xmpCore_scheme[] = { 'h','t','t','p',':','/','/','i','p','t','c','.','o','r','g','/','s','t','d','/','I','p','t','c','4','x','m','p','C','o','r','e','/','1','.','0','/','x','m','l','n','s','/',0 }; +static WCHAR MicrosoftPhoto_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','0','/',0 }; +static WCHAR MP_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/',0 }; +static WCHAR MPRI_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','I','n','f','o','#',0 }; +static WCHAR MPReg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','#',0 }; + +static WCHAR *schema_list[] = +{ + aux_scheme, + rdf_scheme, + dc_scheme, + xmp_scheme, + xmpidq_scheme, + xmpRights_scheme, + xmpMM_scheme, + xmpBJ_scheme, + xmpTPg_scheme, + pdf_scheme, + photoshop_scheme, + tiff_scheme, + exif_scheme, + stDim_scheme, + xapGImg_scheme, + stEvt_scheme, + stRef_scheme, + stVer_scheme, + stJob_scheme, + crs_scheme, + xmpDM_scheme, + Iptc4xmpCore_scheme, + MicrosoftPhoto_scheme, + MP_scheme, + MPRI_scheme, + MPReg_scheme +}; + +static void test_WICMapSchemaToName(void) +{ + static const WCHAR xmW[] = { 'x','m',0 }; + static const WCHAR xmpW[] = { 'x','m','p',0 }; + static WCHAR schemaW[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; + static WCHAR SCHEMAW[] = { 'H','T','T','P',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; + HRESULT hr; + UINT len, i, j; + WCHAR name[16]; + + hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, NULL, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, &len); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + + hr = WICMapSchemaToName(NULL, schemaW, 0, NULL, &len); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 4, "got %u\n", len); + + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, NULL, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 4, "got %u\n", len); + + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, SCHEMAW, 0, NULL, &len); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(len == 0xdeadbeef, "got %u\n", len); + + name[0] = 0; + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, &len); + ok(hr == S_OK, "got %#x\n", hr); + ok(len == 4, "got %u\n", len); + ok(!lstrcmpW(name, xmpW), "got %s\n", wine_dbgstr_w(name)); + + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, name, &len); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(len == 0xdeadbeef, "got %u\n", len); + + name[0] = 0; + len = 0xdeadbeef; + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 3, name, &len); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(!lstrcmpW(name, xmW), "got %s\n", wine_dbgstr_w(name)); + + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, NULL); + ok(hr == E_INVALIDARG, "got %#x\n", hr); + + /* Check whether modern schemas are supported */ + hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schema_list[0], 0, NULL, &len); + if (hr == WINCODEC_ERR_PROPERTYNOTFOUND) + { + win_skip("Modern schemas are not supported\n"); + return; + } + + for (i = 0; i < sizeof(guid_list)/sizeof(guid_list[0]); i++) + { + for (j = 0; j < sizeof(schema_list)/sizeof(schema_list[0]); j++) + { + hr = WICMapSchemaToName(guid_list[i], schema_list[j], 0, NULL, &len); + if (IsEqualGUID(guid_list[i], &GUID_MetadataFormatXMP) || + IsEqualGUID(guid_list[i], &GUID_MetadataFormatXMPStruct)) + { + ok(hr == S_OK, "%u: %u: format %s does not support schema %s\n", + i, j, wine_dbgstr_guid(guid_list[i]), wine_dbgstr_w(schema_list[j])); + } + else + { + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "%u: %u: format %s supports schema %s\n", + i, j, wine_dbgstr_guid(guid_list[i]), wine_dbgstr_w(schema_list[j])); + } + } + } +} + START_TEST(metadata) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ test_WICMapGuidToShortName(); + test_WICMapShortNameToGuid(); + test_WICMapSchemaToName(); test_metadata_unknown(); test_metadata_tEXt(); test_metadata_gAMA();
Modified: trunk/rostests/winetests/windowscodecs/pngformat.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/windowscodecs/pn... ============================================================================== --- trunk/rostests/winetests/windowscodecs/pngformat.c [iso-8859-1] (original) +++ trunk/rostests/winetests/windowscodecs/pngformat.c [iso-8859-1] Sun Jun 4 01:48:23 2017 @@ -31,6 +31,8 @@ #include <ole2.h> #include <wincodec.h> #include <wine/test.h> +#include <winreg.h> +#include <shlwapi.h>
/* 1x1 pixel PNG image */ static const char png_no_color_profile[] = { @@ -283,22 +285,17 @@
static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder) { - HGLOBAL hmem; - BYTE *data; HRESULT hr; IStream *stream; GUID format; LONG refcount; + ULARGE_INTEGER pos; + LARGE_INTEGER zero;
*decoder = NULL;
- hmem = GlobalAlloc(0, image_size); - data = GlobalLock(hmem); - memcpy(data, image_data, image_size); - GlobalUnlock(hmem); - - hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + stream = SHCreateMemStream (image_data, image_size); + ok(stream != NULL, "SHCreateMemStream error\n");
hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); if (hr == S_OK) @@ -307,6 +304,11 @@ ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatPng), "wrong container format %s\n", wine_dbgstr_guid(&format)); + + zero.QuadPart = 0; + IStream_Seek (stream, zero, STREAM_SEEK_CUR, &pos); + ok(pos.QuadPart < image_size, "seek beyond the end of stream: %x%08x >= %x\n", + (UINT)(pos.QuadPart >> 32), (UINT)pos.QuadPart, image_size);
refcount = IStream_Release(stream); ok(refcount > 0, "expected stream refcount > 0\n");
Modified: trunk/rostests/winetests/windowscodecs/tiffformat.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/windowscodecs/ti... ============================================================================== --- trunk/rostests/winetests/windowscodecs/tiffformat.c [iso-8859-1] (original) +++ trunk/rostests/winetests/windowscodecs/tiffformat.c [iso-8859-1] Sun Jun 4 01:48:23 2017 @@ -1,5 +1,5 @@ /* - * Copyright 2012 Dmitry Timoshkov + * Copyright 2012,2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -140,6 +140,49 @@ { 96, 1 }, { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 } }; + +static const struct tiff_8bpp_data +{ + USHORT byte_order; + USHORT version; + ULONG dir_offset; + USHORT number_of_entries; + struct IFD_entry entry[14]; + ULONG next_IFD; + struct IFD_rational res; + short palette_data[3][256]; + BYTE pixel_data[4]; +} tiff_8bpp_data = +{ +#ifdef WORDS_BIGENDIAN + 'M' | 'M' << 8, +#else + 'I' | 'I' << 8, +#endif + 42, + FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries), + 14, + { + { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ + { 0x100, IFD_LONG, 1, 4 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ + { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE: XP doesn't accept IFD_LONG here */ + { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ + { 0x106, IFD_SHORT, 1, 3 }, /* PHOTOMETRIC */ + { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_data, pixel_data) }, /* STRIPOFFSETS */ + { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ + { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ + { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ + { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, + { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, + { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ + { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_8bpp_data, palette_data) } /* COLORMAP */ + }, + 0, + { 96, 1 }, + { { 0 } }, + { 0,1,2,3 } +}; #include "poppack.h"
static IWICImagingFactory *factory; @@ -165,29 +208,96 @@ return stream; }
-static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size) -{ +static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder) +{ + HGLOBAL hmem; + BYTE *data; HRESULT hr; IStream *stream; - IWICBitmapDecoder *decoder = NULL; - GUID guid; - - stream = create_stream(image_data, image_size); - - hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); - if (FAILED(hr)) return NULL; - - hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guid); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); - ok(IsEqualGUID(&guid, &GUID_ContainerFormatTiff), "container format is not TIFF\n"); - - IStream_Release(stream); - - return decoder; -} - -static void test_tiff_palette(void) + GUID format; + LONG refcount; + + *decoder = NULL; + + hmem = GlobalAlloc(0, image_size); + data = GlobalLock(hmem); + memcpy(data, image_data, image_size); + GlobalUnlock(hmem); + + hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + + hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); + if (hr == S_OK) + { + hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); + ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff), + "wrong container format %s\n", wine_dbgstr_guid(&format)); + + refcount = IStream_Release(stream); + ok(refcount > 0, "expected stream refcount > 0\n"); + } + + return hr; +} + +static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency) +{ + HRESULT hr; + IWICComponentInfo *info; + IWICPixelFormatInfo2 *formatinfo; + + hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info); + ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo); + if (hr == S_OK) + { + hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency); + ok(hr == S_OK, "SupportsTransparency error %#x\n", hr); + IWICPixelFormatInfo2_Release(formatinfo); + } + hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo); + if (hr == S_OK) + { + hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp); + ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr); + hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels); + ok(hr == S_OK, "GetChannelCount error %#x\n", hr); + IWICPixelFormatInfo2_Release(formatinfo); + } + IWICComponentInfo_Release(info); + } + return hr; +} + +static void dump_tiff(void *buf) +{ + UINT count, i; + struct tiff_1bpp_data *tiff; + struct IFD_entry *tag; + + tiff = buf; + count = *(short *)((char *)tiff + tiff->dir_offset); + tag = (struct IFD_entry *)((char *)tiff + tiff->dir_offset + sizeof(short)); + + for (i = 0; i < count; i++) + { + printf("tag %u: id %04x, type %04x, count %u, value %d", + i, tag[i].id, tag[i].type, tag[i].count, tag[i].value); + if (tag[i].id == 0x102 && tag[i].count > 2) + { + short *bps = (short *)((char *)tiff + tag[i].value); + printf(" (%d,%d,%d,%d)\n", bps[0], bps[1], bps[2], bps[3]); + } + else + printf("\n"); + } +} + +static void test_tiff_1bpp_palette(void) { HRESULT hr; IWICBitmapDecoder *decoder; @@ -195,9 +305,9 @@ IWICPalette *palette; GUID format;
- decoder = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data)); - ok(decoder != 0, "Failed to load TIFF image data\n"); - if (!decoder) return; + hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder); + ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + if (hr != S_OK) return;
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ok(hr == S_OK, "GetFrame error %#x\n", hr); @@ -329,9 +439,9 @@ static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44, 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 };
- decoder = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha)); - ok(decoder != 0, "Failed to load TIFF image data\n"); - if (!decoder) return; + hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder); + ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + if (hr != S_OK) return;
hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); ok(hr == S_OK, "GetFrameCount error %#x\n", hr); @@ -376,6 +486,464 @@ IWICBitmapDecoder_Release(decoder); }
+static void generate_tiff_palette(void *buf, unsigned count) +{ + unsigned short *r, *g, *b; + unsigned i; + + r = buf; + g = r + count; + b = g + count; + + r[0] = 0x11 * 257; + g[0] = 0x22 * 257; + b[0] = 0x33 * 257; + r[1] = 0x44 * 257; + g[1] = 0x55 * 257; + b[1] = 0x66 * 257; + r[2] = 0x77 * 257; + g[2] = 0x88 * 257; + b[2] = 0x99 * 257; + r[3] = 0xa1 * 257; + g[3] = 0xb5 * 257; + b[3] = 0xff * 257; + + for (i = 4; i < count; i++) + { + r[i] = i * 257; + g[i] = (i | 0x40) * 257; + b[i] = (i | 0x80) * 257; + } +} + +static void test_tiff_8bpp_palette(void) +{ + char buf[sizeof(tiff_8bpp_data)]; + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + IWICPalette *palette; + GUID format; + UINT count, ret; + WICColor color[256]; + + memcpy(buf, &tiff_8bpp_data, sizeof(tiff_8bpp_data)); + generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256); + + hr = create_decoder(buf, sizeof(buf), &decoder); + ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + if (hr != S_OK) return; + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "GetFrame error %#x\n", hr); + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); + ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), + "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format)); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#x\n", hr); + hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 256, "expected 256, got %u\n", count); + + hr = IWICPalette_GetColors(palette, 256, color, &ret); + ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff112233, "got %#x\n", color[0]); + ok(color[1] == 0xff445566, "got %#x\n", color[1]); + ok(color[2] == 0xff778899, "got %#x\n", color[2]); + ok(color[3] == 0xffa1b5ff, "got %#x\n", color[3]); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); +} + +#include "pshpack2.h" +static const struct tiff_1x1_data +{ + USHORT byte_order; + USHORT version; + ULONG dir_offset; + USHORT number_of_entries; + struct IFD_entry entry[12]; + ULONG next_IFD; + struct IFD_rational res; + short palette_data[3][256]; + short bps_data[4]; + BYTE pixel_data[32]; +} tiff_1x1_data = +{ +#ifdef WORDS_BIGENDIAN + 'M' | 'M' << 8, +#else + 'I' | 'I' << 8, +#endif + 42, + FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), + 12, + { + { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ + { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ + { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ + { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ + { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ + { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ + { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ + { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, + { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, + { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ + { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ + }, + 0, + { 96, 1 }, + { { 0 } }, + { 8,8,8,0 }, + { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } +}; +#include "poppack.h" + +static UINT width_bytes(UINT width, UINT bpp) +{ + return (width * bpp + 7) / 8; +} + +static void test_color_formats(void) +{ + struct bitmap_data + { + UINT bpp; + UINT width; + UINT height; + const WICPixelFormatGUID *format; + const BYTE *bits; + }; + static const BYTE bits_1bpsBGR[] = { 0,255,0,255,0,255,255,255,0,0,0,255,255,0,0,0,255,255,255,255,255,0,0,0,0,255,0,255,0,255 }; + static const struct bitmap_data data_1bpsBGR = + { + 24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR + }; + static const BYTE bits_4bpsBGR[] = { 204,85,85,136,187,51,0,85,85,85,0,68,0,102,0,136,0,119,0,153,0 }; + static const struct bitmap_data data_4bpsBGR = + { + 24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR + }; + static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 }; + static const struct bitmap_data data_8bpsBGR = + { + 24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR + }; + static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; + static const struct bitmap_data data_48bppRGB = + { + 48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB + }; + static const BYTE bits_1bpsBGRA[] = { 0,255,0,255,0,255,0,255,0,255,255,0,255,0,0,255,255,0,255,255,0,0,255,0,0,255,0,255,0,255,0,255,0,0,0,0,0,255,0,0 }; + static const struct bitmap_data data_1bpsBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA + }; + static const BYTE bits_4bpsBGRA[] = { 204,85,85,51,85,136,187,85,0,68,0,85,0,102,0,119,0,136,0,153,0,0,0,17,0,34,0,51 }; + static const struct bitmap_data data_4bpsBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA + }; + static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 }; + static const struct bitmap_data data_8bpsBGRA = + { + 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA + }; + static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; + static const struct bitmap_data data_64bppRGBA = + { + 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA + }; + static const BYTE bits_BlackWhite[] = { 85,195,184,85 }; + static const struct bitmap_data data_BlackWhite = + { + 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite + }; + static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 }; + static const struct bitmap_data data_BlackWhite_xp = + { + 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp + }; + static const BYTE bits_4bppGray[] = { 85,195,184,85 }; + static const struct bitmap_data data_4bppGray = + { + 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray + }; + static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 }; + static const struct bitmap_data data_4bppGray_xp = + { + 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp + }; + static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 }; + static const struct bitmap_data data_8bppGray = + { + 8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray + }; + static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 }; + static const struct bitmap_data data_16bppGray = + { + 16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray + }; + static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; + static const struct bitmap_data data_32bppGrayFloat = + { + 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat + }; +#if 0 /* FIXME */ + static const BYTE bits_96bpp3Channels[] = { 0 }; + static const struct bitmap_data data_96bpp3Channels = + { + 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels + }; +#endif + static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; + static const struct bitmap_data data_128bppRGBAFloat = + { + 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat + }; + static const BYTE bits_1bppIndexed[] = { 85,195,184,85 }; + static const struct bitmap_data data_1bppIndexed = + { + 1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed + }; + static const BYTE bits_4bppIndexed[] = { 85,195,184,85 }; + static const struct bitmap_data data_4bppIndexed = + { + 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed + }; + static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 }; + static const struct bitmap_data data_4bppIndexed_xp = + { + 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp + }; + static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 }; + static const struct bitmap_data data_8bppIndexed = + { + 8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed + }; + static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; + static const struct bitmap_data data_32bppCMYK = + { + 32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK + }; + static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; + static const struct bitmap_data data_64bppCMYK = + { + 64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK + }; + static const struct + { + int photometric; /* PhotometricInterpretation */ + int samples; /* SamplesPerPixel */ + int bps; /* BitsPerSample */ + const struct bitmap_data *data; + const struct bitmap_data *alt_data; + } td[] = + { + /* 2 - RGB */ + { 2, 3, 1, &data_1bpsBGR }, + { 2, 3, 4, &data_4bpsBGR }, + { 2, 3, 8, &data_8bpsBGR }, + { 2, 3, 16, &data_48bppRGB }, + { 2, 3, 24, NULL }, +#if 0 /* FIXME */ + { 2, 3, 32, &data_96bpp3Channels }, +#endif + { 2, 4, 1, &data_1bpsBGRA }, + { 2, 4, 4, &data_4bpsBGRA }, + { 2, 4, 8, &data_8bpsBGRA }, + { 2, 4, 16, &data_64bppRGBA }, + { 2, 4, 24, NULL }, + { 2, 4, 32, &data_128bppRGBAFloat }, + /* 1 - BlackIsZero (Bilevel) */ + { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp }, + { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp }, + { 1, 1, 8, &data_8bppGray }, + { 1, 1, 16, &data_16bppGray }, + { 1, 1, 24, NULL }, + { 1, 1, 32, &data_32bppGrayFloat }, + /* 3 - Palette Color */ + { 3, 1, 1, &data_1bppIndexed }, + { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp }, + { 3, 1, 8, &data_8bppIndexed }, +#if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ + { 3, 1, 16, &data_8bppIndexed }, + { 3, 1, 24, &data_8bppIndexed }, + { 3, 1, 32, &data_8bppIndexed }, +#endif + /* 5 - Separated */ + { 5, 4, 1, NULL }, + { 5, 4, 4, NULL }, + { 5, 4, 8, &data_32bppCMYK }, + { 5, 4, 16, &data_64bppCMYK }, + { 5, 4, 24, NULL }, + { 5, 4, 32, NULL }, + }; + BYTE buf[sizeof(tiff_1x1_data)]; + BYTE pixels[256]; + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + GUID format; + UINT count, i, bpp, channels, ret; + BOOL trasparency; + struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; + struct IFD_entry *tag_width = NULL, *tag_height = NULL; + short *bps; + + memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); + generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256); + + count = *(short *)(buf + tiff_1x1_data.dir_offset); + tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); + + /* verify the TIFF structure */ + for (i = 0; i < count; i++) + { + if (tag[i].id == 0x100) /* ImageWidth */ + tag_width = &tag[i]; + else if (tag[i].id == 0x101) /* ImageLength */ + tag_height = &tag[i]; + else if (tag[i].id == 0x102) /* BitsPerSample */ + tag_bps = &tag[i]; + else if (tag[i].id == 0x106) /* PhotometricInterpretation */ + tag_photo = &tag[i]; + else if (tag[i].id == 0x115) /* SamplesPerPixel */ + tag_samples = &tag[i]; + else if (tag[i].id == 0x140) /* ColorMap */ + tag_colormap = &tag[i]; + } + + ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); + if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; + + ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); + bps = (short *)(buf + tag_bps->value); + ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, + "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + if (td[i].data) + { + bpp = td[i].samples * td[i].bps; + if (winetest_debug > 1) + trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp, + td[i].data->width, width_bytes(td[i].data->width, bpp)); + tag_width->value = td[i].data->width; + tag_height->value = td[i].data->height; + } + else + { + tag_width->value = 1; + tag_height->value = 1; + } + + tag_colormap->count = (1 << td[i].bps) * 3; + + if (td[i].bps < 8) + { + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55; + } + else + { + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2; + buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3; + } + + tag_photo->value = td[i].photometric; + tag_bps->count = td[i].samples; + tag_samples->value = td[i].samples; + + if (td[i].samples == 1) + tag_bps->value = td[i].bps; + else if (td[i].samples == 2) + tag_bps->value = MAKELONG(td[i].bps, td[i].bps); + else if (td[i].samples == 3) + { + tag_bps->value = (BYTE *)bps - buf; + bps[0] = bps[1] = bps[2] = td[i].bps; + } + else if (td[i].samples == 4) + { + tag_bps->value = (BYTE *)bps - buf; + bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; + } + else + { + ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); + continue; + } + + hr = create_decoder(buf, sizeof(buf), &decoder); + if (!td[i].data) + { + ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */, + "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr); + if (hr == S_OK) + { + IWICBitmapDecoder_Release(decoder); + dump_tiff(buf); + } + continue; + } + else + ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */, + "%u: failed to load TIFF image data (%d,%d,%d) %#x\n", + i, td[i].photometric, td[i].samples, td[i].bps, hr); + if (hr != S_OK) continue; + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr); + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); + ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr); + ok(IsEqualGUID(&format, td[i].data->format), + "%u (%d,%d,%d): expected %s, got %s\n", + i, td[i].photometric, td[i].samples, td[i].bps, + wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format)); + + trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ + hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency); + ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr); + ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp); + ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels); + ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency); + + memset(pixels, 0, sizeof(pixels)); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels); + ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr); + ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp)); + if (ret && td[i].alt_data) + ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp)); + ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps); + if (ret) + { + UINT j, n = width_bytes(td[i].data->width, bpp); + for (j = 0; j < n; j++) + printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n"); + } + + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); + } +} + START_TEST(tiffformat) { HRESULT hr; @@ -387,7 +955,9 @@ ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); if (FAILED(hr)) return;
- test_tiff_palette(); + test_color_formats(); + test_tiff_1bpp_palette(); + test_tiff_8bpp_palette(); test_QueryCapability(); test_tiff_8bpp_alpha();