ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
March 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
25 participants
436 discussions
Start a n
N
ew thread
01/01: [SHELL32] Fix item order in Folder Options (#415)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1f4c63645314c7c646897…
commit 1f4c63645314c7c6468979d761a57743a667fdef Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Tue Mar 6 07:40:41 2018 +0900 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Mon Mar 5 23:40:41 2018 +0100 [SHELL32] Fix item order in Folder Options (#415) --- dll/win32/shell32/dialogs/folder_options.cpp | 47 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/dll/win32/shell32/dialogs/folder_options.cpp b/dll/win32/shell32/dialogs/folder_options.cpp index cab61908b5..197b301395 100644 --- a/dll/win32/shell32/dialogs/folder_options.cpp +++ b/dll/win32/shell32/dialogs/folder_options.cpp @@ -359,6 +359,9 @@ CreateTreeImageList(VOID) static ADVANCED_ENTRY * Advanced_GetItem(DWORD dwID) { + if (dwID == DWORD(-1)) + return NULL; + for (INT i = 0; i < s_AdvancedCount; ++i) { ADVANCED_ENTRY *pEntry = &s_Advanced[i]; @@ -701,24 +704,52 @@ Advanced_Compare(const void *x, const void *y) { ADVANCED_ENTRY *pEntry1 = (ADVANCED_ENTRY *)x; ADVANCED_ENTRY *pEntry2 = (ADVANCED_ENTRY *)y; + DWORD dwParentID1 = pEntry1->dwParentID; DWORD dwParentID2 = pEntry2->dwParentID; - while (dwParentID1 != dwParentID2) + + if (dwParentID1 == dwParentID2) + return lstrcmpi(pEntry1->szText, pEntry2->szText); + + DWORD i, m, n; + const UINT MAX_DEPTH = 32; + ADVANCED_ENTRY *pArray1[MAX_DEPTH]; + ADVANCED_ENTRY *pArray2[MAX_DEPTH]; + + // Make ancestor lists + for (i = m = n = 0; i < MAX_DEPTH; ++i) { ADVANCED_ENTRY *pParent1 = Advanced_GetItem(dwParentID1); ADVANCED_ENTRY *pParent2 = Advanced_GetItem(dwParentID2); if (!pParent1 && !pParent2) break; - if (!pParent1 && pParent2) + + if (pParent1) + { + pArray1[m++] = pParent1; + dwParentID1 = pParent1->dwParentID; + } + if (pParent2) + { + pArray2[n++] = pParent2; + dwParentID2 = pParent2->dwParentID; + } + } + + UINT k = min(m, n); + for (i = 0; i < k; ++i) + { + INT nCompare = lstrcmpi(pArray1[m - i - 1]->szText, pArray2[n - i - 1]->szText); + if (nCompare < 0) return -1; - if (pParent1 && !pParent2) + if (nCompare > 0) return 1; - INT nCompare = lstrcmpi(pParent1->szText, pParent2->szText); - if (nCompare) - return nCompare; - dwParentID1 = pParent1->dwParentID; - dwParentID2 = pParent2->dwParentID; } + + if (m < n) + return -1; + if (m > n) + return 1; return lstrcmpi(pEntry1->szText, pEntry2->szText); }
6 years, 9 months
1
0
0
0
02/02: [SHLWAPI] Implement SHAreIconsEqual CORE-14425
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=173b79095c1f7aaf8e5c0…
commit 173b79095c1f7aaf8e5c0e5d3b57b6d54392c1c0 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Mon Mar 5 22:43:05 2018 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Mon Mar 5 22:43:18 2018 +0100 [SHLWAPI] Implement SHAreIconsEqual CORE-14425 --- dll/win32/shlwapi/rosordinal.c | 57 ++++++++++++++++++++++++++++++++++++++++++ dll/win32/shlwapi/shlwapi.spec | 2 +- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/dll/win32/shlwapi/rosordinal.c b/dll/win32/shlwapi/rosordinal.c index 53d2a28a43..d392b64120 100644 --- a/dll/win32/shlwapi/rosordinal.c +++ b/dll/win32/shlwapi/rosordinal.c @@ -37,3 +37,60 @@ HRESULT WINAPI SHForwardContextMenuMsg(IUnknown* pUnk, UINT uMsg, WPARAM wParam, IContextMenu2_Release(pcmenu2); return hr; } + +/*
http://undoc.airesoft.co.uk/shlwapi.dll/SHAreIconsEqual.php
*/ + +BOOL WINAPI SHAreIconsEqual(HICON hIcon1, HICON hIcon2) +{ + ICONINFO iconInfo1, iconInfo2; + BITMAP bm1, bm2; + BOOL bSame = FALSE; + + if (!hIcon1 || !hIcon2) + return FALSE; + + if (!GetIconInfo(hIcon1, &iconInfo1)) + return FALSE; + + if (!GetIconInfo(hIcon2, &iconInfo2)) + { + DeleteObject(iconInfo1.hbmColor); + DeleteObject(iconInfo1.hbmMask); + return FALSE; + } + + GetObjectW(iconInfo1.hbmColor, sizeof(bm1), &bm1); + GetObjectW(iconInfo2.hbmColor, sizeof(bm2), &bm2); + + if (bm1.bmWidth == bm2.bmWidth && bm1.bmHeight == bm2.bmHeight) + { + BITMAPINFO bmi = { { sizeof(bmi), bm1.bmWidth, bm1.bmHeight, 1, 32 } }; + HDC hdc = GetDC(0); + SIZE_T size = bm1.bmWidth * bm1.bmHeight * 4; + BYTE *data1, *data2; + + data1 = HeapAlloc(GetProcessHeap(), 0, size); + data2 = HeapAlloc(GetProcessHeap(), 0, size); + + if (data1 && data2) + { + if (GetDIBits(hdc, iconInfo1.hbmColor, 0, bm1.bmHeight, data1, &bmi, DIB_RGB_COLORS) && + GetDIBits(hdc, iconInfo2.hbmColor, 0, bm2.bmHeight, data2, &bmi, DIB_RGB_COLORS)) + { + bSame = memcmp(data1, data2, size) == 0; + } + } + HeapFree(GetProcessHeap(), 0, data1); + HeapFree(GetProcessHeap(), 0, data2); + + ReleaseDC(NULL, hdc); + } + + DeleteObject(iconInfo1.hbmColor); + DeleteObject(iconInfo1.hbmMask); + + DeleteObject(iconInfo2.hbmColor); + DeleteObject(iconInfo2.hbmMask); + + return bSame; +} diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec index b70601775d..0f5707c8d4 100644 --- a/dll/win32/shlwapi/shlwapi.spec +++ b/dll/win32/shlwapi/shlwapi.spec @@ -545,7 +545,7 @@ 545 stdcall -noname SHForwardContextMenuMsg(ptr long long long ptr long) 546 stub -noname IUnknown_DoContextMenuPopup 547 stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook -548 stub -noname SHAreIconsEqual +548 stdcall -noname SHAreIconsEqual(ptr ptr) 549 stdcall -noname SHCoCreateInstanceAC(ptr ptr long ptr ptr) 550 stub -noname GetTemplateInfoFromHandle 551 stub -noname IShellFolder_CompareIDs
6 years, 9 months
1
0
0
0
01/02: [SHLWAPI_APITEST] Add test for SHAreIconsEqual
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=754a2fa8724a3efdd5055…
commit 754a2fa8724a3efdd5055bff7e369604ac7e5205 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Mon Mar 5 22:18:21 2018 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Mon Mar 5 22:43:17 2018 +0100 [SHLWAPI_APITEST] Add test for SHAreIconsEqual --- modules/rostests/apitests/shlwapi/16_32_black.ico | Bin 0 -> 1150 bytes modules/rostests/apitests/shlwapi/16_32_red.ico | Bin 0 -> 1150 bytes modules/rostests/apitests/shlwapi/16_8_black.ico | Bin 0 -> 1406 bytes modules/rostests/apitests/shlwapi/16_8_red.ico | Bin 0 -> 1406 bytes modules/rostests/apitests/shlwapi/32_32.ico | Bin 0 -> 4286 bytes modules/rostests/apitests/shlwapi/32_8.ico | Bin 0 -> 2238 bytes modules/rostests/apitests/shlwapi/CMakeLists.txt | 4 +- .../rostests/apitests/shlwapi/SHAreIconsEqual.c | 81 +++++++++++++++++++++ modules/rostests/apitests/shlwapi/resource.h | 9 +++ modules/rostests/apitests/shlwapi/testdata.rc | 10 +++ modules/rostests/apitests/shlwapi/testlist.c | 2 + 11 files changed, 105 insertions(+), 1 deletion(-) diff --git a/modules/rostests/apitests/shlwapi/16_32_black.ico b/modules/rostests/apitests/shlwapi/16_32_black.ico new file mode 100644 index 0000000000..f93cf06c1d Binary files /dev/null and b/modules/rostests/apitests/shlwapi/16_32_black.ico differ diff --git a/modules/rostests/apitests/shlwapi/16_32_red.ico b/modules/rostests/apitests/shlwapi/16_32_red.ico new file mode 100644 index 0000000000..f6aadcd483 Binary files /dev/null and b/modules/rostests/apitests/shlwapi/16_32_red.ico differ diff --git a/modules/rostests/apitests/shlwapi/16_8_black.ico b/modules/rostests/apitests/shlwapi/16_8_black.ico new file mode 100644 index 0000000000..5efc283ce2 Binary files /dev/null and b/modules/rostests/apitests/shlwapi/16_8_black.ico differ diff --git a/modules/rostests/apitests/shlwapi/16_8_red.ico b/modules/rostests/apitests/shlwapi/16_8_red.ico new file mode 100644 index 0000000000..5b73a5ddee Binary files /dev/null and b/modules/rostests/apitests/shlwapi/16_8_red.ico differ diff --git a/modules/rostests/apitests/shlwapi/32_32.ico b/modules/rostests/apitests/shlwapi/32_32.ico new file mode 100644 index 0000000000..e49a3e219c Binary files /dev/null and b/modules/rostests/apitests/shlwapi/32_32.ico differ diff --git a/modules/rostests/apitests/shlwapi/32_8.ico b/modules/rostests/apitests/shlwapi/32_8.ico new file mode 100644 index 0000000000..e098f7fab7 Binary files /dev/null and b/modules/rostests/apitests/shlwapi/32_8.ico differ diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt b/modules/rostests/apitests/shlwapi/CMakeLists.txt index 104f50bf86..da4c6a808f 100644 --- a/modules/rostests/apitests/shlwapi/CMakeLists.txt +++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt @@ -5,11 +5,13 @@ list(APPEND SOURCE PathIsUNCServer.c PathIsUNCServerShare.c PathUnExpandEnvStrings.c + SHAreIconsEqual.c StrFormatByteSizeW.c + testdata.rc testlist.c) add_executable(shlwapi_apitest ${SOURCE}) set_module_type(shlwapi_apitest win32cui) target_link_libraries(shlwapi_apitest ${PSEH_LIB}) -add_importlibs(shlwapi_apitest shlwapi msvcrt kernel32) +add_importlibs(shlwapi_apitest shlwapi user32 msvcrt kernel32) add_rostests_file(TARGET shlwapi_apitest) diff --git a/modules/rostests/apitests/shlwapi/SHAreIconsEqual.c b/modules/rostests/apitests/shlwapi/SHAreIconsEqual.c new file mode 100644 index 0000000000..27592325c7 --- /dev/null +++ b/modules/rostests/apitests/shlwapi/SHAreIconsEqual.c @@ -0,0 +1,81 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Tests for SHAreIconsEqual + * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include <apitest.h> +#include <shlwapi.h> +#include "resource.h" + +static BOOL (WINAPI *pSHAreIconsEqual)(HICON hIcon1, HICON hIcon2); + +static const char* names[] = +{ + "16_8_black", + "16_8_red", + "16_32_black", + "16_32_red", + "32_8", + "32_32", +}; + +void compare_icons_imp(int id1, int id2, BOOL expected) +{ + HICON icon1 = LoadImageA(GetModuleHandle(NULL), MAKEINTRESOURCEA(id1), IMAGE_ICON, 0, 0, 0); + HICON icon2 = LoadImageA(GetModuleHandle(NULL), MAKEINTRESOURCEA(id2), IMAGE_ICON, 0, 0, 0); + + BOOL result = pSHAreIconsEqual(icon1, icon2); + + winetest_ok(icon1 != icon2, "Expected two different handles for %s==%s\n", names[id1-1], names[id2-1]); + winetest_ok(result == expected, "Expected %d, got %d for %s==%s\n", expected, result, names[id1-1], names[id2-1]); + + DestroyIcon(icon1); + DestroyIcon(icon2); +} + +#define compare_icons (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : compare_icons_imp + + + +START_TEST(SHAreIconsEqual) +{ + HMODULE module = LoadLibraryA("shlwapi.dll"); + BOOL Continue = FALSE; + pSHAreIconsEqual = (void*)GetProcAddress(module, MAKEINTRESOURCEA(548)); + if (!pSHAreIconsEqual) + { + skip("SHAreIconsEqual not exported\n"); + return; + } + + _SEH2_TRY + { + pSHAreIconsEqual((HICON)IDC_APPSTARTING, (HICON)IDC_APPSTARTING); + Continue = TRUE; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Continue = FALSE; + trace("SHAreIconsEqual not implemented?\n"); + } + _SEH2_END; + + if (!Continue) + { + return; + } + + ok(pSHAreIconsEqual((HICON)NULL, (HICON)NULL) == FALSE, "NULL\n"); + ok(pSHAreIconsEqual((HICON)IDC_APPSTARTING, (HICON)IDC_APPSTARTING) == FALSE, "IDC_APPSTARTING\n"); + ok(pSHAreIconsEqual((HICON)IDC_ARROW, (HICON)IDC_ARROW) == FALSE, "IDC_ARROW\n"); + ok(pSHAreIconsEqual((HICON)IDC_SIZENESW, (HICON)IDC_SIZENESW) == FALSE, "IDC_SIZENESW\n"); + + compare_icons(ICON_16_8_BLACK, ICON_16_8_BLACK, TRUE); + compare_icons(ICON_16_8_BLACK, ICON_16_8_RED, FALSE); + compare_icons(ICON_16_8_BLACK, ICON_16_32_BLACK, FALSE); + compare_icons(ICON_16_8_BLACK, ICON_16_32_RED, FALSE); + compare_icons(ICON_16_8_BLACK, ICON_32_8, FALSE); + compare_icons(ICON_16_8_BLACK, ICON_32_32, FALSE); +} diff --git a/modules/rostests/apitests/shlwapi/resource.h b/modules/rostests/apitests/shlwapi/resource.h new file mode 100644 index 0000000000..1e22985bdd --- /dev/null +++ b/modules/rostests/apitests/shlwapi/resource.h @@ -0,0 +1,9 @@ + +#define ICON_16_8_BLACK 1 +#define ICON_16_8_RED 2 +#define ICON_16_32_BLACK 3 +#define ICON_16_32_RED 4 +#define ICON_32_8 5 +#define ICON_32_32 6 + + diff --git a/modules/rostests/apitests/shlwapi/testdata.rc b/modules/rostests/apitests/shlwapi/testdata.rc new file mode 100644 index 0000000000..b6aa19173e --- /dev/null +++ b/modules/rostests/apitests/shlwapi/testdata.rc @@ -0,0 +1,10 @@ + +#include "resource.h" + +ICON_16_8_BLACK ICON "16_8_black.ico" +ICON_16_8_RED ICON "16_8_red.ico" +ICON_16_32_BLACK ICON "16_32_black.ico" +ICON_16_32_RED ICON "16_32_red.ico" +ICON_32_8 ICON "32_8.ico" +ICON_32_32 ICON "32_32.ico" + diff --git a/modules/rostests/apitests/shlwapi/testlist.c b/modules/rostests/apitests/shlwapi/testlist.c index 1f3fc39498..793385e1a2 100644 --- a/modules/rostests/apitests/shlwapi/testlist.c +++ b/modules/rostests/apitests/shlwapi/testlist.c @@ -6,6 +6,7 @@ extern void func_isuncpath(void); extern void func_isuncpathserver(void); extern void func_isuncpathservershare(void); extern void func_PathUnExpandEnvStrings(void); +extern void func_SHAreIconsEqual(void); extern void func_StrFormatByteSizeW(void); const struct test winetest_testlist[] = @@ -15,6 +16,7 @@ const struct test winetest_testlist[] = { "PathIsUNCServer", func_isuncpathserver }, { "PathIsUNCServerShare", func_isuncpathservershare }, { "PathUnExpandEnvStrings", func_PathUnExpandEnvStrings }, + { "SHAreIconsEqual", func_SHAreIconsEqual }, { "StrFormatByteSizeW", func_StrFormatByteSizeW }, { 0, 0 } };
6 years, 9 months
1
0
0
0
01/01: [WINDOWSCODECS] Fix stack pointer corruption when handling PNGs.
by Thomas Faber
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1f7cb06c22fb0fcd7228c…
commit 1f7cb06c22fb0fcd7228cbd1d210c0c2175548d0 Author: Thomas Faber <thomas.faber(a)reactos.org> AuthorDate: Mon Mar 5 18:51:24 2018 +0100 Commit: Thomas Faber <thomas.faber(a)reactos.org> CommitDate: Mon Mar 5 18:51:48 2018 +0100 [WINDOWSCODECS] Fix stack pointer corruption when handling PNGs. Without PNG_API_RULE defined, these functions (like all others) aren't stdcall. --- dll/win32/windowscodecs/typeof.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dll/win32/windowscodecs/typeof.h b/dll/win32/windowscodecs/typeof.h index 0d77ec9ab7..12e6b8bcc4 100644 --- a/dll/win32/windowscodecs/typeof.h +++ b/dll/win32/windowscodecs/typeof.h @@ -76,8 +76,8 @@ typedef void (__cdecl typeof(png_write_info))(struct png_struct_def *, struct pn typedef void (__cdecl typeof(png_write_rows))(struct png_struct_def *, unsigned char **row, unsigned int); typedef unsigned int (__cdecl typeof(png_get_iCCP))(struct png_struct_def *, struct png_info_def *, char **, int *, char **, unsigned int *); typedef void (__cdecl typeof(png_set_crc_action))(struct png_struct_def *, int, int); -typedef void (__stdcall typeof(png_set_PLTE))(struct png_struct_def *, struct png_info_def *, const struct png_color_struct *, int); -typedef void (__stdcall typeof(png_set_tRNS))(struct png_struct_def *, struct png_info_def *, const unsigned char *, int, const struct png_color_16_struct *); +typedef void (__cdecl typeof(png_set_PLTE))(struct png_struct_def *, struct png_info_def *, const struct png_color_struct *, int); +typedef void (__cdecl typeof(png_set_tRNS))(struct png_struct_def *, struct png_info_def *, const unsigned char *, int, const struct png_color_16_struct *); typedef void (__cdecl typeof(png_set_filter))(struct png_struct_def *, int, int); typedef void *thandle_t_1; typedef int (*TIFFReadWriteProc_1)(thandle_t_1, void *, __typeof_intptr);
6 years, 9 months
1
0
0
0
01/01: [AFD_APITEST] Introduce a test for directly creating and using sockets via AFD. CORE-9810
by Thomas Faber
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=680d69d373969a81c78e3…
commit 680d69d373969a81c78e365e9eb8577b8b6924a7 Author: Thomas Faber <thomas.faber(a)reactos.org> AuthorDate: Sun Feb 25 10:34:49 2018 +0100 Commit: Thomas Faber <thomas.faber(a)reactos.org> CommitDate: Mon Mar 5 14:52:56 2018 +0100 [AFD_APITEST] Introduce a test for directly creating and using sockets via AFD. CORE-9810 The initial tests in send.c validate correct behavior of send/sendto on disconnected sockets (CORE-9810), fixed in r68129. However, the helper functions are generic, so they can be used for additional tests against AFD. Because AFD's create packet structure changes between Windows versions, the functions check the OS version to determine the right layout. Tests succeed on Win2003 as well as Win10. --- modules/rostests/apitests/CMakeLists.txt | 1 + modules/rostests/apitests/afd/AfdHelpers.c | 384 +++++++++++++++++++++++++++ modules/rostests/apitests/afd/AfdHelpers.h | 41 +++ modules/rostests/apitests/afd/CMakeLists.txt | 15 ++ modules/rostests/apitests/afd/precomp.h | 26 ++ modules/rostests/apitests/afd/send.c | 95 +++++++ modules/rostests/apitests/afd/testlist.c | 10 + 7 files changed, 572 insertions(+) diff --git a/modules/rostests/apitests/CMakeLists.txt b/modules/rostests/apitests/CMakeLists.txt index 6b6149ce35..5312b2838f 100644 --- a/modules/rostests/apitests/CMakeLists.txt +++ b/modules/rostests/apitests/CMakeLists.txt @@ -1,6 +1,7 @@ include_directories(include) add_subdirectory(advapi32) +add_subdirectory(afd) add_subdirectory(apphelp) add_subdirectory(appshim) add_subdirectory(atl) diff --git a/modules/rostests/apitests/afd/AfdHelpers.c b/modules/rostests/apitests/afd/AfdHelpers.c new file mode 100644 index 0000000000..ad7793efd7 --- /dev/null +++ b/modules/rostests/apitests/afd/AfdHelpers.c @@ -0,0 +1,384 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1+ (
https://spdx.org/licenses/LGPL-2.1+
) + * PURPOSE: Utility function definitions for calling AFD + * COPYRIGHT: Copyright 2015-2018 Thomas Faber (thomas.faber(a)reactos.org) + */ + +#include "precomp.h" + +#define DD_UDP_DEVICE_NAME L"\\Device\\Udp" + +typedef struct _AFD_CREATE_PACKET_NT6 { + DWORD EndpointFlags; + DWORD GroupID; + DWORD AddressFamily; + DWORD SocketType; + DWORD Protocol; + DWORD SizeOfTransportName; + WCHAR TransportName[1]; +} AFD_CREATE_PACKET_NT6, *PAFD_CREATE_PACKET_NT6; + +NTSTATUS +AfdCreateSocket( + _Out_ PHANDLE SocketHandle, + _In_ int AddressFamily, + _In_ int SocketType, + _In_ int Protocol) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatus; + PFILE_FULL_EA_INFORMATION EaBuffer = NULL; + ULONG EaLength; + PAFD_CREATE_PACKET AfdPacket; + PAFD_CREATE_PACKET_NT6 AfdPacket6; + ULONG SizeOfPacket; + ANSI_STRING EaName = RTL_CONSTANT_STRING(AfdCommand); + UNICODE_STRING TcpTransportName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME); + UNICODE_STRING UdpTransportName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME); + UNICODE_STRING TransportName = SocketType == SOCK_STREAM ? TcpTransportName : UdpTransportName; + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Afd\\Endpoint"); + + *SocketHandle = NULL; + + if (LOBYTE(LOWORD(GetVersion())) >= 6) + { + SizeOfPacket = FIELD_OFFSET(AFD_CREATE_PACKET_NT6, TransportName) + TransportName.Length + sizeof(UNICODE_NULL); + } + else + { + SizeOfPacket = FIELD_OFFSET(AFD_CREATE_PACKET, TransportName) + TransportName.Length + sizeof(UNICODE_NULL); + } + EaLength = SizeOfPacket + FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) + EaName.Length + sizeof(ANSI_NULL); + + /* Set up EA Buffer */ + EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, EaLength); + if (!EaBuffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + EaBuffer->NextEntryOffset = 0; + EaBuffer->Flags = 0; + EaBuffer->EaNameLength = EaName.Length; + RtlCopyMemory(EaBuffer->EaName, + EaName.Buffer, + EaName.Length + sizeof(ANSI_NULL)); + EaBuffer->EaValueLength = SizeOfPacket; + + if (LOBYTE(LOWORD(GetVersion())) >= 6) + { + AfdPacket6 = (PAFD_CREATE_PACKET_NT6)(EaBuffer->EaName + EaBuffer->EaNameLength + sizeof(ANSI_NULL)); + AfdPacket6->GroupID = 0; + if (SocketType == SOCK_DGRAM) + { + AfdPacket6->EndpointFlags = AFD_ENDPOINT_CONNECTIONLESS; + } + else if (SocketType == SOCK_STREAM) + { + AfdPacket6->EndpointFlags = AFD_ENDPOINT_MESSAGE_ORIENTED; + } + AfdPacket6->AddressFamily = AddressFamily; + AfdPacket6->SocketType = SocketType; + AfdPacket6->Protocol = Protocol; + AfdPacket6->SizeOfTransportName = TransportName.Length; + RtlCopyMemory(AfdPacket6->TransportName, + TransportName.Buffer, + TransportName.Length + sizeof(UNICODE_NULL)); + } + else + { + AfdPacket = (PAFD_CREATE_PACKET)(EaBuffer->EaName + EaBuffer->EaNameLength + sizeof(ANSI_NULL)); + AfdPacket->GroupID = 0; + if (SocketType == SOCK_DGRAM) + { + AfdPacket->EndpointFlags = AFD_ENDPOINT_CONNECTIONLESS; + } + else if (SocketType == SOCK_STREAM) + { + AfdPacket->EndpointFlags = AFD_ENDPOINT_MESSAGE_ORIENTED; + } + AfdPacket->SizeOfTransportName = TransportName.Length; + RtlCopyMemory(AfdPacket->TransportName, + TransportName.Buffer, + TransportName.Length + sizeof(UNICODE_NULL)); + } + + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + 0, + 0); + + Status = NtCreateFile(SocketHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatus, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + 0, + EaBuffer, + EaLength); + + RtlFreeHeap(RtlGetProcessHeap(), 0, EaBuffer); + + return Status; +} + + +NTSTATUS +AfdBind( + _In_ HANDLE SocketHandle, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + PAFD_BIND_DATA BindInfo; + ULONG BindInfoLength; + HANDLE Event; + + Status = NtCreateEvent(&Event, + EVENT_ALL_ACCESS, + NULL, + NotificationEvent, + FALSE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + BindInfoLength = FIELD_OFFSET(AFD_BIND_DATA, Address.Address[0].Address) + + AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + BindInfo = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + BindInfoLength); + if (!BindInfo) + { + NtClose(Event); + return STATUS_INSUFFICIENT_RESOURCES; + } + + BindInfo->ShareType = AFD_SHARE_UNIQUE; + BindInfo->Address.TAAddressCount = 1; + BindInfo->Address.Address[0].AddressType = Address->sa_family; + BindInfo->Address.Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + RtlCopyMemory(&BindInfo->Address.Address[0].Address, + Address->sa_data, + BindInfo->Address.Address[0].AddressLength); + + Status = NtDeviceIoControlFile(SocketHandle, + Event, + NULL, + NULL, + &IoStatus, + IOCTL_AFD_BIND, + BindInfo, + BindInfoLength, + BindInfo, + BindInfoLength); + if (Status == STATUS_PENDING) + { + NtWaitForSingleObject(Event, FALSE, NULL); + Status = IoStatus.Status; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, BindInfo); + NtClose(Event); + + return Status; +} + +NTSTATUS +AfdConnect( + _In_ HANDLE SocketHandle, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + PAFD_CONNECT_INFO ConnectInfo; + ULONG ConnectInfoLength; + HANDLE Event; + + Status = NtCreateEvent(&Event, + EVENT_ALL_ACCESS, + NULL, + NotificationEvent, + FALSE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + ASSERT(FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address) == 20); + ConnectInfoLength = FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address) + + AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + ConnectInfo = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + ConnectInfoLength); + if (!ConnectInfo) + { + NtClose(Event); + return STATUS_INSUFFICIENT_RESOURCES; + } + + + ConnectInfo->UseSAN = FALSE; + ConnectInfo->Root = 0; + ConnectInfo->Unknown = 0; + ConnectInfo->RemoteAddress.TAAddressCount = 1; + ConnectInfo->RemoteAddress.Address[0].AddressType = Address->sa_family; + ConnectInfo->RemoteAddress.Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + RtlCopyMemory(&ConnectInfo->RemoteAddress.Address[0].Address, + Address->sa_data, + ConnectInfo->RemoteAddress.Address[0].AddressLength); + + Status = NtDeviceIoControlFile(SocketHandle, + Event, + NULL, + NULL, + &IoStatus, + IOCTL_AFD_CONNECT, + ConnectInfo, + ConnectInfoLength, + NULL, + 0); + if (Status == STATUS_PENDING) + { + NtWaitForSingleObject(Event, FALSE, NULL); + Status = IoStatus.Status; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, ConnectInfo); + NtClose(Event); + + return Status; +} + +NTSTATUS +AfdSend( + _In_ HANDLE SocketHandle, + _In_ const void *Buffer, + _In_ ULONG BufferLength) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + AFD_SEND_INFO SendInfo; + HANDLE Event; + AFD_WSABUF AfdBuffer; + + Status = NtCreateEvent(&Event, + EVENT_ALL_ACCESS, + NULL, + NotificationEvent, + FALSE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + AfdBuffer.buf = (PVOID)Buffer; + AfdBuffer.len = BufferLength; + SendInfo.BufferArray = &AfdBuffer; + SendInfo.BufferCount = 1; + SendInfo.TdiFlags = 0; + SendInfo.AfdFlags = 0; + + Status = NtDeviceIoControlFile(SocketHandle, + Event, + NULL, + NULL, + &IoStatus, + IOCTL_AFD_SEND, + &SendInfo, + sizeof(SendInfo), + NULL, + 0); + if (Status == STATUS_PENDING) + { + NtWaitForSingleObject(Event, FALSE, NULL); + Status = IoStatus.Status; + } + + NtClose(Event); + + return Status; +} + +NTSTATUS +AfdSendTo( + _In_ HANDLE SocketHandle, + _In_ const void *Buffer, + _In_ ULONG BufferLength, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + AFD_SEND_INFO_UDP SendInfo; + HANDLE Event; + AFD_WSABUF AfdBuffer; + PTRANSPORT_ADDRESS TransportAddress; + ULONG TransportAddressLength; + + Status = NtCreateEvent(&Event, + EVENT_ALL_ACCESS, + NULL, + NotificationEvent, + FALSE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + TransportAddressLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address[0].Address) + + AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + TransportAddress = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + TransportAddressLength); + if (!TransportAddress) + { + NtClose(Event); + return STATUS_INSUFFICIENT_RESOURCES; + } + TransportAddress->TAAddressCount = 1; + TransportAddress->Address[0].AddressType = Address->sa_family; + TransportAddress->Address[0].AddressLength = AddressLength - FIELD_OFFSET(struct sockaddr, sa_data); + RtlCopyMemory(&TransportAddress->Address[0].Address, + Address->sa_data, + TransportAddress->Address[0].AddressLength); + + AfdBuffer.buf = (PVOID)Buffer; + AfdBuffer.len = BufferLength; + RtlZeroMemory(&SendInfo, sizeof(SendInfo)); + SendInfo.BufferArray = &AfdBuffer; + SendInfo.BufferCount = 1; + SendInfo.AfdFlags = 0; + SendInfo.TdiConnection.RemoteAddress = TransportAddress; + SendInfo.TdiConnection.RemoteAddressLength = TransportAddressLength; + + Status = NtDeviceIoControlFile(SocketHandle, + Event, + NULL, + NULL, + &IoStatus, + IOCTL_AFD_SEND_DATAGRAM, + &SendInfo, + sizeof(SendInfo), + NULL, + 0); + if (Status == STATUS_PENDING) + { + NtWaitForSingleObject(Event, FALSE, NULL); + Status = IoStatus.Status; + } + + RtlFreeHeap(RtlGetProcessHeap(), 0, TransportAddress); + NtClose(Event); + + return Status; +} diff --git a/modules/rostests/apitests/afd/AfdHelpers.h b/modules/rostests/apitests/afd/AfdHelpers.h new file mode 100644 index 0000000000..fadd03d563 --- /dev/null +++ b/modules/rostests/apitests/afd/AfdHelpers.h @@ -0,0 +1,41 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1+ (
https://spdx.org/licenses/LGPL-2.1+
) + * PURPOSE: Utility function declarations for calling AFD + * COPYRIGHT: Copyright 2015 Thomas Faber (thomas.faber(a)reactos.org) + */ + +#pragma once + +NTSTATUS +AfdCreateSocket( + _Out_ PHANDLE SocketHandle, + _In_ int AddressFamily, + _In_ int SocketType, + _In_ int Protocol); + +NTSTATUS +AfdBind( + _In_ HANDLE SocketHandle, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength); + +NTSTATUS +AfdConnect( + _In_ HANDLE SocketHandle, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength); + +NTSTATUS +AfdSend( + _In_ HANDLE SocketHandle, + _In_ const void *Buffer, + _In_ ULONG BufferLength); + +NTSTATUS +AfdSendTo( + _In_ HANDLE SocketHandle, + _In_ const void *Buffer, + _In_ ULONG BufferLength, + _In_ const struct sockaddr *Address, + _In_ ULONG AddressLength); diff --git a/modules/rostests/apitests/afd/CMakeLists.txt b/modules/rostests/apitests/afd/CMakeLists.txt new file mode 100644 index 0000000000..412c27e177 --- /dev/null +++ b/modules/rostests/apitests/afd/CMakeLists.txt @@ -0,0 +1,15 @@ + +include_directories( + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/drivers) + +list(APPEND SOURCE + AfdHelpers.c + send.c + precomp.h) + +add_executable(afd_apitest ${SOURCE} testlist.c) +target_link_libraries(afd_apitest wine) +set_module_type(afd_apitest win32cui) +add_importlibs(afd_apitest ws2_32 msvcrt kernel32 ntdll) +add_pch(afd_apitest precomp.h SOURCE) +add_rostests_file(TARGET afd_apitest) diff --git a/modules/rostests/apitests/afd/precomp.h b/modules/rostests/apitests/afd/precomp.h new file mode 100644 index 0000000000..c9a2c8441a --- /dev/null +++ b/modules/rostests/apitests/afd/precomp.h @@ -0,0 +1,26 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1+ (
https://spdx.org/licenses/LGPL-2.1+
) + * PURPOSE: Precompiled header for afd_apitest + * COPYRIGHT: Copyright 2018 Thomas Faber (thomas.faber(a)reactos.org) + */ + +#if !defined(_AFD_APITEST_PRECOMP_H_) +#define _AFD_APITEST_PRECOMP_H_ + +#include <apitest.h> + +#define WIN32_NO_STATUS +#include <ndk/exfuncs.h> +#include <ndk/iofuncs.h> +#include <ndk/obfuncs.h> +#include <ndk/rtlfuncs.h> + +#include <winsock2.h> +#include <tcpioctl.h> +#include <tdi.h> +#include <afd/shared.h> + +#include "AfdHelpers.h" + +#endif /* _AFD_APITEST_PRECOMP_H_ */ diff --git a/modules/rostests/apitests/afd/send.c b/modules/rostests/apitests/afd/send.c new file mode 100644 index 0000000000..9452e78dec --- /dev/null +++ b/modules/rostests/apitests/afd/send.c @@ -0,0 +1,95 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1+ (
https://spdx.org/licenses/LGPL-2.1+
) + * PURPOSE: Test for IOCTL_AFD_SEND/IOCTL_AFD_SEND_DATAGRAM + * COPYRIGHT: Copyright 2015 Thomas Faber (thomas.faber(a)reactos.org) + */ + +#include "precomp.h" + +static +void +TestSend(void) +{ + NTSTATUS Status; + HANDLE SocketHandle; + CHAR Buffer[32]; + struct sockaddr_in addr; + + RtlZeroMemory(Buffer, sizeof(Buffer)); + + Status = AfdCreateSocket(&SocketHandle, AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(Status == STATUS_SUCCESS, "AfdCreateSocket failed with %lx\n", Status); + + Status = AfdSend(SocketHandle, NULL, 0); + ok(Status == STATUS_INVALID_CONNECTION, "AfdSend failed with %lx\n", Status); + + Status = AfdSend(SocketHandle, Buffer, sizeof(Buffer)); + ok(Status == STATUS_INVALID_CONNECTION, "AfdSend failed with %lx\n", Status); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + addr.sin_port = htons(0); + + Status = AfdBind(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr)); + ok(Status == STATUS_SUCCESS, "AfdBind failed with %lx\n", Status); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("8.8.8.8"); + addr.sin_port = htons(53); + + Status = AfdConnect(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr)); + ok(Status == STATUS_SUCCESS, "AfdConnect failed with %lx\n", Status); + + Status = AfdSend(SocketHandle, NULL, 0); + ok(Status == STATUS_SUCCESS, "AfdSend failed with %lx\n", Status); + + Status = AfdSend(SocketHandle, Buffer, sizeof(Buffer)); + ok(Status == STATUS_SUCCESS, "AfdSend failed with %lx\n", Status); + + NtClose(SocketHandle); +} + +static +void +TestSendTo(void) +{ + NTSTATUS Status; + HANDLE SocketHandle; + CHAR Buffer[32]; + struct sockaddr_in addr; + + RtlZeroMemory(Buffer, sizeof(Buffer)); + + Status = AfdCreateSocket(&SocketHandle, AF_INET, SOCK_DGRAM, IPPROTO_UDP); + ok(Status == STATUS_SUCCESS, "AfdCreateSocket failed with %lx\n", Status); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + addr.sin_port = htons(0); + + Status = AfdBind(SocketHandle, (const struct sockaddr *)&addr, sizeof(addr)); + ok(Status == STATUS_SUCCESS, "AfdBind failed with %lx\n", Status); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("8.8.8.8"); + addr.sin_port = htons(53); + + Status = AfdSendTo(SocketHandle, NULL, 0, (const struct sockaddr *)&addr, sizeof(addr)); + ok(Status == STATUS_SUCCESS, "AfdSendTo failed with %lx\n", Status); + + Status = AfdSendTo(SocketHandle, Buffer, sizeof(Buffer), (const struct sockaddr *)&addr, sizeof(addr)); + ok(Status == STATUS_SUCCESS, "AfdSendTo failed with %lx\n", Status); + + NtClose(SocketHandle); +} + +START_TEST(send) +{ + TestSend(); + TestSendTo(); +} diff --git a/modules/rostests/apitests/afd/testlist.c b/modules/rostests/apitests/afd/testlist.c new file mode 100644 index 0000000000..17c82b9f0b --- /dev/null +++ b/modules/rostests/apitests/afd/testlist.c @@ -0,0 +1,10 @@ +#define STANDALONE +#include <apitest.h> + +extern void func_send(void); + +const struct test winetest_testlist[] = +{ + { "send", func_send }, + { 0, 0 } +};
6 years, 9 months
1
0
0
0
01/01: [MSI_WINETEST] Sync with Wine Staging 3.3. CORE-14434
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=31139640eaf53b8147a4a…
commit 31139640eaf53b8147a4a4f46d7b98c8543de5bf Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Mar 5 00:31:58 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Mar 5 00:31:58 2018 +0100 [MSI_WINETEST] Sync with Wine Staging 3.3. CORE-14434 --- modules/rostests/winetests/msi/CMakeLists.txt | 9 +- modules/rostests/winetests/msi/action.c | 52 ++++++- modules/rostests/winetests/msi/automation.c | 17 ++- modules/rostests/winetests/msi/custom.c | 153 ++++++++++++++++++++ modules/rostests/winetests/msi/custom.spec | 4 + modules/rostests/winetests/msi/db.c | 12 +- modules/rostests/winetests/msi/format.c | 8 +- modules/rostests/winetests/msi/install.c | 190 +++++++++++++++++++++++-- modules/rostests/winetests/msi/msi.c | 15 +- modules/rostests/winetests/msi/msi_winetest.rc | 2 + modules/rostests/winetests/msi/package.c | 15 +- modules/rostests/winetests/msi/patch.c | 13 +- modules/rostests/winetests/msi/precomp.h | 1 + modules/rostests/winetests/msi/record.c | 6 +- modules/rostests/winetests/msi/source.c | 12 +- modules/rostests/winetests/msi/suminfo.c | 10 +- 16 files changed, 490 insertions(+), 29 deletions(-) diff --git a/modules/rostests/winetests/msi/CMakeLists.txt b/modules/rostests/winetests/msi/CMakeLists.txt index 3a3a03d77f..23e2f53412 100644 --- a/modules/rostests/winetests/msi/CMakeLists.txt +++ b/modules/rostests/winetests/msi/CMakeLists.txt @@ -3,6 +3,12 @@ add_definitions( -DUSE_WINE_TODOS -D__WINESRC__) +spec2def(custom.dll custom.spec) +add_library(custom SHARED custom.c ${CMAKE_CURRENT_BINARY_DIR}/custom.def) +target_link_libraries(custom uuid) +set_module_type(custom win32dll) +add_importlibs(custom msi ole32 msvcrt kernel32) + list(APPEND SOURCE action.c automation.c @@ -17,9 +23,10 @@ list(APPEND SOURCE suminfo.c precomp.h) -add_executable(msi_winetest ${SOURCE} testlist.c) +add_executable(msi_winetest ${SOURCE} testlist.c msi_winetest.rc) target_link_libraries(msi_winetest uuid) set_module_type(msi_winetest win32cui) add_importlibs(msi_winetest cabinet msi shell32 ole32 oleaut32 user32 advapi32 version msvcrt kernel32) add_pch(msi_winetest precomp.h SOURCE) add_rostests_file(TARGET msi_winetest) +add_dependencies(msi_winetest custom) diff --git a/modules/rostests/winetests/msi/action.c b/modules/rostests/winetests/msi/action.c index 7d8eaa2ebf..31cc9819b0 100644 --- a/modules/rostests/winetests/msi/action.c +++ b/modules/rostests/winetests/msi/action.c @@ -19,7 +19,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#include <stdio.h> +#include <stdlib.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <srrestoreptapi.h> +#include <wtypes.h> +#include <shellapi.h> +#include <winsvc.h> + +#include "wine/test.h" static UINT (WINAPI *pMsiQueryComponentStateA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE *); @@ -492,7 +506,22 @@ static const char wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" - "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; + "augustus\t\tMSITESTDIR\t0\t\taugustus\n" + "caesar\t\tMSITESTDIR\t1\t\t\n"; + +static const char wrv_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "feature\t\tFeature\tFeature\t2\t1\tTARGETDIR\t0\n" + "feature2\t\tFeature2\tFeature2\t2\t1\tTARGETDIR\t1"; + +static const char wrv_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\taugustus\n" + "feature2\tcaesar"; static const char wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" @@ -513,7 +542,8 @@ static const char wrv_registry_dat[] = "regdata12\t2\tSOFTWARE\\Wine\\msitest\tValue8\t#1\taugustus\n" "regdata13\t2\tSOFTWARE\\Wine\\msitest\tValue9\t#x1\taugustus\n" "regdata14\t2\tSOFTWARE\\Wine\\msitest\tValue10\t#x01\taugustus\n" - "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n"; + "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n" + "regdata16\t2\tSOFTWARE\\Wine\\msitest\tValue12\t#1\tcaesar\n"; static const char cf_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" @@ -1738,8 +1768,8 @@ static const msi_table wrv_tables[] = { ADD_TABLE(wrv_component), ADD_TABLE(directory), - ADD_TABLE(rof_feature), - ADD_TABLE(ci2_feature_comp), + ADD_TABLE(wrv_feature), + ADD_TABLE(wrv_feature_comp), ADD_TABLE(ci2_file), ADD_TABLE(install_exec_seq), ADD_TABLE(rof_media), @@ -4974,7 +5004,7 @@ static void test_write_registry_values(void) goto error; } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\augustus", TRUE), "File installed\n"); + ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n"); ok(delete_pf("msitest", FALSE), "Directory not created\n"); if (is_64bit) @@ -5097,6 +5127,15 @@ static void test_write_registry_values(void) ok(size == 1, "got %u\n", size); ok(type == REG_BINARY, "got %u\n", type); + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value12", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(*(DWORD *)buf == 1, "got %u\n", *(DWORD *)buf); + ok(size == 4, "got %u\n", size); + ok(type == REG_DWORD, "got %u\n", type); + RegDeleteValueA(hkey, "Value"); RegDeleteValueA(hkey, "Value1"); RegDeleteValueA(hkey, "Value2"); @@ -5109,6 +5148,7 @@ static void test_write_registry_values(void) RegDeleteValueA(hkey, "Value9"); RegDeleteValueA(hkey, "Value10"); RegDeleteValueA(hkey, "Value11"); + RegDeleteValueA(hkey, "Value12"); RegCloseKey(hkey); RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); diff --git a/modules/rostests/winetests/msi/automation.c b/modules/rostests/winetests/msi/automation.c index 1cb4959bc3..39d1980122 100644 --- a/modules/rostests/winetests/msi/automation.c +++ b/modules/rostests/winetests/msi/automation.c @@ -19,10 +19,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS -#include "precomp.h" +#include <stdio.h> -#include <ole2.h> +#include <initguid.h> +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <oaidl.h> + +#include "wine/test.h" + +#ifdef __REACTOS__ +#include "ole2.h" +#endif static BOOL is_wow64; diff --git a/modules/rostests/winetests/msi/custom.c b/modules/rostests/winetests/msi/custom.c new file mode 100644 index 0000000000..feb8061519 --- /dev/null +++ b/modules/rostests/winetests/msi/custom.c @@ -0,0 +1,153 @@ +/* + * DLL for testing type 1 custom actions + * + * Copyright 2017 Zebediah Figura + * + * 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 <stdarg.h> +#include <stdio.h> + +#include <windef.h> +#include <winbase.h> +#define COBJMACROS +#include <objbase.h> +#include <unknwn.h> +#include <msi.h> +#include <msiquery.h> + +static void ok_(MSIHANDLE hinst, int todo, const char *file, int line, int condition, const char *msg, ...) +{ + static char buffer[2000]; + MSIHANDLE record; + va_list valist; + + va_start(valist, msg); + vsprintf(buffer, msg, valist); + va_end(valist); + + record = MsiCreateRecord(5); + MsiRecordSetInteger(record, 1, todo); + MsiRecordSetStringA(record, 2, file); + MsiRecordSetInteger(record, 3, line); + MsiRecordSetInteger(record, 4, condition); + MsiRecordSetStringA(record, 5, buffer); + MsiProcessMessage(hinst, INSTALLMESSAGE_USER, record); + MsiCloseHandle(record); +} +#define ok(hinst, condition, ...) ok_(hinst, 0, __FILE__, __LINE__, condition, __VA_ARGS__) +#define todo_wine_ok(hinst, condition, ...) ok_(hinst, 1, __FILE__, __LINE__, condition, __VA_ARGS__) + + +/* Main test. Anything that doesn't depend on a specific install configuration + * or have undesired side effects should go here. */ +UINT WINAPI main_test(MSIHANDLE hinst) +{ + UINT res; + IUnknown *unk = NULL; + HRESULT hres; + + /* Test for an MTA apartment */ + hres = CoCreateInstance(&CLSID_Picture_Metafile, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + todo_wine_ok(hinst, hres == S_OK, "CoCreateInstance failed with %08x\n", hres); + + if (unk) IUnknown_Release(unk); + + /* Test MsiGetDatabaseState() */ + res = MsiGetDatabaseState(hinst); + todo_wine_ok(hinst, res == MSIDBSTATE_ERROR, "expected MSIDBSTATE_ERROR, got %u\n", res); + + return ERROR_SUCCESS; +} + +UINT WINAPI test_retval(MSIHANDLE hinst) +{ + char prop[10]; + DWORD len = sizeof(prop); + UINT retval; + + MsiGetPropertyA(hinst, "TEST_RETVAL", prop, &len); + sscanf(prop, "%u", &retval); + return retval; +} + +static void append_file(MSIHANDLE hinst, const char *filename, const char *text) +{ + DWORD size; + HANDLE file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(hinst, file != INVALID_HANDLE_VALUE, "CreateFile failed, error %u\n", GetLastError()); + + SetFilePointer(file, 0, NULL, FILE_END); + WriteFile(file, text, strlen(text), &size, NULL); + CloseHandle(file); +} + +UINT WINAPI da_immediate(MSIHANDLE hinst) +{ + char prop[300]; + DWORD len = sizeof(prop); + + MsiGetPropertyA(hinst, "TESTPATH", prop, &len); + + append_file(hinst, prop, "one"); + + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "shouldn't be scheduled\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); + + return ERROR_SUCCESS; +} + +UINT WINAPI da_deferred(MSIHANDLE hinst) +{ + char prop[300]; + DWORD len = sizeof(prop); + LANGID lang; + UINT r; + + /* Test that we were in fact deferred */ + r = MsiGetPropertyA(hinst, "CustomActionData", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "CustomActionData was empty\n"); + + append_file(hinst, prop, "two"); + + /* Test available properties */ + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "ProductCode", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "got %s\n", prop); + + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "UserSID", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + ok(hinst, prop[0], "got %s\n", prop); + + len = sizeof(prop); + r = MsiGetPropertyA(hinst, "TESTPATH", prop, &len); + ok(hinst, r == ERROR_SUCCESS, "got %u\n", r); + todo_wine_ok(hinst, !prop[0], "got %s\n", prop); + + /* Test modes */ + ok(hinst, MsiGetMode(hinst, MSIRUNMODE_SCHEDULED), "should be scheduled\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_ROLLBACK), "shouldn't be rollback\n"); + ok(hinst, !MsiGetMode(hinst, MSIRUNMODE_COMMIT), "shouldn't be commit\n"); + + lang = MsiGetLanguage(hinst); + ok(hinst, lang != ERROR_INVALID_HANDLE, "MsiGetLanguage failed\n"); + + return ERROR_SUCCESS; +} diff --git a/modules/rostests/winetests/msi/custom.spec b/modules/rostests/winetests/msi/custom.spec new file mode 100644 index 0000000000..bb400fffe9 --- /dev/null +++ b/modules/rostests/winetests/msi/custom.spec @@ -0,0 +1,4 @@ +@ stdcall main_test(long) +@ stdcall test_retval(long) +@ stdcall da_immediate(long) +@ stdcall da_deferred(long) diff --git a/modules/rostests/winetests/msi/db.c b/modules/rostests/winetests/msi/db.c index 15fb93c82e..3cbb9b3e28 100644 --- a/modules/rostests/winetests/msi/db.c +++ b/modules/rostests/winetests/msi/db.c @@ -18,7 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS + +#include <stdio.h> + +#include <windows.h> +#include <objidl.h> +#include <msi.h> +#include <msidefs.h> +#include <msiquery.h> + +#include "wine/test.h" static const char *msifile = "winetest-db.msi"; static const char *msifile2 = "winetst2-db.msi"; diff --git a/modules/rostests/winetests/msi/format.c b/modules/rostests/winetests/msi/format.c index cc00af063f..6cb52cf04d 100644 --- a/modules/rostests/winetests/msi/format.c +++ b/modules/rostests/winetests/msi/format.c @@ -19,7 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdio.h> +#include <windows.h> +#include <shlwapi.h> +#include <msi.h> +#include <msiquery.h> + +#include "wine/test.h" static const char msifile[] = "winetest-format.msi"; diff --git a/modules/rostests/winetests/msi/install.c b/modules/rostests/winetests/msi/install.c index 2e08918b9e..69095cd8f0 100644 --- a/modules/rostests/winetests/msi/install.c +++ b/modules/rostests/winetests/msi/install.c @@ -18,7 +18,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <fci.h> +#include <objidl.h> +#include <srrestoreptapi.h> +#include <shlobj.h> +#include <winsvc.h> +#include <shellapi.h> + +#include "wine/test.h" static UINT (WINAPI *pMsiQueryComponentStateA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*); @@ -54,6 +70,8 @@ static CHAR COMMON_FILES_DIR[MAX_PATH]; static CHAR APP_DATA_DIR[MAX_PATH]; static CHAR WINDOWS_DIR[MAX_PATH]; +static const char *customdll; + /* msi database data */ static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" @@ -674,6 +692,18 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt "Component\tComponent\n" "augustus\t\tMSITESTDIR\t0\t\taugustus\n"; +static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "maintest\tMAIN_TEST\t700\n" + "testretval\tTEST_RETVAL\t710\n"; + +static const CHAR ca1_custom_action_dat[] = "Action\tType\tSource\tTarget\n" + "s72\ti2\tS64\tS0\n" + "CustomAction\tAction\n" + "maintest\t1\tcustom.dll\tmain_test\n" + "testretval\t1\tcustom.dll\ttest_retval\n"; + static const CHAR ca51_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -1270,12 +1300,12 @@ static const char ft_install_exec_seq_dat[] = "InstallFinalize\t\t1500\n"; static const char da_custom_action_dat[] = - "Action\tType\tSource\tTarget\tISComments\n" - "s72\ti2\tS64\tS0\tS255\n" + "Action\tType\tSource\tTarget\n" + "s72\ti2\tS64\tS0\n" "CustomAction\tAction\n" - "deferred\t1074\tCMDEXE\t/c if exist msitest (exit 0) else (exit 1)\t\n" - "immediate\t50\tCMDEXE\t/c mkdir msitest\t\n" - "cleanup\t50\tCMDEXE\t/c rmdir msitest\t\n"; + "setprop\t51\tdeferred\t[TESTPATH]\n" + "immediate\t1\tcustom.dll\tda_immediate\n" + "deferred\t1025\tcustom.dll\tda_deferred\n"; static const char da_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" @@ -1285,10 +1315,10 @@ static const char da_install_exec_seq_dat[] = "FileCost\t\t300\n" "CostFinalize\t\t400\n" "InstallInitialize\t\t500\n" - "deferred\t\t600\n" - "immediate\t\t700\n" - "InstallFinalize\t\t1100\n" - "cleanup\t\t1200\n"; + "setprop\t\t600\n" + "deferred\t\t700\n" + "immediate\t\t800\n" + "InstallFinalize\t\t1100\n"; typedef struct _msi_table { @@ -1667,6 +1697,13 @@ static const msi_table sf_tables[] = ADD_TABLE(property), }; +static const msi_table ca1_tables[] = +{ + ADD_TABLE(property), + ADD_TABLE(ca1_install_exec_seq), + ADD_TABLE(ca1_custom_action), +}; + static const msi_table ca51_tables[] = { ADD_TABLE(ca51_component), @@ -2573,6 +2610,29 @@ static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access ) return RegDeleteKeyA( key, subkey ); } +static char *load_resource(const char *name) +{ + static char path[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempFileNameA(".", name, 0, path); + + file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", path, GetLastError()); + + res = FindResourceA(NULL, name, "TESTDLL"); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); + + return path; +} + static void test_MsiInstallProduct(void) { UINT r; @@ -3998,6 +4058,84 @@ error: DeleteFileA("augustus"); } +static void add_custom_dll(void) +{ + MSIHANDLE hdb = 0, record; + UINT res; + + res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_TRANSACT, &hdb); + ok(res == ERROR_SUCCESS, "failed to open db: %u\n", res); + + res = run_query(hdb, 0, "CREATE TABLE `Binary` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL PRIMARY KEY `Name`)"); + ok(res == ERROR_SUCCESS, "failed to create Binary table: %u\n", res); + + record = MsiCreateRecord(1); + res = MsiRecordSetStreamA(record, 1, customdll); + ok(res == ERROR_SUCCESS, "failed to add %s to stream: %u\n", customdll, res); + + res = run_query(hdb, record, "INSERT INTO `Binary` (`Name`, `Data`) VALUES ('custom.dll', ?)"); + ok(res == ERROR_SUCCESS, "failed to insert into Binary table: %u\n", res); + + res = MsiDatabaseCommit(hdb); + ok(res == ERROR_SUCCESS, "failed to commit database: %u\n", res); + + MsiCloseHandle(record); + MsiCloseHandle(hdb); +} + +static INT CALLBACK ok_callback(void *context, UINT message_type, MSIHANDLE record) +{ + if (message_type == INSTALLMESSAGE_USER) + { + char file[200]; + char msg[2000]; + DWORD len; + + len = sizeof(file); + MsiRecordGetStringA(record, 2, file, &len); + len = sizeof(msg); + MsiRecordGetStringA(record, 5, msg, &len); + + todo_wine_if(MsiRecordGetInteger(record, 1)) + ok_(file, MsiRecordGetInteger(record, 3)) (MsiRecordGetInteger(record, 4), "%s", msg); + + return 1; + } + return 0; +} + +static void test_customaction1(void) +{ + UINT r; + + create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table)); + add_custom_dll(); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, "MAIN_TEST=1"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* Test return values */ + r = MsiInstallProductA(msifile, "TEST_RETVAL=0"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=1626"); /* ERROR_FUNCTION_NOT_CALLED*/ + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=1602"); + ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %u\n", r); + + r = MsiInstallProductA(msifile, "TEST_RETVAL=259"); /* ERROR_NO_MORE_ITEMS */ + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + /* any other error maps to ERROR_INSTALL_FAILURE */ + r = MsiInstallProductA(msifile, "TEST_RETVAL=1"); + ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); + + DeleteFileA(msifile); +} + static void test_customaction51(void) { UINT r; @@ -5904,23 +6042,45 @@ static void test_feature_tree(void) DeleteFileA( msifile ); } +static void check_file_matches(const char *filename, const char *text) +{ + char buffer[200]; + HANDLE file; + DWORD size; + + file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + ReadFile(file, buffer, sizeof(buffer), &size, NULL); + ok(size == strlen(text) && !memcmp(buffer, text, size), "got %.*s\n", size, buffer); + CloseHandle(file); +} + static void test_deferred_action(void) { + char path[200], file[200], buffer[200]; UINT r; + GetTempPathA(sizeof(path), path); + GetTempFileNameA(path, "da", 0, file); + sprintf(buffer, "TESTPATH=\"%s\"", file); + create_database(msifile, da_tables, sizeof(da_tables) / sizeof(da_tables[0])); + add_custom_dll(); MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - r = MsiInstallProductA(msifile, "CMDEXE=\"cmd.exe\""); + r = MsiInstallProductA(msifile, buffer); if (r == ERROR_INSTALL_PACKAGE_REJECTED) { skip("Not enough rights to perform tests\n"); goto error; } -todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); +todo_wine + check_file_matches(file, "onetwo"); + + ok(DeleteFileA(file), "Directory not created\n"); + error: DeleteFileA(msifile); } @@ -5971,6 +6131,9 @@ START_TEST(install) lstrcatA(log_file, "\\msitest.log"); MsiEnableLogA(INSTALLLOGMODE_FATALEXIT, log_file, 0); + customdll = load_resource("custom.dll"); + MsiSetExternalUIRecord(ok_callback, INSTALLLOGMODE_USER, NULL, NULL); + if (pSRSetRestorePointA) /* test has side-effects on win2k3 that cause failures in following tests */ test_MsiInstallProduct(); test_MsiSetComponentState(); @@ -5990,6 +6153,7 @@ START_TEST(install) test_adminprops(); test_missingcab(); test_sourcefolder(); + test_customaction1(); test_customaction51(); test_installstate(); test_sourcepath(); @@ -6015,6 +6179,8 @@ START_TEST(install) test_feature_tree(); test_deferred_action(); + DeleteFileA(customdll); + DeleteFileA(log_file); if (pSRSetRestorePointA && !pMsiGetComponentPathExA && ret) diff --git a/modules/rostests/winetests/msi/msi.c b/modules/rostests/winetests/msi/msi.c index 25d9dad459..4b545f2d5a 100644 --- a/modules/rostests/winetests/msi/msi.c +++ b/modules/rostests/winetests/msi/msi.c @@ -18,7 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include <stdio.h> +#include <windows.h> +#include <msi.h> +#include <msiquery.h> +#include <msidefs.h> +#include <sddl.h> +#include <fci.h> +#include <shellapi.h> +#include <objidl.h> + +#include "wine/test.h" static BOOL is_wow64; static const char msifile[] = "winetest.msi"; diff --git a/modules/rostests/winetests/msi/msi_winetest.rc b/modules/rostests/winetests/msi/msi_winetest.rc new file mode 100644 index 0000000000..6aa15fe499 --- /dev/null +++ b/modules/rostests/winetests/msi/msi_winetest.rc @@ -0,0 +1,2 @@ + +CUSTOM.DLL TESTDLL "custom.dll" diff --git a/modules/rostests/winetests/msi/package.c b/modules/rostests/winetests/msi/package.c index f29baa9d25..2022953f9b 100644 --- a/modules/rostests/winetests/msi/package.c +++ b/modules/rostests/winetests/msi/package.c @@ -19,11 +19,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS #include <assert.h> +#include <stdio.h> +#include <windows.h> +#include <msidefs.h> +#include <msi.h> +#include <msiquery.h> +#include <srrestoreptapi.h> #include <shlobj.h> +#include "wine/test.h" + static BOOL is_wow64; static const char msifile[] = "winetest-package.msi"; static const WCHAR msifileW[] = @@ -5644,6 +5652,11 @@ static void test_installprops(void) ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); ok(atol(buf) == res, "Expected %d, got %ld\n", res, atol(buf)); + buf[0] = 0; + size = MAX_PATH; + r = MsiGetPropertyA(hpkg, "MsiNetAssemblySupport", buf, &size); + if (r == ERROR_SUCCESS) trace( "MsiNetAssemblySupport \"%s\"\n", buf ); + if (pGetSystemInfo && pSHGetFolderPathA) { pGetSystemInfo(&si); diff --git a/modules/rostests/winetests/msi/patch.c b/modules/rostests/winetests/msi/patch.c index bb2276ee58..b6e990b461 100644 --- a/modules/rostests/winetests/msi/patch.c +++ b/modules/rostests/winetests/msi/patch.c @@ -18,7 +18,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#define COBJMACROS + +#include <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <wtypes.h> + +#include "wine/test.h" static UINT (WINAPI *pMsiApplyPatchA)( LPCSTR, LPCSTR, INSTALLTYPE, LPCSTR ); static UINT (WINAPI *pMsiGetPatchInfoExA)( LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, diff --git a/modules/rostests/winetests/msi/precomp.h b/modules/rostests/winetests/msi/precomp.h index 67839b12f0..f5ae370220 100644 --- a/modules/rostests/winetests/msi/precomp.h +++ b/modules/rostests/winetests/msi/precomp.h @@ -1,3 +1,4 @@ + #ifndef _MSI_WINETEST_PRECOMP_H_ #define _MSI_WINETEST_PRECOMP_H_ diff --git a/modules/rostests/winetests/msi/record.c b/modules/rostests/winetests/msi/record.c index a37e408c98..777f1f78ed 100644 --- a/modules/rostests/winetests/msi/record.c +++ b/modules/rostests/winetests/msi/record.c @@ -18,7 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <windows.h> +#include <msi.h> +#include <msiquery.h> + +#include "wine/test.h" static const char *msifile = "winetest-record.msi"; static const WCHAR msifileW[] = diff --git a/modules/rostests/winetests/msi/source.c b/modules/rostests/winetests/msi/source.c index daf2979bbb..a03cf557aa 100644 --- a/modules/rostests/winetests/msi/source.c +++ b/modules/rostests/winetests/msi/source.c @@ -18,9 +18,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define _WIN32_MSI 300 +#include <stdio.h> + +#include <windows.h> +#include <msiquery.h> +#include <msidefs.h> +#include <msi.h> +#include <sddl.h> #include <secext.h> +#include <objbase.h> + +#include "wine/test.h" static BOOL is_wow64; diff --git a/modules/rostests/winetests/msi/suminfo.c b/modules/rostests/winetests/msi/suminfo.c index 40fcef4488..8c2e292ab8 100644 --- a/modules/rostests/winetests/msi/suminfo.c +++ b/modules/rostests/winetests/msi/suminfo.c @@ -18,7 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define COBJMACROS + +#include <stdio.h> +#include <windows.h> +#include <msi.h> +#include <msiquery.h> +#include <objidl.h> + +#include "wine/test.h" /* * The following are defined in Windows SDK's msidefs.h
6 years, 9 months
1
0
0
0
01/01: [MSI] Sync with Wine Staging 3.3. CORE-14434
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c42b133eb11aab09f5d8b…
commit c42b133eb11aab09f5d8bb261c9a25188963eee8 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Mar 5 00:30:58 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Mar 5 00:30:58 2018 +0100 [MSI] Sync with Wine Staging 3.3. CORE-14434 --- dll/win32/msi/CMakeLists.txt | 4 +- dll/win32/msi/action.c | 76 ++++++++++++++- dll/win32/msi/alter.c | 12 +++ dll/win32/msi/appsearch.c | 15 ++- dll/win32/msi/assembly.c | 9 ++ dll/win32/msi/automation.c | 16 ++++ dll/win32/msi/classes.c | 9 ++ dll/win32/msi/cond.tab.c | 208 ++++++++++++++++++++++------------------- dll/win32/msi/cond.y | 20 ++++ dll/win32/msi/create.c | 15 +++ dll/win32/msi/custom.c | 20 +++- dll/win32/msi/database.c | 203 ++++++++++++++++++++++++++++++++-------- dll/win32/msi/delete.c | 14 +++ dll/win32/msi/dialog.c | 33 +++++-- dll/win32/msi/distinct.c | 13 +++ dll/win32/msi/drop.c | 12 +++ dll/win32/msi/files.c | 30 ++++-- dll/win32/msi/font.c | 7 ++ dll/win32/msi/format.c | 16 ++++ dll/win32/msi/handle.c | 11 +++ dll/win32/msi/insert.c | 15 +++ dll/win32/msi/install.c | 15 +++ dll/win32/msi/media.c | 16 +++- dll/win32/msi/msi.c | 32 ++++++- dll/win32/msi/msi.rc | 5 +- dll/win32/msi/msi_main.c | 13 ++- dll/win32/msi/msipriv.h | 45 +++------ dll/win32/msi/msiquery.c | 19 ++++ dll/win32/msi/package.c | 130 ++++++++++++++++---------- dll/win32/msi/patch.c | 9 ++ dll/win32/msi/precomp.h | 30 ++++++ dll/win32/msi/query.h | 12 +++ dll/win32/msi/record.c | 20 ++++ dll/win32/msi/registry.c | 16 ++++ dll/win32/msi/resource.h | 2 + dll/win32/msi/script.c | 14 ++- dll/win32/msi/select.c | 14 +++ dll/win32/msi/source.c | 17 ++++ dll/win32/msi/sql.tab.c | 217 +++++++++++++++++++++---------------------- dll/win32/msi/sql.tab.h | 8 +- dll/win32/msi/storages.c | 15 +++ dll/win32/msi/streams.c | 42 ++++++++- dll/win32/msi/string.c | 17 ++++ dll/win32/msi/suminfo.c | 137 ++++++++++++++++++++++++++- dll/win32/msi/table.c | 17 ++++ dll/win32/msi/tokenize.c | 9 +- dll/win32/msi/update.c | 14 +++ dll/win32/msi/upgrade.c | 10 ++ dll/win32/msi/where.c | 15 +++ media/doc/README.WINE | 2 +- 50 files changed, 1293 insertions(+), 377 deletions(-) diff --git a/dll/win32/msi/CMakeLists.txt b/dll/win32/msi/CMakeLists.txt index 9bbf9eaaa1..3eaee0fefa 100644 --- a/dll/win32/msi/CMakeLists.txt +++ b/dll/win32/msi/CMakeLists.txt @@ -49,7 +49,7 @@ list(APPEND SOURCE update.c upgrade.c where.c - msipriv.h) + precomp.h) add_library(msi SHARED ${SOURCE} @@ -73,5 +73,5 @@ add_importlibs(msi advapi32 advapi32_vista cabinet comctl32 gdi32 ole32 oleaut32 kernel32 ntdll) -add_pch(msi msipriv.h SOURCE) +add_pch(msi precomp.h SOURCE) add_cd_file(TARGET msi DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/msi/action.c b/dll/win32/msi/action.c index c3a36eefac..3909246869 100644 --- a/dll/win32/msi/action.c +++ b/dll/win32/msi/action.c @@ -18,11 +18,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "winsvc.h" +#include "odbcinst.h" +#include "wine/debug.h" +#include "msidefs.h" +#include "winuser.h" +#include "shlobj.h" +#include "objbase.h" +#include "mscoree.h" +#include "shlwapi.h" +#include "imagehlp.h" +#include "wine/unicode.h" +#include "winver.h" -#include <winsvc.h> -#include <odbcinst.h> -#include <imagehlp.h> +#include "msipriv.h" +#include "resource.h" #define REG_PROGRESS_VALUE 13200 #define COMPONENT_PROGRESS_VALUE 24000 @@ -142,6 +160,13 @@ static const WCHAR szWriteEnvironmentStrings[] = static const WCHAR szINSTALL[] = {'I','N','S','T','A','L','L',0}; +struct dummy_thread +{ + HANDLE started; + HANDLE stopped; + HANDLE thread; +}; + static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR description, LPCWSTR template) { WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', @@ -2854,7 +2879,7 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; comp->Action = msi_get_component_action( package, comp ); - if (comp->Action != INSTALLSTATE_LOCAL) + if (comp->Action != INSTALLSTATE_LOCAL && comp->Action != INSTALLSTATE_SOURCE) { TRACE("component not scheduled for installation %s\n", debugstr_w(component)); return ERROR_SUCCESS; @@ -7952,6 +7977,42 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq) return rc; } +DWORD WINAPI dummy_thread_proc(void *arg) +{ + struct dummy_thread *info = arg; + HRESULT hr; + + hr = CoInitializeEx(0, COINIT_MULTITHREADED); + if (FAILED(hr)) ERR("CoInitializeEx failed %08x\n", hr); + + SetEvent(info->started); + WaitForSingleObject(info->stopped, INFINITE); + + CoUninitialize(); + return 0; +} + +static void start_dummy_thread(struct dummy_thread *info) +{ + if (!(info->started = CreateEventA(NULL, TRUE, FALSE, NULL))) return; + if (!(info->stopped = CreateEventA(NULL, TRUE, FALSE, NULL))) return; + if (!(info->thread = CreateThread(NULL, 0, dummy_thread_proc, info, 0, NULL))) return; + + WaitForSingleObject(info->started, INFINITE); +} + +static void stop_dummy_thread(struct dummy_thread *info) +{ + if (info->thread) + { + SetEvent(info->stopped); + WaitForSingleObject(info->thread, INFINITE); + CloseHandle(info->thread); + } + if (info->started) CloseHandle(info->started); + if (info->stopped) CloseHandle(info->stopped); +} + /**************************************************** * TOP level entry points *****************************************************/ @@ -7962,6 +8023,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, static const WCHAR szDisableRollback[] = {'D','I','S','A','B','L','E','R','O','L','L','B','A','C','K',0}; static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; WCHAR *reinstall = NULL, *productcode, *action; + struct dummy_thread thread_info = {NULL, NULL, NULL}; UINT rc; DWORD len = 0; @@ -8018,6 +8080,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_adjust_privilege_properties( package ); msi_set_context( package ); + start_dummy_thread(&thread_info); + productcode = msi_dup_property( package->db, szProductCode ); if (strcmpiW( productcode, package->ProductCode )) { @@ -8054,6 +8118,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, /* finish up running custom actions */ ACTION_FinishCustomActions(package); + stop_dummy_thread(&thread_info); + if (package->need_rollback && !(reinstall = msi_dup_property( package->db, szReinstall ))) { WARN("installation failed, running rollback script\n"); diff --git a/dll/win32/msi/alter.c b/dll/win32/msi/alter.c index fff3785a00..8b11351f8b 100644 --- a/dll/win32/msi/alter.c +++ b/dll/win32/msi/alter.c @@ -18,8 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "query.h" + WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct tagMSIALTERVIEW diff --git a/dll/win32/msi/appsearch.c b/dll/win32/msi/appsearch.c index 8f2df294b4..693da18355 100644 --- a/dll/win32/msi/appsearch.c +++ b/dll/win32/msi/appsearch.c @@ -17,7 +17,20 @@ * 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 <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "msi.h" +#include "msiquery.h" +#include "msidefs.h" +#include "winver.h" +#include "shlwapi.h" +#include "wine/unicode.h" +#include "wine/debug.h" #include "msipriv.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/assembly.c b/dll/win32/msi/assembly.c index c652b3040e..bccd114b49 100644 --- a/dll/win32/msi/assembly.c +++ b/dll/win32/msi/assembly.c @@ -18,6 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/unicode.h" #include "msipriv.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/automation.c b/dll/win32/msi/automation.c index cef4059bac..06ad2f90a4 100644 --- a/dll/win32/msi/automation.c +++ b/dll/win32/msi/automation.c @@ -18,7 +18,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winuser.h" +#include "winreg.h" +#include "msidefs.h" #include "msipriv.h" +#include "activscp.h" +#include "oleauto.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +#include "msiserver.h" #include "msiserver_dispids.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/classes.c b/dll/win32/msi/classes.c index 9b5794fdf3..60cc3c1a4b 100644 --- a/dll/win32/msi/classes.c +++ b/dll/win32/msi/classes.c @@ -30,7 +30,16 @@ * UnregisterMIMEInfo */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/debug.h" #include "msipriv.h" +#include "winuser.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/cond.tab.c b/dll/win32/msi/cond.tab.c index 122f92a153..65c56bdc76 100644 --- a/dll/win32/msi/cond.tab.c +++ b/dll/win32/msi/cond.tab.c @@ -91,7 +91,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "oleauto.h" + #include "msipriv.h" +#include "msiserver.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -164,7 +184,7 @@ static void value_free( struct value val ) } -#line 168 "cond.tab.c" /* yacc.c:339 */ +#line 188 "cond.tab.c" /* yacc.c:339 */ # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus @@ -184,8 +204,8 @@ static void value_free( struct value val ) /* In a future release of Bison, this section will be replaced by #include "cond.tab.h". */ -#ifndef YY_COND_E_REACTOSSYNC3_0_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED -# define YY_COND_E_REACTOSSYNC3_0_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED +#ifndef YY_COND_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED +# define YY_COND_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -245,7 +265,7 @@ extern int cond_debug; typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 102 "cond.y" /* yacc.c:355 */ +#line 122 "cond.y" /* yacc.c:355 */ struct cond_str str; struct value value; @@ -253,7 +273,7 @@ union YYSTYPE INT operator; BOOL bool; -#line 257 "cond.tab.c" /* yacc.c:355 */ +#line 277 "cond.tab.c" /* yacc.c:355 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 @@ -263,11 +283,11 @@ union YYSTYPE int cond_parse (COND_input *info); -#endif /* !YY_COND_E_REACTOSSYNC3_0_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED */ +#endif /* !YY_COND_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_COND_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 271 "cond.tab.c" /* yacc.c:358 */ +#line 291 "cond.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -549,11 +569,11 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 129, 129, 135, 142, 146, 150, 154, 158, 165, - 169, 176, 180, 188, 223, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 252, 266, 281, 289, 299, 316, 333, - 350, 370 + 0, 149, 149, 155, 162, 166, 170, 174, 178, 185, + 189, 196, 200, 208, 243, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 272, 286, 301, 309, 319, 336, 353, + 370, 390 }; #endif @@ -1372,89 +1392,89 @@ yyreduce: switch (yyn) { case 2: -#line 130 "cond.y" /* yacc.c:1646 */ +#line 150 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; cond->result = (yyvsp[0].bool); } -#line 1381 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1401 "cond.tab.c" /* yacc.c:1646 */ break; case 3: -#line 135 "cond.y" /* yacc.c:1646 */ +#line 155 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; cond->result = MSICONDITION_NONE; } -#line 1390 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1410 "cond.tab.c" /* yacc.c:1646 */ break; case 4: -#line 143 "cond.y" /* yacc.c:1646 */ +#line 163 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = (yyvsp[0].bool); } -#line 1398 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1418 "cond.tab.c" /* yacc.c:1646 */ break; case 5: -#line 147 "cond.y" /* yacc.c:1646 */ +#line 167 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = (yyvsp[-2].bool) || (yyvsp[0].bool); } -#line 1406 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1426 "cond.tab.c" /* yacc.c:1646 */ break; case 6: -#line 151 "cond.y" /* yacc.c:1646 */ +#line 171 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = !(yyvsp[-2].bool) || (yyvsp[0].bool); } -#line 1414 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1434 "cond.tab.c" /* yacc.c:1646 */ break; case 7: -#line 155 "cond.y" /* yacc.c:1646 */ +#line 175 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = ( (yyvsp[-2].bool) || (yyvsp[0].bool) ) && !( (yyvsp[-2].bool) && (yyvsp[0].bool) ); } -#line 1422 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1442 "cond.tab.c" /* yacc.c:1646 */ break; case 8: -#line 159 "cond.y" /* yacc.c:1646 */ +#line 179 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = ( (yyvsp[-2].bool) && (yyvsp[0].bool) ) || ( !(yyvsp[-2].bool) && !(yyvsp[0].bool) ); } -#line 1430 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1450 "cond.tab.c" /* yacc.c:1646 */ break; case 9: -#line 166 "cond.y" /* yacc.c:1646 */ +#line 186 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = (yyvsp[0].bool); } -#line 1438 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1458 "cond.tab.c" /* yacc.c:1646 */ break; case 10: -#line 170 "cond.y" /* yacc.c:1646 */ +#line 190 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = (yyvsp[-2].bool) && (yyvsp[0].bool); } -#line 1446 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1466 "cond.tab.c" /* yacc.c:1646 */ break; case 11: -#line 177 "cond.y" /* yacc.c:1646 */ +#line 197 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = !(yyvsp[0].bool); } -#line 1454 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1474 "cond.tab.c" /* yacc.c:1646 */ break; case 12: -#line 181 "cond.y" /* yacc.c:1646 */ +#line 201 "cond.y" /* yacc.c:1646 */ { if ((yyvsp[0].value).type == VALUE_INTEGER) (yyval.bool) = (yyvsp[0].value).u.integer ? 1 : 0; @@ -1462,11 +1482,11 @@ yyreduce: (yyval.bool) = (yyvsp[0].value).u.string && (yyvsp[0].value).u.string[0]; value_free( (yyvsp[0].value) ); } -#line 1466 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1486 "cond.tab.c" /* yacc.c:1646 */ break; case 13: -#line 189 "cond.y" /* yacc.c:1646 */ +#line 209 "cond.y" /* yacc.c:1646 */ { if ((yyvsp[-2].value).type == VALUE_INTEGER && (yyvsp[0].value).type == VALUE_INTEGER) { @@ -1501,127 +1521,127 @@ yyreduce: value_free( (yyvsp[-2].value) ); value_free( (yyvsp[0].value) ); } -#line 1505 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1525 "cond.tab.c" /* yacc.c:1646 */ break; case 14: -#line 224 "cond.y" /* yacc.c:1646 */ +#line 244 "cond.y" /* yacc.c:1646 */ { (yyval.bool) = (yyvsp[-1].bool); } -#line 1513 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1533 "cond.tab.c" /* yacc.c:1646 */ break; case 15: -#line 231 "cond.y" /* yacc.c:1646 */ +#line 251 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_EQ; } -#line 1519 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1539 "cond.tab.c" /* yacc.c:1646 */ break; case 16: -#line 232 "cond.y" /* yacc.c:1646 */ +#line 252 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_NE; } -#line 1525 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1545 "cond.tab.c" /* yacc.c:1646 */ break; case 17: -#line 233 "cond.y" /* yacc.c:1646 */ +#line 253 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_LT; } -#line 1531 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1551 "cond.tab.c" /* yacc.c:1646 */ break; case 18: -#line 234 "cond.y" /* yacc.c:1646 */ +#line 254 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_GT; } -#line 1537 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1557 "cond.tab.c" /* yacc.c:1646 */ break; case 19: -#line 235 "cond.y" /* yacc.c:1646 */ +#line 255 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_LE; } -#line 1543 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1563 "cond.tab.c" /* yacc.c:1646 */ break; case 20: -#line 236 "cond.y" /* yacc.c:1646 */ +#line 256 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_GE; } -#line 1549 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1569 "cond.tab.c" /* yacc.c:1646 */ break; case 21: -#line 237 "cond.y" /* yacc.c:1646 */ +#line 257 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_SS; } -#line 1555 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1575 "cond.tab.c" /* yacc.c:1646 */ break; case 22: -#line 238 "cond.y" /* yacc.c:1646 */ +#line 258 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_IEQ; } -#line 1561 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1581 "cond.tab.c" /* yacc.c:1646 */ break; case 23: -#line 239 "cond.y" /* yacc.c:1646 */ +#line 259 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_INE; } -#line 1567 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1587 "cond.tab.c" /* yacc.c:1646 */ break; case 24: -#line 240 "cond.y" /* yacc.c:1646 */ +#line 260 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_ILT; } -#line 1573 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1593 "cond.tab.c" /* yacc.c:1646 */ break; case 25: -#line 241 "cond.y" /* yacc.c:1646 */ +#line 261 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_IGT; } -#line 1579 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1599 "cond.tab.c" /* yacc.c:1646 */ break; case 26: -#line 242 "cond.y" /* yacc.c:1646 */ +#line 262 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_ILE; } -#line 1585 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1605 "cond.tab.c" /* yacc.c:1646 */ break; case 27: -#line 243 "cond.y" /* yacc.c:1646 */ +#line 263 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_IGE; } -#line 1591 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1611 "cond.tab.c" /* yacc.c:1646 */ break; case 28: -#line 244 "cond.y" /* yacc.c:1646 */ +#line 264 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_ISS; } -#line 1597 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1617 "cond.tab.c" /* yacc.c:1646 */ break; case 29: -#line 245 "cond.y" /* yacc.c:1646 */ +#line 265 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_LHS; } -#line 1603 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1623 "cond.tab.c" /* yacc.c:1646 */ break; case 30: -#line 246 "cond.y" /* yacc.c:1646 */ +#line 266 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_RHS; } -#line 1609 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1629 "cond.tab.c" /* yacc.c:1646 */ break; case 31: -#line 247 "cond.y" /* yacc.c:1646 */ +#line 267 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_ILHS; } -#line 1615 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1635 "cond.tab.c" /* yacc.c:1646 */ break; case 32: -#line 248 "cond.y" /* yacc.c:1646 */ +#line 268 "cond.y" /* yacc.c:1646 */ { (yyval.operator) = COND_IRHS; } -#line 1621 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1641 "cond.tab.c" /* yacc.c:1646 */ break; case 33: -#line 253 "cond.y" /* yacc.c:1646 */ +#line 273 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; UINT len; @@ -1635,11 +1655,11 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1639 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1659 "cond.tab.c" /* yacc.c:1646 */ break; case 34: -#line 267 "cond.y" /* yacc.c:1646 */ +#line 287 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; UINT len = GetEnvironmentVariableW( (yyvsp[0].identifier), NULL, 0 ); @@ -1654,11 +1674,11 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1658 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1678 "cond.tab.c" /* yacc.c:1646 */ break; case 35: -#line 282 "cond.y" /* yacc.c:1646 */ +#line 302 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; (yyval.value).type = VALUE_LITERAL; @@ -1666,11 +1686,11 @@ yyreduce: if( !(yyval.value).u.string ) YYABORT; } -#line 1670 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1690 "cond.tab.c" /* yacc.c:1646 */ break; case 36: -#line 290 "cond.y" /* yacc.c:1646 */ +#line 310 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; LPWSTR szNum = COND_GetString( cond, &(yyvsp[0].str) ); @@ -1680,11 +1700,11 @@ yyreduce: (yyval.value).u.integer = atoiW( szNum ); cond_free( szNum ); } -#line 1684 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1704 "cond.tab.c" /* yacc.c:1646 */ break; case 37: -#line 300 "cond.y" /* yacc.c:1646 */ +#line 320 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; @@ -1701,11 +1721,11 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1705 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1725 "cond.tab.c" /* yacc.c:1646 */ break; case 38: -#line 317 "cond.y" /* yacc.c:1646 */ +#line 337 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; @@ -1722,11 +1742,11 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1726 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1746 "cond.tab.c" /* yacc.c:1646 */ break; case 39: -#line 334 "cond.y" /* yacc.c:1646 */ +#line 354 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; INSTALLSTATE install, action; @@ -1743,11 +1763,11 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1747 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1767 "cond.tab.c" /* yacc.c:1646 */ break; case 40: -#line 351 "cond.y" /* yacc.c:1646 */ +#line 371 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; @@ -1764,22 +1784,22 @@ yyreduce: } cond_free( (yyvsp[0].identifier) ); } -#line 1768 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1788 "cond.tab.c" /* yacc.c:1646 */ break; case 41: -#line 371 "cond.y" /* yacc.c:1646 */ +#line 391 "cond.y" /* yacc.c:1646 */ { COND_input* cond = (COND_input*) info; (yyval.identifier) = COND_GetString( cond, &(yyvsp[0].str) ); if( !(yyval.identifier) ) YYABORT; } -#line 1779 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1799 "cond.tab.c" /* yacc.c:1646 */ break; -#line 1783 "E:/reactosSync3.0_gcc/dll/win32/msi/cond.tab.c" /* yacc.c:1646 */ +#line 1803 "cond.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2007,7 +2027,7 @@ yyreturn: #endif return yyresult; } -#line 379 "cond.y" /* yacc.c:1906 */ +#line 399 "cond.y" /* yacc.c:1906 */ diff --git a/dll/win32/msi/cond.y b/dll/win32/msi/cond.y index 61ace8c57e..6ee6ab979c 100644 --- a/dll/win32/msi/cond.y +++ b/dll/win32/msi/cond.y @@ -20,7 +20,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "oleauto.h" + #include "msipriv.h" +#include "msiserver.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/create.c b/dll/win32/msi/create.c index 3c10bedeb4..c679d6b131 100644 --- a/dll/win32/msi/create.c +++ b/dll/win32/msi/create.c @@ -18,10 +18,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); + /* below is the query interface to a table */ typedef struct tagMSICREATEVIEW diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index c3fb8d3cd7..310a144173 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -18,9 +18,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" +#include "config.h" +#include "wine/port.h" + +#define COBJMACROS -#include <wine/exception.h> +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "msidefs.h" +#include "winuser.h" +#include "objbase.h" +#include "oleauto.h" + +#include "msipriv.h" +#include "msiserver.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/exception.h" #ifdef _MSC_VER #include "msvchelper.h" diff --git a/dll/win32/msi/database.c b/dll/win32/msi/database.c index 80d366b479..fc62340ace 100644 --- a/dll/win32/msi/database.c +++ b/dll/win32/msi/database.c @@ -18,9 +18,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#include <stdio.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" #include "msipriv.h" +#include "objidl.h" +#include "objbase.h" +#include "msiserver.h" +#include "query.h" -#include <stdio.h> +#include "initguid.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -36,6 +53,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); #define IS_INTMSIDBOPEN(x) (((ULONG_PTR)(x) >> 16) == 0) +struct row_export_info +{ + HANDLE handle; + LPCWSTR folder; + LPCWSTR table; +}; + static void free_transforms( MSIDATABASE *db ) { while( !list_empty( &db->transforms ) ) @@ -904,50 +928,131 @@ end: return r; } -static UINT msi_export_record( HANDLE handle, MSIRECORD *row, UINT start ) +static UINT msi_export_field( HANDLE handle, MSIRECORD *row, UINT field ) { - UINT i, count, len, r = ERROR_SUCCESS; - const char *sep; char *buffer; + BOOL bret; DWORD sz; + UINT r; - len = 0x100; - buffer = msi_alloc( len ); - if ( !buffer ) + sz = 0x100; + buffer = msi_alloc( sz ); + if (!buffer) return ERROR_OUTOFMEMORY; - count = MSI_RecordGetFieldCount( row ); - for ( i=start; i<=count; i++ ) + r = MSI_RecordGetStringA( row, field, buffer, &sz ); + if (r == ERROR_MORE_DATA) { - sz = len; - r = MSI_RecordGetStringA( row, i, buffer, &sz ); - if (r == ERROR_MORE_DATA) + char *p; + + sz++; /* leave room for NULL terminator */ + p = msi_realloc( buffer, sz ); + if (!p) { - char *p = msi_realloc( buffer, sz + 1 ); - if (!p) - break; - len = sz + 1; - buffer = p; + msi_free( buffer ); + return ERROR_OUTOFMEMORY; } - sz = len; - r = MSI_RecordGetStringA( row, i, buffer, &sz ); + buffer = p; + + r = MSI_RecordGetStringA( row, field, buffer, &sz ); if (r != ERROR_SUCCESS) - break; + { + msi_free( buffer ); + return r; + } + } + else if (r != ERROR_SUCCESS) + return r; - if (!WriteFile( handle, buffer, sz, &sz, NULL )) + bret = WriteFile( handle, buffer, sz, &sz, NULL ); + msi_free( buffer ); + if (!bret) + return ERROR_FUNCTION_FAILED; + + return r; +} + +static UINT msi_export_stream( LPCWSTR folder, LPCWSTR table, MSIRECORD *row, UINT field, + UINT start ) +{ + static const WCHAR fmt_file[] = { '%','s','/','%','s','/','%','s',0 }; + static const WCHAR fmt_folder[] = { '%','s','/','%','s',0 }; + WCHAR stream_name[256], stream_filename[MAX_PATH]; + DWORD sz, read_size, write_size; + char buffer[1024]; + HANDLE file; + UINT r; + + /* get the name of the file */ + sz = sizeof(stream_name)/sizeof(WCHAR); + r = MSI_RecordGetStringW( row, start, stream_name, &sz ); + if (r != ERROR_SUCCESS) + return r; + + /* if the destination folder does not exist then create it (folder name = table name) */ + snprintfW( stream_filename, sizeof(stream_filename)/sizeof(WCHAR), fmt_folder, folder, table ); + if (GetFileAttributesW( stream_filename ) == INVALID_FILE_ATTRIBUTES) + { + if (!CreateDirectoryW( stream_filename, NULL )) + return ERROR_PATH_NOT_FOUND; + } + + /* actually create the file */ + snprintfW( stream_filename, sizeof(stream_filename)/sizeof(WCHAR), fmt_file, folder, table, stream_name ); + file = CreateFileW( stream_filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + if (file == INVALID_HANDLE_VALUE) + return ERROR_FILE_NOT_FOUND; + + /* copy the stream to the file */ + read_size = sizeof(buffer); + while (read_size == sizeof(buffer)) + { + r = MSI_RecordReadStream( row, field, buffer, &read_size ); + if (r != ERROR_SUCCESS) { - r = ERROR_FUNCTION_FAILED; - break; + CloseHandle( file ); + return r; + } + if (!WriteFile( file, buffer, read_size, &write_size, NULL ) || read_size != write_size) + { + CloseHandle( file ); + return ERROR_WRITE_FAULT; } + } + CloseHandle( file ); + return r; +} - sep = (i < count) ? "\t" : "\r\n"; - if (!WriteFile( handle, sep, strlen(sep), &sz, NULL )) +static UINT msi_export_record( struct row_export_info *row_export_info, MSIRECORD *row, UINT start ) +{ + HANDLE handle = row_export_info->handle; + UINT i, count, r = ERROR_SUCCESS; + const char *sep; + DWORD sz; + + count = MSI_RecordGetFieldCount( row ); + for (i = start; i <= count; i++) + { + r = msi_export_field( handle, row, i ); + if (r == ERROR_INVALID_PARAMETER) { - r = ERROR_FUNCTION_FAILED; - break; + r = msi_export_stream( row_export_info->folder, row_export_info->table, row, i, start ); + if (r != ERROR_SUCCESS) + return r; + + /* exporting a binary stream, repeat the "Name" field */ + r = msi_export_field( handle, row, start ); + if (r != ERROR_SUCCESS) + return r; } + else if (r != ERROR_SUCCESS) + return r; + + sep = (i < count) ? "\t" : "\r\n"; + if (!WriteFile( handle, sep, strlen(sep), &sz, NULL )) + return ERROR_FUNCTION_FAILED; } - msi_free( buffer ); return r; } @@ -971,9 +1076,25 @@ static UINT msi_export_forcecodepage( HANDLE handle, UINT codepage ) return ERROR_SUCCESS; } +static UINT msi_export_summaryinformation( MSIDATABASE *db, HANDLE handle ) +{ + static const char header[] = "PropertyId\tValue\r\n" + "i2\tl255\r\n" + "_SummaryInformation\tPropertyId\r\n"; + DWORD sz; + + sz = lstrlenA(header); + if (!WriteFile(handle, header, sz, &sz, NULL)) + return ERROR_WRITE_FAULT; + + return msi_export_suminfo( db, handle ); +} + static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file ) { + static const WCHAR summaryinformation[] = { + '_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0 }; static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 }; static const WCHAR forcecodepage[] = { @@ -1012,14 +1133,22 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, goto done; } + if (!strcmpW( table, summaryinformation )) + { + r = msi_export_summaryinformation( db, handle ); + goto done; + } + r = MSI_OpenQuery( db, &view, query, table ); if (r == ERROR_SUCCESS) { + struct row_export_info row_export_info = { handle, folder, table }; + /* write out row 1, the column names */ r = MSI_ViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec); if (r == ERROR_SUCCESS) { - msi_export_record( handle, rec, 1 ); + msi_export_record( &row_export_info, rec, 1 ); msiobj_release( &rec->hdr ); } @@ -1027,7 +1156,7 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, r = MSI_ViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec); if (r == ERROR_SUCCESS) { - msi_export_record( handle, rec, 1 ); + msi_export_record( &row_export_info, rec, 1 ); msiobj_release( &rec->hdr ); } @@ -1036,12 +1165,12 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, if (r == ERROR_SUCCESS) { MSI_RecordSetStringW( rec, 0, table ); - msi_export_record( handle, rec, 0 ); + msi_export_record( &row_export_info, rec, 0 ); msiobj_release( &rec->hdr ); } /* write out row 4 onwards, the data */ - r = MSI_IterateRecords( view, 0, msi_export_row, handle ); + r = MSI_IterateRecords( view, 0, msi_export_row, &row_export_info ); msiobj_release( &view->hdr ); } @@ -1879,16 +2008,8 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle ) db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ); if( !db ) { - IWineMsiRemoteDatabase *remote_database; - - remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle ); - if ( !remote_database ) - return MSIDBSTATE_ERROR; - - IWineMsiRemoteDatabase_Release( remote_database ); WARN("MsiGetDatabaseState not allowed during a custom action!\n"); - - return MSIDBSTATE_READ; + return MSIDBSTATE_ERROR; } if (db->mode != MSIDBOPEN_READONLY ) diff --git a/dll/win32/msi/delete.c b/dll/win32/msi/delete.c index d3c16bf40c..4472409a0a 100644 --- a/dll/win32/msi/delete.c +++ b/dll/win32/msi/delete.c @@ -18,10 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); + /* * Code to delete rows from a table. * diff --git a/dll/win32/msi/dialog.c b/dll/win32/msi/dialog.c index af986a1da6..97fc89cbce 100644 --- a/dll/win32/msi/dialog.c +++ b/dll/win32/msi/dialog.c @@ -19,11 +19,32 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" +#define COBJMACROS +#define NONAMELESSUNION + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" +#include "msi.h" +#include "msidefs.h" +#include "ocidl.h" +#include "olectl.h" +#include "richedit.h" +#include "commctrl.h" +#include "winreg.h" +#include "shlwapi.h" +#include "shellapi.h" + +#include "wine/debug.h" +#include "wine/unicode.h" -#include <olectl.h> -#include <richedit.h> -#include <shellapi.h> +#include "msipriv.h" +#include "msiserver.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -3179,13 +3200,13 @@ static LONGLONG msi_vcl_get_cost( msi_dialog *dialog ) MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &each_cost))) { /* each_cost is in 512-byte units */ - total_cost += each_cost * 512; + total_cost += ((LONGLONG)each_cost) * 512; } if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature, MSICOSTTREE_SELFONLY, INSTALLSTATE_ABSENT, &each_cost))) { /* each_cost is in 512-byte units */ - total_cost -= each_cost * 512; + total_cost -= ((LONGLONG)each_cost) * 512; } } return total_cost; diff --git a/dll/win32/msi/distinct.c b/dll/win32/msi/distinct.c index 7834931d8a..04f09fa491 100644 --- a/dll/win32/msi/distinct.c +++ b/dll/win32/msi/distinct.c @@ -18,7 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/dll/win32/msi/drop.c b/dll/win32/msi/drop.c index dd0af104f8..f0b58039fd 100644 --- a/dll/win32/msi/drop.c +++ b/dll/win32/msi/drop.c @@ -18,8 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "query.h" + WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct tagMSIDROPVIEW diff --git a/dll/win32/msi/files.c b/dll/win32/msi/files.c index 635bff6198..adffcafb58 100644 --- a/dll/win32/msi/files.c +++ b/dll/win32/msi/files.c @@ -30,9 +30,23 @@ * RemoveFiles */ -#include "msipriv.h" +#include <stdarg.h> + +#define COBJMACROS -#include <patchapi.h> +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "fdi.h" +#include "msi.h" +#include "msidefs.h" +#include "msipriv.h" +#include "winuser.h" +#include "winreg.h" +#include "shlwapi.h" +#include "patchapi.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -186,8 +200,6 @@ static UINT copy_file(MSIFILE *file, LPWSTR source) return GetLastError(); SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL); - - file->state = msifs_installed; return ERROR_SUCCESS; } @@ -235,7 +247,6 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && MoveFileExW(tmpfileW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT)) { - file->state = msifs_installed; package->need_reboot_at_end = 1; gle = ERROR_SUCCESS; } @@ -351,6 +362,8 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { + BOOL is_global_assembly = msi_is_global_assembly( file->Component ); + msi_file_update_ui( package, file, szInstallFiles ); rc = msi_load_media_info( package, file->Sequence, mi ); @@ -398,7 +411,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) TRACE("copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath)); - if (!msi_is_global_assembly( file->Component )) + if (!is_global_assembly) { msi_create_directory(package, file->Component->Directory); } @@ -410,10 +423,11 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) msi_free(source); goto done; } + if (!is_global_assembly) file->state = msifs_installed; msi_free(source); } - else if (!msi_is_global_assembly( file->Component ) && - file->state != msifs_installed && !(file->Attributes & msidbFileAttributesPatchAdded)) + else if (!is_global_assembly && file->state != msifs_installed && + !(file->Attributes & msidbFileAttributesPatchAdded)) { ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->File)); rc = ERROR_INSTALL_FAILURE; diff --git a/dll/win32/msi/font.c b/dll/win32/msi/font.c index 8a91ecab94..5c1e59d95e 100644 --- a/dll/win32/msi/font.c +++ b/dll/win32/msi/font.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/debug.h" #include "msipriv.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/format.c b/dll/win32/msi/format.c index 3b8a472d15..3bcd0b84ee 100644 --- a/dll/win32/msi/format.c +++ b/dll/win32/msi/format.c @@ -19,7 +19,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#include <stdio.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "winnls.h" +#include "objbase.h" +#include "oleauto.h" + #include "msipriv.h" +#include "msiserver.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/handle.c b/dll/win32/msi/handle.c index 1b3a7e1bea..80c6873981 100644 --- a/dll/win32/msi/handle.c +++ b/dll/win32/msi/handle.c @@ -18,6 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" #include "msipriv.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/insert.c b/dll/win32/msi/insert.c index d9a4ad82db..c404929f28 100644 --- a/dll/win32/msi/insert.c +++ b/dll/win32/msi/insert.c @@ -18,10 +18,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); + /* below is the query interface to a table */ typedef struct tagMSIINSERTVIEW diff --git a/dll/win32/msi/install.c b/dll/win32/msi/install.c index 8882ea1fa6..261a259f3f 100644 --- a/dll/win32/msi/install.c +++ b/dll/win32/msi/install.c @@ -20,7 +20,22 @@ /* Msi top level apis directly related to installs */ +#define COBJMACROS + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msidefs.h" +#include "objbase.h" +#include "oleauto.h" + #include "msipriv.h" +#include "msiserver.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/media.c b/dll/win32/msi/media.c index 627ced1a0a..0bb883b34a 100644 --- a/dll/win32/msi/media.c +++ b/dll/win32/msi/media.c @@ -18,9 +18,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" +#include <stdarg.h> + +#define COBJMACROS -#include <fdi.h> +#include "windef.h" +#include "winerror.h" +#include "wine/debug.h" +#include "fdi.h" +#include "msipriv.h" +#include "winuser.h" +#include "winreg.h" +#include "shlwapi.h" +#include "objidl.h" +#include "wine/unicode.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c index ce1bd4f6de..7e5e23fc51 100644 --- a/dll/win32/msi/msi.c +++ b/dll/win32/msi/msi.c @@ -18,11 +18,35 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "shlwapi.h" +#include "msi.h" +#include "msidefs.h" +#include "msiquery.h" #include "msipriv.h" - -#include <softpub.h> -#include <initguid.h> -#include <msxml2.h> +#include "msiserver.h" +#include "wincrypt.h" +#include "winver.h" +#include "winuser.h" +#include "shlobj.h" +#include "shobjidl.h" +#include "objidl.h" +#include "wintrust.h" +#include "softpub.h" + +#include "initguid.h" +#include "msxml2.h" + +#include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/msi.rc b/dll/win32/msi/msi.rc index 97a76d1504..947fded1fb 100644 --- a/dll/win32/msi/msi.rc +++ b/dll/win32/msi/msi.rc @@ -18,8 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <windef.h> - +#include "windef.h" #include "resource.h" LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL @@ -50,6 +49,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define WINE_PRODUCTVERSION 4,5,6001,22308 #define WINE_PRODUCTVERSION_STR "4.5.6001.22308" -#include <wine/wine_common_ver.rc> +#include "wine/wine_common_ver.rc" #include "rsrc.rc" diff --git a/dll/win32/msi/msi_main.c b/dll/win32/msi/msi_main.c index eaab63d1ea..31431180ea 100644 --- a/dll/win32/msi/msi_main.c +++ b/dll/win32/msi/msi_main.c @@ -18,9 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "shlwapi.h" +#include "oleauto.h" +#include "rpcproxy.h" #include "msipriv.h" +#include "msiserver.h" -#include <rpcproxy.h> +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h index 971750d452..c0a02780b8 100644 --- a/dll/win32/msi/msipriv.h +++ b/dll/win32/msi/msipriv.h @@ -22,37 +22,21 @@ #ifndef __WINE_MSI_PRIVATE__ #define __WINE_MSI_PRIVATE__ -#include <wine/config.h> - -#include <assert.h> #include <stdarg.h> -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - -#define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include <windef.h> -#include <winbase.h> -#include <winreg.h> -#include <wincon.h> -#include <winver.h> -#include <msiquery.h> -#include <objbase.h> -#include <msiserver.h> -#include <shlobj.h> -#include <shlwapi.h> -#include <fusion.h> -#include <sddl.h> -#include <msidefs.h> - -#include <wine/debug.h> -#include <wine/list.h> -#include <wine/unicode.h> - -#include "resource.h" +#include "windef.h" +#include "winbase.h" +#include "fdi.h" +#include "msi.h" +#include "msiquery.h" +#include "msidefs.h" +#include "objbase.h" +#include "objidl.h" +#include "fusion.h" +#include "winnls.h" +#include "winver.h" +#include "wine/list.h" +#include "wine/debug.h" static const BOOL is_64bit = sizeof(void *) > sizeof(int); BOOL is_wow64 DECLSPEC_HIDDEN; @@ -968,6 +952,7 @@ extern LPWSTR msi_suminfo_dup_string( MSISUMMARYINFO *si, UINT uiProperty ) DECL extern INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty ) DECLSPEC_HIDDEN; extern LPWSTR msi_get_suminfo_product( IStorage *stg ) DECLSPEC_HIDDEN; extern UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns ) DECLSPEC_HIDDEN; +extern UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle ) DECLSPEC_HIDDEN; extern UINT msi_load_suminfo_properties( MSIPACKAGE *package ) DECLSPEC_HIDDEN; /* undocumented functions */ @@ -1280,6 +1265,4 @@ static inline LPWSTR strdupW( LPCWSTR src ) return dest; } -#include "query.h" - #endif /* __WINE_MSI_PRIVATE__ */ diff --git a/dll/win32/msi/msiquery.c b/dll/win32/msi/msiquery.c index 4dcc971437..d73e5febdc 100644 --- a/dll/win32/msi/msiquery.c +++ b/dll/win32/msi/msiquery.c @@ -18,7 +18,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" +#include "msiserver.h" + +#include "initguid.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c index 5ddc5c8483..5aa3dd0e12 100644 --- a/dll/win32/msi/package.c +++ b/dll/win32/msi/package.c @@ -18,9 +18,35 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#define COBJMACROS + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "shlwapi.h" +#include "wingdi.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objidl.h" +#include "wincrypt.h" +#include "winuser.h" +#include "wininet.h" +#include "winver.h" +#include "urlmon.h" +#include "shlobj.h" +#include "wine/unicode.h" +#include "objbase.h" +#include "msidefs.h" +#include "sddl.h" -#include <wininet.h> +#include "msipriv.h" +#include "msiserver.h" +#include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -502,71 +528,73 @@ done: static LPWSTR get_fusion_filename(MSIPACKAGE *package) { - HKEY netsetup; + static const WCHAR fusion[] = + {'f','u','s','i','o','n','.','d','l','l',0}; + static const WCHAR subkey[] = + {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', + 'N','E','T',' ','F','r','a','m','e','w','o','r','k',' ','S','e','t','u','p','\\','N','D','P',0}; + static const WCHAR subdir[] = + {'M','i','c','r','o','s','o','f','t','.','N','E','T','\\','F','r','a','m','e','w','o','r','k','\\',0}; + static const WCHAR v2050727[] = + {'v','2','.','0','.','5','0','7','2','7',0}; + static const WCHAR v4client[] = + {'v','4','\\','C','l','i','e','n','t',0}; + static const WCHAR installpath[] = + {'I','n','s','t','a','l','l','P','a','t','h',0}; + HKEY netsetup, hkey; LONG res; - LPWSTR file = NULL; - DWORD index = 0, size; - WCHAR ver[MAX_PATH]; - WCHAR name[MAX_PATH]; - WCHAR windir[MAX_PATH]; - - static const WCHAR fusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; - static const WCHAR sub[] = { - 'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\', - 'N','E','T',' ','F','r','a','m','e','w','o','r','k',' ','S','e','t','u','p','\\', - 'N','D','P',0 - }; - static const WCHAR subdir[] = { - 'M','i','c','r','o','s','o','f','t','.','N','E','T','\\', - 'F','r','a','m','e','w','o','r','k','\\',0 - }; + DWORD size, len, type; + WCHAR windir[MAX_PATH], path[MAX_PATH], *filename = NULL; - res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub, 0, KEY_ENUMERATE_SUB_KEYS, &netsetup); + res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, subkey, 0, KEY_CREATE_SUB_KEY, &netsetup); if (res != ERROR_SUCCESS) return NULL; - GetWindowsDirectoryW(windir, MAX_PATH); - - ver[0] = '\0'; - size = MAX_PATH; - while (RegEnumKeyExW(netsetup, index, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + if (!RegCreateKeyExW(netsetup, v4client, 0, NULL, 0, KEY_QUERY_VALUE, NULL, &hkey, NULL)) { - index++; - - /* verify existence of fusion.dll .Net 3.0 does not install a new one */ - if (strcmpW( ver, name ) < 0) + size = sizeof(path)/sizeof(path[0]); + if (!RegQueryValueExW(hkey, installpath, NULL, &type, (BYTE *)path, &size)) { - LPWSTR check; - size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3; - check = msi_alloc(size * sizeof(WCHAR)); + len = strlenW(path) + strlenW(fusion) + 2; + if (!(filename = msi_alloc(len * sizeof(WCHAR)))) return NULL; - if (!check) + strcpyW(filename, path); + strcatW(filename, szBackSlash); + strcatW(filename, fusion); + if (GetFileAttributesW(filename) != INVALID_FILE_ATTRIBUTES) { - msi_free(file); - return NULL; + TRACE( "found %s\n", debugstr_w(filename) ); + RegCloseKey(hkey); + RegCloseKey(netsetup); + return filename; } + } + RegCloseKey(hkey); + } - lstrcpyW(check, windir); - lstrcatW(check, szBackSlash); - lstrcatW(check, subdir); - lstrcatW(check, name); - lstrcatW(check, szBackSlash); - lstrcatW(check, fusion); + if (!RegCreateKeyExW(netsetup, v2050727, 0, NULL, 0, KEY_QUERY_VALUE, NULL, &hkey, NULL)) + { + RegCloseKey(hkey); + GetWindowsDirectoryW(windir, MAX_PATH); + len = strlenW(windir) + strlenW(subdir) + strlenW(v2050727) + strlenW(fusion) + 3; + if (!(filename = msi_alloc(len * sizeof(WCHAR)))) return NULL; - if(GetFileAttributesW(check) != INVALID_FILE_ATTRIBUTES) - { - msi_free(file); - file = check; - lstrcpyW(ver, name); - } - else - msi_free(check); + strcpyW(filename, windir); + strcatW(filename, szBackSlash); + strcatW(filename, subdir); + strcatW(filename, v2050727); + strcatW(filename, szBackSlash); + strcatW(filename, fusion); + if (GetFileAttributesW(filename) != INVALID_FILE_ATTRIBUTES) + { + TRACE( "found %s\n", debugstr_w(filename) ); + RegCloseKey(netsetup); + return filename; } } RegCloseKey(netsetup); - return file; + return filename; } typedef struct tagLANGANDCODEPAGE diff --git a/dll/win32/msi/patch.c b/dll/win32/msi/patch.c index c3d2299fd6..f6ed3c1f1a 100644 --- a/dll/win32/msi/patch.c +++ b/dll/win32/msi/patch.c @@ -19,6 +19,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "wine/unicode.h" #include "msipriv.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/precomp.h b/dll/win32/msi/precomp.h new file mode 100644 index 0000000000..f4951c71ee --- /dev/null +++ b/dll/win32/msi/precomp.h @@ -0,0 +1,30 @@ + +#ifndef __WINE_MSI_PRECOMP__ +#define __WINE_MSI_PRECOMP__ + +#include <wine/config.h> + +#include <assert.h> + +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "msipriv.h" +#include "query.h" + +#include <winreg.h> +#include <wincon.h> +#include <msiserver.h> +#include <shlobj.h> +#include <shlwapi.h> +#include <sddl.h> + +#include <wine/unicode.h> + +#include "resource.h" + +#endif /* !__WINE_MSI_PRECOMP__ */ diff --git a/dll/win32/msi/query.h b/dll/win32/msi/query.h index 73feac5122..063fbb9749 100644 --- a/dll/win32/msi/query.h +++ b/dll/win32/msi/query.h @@ -21,6 +21,18 @@ #ifndef __WINE_MSI_QUERY_H #define __WINE_MSI_QUERY_H +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "objidl.h" +#include "msi.h" +#include "msiquery.h" +#include "msipriv.h" +#include "wine/list.h" + + #define OP_EQ 1 #define OP_AND 2 #define OP_OR 3 diff --git a/dll/win32/msi/record.c b/dll/win32/msi/record.c index 72d2959763..de45191786 100644 --- a/dll/win32/msi/record.c +++ b/dll/win32/msi/record.c @@ -18,7 +18,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" #include "msipriv.h" +#include "objidl.h" +#include "winnls.h" +#include "ole2.h" + +#include "winreg.h" +#include "shlwapi.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/dll/win32/msi/registry.c b/dll/win32/msi/registry.c index dace181134..cbc8d8d6f0 100644 --- a/dll/win32/msi/registry.c +++ b/dll/win32/msi/registry.c @@ -19,7 +19,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "msi.h" #include "msipriv.h" +#include "wincrypt.h" +#include "wine/unicode.h" +#include "winver.h" +#include "winuser.h" +#include "sddl.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/resource.h b/dll/win32/msi/resource.h index 045aa209c9..7977747f61 100644 --- a/dll/win32/msi/resource.h +++ b/dll/win32/msi/resource.h @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma once + #define MSIERR_INSTALLERROR 5 #define MSIERR_ACTIONSTART 8 #define MSIERR_COMMONDATA 11 diff --git a/dll/win32/msi/script.c b/dll/win32/msi/script.c index 1165ec41ff..c70790f538 100644 --- a/dll/win32/msi/script.c +++ b/dll/win32/msi/script.c @@ -18,9 +18,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winuser.h" +#include "msidefs.h" #include "msipriv.h" +#include "activscp.h" +#include "oleauto.h" +#include "wine/debug.h" +#include "wine/unicode.h" -#include <activscp.h> +#include "msiserver.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/select.c b/dll/win32/msi/select.c index a285917b49..e8f38855a8 100644 --- a/dll/win32/msi/select.c +++ b/dll/win32/msi/select.c @@ -18,10 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); + /* below is the query interface to a table */ typedef struct tagMSISELECTVIEW diff --git a/dll/win32/msi/source.c b/dll/win32/msi/source.c index 2d536494e8..68bf9d0a22 100644 --- a/dll/win32/msi/source.c +++ b/dll/win32/msi/source.c @@ -18,7 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" #include "msipriv.h" +#include "wincrypt.h" +#include "winver.h" +#include "winuser.h" +#include "wine/unicode.h" +#include "sddl.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/sql.tab.c b/dll/win32/msi/sql.tab.c index f4cfd6bbef..61263a58ef 100644 --- a/dll/win32/msi/sql.tab.c +++ b/dll/win32/msi/sql.tab.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 3.0. */ /* Bison implementation for Yacc-like parsers in C @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.2" +#define YYBISON_VERSION "3.0" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -91,7 +91,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "msipriv.h" + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "query.h" +#include "wine/list.h" +#include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -120,11 +132,11 @@ static struct expr * EXPR_wildcard( void *info ); #line 134 "sql.tab.c" /* yacc.c:339 */ -# ifndef YY_NULLPTR +# ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# define YY_NULL nullptr # else -# define YY_NULLPTR 0 +# define YY_NULL 0 # endif # endif @@ -138,8 +150,8 @@ static struct expr * EXPR_wildcard( void *info ); /* In a future release of Bison, this section will be replaced by #include "sql.tab.h". */ -#ifndef YY_SQL_SQL_TAB_H_INCLUDED -# define YY_SQL_SQL_TAB_H_INCLUDED +#ifndef YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED +# define YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -242,7 +254,7 @@ union YYSTYPE int sql_parse (SQL_input *info); -#endif /* !YY_SQL_SQL_TAB_H_INCLUDED */ +#endif /* !YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ @@ -303,30 +315,11 @@ typedef short int yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ # endif #endif @@ -583,7 +576,7 @@ static const char *const yytname[] = "data_count", "oneselect", "selectfrom", "selcollist", "collist", "from", "unorderdfrom", "tablelist", "expr", "val", "constlist", "update_assign_list", "column_assignment", "const_val", "column_val", - "column", "selcolumn", "table", "id", "string", "number", YY_NULLPTR + "column", "selcolumn", "table", "id", "string", "number", YY_NULL }; #endif @@ -1050,11 +1043,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; + const char *yyformat = YY_NULL; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1111,7 +1104,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; @@ -1453,7 +1446,7 @@ yyreduce: SQL_input* sql = (SQL_input*) info; *sql->view = (yyvsp[0].query); } -#line 1469 "sql.tab.c" /* yacc.c:1646 */ +#line 1450 "sql.tab.c" /* yacc.c:1646 */ break; case 10: @@ -1468,7 +1461,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert ); } -#line 1484 "sql.tab.c" /* yacc.c:1646 */ +#line 1465 "sql.tab.c" /* yacc.c:1646 */ break; case 11: @@ -1483,7 +1476,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert ); } -#line 1499 "sql.tab.c" /* yacc.c:1646 */ +#line 1480 "sql.tab.c" /* yacc.c:1646 */ break; case 12: @@ -1504,7 +1497,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create ); } -#line 1520 "sql.tab.c" /* yacc.c:1646 */ +#line 1501 "sql.tab.c" /* yacc.c:1646 */ break; case 13: @@ -1521,7 +1514,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create ); } -#line 1537 "sql.tab.c" /* yacc.c:1646 */ +#line 1518 "sql.tab.c" /* yacc.c:1646 */ break; case 14: @@ -1536,7 +1529,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update ); } -#line 1552 "sql.tab.c" /* yacc.c:1646 */ +#line 1533 "sql.tab.c" /* yacc.c:1646 */ break; case 15: @@ -1551,7 +1544,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update ); } -#line 1567 "sql.tab.c" /* yacc.c:1646 */ +#line 1548 "sql.tab.c" /* yacc.c:1646 */ break; case 16: @@ -1566,7 +1559,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), delete ); } -#line 1582 "sql.tab.c" /* yacc.c:1646 */ +#line 1563 "sql.tab.c" /* yacc.c:1646 */ break; case 17: @@ -1581,7 +1574,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter ); } -#line 1597 "sql.tab.c" /* yacc.c:1646 */ +#line 1578 "sql.tab.c" /* yacc.c:1646 */ break; case 18: @@ -1596,7 +1589,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter ); } -#line 1612 "sql.tab.c" /* yacc.c:1646 */ +#line 1593 "sql.tab.c" /* yacc.c:1646 */ break; case 19: @@ -1611,7 +1604,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter ); } -#line 1627 "sql.tab.c" /* yacc.c:1646 */ +#line 1608 "sql.tab.c" /* yacc.c:1646 */ break; case 20: @@ -1619,7 +1612,7 @@ yyreduce: { (yyval.integer) = 1; } -#line 1635 "sql.tab.c" /* yacc.c:1646 */ +#line 1616 "sql.tab.c" /* yacc.c:1646 */ break; case 21: @@ -1627,7 +1620,7 @@ yyreduce: { (yyval.integer) = -1; } -#line 1643 "sql.tab.c" /* yacc.c:1646 */ +#line 1624 "sql.tab.c" /* yacc.c:1646 */ break; case 22: @@ -1643,7 +1636,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), drop ); } -#line 1659 "sql.tab.c" /* yacc.c:1646 */ +#line 1640 "sql.tab.c" /* yacc.c:1646 */ break; case 23: @@ -1654,7 +1647,7 @@ yyreduce: else (yyval.column_list) = NULL; } -#line 1670 "sql.tab.c" /* yacc.c:1646 */ +#line 1651 "sql.tab.c" /* yacc.c:1646 */ break; case 24: @@ -1668,7 +1661,7 @@ yyreduce: ci->next = (yyvsp[0].column_list); (yyval.column_list) = (yyvsp[-2].column_list); } -#line 1684 "sql.tab.c" /* yacc.c:1646 */ +#line 1665 "sql.tab.c" /* yacc.c:1646 */ break; case 25: @@ -1676,7 +1669,7 @@ yyreduce: { (yyval.column_list) = (yyvsp[0].column_list); } -#line 1692 "sql.tab.c" /* yacc.c:1646 */ +#line 1673 "sql.tab.c" /* yacc.c:1646 */ break; case 26: @@ -1686,7 +1679,7 @@ yyreduce: (yyval.column_list)->type = ((yyvsp[0].column_type) | MSITYPE_VALID); (yyval.column_list)->temporary = (yyvsp[0].column_type) & MSITYPE_TEMPORARY ? TRUE : FALSE; } -#line 1702 "sql.tab.c" /* yacc.c:1646 */ +#line 1683 "sql.tab.c" /* yacc.c:1646 */ break; case 27: @@ -1694,7 +1687,7 @@ yyreduce: { (yyval.column_type) = (yyvsp[0].column_type); } -#line 1710 "sql.tab.c" /* yacc.c:1646 */ +#line 1691 "sql.tab.c" /* yacc.c:1646 */ break; case 28: @@ -1702,7 +1695,7 @@ yyreduce: { (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_LOCALIZABLE; } -#line 1718 "sql.tab.c" /* yacc.c:1646 */ +#line 1699 "sql.tab.c" /* yacc.c:1646 */ break; case 29: @@ -1710,7 +1703,7 @@ yyreduce: { (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_TEMPORARY; } -#line 1726 "sql.tab.c" /* yacc.c:1646 */ +#line 1707 "sql.tab.c" /* yacc.c:1646 */ break; case 30: @@ -1718,7 +1711,7 @@ yyreduce: { (yyval.column_type) |= MSITYPE_NULLABLE; } -#line 1734 "sql.tab.c" /* yacc.c:1646 */ +#line 1715 "sql.tab.c" /* yacc.c:1646 */ break; case 31: @@ -1726,15 +1719,15 @@ yyreduce: { (yyval.column_type) = (yyvsp[-2].column_type); } -#line 1742 "sql.tab.c" /* yacc.c:1646 */ +#line 1723 "sql.tab.c" /* yacc.c:1646 */ break; case 32: #line 357 "sql.y" /* yacc.c:1646 */ { - (yyval.column_type) = MSITYPE_STRING | 1; + (yyval.column_type) = MSITYPE_STRING | 0x400; } -#line 1750 "sql.tab.c" /* yacc.c:1646 */ +#line 1731 "sql.tab.c" /* yacc.c:1646 */ break; case 33: @@ -1742,7 +1735,7 @@ yyreduce: { (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[-1].column_type); } -#line 1758 "sql.tab.c" /* yacc.c:1646 */ +#line 1739 "sql.tab.c" /* yacc.c:1646 */ break; case 34: @@ -1750,7 +1743,7 @@ yyreduce: { (yyval.column_type) = MSITYPE_STRING | 0x400; } -#line 1766 "sql.tab.c" /* yacc.c:1646 */ +#line 1747 "sql.tab.c" /* yacc.c:1646 */ break; case 35: @@ -1758,7 +1751,7 @@ yyreduce: { (yyval.column_type) = 2 | 0x400; } -#line 1774 "sql.tab.c" /* yacc.c:1646 */ +#line 1755 "sql.tab.c" /* yacc.c:1646 */ break; case 36: @@ -1766,7 +1759,7 @@ yyreduce: { (yyval.column_type) = 2 | 0x400; } -#line 1782 "sql.tab.c" /* yacc.c:1646 */ +#line 1763 "sql.tab.c" /* yacc.c:1646 */ break; case 37: @@ -1774,7 +1767,7 @@ yyreduce: { (yyval.column_type) = 4; } -#line 1790 "sql.tab.c" /* yacc.c:1646 */ +#line 1771 "sql.tab.c" /* yacc.c:1646 */ break; case 38: @@ -1782,7 +1775,7 @@ yyreduce: { (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID; } -#line 1798 "sql.tab.c" /* yacc.c:1646 */ +#line 1779 "sql.tab.c" /* yacc.c:1646 */ break; case 39: @@ -1792,7 +1785,7 @@ yyreduce: YYABORT; (yyval.column_type) = (yyvsp[0].integer); } -#line 1808 "sql.tab.c" /* yacc.c:1646 */ +#line 1789 "sql.tab.c" /* yacc.c:1646 */ break; case 40: @@ -1800,7 +1793,7 @@ yyreduce: { (yyval.query) = (yyvsp[0].query); } -#line 1816 "sql.tab.c" /* yacc.c:1646 */ +#line 1797 "sql.tab.c" /* yacc.c:1646 */ break; case 41: @@ -1816,7 +1809,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), distinct ); } -#line 1832 "sql.tab.c" /* yacc.c:1646 */ +#line 1813 "sql.tab.c" /* yacc.c:1646 */ break; case 42: @@ -1837,7 +1830,7 @@ yyreduce: else (yyval.query) = (yyvsp[0].query); } -#line 1853 "sql.tab.c" /* yacc.c:1646 */ +#line 1834 "sql.tab.c" /* yacc.c:1646 */ break; case 44: @@ -1845,7 +1838,7 @@ yyreduce: { (yyvsp[-2].column_list)->next = (yyvsp[0].column_list); } -#line 1861 "sql.tab.c" /* yacc.c:1646 */ +#line 1842 "sql.tab.c" /* yacc.c:1646 */ break; case 45: @@ -1853,7 +1846,7 @@ yyreduce: { (yyval.column_list) = NULL; } -#line 1869 "sql.tab.c" /* yacc.c:1646 */ +#line 1850 "sql.tab.c" /* yacc.c:1646 */ break; case 47: @@ -1861,7 +1854,7 @@ yyreduce: { (yyvsp[-2].column_list)->next = (yyvsp[0].column_list); } -#line 1877 "sql.tab.c" /* yacc.c:1646 */ +#line 1858 "sql.tab.c" /* yacc.c:1646 */ break; case 48: @@ -1869,7 +1862,7 @@ yyreduce: { (yyval.column_list) = NULL; } -#line 1885 "sql.tab.c" /* yacc.c:1646 */ +#line 1866 "sql.tab.c" /* yacc.c:1646 */ break; case 49: @@ -1885,7 +1878,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), table ); } -#line 1901 "sql.tab.c" /* yacc.c:1646 */ +#line 1882 "sql.tab.c" /* yacc.c:1646 */ break; case 50: @@ -1902,7 +1895,7 @@ yyreduce: (yyval.query) = (yyvsp[-3].query); } -#line 1918 "sql.tab.c" /* yacc.c:1646 */ +#line 1899 "sql.tab.c" /* yacc.c:1646 */ break; case 52: @@ -1918,7 +1911,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), where ); } -#line 1934 "sql.tab.c" /* yacc.c:1646 */ +#line 1915 "sql.tab.c" /* yacc.c:1646 */ break; case 53: @@ -1934,7 +1927,7 @@ yyreduce: PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), where ); } -#line 1950 "sql.tab.c" /* yacc.c:1646 */ +#line 1931 "sql.tab.c" /* yacc.c:1646 */ break; case 54: @@ -1942,7 +1935,7 @@ yyreduce: { (yyval.string) = (yyvsp[0].string); } -#line 1958 "sql.tab.c" /* yacc.c:1646 */ +#line 1939 "sql.tab.c" /* yacc.c:1646 */ break; case 55: @@ -1952,7 +1945,7 @@ yyreduce: if (!(yyval.string)) YYABORT; } -#line 1968 "sql.tab.c" /* yacc.c:1646 */ +#line 1949 "sql.tab.c" /* yacc.c:1646 */ break; case 56: @@ -1962,7 +1955,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 1978 "sql.tab.c" /* yacc.c:1646 */ +#line 1959 "sql.tab.c" /* yacc.c:1646 */ break; case 57: @@ -1972,7 +1965,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 1988 "sql.tab.c" /* yacc.c:1646 */ +#line 1969 "sql.tab.c" /* yacc.c:1646 */ break; case 58: @@ -1982,7 +1975,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 1998 "sql.tab.c" /* yacc.c:1646 */ +#line 1979 "sql.tab.c" /* yacc.c:1646 */ break; case 59: @@ -1992,7 +1985,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2008 "sql.tab.c" /* yacc.c:1646 */ +#line 1989 "sql.tab.c" /* yacc.c:1646 */ break; case 60: @@ -2002,7 +1995,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2018 "sql.tab.c" /* yacc.c:1646 */ +#line 1999 "sql.tab.c" /* yacc.c:1646 */ break; case 61: @@ -2012,7 +2005,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2028 "sql.tab.c" /* yacc.c:1646 */ +#line 2009 "sql.tab.c" /* yacc.c:1646 */ break; case 62: @@ -2022,7 +2015,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2038 "sql.tab.c" /* yacc.c:1646 */ +#line 2019 "sql.tab.c" /* yacc.c:1646 */ break; case 63: @@ -2032,7 +2025,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2048 "sql.tab.c" /* yacc.c:1646 */ +#line 2029 "sql.tab.c" /* yacc.c:1646 */ break; case 64: @@ -2042,7 +2035,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2058 "sql.tab.c" /* yacc.c:1646 */ +#line 2039 "sql.tab.c" /* yacc.c:1646 */ break; case 65: @@ -2052,7 +2045,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2068 "sql.tab.c" /* yacc.c:1646 */ +#line 2049 "sql.tab.c" /* yacc.c:1646 */ break; case 66: @@ -2062,7 +2055,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2078 "sql.tab.c" /* yacc.c:1646 */ +#line 2059 "sql.tab.c" /* yacc.c:1646 */ break; case 69: @@ -2073,7 +2066,7 @@ yyreduce: YYABORT; (yyval.column_list)->val = (yyvsp[0].expr); } -#line 2089 "sql.tab.c" /* yacc.c:1646 */ +#line 2070 "sql.tab.c" /* yacc.c:1646 */ break; case 70: @@ -2085,7 +2078,7 @@ yyreduce: (yyval.column_list)->val = (yyvsp[-2].expr); (yyval.column_list)->next = (yyvsp[0].column_list); } -#line 2101 "sql.tab.c" /* yacc.c:1646 */ +#line 2082 "sql.tab.c" /* yacc.c:1646 */ break; case 72: @@ -2094,7 +2087,7 @@ yyreduce: (yyval.column_list) = (yyvsp[-2].column_list); (yyval.column_list)->next = (yyvsp[0].column_list); } -#line 2110 "sql.tab.c" /* yacc.c:1646 */ +#line 2091 "sql.tab.c" /* yacc.c:1646 */ break; case 73: @@ -2103,7 +2096,7 @@ yyreduce: (yyval.column_list) = (yyvsp[-2].column_list); (yyval.column_list)->val = (yyvsp[0].expr); } -#line 2119 "sql.tab.c" /* yacc.c:1646 */ +#line 2100 "sql.tab.c" /* yacc.c:1646 */ break; case 74: @@ -2113,7 +2106,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2129 "sql.tab.c" /* yacc.c:1646 */ +#line 2110 "sql.tab.c" /* yacc.c:1646 */ break; case 75: @@ -2123,7 +2116,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2139 "sql.tab.c" /* yacc.c:1646 */ +#line 2120 "sql.tab.c" /* yacc.c:1646 */ break; case 76: @@ -2133,7 +2126,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2149 "sql.tab.c" /* yacc.c:1646 */ +#line 2130 "sql.tab.c" /* yacc.c:1646 */ break; case 77: @@ -2143,7 +2136,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2159 "sql.tab.c" /* yacc.c:1646 */ +#line 2140 "sql.tab.c" /* yacc.c:1646 */ break; case 78: @@ -2153,7 +2146,7 @@ yyreduce: if( !(yyval.expr) ) YYABORT; } -#line 2169 "sql.tab.c" /* yacc.c:1646 */ +#line 2150 "sql.tab.c" /* yacc.c:1646 */ break; case 79: @@ -2163,7 +2156,7 @@ yyreduce: if( !(yyval.column_list) ) YYABORT; } -#line 2179 "sql.tab.c" /* yacc.c:1646 */ +#line 2160 "sql.tab.c" /* yacc.c:1646 */ break; case 80: @@ -2173,7 +2166,7 @@ yyreduce: if( !(yyval.column_list) ) YYABORT; } -#line 2189 "sql.tab.c" /* yacc.c:1646 */ +#line 2170 "sql.tab.c" /* yacc.c:1646 */ break; case 81: @@ -2183,7 +2176,7 @@ yyreduce: if( !(yyval.column_list) ) YYABORT; } -#line 2199 "sql.tab.c" /* yacc.c:1646 */ +#line 2180 "sql.tab.c" /* yacc.c:1646 */ break; case 82: @@ -2193,7 +2186,7 @@ yyreduce: if( !(yyval.column_list) ) YYABORT; } -#line 2209 "sql.tab.c" /* yacc.c:1646 */ +#line 2190 "sql.tab.c" /* yacc.c:1646 */ break; case 83: @@ -2203,7 +2196,7 @@ yyreduce: if( !(yyval.column_list) ) YYABORT; } -#line 2219 "sql.tab.c" /* yacc.c:1646 */ +#line 2200 "sql.tab.c" /* yacc.c:1646 */ break; case 84: @@ -2211,7 +2204,7 @@ yyreduce: { (yyval.string) = (yyvsp[0].string); } -#line 2227 "sql.tab.c" /* yacc.c:1646 */ +#line 2208 "sql.tab.c" /* yacc.c:1646 */ break; case 85: @@ -2220,7 +2213,7 @@ yyreduce: if ( SQL_getstring( info, &(yyvsp[0].str), &(yyval.string) ) != ERROR_SUCCESS || !(yyval.string) ) YYABORT; } -#line 2236 "sql.tab.c" /* yacc.c:1646 */ +#line 2217 "sql.tab.c" /* yacc.c:1646 */ break; case 86: @@ -2229,7 +2222,7 @@ yyreduce: if ( SQL_getstring( info, &(yyvsp[0].str), &(yyval.string) ) != ERROR_SUCCESS || !(yyval.string) ) YYABORT; } -#line 2245 "sql.tab.c" /* yacc.c:1646 */ +#line 2226 "sql.tab.c" /* yacc.c:1646 */ break; case 87: @@ -2237,11 +2230,11 @@ yyreduce: { (yyval.integer) = SQL_getint( info ); } -#line 2253 "sql.tab.c" /* yacc.c:1646 */ +#line 2234 "sql.tab.c" /* yacc.c:1646 */ break; -#line 2257 "sql.tab.c" /* yacc.c:1646 */ +#line 2238 "sql.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/dll/win32/msi/sql.tab.h b/dll/win32/msi/sql.tab.h index e648d74478..d9138c2550 100644 --- a/dll/win32/msi/sql.tab.h +++ b/dll/win32/msi/sql.tab.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 3.0. */ /* Bison interface for Yacc-like parsers in C @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef YY_SQL_SQL_TAB_H_INCLUDED -# define YY_SQL_SQL_TAB_H_INCLUDED +#ifndef YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED +# define YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -134,4 +134,4 @@ union YYSTYPE int sql_parse (SQL_input *info); -#endif /* !YY_SQL_SQL_TAB_H_INCLUDED */ +#endif /* !YY_SQL_E_REACTOSSYNC_GCC_DLL_WIN32_MSI_SQL_TAB_H_INCLUDED */ diff --git a/dll/win32/msi/storages.c b/dll/win32/msi/storages.c index a88dc95390..3ca708cb5b 100644 --- a/dll/win32/msi/storages.c +++ b/dll/win32/msi/storages.c @@ -18,7 +18,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winerror.h" +#include "ole2.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" #include "msipriv.h" +#include "query.h" + +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/dll/win32/msi/streams.c b/dll/win32/msi/streams.c index 642093e92c..e170c0367f 100644 --- a/dll/win32/msi/streams.c +++ b/dll/win32/msi/streams.c @@ -19,7 +19,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" #include "msipriv.h" +#include "query.h" + +#include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); @@ -194,7 +208,28 @@ static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row) { - FIXME("(%p %d): stub!\n", view, row); + MSIDATABASE *db = ((MSISTREAMSVIEW *)view)->db; + UINT i, num_rows = db->num_streams - 1; + const WCHAR *name; + WCHAR *encname; + HRESULT hr; + + TRACE("(%p %d)!\n", view, row); + + name = msi_string_lookup( db->strings, db->streams[row].str_index, NULL ); + if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY; + hr = IStorage_DestroyElement( db->storage, encname ); + msi_free( encname ); + if (FAILED( hr )) + return ERROR_FUNCTION_FAILED; + hr = IStream_Release( db->streams[row].stream ); + if (FAILED( hr )) + return ERROR_FUNCTION_FAILED; + + for (i = row; i < num_rows; i++) + db->streams[i] = db->streams[i + 1]; + db->num_streams = num_rows; + return ERROR_SUCCESS; } @@ -293,12 +328,15 @@ static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRE r = streams_modify_update(view, rec); break; + case MSIMODIFY_DELETE: + r = STREAMS_delete_row(view, row - 1); + break; + case MSIMODIFY_VALIDATE_NEW: case MSIMODIFY_INSERT_TEMPORARY: case MSIMODIFY_REFRESH: case MSIMODIFY_REPLACE: case MSIMODIFY_MERGE: - case MSIMODIFY_DELETE: case MSIMODIFY_VALIDATE: case MSIMODIFY_VALIDATE_FIELD: case MSIMODIFY_VALIDATE_DELETE: diff --git a/dll/win32/msi/string.c b/dll/win32/msi/string.c index 7801392aa1..f094a53c9e 100644 --- a/dll/win32/msi/string.c +++ b/dll/win32/msi/string.c @@ -20,7 +20,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include <stdarg.h> +#include <assert.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/dll/win32/msi/suminfo.c b/dll/win32/msi/suminfo.c index 067483d629..c929fa574f 100644 --- a/dll/win32/msi/suminfo.c +++ b/dll/win32/msi/suminfo.c @@ -18,14 +18,30 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS +#define NONAMELESSUNION + +#include "stdio.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "shlwapi.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "msidefs.h" #include "msipriv.h" - -#include <stdio.h> -#include <propvarutil.h> +#include "objidl.h" +#include "propvarutil.h" +#include "msiserver.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); -#include <pshpack1.h> +#include "pshpack1.h" typedef struct { WORD wByteOrder; @@ -63,7 +79,7 @@ typedef struct { } u; } PROPERTY_DATA; -#include <poppack.h> +#include "poppack.h" static HRESULT (WINAPI *pPropVariantChangeType) (PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, @@ -1000,6 +1016,117 @@ end: return r; } +static UINT save_prop( MSISUMMARYINFO *si, HANDLE handle, UINT row ) +{ + static const char fmt_systemtime[] = "%d/%02d/%02d %02d:%02d:%02d"; + char data[20]; /* largest string: YYYY/MM/DD hh:mm:ss */ + static const char fmt_begin[] = "%u\t"; + static const char data_end[] = "\r\n"; + static const char fmt_int[] = "%u"; + UINT r, data_type, len; + SYSTEMTIME system_time; + FILETIME file_time; + INT int_value; + awstring str; + DWORD sz; + + str.unicode = FALSE; + str.str.a = NULL; + len = 0; + r = get_prop( si, row, &data_type, &int_value, &file_time, &str, &len ); + if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) + return r; + if (data_type == VT_EMPTY) + return ERROR_SUCCESS; /* property not set */ + snprintf( data, sizeof(data), fmt_begin, row ); + sz = lstrlenA( data ); + if (!WriteFile( handle, data, sz, &sz, NULL )) + return ERROR_WRITE_FAULT; + + switch (data_type) + { + case VT_I2: + case VT_I4: + snprintf( data, sizeof(data), fmt_int, int_value ); + sz = lstrlenA( data ); + if (!WriteFile( handle, data, sz, &sz, NULL )) + return ERROR_WRITE_FAULT; + break; + case VT_LPSTR: + len++; + if (!(str.str.a = msi_alloc( len ))) + return ERROR_OUTOFMEMORY; + r = get_prop( si, row, NULL, NULL, NULL, &str, &len ); + if (r != ERROR_SUCCESS) + { + msi_free( str.str.a ); + return r; + } + sz = lstrlenA( str.str.a ); + if (!WriteFile( handle, str.str.a, sz, &sz, NULL )) + { + msi_free( str.str.a ); + return ERROR_WRITE_FAULT; + } + msi_free( str.str.a ); + break; + case VT_FILETIME: + if (!FileTimeToSystemTime( &file_time, &system_time )) + return ERROR_FUNCTION_FAILED; + snprintf( data, sizeof(data), fmt_systemtime, system_time.wYear, system_time.wMonth, + system_time.wDay, system_time.wHour, system_time.wMinute, + system_time.wSecond ); + sz = lstrlenA( data ); + if (!WriteFile( handle, data, sz, &sz, NULL )) + return ERROR_WRITE_FAULT; + break; + case VT_EMPTY: + /* cannot reach here, property not set */ + break; + default: + FIXME( "Unknown property variant type\n" ); + return ERROR_FUNCTION_FAILED; + } + + sz = lstrlenA( data_end ); + if (!WriteFile( handle, data_end, sz, &sz, NULL )) + return ERROR_WRITE_FAULT; + + return ERROR_SUCCESS; +} + +UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle ) +{ + UINT i, r, num_rows; + MSISUMMARYINFO *si; + + r = msi_get_suminfo( db->storage, 0, &si ); + if (r != ERROR_SUCCESS) + r = msi_get_db_suminfo( db, 0, &si ); + if (r != ERROR_SUCCESS) + return r; + + num_rows = get_property_count( si->property ); + if (!num_rows) + { + msiobj_release( &si->hdr ); + return ERROR_FUNCTION_FAILED; + } + + for (i = 0; i < num_rows; i++) + { + r = save_prop( si, handle, i ); + if (r != ERROR_SUCCESS) + { + msiobj_release( &si->hdr ); + return r; + } + } + + msiobj_release( &si->hdr ); + return ERROR_SUCCESS; +} + UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE handle ) { MSISUMMARYINFO *si; diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c index c21c110642..45a181445a 100644 --- a/dll/win32/msi/table.c +++ b/dll/win32/msi/table.c @@ -18,7 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#include <assert.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" +#include "winnls.h" #include "msipriv.h" +#include "query.h" + +#include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/dll/win32/msi/tokenize.c b/dll/win32/msi/tokenize.c index 52dd3dffde..1656fd8c3d 100644 --- a/dll/win32/msi/tokenize.c +++ b/dll/win32/msi/tokenize.c @@ -16,7 +16,14 @@ ** parser for analysis. */ -#include "msipriv.h" +#include <ctype.h> +#include <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "wine/unicode.h" +#include "query.h" #include "sql.tab.h" /* diff --git a/dll/win32/msi/update.c b/dll/win32/msi/update.c index b09c8ed75a..d0e3c28f79 100644 --- a/dll/win32/msi/update.c +++ b/dll/win32/msi/update.c @@ -18,10 +18,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); + /* below is the query interface to a table */ typedef struct tagMSIUPDATEVIEW diff --git a/dll/win32/msi/upgrade.c b/dll/win32/msi/upgrade.c index edc4c309a2..ac58d909e0 100644 --- a/dll/win32/msi/upgrade.c +++ b/dll/win32/msi/upgrade.c @@ -26,7 +26,17 @@ * RemoveExistingProducts (TODO) */ +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/debug.h" +#include "msidefs.h" #include "msipriv.h" +#include "winuser.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); diff --git a/dll/win32/msi/where.c b/dll/win32/msi/where.c index c0bb0d328d..ddd8c07fab 100644 --- a/dll/win32/msi/where.c +++ b/dll/win32/msi/where.c @@ -19,7 +19,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> +#include <assert.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "msi.h" +#include "msiquery.h" +#include "objbase.h" +#include "objidl.h" #include "msipriv.h" +#include "winnls.h" + +#include "query.h" WINE_DEFAULT_DEBUG_CHANNEL(msidb); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index d7590c2880..8694f27ce6 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -112,7 +112,7 @@ reactos/dll/win32/msg711.acm # Synced to WineStaging-2.9 reactos/dll/win32/msgsm32.acm # Synced to WineStaging-2.9 reactos/dll/win32/mshtml # Synced to WineStaging-1.7.55 reactos/dll/win32/mshtml.tlb # Synced to WineStaging-1.7.55 -reactos/dll/win32/msi # Synced to Wine-3.0 +reactos/dll/win32/msi # Synced to WineStaging-3.3 reactos/dll/win32/msimg32 # Synced to WineStaging-2.16 reactos/dll/win32/msimtf # Synced to WineStaging-2.9 reactos/dll/win32/msisip # Synced to WineStaging-2.9
6 years, 9 months
1
0
0
0
01/01: [WINDOWSCODECS_WINETEST] Sync with Wine Staging 3.3. CORE-14434
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=23ec1e5e6f62c1d2f0556…
commit 23ec1e5e6f62c1d2f0556016b1124be90646adc5 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Mar 5 00:20:56 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Mar 5 00:20:56 2018 +0100 [WINDOWSCODECS_WINETEST] Sync with Wine Staging 3.3. CORE-14434 --- .../winetests/windowscodecs/CMakeLists.txt | 1 + modules/rostests/winetests/windowscodecs/bitmap.c | 13 +- .../rostests/winetests/windowscodecs/bmpformat.c | 12 +- .../rostests/winetests/windowscodecs/converter.c | 848 +++++++++++++++++++-- .../rostests/winetests/windowscodecs/gifformat.c | 9 +- .../rostests/winetests/windowscodecs/icoformat.c | 10 +- modules/rostests/winetests/windowscodecs/info.c | 332 +++++--- .../rostests/winetests/windowscodecs/jpegformat.c | 145 ++++ .../rostests/winetests/windowscodecs/metadata.c | 17 +- modules/rostests/winetests/windowscodecs/palette.c | 149 +++- .../rostests/winetests/windowscodecs/pngformat.c | 14 +- modules/rostests/winetests/windowscodecs/precomp.h | 4 +- .../rostests/winetests/windowscodecs/propertybag.c | 12 +- modules/rostests/winetests/windowscodecs/stream.c | 5 +- .../rostests/winetests/windowscodecs/testlist.c | 2 + .../rostests/winetests/windowscodecs/tiffformat.c | 758 +++++++++++++++++- 16 files changed, 2091 insertions(+), 240 deletions(-) diff --git a/modules/rostests/winetests/windowscodecs/CMakeLists.txt b/modules/rostests/winetests/windowscodecs/CMakeLists.txt index 293a437853..0cffe520e8 100644 --- a/modules/rostests/winetests/windowscodecs/CMakeLists.txt +++ b/modules/rostests/winetests/windowscodecs/CMakeLists.txt @@ -8,6 +8,7 @@ list(APPEND SOURCE gifformat.c icoformat.c info.c + jpegformat.c metadata.c palette.c pngformat.c diff --git a/modules/rostests/winetests/windowscodecs/bitmap.c b/modules/rostests/winetests/windowscodecs/bitmap.c index b35c07fbf1..42f452acaf 100644 --- a/modules/rostests/winetests/windowscodecs/bitmap.c +++ b/modules/rostests/winetests/windowscodecs/bitmap.c @@ -17,7 +17,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> +#include <assert.h> +#include <math.h> + +#define COBJMACROS +#define CONST_VTABLE + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" static IWICImagingFactory *factory; diff --git a/modules/rostests/winetests/windowscodecs/bmpformat.c b/modules/rostests/winetests/windowscodecs/bmpformat.c index afa2bd92b8..48985b9cba 100644 --- a/modules/rostests/winetests/windowscodecs/bmpformat.c +++ b/modules/rostests/winetests/windowscodecs/bmpformat.c @@ -16,7 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <math.h> + +#define COBJMACROS + +#include "windef.h" +#include "initguid.h" +#include "objbase.h" +#include "wincodec.h" +#include "wincodecsdk.h" +#include "wine/test.h" static const char testbmp_24bpp[] = { /* BITMAPFILEHEADER */ diff --git a/modules/rostests/winetests/windowscodecs/converter.c b/modules/rostests/winetests/windowscodecs/converter.c index 2a44ef50b0..91deda2010 100644 --- a/modules/rostests/winetests/windowscodecs/converter.c +++ b/modules/rostests/winetests/windowscodecs/converter.c @@ -17,7 +17,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> +#include <math.h> + +#define COBJMACROS +#define CONST_VTABLE + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wincodecsdk.h" +#include "wine/test.h" static IWICImagingFactory *factory; @@ -107,9 +118,30 @@ static HRESULT WINAPI BitmapTestSrc_GetResolution(IWICBitmapSource *iface, } static HRESULT WINAPI BitmapTestSrc_CopyPalette(IWICBitmapSource *iface, - IWICPalette *pIPalette) + IWICPalette *palette) { - return E_NOTIMPL; + BitmapTestSrc *This = impl_from_IWICBitmapSource(iface); + + if (IsEqualGUID(This->data->format, &GUID_WICPixelFormat1bppIndexed) || + IsEqualGUID(This->data->format, &GUID_WICPixelFormat2bppIndexed) || + IsEqualGUID(This->data->format, &GUID_WICPixelFormat4bppIndexed) || + IsEqualGUID(This->data->format, &GUID_WICPixelFormat8bppIndexed)) + { + WICColor colors[8]; + + colors[0] = 0xff0000ff; + colors[1] = 0xff00ff00; + colors[2] = 0xffff0000; + colors[3] = 0xff000000; + colors[4] = 0xffffff00; + colors[5] = 0xffff00ff; + colors[6] = 0xff00ffff; + colors[7] = 0xffffffff; + return IWICPalette_InitializeCustom(palette, colors, 8); + } + + /* unique error marker */ + return 0xdeadbeef; } static HRESULT WINAPI BitmapTestSrc_CopyPixels(IWICBitmapSource *iface, @@ -241,16 +273,58 @@ static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, cons break; } } + else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat2bppIndexed) || + IsEqualGUID(expect->format, &GUID_WICPixelFormat4bppIndexed) || + IsEqualGUID(expect->format, &GUID_WICPixelFormat8bppIndexed)) + { + UINT i; + const BYTE *a=(const BYTE*)expect->bits, *b=(const BYTE*)converted_bits; + equal=TRUE; + + for (i=0; i<buffersize; i++) + if (a[i] != b[i]) + { + equal = FALSE; + break; + } + } else equal = (memcmp(expect->bits, converted_bits, buffersize) == 0); 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; } -static void compare_bitmap_data(const struct bitmap_data *expect, IWICBitmapSource *source, const char *name) +static BOOL is_indexed_format(const GUID *format) +{ + if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed) || + IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed) || + IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed) || + IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) + return TRUE; + + return FALSE; +} + +static void compare_bitmap_data(const struct bitmap_data *src, const struct bitmap_data *expect, + IWICBitmapSource *source, const char *name) { BYTE *converted_bits; UINT width, height; @@ -283,15 +357,24 @@ static void compare_bitmap_data(const struct bitmap_data *expect, IWICBitmapSour buffersize = stride * expect->height; converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize); + memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits); ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr); - ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); + + /* The result of conversion of color to indexed formats depends on + * optimized palette generation implementation. We either need to + * assign our own palette, or just skip the comparison. + */ + if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format))) + ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); /* Test with NULL rectangle - should copy the whole bitmap */ memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits); ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr); - ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); + /* see comment above */ + if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format))) + ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); HeapFree(GetProcessHeap(), 0, converted_bits); } @@ -305,66 +388,161 @@ static const struct bitmap_data testdata_BlackWhite = { static const struct bitmap_data testdata_1bppIndexed = { &GUID_WICPixelFormat1bppIndexed, 1, bits_1bpp, 32, 2, 96.0, 96.0}; +/* some encoders (like BMP) require data to be 4-bytes aligned */ +static const BYTE bits_2bpp[] = { + 0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb, + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24}; +static const struct bitmap_data testdata_2bppIndexed = { + &GUID_WICPixelFormat2bppIndexed, 2, bits_2bpp, 32, 2, 96.0, 96.0}; + +/* some encoders (like BMP) require data to be 4-bytes aligned */ +static const BYTE bits_4bpp[] = { + 0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23, + 0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67}; + +static const struct bitmap_data testdata_4bppIndexed = { + &GUID_WICPixelFormat4bppIndexed, 4, bits_4bpp, 32, 2, 96.0, 96.0}; + +static const BYTE bits_8bpp_BW[] = { + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}; +static const struct bitmap_data testdata_8bppIndexed_BW = { + &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp_BW, 32, 2, 96.0, 96.0}; + +static const BYTE bits_8bpp_4colors[] = { + 0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0, + 3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3}; +static const struct bitmap_data testdata_8bppIndexed_4colors = { + &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp_4colors, 32, 2, 96.0, 96.0}; + static const BYTE bits_8bpp[] = { - 0,1,2,3, - 4,5,6,7}; + 0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3, + 4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7}; static const struct bitmap_data testdata_8bppIndexed = { - &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp, 32, 2, 96.0, 96.0}; static const BYTE bits_24bppBGR[] = { - 255,0,0, 0,255,0, 0,0,255, 0,0,0, - 0,255,255, 255,0,255, 255,255,0, 255,255,255}; + 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0, + 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0, + 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0, + 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0, + 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255, + 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255, + 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255, + 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255}; static const struct bitmap_data testdata_24bppBGR = { - &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR, 32, 2, 96.0, 96.0}; static const BYTE bits_24bppRGB[] = { - 0,0,255, 0,255,0, 255,0,0, 0,0,0, - 255,255,0, 255,0,255, 0,255,255, 255,255,255}; + 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0, + 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0, + 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0, + 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0, + 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255, + 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255, + 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255, + 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255 }; static const struct bitmap_data testdata_24bppRGB = { - &GUID_WICPixelFormat24bppRGB, 24, bits_24bppRGB, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat24bppRGB, 24, bits_24bppRGB, 32, 2, 96.0, 96.0}; static const BYTE bits_32bppBGR[] = { - 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, - 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80}; + 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, + 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, + 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, + 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, + 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, + 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, + 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, + 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, 4, 2, 96.0, 96.0}; + &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, - 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255}; + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, 4, 2, 96.0, 96.0}; + &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[] = { - 0.114000f,0.587000f,0.299000f,0.000000f, - 0.886000f,0.413000f,0.701000f,1.000000f}; + 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f, + 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f, + 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f, + 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f, + 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f, + 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f, + 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f, + 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f}; static const struct bitmap_data testdata_32bppGrayFloat_xp = { - &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat_xp, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat_xp, 32, 2, 96.0, 96.0}; static const float bits_32bppGrayFloat[] = { - 0.072200f,0.715200f,0.212600f,0.000000f, - 0.927800f,0.284800f,0.787400f,1.000000f}; + 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f, + 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f, + 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f, + 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f, + 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f, + 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f, + 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f, + 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f}; static const struct bitmap_data testdata_32bppGrayFloat = { - &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 4, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp}; + &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp}; static const BYTE bits_8bppGray_xp[] = { - 29,150,76,0, - 226,105,179,255}; + 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, + 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, + 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255, + 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255}; static const struct bitmap_data testdata_8bppGray_xp = { - &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray_xp, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray_xp, 32, 2, 96.0, 96.0}; static const BYTE bits_8bppGray[] = { - 76,220,127,0, - 247,145,230,255}; + 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0, + 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0, + 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255, + 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255}; static const struct bitmap_data testdata_8bppGray = { - &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 4, 2, 96.0, 96.0, &testdata_8bppGray_xp}; + &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 32, 2, 96.0, 96.0, &testdata_8bppGray_xp}; static const BYTE bits_24bppBGR_gray[] = { - 76,76,76, 220,220,220, 127,127,127, 0,0,0, - 247,247,247, 145,145,145, 230,230,230, 255,255,255}; + 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, + 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, + 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, + 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, + 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255, + 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255, + 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255, + 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255}; static const struct bitmap_data testdata_24bppBGR_gray = { - &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 4, 2, 96.0, 96.0}; + &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0}; static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo) { @@ -376,11 +554,12 @@ static void test_conversion(const struct bitmap_data *src, const struct bitmap_d hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap); todo_wine_if (todo) - ok(SUCCEEDED(hr), "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); + ok(hr == S_OK || + broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); - if (SUCCEEDED(hr)) + if (hr == S_OK) { - compare_bitmap_data(dst, dst_bitmap, name); + compare_bitmap_data(src, dst, dst_bitmap, name); IWICBitmapSource_Release(dst_bitmap); } @@ -428,7 +607,7 @@ static void test_default_converter(void) ok(SUCCEEDED(hr), "Initialize returned %x\n", hr); if (SUCCEEDED(hr)) - compare_bitmap_data(&testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter"); + compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter"); IWICFormatConverter_Release(converter); } @@ -456,6 +635,7 @@ static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0}; static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0}; static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0}; static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0}; +static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0}; static const struct property_opt_test_data testdata_tiff_props[] = { { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare }, @@ -479,6 +659,11 @@ static const struct property_opt_test_data testdata_jpeg_props[] = { { NULL } }; +static const struct property_opt_test_data testdata_bmp_props[] = { + { wszEnableV5Header32bppBGRA, VT_BOOL, VT_BOOL, VARIANT_FALSE, 0.0f, TRUE }, /* Supported since Win7 */ + { NULL } +}; + static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt) { int i; @@ -605,6 +790,8 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2); else if (IsEqualCLSID(clsid_encoder, &CLSID_WICJpegEncoder)) test_specific_encoder_properties(options, testdata_jpeg_props, all_props, cProperties2); + else if (IsEqualCLSID(clsid_encoder, &CLSID_WICBmpEncoder)) + test_specific_encoder_properties(options, testdata_bmp_props, all_props, cProperties2); for (i=0; i < cProperties2; i++) { @@ -613,14 +800,232 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o } } -static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format) +static void load_stream(IUnknown *reader, IStream *stream) { - /* FIXME */ + HRESULT hr; + IWICPersistStream *persist; +#ifdef WORDS_BIGENDIAN + DWORD persist_options = WICPersistOptionBigEndian; +#else + DWORD persist_options = WICPersistOptionLittleEndian; +#endif + + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + + hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); + ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); + + IWICPersistStream_Release(persist); } static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format) { - /* FIXME */ + HRESULT hr; + IWICMetadataReader *reader; + PROPVARIANT id, value; + struct + { + USHORT byte_order; + USHORT version; + ULONG dir_offset; + } tiff; + LARGE_INTEGER pos; + UINT count, i; + int width, height, bps, photo, samples, colormap; + struct + { + int id, *value; + } tag[] = + { + { 0x100, &width }, { 0x101, &height }, { 0x102, &bps }, + { 0x106, &photo }, { 0x115, &samples }, { 0x140, &colormap } + }; + + memset(&tiff, 0, sizeof(tiff)); + hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL); + ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'), + "wrong TIFF byte order mark %02x\n", tiff.byte_order); + ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version); + + pos.QuadPart = tiff.dir_offset; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + + hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + + load_stream((IUnknown *)reader, stream); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(count != 0, "wrong count %u\n", count); + + for (i = 0; i < sizeof(tag)/sizeof(tag[0]); i++) + { + PropVariantInit(&id); + PropVariantInit(&value); + + id.vt = VT_UI2; + U(id).uiVal = tag[i].id; + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND), + "GetValue(%04x) error %#x\n", tag[i].id, hr); + if (hr == S_OK) + { + ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt); + tag[i].value[0] = U(value).uiVal; + } + else + tag[i].value[0] = -1; + } + + IWICMetadataReader_Release(reader); + + if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 1, "wrong bps %d\n", bps); + ok(photo == 1, "wrong photometric %d\n", photo); + ok(samples == 1, "wrong samples %d\n", samples); + ok(colormap == -1, "wrong colormap %d\n", colormap); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 1, "wrong bps %d\n", bps); + ok(photo == 3, "wrong photometric %d\n", photo); + ok(samples == 1, "wrong samples %d\n", samples); + ok(colormap == 6, "wrong colormap %d\n", colormap); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 2, "wrong bps %d\n", bps); + ok(photo == 3, "wrong photometric %d\n", photo); + ok(samples == 1, "wrong samples %d\n", samples); + ok(colormap == 12, "wrong colormap %d\n", colormap); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 4, "wrong bps %d\n", bps); + ok(photo == 3, "wrong photometric %d\n", photo); + ok(samples == 1, "wrong samples %d\n", samples); + ok(colormap == 48, "wrong colormap %d\n", colormap); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 8, "wrong bps %d\n", bps); + ok(photo == 3, "wrong photometric %d\n", photo); + ok(samples == 1, "wrong samples %d\n", samples); + ok(colormap == 768, "wrong colormap %d\n", colormap); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR)) + { + ok(width == 32, "wrong width %u\n", width); + ok(height == 2, "wrong height %u\n", height); + + ok(bps == 3, "wrong bps %d\n", bps); + ok(photo == 2, "wrong photometric %d\n", photo); + ok(samples == 3, "wrong samples %d\n", samples); + ok(colormap == -1, "wrong colormap %d\n", colormap); + } + else + ok(0, "unknown TIFF pixel format %s\n", wine_dbgstr_guid(format)); +} + +static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format) +{ + HRESULT hr; + BITMAPFILEHEADER bfh; + BITMAPV5HEADER bih; + + hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL); + ok(hr == S_OK, "IStream_Read error %#x\n", hr); + + ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType); + ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1); + ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2); + + hr = IStream_Read(stream, &bih, sizeof(bih), NULL); + ok(hr == S_OK, "IStream_Read error %#x\n", hr); + + if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed)) + { + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + + ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + + ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); + ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed)) + { + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + + ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + + ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); + ok(bih.bV5BitCount == 2, "wrong BitCount %d\n", bih.bV5BitCount); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed)) + { + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + + ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + + ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); + ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) + { + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + + ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + + ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); + ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR)) + { + ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits); + + ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + + ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); + ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount); + ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + } + else + ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format)); } static unsigned be_uint(unsigned val) @@ -677,9 +1082,31 @@ static void check_png_format(IStream *stream, const WICPixelFormatGUID *format) ok(png.filter == 0, "wrong filter %d\n", png.filter); ok(png.interlace == 0, "wrong interlace %d\n", png.interlace); } + else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed)) + { + ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width)); + ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height)); + + ok(png.bit_depth == 2, "wrong bit_depth %d\n", png.bit_depth); + ok(png.color_type == 3, "wrong color_type %d\n", png.color_type); + ok(png.compression == 0, "wrong compression %d\n", png.compression); + ok(png.filter == 0, "wrong filter %d\n", png.filter); + ok(png.interlace == 0, "wrong interlace %d\n", png.interlace); + } + else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed)) + { + ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width)); + ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height)); + + ok(png.bit_depth == 4, "wrong bit_depth %d\n", png.bit_depth); + ok(png.color_type == 3, "wrong color_type %d\n", png.color_type); + ok(png.compression == 0, "wrong compression %d\n", png.compression); + ok(png.filter == 0, "wrong filter %d\n", png.filter); + ok(png.interlace == 0, "wrong interlace %d\n", png.interlace); + } else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) { - ok(be_uint(png.width) == 4, "wrong width %u\n", be_uint(png.width)); + ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width)); ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height)); ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth); @@ -690,7 +1117,7 @@ static void check_png_format(IStream *stream, const WICPixelFormatGUID *format) } else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR)) { - ok(be_uint(png.width) == 4, "wrong width %u\n", be_uint(png.width)); + ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width)); ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height)); ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth); @@ -703,6 +1130,40 @@ static void check_png_format(IStream *stream, const WICPixelFormatGUID *format) ok(0, "unknown PNG pixel format %s\n", wine_dbgstr_guid(format)); } +static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format) +{ +#include "pshpack1.h" + struct logical_screen_descriptor + { + char signature[6]; + USHORT width; + USHORT height; + BYTE packed; + /* global_color_table_flag : 1; + * color_resolution : 3; + * sort_flag : 1; + * global_color_table_size : 3; + */ + BYTE background_color_index; + BYTE pixel_aspect_ratio; + } lsd; +#include "poppack.h" + UINT color_resolution; + HRESULT hr; + + memset(&lsd, 0, sizeof(lsd)); + hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL); + ok(hr == S_OK, "IStream_Read error %#x\n", hr); + + ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature); + + ok(lsd.width == 32, "wrong width %u\n", lsd.width); + ok(lsd.height == 2, "wrong height %u\n", lsd.height); + color_resolution = 1 << (((lsd.packed >> 4) & 0x07) + 1); + ok(color_resolution == 256, "wrong color resolution %u\n", color_resolution); + ok(lsd.pixel_aspect_ratio == 0, "wrong pixel_aspect_ratio %u\n", lsd.pixel_aspect_ratio); +} + static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WICPixelFormatGUID *format) { HRESULT hr; @@ -718,6 +1179,8 @@ static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WIC check_bmp_format(stream, format); else if (IsEqualGUID(encoder, &CLSID_WICTiffEncoder)) check_tiff_format(stream, format); + else if (IsEqualGUID(encoder, &CLSID_WICGifEncoder)) + check_gif_format(stream, format); else ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder)); @@ -793,8 +1256,26 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls int i; hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICBitmapEncoder, (void**)&encoder); + &IID_IWICBitmapEncoder, (void **)&encoder); ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + + /* Encoder options are optional. */ + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL); + ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr); + + IStream_Release(stream); + IWICBitmapEncoder_Release(encoder); + IWICBitmapFrameEncode_Release(frameencode); + + hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapEncoder, (void**)&encoder); + ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr); if (SUCCEEDED(hr)) { hglobal = GlobalAlloc(GMEM_MOVEABLE, 0); @@ -819,7 +1300,10 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (palette) { hr = IWICBitmapEncoder_SetPalette(encoder, palette); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr); + if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder)) + ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr); + else + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr); hr = S_OK; } @@ -868,8 +1352,10 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls memcpy(&pixelformat, srcs[i]->format, sizeof(GUID)); hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat); ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr); - ok(IsEqualGUID(&pixelformat, dsts[i]->format), "SetPixelFormat changed the format to %s (%s)\n", - wine_dbgstr_guid(&pixelformat), name); + ok(IsEqualGUID(&pixelformat, dsts[i]->format) || + broken(IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) || + broken(IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)), + "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name); hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr); @@ -904,6 +1390,8 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name); else ok(hr == S_OK || + broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2) /* XP */ || + broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) /* XP */ || broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && IsEqualGUID(srcs[i]->format, &GUID_WICPixelFormatBlackWhite)) /* XP */, "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name); } @@ -935,7 +1423,8 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls hr = IWICBitmapEncoder_Commit(encoder); ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr); - check_bitmap_format(stream, clsid_encoder, dsts[0]->format); + if (IsEqualGUID(&pixelformat, dsts[0]->format)) + check_bitmap_format(stream, clsid_encoder, dsts[0]->format); } if (SUCCEEDED(hr)) @@ -953,13 +1442,19 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls ok(hr == S_OK, "CreatePalette error %#x\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) + ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#x\n", hr); + else + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) + ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#x\n", hr); + else + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); hr = S_OK; i=0; @@ -970,7 +1465,10 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (SUCCEEDED(hr)) { - compare_bitmap_data(dsts[i], (IWICBitmapSource*)framedecode, name); + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat); + ok(hr == S_OK, "GetPixelFormat) failed, hr=%x (%s)\n", hr, name); + if (IsEqualGUID(&pixelformat, dsts[i]->format)) + compare_bitmap_data(srcs[i], dsts[i], (IWICBitmapSource*)framedecode, name); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, frame_palette); if (winetest_debug > 1) @@ -995,7 +1493,12 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls ok(ret == count, "expected %u, got %u\n", count, ret); if (IsEqualGUID(clsid_decoder, &CLSID_WICPngDecoder)) { - ok(count == 256 || count == 2 /* newer libpng versions */, "expected 256, got %u (%s)\n", count, name); + /* Newer libpng versions don't accept larger palettes than the declared + * bit depth, so we need to generate the palette of the correct length. + */ + ok(count == 256 || (dsts[i]->bpp == 1 && count == 2) || + (dsts[i]->bpp == 2 && count == 4) || (dsts[i]->bpp == 4 && count == 16), + "expected 256, got %u (%s)\n", count, name); ok(colors[0] == 0x11111111, "got %08x (%s)\n", colors[0], name); ok(colors[1] == 0x22222222, "got %08x (%s)\n", colors[1], name); @@ -1003,15 +1506,19 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls { ok(colors[2] == 0x33333333, "got %08x (%s)\n", colors[2], name); ok(colors[3] == 0x44444444, "got %08x (%s)\n", colors[3], name); - ok(colors[4] == 0x55555555, "got %08x (%s)\n", colors[4], name); - ok(colors[5] == 0, "got %08x (%s)\n", colors[5], name); + if (count > 4) + { + ok(colors[4] == 0x55555555, "got %08x (%s)\n", colors[4], name); + ok(colors[5] == 0, "got %08x (%s)\n", colors[5], name); + } } } else if (IsEqualGUID(clsid_decoder, &CLSID_WICBmpDecoder) || - IsEqualGUID(clsid_decoder, &CLSID_WICTiffDecoder)) + IsEqualGUID(clsid_decoder, &CLSID_WICTiffDecoder) || + IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) { - if (IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormatBlackWhite) || - IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormat8bppIndexed)) + if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormatBlackWhite) || + IsEqualGUID(&pixelformat, &GUID_WICPixelFormat8bppIndexed)) { ok(count == 256, "expected 256, got %u (%s)\n", count, name); @@ -1022,6 +1529,26 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name); ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name); } + else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat2bppIndexed)) + { + ok(count == 4, "expected 4, got %u (%s)\n", count, name); + + ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name); + ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name); + ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name); + ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name); + } + else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) + { + ok(count == 16, "expected 16, got %u (%s)\n", count, name); + + ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name); + ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name); + ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name); + ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name); + ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name); + ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name); + } else { ok(count == 2, "expected 2, got %u (%s)\n", count, name); @@ -1101,7 +1628,7 @@ static void test_encoder_rects(void) rc.X = 0; rc.Y = 0; - rc.Width = 4; + rc.Width = 32; rc.Height = 2; test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects full", NULL); @@ -1112,7 +1639,7 @@ static void test_encoder_rects(void) rc.Width = -1; test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=-1", NULL); - rc.Width = 4; + rc.Width = 32; rc.Height = 0; test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=0", NULL); @@ -1134,6 +1661,163 @@ static const struct setting png_interlace_settings[] = { {NULL} }; +static void test_converter_8bppIndexed(void) +{ + HRESULT hr; + BitmapTestSrc *src_obj; + IWICFormatConverter *converter; + IWICPalette *palette; + UINT count, i; + BYTE buf[32 * 2 * 3]; /* enough to hold 32x2 24bppBGR data */ + + CreateTestBitmap(&testdata_24bppBGR, &src_obj); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 0, "expected 0, got %u\n", count); + + /* NULL palette + Custom type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == S_OK, "Initialize error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + IWICFormatConverter_Release(converter); + + /* NULL palette + Custom type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + IWICFormatConverter_Release(converter); + + /* empty palette + Custom type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + palette, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == S_OK, "Initialize error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 0, "expected 0, got %u\n", count); + memset(buf, 0xaa, sizeof(buf)); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + count = 0; + for (i = 0; i < 32 * 2; i++) + if (buf[i] != 0) count++; + ok(count == 0, "expected 0\n"); + IWICFormatConverter_Release(converter); + + /* NULL palette + Predefined type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeFixedGray16); + ok(hr == S_OK, "Initialize error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 16, "expected 16, got %u\n", count); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + count = 0; + for (i = 0; i < 32 * 2; i++) + if (buf[i] != 0) count++; + ok(count != 0, "expected != 0\n"); + IWICFormatConverter_Release(converter); + + /* not empty palette + Predefined type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + palette, 0.0, WICBitmapPaletteTypeFixedHalftone64); + ok(hr == S_OK, "Initialize error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 16, "expected 16, got %u\n", count); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + count = 0; + for (i = 0; i < 32 * 2; i++) + if (buf[i] != 0) count++; + ok(count != 0, "expected != 0\n"); + IWICFormatConverter_Release(converter); + + /* not empty palette + MedianCut type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + palette, 0.0, WICBitmapPaletteTypeMedianCut); + ok(hr == S_OK, "Initialize error %#x\n", hr); + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 16, "expected 16, got %u\n", count); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + count = 0; + for (i = 0; i < 32 * 2; i++) + if (buf[i] != 0) count++; + ok(count != 0, "expected != 0\n"); + IWICFormatConverter_Release(converter); + + /* NULL palette + MedianCut type*/ + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeMedianCut); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr); + if (hr == S_OK) + { + hr = IWICFormatConverter_CopyPalette(converter, palette); + ok(hr == S_OK, "CopyPalette error %#x\n", hr); + count = 0xdeadbeef; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 8, "expected 8, got %u\n", count); + hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); + ok(hr == S_OK, "CopyPixels error %#x\n", hr); + count = 0; + for (i = 0; i < 32 * 2; i++) + if (buf[i] != 0) count++; + ok(count != 0, "expected != 0\n"); + } + IWICFormatConverter_Release(converter); + + IWICPalette_Release(palette); + DeleteTestBitmap(src_obj); +} + START_TEST(converter) { HRESULT hr; @@ -1144,9 +1828,27 @@ START_TEST(converter) &IID_IWICImagingFactory, (void **)&factory); ok(hr == S_OK, "failed to create factory: %#x\n", hr); + test_converter_8bppIndexed(); + + 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); + + test_conversion(&testdata_BlackWhite, &testdata_8bppIndexed_BW, "BlackWhite -> 8bppIndexed", TRUE); + test_conversion(&testdata_1bppIndexed, &testdata_8bppIndexed_BW, "1bppIndexed -> 8bppIndexed", TRUE); + test_conversion(&testdata_2bppIndexed, &testdata_8bppIndexed_4colors, "2bppIndexed -> 8bppIndexed", TRUE); + test_conversion(&testdata_4bppIndexed, &testdata_8bppIndexed, "4bppIndexed -> 8bppIndexed", TRUE); + 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); @@ -1169,36 +1871,50 @@ START_TEST(converter) test_invalid_conversion(); test_default_converter(); + test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder, + &testdata_8bppIndexed, &CLSID_WICGifDecoder, "GIF encoder 8bppIndexed"); + test_encoder(&testdata_BlackWhite, &CLSID_WICPngEncoder, &testdata_BlackWhite, &CLSID_WICPngDecoder, "PNG encoder BlackWhite"); test_encoder(&testdata_1bppIndexed, &CLSID_WICPngEncoder, &testdata_1bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 1bppIndexed"); + test_encoder(&testdata_2bppIndexed, &CLSID_WICPngEncoder, + &testdata_2bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 2bppIndexed"); + test_encoder(&testdata_4bppIndexed, &CLSID_WICPngEncoder, + &testdata_4bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 4bppIndexed"); test_encoder(&testdata_8bppIndexed, &CLSID_WICPngEncoder, &testdata_8bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 8bppIndexed"); test_encoder(&testdata_24bppBGR, &CLSID_WICPngEncoder, &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 24bppBGR"); - if (!strcmp(winetest_platform, "windows")) /* FIXME: enable once implemented in Wine */ { + test_encoder(&testdata_32bppBGR, &CLSID_WICPngEncoder, + &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 32bppBGR"); +} + test_encoder(&testdata_BlackWhite, &CLSID_WICBmpEncoder, &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder BlackWhite"); test_encoder(&testdata_1bppIndexed, &CLSID_WICBmpEncoder, &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 1bppIndexed"); + test_encoder(&testdata_2bppIndexed, &CLSID_WICBmpEncoder, + &testdata_2bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 2bppIndexed"); + test_encoder(&testdata_4bppIndexed, &CLSID_WICBmpEncoder, + &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 4bppIndexed"); test_encoder(&testdata_8bppIndexed, &CLSID_WICBmpEncoder, &testdata_8bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 8bppIndexed"); -} test_encoder(&testdata_32bppBGR, &CLSID_WICBmpEncoder, &testdata_32bppBGR, &CLSID_WICBmpDecoder, "BMP encoder 32bppBGR"); test_encoder(&testdata_BlackWhite, &CLSID_WICTiffEncoder, &testdata_BlackWhite, &CLSID_WICTiffDecoder, "TIFF encoder BlackWhite"); -if (!strcmp(winetest_platform, "windows")) /* FIXME: enable once implemented in Wine */ -{ test_encoder(&testdata_1bppIndexed, &CLSID_WICTiffEncoder, &testdata_1bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 1bppIndexed"); + test_encoder(&testdata_2bppIndexed, &CLSID_WICTiffEncoder, + &testdata_2bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 2bppIndexed"); + test_encoder(&testdata_4bppIndexed, &CLSID_WICTiffEncoder, + &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 4bppIndexed"); test_encoder(&testdata_8bppIndexed, &CLSID_WICTiffEncoder, &testdata_8bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 8bppIndexed"); -} test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder, &testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR"); diff --git a/modules/rostests/winetests/windowscodecs/gifformat.c b/modules/rostests/winetests/windowscodecs/gifformat.c index 3af0a80707..53b4e473bd 100644 --- a/modules/rostests/winetests/windowscodecs/gifformat.c +++ b/modules/rostests/winetests/windowscodecs/gifformat.c @@ -16,7 +16,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> + +#define COBJMACROS + +#include "windef.h" +#include "wincodec.h" +#include "wine/test.h" HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); diff --git a/modules/rostests/winetests/windowscodecs/icoformat.c b/modules/rostests/winetests/windowscodecs/icoformat.c index c614898131..c53739dbd6 100644 --- a/modules/rostests/winetests/windowscodecs/icoformat.c +++ b/modules/rostests/winetests/windowscodecs/icoformat.c @@ -16,7 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <math.h> + +#define COBJMACROS + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" static unsigned char testico_bad_icondirentry_size[] = { /* ICONDIR */ diff --git a/modules/rostests/winetests/windowscodecs/info.c b/modules/rostests/winetests/windowscodecs/info.c index 83b729adaf..4a9c9c6e93 100644 --- a/modules/rostests/winetests/windowscodecs/info.c +++ b/modules/rostests/winetests/windowscodecs/info.c @@ -16,9 +16,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdio.h> +#include <stdarg.h> +#include <math.h> -#include <initguid.h> +#define COBJMACROS + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wincodecsdk.h" +#include "wine/test.h" + +#include "initguid.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) @@ -57,126 +67,218 @@ static BOOL is_pixelformat(GUID *format) static void test_decoder_info(void) { + struct decoder_info_test + { + const CLSID *clsid; + const char *mimetype; + const char *extensions; + unsigned int todo; + } decoder_info_tests[] = + { + { + &CLSID_WICBmpDecoder, + "image/bmp", + ".bmp,.dib,.rle" + }, + { + &CLSID_WICGifDecoder, + "image/gif", + ".gif" + }, + { + &CLSID_WICIcoDecoder, + "image/ico,image/x-icon", + ".ico,.icon", + 1 + }, + { + &CLSID_WICJpegDecoder, + "image/jpeg,image/jpe,image/jpg", + ".jpeg,.jpe,.jpg,.jfif,.exif", + 1 + }, + { + &CLSID_WICPngDecoder, + "image/png", + ".png" + }, + { + &CLSID_WICTiffDecoder, + "image/tiff,image/tif", + ".tiff,.tif", + 1 + }, + }; + IWICBitmapDecoderInfo *decoder_info, *decoder_info2; IWICComponentInfo *info; - IWICBitmapDecoderInfo *decoder_info; HRESULT hr; ULONG len; WCHAR value[256]; - const WCHAR expected_mimetype[] = {'i','m','a','g','e','/','b','m','p',0}; - const WCHAR expected_extensions[] = {'.','b','m','p',',','.','d','i','b',',','.','r','l','e',0}; CLSID clsid; - GUID pixelformats[20]; + GUID pixelformats[32]; UINT num_formats, count; - int i; - - hr = get_component_info(&CLSID_WICBmpDecoder, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); - - hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void**)&decoder_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); - ok(IsEqualGUID(&CLSID_WICBmpDecoder, &clsid), "GetCLSID returned wrong result\n"); - - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_mimetype)+1, "GetMimeType returned wrong len %i\n", len); - - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_mimetype)+1, "GetMimeType returned wrong len %i\n", len); - - value[0] = 0; - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); - ok(lstrcmpW(value, expected_mimetype) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); - ok(len == lstrlenW(expected_mimetype)+1, "GetMimeType returned wrong len %i\n", len); + int i, j; - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_mimetype)+1, "GetMimeType returned wrong len %i\n", len); - - hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); - ok(lstrcmpW(value, expected_mimetype) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); - ok(len == lstrlenW(expected_mimetype)+1, "GetMimeType returned wrong len %i\n", len); - - num_formats = 0xdeadbeef; - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, &num_formats); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); - ok(num_formats < 20 && num_formats > 1, "got %d formats\n", num_formats); - - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); - - count = 0xdeadbeef; - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); - ok(count == 0, "got %d formats\n", count); - - count = 0xdeadbeef; - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 1, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); - ok(count == 1, "got %d formats\n", count); - ok(is_pixelformat(&pixelformats[0]), "got invalid pixel format\n"); - - count = 0xdeadbeef; - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); - ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); - for (i=0; i<num_formats; i++) - ok(is_pixelformat(&pixelformats[i]), "got invalid pixel format\n"); - - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); - - count = 0xdeadbeef; - hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 20, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); - ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_extensions)+1, "GetFileExtensions returned wrong len %i\n", len); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_extensions)+1, "GetFileExtensions returned wrong len %i\n", len); - - value[0] = 0; - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - ok(lstrcmpW(value, expected_extensions) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - ok(len == lstrlenW(expected_extensions)+1, "GetFileExtensions returned wrong len %i\n", len); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%x\n", hr); - ok(len == lstrlenW(expected_extensions)+1, "GetFileExtensions returned wrong len %i\n", len); - - hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - ok(lstrcmpW(value, expected_extensions) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - ok(len == lstrlenW(expected_extensions)+1, "GetFileExtensions returned wrong len %i\n", len); - - IWICBitmapDecoderInfo_Release(decoder_info); - - IWICComponentInfo_Release(info); + for (i = 0; i < sizeof(decoder_info_tests)/sizeof(decoder_info_tests[0]); i++) + { + struct decoder_info_test *test = &decoder_info_tests[i]; + IWICBitmapDecoder *decoder, *decoder2; + WCHAR extensionsW[64]; + WCHAR mimetypeW[64]; + + hr = CoCreateInstance(test->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); + ok(SUCCEEDED(hr), "Failed to create decoder, hr %#x.\n", hr); + + decoder_info = NULL; + hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info); + ok(hr == S_OK || broken(IsEqualCLSID(&CLSID_WICBmpDecoder, test->clsid) && FAILED(hr)) /* Fails on Windows */, + "%u: failed to get decoder info, hr %#x.\n", i, hr); + + if (hr == S_OK) + { + decoder_info2 = NULL; + hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info2); + ok(hr == S_OK, "Failed to get decoder info, hr %#x.\n", hr); + todo_wine + ok(decoder_info == decoder_info2, "Unexpected decoder info instance.\n"); + + hr = IWICBitmapDecoderInfo_QueryInterface(decoder_info, &IID_IWICBitmapDecoder, (void **)&decoder2); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + + IWICBitmapDecoderInfo_Release(decoder_info); + IWICBitmapDecoderInfo_Release(decoder_info2); + } + IWICBitmapDecoder_Release(decoder); + + MultiByteToWideChar(CP_ACP, 0, test->mimetype, -1, mimetypeW, sizeof(mimetypeW)/sizeof(mimetypeW[0])); + MultiByteToWideChar(CP_ACP, 0, test->extensions, -1, extensionsW, sizeof(extensionsW)/sizeof(extensionsW[0])); + + hr = get_component_info(test->clsid, &info); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + + hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void **)&decoder_info); + ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + + hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, NULL); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + + hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, &clsid); + ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(IsEqualGUID(test->clsid, &clsid), "GetCLSID returned wrong result\n"); + + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + + len = 0; + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, NULL, &len); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + todo_wine_if(test->todo) + ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); + + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, NULL); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + + len = 0; + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, &len); + ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + todo_wine_if(test->todo) + ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); + + value[0] = 0; + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, &len); + ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + todo_wine_if(test->todo) { + ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); + ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); + } + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, value, &len); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%x\n", hr); + todo_wine_if(test->todo) + ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); + + hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 256, value, &len); + ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + todo_wine_if(test->todo) { + ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); + ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); + } + num_formats = 0xdeadbeef; + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, &num_formats); + ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok((num_formats <= 21 && num_formats >= 1) || + broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && num_formats == 0) /* WinXP */, + "%u: got %d formats\n", i, num_formats); + + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + + count = 0xdeadbeef; + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, pixelformats, &count); + ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(count == 0, "got %d formats\n", count); + + count = 0xdeadbeef; + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 1, pixelformats, &count); + ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok((count == 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && count == 0) /* WinXP */, + "%u: got %d formats\n", i, num_formats); + ok(is_pixelformat(&pixelformats[0]), "got invalid pixel format\n"); + + count = 0xdeadbeef; + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, &count); + ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); + for (j = 0; j < num_formats; j++) + ok(is_pixelformat(&pixelformats[j]), "got invalid pixel format\n"); + + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, NULL); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + + count = 0xdeadbeef; + hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, sizeof(pixelformats)/sizeof(pixelformats[0]), + pixelformats, &count); + ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, NULL, &len); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(len == lstrlenW(extensionsW) + 1, "%u: GetFileExtensions returned wrong len %i\n", i, len); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, NULL); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, &len); + ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); + + value[0] = 0; + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, &len); + ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); + todo_wine_if(test->todo) + ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, value, &len); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%x\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); + + hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 256, value, &len); + ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); + todo_wine_if(test->todo) + ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); + + IWICBitmapDecoderInfo_Release(decoder_info); + IWICComponentInfo_Release(info); + } } static void test_pixelformat_info(void) diff --git a/modules/rostests/winetests/windowscodecs/jpegformat.c b/modules/rostests/winetests/windowscodecs/jpegformat.c new file mode 100644 index 0000000000..c1e46c4869 --- /dev/null +++ b/modules/rostests/winetests/windowscodecs/jpegformat.c @@ -0,0 +1,145 @@ +/* + * 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 + */ + +#define COBJMACROS + +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" + +static const char jpeg_adobe_cmyk_1x5[] = + "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x01\x2c" + "\x01\x2c\x00\x00\xff\xee\x00\x0e\x41\x64\x6f\x62\x65\x00\x64\x00" + "\x00\x00\x00\x02\xff\xfe\x00\x13\x43\x72\x65\x61\x74\x65\x64\x20" + "\x77\x69\x74\x68\x20\x47\x49\x4d\x50\xff\xdb\x00\x43\x00\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xff\xdb" + "\x00\x43\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\xff\xc0\x00\x14\x08\x00\x05\x00\x01\x04\x01\x11\x00" + "\x02\x11\x01\x03\x11\x01\x04\x11\x00\xff\xc4\x00\x15\x00\x01\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x08" + "\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\xff\xc4\x00\x14" + "\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xff\xda\x00\x0e\x04\x01\x00\x02\x11\x03\x11\x04\x00\x00" + "\x3f\x00\x40\x44\x02\x1e\xa4\x1f\xff\xd9"; + +static void test_decode_adobe_cmyk(void) +{ + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + HRESULT hr; + HGLOBAL hjpegdata; + char *jpegdata; + IStream *jpegstream; + GUID guidresult; + UINT count=0, width=0, height=0; + BYTE imagedata[5 * 4] = {1}; + UINT i; + + const BYTE expected_imagedata[5 * 4] = { + 0x00, 0xb0, 0xfc, 0x6d, + 0x00, 0xb0, 0xfc, 0x6d, + 0x00, 0xb0, 0xfc, 0x6d, + 0x00, 0xb0, 0xfc, 0x6d, + 0x00, 0xb0, 0xfc, 0x6d, + }; + + const BYTE expected_imagedata_24bpp[5 * 4] = { + 0x0d, 0x4b, 0x94, 0x00, + 0x0d, 0x4b, 0x94, 0x00, + 0x0d, 0x4b, 0x94, 0x00, + 0x0d, 0x4b, 0x94, 0x00, + 0x0d, 0x4b, 0x94, 0x00, + }; + + hr = CoCreateInstance(&CLSID_WICJpegDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void**)&decoder); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + if (FAILED(hr)) return; + + hjpegdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(jpeg_adobe_cmyk_1x5)); + ok(hjpegdata != 0, "GlobalAlloc failed\n"); + if (hjpegdata) + { + jpegdata = GlobalLock(hjpegdata); + memcpy(jpegdata, jpeg_adobe_cmyk_1x5, sizeof(jpeg_adobe_cmyk_1x5)); + GlobalUnlock(hjpegdata); + + hr = CreateStreamOnHGlobal(hjpegdata, FALSE, &jpegstream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_Initialize(decoder, jpegstream, WICDecodeMetadataCacheOnLoad); + ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatJpeg), "unexpected container format\n"); + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(count == 1, "unexpected count %u\n", count); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); + ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(width == 1, "expected width=1, got %u\n", width); + ok(height == 5, "expected height=5, got %u\n", height); + + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppCMYK) || + broken(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR)), /* xp/2003 */ + "unexpected pixel format: %s\n", wine_dbgstr_guid(&guidresult)); + + /* We want to be sure our state tracking will not impact output + * data on subsequent calls */ + for(i=2; i>0; --i) + { + hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 4, sizeof(imagedata), imagedata); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)) || + broken(!memcmp(imagedata, expected_imagedata_24bpp, sizeof(expected_imagedata))), /* xp/2003 */ + "unexpected image data\n"); + } + IWICBitmapFrameDecode_Release(framedecode); + } + IStream_Release(jpegstream); + } + GlobalFree(hjpegdata); + } + IWICBitmapDecoder_Release(decoder); +} + + +START_TEST(jpegformat) +{ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + test_decode_adobe_cmyk(); + + CoUninitialize(); +} diff --git a/modules/rostests/winetests/windowscodecs/metadata.c b/modules/rostests/winetests/windowscodecs/metadata.c index 9de1c4d31e..1d4203d5cf 100644 --- a/modules/rostests/winetests/windowscodecs/metadata.c +++ b/modules/rostests/winetests/windowscodecs/metadata.c @@ -17,12 +17,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdio.h> +#include <stdarg.h> +#include <math.h> +#include <assert.h> -#include <winnls.h> -#include <propvarutil.h> +#define COBJMACROS -#include <initguid.h> +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wincodecsdk.h" +#include "propvarutil.h" +#include "wine/test.h" + +#include "initguid.h" DEFINE_GUID(IID_MdbrUnknown, 0x00240e6f,0x3f23,0x4432,0xb0,0xcc,0x48,0xd5,0xbb,0xff,0x6c,0x36); #define expect_blob(propvar, data, length) do { \ diff --git a/modules/rostests/winetests/windowscodecs/palette.c b/modules/rostests/winetests/windowscodecs/palette.c index 9031556f53..33fd119f65 100644 --- a/modules/rostests/winetests/windowscodecs/palette.c +++ b/modules/rostests/winetests/windowscodecs/palette.c @@ -1,6 +1,6 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers - * 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 @@ -17,11 +17,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <assert.h> + +#define COBJMACROS + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" + +static IWICImagingFactory *factory; static void test_custom_palette(void) { - IWICImagingFactory *factory; IWICPalette *palette, *palette2; HRESULT hr; WICBitmapPaletteType type=0xffffffff; @@ -30,11 +39,6 @@ static void test_custom_palette(void) WICColor colors[4]; BOOL boolresult; - hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); - if (FAILED(hr)) return; - hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); if (SUCCEEDED(hr)) @@ -199,8 +203,6 @@ static void test_custom_palette(void) IWICPalette_Release(palette2); IWICPalette_Release(palette); } - - IWICImagingFactory_Release(factory); } static void generate_gray16_palette(DWORD *entries, UINT count) @@ -443,7 +445,6 @@ static void test_predefined_palette(void) { WICBitmapPaletteTypeFixedHalftone256, 0, 0, 256, { 0 } }, { WICBitmapPaletteTypeFixedHalftone256, 0, 0, 256, { 0 }, 1 } }; - IWICImagingFactory *factory; IWICPalette *palette; HRESULT hr; WICBitmapPaletteType type; @@ -451,10 +452,6 @@ static void test_predefined_palette(void) BOOL bret; WICColor color[256]; - hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); - hr = IWICImagingFactory_CreatePalette(factory, &palette); ok(hr == S_OK, "CreatePalette error %#x\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeCustom, FALSE); @@ -530,16 +527,136 @@ static void test_predefined_palette(void) IWICPalette_Release(palette); } +} - IWICImagingFactory_Release(factory); +static BYTE *init_bitmap(UINT *width, UINT *height, UINT *stride) +{ + BYTE *src; + UINT i, j, scale; + + *width = 256; + *height = 256; + *stride = (*width * 3 + 3) & ~3; + trace("width %d, height %d, stride %d\n", *width, *height, *stride); + + src = HeapAlloc(GetProcessHeap(), 0, *stride * *height); + + scale = 256 / *width; + if (!scale) scale = 1; + + for (i = 0; i < *height; i++) + { + for (j = 0; j < *width; j++) + { + src[i * *stride + j*3 + 0] = scale * i; + src[i * *stride + j*3 + 1] = scale * (255 - (i+j)/2); + src[i * *stride + j*3 + 2] = scale * j; + } + } + + return src; +} + +static void test_palette_from_bitmap(void) +{ + HRESULT hr; + BYTE *data; + IWICBitmap *bitmap; + IWICPalette *palette; + WICBitmapPaletteType type; + UINT width, height, stride, count, ret; + WICColor color[257]; + + data = init_bitmap(&width, &height, &stride); + + hr = IWICImagingFactory_CreateBitmapFromMemory(factory, width, height, &GUID_WICPixelFormat24bppRGB, + stride, stride * height, data, &bitmap); + ok(hr == S_OK, "CreateBitmapFromMemory error %#x\n", hr); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#x\n", hr); + + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 0, FALSE); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 1, FALSE); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 257, FALSE); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = IWICPalette_InitializeFromBitmap(palette, NULL, 16, FALSE); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, FALSE); + ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + count = 0; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, TRUE); + ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + count = 0; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 2, "expected 2, got %u\n", count); + + /* without trasparent color */ + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, FALSE); + ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + type = -1; + hr = IWICPalette_GetType(palette, &type); + ok(hr == S_OK, "GetType error %#x\n", hr); + ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); + count = 0; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 16, "expected 16, got %u\n", count); + memset(color, 0, sizeof(color)); + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[count - 1] != 0, "expected !0, got %08x\n", color[count - 1]); + + /* with trasparent color */ + hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, TRUE); + ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + type = -1; + hr = IWICPalette_GetType(palette, &type); + ok(hr == S_OK, "GetType error %#x\n", hr); + ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); + count = 0; + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(count == 16, "expected 16, got %u\n", count); + memset(color, 0xff, sizeof(color)); + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[count - 1] == 0, "expected 0, got %08x\n", color[count - 1]); + + IWICPalette_Release(palette); + IWICBitmap_Release(bitmap); + + HeapFree(GetProcessHeap(), 0, data); } START_TEST(palette) { + HRESULT hr; + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + test_custom_palette(); test_predefined_palette(); + test_palette_from_bitmap(); + + IWICImagingFactory_Release(factory); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/pngformat.c b/modules/rostests/winetests/windowscodecs/pngformat.c index 22f77936c7..3a0ea28ead 100644 --- a/modules/rostests/winetests/windowscodecs/pngformat.c +++ b/modules/rostests/winetests/windowscodecs/pngformat.c @@ -17,9 +17,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> -#include <shlwapi.h> +#define COBJMACROS + +#include "windef.h" +#include "wincodec.h" +#include "wine/test.h" +#include "shlwapi.h" /* 1x1 pixel PNG image */ static const char png_no_color_profile[] = { @@ -720,7 +726,6 @@ static void test_color_formats(void) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) -todo_wine ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) @@ -749,7 +754,6 @@ next_1: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) -todo_wine ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) @@ -778,7 +782,6 @@ next_2: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) -todo_wine ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) @@ -806,7 +809,6 @@ next_3: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) -todo_wine ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); else todo_wine_if(td[i].todo_load) diff --git a/modules/rostests/winetests/windowscodecs/precomp.h b/modules/rostests/winetests/windowscodecs/precomp.h index 59d037ab1f..b5ae868f5e 100644 --- a/modules/rostests/winetests/windowscodecs/precomp.h +++ b/modules/rostests/winetests/windowscodecs/precomp.h @@ -1,3 +1,4 @@ + #ifndef _WINDOWSCODECS_WINETEST_PRECOMP_H_ #define _WINDOWSCODECS_WINETEST_PRECOMP_H_ @@ -16,7 +17,8 @@ #include <wingdi.h> #include <winreg.h> +#include <winnls.h> #include <ole2.h> #include <wincodecsdk.h> -#endif /* _WINDOWSCODECS_WINETEST_PRECOMP_H_ */ +#endif /* !_WINDOWSCODECS_WINETEST_PRECOMP_H_ */ diff --git a/modules/rostests/winetests/windowscodecs/propertybag.c b/modules/rostests/winetests/windowscodecs/propertybag.c index b0a3bd3415..fd57073d91 100644 --- a/modules/rostests/winetests/windowscodecs/propertybag.c +++ b/modules/rostests/winetests/windowscodecs/propertybag.c @@ -16,7 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <stdarg.h> +#include <math.h> + +#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}; diff --git a/modules/rostests/winetests/windowscodecs/stream.c b/modules/rostests/winetests/windowscodecs/stream.c index 70807aab64..5f311b897b 100644 --- a/modules/rostests/winetests/windowscodecs/stream.c +++ b/modules/rostests/winetests/windowscodecs/stream.c @@ -16,7 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "wine/test.h" + +#define COBJMACROS +#include "wincodec.h" static void test_StreamOnMemory(void) { diff --git a/modules/rostests/winetests/windowscodecs/testlist.c b/modules/rostests/winetests/windowscodecs/testlist.c index 588446a013..6ea28ad82b 100644 --- a/modules/rostests/winetests/windowscodecs/testlist.c +++ b/modules/rostests/winetests/windowscodecs/testlist.c @@ -9,6 +9,7 @@ extern void func_converter(void); extern void func_gifformat(void); extern void func_icoformat(void); extern void func_info(void); +extern void func_jpegformat(void); extern void func_metadata(void); extern void func_palette(void); extern void func_pngformat(void); @@ -24,6 +25,7 @@ const struct test winetest_testlist[] = { "gifformat", func_gifformat }, { "icoformat", func_icoformat }, { "info", func_info }, + { "jpegformat", func_jpegformat }, { "metadata", func_metadata }, { "palette", func_palette }, { "pngformat", func_pngformat }, diff --git a/modules/rostests/winetests/windowscodecs/tiffformat.c b/modules/rostests/winetests/windowscodecs/tiffformat.c index e529a44a58..5671dfbfbc 100644 --- a/modules/rostests/winetests/windowscodecs/tiffformat.c +++ b/modules/rostests/winetests/windowscodecs/tiffformat.c @@ -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 @@ -16,7 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include <math.h> +#include <stdarg.h> +#include <stdio.h> + +#define COBJMACROS + +#include "windef.h" +#include "wincodec.h" +#include "wine/test.h" #define IFD_BYTE 1 #define IFD_ASCII 2 @@ -77,8 +85,8 @@ static const struct tiff_1bpp_data { 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_1bpp_data, res) }, - { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, + { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* XRESOLUTION */ + { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* YRESOLUTION */ { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ }, 0, @@ -117,8 +125,8 @@ static const struct tiff_8bpp_alpha { 0x115, IFD_SHORT, 1, 2 }, /* SAMPLESPERPIXEL */ { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */ { 0x117, IFD_LONG, 1, 8 }, /* STRIPBYTECOUNT */ - { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, - { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, + { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* XRESOLUTION */ + { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* YRESOLUTION */ { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */ { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */ @@ -127,6 +135,124 @@ static const struct tiff_8bpp_alpha { 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 } +}; + +static const struct tiff_resolution_test_data +{ + struct IFD_rational resx; + struct IFD_rational resy; + LONG resolution_unit; + double expected_dpi_x; + double expected_dpi_y; + /* if != 0: values for different behavior of some Windows versions */ + double broken_dpi_x; + double broken_dpi_y; +} tiff_resolution_test_data[] = +{ + { { 100, 1 }, { 50, 1 }, 0, 100.0, 50.0, 0, 0 }, /* invalid resolution unit */ + { { 50, 1 }, { 100, 1 }, 0, 50.0, 100.0, 0, 0 }, + + { { 100, 1 }, { 50, 1 }, 1, 100.0, 50.0, 0, 0 }, /* RESUNIT_NONE */ + { { 50, 1 }, { 100, 1 }, 1, 50.0, 100.0, 0, 0 }, + + { { 49, 1 }, { 49, 1 }, 2, 49.0, 49.0, 0, 0 }, /* same resolution for both X and Y */ + { { 33, 1 }, { 55, 1 }, 2, 33.0, 55.0, 0, 0 }, /* different resolutions for X and Y */ + { { 50, 2 }, { 66, 3 }, 2, 25.0, 22.0, 0, 0 }, /* denominator != 1 */ + + { { 100, 1 }, { 200, 1 }, 3, 254.0, 508.0, 0, 0 }, /* unit = centimeters */ + + /* XP and Server 2003 do not discard both resolution values if only one of them is invalid */ + { { 0, 1 }, { 29, 1 }, 2, 96.0, 96.0, 0, 29.0 }, /* resolution 0 */ + { { 58, 1 }, { 29, 0 }, 2, 96.0, 96.0, 58.0, 0 }, /* denominator 0 (division by zero) */ + + /* XP and Server 2003 return 96 dots per centimeter (= 243.84 dpi) as fallback value */ + { { 0, 1 }, { 100, 1 }, 3, 96.0, 96.0, 243.84, 254.0 }, /* resolution 0 and unit = centimeters */ + { { 50, 1 }, { 72, 0 }, 3, 96.0, 96.0, 127.0, 243.84 } /* denominator 0 and unit = centimeters */ +}; + +static struct tiff_resolution_image_data +{ + USHORT byte_order; + USHORT version; + ULONG dir_offset; + USHORT number_of_entries; + struct IFD_entry entry[13]; + ULONG next_IFD; + struct IFD_rational resx; + struct IFD_rational resy; + BYTE pixel_data[4]; +} tiff_resolution_image_data = +{ +#ifdef WORDS_BIGENDIAN + 'M' | 'M' << 8, +#else + 'I' | 'I' << 8, +#endif + 42, + FIELD_OFFSET(struct tiff_resolution_image_data, number_of_entries), + 13, + { + { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ + { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ + { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */ + { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ + { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */ + { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_resolution_image_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_resolution_image_data, resx) }, /* XRESOLUTION */ + { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_resolution_image_data, resy) }, /* YRESOLUTION */ + { 0x128, IFD_SHORT, 1, 1 }, /* RESOLUTIONUNIT -- value will be filled with test data */ + }, + 0, + { 72, 1 }, /* value will be filled with test data */ + { 72, 1 }, /* value will be filled with test data */ + { 0x11, 0x22, 0x33, 0 } +}; #include "poppack.h" static IWICImagingFactory *factory; @@ -152,29 +278,96 @@ static IStream *create_stream(const void *data, int data_size) 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; + GUID format; + LONG refcount; - stream = create_stream(image_data, image_size); + *decoder = NULL; - hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); - if (FAILED(hr)) return NULL; + hmem = GlobalAlloc(0, image_size); + data = GlobalLock(hmem); + memcpy(data, image_data, image_size); + GlobalUnlock(hmem); - 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"); + hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); - IStream_Release(stream); + 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)); - return decoder; + refcount = IStream_Release(stream); + ok(refcount > 0, "expected stream refcount > 0\n"); + } + + return hr; } -static void test_tiff_palette(void) +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; @@ -182,9 +375,9 @@ static void test_tiff_palette(void) 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); @@ -316,9 +509,9 @@ static void test_tiff_8bpp_alpha(void) 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); @@ -363,6 +556,516 @@ static void test_tiff_8bpp_alpha(void) 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); +} + +static void test_tiff_resolution(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + double dpi_x, dpi_y; + int i; + + for (i = 0; i < sizeof(tiff_resolution_test_data)/sizeof(tiff_resolution_test_data[0]); i++) + { + const struct tiff_resolution_test_data *test_data = &tiff_resolution_test_data[i]; + tiff_resolution_image_data.resx = test_data->resx; + tiff_resolution_image_data.resy = test_data->resy; + tiff_resolution_image_data.entry[12].value = test_data->resolution_unit; + + hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_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, "%d: GetFrame error %#x\n", i, hr); + + hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); + ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr); + + if (test_data->broken_dpi_x != 0) + { + ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01 || broken(fabs(dpi_x - test_data->broken_dpi_x) < 0.01), + "%d: x: expected %f or %f, got %f\n", i, test_data->expected_dpi_x, test_data->broken_dpi_x, dpi_x); + } + else + { + ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01, + "%d: x: expected %f, got %f\n", i, test_data->expected_dpi_x, dpi_x); + } + + if (test_data->broken_dpi_y != 0) + { + ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01 || broken(fabs(dpi_y - test_data->broken_dpi_y) < 0.01), + "%d: y: expected %f or %f, got %f\n", i, test_data->expected_dpi_y, test_data->broken_dpi_y, dpi_y); + } + else + { + ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01, + "%d: y: expected %f, got %f\n", i, test_data->expected_dpi_y, dpi_y); + } + + 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; @@ -374,9 +1077,12 @@ START_TEST(tiffformat) 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(); + test_tiff_resolution(); IWICImagingFactory_Release(factory); CoUninitialize();
6 years, 9 months
1
0
0
0
01/01: [WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ae80686d816b6383d5e46…
commit ae80686d816b6383d5e46b90ced89b680b62642d Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Mar 5 00:19:05 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Mar 5 00:19:05 2018 +0100 [WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434 --- dll/win32/windowscodecs/CMakeLists.txt | 15 +- dll/win32/windowscodecs/bitmap.c | 225 ++++- dll/win32/windowscodecs/bmpdecode.c | 19 +- dll/win32/windowscodecs/bmpencode.c | 112 ++- dll/win32/windowscodecs/clipper.c | 12 + dll/win32/windowscodecs/clsfactory.c | 18 + dll/win32/windowscodecs/colorcontext.c | 14 + dll/win32/windowscodecs/colortransform.c | 14 + dll/win32/windowscodecs/converter.c | 269 ++++- dll/win32/windowscodecs/fliprotate.c | 14 + dll/win32/windowscodecs/gifformat.c | 1034 +++++++++++++++++++- dll/win32/windowscodecs/icnsformat.c | 25 +- dll/win32/windowscodecs/icoformat.c | 19 +- dll/win32/windowscodecs/imgfactory.c | 131 ++- dll/win32/windowscodecs/info.c | 37 +- dll/win32/windowscodecs/jpegformat.c | 99 +- dll/win32/windowscodecs/main.c | 14 + dll/win32/windowscodecs/metadatahandler.c | 67 +- dll/win32/windowscodecs/metadataquery.c | 16 +- dll/win32/windowscodecs/palette.c | 294 +++++- dll/win32/windowscodecs/pngformat.c | 74 +- dll/win32/windowscodecs/precomp.h | 30 + dll/win32/windowscodecs/propertybag.c | 19 +- dll/win32/windowscodecs/proxy.c | 14 + dll/win32/windowscodecs/regsvr.c | 132 ++- dll/win32/windowscodecs/scaler.c | 183 ++++ dll/win32/windowscodecs/stream.c | 10 +- dll/win32/windowscodecs/tgaformat.c | 16 + dll/win32/windowscodecs/tiffformat.c | 425 ++++++-- dll/win32/windowscodecs/ungif.c | 9 +- dll/win32/windowscodecs/wincodecs_private.h | 110 ++- dll/win32/windowscodecs/windowscodecs.spec | 3 +- dll/win32/windowscodecs/windowscodecs_wincodec.idl | 7 + media/doc/README.WINE | 2 +- 34 files changed, 3107 insertions(+), 375 deletions(-) diff --git a/dll/win32/windowscodecs/CMakeLists.txt b/dll/win32/windowscodecs/CMakeLists.txt index 7ed058d112..6c67bfe1a9 100644 --- a/dll/win32/windowscodecs/CMakeLists.txt +++ b/dll/win32/windowscodecs/CMakeLists.txt @@ -23,7 +23,6 @@ spec2def(windowscodecs.dll windowscodecs.spec ADD_IMPORTLIB) add_rpcproxy_files(windowscodecs_wincodec.idl) list(APPEND SOURCE - bitmap.c bmpdecode.c bmpencode.c clipper.c @@ -51,7 +50,17 @@ list(APPEND SOURCE tgaformat.c tiffformat.c ungif.c - wincodecs_private.h) + precomp.h) + +if(MSVC) + if(ARCH STREQUAL "i386") + list(APPEND SOURCE msvc-thiscall.c) + endif() + set_source_files_properties(bitmap.c PROPERTIES COMPILE_FLAGS "/FImsvc.h") + list(APPEND ADDITIONAL_SOURCE bitmap.c) +else() + list(APPEND SOURCE bitmap.c) +endif() list(APPEND ADDITIONAL_SOURCE guid.c @@ -68,5 +77,5 @@ add_library(windowscodecs SHARED set_module_type(windowscodecs win32dll) target_link_libraries(windowscodecs wine uuid ${PSEH_LIB}) add_importlibs(windowscodecs ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll) -add_pch(windowscodecs wincodecs_private.h SOURCE) +add_pch(windowscodecs precomp.h SOURCE) add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/windowscodecs/bitmap.c b/dll/win32/windowscodecs/bitmap.c index dfd7dda89f..69ec14fed2 100644 --- a/dll/win32/windowscodecs/bitmap.c +++ b/dll/win32/windowscodecs/bitmap.c @@ -16,8 +16,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + /* WARNING: .NET Media Integration Layer (MIL) directly dereferences * BitmapImpl members and depends on its exact layout. */ @@ -31,6 +45,7 @@ typedef struct BitmapImpl { int palette_set; LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */ BYTE *data; + BOOL is_section; /* TRUE if data is a section created by an application */ UINT width, height; UINT stride; UINT bpp; @@ -121,6 +136,7 @@ static HRESULT WINAPI BitmapLockImpl_QueryInterface(IWICBitmapLock *iface, REFII } else { + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -234,12 +250,14 @@ static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid, { *ppv = &This->IWICBitmap_iface; } - else if (IsEqualIID(&IID_IMILBitmapSource, iid)) + else if (IsEqualIID(&IID_IMILBitmap, iid) || + IsEqualIID(&IID_IMILBitmapSource, iid)) { *ppv = &This->IMILBitmapSource_iface; } else { + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -270,7 +288,10 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface) if (This->palette) IWICPalette_Release(This->palette); This->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->cs); - HeapFree(GetProcessHeap(), 0, This->data); + if (This->is_section) + UnmapViewOfFile(This->data); + else + HeapFree(GetProcessHeap(), 0, This->data); HeapFree(GetProcessHeap(), 0, This); } @@ -465,13 +486,22 @@ static HRESULT WINAPI IMILBitmapImpl_QueryInterface(IMILBitmapSource *iface, REF if (!ppv) return E_INVALIDARG; if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IMILBitmap, iid) || IsEqualIID(&IID_IMILBitmapSource, iid)) { IUnknown_AddRef(&This->IMILBitmapSource_iface); *ppv = &This->IMILBitmapSource_iface; return S_OK; } + else if (IsEqualIID(&IID_IWICBitmap, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid)) + { + IUnknown_AddRef(&This->IWICBitmap_iface); + *ppv = &This->IWICBitmap_iface; + return S_OK; + } + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -492,6 +522,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetSize(IMILBitmapSource *iface, UINT *width, UINT *height) { BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p,%p)\n", iface, width, height); return IWICBitmap_GetSize(&This->IWICBitmap_iface, width, height); } @@ -545,6 +576,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetPixelFormat(IMILBitmapSource *iface, } } + TRACE("=> %u\n", *format); return S_OK; } @@ -552,6 +584,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetResolution(IMILBitmapSource *iface, double *dpix, double *dpiy) { BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p,%p)\n", iface, dpix, dpiy); return IWICBitmap_GetResolution(&This->IWICBitmap_iface, dpix, dpiy); } @@ -559,6 +592,7 @@ static HRESULT WINAPI IMILBitmapImpl_CopyPalette(IMILBitmapSource *iface, IWICPalette *palette) { BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p)\n", iface, palette); return IWICBitmap_CopyPalette(&This->IWICBitmap_iface, palette); } @@ -566,10 +600,11 @@ static HRESULT WINAPI IMILBitmapImpl_CopyPixels(IMILBitmapSource *iface, const WICRect *rc, UINT stride, UINT size, BYTE *buffer) { BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p,%u,%u,%p)\n", iface, rc, stride, size, buffer); return IWICBitmap_CopyPixels(&This->IWICBitmap_iface, rc, stride, size, buffer); } -static HRESULT WINAPI IMILBitmapImpl_UnknownMethod1(IMILBitmapSource *iface, void **ppv) +static HRESULT WINAPI IMILBitmapImpl_unknown1(IMILBitmapSource *iface, void **ppv) { BitmapImpl *This = impl_from_IMILBitmapSource(iface); @@ -577,12 +612,46 @@ static HRESULT WINAPI IMILBitmapImpl_UnknownMethod1(IMILBitmapSource *iface, voi if (!ppv) return E_INVALIDARG; - IUnknown_AddRef(&This->IMILUnknown1_iface); + /* reference count is not incremented here */ *ppv = &This->IMILUnknown1_iface; return S_OK; } +static HRESULT WINAPI IMILBitmapImpl_Lock(IMILBitmapSource *iface, const WICRect *rc, DWORD flags, IWICBitmapLock **lock) +{ + BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p,%08x,%p)\n", iface, rc, flags, lock); + return IWICBitmap_Lock(&This->IWICBitmap_iface, rc, flags, lock); +} + +static HRESULT WINAPI IMILBitmapImpl_Unlock(IMILBitmapSource *iface, IWICBitmapLock *lock) +{ + TRACE("(%p,%p)\n", iface, lock); + IWICBitmapLock_Release(lock); + return S_OK; +} + +static HRESULT WINAPI IMILBitmapImpl_SetPalette(IMILBitmapSource *iface, IWICPalette *palette) +{ + BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%p)\n", iface, palette); + return IWICBitmap_SetPalette(&This->IWICBitmap_iface, palette); +} + +static HRESULT WINAPI IMILBitmapImpl_SetResolution(IMILBitmapSource *iface, double dpix, double dpiy) +{ + BitmapImpl *This = impl_from_IMILBitmapSource(iface); + TRACE("(%p,%f,%f)\n", iface, dpix, dpiy); + return IWICBitmap_SetResolution(&This->IWICBitmap_iface, dpix, dpiy); +} + +static HRESULT WINAPI IMILBitmapImpl_AddDirtyRect(IMILBitmapSource *iface, const WICRect *rc) +{ + FIXME("(%p,%p): stub\n", iface, rc); + return E_NOTIMPL; +} + static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl = { IMILBitmapImpl_QueryInterface, @@ -593,26 +662,20 @@ static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl = IMILBitmapImpl_GetResolution, IMILBitmapImpl_CopyPalette, IMILBitmapImpl_CopyPixels, - IMILBitmapImpl_UnknownMethod1, + IMILBitmapImpl_unknown1, + IMILBitmapImpl_Lock, + IMILBitmapImpl_Unlock, + IMILBitmapImpl_SetPalette, + IMILBitmapImpl_SetResolution, + IMILBitmapImpl_AddDirtyRect }; static HRESULT WINAPI IMILUnknown1Impl_QueryInterface(IMILUnknown1 *iface, REFIID iid, void **ppv) { - BitmapImpl *This = impl_from_IMILUnknown1(iface); - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid)) - { - IUnknown_AddRef(&This->IMILUnknown1_iface); - *ppv = iface; - return S_OK; - } - - return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv); + FIXME("(%p,%s,%p): stub\n", iface, debugstr_guid(iid), ppv); + *ppv = NULL; + return E_NOINTERFACE; } static ULONG WINAPI IMILUnknown1Impl_AddRef(IMILUnknown1 *iface) @@ -627,66 +690,128 @@ static ULONG WINAPI IMILUnknown1Impl_Release(IMILUnknown1 *iface) return IWICBitmap_Release(&This->IWICBitmap_iface); } +DECLSPEC_HIDDEN void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg) +{ + FIXME("(%p,%p): stub\n", iface, arg); +} + +static HRESULT WINAPI IMILUnknown1Impl_unknown2(IMILUnknown1 *iface, void *arg1, void *arg2) +{ + FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2); + return E_NOTIMPL; +} + +DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg) +{ + FIXME("(%p,%p): stub\n", iface, arg); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMILUnknown1Impl_unknown4(IMILUnknown1 *iface, void *arg) +{ + FIXME("(%p,%p): stub\n", iface, arg); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMILUnknown1Impl_unknown5(IMILUnknown1 *iface, void *arg) +{ + FIXME("(%p,%p): stub\n", iface, arg); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMILUnknown1Impl_unknown6(IMILUnknown1 *iface, DWORD64 arg) +{ + FIXME("(%p,%s): stub\n", iface, wine_dbgstr_longlong(arg)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMILUnknown1Impl_unknown7(IMILUnknown1 *iface, void *arg) +{ + FIXME("(%p,%p): stub\n", iface, arg); + return E_NOTIMPL; +} + +DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown1, 8) +DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown3, 8) +DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown8, 4) + static const IMILUnknown1Vtbl IMILUnknown1Impl_Vtbl = { IMILUnknown1Impl_QueryInterface, IMILUnknown1Impl_AddRef, IMILUnknown1Impl_Release, + THISCALL(IMILUnknown1Impl_unknown1), + IMILUnknown1Impl_unknown2, + THISCALL(IMILUnknown1Impl_unknown3), + IMILUnknown1Impl_unknown4, + IMILUnknown1Impl_unknown5, + IMILUnknown1Impl_unknown6, + IMILUnknown1Impl_unknown7, + THISCALL(IMILUnknown1Impl_unknown8) }; static HRESULT WINAPI IMILUnknown2Impl_QueryInterface(IMILUnknown2 *iface, REFIID iid, void **ppv) { - BitmapImpl *This = impl_from_IMILUnknown2(iface); - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid)) - { - IUnknown_AddRef(&This->IMILUnknown2_iface); - *ppv = iface; - return S_OK; - } - - return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv); + FIXME("(%p,%s,%p): stub\n", iface, debugstr_guid(iid), ppv); + *ppv = NULL; + return E_NOINTERFACE; } static ULONG WINAPI IMILUnknown2Impl_AddRef(IMILUnknown2 *iface) { - BitmapImpl *This = impl_from_IMILUnknown2(iface); - return IWICBitmap_AddRef(&This->IWICBitmap_iface); + FIXME("(%p): stub\n", iface); + return 0; } static ULONG WINAPI IMILUnknown2Impl_Release(IMILUnknown2 *iface) { - BitmapImpl *This = impl_from_IMILUnknown2(iface); - return IWICBitmap_Release(&This->IWICBitmap_iface); + FIXME("(%p): stub\n", iface); + return 0; +} + +static HRESULT WINAPI IMILUnknown2Impl_unknown1(IMILUnknown2 *iface, void *arg1, void **arg2) +{ + FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2); + if (arg2) *arg2 = NULL; + return E_NOTIMPL; } -static HRESULT WINAPI IMILUnknown2Impl_UnknownMethod1(IMILUnknown2 *iface, void *arg1, void *arg2) +static HRESULT WINAPI IMILUnknown2Impl_unknown2(IMILUnknown2 *iface, void *arg1, void *arg2) { FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2); return E_NOTIMPL; } +static HRESULT WINAPI IMILUnknown2Impl_unknown3(IMILUnknown2 *iface, void *arg1) +{ + FIXME("(%p,%p): stub\n", iface, arg1); + return E_NOTIMPL; +} + static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl = { IMILUnknown2Impl_QueryInterface, IMILUnknown2Impl_AddRef, IMILUnknown2Impl_Release, - IMILUnknown2Impl_UnknownMethod1, + IMILUnknown2Impl_unknown1, + IMILUnknown2Impl_unknown2, + IMILUnknown2Impl_unknown3 }; HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, - UINT stride, UINT datasize, BYTE *bits, + UINT stride, UINT datasize, BYTE *data, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) { HRESULT hr; BitmapImpl *This; - BYTE *data; UINT bpp; hr = get_pixelformat_bpp(pixelFormat, &bpp); @@ -699,14 +824,20 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG; This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl)); - data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize); - if (!This || !data) + if (!This) return E_OUTOFMEMORY; + + if (!data) { - HeapFree(GetProcessHeap(), 0, This); - HeapFree(GetProcessHeap(), 0, data); - return E_OUTOFMEMORY; + data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize); + if (!data) + { + HeapFree(GetProcessHeap(), 0, This); + return E_OUTOFMEMORY; + } + This->is_section = FALSE; } - if (bits) memcpy(data, bits, datasize); + else + This->is_section = TRUE; This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl; This->IMILBitmapSource_iface.lpVtbl = &IMILBitmapImpl_Vtbl; diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c index 5039694a76..47f312ffcf 100644 --- a/dll/win32/windowscodecs/bmpdecode.c +++ b/dll/win32/windowscodecs/bmpdecode.c @@ -16,9 +16,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" #include <assert.h> +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); typedef struct { DWORD bc2Size; @@ -256,7 +271,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, if (This->bih.bV5ClrUsed == 0) count = 1 << This->bih.bV5BitCount; else - count = This->bih.bV5ClrUsed; + count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount); tablesize = sizeof(WICColor) * count; wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); diff --git a/dll/win32/windowscodecs/bmpencode.c b/dll/win32/windowscodecs/bmpencode.c index e339324015..cb8b4897e4 100644 --- a/dll/win32/windowscodecs/bmpencode.c +++ b/dll/win32/windowscodecs/bmpencode.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 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 @@ -16,13 +17,28 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "objbase.h" + #include "wincodecs_private.h" -#include <wingdi.h> +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); struct bmp_pixelformat { const WICPixelFormatGUID *guid; UINT bpp; + UINT colors; /* palette size */ DWORD compression; DWORD redmask; DWORD greenmask; @@ -31,13 +47,18 @@ struct bmp_pixelformat { }; static const struct bmp_pixelformat formats[] = { - {&GUID_WICPixelFormat24bppBGR, 24, BI_RGB}, - {&GUID_WICPixelFormat16bppBGR555, 16, BI_RGB}, - {&GUID_WICPixelFormat16bppBGR565, 16, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0}, - {&GUID_WICPixelFormat32bppBGR, 32, BI_RGB}, + {&GUID_WICPixelFormat24bppBGR, 24, 0, BI_RGB}, + {&GUID_WICPixelFormatBlackWhite, 1, 2, BI_RGB}, + {&GUID_WICPixelFormat1bppIndexed, 1, 2, BI_RGB}, + {&GUID_WICPixelFormat2bppIndexed, 2, 4, BI_RGB}, + {&GUID_WICPixelFormat4bppIndexed, 4, 16, BI_RGB}, + {&GUID_WICPixelFormat8bppIndexed, 8, 256, BI_RGB}, + {&GUID_WICPixelFormat16bppBGR555, 16, 0, BI_RGB}, + {&GUID_WICPixelFormat16bppBGR565, 16, 0, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0}, + {&GUID_WICPixelFormat32bppBGR, 32, 0, BI_RGB}, #if 0 /* Windows doesn't seem to support this one. */ - {&GUID_WICPixelFormat32bppBGRA, 32, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000}, + {&GUID_WICPixelFormat32bppBGRA, 32, 0, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000}, #endif {NULL} }; @@ -58,6 +79,8 @@ typedef struct BmpFrameEncode { BOOL committed; } BmpFrameEncode; +static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0}; + static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) { return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface); @@ -121,6 +144,9 @@ static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface, if (This->initialized) return WINCODEC_ERR_WRONGSTATE; + if (pIEncoderOptions) + WARN("ignoring encoder options.\n"); + This->initialized = TRUE; return S_OK; @@ -165,11 +191,13 @@ static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface for (i=0; formats[i].guid; i++) { - if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) + if (IsEqualGUID(formats[i].guid, pPixelFormat)) break; } if (!formats[i].guid) i = 0; + else if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormatBlackWhite)) + i = 2; /* GUID_WICPixelFormat1bppIndexed */ This->format = &formats[i]; memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); @@ -188,6 +216,7 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette *palette) { BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; TRACE("(%p,%p)\n", iface, palette); @@ -196,7 +225,14 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED; - return IWICPalette_GetColors(palette, 256, This->palette, &This->colors); + hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); + if (hr == S_OK) + { + UINT i; + for (i = 0; i < This->colors; i++) + This->palette[i] |= 0xff000000; /* BMP palette has no alpha */ + } + return hr; } static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, @@ -278,10 +314,11 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); BITMAPFILEHEADER bfh; BITMAPV5HEADER bih; - UINT info_size; + UINT info_size, i; LARGE_INTEGER pos; ULONG byteswritten; HRESULT hr; + const BYTE *bits; TRACE("(%p)\n", iface); @@ -294,15 +331,15 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER); bih.bV5Width = This->width; - bih.bV5Height = -This->height; /* top-down bitmap */ + bih.bV5Height = This->height; /* bottom-top bitmap */ bih.bV5Planes = 1; bih.bV5BitCount = This->format->bpp; bih.bV5Compression = This->format->compression; bih.bV5SizeImage = This->stride*This->height; bih.bV5XPelsPerMeter = (This->xres+0.0127) / 0.0254; bih.bV5YPelsPerMeter = (This->yres+0.0127) / 0.0254; - bih.bV5ClrUsed = 0; - bih.bV5ClrImportant = 0; + bih.bV5ClrUsed = (This->format->bpp <= 8) ? This->colors : 0; + bih.bV5ClrImportant = bih.bV5ClrUsed; if (This->format->compression == BI_BITFIELDS) { @@ -319,6 +356,7 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage; bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size; + bfh.bfOffBits += bih.bV5ClrUsed * sizeof(WICColor); pos.QuadPart = 0; hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL); @@ -332,9 +370,23 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) if (FAILED(hr)) return hr; if (byteswritten != info_size) return E_FAIL; - hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage, &byteswritten); - if (FAILED(hr)) return hr; - if (byteswritten != bih.bV5SizeImage) return E_FAIL; + /* write the palette */ + if (This->format->colors) + { + hr = IStream_Write(This->stream, This->palette, This->colors * sizeof(WICColor), &byteswritten); + if (FAILED(hr)) return hr; + if (byteswritten != This->colors * sizeof(WICColor)) return E_FAIL; + } + + /* write the image bits as a bottom-top array */ + bits = This->bits + bih.bV5SizeImage; + for (i = 0; i < This->height; i++) + { + bits -= This->stride; + hr = IStream_Write(This->stream, bits, This->stride, &byteswritten); + if (FAILED(hr)) return hr; + if (byteswritten != This->stride) return E_FAIL; + } This->committed = TRUE; @@ -447,11 +499,22 @@ static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface, return S_OK; } -static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) +static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) { - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICBmpEncoder, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; } static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface, @@ -487,6 +550,10 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, BmpEncoder *This = impl_from_IWICBitmapEncoder(iface); BmpFrameEncode *encode; HRESULT hr; + static const PROPBAG2 opts[1] = + { + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszEnableV5Header32bppBGRA }, + }; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -494,8 +561,11 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED; - hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); - if (FAILED(hr)) return hr; + if (ppIEncoderOptions) + { + hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions); + if (FAILED(hr)) return hr; + } encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode)); if (!encode) diff --git a/dll/win32/windowscodecs/clipper.c b/dll/win32/windowscodecs/clipper.c index f7df230247..94127f3df1 100644 --- a/dll/win32/windowscodecs/clipper.c +++ b/dll/win32/windowscodecs/clipper.c @@ -16,8 +16,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct BitmapClipper { IWICBitmapClipper IWICBitmapClipper_iface; LONG ref; diff --git a/dll/win32/windowscodecs/clsfactory.c b/dll/win32/windowscodecs/clsfactory.c index 2116ff9e8b..98938eb872 100644 --- a/dll/win32/windowscodecs/clsfactory.c +++ b/dll/win32/windowscodecs/clsfactory.c @@ -16,8 +16,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "ocidl.h" +#include "initguid.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; typedef struct { @@ -32,6 +49,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICPngEncoder, PngEncoder_CreateInstance}, {&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance}, {&CLSID_WICGifDecoder, GifDecoder_CreateInstance}, + {&CLSID_WICGifEncoder, GifEncoder_CreateInstance}, {&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance}, {&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance}, {&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance}, diff --git a/dll/win32/windowscodecs/colorcontext.c b/dll/win32/windowscodecs/colorcontext.c index d0c0a3bb36..eb13482cf4 100644 --- a/dll/win32/windowscodecs/colorcontext.c +++ b/dll/win32/windowscodecs/colorcontext.c @@ -16,8 +16,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct ColorContext { IWICColorContext IWICColorContext_iface; LONG ref; diff --git a/dll/win32/windowscodecs/colortransform.c b/dll/win32/windowscodecs/colortransform.c index 6a3f7d1528..5b1c7e8b70 100644 --- a/dll/win32/windowscodecs/colortransform.c +++ b/dll/win32/windowscodecs/colortransform.c @@ -16,8 +16,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct ColorTransform { IWICColorTransform IWICColorTransform_iface; LONG ref; diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c index d6086b087a..c3bcce89e0 100644 --- a/dll/win32/windowscodecs/converter.c +++ b/dll/win32/windowscodecs/converter.c @@ -17,10 +17,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" +#include <stdarg.h> #include <math.h> +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + struct FormatConverter; enum pixelformat { @@ -40,8 +53,11 @@ enum pixelformat { format_24bppRGB, format_32bppGrayFloat, format_32bppBGR, + format_32bppRGB, format_32bppBGRA, + format_32bppRGBA, format_32bppPBGRA, + format_32bppPRGBA, format_48bppRGB, format_64bppRGBA, format_32bppCMYK, @@ -63,7 +79,7 @@ typedef struct FormatConverter { const struct pixelformatinfo *dst_format, *src_format; WICBitmapDitherType dither; double alpha_threshold; - WICBitmapPaletteType palette_type; + IWICPalette *palette; CRITICAL_SECTION lock; /* must be held when initialized */ } FormatConverter; @@ -847,6 +863,27 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } +static HRESULT copypixels_to_32bppRGBA(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_32bppRGB: + case format_32bppRGBA: + case format_32bppPRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + default: + hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format); + if (SUCCEEDED(hr) && prc) + reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride); + return hr; + } +} + static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) { @@ -863,6 +900,22 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec } } +static HRESULT copypixels_to_32bppRGB(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + switch (source_format) + { + case format_32bppRGB: + case format_32bppRGBA: + case format_32bppPRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + default: + return copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format); + } +} + static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) { @@ -896,6 +949,39 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR } } +static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_32bppPRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + default: + hr = copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format); + if (SUCCEEDED(hr) && prc) + { + INT x, y; + + for (y=0; y<prc->Height; y++) + for (x=0; x<prc->Width; x++) + { + BYTE alpha = pbBuffer[cbStride*y+4*x+3]; + if (alpha != 255) + { + pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255; + pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255; + pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255; + } + } + } + return hr; + } +} + static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) { @@ -1208,11 +1294,95 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec return hr; } +static UINT rgb_to_palette_index(BYTE r, BYTE g, BYTE b, WICColor *colors, UINT count) +{ + UINT best_diff, best_index, i; + + best_diff = ~0; + best_index = 0; + + for (i = 0; i < count; i++) + { + BYTE pal_r, pal_g, pal_b; + DWORD diff_r, diff_g, diff_b, diff; + + pal_r = colors[i] >> 16; + pal_g = colors[i] >> 8; + pal_b = colors[i]; + + diff_r = r - pal_r; + diff_g = g - pal_g; + diff_b = b - pal_b; + + diff = diff_r * diff_r + diff_g * diff_g + diff_b * diff_b; + if (diff == 0) return i; + + if (diff < best_diff) + { + best_diff = diff; + best_index = i; + } + } + + return best_index; +} + +static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + BYTE *srcdata; + WICColor colors[256]; + UINT srcstride, srcdatasize, count; + + if (source_format == format_8bppIndexed) + { + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + + return S_OK; + } + + if (!This->palette) return WINCODEC_ERR_WRONGSTATE; + + hr = IWICPalette_GetColors(This->palette, 256, colors, &count); + if (hr != S_OK) return hr; + + srcstride = 3 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format); + if (SUCCEEDED(hr) && prc) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y = 0; y < prc->Height; y++) + { + BYTE *bgr = src; + + for (x = 0; x < prc->Width; x++) + { + dst[x] = rgb_to_palette_index(bgr[2], bgr[1], bgr[0], colors, count); + bgr += 3; + } + src += srcstride; + dst += cbStride; + } + } + + HeapFree(GetProcessHeap(), 0, srcdata); + return hr; +} + static const struct pixelformatinfo supported_formats[] = { {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL}, {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL}, {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL}, - {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, NULL}, + {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed}, {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL}, {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL}, {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL}, @@ -1225,8 +1395,11 @@ static const struct pixelformatinfo supported_formats[] = { {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB}, {format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat}, {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR}, + {format_32bppRGB, &GUID_WICPixelFormat32bppRGB, copypixels_to_32bppRGB}, {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA}, + {format_32bppRGBA, &GUID_WICPixelFormat32bppRGBA, copypixels_to_32bppRGBA}, {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA}, + {format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA}, {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL}, {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL}, {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL}, @@ -1289,6 +1462,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); + if (This->palette) IWICPalette_Release(This->palette); HeapFree(GetProcessHeap(), 0, This); } @@ -1337,10 +1511,27 @@ static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface, } static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface, - IWICPalette *pIPalette) + IWICPalette *palette) { - FIXME("(%p,%p): stub\n", iface, pIPalette); - return E_NOTIMPL; + FormatConverter *This = impl_from_IWICFormatConverter(iface); + + TRACE("(%p,%p)\n", iface, palette); + + if (!palette) return E_INVALIDARG; + if (!This->source) return WINCODEC_ERR_WRONGSTATE; + + if (!This->palette) + { + HRESULT hr; + UINT bpp; + + hr = get_pixelformat_bpp(This->dst_format->guid, &bpp); + if (hr != S_OK) return hr; + if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE; + return IWICBitmapSource_CopyPalette(This->source, palette); + } + + return IWICPalette_InitializeFromPalette(palette, This->palette); } static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface, @@ -1369,23 +1560,59 @@ static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface, pbBuffer, This->src_format->format); } else - return WINCODEC_ERR_NOTINITIALIZED; + return WINCODEC_ERR_WRONGSTATE; } static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, - IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither, - IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate) + IWICBitmapSource *source, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither, + IWICPalette *palette, double alpha_threshold, WICBitmapPaletteType palette_type) { FormatConverter *This = impl_from_IWICFormatConverter(iface); const struct pixelformatinfo *srcinfo, *dstinfo; - static INT fixme=0; GUID srcFormat; - HRESULT res=S_OK; + HRESULT res; + + TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat), + dither, palette, alpha_threshold, palette_type); - TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat), - dither, pIPalette, alphaThresholdPercent, paletteTranslate); + if (!palette) + { + UINT bpp; + res = get_pixelformat_bpp(dstFormat, &bpp); + if (res != S_OK) return res; - if (pIPalette && !fixme++) FIXME("ignoring palette\n"); + res = PaletteImpl_Create(&palette); + if (res != S_OK) return res; + + switch (palette_type) + { + case WICBitmapPaletteTypeCustom: + IWICPalette_Release(palette); + palette = NULL; + if (bpp <= 8) return E_INVALIDARG; + break; + + case WICBitmapPaletteTypeMedianCut: + { + if (bpp <= 8) + res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE); + break; + } + + default: + if (bpp <= 8) + res = IWICPalette_InitializePredefined(palette, palette_type, FALSE); + break; + } + + if (res != S_OK) + { + IWICPalette_Release(palette); + return res; + } + } + else + IWICPalette_AddRef(palette); EnterCriticalSection(&This->lock); @@ -1395,7 +1622,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, goto end; } - res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat); + res = IWICBitmapSource_GetPixelFormat(source, &srcFormat); if (FAILED(res)) goto end; srcinfo = get_formatinfo(&srcFormat); @@ -1416,13 +1643,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, if (dstinfo->copy_function) { - IWICBitmapSource_AddRef(pISource); + IWICBitmapSource_AddRef(source); This->src_format = srcinfo; This->dst_format = dstinfo; This->dither = dither; - This->alpha_threshold = alphaThresholdPercent; - This->palette_type = paletteTranslate; - This->source = pISource; + This->alpha_threshold = alpha_threshold; + This->palette = palette; + This->source = source; } else { @@ -1434,6 +1661,9 @@ end: LeaveCriticalSection(&This->lock); + if (res != S_OK && palette) + IWICPalette_Release(palette); + return res; } @@ -1501,6 +1731,7 @@ HRESULT FormatConverter_CreateInstance(REFIID iid, void** ppv) This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl; This->ref = 1; This->source = NULL; + This->palette = NULL; InitializeCriticalSection(&This->lock); This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock"); diff --git a/dll/win32/windowscodecs/fliprotate.c b/dll/win32/windowscodecs/fliprotate.c index e75107161a..72d1e8a287 100644 --- a/dll/win32/windowscodecs/fliprotate.c +++ b/dll/win32/windowscodecs/fliprotate.c @@ -16,8 +16,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct FlipRotator { IWICBitmapFlipRotator IWICBitmapFlipRotator_iface; LONG ref; diff --git a/dll/win32/windowscodecs/gifformat.c b/dll/win32/windowscodecs/gifformat.c index 3bc3bac409..e898d9c852 100644 --- a/dll/win32/windowscodecs/gifformat.c +++ b/dll/win32/windowscodecs/gifformat.c @@ -1,6 +1,6 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers - * 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 @@ -17,11 +17,62 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "ungif.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +#ifdef __REACTOS__ #include <ole2.h> +#endif -#include "ungif.h" +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#include "pshpack1.h" + +struct logical_screen_descriptor +{ + char signature[6]; + USHORT width; + USHORT height; + BYTE packed; + /* global_color_table_flag : 1; + * color_resolution : 3; + * sort_flag : 1; + * global_color_table_size : 3; + */ + BYTE background_color_index; + BYTE pixel_aspect_ratio; +}; + +struct image_descriptor +{ + USHORT left; + USHORT top; + USHORT width; + USHORT height; + BYTE packed; + /* local_color_table_flag : 1; + * interlace_flag : 1; + * sort_flag : 1; + * reserved : 2; + * local_color_table_size : 3; + */ +}; + +#include "poppack.h" static LPWSTR strdupAtoW(const char *src) { @@ -34,22 +85,7 @@ static LPWSTR strdupAtoW(const char *src) static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count) { -#include "pshpack1.h" - struct logical_screen_descriptor - { - char signature[6]; - USHORT width; - USHORT height; - BYTE packed; - /* global_color_table_flag : 1; - * color_resolution : 3; - * sort_flag : 1; - * global_color_table_size : 3; - */ - BYTE background_color_index; - BYTE pixel_aspect_ratio; - } lsd_data; -#include "poppack.h" + struct logical_screen_descriptor lsd_data; HRESULT hr; ULONG bytesread, i; MetadataItem *result; @@ -134,23 +170,6 @@ HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&LSDReader_Vtbl, iid, ppv); } -#include "pshpack1.h" -struct image_descriptor -{ - USHORT left; - USHORT top; - USHORT width; - USHORT height; - BYTE packed; - /* local_color_table_flag : 1; - * interlace_flag : 1; - * sort_flag : 1; - * reserved : 2; - * local_color_table_size : 3; - */ -}; -#include "poppack.h" - static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count) { @@ -1183,6 +1202,9 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet TRACE("(%p,%p)\n", iface, palette); + if (!This->gif) + return WINCODEC_ERR_WRONGSTATE; + cm = This->gif->SColorMap; if (cm) { @@ -1447,3 +1469,945 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv) return ret; } + +typedef struct GifEncoder +{ + IWICBitmapEncoder IWICBitmapEncoder_iface; + LONG ref; + IStream *stream; + CRITICAL_SECTION lock; + BOOL initialized, info_written, committed; + UINT n_frames; + WICColor palette[256]; + UINT colors; +} GifEncoder; + +static inline GifEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) +{ + return CONTAINING_RECORD(iface, GifEncoder, IWICBitmapEncoder_iface); +} + +typedef struct GifFrameEncode +{ + IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + LONG ref; + GifEncoder *encoder; + BOOL initialized, interlace, committed; + UINT width, height, lines; + double xres, yres; + WICColor palette[256]; + UINT colors; + BYTE *image_data; +} GifFrameEncode; + +static inline GifFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) +{ + return CONTAINING_RECORD(iface, GifFrameEncode, IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) +{ + TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + IWICBitmapFrameEncode_AddRef(iface); + *ppv = iface; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("%p -> %u\n", iface, ref); + return ref; +} + +static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("%p -> %u\n", iface, ref); + + if (!ref) + { + IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); + HeapFree(GetProcessHeap(), 0, This->image_data); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI GifFrameEncode_Initialize(IWICBitmapFrameEncode *iface, IPropertyBag2 *options) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%p\n", iface, options); + + EnterCriticalSection(&This->encoder->lock); + + if (!This->initialized) + { + This->initialized = TRUE; + hr = S_OK; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + + return hr; +} + +static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT width, UINT height) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%u,%u\n", iface, width, height); + + if (!width || !height) return E_INVALIDARG; + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized) + { + HeapFree(GetProcessHeap(), 0, This->image_data); + + This->image_data = HeapAlloc(GetProcessHeap(), 0, width * height); + if (This->image_data) + { + This->width = width; + This->height = height; + hr = S_OK; + } + else + hr = E_OUTOFMEMORY; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + + return hr; +} + +static HRESULT WINAPI GifFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double xres, double yres) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%f,%f\n", iface, xres, yres); + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized) + { + This->xres = xres; + This->yres = yres; + hr = S_OK; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + + return hr; +} + +static HRESULT WINAPI GifFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, WICPixelFormatGUID *format) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%s\n", iface, debugstr_guid(format)); + + if (!format) return E_INVALIDARG; + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized) + { + *format = GUID_WICPixelFormat8bppIndexed; + hr = S_OK; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + + return hr; +} + +static HRESULT WINAPI GifFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, UINT count, IWICColorContext **context) +{ + FIXME("%p,%u,%p: stub\n", iface, count, context); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette *palette) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%p\n", iface, palette); + + if (!palette) return E_INVALIDARG; + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized) + hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); + else + hr = WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->encoder->lock); + return hr; +} + +static HRESULT WINAPI GifFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, IWICBitmapSource *thumbnail) +{ + FIXME("%p,%p: stub\n", iface, thumbnail); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT lines, UINT stride, UINT size, BYTE *pixels) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%u,%u,%u,%p\n", iface, lines, stride, size, pixels); + + if (!pixels) return E_INVALIDARG; + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized && This->image_data) + { + if (This->lines + lines <= This->height) + { + UINT i; + BYTE *src, *dst; + + src = pixels; + dst = This->image_data + This->lines * This->width; + + for (i = 0; i < lines; i++) + { + memcpy(dst, src, This->width); + src += stride; + dst += This->width; + } + + This->lines += lines; + hr = S_OK; + } + else + hr = E_INVALIDARG; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + return hr; +} + +static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, WICRect *rc) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p,%p,%p\n", iface, source, rc); + + if (!source) return E_INVALIDARG; + + EnterCriticalSection(&This->encoder->lock); + + if (This->initialized) + { + const GUID *format = &GUID_WICPixelFormat8bppIndexed; + + hr = configure_write_source(iface, source, rc, format, + This->width, This->height, This->xres, This->yres); + if (hr == S_OK) + hr = write_source(iface, source, rc, format, 8, This->width, This->height); + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + return hr; +} + +#define LZW_DICT_SIZE (1 << 12) + +struct lzw_dict +{ + short prefix[LZW_DICT_SIZE]; + unsigned char suffix[LZW_DICT_SIZE]; +}; + +struct lzw_state +{ + struct lzw_dict dict; + short init_code_bits, code_bits, next_code, clear_code, eof_code; + unsigned bits_buf; + int bits_count; + int (*user_write_data)(void *user_ptr, void *data, int length); + void *user_ptr; +}; + +struct input_stream +{ + unsigned len; + const BYTE *in; +}; + +struct output_stream +{ + struct + { + unsigned char len; + char data[255]; + } gif_block; + IStream *out; +}; + +static int lzw_output_code(struct lzw_state *state, short code) +{ + state->bits_buf |= code << state->bits_count; + state->bits_count += state->code_bits; + + while (state->bits_count >= 8) + { + unsigned char byte = (unsigned char)state->bits_buf; + if (state->user_write_data(state->user_ptr, &byte, 1) != 1) + return 0; + state->bits_buf >>= 8; + state->bits_count -= 8; + } + + return 1; +} + +static inline int lzw_output_clear_code(struct lzw_state *state) +{ + return lzw_output_code(state, state->clear_code); +} + +static inline int lzw_output_eof_code(struct lzw_state *state) +{ + return lzw_output_code(state, state->eof_code); +} + +static int lzw_flush_bits(struct lzw_state *state) +{ + unsigned char byte; + + while (state->bits_count >= 8) + { + byte = (unsigned char)state->bits_buf; + if (state->user_write_data(state->user_ptr, &byte, 1) != 1) + return 0; + state->bits_buf >>= 8; + state->bits_count -= 8; + } + + if (state->bits_count) + { + static const char mask[8] = { 0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f }; + + byte = (unsigned char)state->bits_buf & mask[state->bits_count]; + if (state->user_write_data(state->user_ptr, &byte, 1) != 1) + return 0; + } + + state->bits_buf = 0; + state->bits_count = 0; + + return 1; +} + +static void lzw_dict_reset(struct lzw_state *state) +{ + int i; + + state->code_bits = state->init_code_bits + 1; + state->next_code = (1 << state->init_code_bits) + 2; + + for(i = 0; i < LZW_DICT_SIZE; i++) + { + state->dict.prefix[i] = 1 << 12; /* impossible LZW code value */ + state->dict.suffix[i] = 0; + } +} + +static void lzw_state_init(struct lzw_state *state, short init_code_bits, void *user_write_data, void *user_ptr) +{ + state->init_code_bits = init_code_bits; + state->clear_code = 1 << init_code_bits; + state->eof_code = state->clear_code + 1; + state->bits_buf = 0; + state->bits_count = 0; + state->user_write_data = user_write_data; + state->user_ptr = user_ptr; + + lzw_dict_reset(state); +} + +static int lzw_dict_add(struct lzw_state *state, short prefix, unsigned char suffix) +{ + if (state->next_code < LZW_DICT_SIZE) + { + state->dict.prefix[state->next_code] = prefix; + state->dict.suffix[state->next_code] = suffix; + + if ((state->next_code & (state->next_code - 1)) == 0) + state->code_bits++; + + state->next_code++; + return state->next_code; + } + + return -1; +} + +static short lzw_dict_lookup(const struct lzw_state *state, short prefix, unsigned char suffix) +{ + short i; + + for (i = 0; i < state->next_code; i++) + { + if (state->dict.prefix[i] == prefix && state->dict.suffix[i] == suffix) + return i; + } + + return -1; +} + +static inline int write_byte(struct output_stream *out, char byte) +{ + if (out->gif_block.len == 255) + { + if (IStream_Write(out->out, &out->gif_block, sizeof(out->gif_block), NULL) != S_OK) + return 0; + + out->gif_block.len = 0; + } + + out->gif_block.data[out->gif_block.len++] = byte; + + return 1; +} + +static int write_data(void *user_ptr, void *user_data, int length) +{ + unsigned char *data = user_data; + struct output_stream *out = user_ptr; + int len = length; + + while (len-- > 0) + { + if (!write_byte(out, *data++)) return 0; + } + + return length; +} + +static int flush_output_data(void *user_ptr) +{ + struct output_stream *out = user_ptr; + + if (out->gif_block.len) + { + if (IStream_Write(out->out, &out->gif_block, out->gif_block.len + sizeof(out->gif_block.len), NULL) != S_OK) + return 0; + } + + /* write GIF block terminator */ + out->gif_block.len = 0; + return IStream_Write(out->out, &out->gif_block, sizeof(out->gif_block.len), NULL) == S_OK; +} + +static inline int read_byte(struct input_stream *in, unsigned char *byte) +{ + if (in->len) + { + in->len--; + *byte = *in->in++; + return 1; + } + + return 0; +} + +static HRESULT gif_compress(IStream *out_stream, const BYTE *in_data, ULONG in_size) +{ + struct input_stream in; + struct output_stream out; + struct lzw_state state; + short init_code_bits, prefix, code; + unsigned char suffix; + + in.in = in_data; + in.len = in_size; + + out.gif_block.len = 0; + out.out = out_stream; + + init_code_bits = suffix = 8; + if (IStream_Write(out.out, &suffix, sizeof(suffix), NULL) != S_OK) + return E_FAIL; + + lzw_state_init(&state, init_code_bits, write_data, &out); + + if (!lzw_output_clear_code(&state)) + return E_FAIL; + + if (read_byte(&in, &suffix)) + { + prefix = suffix; + + while (read_byte(&in, &suffix)) + { + code = lzw_dict_lookup(&state, prefix, suffix); + if (code == -1) + { + if (!lzw_output_code(&state, prefix)) + return E_FAIL; + + if (lzw_dict_add(&state, prefix, suffix) == -1) + { + if (!lzw_output_clear_code(&state)) + return E_FAIL; + lzw_dict_reset(&state); + } + + prefix = suffix; + } + else + prefix = code; + } + + if (!lzw_output_code(&state, prefix)) + return E_FAIL; + if (!lzw_output_eof_code(&state)) + return E_FAIL; + if (!lzw_flush_bits(&state)) + return E_FAIL; + } + + return flush_output_data(&out) ? S_OK : E_FAIL; +} + +static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface) +{ + GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("%p\n", iface); + + EnterCriticalSection(&This->encoder->lock); + + if (This->image_data && This->lines == This->height && !This->committed) + { + BYTE gif_palette[256][3]; + + hr = S_OK; + + if (!This->encoder->info_written) + { + struct logical_screen_descriptor lsd; + + /* Logical Screen Descriptor */ + memcpy(lsd.signature, "GIF89a", 6); + lsd.width = This->width; + lsd.height = This->height; + lsd.packed = 0; + if (This->encoder->colors) + lsd.packed |= 0x80; /* global color table flag */ + lsd.packed |= 0x07 << 4; /* color resolution */ + lsd.packed |= 0x07; /* global color table size */ + lsd.background_color_index = 0; /* FIXME */ + lsd.pixel_aspect_ratio = 0; + hr = IStream_Write(This->encoder->stream, &lsd, sizeof(lsd), NULL); + if (hr == S_OK && This->encoder->colors) + { + UINT i; + + /* Global Color Table */ + memset(gif_palette, 0, sizeof(gif_palette)); + for (i = 0; i < This->encoder->colors; i++) + { + gif_palette[i][0] = (This->encoder->palette[i] >> 16) & 0xff; + gif_palette[i][1] = (This->encoder->palette[i] >> 8) & 0xff; + gif_palette[i][2] = This->encoder->palette[i] & 0xff; + } + hr = IStream_Write(This->encoder->stream, gif_palette, sizeof(gif_palette), NULL); + } + + /* FIXME: write GCE, APE, etc. GIF extensions */ + + if (hr == S_OK) + This->encoder->info_written = TRUE; + } + + if (hr == S_OK) + { + char image_separator = 0x2c; + + hr = IStream_Write(This->encoder->stream, &image_separator, sizeof(image_separator), NULL); + if (hr == S_OK) + { + struct image_descriptor imd; + + /* Image Descriptor */ + imd.left = 0; + imd.top = 0; + imd.width = This->width; + imd.height = This->height; + imd.packed = 0; + if (This->colors) + { + imd.packed |= 0x80; /* local color table flag */ + imd.packed |= 0x07; /* local color table size */ + } + /* FIXME: interlace flag */ + hr = IStream_Write(This->encoder->stream, &imd, sizeof(imd), NULL); + if (hr == S_OK && This->colors) + { + UINT i; + + /* Local Color Table */ + memset(gif_palette, 0, sizeof(gif_palette)); + for (i = 0; i < This->colors; i++) + { + gif_palette[i][0] = (This->palette[i] >> 16) & 0xff; + gif_palette[i][1] = (This->palette[i] >> 8) & 0xff; + gif_palette[i][2] = This->palette[i] & 0xff; + } + hr = IStream_Write(This->encoder->stream, gif_palette, sizeof(gif_palette), NULL); + if (hr == S_OK) + { + /* Image Data */ + hr = gif_compress(This->encoder->stream, This->image_data, This->width * This->height); + if (hr == S_OK) + This->committed = TRUE; + } + } + } + } + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->encoder->lock); + return hr; +} + +static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, IWICMetadataQueryWriter **writer) +{ + FIXME("%p, %p: stub\n", iface, writer); + return E_NOTIMPL; +} + +static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl = +{ + GifFrameEncode_QueryInterface, + GifFrameEncode_AddRef, + GifFrameEncode_Release, + GifFrameEncode_Initialize, + GifFrameEncode_SetSize, + GifFrameEncode_SetResolution, + GifFrameEncode_SetPixelFormat, + GifFrameEncode_SetColorContexts, + GifFrameEncode_SetPalette, + GifFrameEncode_SetThumbnail, + GifFrameEncode_WritePixels, + GifFrameEncode_WriteSource, + GifFrameEncode_Commit, + GifFrameEncode_GetMetadataQueryWriter +}; + +static HRESULT WINAPI GifEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, void **ppv) +{ + TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapEncoder, iid)) + { + IWICBitmapEncoder_AddRef(iface); + *ppv = iface; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("%p -> %u\n", iface, ref); + return ref; +} + +static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("%p -> %u\n", iface, ref); + + if (!ref) + { + if (This->stream) IStream_Release(This->stream); + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI GifEncoder_Initialize(IWICBitmapEncoder *iface, IStream *stream, WICBitmapEncoderCacheOption option) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("%p,%p,%#x\n", iface, stream, option); + + if (!stream) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) + { + IStream_AddRef(stream); + This->stream = stream; + This->initialized = TRUE; + hr = S_OK; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI GifEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) +{ + if (!format) return E_INVALIDARG; + + *format = GUID_ContainerFormatGif; + return S_OK; +} + +static HRESULT WINAPI GifEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) +{ + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICGifEncoder, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; +} + +static HRESULT WINAPI GifEncoder_SetColorContexts(IWICBitmapEncoder *iface, UINT count, IWICColorContext **context) +{ + FIXME("%p,%u,%p: stub\n", iface, count, context); + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("%p,%p\n", iface, palette); + + if (!palette) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (This->initialized) + hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); + else + hr = WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI GifEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *thumbnail) +{ + TRACE("%p,%p\n", iface, thumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *preview) +{ + TRACE("%p,%p\n", iface, preview); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **frame, IPropertyBag2 **options) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("%p,%p,%p\n", iface, frame, options); + + if (!frame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (This->initialized && !This->committed) + { + GifFrameEncode *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); + if (ret) + { + This->n_frames++; + + ret->IWICBitmapFrameEncode_iface.lpVtbl = &GifFrameEncode_Vtbl; + ret->ref = 1; + ret->encoder = This; + ret->initialized = FALSE; + ret->interlace = FALSE; /* FIXME: read from the properties */ + ret->committed = FALSE; + ret->width = 0; + ret->height = 0; + ret->lines = 0; + ret->xres = 0.0; + ret->yres = 0.0; + ret->colors = 0; + ret->image_data = NULL; + IWICBitmapEncoder_AddRef(iface); + *frame = &ret->IWICBitmapFrameEncode_iface; + + hr = S_OK; + + if (options) + { + hr = CreatePropertyBag2(NULL, 0, options); + if (hr != S_OK) + { + IWICBitmapFrameEncode_Release(*frame); + *frame = NULL; + } + } + } + else + hr = E_OUTOFMEMORY; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->lock); + + return hr; + +} + +static HRESULT WINAPI GifEncoder_Commit(IWICBitmapEncoder *iface) +{ + GifEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("%p\n", iface); + + EnterCriticalSection(&This->lock); + + if (This->initialized && !This->committed) + { + char gif_trailer = 0x3b; + + /* FIXME: write text, comment GIF extensions */ + + hr = IStream_Write(This->stream, &gif_trailer, sizeof(gif_trailer), NULL); + if (hr == S_OK) + This->committed = TRUE; + } + else + hr = WINCODEC_ERR_WRONGSTATE; + + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI GifEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, IWICMetadataQueryWriter **writer) +{ + FIXME("%p,%p: stub\n", iface, writer); + return E_NOTIMPL; +} + +static const IWICBitmapEncoderVtbl GifEncoder_Vtbl = +{ + GifEncoder_QueryInterface, + GifEncoder_AddRef, + GifEncoder_Release, + GifEncoder_Initialize, + GifEncoder_GetContainerFormat, + GifEncoder_GetEncoderInfo, + GifEncoder_SetColorContexts, + GifEncoder_SetPalette, + GifEncoder_SetThumbnail, + GifEncoder_SetPreview, + GifEncoder_CreateNewFrame, + GifEncoder_Commit, + GifEncoder_GetMetadataQueryWriter +}; + +HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv) +{ + GifEncoder *This; + HRESULT ret; + + TRACE("%s,%p\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapEncoder_iface.lpVtbl = &GifEncoder_Vtbl; + This->ref = 1; + This->stream = NULL; + InitializeCriticalSection(&This->lock); + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifEncoder.lock"); + This->initialized = FALSE; + This->info_written = FALSE; + This->committed = FALSE; + This->n_frames = 0; + This->colors = 0; + + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + + return ret; +} diff --git a/dll/win32/windowscodecs/icnsformat.c b/dll/win32/windowscodecs/icnsformat.c index e7d6f96226..aa9640417f 100644 --- a/dll/win32/windowscodecs/icnsformat.c +++ b/dll/win32/windowscodecs/icnsformat.c @@ -16,6 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include <stdarg.h> + #ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H #define GetCurrentProcess GetCurrentProcess_Mac #define GetCurrentThread GetCurrentThread_Mac @@ -73,8 +78,19 @@ #undef DPRINTF #endif +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" +#include "wine/library.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + #if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \ MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 @@ -601,9 +617,12 @@ static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, goto end; } - hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); - if (FAILED(hr)) - goto end; + if (ppIEncoderOptions) + { + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); + if (FAILED(hr)) + goto end; + } frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode)); if (frameEncode == NULL) diff --git a/dll/win32/windowscodecs/icoformat.c b/dll/win32/windowscodecs/icoformat.c index 86629568fd..1b1c79291b 100644 --- a/dll/win32/windowscodecs/icoformat.c +++ b/dll/win32/windowscodecs/icoformat.c @@ -16,9 +16,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "objbase.h" + #include "wincodecs_private.h" -#include <pshpack1.h> +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#include "pshpack1.h" typedef struct { BYTE bWidth; @@ -38,7 +53,7 @@ typedef struct WORD idCount; } ICONHEADER; -#include <poppack.h> +#include "poppack.h" typedef struct { IWICBitmapDecoder IWICBitmapDecoder_iface; diff --git a/dll/win32/windowscodecs/imgfactory.c b/dll/win32/windowscodecs/imgfactory.c index 623265762a..88ce00e651 100644 --- a/dll/win32/windowscodecs/imgfactory.c +++ b/dll/win32/windowscodecs/imgfactory.c @@ -17,8 +17,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "shellapi.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct { IWICComponentFactory IWICComponentFactory_iface; LONG ref; @@ -104,22 +120,23 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename( return hr; } -static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor, - WICDecodeOptions metadataOptions) +static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor, + WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder) { IEnumUnknown *enumdecoders; IUnknown *unkdecoderinfo; IWICBitmapDecoderInfo *decoderinfo; - IWICBitmapDecoder *decoder = NULL; GUID vendor; HRESULT res; ULONG num_fetched; BOOL matches; + *decoder = NULL; + res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders); - if (FAILED(res)) return NULL; + if (FAILED(res)) return res; - while (!decoder) + while (!*decoder) { res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched); @@ -144,18 +161,21 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo if (SUCCEEDED(res) && matches) { - res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder); + res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); /* FIXME: should use QueryCapability to choose a decoder */ if (SUCCEEDED(res)) { - res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions); + res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); if (FAILED(res)) { - IWICBitmapDecoder_Release(decoder); - decoder = NULL; + IWICBitmapDecoder_Release(*decoder); + IWICBitmapDecoderInfo_Release(decoderinfo); + IUnknown_Release(unkdecoderinfo); + *decoder = NULL; + return res; } } } @@ -171,7 +191,7 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo IEnumUnknown_Release(enumdecoders); - return decoder; + return WINCODEC_ERR_COMPONENTNOTFOUND; } static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream( @@ -185,9 +205,9 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream( metadataOptions, ppIDecoder); if (pguidVendor) - decoder = find_decoder(pIStream, pguidVendor, metadataOptions); + res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder); if (!decoder) - decoder = find_decoder(pIStream, NULL, metadataOptions); + res = find_decoder(pIStream, NULL, metadataOptions, &decoder); if (decoder) { @@ -202,17 +222,17 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream( BYTE data[4]; ULONG bytesread; - WARN("failed to load from a stream\n"); + WARN("failed to load from a stream %#x\n", res); seek.QuadPart = 0; - res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - if (SUCCEEDED(res)) - res = IStream_Read(pIStream, data, 4, &bytesread); - if (SUCCEEDED(res)) - WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); + if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK) + { + if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK) + WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); + } } *ppIDecoder = NULL; - return WINCODEC_ERR_COMPONENTNOTFOUND; + return res; } } @@ -579,12 +599,36 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride, UINT size, BYTE *buffer, IWICBitmap **bitmap) { + HRESULT hr; + TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height, debugstr_guid(format), stride, size, buffer, bitmap); if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG; - return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap); + hr = BitmapImpl_Create(width, height, stride, size, NULL, format, WICBitmapCacheOnLoad, bitmap); + if (SUCCEEDED(hr)) + { + IWICBitmapLock *lock; + + hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); + if (SUCCEEDED(hr)) + { + UINT buffersize; + BYTE *data; + + IWICBitmapLock_GetDataPointer(lock, &buffersize, &data); + memcpy(data, buffer, buffersize); + + IWICBitmapLock_Release(lock); + } + else + { + IWICBitmap_Release(*bitmap); + *bitmap = NULL; + } + } + return hr; } static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format) @@ -1160,3 +1204,50 @@ HRESULT ComponentFactory_CreateInstance(REFIID iid, void** ppv) return ret; } + +HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, + REFWICPixelFormatGUID format, HANDLE section, UINT stride, + UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap) +{ + DWORD access; + void *buffer; + HRESULT hr; + + TRACE("%u,%u,%s,%p,%u,%#x,%#x,%p\n", width, height, debugstr_guid(format), + section, stride, offset, wicaccess, bitmap); + + if (!width || !height || !section || !bitmap) return E_INVALIDARG; + + switch (wicaccess) + { + case WICSectionAccessLevelReadWrite: + access = FILE_MAP_READ | FILE_MAP_WRITE; + break; + + case WICSectionAccessLevelRead: + access = FILE_MAP_READ; + break; + + default: + FIXME("unsupported access %#x\n", wicaccess); + return E_INVALIDARG; + } + + buffer = MapViewOfFile(section, access, 0, offset, 0); + if (!buffer) return HRESULT_FROM_WIN32(GetLastError()); + + hr = BitmapImpl_Create(width, height, stride, 0, buffer, format, WICBitmapCacheOnLoad, bitmap); + if (FAILED(hr)) UnmapViewOfFile(buffer); + return hr; +} + +HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, + REFWICPixelFormatGUID format, HANDLE section, + UINT stride, UINT offset, IWICBitmap **bitmap) +{ + TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format), + section, stride, offset, bitmap); + + return WICCreateBitmapFromSectionEx(width, height, format, section, + stride, offset, WICSectionAccessLevelRead, bitmap); +} diff --git a/dll/win32/windowscodecs/info.c b/dll/win32/windowscodecs/info.c index 63cdc07dbc..22a7b83e2c 100644 --- a/dll/win32/windowscodecs/info.c +++ b/dll/win32/windowscodecs/info.c @@ -17,9 +17,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" + #include "wincodecs_private.h" -#include <wine/list.h> +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/list.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0}; static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0}; @@ -853,8 +868,12 @@ static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *ifac static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface, UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual) { - FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); - return E_NOTIMPL; + BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); + + TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); + + return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, + cchFileExtensions, wzFileExtensions, pcchActual); } static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface, @@ -2265,6 +2284,12 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn return hr; } +static BOOL is_1bpp_format(const WICPixelFormatGUID *format) +{ + return IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite) || + IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed); +} + HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst) { HRESULT res; @@ -2277,10 +2302,12 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma BOOL canconvert; ULONG num_fetched; + TRACE("%s,%p,%p\n", debugstr_guid(dstFormat), pISrc, ppIDst); + res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat); if (FAILED(res)) return res; - if (IsEqualGUID(&srcFormat, dstFormat)) + if (IsEqualGUID(&srcFormat, dstFormat) || (is_1bpp_format(&srcFormat) && is_1bpp_format(dstFormat))) { IWICBitmapSource_AddRef(pISrc); *ppIDst = pISrc; @@ -2317,7 +2344,7 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma if (SUCCEEDED(res) && canconvert) res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone, - NULL, 0.0, WICBitmapPaletteTypeCustom); + NULL, 0.0, WICBitmapPaletteTypeMedianCut); if (FAILED(res) || !canconvert) { diff --git a/dll/win32/windowscodecs/jpegformat.c b/dll/win32/windowscodecs/jpegformat.c index cfb84c36aa..0069bdfd89 100644 --- a/dll/win32/windowscodecs/jpegformat.c +++ b/dll/win32/windowscodecs/jpegformat.c @@ -16,11 +16,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" +#include "wine/port.h" #ifdef HAVE_UNISTD_H # include <unistd.h> #endif +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <setjmp.h> #ifdef SONAME_LIBJPEG /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ @@ -37,6 +42,19 @@ #undef boolean #endif +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" +#include "wine/library.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + #ifdef SONAME_LIBJPEG WINE_DECLARE_DEBUG_CHANNEL(jpeg); @@ -405,10 +423,14 @@ static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface, } static HRESULT WINAPI JpegDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) + IWICMetadataQueryReader **reader) { - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader); - return E_NOTIMPL; + FIXME("(%p,%p): stub\n", iface, reader); + + if (!reader) return E_INVALIDARG; + + *reader = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static HRESULT WINAPI JpegDecoder_GetPreview(IWICBitmapDecoder *iface, @@ -662,9 +684,15 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, } if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) + { + DWORD *pDwordData = (DWORD*) (This->image_data + stride * first_scanline); + DWORD *pDwordDataEnd = (DWORD*) (This->image_data + This->cinfo.output_scanline * stride); + /* Adobe JPEG's have inverted CMYK data. */ - for (i=0; i<data_size; i++) - This->image_data[i] ^= 0xff; + while(pDwordData < pDwordDataEnd) + *pDwordData++ ^= 0xffffffff; + } + } LeaveCriticalSection(&This->lock); @@ -1375,11 +1403,22 @@ static HRESULT WINAPI JpegEncoder_GetContainerFormat(IWICBitmapEncoder *iface, return E_NOTIMPL; } -static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) +static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) { - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICJpegEncoder, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; } static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface, @@ -1422,7 +1461,15 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, { JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); HRESULT hr; - PROPBAG2 opts[6] = {{0}}; + static const PROPBAG2 opts[6] = + { + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszImageQuality }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszBitmapTransform }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszLuminance }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszChrominance }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszJpegYCrCbSubsampling }, + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszSuppressApp0 }, + }; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -1440,30 +1487,14 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, return WINCODEC_ERR_NOTINITIALIZED; } - opts[0].pstrName = (LPOLESTR)wszImageQuality; - opts[0].vt = VT_R4; - opts[0].dwType = PROPBAG2_TYPE_DATA; - opts[1].pstrName = (LPOLESTR)wszBitmapTransform; - opts[1].vt = VT_UI1; - opts[1].dwType = PROPBAG2_TYPE_DATA; - opts[2].pstrName = (LPOLESTR)wszLuminance; - opts[2].vt = VT_I4|VT_ARRAY; - opts[2].dwType = PROPBAG2_TYPE_DATA; - opts[3].pstrName = (LPOLESTR)wszChrominance; - opts[3].vt = VT_I4|VT_ARRAY; - opts[3].dwType = PROPBAG2_TYPE_DATA; - opts[4].pstrName = (LPOLESTR)wszJpegYCrCbSubsampling; - opts[4].vt = VT_UI1; - opts[4].dwType = PROPBAG2_TYPE_DATA; - opts[5].pstrName = (LPOLESTR)wszSuppressApp0; - opts[5].vt = VT_BOOL; - opts[5].dwType = PROPBAG2_TYPE_DATA; - - hr = CreatePropertyBag2(opts, 6, ppIEncoderOptions); - if (FAILED(hr)) + if (ppIEncoderOptions) { - LeaveCriticalSection(&This->lock); - return hr; + hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions); + if (FAILED(hr)) + { + LeaveCriticalSection(&This->lock); + return hr; + } } This->frame_count = 1; diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c index c53e330a21..3bed56536c 100644 --- a/dll/win32/windowscodecs/main.c +++ b/dll/win32/windowscodecs/main.c @@ -16,8 +16,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + +#define COBJMACROS +#include "config.h" + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) diff --git a/dll/win32/windowscodecs/metadatahandler.c b/dll/win32/windowscodecs/metadatahandler.c index dff5ed3c7f..3d48924a44 100644 --- a/dll/win32/windowscodecs/metadatahandler.c +++ b/dll/win32/windowscodecs/metadatahandler.c @@ -17,11 +17,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" +#include <stdarg.h> #include <stdio.h> -#include <wine/winternl.h> -#include <propvarutil.h> + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "wine/winternl.h" +#include "objbase.h" +#include "propvarutil.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); typedef struct MetadataHandler { IWICMetadataWriter IWICMetadataWriter_iface; @@ -704,7 +718,7 @@ static int tag_to_vt(SHORT tag) static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, MetadataItem *item, BOOL native_byte_order) { - ULONG count, value, i, bytesread; + ULONG count, value, i; SHORT type; LARGE_INTEGER pos; HRESULT hr; @@ -746,7 +760,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, item->value.vt |= VT_VECTOR; item->value.u.caub.cElems = count; - item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count); + item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); if (!item->value.u.caub.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; @@ -756,9 +770,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread); - if (bytesread != count) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); return hr; @@ -791,7 +804,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, item->value.vt |= VT_VECTOR; item->value.u.caui.cElems = count; - item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2); + item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2); if (!item->value.u.caui.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; @@ -801,9 +814,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread); - if (bytesread != count * 2) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); return hr; @@ -824,7 +836,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, item->value.vt |= VT_VECTOR; item->value.u.caul.cElems = count; - item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4); + item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4); if (!item->value.u.caul.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; @@ -834,9 +846,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread); - if (bytesread != count * 4) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); return hr; @@ -862,8 +873,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) return hr; - hr = IStream_Read(input, &ull, sizeof(ull), &bytesread); - if (bytesread != sizeof(ull)) hr = E_FAIL; + hr = IStream_Read(input, &ull, sizeof(ull), NULL); if (hr != S_OK) return hr; item->value.u.uhVal.QuadPart = ull; @@ -881,7 +891,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, { item->value.vt |= VT_VECTOR; item->value.u.cauh.cElems = count; - item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8); + item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8); if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; @@ -891,9 +901,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); return hr; } - hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread); - if (bytesread != count * 8) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); return hr; @@ -911,7 +920,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, } break; case IFD_ASCII: - item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1); + item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1); if (!item->value.u.pszVal) return E_OUTOFMEMORY; if (count <= 4) @@ -929,9 +938,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); return hr; } - hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread); - if (bytesread != count) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.pszVal, count, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); return hr; @@ -946,7 +954,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, break; } - item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), 0, count); + item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY; item->value.u.blob.cbSize = count; @@ -965,9 +973,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); return hr; } - hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread); - if (bytesread != count) hr = E_FAIL; - if (hr != S_OK) + hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL); + if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); return hr; diff --git a/dll/win32/windowscodecs/metadataquery.c b/dll/win32/windowscodecs/metadataquery.c index c45082b202..e33884881b 100644 --- a/dll/win32/windowscodecs/metadataquery.c +++ b/dll/win32/windowscodecs/metadataquery.c @@ -17,9 +17,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "propvarutil.h" + #include "wincodecs_private.h" -#include <propvarutil.h> +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name); diff --git a/dll/win32/windowscodecs/palette.c b/dll/win32/windowscodecs/palette.c index 89b10b7ba9..a8370ff103 100644 --- a/dll/win32/windowscodecs/palette.c +++ b/dll/win32/windowscodecs/palette.c @@ -1,6 +1,7 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers - * Copyright 2012 Dmitry Timoshkov + * Copyright 2012,2016 Dmitry Timoshkov + * Copyright 2016 Sebastian Lackner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,8 +18,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct { IWICPalette IWICPalette_iface; LONG ref; @@ -431,11 +447,279 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface, return S_OK; } -static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *iface, - IWICBitmapSource *pISurface, UINT colorCount, BOOL fAddTransparentColor) +#define R_COUNT (1 << 5) +#define R_SHIFT (8 - 5) +#define R_SCALE 2 + +#define G_COUNT (1 << 6) +#define G_SHIFT (8 - 6) +#define G_SCALE 3 + +#define B_COUNT (1 << 5) +#define B_SHIFT (8 - 5) +#define B_SCALE 1 + +struct histogram +{ + unsigned int data[R_COUNT][G_COUNT][B_COUNT]; +}; + +struct box +{ + int r_min, r_max; + int g_min, g_max; + int b_min, b_max; + unsigned int count; + unsigned int score; +}; + +/* count nonzero elements in the histogram range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */ +static inline unsigned int histogram_count(struct histogram *h, int r_min, int r_max, + int g_min, int g_max, int b_min, int b_max) +{ + unsigned int count = 0; + int r, g, b; + for (r = r_min; r <= r_max; r++) + for (g = g_min; g <= g_max; g++) + for (b = b_min; b <= b_max; b++) + if (h->data[r][g][b] != 0) count++; + return count; +} + +/* compute weighted average color in the range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */ +static unsigned int histogram_color(struct histogram *h, int r_min, int r_max, + int g_min, int g_max, int b_min, int b_max) +{ + unsigned long long r_sum = 0, g_sum = 0, b_sum = 0; + unsigned int tmp, count = 0; + int r, g, b; + + for (r = r_min; r <= r_max; r++) + for (g = g_min; g <= g_max; g++) + for (b = b_min; b <= b_max; b++) + { + if (!(tmp = h->data[r][g][b])) continue; + r_sum += ((r << R_SHIFT) + ((1 << R_SHIFT) / 2)) * tmp; + g_sum += ((g << G_SHIFT) + ((1 << G_SHIFT) / 2)) * tmp; + b_sum += ((b << B_SHIFT) + ((1 << B_SHIFT) / 2)) * tmp; + count += tmp; + } + + return ((b_sum + (count / 2)) / count) | + ((g_sum + (count / 2)) / count) << 8 | + ((r_sum + (count / 2)) / count) << 16 | 0xff000000; +} + +/* same as histogram_count */ +static inline unsigned int box_count(struct histogram *h, struct box *b) +{ + return histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max); +} + +/* same as histogram_color */ +static inline unsigned int box_color(struct histogram *h, struct box *b) +{ + return histogram_color(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max); +} + +/* compute score used to determine best split (also called "volume") */ +static inline unsigned int box_score(struct box *b) +{ + unsigned int tmp, sum = 0; + tmp = ((b->r_max - b->r_min) << R_SHIFT) * R_SCALE; sum += tmp * tmp; + tmp = ((b->g_max - b->g_min) << G_SHIFT) * G_SCALE; sum += tmp * tmp; + tmp = ((b->b_max - b->b_min) << B_SHIFT) * B_SCALE; sum += tmp * tmp; + return sum; +} + +/* attempt to shrink a box */ +static void shrink_box(struct histogram *h, struct box *b) +{ + int i; + for (i = b->r_min; i <= b->r_max; i++) + if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_min = i; break; } + for (i = b->r_max; i >= b->r_min; i--) + if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_max = i; break; } + for (i = b->g_min; i <= b->g_max; i++) + if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_min = i; break; } + for (i = b->g_max; i >= b->g_min; i--) + if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_max = i; break; } + for (i = b->b_min; i <= b->b_max; i++) + if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_min = i; break; } + for (i = b->b_max; i >= b->b_min; i--) + if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_max = i; break; } + b->count = box_count(h, b); + b->score = box_score(b); +} + +/* helper for split_box */ +static inline void set_avg(int *min, int *max) +{ + int avg = (*min + *max) / 2; + *min = avg + 1; + *max = avg; +} + +/* split a box based on the best axis */ +static void split_box(struct histogram *h, struct box *b1, struct box *b2) +{ + int r = ((b1->r_max - b1->r_min) << R_SHIFT) * R_SCALE; + int g = ((b1->g_max - b1->g_min) << G_SHIFT) * G_SCALE; + int b = ((b1->b_max - b1->b_min) << B_SHIFT) * B_SCALE; + + *b2 = *b1; + + if (r > g) + { + if (b > r) set_avg(&b1->b_min, &b2->b_max); + else set_avg(&b1->r_min, &b2->r_max); + } + else + { + if (b > g) set_avg(&b1->b_min, &b2->b_max); + else set_avg(&b1->g_min, &b2->g_max); + } + + shrink_box(h, b1); + shrink_box(h, b2); +} + +/* find box suitable for split based on count */ +static struct box *find_box_max_count(struct box *b, int count) +{ + struct box *best = NULL; + for (; count--; b++) + if (b->score && (!best || b->count > best->count)) best = b; + return best; +} + +/* find box suitable for split based on score */ +static struct box *find_box_max_score(struct box *b, int count) +{ + struct box *best = NULL; + for (; count--; b++) + if (b->score && (!best || b->score > best->score)) best = b; + return best; +} + +/* compute color map with at most 'desired' colors + * image must be in 24bpp BGR format and colors are returned in 0xAARRGGBB format */ +static int median_cut(unsigned char *image, unsigned int width, unsigned int height, + unsigned int stride, int desired, unsigned int *colors) { - FIXME("(%p,%p,%u,%i): stub\n", iface, pISurface, colorCount, fAddTransparentColor); - return E_NOTIMPL; + struct box boxes[256]; + struct histogram *h; + unsigned int x, y; + unsigned char *p; + struct box *b1, *b2; + int numboxes, i; + + if (!(h = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*h)))) + return 0; + + for (y = 0; y < height; y++) + for (x = 0, p = image + y * stride; x < width; x++, p += 3) + h->data[p[2] >> R_SHIFT][p[1] >> G_SHIFT][p[0] >> B_SHIFT]++; + + numboxes = 1; + boxes[0].r_min = 0; boxes[0].r_max = R_COUNT - 1; + boxes[0].g_min = 0; boxes[0].g_max = G_COUNT - 1; + boxes[0].b_min = 0; boxes[0].b_max = B_COUNT - 1; + shrink_box(h, &boxes[0]); + + while (numboxes <= desired / 2) + { + if (!(b1 = find_box_max_count(boxes, numboxes))) break; + b2 = &boxes[numboxes++]; + split_box(h, b1, b2); + } + while (numboxes < desired) + { + if (!(b1 = find_box_max_score(boxes, numboxes))) break; + b2 = &boxes[numboxes++]; + split_box(h, b1, b2); + } + + for (i = 0; i < numboxes; i++) + colors[i] = box_color(h, &boxes[i]); + + HeapFree(GetProcessHeap(), 0, h); + return numboxes; +} + + +static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *palette, + IWICBitmapSource *source, UINT desired, BOOL add_transparent) +{ + IWICImagingFactory *factory = NULL; + IWICBitmap *rgb24_bitmap = NULL; + IWICBitmapSource *rgb24_source; + IWICBitmapLock *lock = NULL; + WICPixelFormatGUID format; + HRESULT hr; + UINT width, height, stride, size, actual_number_of_colors; + BYTE *src; + WICColor colors[256]; + + TRACE("(%p,%p,%u,%d)\n", palette, source, desired, add_transparent); + + if (!source || desired < 2 || desired > 256) + return E_INVALIDARG; + + hr = IWICBitmapSource_GetPixelFormat(source, &format); + if (hr != S_OK) return hr; + + /* For interoperability with gdiplus where PixelFormat24bppRGB actully stored + * as BGR (and there is no a corresponding RGB format) we have to use 24bppBGR + * to avoid format conversions. + */ + if (!IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR)) + { + hr = WICConvertBitmapSource(&GUID_WICPixelFormat24bppBGR, source, &rgb24_source); + if (hr != S_OK) return hr; + } + else + rgb24_source = source; + + hr = ComponentFactory_CreateInstance(&IID_IWICImagingFactory, (void **)&factory); + if (hr != S_OK) goto fail; + + hr = IWICImagingFactory_CreateBitmapFromSource(factory, rgb24_source, WICBitmapCacheOnLoad, &rgb24_bitmap); + if (hr != S_OK) goto fail; + + hr = IWICBitmap_Lock(rgb24_bitmap, NULL, WICBitmapLockRead, &lock); + if (hr != S_OK) goto fail; + + IWICBitmapLock_GetSize(lock, &width, &height); + IWICBitmapLock_GetStride(lock, &stride); + IWICBitmapLock_GetDataPointer(lock, &size, &src); + + actual_number_of_colors = median_cut(src, width, height, stride, add_transparent ? desired - 1 : desired, colors); + TRACE("actual number of colors: %u\n", actual_number_of_colors); + + if (actual_number_of_colors) + { + if (add_transparent) colors[actual_number_of_colors++] = 0; + + hr = IWICPalette_InitializeCustom(palette, colors, actual_number_of_colors); + } + else + hr = E_OUTOFMEMORY; + +fail: + if (lock) + IWICBitmapLock_Release(lock); + + if (rgb24_bitmap) + IWICBitmap_Release(rgb24_bitmap); + + if (factory) + IWICImagingFactory_Release(factory); + + if (rgb24_source != source) + IWICBitmapSource_Release(rgb24_source); + + return hr; } static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface, diff --git a/dll/win32/windowscodecs/pngformat.c b/dll/win32/windowscodecs/pngformat.c index 6946721b77..54be5edb45 100644 --- a/dll/win32/windowscodecs/pngformat.c +++ b/dll/win32/windowscodecs/pngformat.c @@ -17,12 +17,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" +#include "wine/port.h" + +#include <stdarg.h> #ifdef HAVE_PNG_H #include <png.h> #endif +#define NONAMELESSUNION +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" +#include "wine/library.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + static inline ULONG read_ulong_be(BYTE* data) { return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; @@ -605,7 +622,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); HeapFree(GetProcessHeap(), 0, row_pointers); This->png_ptr = NULL; - hr = E_FAIL; + hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; goto end; } ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); @@ -836,10 +853,14 @@ static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface, } static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) + IWICMetadataQueryReader **reader) { - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader); - return E_NOTIMPL; + FIXME("(%p,%p): stub\n", iface, reader); + + if (!reader) return E_INVALIDARG; + + *reader = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface, @@ -1969,11 +1990,22 @@ static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface, return E_NOTIMPL; } -static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) +static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) { - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICPngEncoder, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; } static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface, @@ -2016,7 +2048,11 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, { PngEncoder *This = impl_from_IWICBitmapEncoder(iface); HRESULT hr; - PROPBAG2 opts[2]= {{0}}; + static const PROPBAG2 opts[2] = + { + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption }, + }; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -2034,18 +2070,14 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, return WINCODEC_ERR_NOTINITIALIZED; } - 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, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions); - if (FAILED(hr)) + if (ppIEncoderOptions) { - LeaveCriticalSection(&This->lock); - return hr; + hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions); + if (FAILED(hr)) + { + LeaveCriticalSection(&This->lock); + return hr; + } } This->frame_count = 1; diff --git a/dll/win32/windowscodecs/precomp.h b/dll/win32/windowscodecs/precomp.h new file mode 100644 index 0000000000..7f4c241216 --- /dev/null +++ b/dll/win32/windowscodecs/precomp.h @@ -0,0 +1,30 @@ + +#ifndef WINCODECS_PRECOMP_H +#define WINCODECS_PRECOMP_H + +#include <wine/config.h> +#include <wine/port.h> + +#include <stdarg.h> + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include <windef.h> +#include <winbase.h> +#include <wingdi.h> +#include <winreg.h> +#include <objbase.h> +#include <oleauto.h> + +#include "wincodecs_private.h" + +#include <wine/debug.h> +#include <wine/library.h> + +#endif /* !WINCODECS_PRECOMP_H */ diff --git a/dll/win32/windowscodecs/propertybag.c b/dll/win32/windowscodecs/propertybag.c index 29f7ac969b..e9d1af9670 100644 --- a/dll/win32/windowscodecs/propertybag.c +++ b/dll/win32/windowscodecs/propertybag.c @@ -17,8 +17,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "wine/unicode.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct PropertyBag { IPropertyBag2 IPropertyBag2_iface; LONG ref; @@ -198,7 +213,7 @@ static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *p return S_OK; } -static HRESULT copy_propbag2(PROPBAG2 *dest, PROPBAG2 *src) +static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src) { dest->cfType = src->cfType; dest->clsid = src->clsid; @@ -263,7 +278,7 @@ static const IPropertyBag2Vtbl PropertyBag_Vtbl = { PropertyBag_LoadObject }; -HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count, +HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2) { UINT i; diff --git a/dll/win32/windowscodecs/proxy.c b/dll/win32/windowscodecs/proxy.c index 2482d4900e..a28b38681e 100644 --- a/dll/win32/windowscodecs/proxy.c +++ b/dll/win32/windowscodecs/proxy.c @@ -18,8 +18,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + HRESULT WINAPI IPropertyBag2_Write_Proxy(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *ppropbag, VARIANT *pvarValue) { diff --git a/dll/win32/windowscodecs/regsvr.c b/dll/win32/windowscodecs/regsvr.c index 756fb19651..328ea54c84 100644 --- a/dll/win32/windowscodecs/regsvr.c +++ b/dll/win32/windowscodecs/regsvr.c @@ -16,9 +16,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS +#include <stdarg.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" + +#include "objbase.h" +#include "ocidl.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + #include "wincodecs_private.h" -#include <shlwapi.h> +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); /*********************************************************************** * interface for self-registering @@ -1194,6 +1211,10 @@ static GUID const * const tiff_decode_formats[] = { &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat8bppGray, + &GUID_WICPixelFormat16bppGray, + &GUID_WICPixelFormat32bppGrayFloat, + &GUID_WICPixelFormat1bppIndexed, + &GUID_WICPixelFormat2bppIndexed, &GUID_WICPixelFormat4bppIndexed, &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat24bppBGR, @@ -1203,6 +1224,9 @@ static GUID const * const tiff_decode_formats[] = { &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat64bppRGBA, &GUID_WICPixelFormat64bppPRGBA, + &GUID_WICPixelFormat32bppCMYK, + &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat128bppRGBAFloat, NULL }; @@ -1328,6 +1352,11 @@ static GUID const * const bmp_encode_formats[] = { &GUID_WICPixelFormat16bppBGR565, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormatBlackWhite, + &GUID_WICPixelFormat1bppIndexed, + &GUID_WICPixelFormat2bppIndexed, + &GUID_WICPixelFormat4bppIndexed, + &GUID_WICPixelFormat8bppIndexed, NULL }; @@ -1353,6 +1382,10 @@ static GUID const * const tiff_encode_formats[] = { &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat8bppGray, + &GUID_WICPixelFormat1bppIndexed, + &GUID_WICPixelFormat2bppIndexed, + &GUID_WICPixelFormat4bppIndexed, + &GUID_WICPixelFormat8bppIndexed, &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat32bppBGRA, &GUID_WICPixelFormat32bppPBGRA, @@ -1378,6 +1411,16 @@ static struct regsvr_encoder const encoder_list[] = { ".bmp,.dib,.rle", bmp_encode_formats }, + { &CLSID_WICGifEncoder, + "The Wine Project", + "GIF Encoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatGif, + "image/gif", + ".gif", + gif_formats + }, { &CLSID_WICJpegEncoder, "The Wine Project", "JPEG Encoder", @@ -1437,8 +1480,11 @@ static GUID const * const converter_formats[] = { &GUID_WICPixelFormat24bppBGR, &GUID_WICPixelFormat24bppRGB, &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppRGB, &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppRGBA, &GUID_WICPixelFormat32bppPBGRA, + &GUID_WICPixelFormat32bppPRGBA, &GUID_WICPixelFormat32bppGrayFloat, &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat64bppRGBA, @@ -1710,6 +1756,13 @@ static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; +static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; + +static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; + static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 }; static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 }; static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c }; @@ -1726,6 +1779,9 @@ static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit, static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; +static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; +static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; + static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 }; @@ -1742,7 +1798,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { 1, /* channel count */ channel_masks_1bit, WICPixelFormatNumericRepresentationIndexed, - 1 + 0 }, { &GUID_WICPixelFormat2bppIndexed, "The Wine Project", @@ -1753,7 +1809,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { 1, /* channel count */ channel_masks_2bit, WICPixelFormatNumericRepresentationIndexed, - 1 + 0 }, { &GUID_WICPixelFormat4bppIndexed, "The Wine Project", @@ -1764,7 +1820,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { 1, /* channel count */ channel_masks_4bit, WICPixelFormatNumericRepresentationIndexed, - 1 + 0 }, { &GUID_WICPixelFormat8bppIndexed, "The Wine Project", @@ -1775,7 +1831,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { 1, /* channel count */ channel_masks_8bit, WICPixelFormatNumericRepresentationIndexed, - 1 + 0 }, { &GUID_WICPixelFormatBlackWhite, "The Wine Project", @@ -1898,6 +1954,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 0 }, + { &GUID_WICPixelFormat32bppRGB, + "The Wine Project", + "32bpp RGB", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 32, /* bitsperpixel */ + 3, /* channel count */ + channel_masks_8bit, + WICPixelFormatNumericRepresentationUnsignedInteger, + 0 + }, { &GUID_WICPixelFormat32bppBGRA, "The Wine Project", "32bpp BGRA", @@ -1909,6 +1976,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 1 }, + { &GUID_WICPixelFormat32bppRGBA, + "The Wine Project", + "32bpp RGBA", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 32, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_8bit, + WICPixelFormatNumericRepresentationUnsignedInteger, + 1 + }, { &GUID_WICPixelFormat32bppPBGRA, "The Wine Project", "32bpp PBGRA", @@ -1920,6 +1998,28 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 1 }, + { &GUID_WICPixelFormat32bppPRGBA, + "The Wine Project", + "32bpp PRGBA", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 32, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_8bit, + WICPixelFormatNumericRepresentationUnsignedInteger, + 1 + }, + { &GUID_WICPixelFormat32bppGrayFloat, + "The Wine Project", + "32bpp GrayFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 32, /* bitsperpixel */ + 1, /* channel count */ + channel_masks_32bit, + WICPixelFormatNumericRepresentationFloat, + 0 + }, { &GUID_WICPixelFormat48bppRGB, "The Wine Project", "48bpp RGB", @@ -1964,6 +2064,28 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 0 }, + { &GUID_WICPixelFormat64bppCMYK, + "The Wine Project", + "64bpp CMYK", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 64, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_16bit, + WICPixelFormatNumericRepresentationUnsignedInteger, + 0 + }, + { &GUID_WICPixelFormat128bppRGBAFloat, + "The Wine Project", + "128bpp RGBAFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 128, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_128bit, + WICPixelFormatNumericRepresentationFloat, + 1 + }, { NULL } /* list terminator */ }; diff --git a/dll/win32/windowscodecs/scaler.c b/dll/win32/windowscodecs/scaler.c index 8e267e314a..3801ea5ecd 100644 --- a/dll/win32/windowscodecs/scaler.c +++ b/dll/win32/windowscodecs/scaler.c @@ -16,11 +16,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + typedef struct BitmapScaler { IWICBitmapScaler IWICBitmapScaler_iface; LONG ref; + IMILBitmapScaler IMILBitmapScaler_iface; IWICBitmapSource *source; UINT width, height; UINT src_width, src_height; @@ -36,6 +51,11 @@ static inline BitmapScaler *impl_from_IWICBitmapScaler(IWICBitmapScaler *iface) return CONTAINING_RECORD(iface, BitmapScaler, IWICBitmapScaler_iface); } +static inline BitmapScaler *impl_from_IMILBitmapScaler(IMILBitmapScaler *iface) +{ + return CONTAINING_RECORD(iface, BitmapScaler, IMILBitmapScaler_iface); +} + static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFIID iid, void **ppv) { @@ -50,8 +70,13 @@ static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFII { *ppv = &This->IWICBitmapScaler_iface; } + else if (IsEqualIID(&IID_IMILBitmapScaler, iid)) + { + *ppv = &This->IMILBitmapScaler_iface; + } else { + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -360,6 +385,163 @@ static const IWICBitmapScalerVtbl BitmapScaler_Vtbl = { BitmapScaler_Initialize }; +static HRESULT WINAPI IMILBitmapScaler_QueryInterface(IMILBitmapScaler *iface, REFIID iid, + void **ppv) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IMILBitmapScaler, iid) || + IsEqualIID(&IID_IMILBitmapSource, iid)) + { + IUnknown_AddRef(&This->IMILBitmapScaler_iface); + *ppv = &This->IMILBitmapScaler_iface; + return S_OK; + } + else if (IsEqualIID(&IID_IWICBitmapScaler, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid)) + { + IUnknown_AddRef(&This->IWICBitmapScaler_iface); + *ppv = &This->IWICBitmapScaler_iface; + return S_OK; + } + + FIXME("unknown interface %s\n", debugstr_guid(iid)); + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI IMILBitmapScaler_AddRef(IMILBitmapScaler *iface) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + return IWICBitmapScaler_AddRef(&This->IWICBitmapScaler_iface); +} + +static ULONG WINAPI IMILBitmapScaler_Release(IMILBitmapScaler *iface) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + return IWICBitmapScaler_Release(&This->IWICBitmapScaler_iface); +} + +static HRESULT WINAPI IMILBitmapScaler_GetSize(IMILBitmapScaler *iface, + UINT *width, UINT *height) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + + TRACE("(%p,%p,%p)\n", iface, width, height); + + if (!This->source) + return WINCODEC_ERR_NOTINITIALIZED; + + return IWICBitmapScaler_GetSize(&This->IWICBitmapScaler_iface, width, height); +} + +static HRESULT WINAPI IMILBitmapScaler_GetPixelFormat(IMILBitmapScaler *iface, + int *format) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + IMILBitmapSource *source; + HRESULT hr; + + TRACE("(%p,%p)\n", iface, format); + + if (!format) return E_INVALIDARG; + + if (!This->source) + return WINCODEC_ERR_NOTINITIALIZED; + + hr = IWICBitmapSource_QueryInterface(This->source, &IID_IMILBitmapSource, (void **)&source); + if (hr == S_OK) + { + hr = source->lpVtbl->GetPixelFormat(source, format); + source->lpVtbl->Release(source); + } + return hr; +} + +static HRESULT WINAPI IMILBitmapScaler_GetResolution(IMILBitmapScaler *iface, + double *dpix, double *dpiy) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + + TRACE("(%p,%p,%p)\n", iface, dpix, dpiy); + + if (!This->source) + return WINCODEC_ERR_NOTINITIALIZED; + + return IWICBitmapScaler_GetResolution(&This->IWICBitmapScaler_iface, dpix, dpiy); +} + +static HRESULT WINAPI IMILBitmapScaler_CopyPalette(IMILBitmapScaler *iface, + IWICPalette *palette) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + + TRACE("(%p,%p)\n", iface, palette); + + if (!This->source) + return WINCODEC_ERR_NOTINITIALIZED; + + return IWICBitmapScaler_CopyPalette(&This->IWICBitmapScaler_iface, palette); +} + +static HRESULT WINAPI IMILBitmapScaler_CopyPixels(IMILBitmapScaler *iface, + const WICRect *rc, UINT stride, UINT size, BYTE *buffer) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + + TRACE("(%p,%p,%u,%u,%p)\n", iface, rc, stride, size, buffer); + + if (!This->source) + return WINCODEC_ERR_NOTINITIALIZED; + + return IWICBitmapScaler_CopyPixels(&This->IWICBitmapScaler_iface, rc, stride, size, buffer); +} + +static HRESULT WINAPI IMILBitmapScaler_unknown1(IMILBitmapScaler *iface, void **ppv) +{ + TRACE("(%p,%p)\n", iface, ppv); + return E_NOINTERFACE; +} + +static HRESULT WINAPI IMILBitmapScaler_Initialize(IMILBitmapScaler *iface, + IMILBitmapSource *mil_source, UINT width, UINT height, + WICBitmapInterpolationMode mode) +{ + BitmapScaler *This = impl_from_IMILBitmapScaler(iface); + IWICBitmapSource *wic_source; + HRESULT hr; + + TRACE("(%p,%p,%u,%u,%u)\n", iface, mil_source, width, height, mode); + + if (!mil_source) return E_INVALIDARG; + + hr = mil_source->lpVtbl->QueryInterface(mil_source, &IID_IWICBitmapSource, (void **)&wic_source); + if (hr == S_OK) + { + hr = IWICBitmapScaler_Initialize(&This->IWICBitmapScaler_iface, wic_source, width, height, mode); + IWICBitmapSource_Release(wic_source); + } + return hr; +} + +static const IMILBitmapScalerVtbl IMILBitmapScaler_Vtbl = { + IMILBitmapScaler_QueryInterface, + IMILBitmapScaler_AddRef, + IMILBitmapScaler_Release, + IMILBitmapScaler_GetSize, + IMILBitmapScaler_GetPixelFormat, + IMILBitmapScaler_GetResolution, + IMILBitmapScaler_CopyPalette, + IMILBitmapScaler_CopyPixels, + IMILBitmapScaler_unknown1, + IMILBitmapScaler_Initialize +}; + HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) { BitmapScaler *This; @@ -368,6 +550,7 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) if (!This) return E_OUTOFMEMORY; This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl; + This->IMILBitmapScaler_iface.lpVtbl = &IMILBitmapScaler_Vtbl; This->ref = 1; This->source = NULL; This->width = 0; diff --git a/dll/win32/windowscodecs/stream.c b/dll/win32/windowscodecs/stream.c index f585036ede..308ef8e02b 100644 --- a/dll/win32/windowscodecs/stream.c +++ b/dll/win32/windowscodecs/stream.c @@ -16,9 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "wine/debug.h" + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "shlwapi.h" #include "wincodecs_private.h" -#include <shlwapi.h> +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); /****************************************** * StreamOnMemory implementation diff --git a/dll/win32/windowscodecs/tgaformat.c b/dll/win32/windowscodecs/tgaformat.c index 52b5877095..ec7fa23169 100644 --- a/dll/win32/windowscodecs/tgaformat.c +++ b/dll/win32/windowscodecs/tgaformat.c @@ -16,8 +16,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + #include "wincodecs_private.h" +#include "wine/debug.h" +#include "wine/library.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + #include "pshpack1.h" typedef struct { diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c index 55423028a4..c23594f61f 100644 --- a/dll/win32/windowscodecs/tiffformat.c +++ b/dll/win32/windowscodecs/tiffformat.c @@ -1,5 +1,6 @@ /* * Copyright 2010 Vincent Povirk for CodeWeavers + * Copyright 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 @@ -16,8 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wincodecs_private.h" +#include "config.h" +#include "wine/port.h" +#include <stdarg.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -25,6 +28,19 @@ #include <tiffio.h> #endif +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" +#include "wine/library.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + #ifdef SONAME_LIBTIFF /* Workaround for broken libtiff 4.x headers on some 64-bit hosts which @@ -303,6 +319,8 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) } decode_info->planar = planar; + TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); + switch(photometric) { case 0: /* WhiteIsZero */ @@ -367,14 +385,28 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) } } break; + case 16: + if (samples != 1) + { + FIXME("unhandled 16bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->format = &GUID_WICPixelFormat16bppGray; + break; + case 32: + if (samples != 1) + { + FIXME("unhandled 32bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->format = &GUID_WICPixelFormat32bppGrayFloat; + break; default: - FIXME("unhandled greyscale bit count %u\n", bps); - return E_FAIL; + WARN("unhandled greyscale bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; } break; case 2: /* RGB */ - decode_info->bpp = bps * samples; - if (samples == 4) { ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); @@ -391,8 +423,12 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) return E_FAIL; } + decode_info->bpp = max(bps, 8) * samples; + decode_info->source_bpp = bps * samples; switch(bps) { + case 1: + case 4: case 8: decode_info->reverse_bgr = 1; if (samples == 3) @@ -430,9 +466,17 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) return E_FAIL; } break; + case 32: + if (samples != 4) + { + FIXME("unhandled 32bpp RGB sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat; + break; default: - FIXME("unhandled RGB bit count %u\n", bps); - return E_FAIL; + WARN("unhandled RGB bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; } break; case 3: /* RGB Palette */ @@ -446,6 +490,12 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) decode_info->bpp = bps; switch (bps) { + case 1: + decode_info->format = &GUID_WICPixelFormat1bppIndexed; + break; + case 2: + decode_info->format = &GUID_WICPixelFormat2bppIndexed; + break; case 4: decode_info->format = &GUID_WICPixelFormat4bppIndexed; break; @@ -457,8 +507,31 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) return E_FAIL; } break; + + case 5: /* Separated */ + if (samples != 4) + { + FIXME("unhandled Separated sample count %u\n", samples); + return E_FAIL; + } + + decode_info->bpp = bps * samples; + switch(bps) + { + case 8: + decode_info->format = &GUID_WICPixelFormat32bppCMYK; + break; + case 16: + decode_info->format = &GUID_WICPixelFormat64bppCMYK; + break; + + default: + WARN("unhandled Separated bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 4: /* Transparency mask */ - case 5: /* CMYK */ case 6: /* YCbCr */ case 8: /* CIELab */ default: @@ -514,21 +587,27 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) decode_info->resolution_unit = 0; pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &decode_info->resolution_unit); - if (decode_info->resolution_unit != 0) + + ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres); + if (!ret) { - ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres); - if (!ret) - { - WARN("missing X resolution\n"); - decode_info->resolution_unit = 0; - } + WARN("missing X resolution\n"); + } + /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131) + * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */ + if (!isfinite(decode_info->xres)) + { + decode_info->xres = 0.0; + } - ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres); - if (!ret) - { - WARN("missing Y resolution\n"); - decode_info->resolution_unit = 0; - } + ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres); + if (!ret) + { + WARN("missing Y resolution\n"); + } + if (!isfinite(decode_info->yres)) + { + decode_info->yres = 0.0; } return S_OK; @@ -609,6 +688,7 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream * { TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); TIFF *tiff; + tiff_decode_info decode_info; HRESULT hr=S_OK; TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); @@ -622,13 +702,20 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream * } tiff = tiff_open_stream(pIStream, "r"); - if (!tiff) { hr = E_FAIL; goto exit; } + /* make sure that TIFF format is supported */ + hr = tiff_get_decode_info(tiff, &decode_info); + if (hr != S_OK) + { + pTIFFClose(tiff); + goto exit; + } + This->tiff = tiff; This->stream = pIStream; IStream_AddRef(pIStream); @@ -677,8 +764,12 @@ static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface, static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, IWICMetadataQueryReader **ppIMetadataQueryReader) { - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); + + if (!ppIMetadataQueryReader) return E_INVALIDARG; + + *ppIMetadataQueryReader = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface, @@ -878,26 +969,28 @@ static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface { TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - switch (This->decode_info.resolution_unit) + if (This->decode_info.xres == 0 || This->decode_info.yres == 0) { - default: - FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit); - /* fall through */ - case 0: /* Not set */ *pDpiX = *pDpiY = 96.0; - break; - case 1: /* Relative measurements */ - *pDpiX = 96.0; - *pDpiY = 96.0 * This->decode_info.yres / This->decode_info.xres; - break; - case 2: /* Inch */ - *pDpiX = This->decode_info.xres; - *pDpiY = This->decode_info.yres; - break; - case 3: /* Centimeter */ - *pDpiX = This->decode_info.xres / 2.54; - *pDpiY = This->decode_info.yres / 2.54; - break; + } + else + { + switch (This->decode_info.resolution_unit) + { + default: + FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit); + /* fall through */ + case 0: /* Not set */ + case 1: /* Relative measurements */ + case 2: /* Inch */ + *pDpiX = This->decode_info.xres; + *pDpiY = This->decode_info.yres; + break; + case 3: /* Centimeter */ + *pDpiX = This->decode_info.xres * 2.54; + *pDpiY = This->decode_info.yres * 2.54; + break; + } } TRACE("(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY, This->decode_info.resolution_unit); @@ -940,34 +1033,183 @@ static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y) { - HRESULT hr=S_OK; tsize_t ret; int swap_bytes; swap_bytes = pTIFFIsByteSwapped(This->parent->tiff); ret = pTIFFSetDirectory(This->parent->tiff, This->index); + if (ret == -1) + return E_FAIL; + + if (This->decode_info.tiled) + ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); + else + ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); if (ret == -1) - hr = E_FAIL; + return E_FAIL; - if (hr == S_OK) + /* 3bpp RGB */ + if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) { - if (This->decode_info.tiled) + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; + + count = width_bytes * This->decode_info.tile_height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < This->decode_info.tile_height; y++) { - ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * This->decode_info.tile_width * 3; + + for (x = 0; x < This->decode_info.tile_width; x += 8) + { + dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ + dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ + dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ + if (x + 1 < This->decode_info.tile_width) + { + dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ + dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ + dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ + } + if (x + 2 < This->decode_info.tile_width) + { + dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ + dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ + dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ + } + if (x + 3 < This->decode_info.tile_width) + { + dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ + dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ + dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ + } + if (x + 4 < This->decode_info.tile_width) + { + dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ + dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ + dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ + } + if (x + 5 < This->decode_info.tile_width) + { + dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ + dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ + dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ + } + if (x + 6 < This->decode_info.tile_width) + { + dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ + dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ + dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ + } + if (x + 7 < This->decode_info.tile_width) + { + dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ + dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ + dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ + } + src += 3; + dst += 24; + } } - else + + HeapFree(GetProcessHeap(), 0, srcdata); + } + /* 12bpp RGB */ + else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8; + + count = width_bytes * This->decode_info.tile_height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < This->decode_info.tile_height; y++) { - ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * This->decode_info.tile_width * 3; + + for (x = 0; x < This->decode_info.tile_width; x += 2) + { + dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (src[0] & 0x0f) * 17; /* G */ + dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ + if (x + 1 < This->decode_info.tile_width) + { + dst[5] = (src[1] & 0x0f) * 17; /* B */ + dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ + dst[3] = (src[2] & 0x0f) * 17; /* R */ + } + src += 3; + dst += 6; + } } - if (ret == -1) - hr = E_FAIL; + HeapFree(GetProcessHeap(), 0, srcdata); } + /* 4bpp RGBA */ + else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) + { + BYTE *src, *dst; + DWORD count; + + /* 1 source byte expands to 2 BGRA samples */ + count = (This->decode_info.tile_width * This->decode_info.tile_height + 1) / 2; + + src = This->cached_tile + count - 1; + dst = This->cached_tile + This->decode_info.tile_size; + while (count--) + { + BYTE b = *src--; + + dst -= 8; + dst[2] = (b & 0x80) ? 0xff : 0; /* R */ + dst[1] = (b & 0x40) ? 0xff : 0; /* G */ + dst[0] = (b & 0x20) ? 0xff : 0; /* B */ + dst[3] = (b & 0x10) ? 0xff : 0; /* A */ + dst[6] = (b & 0x08) ? 0xff : 0; /* R */ + dst[5] = (b & 0x04) ? 0xff : 0; /* G */ + dst[4] = (b & 0x02) ? 0xff : 0; /* B */ + dst[7] = (b & 0x01) ? 0xff : 0; /* A */ + } + } + /* 16bpp RGBA */ + else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) + { + BYTE *src, *dst; + DWORD count = This->decode_info.tile_width * This->decode_info.tile_height; + + src = This->cached_tile + count * 2; + dst = This->cached_tile + This->decode_info.tile_size; + + while (count--) + { + BYTE b[2]; + + src -= 2; + dst -= 4; + + b[0] = src[0]; + b[1] = src[1]; + + dst[0] = ((b[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (b[0] & 0x0f) * 17; /* G */ + dst[2] = ((b[0] & 0xf0) >> 4) * 17; /* R */ + dst[3] = (b[1] & 0x0f) * 17; /* A */ + } + } /* 8bpp grayscale with extra alpha */ - if (hr == S_OK && This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) { BYTE *src; DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; @@ -982,7 +1224,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT } } - if (hr == S_OK && This->decode_info.reverse_bgr) + if (This->decode_info.reverse_bgr) { if (This->decode_info.bps == 8) { @@ -993,7 +1235,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT } } - if (hr == S_OK && swap_bytes && This->decode_info.bps > 8) + if (swap_bytes && This->decode_info.bps > 8) { UINT row, i, samples_per_row; BYTE *sample, temp; @@ -1021,7 +1263,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT } } - if (hr == S_OK && This->decode_info.invert_grayscale) + if (This->decode_info.invert_grayscale) { BYTE *byte, *end; @@ -1037,13 +1279,10 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT *byte = ~(*byte); } - if (hr == S_OK) - { - This->cached_tile_x = tile_x; - This->cached_tile_y = tile_y; - } + This->cached_tile_x = tile_x; + This->cached_tile_y = tile_y; - return hr; + return S_OK; } static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, @@ -1080,7 +1319,7 @@ static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, if (cbStride < bytesperrow) return E_INVALIDARG; - if ((cbStride * prc->Height) > cbBufferSize) + if ((cbStride * (prc->Height-1)) + ((prc->Width * This->decode_info.bpp) + 7)/8 > cbBufferSize) return E_INVALIDARG; min_tile_x = prc->X / This->decode_info.tile_width; @@ -1394,6 +1633,10 @@ static const struct tiff_encode_format formats[] = { {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0}, {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0}, {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0}, + {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0}, + {&GUID_WICPixelFormat2bppIndexed, 3, 2, 1, 2, 0, 0, 0}, + {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0}, + {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0}, {0} }; @@ -1676,6 +1919,21 @@ static HRESULT WINAPI TiffFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, pTIFFSetField(This->parent->tiff, TIFFTAG_YRESOLUTION, (float)This->yres); } + if (This->format->bpp <= 8 && This->colors && !IsEqualGUID(This->format->guid, &GUID_WICPixelFormatBlackWhite)) + { + uint16 red[256], green[256], blue[256]; + UINT i; + + for (i = 0; i < This->colors; i++) + { + red[i] = (This->palette[i] >> 8) & 0xff00; + green[i] = This->palette[i] & 0xff00; + blue[i] = (This->palette[i] << 8) & 0xff00; + } + + pTIFFSetField(This->parent->tiff, TIFFTAG_COLORMAP, red, green, blue); + } + This->info_written = TRUE; } @@ -1874,11 +2132,22 @@ static HRESULT WINAPI TiffEncoder_GetContainerFormat(IWICBitmapEncoder *iface, return S_OK; } -static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) +static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) { - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICTiffEncoder, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; } static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface, @@ -1921,7 +2190,11 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface, { TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); TiffFrameEncode *result; - + static const PROPBAG2 opts[2] = + { + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszTiffCompressionMethod }, + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszCompressionQuality }, + }; HRESULT hr=S_OK; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -1938,26 +2211,16 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface, hr = E_FAIL; } - if (SUCCEEDED(hr)) + if (ppIEncoderOptions && SUCCEEDED(hr)) { - PROPBAG2 opts[2]= {{0}}; - opts[0].pstrName = (LPOLESTR)wszTiffCompressionMethod; - opts[0].vt = VT_UI1; - opts[0].dwType = PROPBAG2_TYPE_DATA; - - opts[1].pstrName = (LPOLESTR)wszCompressionQuality; - opts[1].vt = VT_R4; - opts[1].dwType = PROPBAG2_TYPE_DATA; - - hr = CreatePropertyBag2(opts, 2, ppIEncoderOptions); - + hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions); if (SUCCEEDED(hr)) { VARIANT v; VariantInit(&v); V_VT(&v) = VT_UI1; - V_UNION(&v, bVal) = WICTiffCompressionDontCare; - hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, opts, &v); + V_UI1(&v) = WICTiffCompressionDontCare; + hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, (PROPBAG2 *)opts, &v); VariantClear(&v); if (FAILED(hr)) { diff --git a/dll/win32/windowscodecs/ungif.c b/dll/win32/windowscodecs/ungif.c index 28d76e5ace..c6711c8e24 100644 --- a/dll/win32/windowscodecs/ungif.c +++ b/dll/win32/windowscodecs/ungif.c @@ -47,9 +47,16 @@ * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *****************************************************************************/ -#include "wincodecs_private.h" +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" #include "ungif.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); static void *ungif_alloc( size_t sz ) { diff --git a/dll/win32/windowscodecs/wincodecs_private.h b/dll/win32/windowscodecs/wincodecs_private.h index 99daf093ad..2f9f6d0b58 100644 --- a/dll/win32/windowscodecs/wincodecs_private.h +++ b/dll/win32/windowscodecs/wincodecs_private.h @@ -19,33 +19,9 @@ #ifndef WINCODECS_PRIVATE_H #define WINCODECS_PRIVATE_H -#include <wine/config.h> -#include <wine/port.h> - -#include <stdarg.h> - -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - -#define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include <windef.h> -#include <winbase.h> -#include <wingdi.h> -#include <winreg.h> -#include <objbase.h> -#include <oleauto.h> -#include <wincodec.h> -#include <wincodecsdk.h> - -#include <wine/debug.h> -#include <wine/library.h> -#include <wine/unicode.h> - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +#include "wincodec.h" +#include "wincodecsdk.h" +#include "wine/unicode.h" DEFINE_GUID(CLSID_WineTgaDecoder, 0xb11fc79a,0x67cc,0x43e6,0xa9,0xce,0xe3,0xd5,0x49,0x45,0xd3,0x04); @@ -55,7 +31,13 @@ DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47 DEFINE_GUID(GUID_VendorWine, 0xddf46da1,0x7dc1,0x404e,0x98,0xf2,0xef,0xa4,0x8d,0xfc,0x95,0x0a); +DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); +DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); +DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); +DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); +DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); + #define INTERFACE IMILBitmapSource DECLARE_INTERFACE_(IMILBitmapSource,IUnknown) { @@ -63,16 +45,58 @@ DECLARE_INTERFACE_(IMILBitmapSource,IUnknown) STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID,void **) PURE; ... 156 lines suppressed ...
6 years, 9 months
1
0
0
0
01/01: [D3DCOMPILER_43] Sync with Wine Staging 3.3. CORE-14434
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8d718da3924b20d7b2b9…
commit a8d718da3924b20d7b2b93b67004d1692d2af3f1 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Mar 5 00:15:03 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Mar 5 00:15:03 2018 +0100 [D3DCOMPILER_43] Sync with Wine Staging 3.3. CORE-14434 --- dll/directx/wine/d3dcompiler_43/CMakeLists.txt | 4 +- dll/directx/wine/d3dcompiler_43/asmparser.c | 4 + dll/directx/wine/d3dcompiler_43/blob.c | 3 + dll/directx/wine/d3dcompiler_43/bytecodewriter.c | 6 +- dll/directx/wine/d3dcompiler_43/compiler.c | 15 +- .../wine/d3dcompiler_43/d3dcompiler_private.h | 23 +- dll/directx/wine/d3dcompiler_43/hlsl.tab.c | 694 +++++++++++---------- dll/directx/wine/d3dcompiler_43/hlsl.tab.h | 8 +- dll/directx/wine/d3dcompiler_43/hlsl.y | 4 + dll/directx/wine/d3dcompiler_43/hlsl.yy.c | 69 +- dll/directx/wine/d3dcompiler_43/main.c | 7 + dll/directx/wine/d3dcompiler_43/precomp.h | 12 + dll/directx/wine/d3dcompiler_43/reflection.c | 3 + dll/directx/wine/d3dcompiler_43/utils.c | 5 + media/doc/README.WINE | 2 +- 15 files changed, 451 insertions(+), 408 deletions(-) diff --git a/dll/directx/wine/d3dcompiler_43/CMakeLists.txt b/dll/directx/wine/d3dcompiler_43/CMakeLists.txt index 245ffd9ab3..d00c1b69ec 100644 --- a/dll/directx/wine/d3dcompiler_43/CMakeLists.txt +++ b/dll/directx/wine/d3dcompiler_43/CMakeLists.txt @@ -18,7 +18,7 @@ list(APPEND SOURCE main.c reflection.c utils.c - d3dcompiler_private.h + precomp.h ${CMAKE_CURRENT_BINARY_DIR}/d3dcompiler_43_stubs.c) add_library(d3dcompiler_43 SHARED @@ -30,5 +30,5 @@ set_module_type(d3dcompiler_43 win32dll) target_link_libraries(d3dcompiler_43 dx10guid uuid wine wpp) add_importlibs(d3dcompiler_43 msvcrt kernel32 ntdll) add_dependencies(d3dcompiler_43 d3d_idl_headers) -add_pch(d3dcompiler_43 d3dcompiler_private.h SOURCE) +add_pch(d3dcompiler_43 precomp.h SOURCE) add_cd_file(TARGET d3dcompiler_43 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3dcompiler_43/asmparser.c b/dll/directx/wine/d3dcompiler_43/asmparser.c index 1e7d107276..2d167dece5 100644 --- a/dll/directx/wine/d3dcompiler_43/asmparser.c +++ b/dll/directx/wine/d3dcompiler_43/asmparser.c @@ -20,6 +20,10 @@ * */ +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + #include "d3dcompiler_private.h" WINE_DEFAULT_DEBUG_CHANNEL(asmshader); diff --git a/dll/directx/wine/d3dcompiler_43/blob.c b/dll/directx/wine/d3dcompiler_43/blob.c index 896038a9d0..f22dc7183d 100644 --- a/dll/directx/wine/d3dcompiler_43/blob.c +++ b/dll/directx/wine/d3dcompiler_43/blob.c @@ -19,6 +19,9 @@ * */ +#include "config.h" +#include "wine/port.h" + #include "d3dcompiler_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); diff --git a/dll/directx/wine/d3dcompiler_43/bytecodewriter.c b/dll/directx/wine/d3dcompiler_43/bytecodewriter.c index 2b36319b83..a3e6f63fd9 100644 --- a/dll/directx/wine/d3dcompiler_43/bytecodewriter.c +++ b/dll/directx/wine/d3dcompiler_43/bytecodewriter.c @@ -20,8 +20,12 @@ * */ -#include "d3dcompiler_private.h" +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + #include "d3d9types.h" +#include "d3dcompiler_private.h" WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter); diff --git a/dll/directx/wine/d3dcompiler_43/compiler.c b/dll/directx/wine/d3dcompiler_43/compiler.c index 9d5e20ce4d..cf75cd516c 100644 --- a/dll/directx/wine/d3dcompiler_43/compiler.c +++ b/dll/directx/wine/d3dcompiler_43/compiler.c @@ -17,8 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "d3dcompiler_private.h" +#define COBJMACROS +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" #include "wine/unicode.h" + +#include "d3dcompiler_private.h" #include "wine/wpp.h" WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); @@ -787,3 +792,11 @@ HRESULT WINAPI D3DCompileFromFile(const WCHAR *filename, const D3D_SHADER_MACRO return E_NOTIMPL; } + +#ifndef __REACTOS__ +HRESULT WINAPI D3DLoadModule(const void *data, SIZE_T size, ID3D11Module **module) +{ + FIXME("data %p, size %lu, module %p stub!\n", data, size, module); + return E_NOTIMPL; +} +#endif diff --git a/dll/directx/wine/d3dcompiler_43/d3dcompiler_private.h b/dll/directx/wine/d3dcompiler_43/d3dcompiler_private.h index c7ed2e9597..1eea0d242c 100644 --- a/dll/directx/wine/d3dcompiler_43/d3dcompiler_private.h +++ b/dll/directx/wine/d3dcompiler_43/d3dcompiler_private.h @@ -22,21 +22,18 @@ #ifndef __WINE_D3DCOMPILER_PRIVATE_H #define __WINE_D3DCOMPILER_PRIVATE_H -#include <config.h> -#include <wine/port.h> - -#include <assert.h> -#include <stdio.h> +#include "wine/debug.h" +#include "wine/list.h" +#include "wine/rbtree.h" #define COBJMACROS -#include <windef.h> -#include <winbase.h> -#include <objbase.h> -#include <d3dcompiler.h> - -#include <wine/debug.h> -#include <wine/list.h> -#include <wine/rbtree.h> +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "d3dcompiler.h" + +#include <assert.h> /* * This doesn't belong here, but for some functions it is possible to return that value, diff --git a/dll/directx/wine/d3dcompiler_43/hlsl.tab.c b/dll/directx/wine/d3dcompiler_43/hlsl.tab.c index 5b6d4d7f6b..465416c053 100644 --- a/dll/directx/wine/d3dcompiler_43/hlsl.tab.c +++ b/dll/directx/wine/d3dcompiler_43/hlsl.tab.c @@ -73,6 +73,10 @@ /* Copy the first part of user declarations. */ #line 21 "hlsl.y" /* yacc.c:339 */ +#include "config.h" +#include "wine/debug.h" + +#include <stdio.h> #include "d3dcompiler_private.h" @@ -951,7 +955,7 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr } -#line 955 "hlsl.tab.c" /* yacc.c:339 */ +#line 959 "hlsl.tab.c" /* yacc.c:339 */ # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus @@ -971,8 +975,8 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr /* In a future release of Bison, this section will be replaced by #include "hlsl.tab.h". */ -#ifndef YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED -# define YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED +#ifndef YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED +# define YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -1096,7 +1100,7 @@ extern int hlsl_debug; typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 906 "hlsl.y" /* yacc.c:355 */ +#line 910 "hlsl.y" /* yacc.c:355 */ struct hlsl_type *type; INT intval; @@ -1116,7 +1120,7 @@ union YYSTYPE struct reg_reservation *reg_reservation; struct parse_colon_attribute colon_attribute; -#line 1120 "hlsl.tab.c" /* yacc.c:355 */ +#line 1124 "hlsl.tab.c" /* yacc.c:355 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 @@ -1141,11 +1145,11 @@ extern YYSTYPE hlsl_lval; extern YYLTYPE hlsl_lloc; int hlsl_parse (void); -#endif /* !YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED */ +#endif /* !YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 1149 "hlsl.tab.c" /* yacc.c:358 */ +#line 1153 "hlsl.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -1435,24 +1439,24 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 1091, 1091, 1093, 1130, 1134, 1137, 1142, 1164, 1181, - 1182, 1184, 1210, 1220, 1221, 1222, 1225, 1229, 1248, 1252, - 1257, 1264, 1271, 1301, 1306, 1313, 1317, 1318, 1321, 1325, - 1330, 1336, 1342, 1347, 1356, 1361, 1366, 1380, 1394, 1405, - 1408, 1419, 1423, 1427, 1432, 1436, 1455, 1475, 1479, 1484, - 1489, 1494, 1499, 1504, 1512, 1530, 1531, 1532, 1543, 1551, - 1560, 1566, 1572, 1580, 1586, 1589, 1594, 1600, 1606, 1615, - 1628, 1631, 1639, 1642, 1646, 1650, 1654, 1658, 1662, 1666, - 1670, 1674, 1678, 1682, 1687, 1693, 1697, 1702, 1707, 1713, - 1719, 1723, 1728, 1732, 1739, 1740, 1741, 1742, 1743, 1744, - 1747, 1770, 1794, 1799, 1805, 1820, 1835, 1843, 1855, 1860, - 1868, 1882, 1896, 1910, 1921, 1926, 1940, 1944, 1963, 1982, - 2036, 2096, 2132, 2136, 2152, 2168, 2188, 2220, 2224, 2228, - 2232, 2237, 2241, 2248, 2255, 2263, 2267, 2274, 2282, 2286, - 2290, 2295, 2299, 2306, 2313, 2320, 2328, 2332, 2339, 2347, - 2351, 2356, 2360, 2365, 2369, 2374, 2378, 2383, 2387, 2392, - 2396, 2401, 2405, 2422, 2426, 2430, 2434, 2438, 2442, 2446, - 2450, 2454, 2458, 2462, 2467, 2471 + 0, 1095, 1095, 1097, 1134, 1138, 1141, 1146, 1168, 1185, + 1186, 1188, 1214, 1224, 1225, 1226, 1229, 1233, 1252, 1256, + 1261, 1268, 1275, 1305, 1310, 1317, 1321, 1322, 1325, 1329, + 1334, 1340, 1346, 1351, 1360, 1365, 1370, 1384, 1398, 1409, + 1412, 1423, 1427, 1431, 1436, 1440, 1459, 1479, 1483, 1488, + 1493, 1498, 1503, 1508, 1516, 1534, 1535, 1536, 1547, 1555, + 1564, 1570, 1576, 1584, 1590, 1593, 1598, 1604, 1610, 1619, + 1632, 1635, 1643, 1646, 1650, 1654, 1658, 1662, 1666, 1670, + 1674, 1678, 1682, 1686, 1691, 1697, 1701, 1706, 1711, 1717, + 1723, 1727, 1732, 1736, 1743, 1744, 1745, 1746, 1747, 1748, + 1751, 1774, 1798, 1803, 1809, 1824, 1839, 1847, 1859, 1864, + 1872, 1886, 1900, 1914, 1925, 1930, 1944, 1948, 1967, 1986, + 2040, 2100, 2136, 2140, 2156, 2172, 2192, 2224, 2228, 2232, + 2236, 2241, 2245, 2252, 2259, 2267, 2271, 2278, 2286, 2290, + 2294, 2299, 2303, 2310, 2317, 2324, 2332, 2336, 2343, 2351, + 2355, 2360, 2364, 2369, 2373, 2378, 2382, 2387, 2391, 2396, + 2400, 2405, 2409, 2426, 2430, 2434, 2438, 2442, 2446, 2450, + 2454, 2458, 2462, 2466, 2471, 2475 }; #endif @@ -2670,14 +2674,14 @@ yyreduce: switch (yyn) { case 2: -#line 1091 "hlsl.y" /* yacc.c:1646 */ +#line 1095 "hlsl.y" /* yacc.c:1646 */ { } -#line 2677 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2681 "hlsl.tab.c" /* yacc.c:1646 */ break; case 3: -#line 1094 "hlsl.y" /* yacc.c:1646 */ +#line 1098 "hlsl.y" /* yacc.c:1646 */ { const struct hlsl_ir_function_decl *decl; @@ -2714,34 +2718,34 @@ yyreduce: TRACE("Adding function '%s' to the function list.\n", (yyvsp[0].function).name); add_function_decl(&hlsl_ctx.functions, (yyvsp[0].function).name, (yyvsp[0].function).decl, FALSE); } -#line 2718 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2722 "hlsl.tab.c" /* yacc.c:1646 */ break; case 4: -#line 1131 "hlsl.y" /* yacc.c:1646 */ +#line 1135 "hlsl.y" /* yacc.c:1646 */ { TRACE("Declaration statement parsed.\n"); } -#line 2726 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2730 "hlsl.tab.c" /* yacc.c:1646 */ break; case 5: -#line 1135 "hlsl.y" /* yacc.c:1646 */ +#line 1139 "hlsl.y" /* yacc.c:1646 */ { } -#line 2733 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2737 "hlsl.tab.c" /* yacc.c:1646 */ break; case 6: -#line 1138 "hlsl.y" /* yacc.c:1646 */ +#line 1142 "hlsl.y" /* yacc.c:1646 */ { TRACE("Skipping stray semicolon.\n"); } -#line 2741 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2745 "hlsl.tab.c" /* yacc.c:1646 */ break; case 7: -#line 1143 "hlsl.y" /* yacc.c:1646 */ +#line 1147 "hlsl.y" /* yacc.c:1646 */ { const char **new_array = NULL; @@ -2762,11 +2766,11 @@ yyreduce: d3dcompiler_free((yyvsp[0].name)); } } -#line 2766 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2770 "hlsl.tab.c" /* yacc.c:1646 */ break; case 8: -#line 1165 "hlsl.y" /* yacc.c:1646 */ +#line 1169 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -2782,11 +2786,11 @@ yyreduce: } (yyval.list) = declare_vars((yyvsp[-2].type), 0, (yyvsp[-1].list)); } -#line 2786 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2790 "hlsl.tab.c" /* yacc.c:1646 */ break; case 11: -#line 1185 "hlsl.y" /* yacc.c:1646 */ +#line 1189 "hlsl.y" /* yacc.c:1646 */ { BOOL ret; struct source_location loc; @@ -2811,11 +2815,11 @@ yyreduce: return 1; } } -#line 2815 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2819 "hlsl.tab.c" /* yacc.c:1646 */ break; case 12: -#line 1211 "hlsl.y" /* yacc.c:1646 */ +#line 1215 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -2824,20 +2828,20 @@ yyreduce: check_invalid_matrix_modifiers((yyvsp[-4].modifiers), &loc); (yyval.type) = new_struct_type(NULL, (yyvsp[-4].modifiers), (yyvsp[-1].list)); } -#line 2828 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2832 "hlsl.tab.c" /* yacc.c:1646 */ break; case 16: -#line 1225 "hlsl.y" /* yacc.c:1646 */ +#line 1229 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); } -#line 2837 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2841 "hlsl.tab.c" /* yacc.c:1646 */ break; case 17: -#line 1230 "hlsl.y" /* yacc.c:1646 */ +#line 1234 "hlsl.y" /* yacc.c:1646 */ { BOOL ret; struct hlsl_struct_field *field, *next; @@ -2855,48 +2859,48 @@ yyreduce: } d3dcompiler_free((yyvsp[0].list)); } -#line 2859 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2863 "hlsl.tab.c" /* yacc.c:1646 */ break; case 18: -#line 1249 "hlsl.y" /* yacc.c:1646 */ +#line 1253 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = gen_struct_fields((yyvsp[-2].type), (yyvsp[-3].modifiers), (yyvsp[-1].list)); } -#line 2867 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2871 "hlsl.tab.c" /* yacc.c:1646 */ break; case 19: -#line 1253 "hlsl.y" /* yacc.c:1646 */ +#line 1257 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = gen_struct_fields((yyvsp[-2].type), 0, (yyvsp[-1].list)); } -#line 2875 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2879 "hlsl.tab.c" /* yacc.c:1646 */ break; case 20: -#line 1258 "hlsl.y" /* yacc.c:1646 */ +#line 1262 "hlsl.y" /* yacc.c:1646 */ { TRACE("Function %s parsed.\n", (yyvsp[-1].function).name); (yyval.function) = (yyvsp[-1].function); (yyval.function).decl->body = (yyvsp[0].list); pop_scope(&hlsl_ctx); } -#line 2886 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2890 "hlsl.tab.c" /* yacc.c:1646 */ break; case 21: -#line 1265 "hlsl.y" /* yacc.c:1646 */ +#line 1269 "hlsl.y" /* yacc.c:1646 */ { TRACE("Function prototype for %s.\n", (yyvsp[-1].function).name); (yyval.function) = (yyvsp[-1].function); pop_scope(&hlsl_ctx); } -#line 2896 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2900 "hlsl.tab.c" /* yacc.c:1646 */ break; case 22: -#line 1272 "hlsl.y" /* yacc.c:1646 */ +#line 1276 "hlsl.y" /* yacc.c:1646 */ { if (get_variable(hlsl_ctx.globals, (yyvsp[-4].name))) { @@ -2925,81 +2929,81 @@ yyreduce: (yyval.function).decl->semantic = (yyvsp[0].colon_attribute).semantic; set_location(&(yyval.function).decl->node.loc, &(yylsp[-4])); } -#line 2929 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2933 "hlsl.tab.c" /* yacc.c:1646 */ break; case 23: -#line 1302 "hlsl.y" /* yacc.c:1646 */ +#line 1306 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); } -#line 2938 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2942 "hlsl.tab.c" /* yacc.c:1646 */ break; case 24: -#line 1307 "hlsl.y" /* yacc.c:1646 */ +#line 1311 "hlsl.y" /* yacc.c:1646 */ { pop_scope(&hlsl_ctx); (yyval.list) = (yyvsp[-1].list); } -#line 2947 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2951 "hlsl.tab.c" /* yacc.c:1646 */ break; case 25: -#line 1313 "hlsl.y" /* yacc.c:1646 */ +#line 1317 "hlsl.y" /* yacc.c:1646 */ { push_scope(&hlsl_ctx); } -#line 2955 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2959 "hlsl.tab.c" /* yacc.c:1646 */ break; case 28: -#line 1321 "hlsl.y" /* yacc.c:1646 */ +#line 1325 "hlsl.y" /* yacc.c:1646 */ { (yyval.colon_attribute).semantic = NULL; (yyval.colon_attribute).reg_reservation = NULL; } -#line 2964 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2968 "hlsl.tab.c" /* yacc.c:1646 */ break; case 29: -#line 1326 "hlsl.y" /* yacc.c:1646 */ +#line 1330 "hlsl.y" /* yacc.c:1646 */ { (yyval.colon_attribute).semantic = (yyvsp[0].name); (yyval.colon_attribute).reg_reservation = NULL; } -#line 2973 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2977 "hlsl.tab.c" /* yacc.c:1646 */ break; case 30: -#line 1331 "hlsl.y" /* yacc.c:1646 */ +#line 1335 "hlsl.y" /* yacc.c:1646 */ { (yyval.colon_attribute).semantic = NULL; (yyval.colon_attribute).reg_reservation = (yyvsp[0].reg_reservation); } -#line 2982 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2986 "hlsl.tab.c" /* yacc.c:1646 */ break; case 31: -#line 1337 "hlsl.y" /* yacc.c:1646 */ +#line 1341 "hlsl.y" /* yacc.c:1646 */ { (yyval.name) = (yyvsp[0].name); } -#line 2990 "hlsl.tab.c" /* yacc.c:1646 */ +#line 2994 "hlsl.tab.c" /* yacc.c:1646 */ break; case 32: -#line 1343 "hlsl.y" /* yacc.c:1646 */ +#line 1347 "hlsl.y" /* yacc.c:1646 */ { (yyval.reg_reservation) = parse_reg_reservation((yyvsp[-1].name)); d3dcompiler_free((yyvsp[-1].name)); } -#line 2999 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3003 "hlsl.tab.c" /* yacc.c:1646 */ break; case 33: -#line 1348 "hlsl.y" /* yacc.c:1646 */ +#line 1352 "hlsl.y" /* yacc.c:1646 */ { FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a((yyvsp[-3].name))); d3dcompiler_free((yyvsp[-3].name)); @@ -3007,28 +3011,28 @@ yyreduce: (yyval.reg_reservation) = parse_reg_reservation((yyvsp[-1].name)); d3dcompiler_free((yyvsp[-1].name)); } -#line 3011 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3015 "hlsl.tab.c" /* yacc.c:1646 */ break; case 34: -#line 1357 "hlsl.y" /* yacc.c:1646 */ +#line 1361 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); } -#line 3020 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3024 "hlsl.tab.c" /* yacc.c:1646 */ break; case 35: -#line 1362 "hlsl.y" /* yacc.c:1646 */ +#line 1366 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[0].list); } -#line 3028 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3032 "hlsl.tab.c" /* yacc.c:1646 */ break; case 36: -#line 1367 "hlsl.y" /* yacc.c:1646 */ +#line 1371 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3042,11 +3046,11 @@ yyreduce: return -1; } } -#line 3046 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3050 "hlsl.tab.c" /* yacc.c:1646 */ break; case 37: -#line 1381 "hlsl.y" /* yacc.c:1646 */ +#line 1385 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3059,11 +3063,11 @@ yyreduce: return 1; } } -#line 3063 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3067 "hlsl.tab.c" /* yacc.c:1646 */ break; case 38: -#line 1395 "hlsl.y" /* yacc.c:1646 */ +#line 1399 "hlsl.y" /* yacc.c:1646 */ { (yyval.parameter).modifiers = (yyvsp[-4].modifiers) ? (yyvsp[-4].modifiers) : HLSL_MODIFIER_IN; (yyval.parameter).modifiers |= (yyvsp[-3].modifiers); @@ -3072,19 +3076,19 @@ yyreduce: (yyval.parameter).semantic = (yyvsp[0].colon_attribute).semantic; (yyval.parameter).reg_reservation = (yyvsp[0].colon_attribute).reg_reservation; } -#line 3076 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3080 "hlsl.tab.c" /* yacc.c:1646 */ break; case 39: -#line 1405 "hlsl.y" /* yacc.c:1646 */ +#line 1409 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = 0; } -#line 3084 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3088 "hlsl.tab.c" /* yacc.c:1646 */ break; case 40: -#line 1409 "hlsl.y" /* yacc.c:1646 */ +#line 1413 "hlsl.y" /* yacc.c:1646 */ { if ((yyvsp[-1].modifiers) & (yyvsp[0].modifiers)) { @@ -3094,43 +3098,43 @@ yyreduce: } (yyval.modifiers) = (yyvsp[-1].modifiers) | (yyvsp[0].modifiers); } -#line 3098 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3102 "hlsl.tab.c" /* yacc.c:1646 */ break; case 41: -#line 1420 "hlsl.y" /* yacc.c:1646 */ +#line 1424 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = HLSL_MODIFIER_IN; } -#line 3106 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3110 "hlsl.tab.c" /* yacc.c:1646 */ break; case 42: -#line 1424 "hlsl.y" /* yacc.c:1646 */ +#line 1428 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = HLSL_MODIFIER_OUT; } -#line 3114 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3118 "hlsl.tab.c" /* yacc.c:1646 */ break; case 43: -#line 1428 "hlsl.y" /* yacc.c:1646 */ +#line 1432 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT; } -#line 3122 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3126 "hlsl.tab.c" /* yacc.c:1646 */ break; case 44: -#line 1433 "hlsl.y" /* yacc.c:1646 */ +#line 1437 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = (yyvsp[0].type); } -#line 3130 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3134 "hlsl.tab.c" /* yacc.c:1646 */ break; case 45: -#line 1437 "hlsl.y" /* yacc.c:1646 */ +#line 1441 "hlsl.y" /* yacc.c:1646 */ { if ((yyvsp[-3].type)->type != HLSL_CLASS_SCALAR) { @@ -3149,11 +3153,11 @@ yyreduce: (yyval.type) = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, (yyvsp[-3].type)->base_type, (yyvsp[-1].intval), 1); } -#line 3153 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3157 "hlsl.tab.c" /* yacc.c:1646 */ break; case 46: -#line 1456 "hlsl.y" /* yacc.c:1646 */ +#line 1460 "hlsl.y" /* yacc.c:1646 */ { if ((yyvsp[-5].type)->type != HLSL_CLASS_SCALAR) { @@ -3172,64 +3176,64 @@ yyreduce: (yyval.type) = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, (yyvsp[-5].type)->base_type, (yyvsp[-3].intval), (yyvsp[-1].intval)); } -#line 3176 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3180 "hlsl.tab.c" /* yacc.c:1646 */ break; case 47: -#line 1476 "hlsl.y" /* yacc.c:1646 */ +#line 1480 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); } -#line 3184 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3188 "hlsl.tab.c" /* yacc.c:1646 */ break; case 48: -#line 1480 "hlsl.y" /* yacc.c:1646 */ +#line 1484 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); (yyval.type)->sampler_dim = HLSL_SAMPLER_DIM_GENERIC; } -#line 3193 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3197 "hlsl.tab.c" /* yacc.c:1646 */ break; case 49: -#line 1485 "hlsl.y" /* yacc.c:1646 */ +#line 1489 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); (yyval.type)->sampler_dim = HLSL_SAMPLER_DIM_1D; } -#line 3202 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3206 "hlsl.tab.c" /* yacc.c:1646 */ break; case 50: -#line 1490 "hlsl.y" /* yacc.c:1646 */ +#line 1494 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); (yyval.type)->sampler_dim = HLSL_SAMPLER_DIM_2D; } -#line 3211 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3215 "hlsl.tab.c" /* yacc.c:1646 */ break; case 51: -#line 1495 "hlsl.y" /* yacc.c:1646 */ +#line 1499 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); (yyval.type)->sampler_dim = HLSL_SAMPLER_DIM_3D; } -#line 3220 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3224 "hlsl.tab.c" /* yacc.c:1646 */ break; case 52: -#line 1500 "hlsl.y" /* yacc.c:1646 */ +#line 1504 "hlsl.y" /* yacc.c:1646 */ { (yyval.type) = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); (yyval.type)->sampler_dim = HLSL_SAMPLER_DIM_CUBE; } -#line 3229 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3233 "hlsl.tab.c" /* yacc.c:1646 */ break; case 53: -#line 1505 "hlsl.y" /* yacc.c:1646 */ +#line 1509 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_type *type; @@ -3237,11 +3241,11 @@ yyreduce: (yyval.type) = type; d3dcompiler_free((yyvsp[0].name)); } -#line 3241 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3245 "hlsl.tab.c" /* yacc.c:1646 */ break; case 54: -#line 1513 "hlsl.y" /* yacc.c:1646 */ +#line 1517 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_type *type; @@ -3258,11 +3262,11 @@ yyreduce: } d3dcompiler_free((yyvsp[0].name)); } -#line 3262 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3266 "hlsl.tab.c" /* yacc.c:1646 */ break; case 57: -#line 1533 "hlsl.y" /* yacc.c:1646 */ +#line 1537 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); if (!(yyval.list)) @@ -3272,11 +3276,11 @@ yyreduce: } list_init((yyval.list)); } -#line 3276 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3280 "hlsl.tab.c" /* yacc.c:1646 */ break; case 58: -#line 1544 "hlsl.y" /* yacc.c:1646 */ +#line 1548 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3284,11 +3288,11 @@ yyreduce: if (!add_typedef((yyvsp[-3].modifiers), (yyvsp[-2].type), (yyvsp[-1].list), &loc)) return 1; } -#line 3288 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3292 "hlsl.tab.c" /* yacc.c:1646 */ break; case 59: -#line 1552 "hlsl.y" /* yacc.c:1646 */ +#line 1556 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3296,84 +3300,84 @@ yyreduce: if (!add_typedef(0, (yyvsp[-2].type), (yyvsp[-1].list), &loc)) return 1; } -#line 3300 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3304 "hlsl.tab.c" /* yacc.c:1646 */ break; case 60: -#line 1561 "hlsl.y" /* yacc.c:1646 */ +#line 1565 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); list_add_head((yyval.list), &(yyvsp[0].variable_def)->entry); } -#line 3310 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3314 "hlsl.tab.c" /* yacc.c:1646 */ break; case 61: -#line 1567 "hlsl.y" /* yacc.c:1646 */ +#line 1571 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-2].list); list_add_tail((yyval.list), &(yyvsp[0].variable_def)->entry); } -#line 3319 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3323 "hlsl.tab.c" /* yacc.c:1646 */ break; case 62: -#line 1573 "hlsl.y" /* yacc.c:1646 */ +#line 1577 "hlsl.y" /* yacc.c:1646 */ { (yyval.variable_def) = d3dcompiler_alloc(sizeof(*(yyval.variable_def))); set_location(&(yyval.variable_def)->loc, &(yylsp[-1])); (yyval.variable_def)->name = (yyvsp[-1].name); (yyval.variable_def)->array_size = (yyvsp[0].intval); } -#line 3330 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3334 "hlsl.tab.c" /* yacc.c:1646 */ break; case 63: -#line 1581 "hlsl.y" /* yacc.c:1646 */ +#line 1585 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = declare_vars((yyvsp[-2].type), (yyvsp[-3].modifiers), (yyvsp[-1].list)); } -#line 3338 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3342 "hlsl.tab.c" /* yacc.c:1646 */ break; case 64: -#line 1586 "hlsl.y" /* yacc.c:1646 */ +#line 1590 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = NULL; } -#line 3346 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3350 "hlsl.tab.c" /* yacc.c:1646 */ break; case 65: -#line 1590 "hlsl.y" /* yacc.c:1646 */ +#line 1594 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[0].list); } -#line 3354 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3358 "hlsl.tab.c" /* yacc.c:1646 */ break; case 66: -#line 1595 "hlsl.y" /* yacc.c:1646 */ +#line 1599 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); list_add_head((yyval.list), &(yyvsp[0].variable_def)->entry); } -#line 3364 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3368 "hlsl.tab.c" /* yacc.c:1646 */ break; case 67: -#line 1601 "hlsl.y" /* yacc.c:1646 */ +#line 1605 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-2].list); list_add_tail((yyval.list), &(yyvsp[0].variable_def)->entry); } -#line 3373 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3377 "hlsl.tab.c" /* yacc.c:1646 */ break; case 68: -#line 1607 "hlsl.y" /* yacc.c:1646 */ +#line 1611 "hlsl.y" /* yacc.c:1646 */ { (yyval.variable_def) = d3dcompiler_alloc(sizeof(*(yyval.variable_def))); set_location(&(yyval.variable_def)->loc, &(yylsp[-2])); @@ -3382,11 +3386,11 @@ yyreduce: (yyval.variable_def)->semantic = (yyvsp[0].colon_attribute).semantic; (yyval.variable_def)->reg_reservation = (yyvsp[0].colon_attribute).reg_reservation; } -#line 3386 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3390 "hlsl.tab.c" /* yacc.c:1646 */ break; case 69: -#line 1616 "hlsl.y" /* yacc.c:1646 */ +#line 1620 "hlsl.y" /* yacc.c:1646 */ { TRACE("Declaration with initializer.\n"); (yyval.variable_def) = d3dcompiler_alloc(sizeof(*(yyval.variable_def))); @@ -3397,212 +3401,212 @@ yyreduce: (yyval.variable_def)->reg_reservation = (yyvsp[-2].colon_attribute).reg_reservation; (yyval.variable_def)->initializer = (yyvsp[0].list); } -#line 3401 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3405 "hlsl.tab.c" /* yacc.c:1646 */ break; case 70: -#line 1628 "hlsl.y" /* yacc.c:1646 */ +#line 1632 "hlsl.y" /* yacc.c:1646 */ { (yyval.intval) = 0; } -#line 3409 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3413 "hlsl.tab.c" /* yacc.c:1646 */ break; case 71: -#line 1632 "hlsl.y" /* yacc.c:1646 */ +#line 1636 "hlsl.y" /* yacc.c:1646 */ { FIXME("Array.\n"); (yyval.intval) = 0; free_instr((yyvsp[-1].instr)); } -#line 3419 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3423 "hlsl.tab.c" /* yacc.c:1646 */ break; case 72: -#line 1639 "hlsl.y" /* yacc.c:1646 */ +#line 1643 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = 0; } -#line 3427 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3431 "hlsl.tab.c" /* yacc.c:1646 */ break; case 73: -#line 1643 "hlsl.y" /* yacc.c:1646 */ +#line 1647 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_EXTERN, &(yylsp[-1])); } -#line 3435 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3439 "hlsl.tab.c" /* yacc.c:1646 */ break; case 74: -#line 1647 "hlsl.y" /* yacc.c:1646 */ +#line 1651 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_NOINTERPOLATION, &(yylsp[-1])); } -#line 3443 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3447 "hlsl.tab.c" /* yacc.c:1646 */ break; case 75: -#line 1651 "hlsl.y" /* yacc.c:1646 */ +#line 1655 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_MODIFIER_PRECISE, &(yylsp[-1])); } -#line 3451 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3455 "hlsl.tab.c" /* yacc.c:1646 */ break; case 76: -#line 1655 "hlsl.y" /* yacc.c:1646 */ +#line 1659 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_SHARED, &(yylsp[-1])); } -#line 3459 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3463 "hlsl.tab.c" /* yacc.c:1646 */ break; case 77: -#line 1659 "hlsl.y" /* yacc.c:1646 */ +#line 1663 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_GROUPSHARED, &(yylsp[-1])); } -#line 3467 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3471 "hlsl.tab.c" /* yacc.c:1646 */ break; case 78: -#line 1663 "hlsl.y" /* yacc.c:1646 */ +#line 1667 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_STATIC, &(yylsp[-1])); } -#line 3475 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3479 "hlsl.tab.c" /* yacc.c:1646 */ break; case 79: -#line 1667 "hlsl.y" /* yacc.c:1646 */ +#line 1671 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_UNIFORM, &(yylsp[-1])); } -#line 3483 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3487 "hlsl.tab.c" /* yacc.c:1646 */ break; case 80: -#line 1671 "hlsl.y" /* yacc.c:1646 */ +#line 1675 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_STORAGE_VOLATILE, &(yylsp[-1])); } -#line 3491 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3495 "hlsl.tab.c" /* yacc.c:1646 */ break; case 81: -#line 1675 "hlsl.y" /* yacc.c:1646 */ +#line 1679 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_MODIFIER_CONST, &(yylsp[-1])); } -#line 3499 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3503 "hlsl.tab.c" /* yacc.c:1646 */ break; case 82: -#line 1679 "hlsl.y" /* yacc.c:1646 */ +#line 1683 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_MODIFIER_ROW_MAJOR, &(yylsp[-1])); } -#line 3507 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3511 "hlsl.tab.c" /* yacc.c:1646 */ break; case 83: -#line 1683 "hlsl.y" /* yacc.c:1646 */ +#line 1687 "hlsl.y" /* yacc.c:1646 */ { (yyval.modifiers) = add_modifier((yyvsp[0].modifiers), HLSL_MODIFIER_COLUMN_MAJOR, &(yylsp[-1])); } -#line 3515 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3519 "hlsl.tab.c" /* yacc.c:1646 */ break; case 84: -#line 1688 "hlsl.y" /* yacc.c:1646 */ +#line 1692 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); list_add_head((yyval.list), &(yyvsp[0].instr)->entry); } -#line 3525 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3529 "hlsl.tab.c" /* yacc.c:1646 */ break; case 85: -#line 1694 "hlsl.y" /* yacc.c:1646 */ +#line 1698 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-1].list); } -#line 3533 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3537 "hlsl.tab.c" /* yacc.c:1646 */ break; case 86: -#line 1698 "hlsl.y" /* yacc.c:1646 */ +#line 1702 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-2].list); } -#line 3541 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3545 "hlsl.tab.c" /* yacc.c:1646 */ break; case 87: -#line 1703 "hlsl.y" /* yacc.c:1646 */ +#line 1707 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 3549 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3553 "hlsl.tab.c" /* yacc.c:1646 */ break; case 88: -#line 1708 "hlsl.y" /* yacc.c:1646 */ +#line 1712 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); list_add_head((yyval.list), &(yyvsp[0].instr)->entry); } -#line 3559 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3563 "hlsl.tab.c" /* yacc.c:1646 */ break; case 89: -#line 1714 "hlsl.y" /* yacc.c:1646 */ +#line 1718 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-2].list); list_add_tail((yyval.list), &(yyvsp[0].instr)->entry); } -#line 3568 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3572 "hlsl.tab.c" /* yacc.c:1646 */ break; case 90: -#line 1720 "hlsl.y" /* yacc.c:1646 */ +#line 1724 "hlsl.y" /* yacc.c:1646 */ { (yyval.boolval) = TRUE; } -#line 3576 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3580 "hlsl.tab.c" /* yacc.c:1646 */ break; case 91: -#line 1724 "hlsl.y" /* yacc.c:1646 */ +#line 1728 "hlsl.y" /* yacc.c:1646 */ { (yyval.boolval) = FALSE; } -#line 3584 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3588 "hlsl.tab.c" /* yacc.c:1646 */ break; case 92: -#line 1729 "hlsl.y" /* yacc.c:1646 */ +#line 1733 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[0].list); } -#line 3592 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3596 "hlsl.tab.c" /* yacc.c:1646 */ break; case 93: -#line 1733 "hlsl.y" /* yacc.c:1646 */ +#line 1737 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = (yyvsp[-1].list); list_move_tail((yyval.list), (yyvsp[0].list)); d3dcompiler_free((yyvsp[0].list)); } -#line 3602 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3606 "hlsl.tab.c" /* yacc.c:1646 */ break; case 100: -#line 1748 "hlsl.y" /* yacc.c:1646 */ +#line 1752 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump)); if (!jump) @@ -3624,11 +3628,11 @@ yyreduce: list_init((yyval.list)); list_add_tail((yyval.list), &jump->node.entry); } -#line 3628 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3632 "hlsl.tab.c" /* yacc.c:1646 */ break; case 101: -#line 1771 "hlsl.y" /* yacc.c:1646 */ +#line 1775 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr)); if (!instr) @@ -3651,29 +3655,29 @@ yyreduce: list_init((yyval.list)); list_add_head((yyval.list), &instr->node.entry); } -#line 3655 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3659 "hlsl.tab.c" /* yacc.c:1646 */ break; case 102: -#line 1795 "hlsl.y" /* yacc.c:1646 */ +#line 1799 "hlsl.y" /* yacc.c:1646 */ { (yyval.if_body).then_instrs = (yyvsp[0].list); (yyval.if_body).else_instrs = NULL; } -#line 3664 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3668 "hlsl.tab.c" /* yacc.c:1646 */ break; case 103: -#line 1800 "hlsl.y" /* yacc.c:1646 */ +#line 1804 "hlsl.y" /* yacc.c:1646 */ { (yyval.if_body).then_instrs = (yyvsp[-2].list); (yyval.if_body).else_instrs = (yyvsp[0].list); } -#line 3673 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3677 "hlsl.tab.c" /* yacc.c:1646 */ break; case 104: -#line 1806 "hlsl.y" /* yacc.c:1646 */ +#line 1810 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; struct list *cond = d3dcompiler_alloc(sizeof(*cond)); @@ -3688,11 +3692,11 @@ yyreduce: set_location(&loc, &(yylsp[-4])); (yyval.list) = create_loop(LOOP_WHILE, NULL, cond, NULL, (yyvsp[0].list), &loc); } -#line 3692 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3696 "hlsl.tab.c" /* yacc.c:1646 */ break; case 105: -#line 1821 "hlsl.y" /* yacc.c:1646 */ +#line 1825 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; struct list *cond = d3dcompiler_alloc(sizeof(*cond)); @@ -3707,11 +3711,11 @@ yyreduce: set_location(&loc, &(yylsp[-6])); (yyval.list) = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, (yyvsp[-5].list), &loc); } -#line 3711 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3715 "hlsl.tab.c" /* yacc.c:1646 */ break; case 106: -#line 1836 "hlsl.y" /* yacc.c:1646 */ +#line 1840 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3719,11 +3723,11 @@ yyreduce: (yyval.list) = create_loop(LOOP_FOR, (yyvsp[-4].list), (yyvsp[-3].list), (yyvsp[-2].instr), (yyvsp[0].list), &loc); pop_scope(&hlsl_ctx); } -#line 3723 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3727 "hlsl.tab.c" /* yacc.c:1646 */ break; case 107: -#line 1844 "hlsl.y" /* yacc.c:1646 */ +#line 1848 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3734,31 +3738,31 @@ yyreduce: (yyval.list) = create_loop(LOOP_FOR, (yyvsp[-4].list), (yyvsp[-3].list), (yyvsp[-2].instr), (yyvsp[0].list), &loc); pop_scope(&hlsl_ctx); } -#line 3738 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3742 "hlsl.tab.c" /* yacc.c:1646 */ break; case 108: -#line 1856 "hlsl.y" /* yacc.c:1646 */ +#line 1860 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); } -#line 3747 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3751 "hlsl.tab.c" /* yacc.c:1646 */ break; case 109: -#line 1861 "hlsl.y" /* yacc.c:1646 */ +#line 1865 "hlsl.y" /* yacc.c:1646 */ { (yyval.list) = d3dcompiler_alloc(sizeof(*(yyval.list))); list_init((yyval.list)); if ((yyvsp[-1].instr)) list_add_head((yyval.list), &(yyvsp[-1].instr)->entry); } -#line 3758 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3762 "hlsl.tab.c" /* yacc.c:1646 */ break; case 110: -#line 1869 "hlsl.y" /* yacc.c:1646 */ +#line 1873 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); if (!c) @@ -3772,11 +3776,11 @@ yyreduce: c->v.value.f[0] = (yyvsp[0].floatval); (yyval.instr) = &c->node; } -#line 3776 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3780 "hlsl.tab.c" /* yacc.c:1646 */ break; case 111: -#line 1883 "hlsl.y" /* yacc.c:1646 */ +#line 1887 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); if (!c) @@ -3790,11 +3794,11 @@ yyreduce: c->v.value.i[0] = (yyvsp[0].intval); (yyval.instr) = &c->node; } -#line 3794 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3798 "hlsl.tab.c" /* yacc.c:1646 */ break; case 112: -#line 1897 "hlsl.y" /* yacc.c:1646 */ +#line 1901 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c)); if (!c) @@ -3808,11 +3812,11 @@ yyreduce: c->v.value.b[0] = (yyvsp[0].boolval); (yyval.instr) = &c->node; } -#line 3812 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3816 "hlsl.tab.c" /* yacc.c:1646 */ break; case 113: -#line 1911 "hlsl.y" /* yacc.c:1646 */ +#line 1915 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_deref *deref = new_var_deref((yyvsp[0].var)); if (deref) @@ -3823,19 +3827,19 @@ yyreduce: else (yyval.instr) = NULL; } -#line 3827 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3831 "hlsl.tab.c" /* yacc.c:1646 */ break; case 114: -#line 1922 "hlsl.y" /* yacc.c:1646 */ +#line 1926 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[-1].instr); } -#line 3835 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3839 "hlsl.tab.c" /* yacc.c:1646 */ break; case 115: -#line 1927 "hlsl.y" /* yacc.c:1646 */ +#line 1931 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_var *var; var = get_variable(hlsl_ctx.cur_scope, (yyvsp[0].name)); @@ -3848,19 +3852,19 @@ yyreduce: } (yyval.var) = var; } -#line 3852 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3856 "hlsl.tab.c" /* yacc.c:1646 */ break; case 116: -#line 1941 "hlsl.y" /* yacc.c:1646 */ +#line 1945 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 3860 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3864 "hlsl.tab.c" /* yacc.c:1646 */ break; case 117: -#line 1945 "hlsl.y" /* yacc.c:1646 */ +#line 1949 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_node *operands[3]; struct source_location loc; @@ -3879,11 +3883,11 @@ yyreduce: (yyval.instr)->data_type = clone_hlsl_type((yyval.instr)->data_type); (yyval.instr)->data_type->modifiers |= HLSL_MODIFIER_CONST; } -#line 3883 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3887 "hlsl.tab.c" /* yacc.c:1646 */ break; case 118: -#line 1964 "hlsl.y" /* yacc.c:1646 */ +#line 1968 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_node *operands[3]; struct source_location loc; @@ -3902,11 +3906,11 @@ yyreduce: (yyval.instr)->data_type = clone_hlsl_type((yyval.instr)->data_type); (yyval.instr)->data_type->modifiers |= HLSL_MODIFIER_CONST; } -#line 3906 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3910 "hlsl.tab.c" /* yacc.c:1646 */ break; case 119: -#line 1983 "hlsl.y" /* yacc.c:1646 */ +#line 1987 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -3960,11 +3964,11 @@ yyreduce: return 1; } } -#line 3964 "hlsl.tab.c" /* yacc.c:1646 */ +#line 3968 "hlsl.tab.c" /* yacc.c:1646 */ break; case 120: -#line 2037 "hlsl.y" /* yacc.c:1646 */ +#line 2041 "hlsl.y" /* yacc.c:1646 */ { /* This may be an array dereference or a vector/matrix * subcomponent access. @@ -4022,11 +4026,11 @@ yyreduce: (yyval.instr) = &deref->node; } -#line 4026 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4030 "hlsl.tab.c" /* yacc.c:1646 */ break; case 121: -#line 2097 "hlsl.y" /* yacc.c:1646 */ +#line 2101 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_constructor *constructor; @@ -4061,19 +4065,19 @@ yyreduce: (yyval.instr) = &constructor->node; } -#line 4065 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4069 "hlsl.tab.c" /* yacc.c:1646 */ break; case 122: -#line 2133 "hlsl.y" /* yacc.c:1646 */ +#line 2137 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4073 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4077 "hlsl.tab.c" /* yacc.c:1646 */ break; case 123: -#line 2137 "hlsl.y" /* yacc.c:1646 */ +#line 2141 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_node *operands[3]; struct source_location loc; @@ -4089,11 +4093,11 @@ yyreduce: operands[1] = operands[2] = NULL; (yyval.instr) = &new_expr(HLSL_IR_UNOP_PREINC, operands, &loc)->node; } -#line 4093 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4097 "hlsl.tab.c" /* yacc.c:1646 */ break; case 124: -#line 2153 "hlsl.y" /* yacc.c:1646 */ +#line 2157 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_node *operands[3]; struct source_location loc; @@ -4109,11 +4113,11 @@ yyreduce: operands[1] = operands[2] = NULL; (yyval.instr) = &new_expr(HLSL_IR_UNOP_PREDEC, operands, &loc)->node; } -#line 4113 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4117 "hlsl.tab.c" /* yacc.c:1646 */ break; case 125: -#line 2169 "hlsl.y" /* yacc.c:1646 */ +#line 2173 "hlsl.y" /* yacc.c:1646 */ { enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG, HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT}; @@ -4132,11 +4136,11 @@ yyreduce: (yyval.instr) = &new_expr(ops[(yyvsp[-1].unary_op)], operands, &loc)->node; } } -#line 4136 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4140 "hlsl.tab.c" /* yacc.c:1646 */ break; case 126: -#line 2189 "hlsl.y" /* yacc.c:1646 */ +#line 2193 "hlsl.y" /* yacc.c:1646 */ { struct hlsl_ir_expr *expr; struct hlsl_type *src_type = (yyvsp[0].instr)->data_type; @@ -4167,324 +4171,324 @@ yyreduce: expr = new_cast((yyvsp[0].instr), dst_type, &loc); (yyval.instr) = expr ? &expr->node : NULL; } -#line 4171 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4175 "hlsl.tab.c" /* yacc.c:1646 */ break; case 127: -#line 2221 "hlsl.y" /* yacc.c:1646 */ +#line 2225 "hlsl.y" /* yacc.c:1646 */ { (yyval.unary_op) = UNARY_OP_PLUS; } -#line 4179 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4183 "hlsl.tab.c" /* yacc.c:1646 */ break; case 128: -#line 2225 "hlsl.y" /* yacc.c:1646 */ +#line 2229 "hlsl.y" /* yacc.c:1646 */ { (yyval.unary_op) = UNARY_OP_MINUS; } -#line 4187 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4191 "hlsl.tab.c" /* yacc.c:1646 */ break; case 129: -#line 2229 "hlsl.y" /* yacc.c:1646 */ +#line 2233 "hlsl.y" /* yacc.c:1646 */ { (yyval.unary_op) = UNARY_OP_LOGICNOT; } -#line 4195 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4199 "hlsl.tab.c" /* yacc.c:1646 */ break; case 130: -#line 2233 "hlsl.y" /* yacc.c:1646 */ +#line 2237 "hlsl.y" /* yacc.c:1646 */ { (yyval.unary_op) = UNARY_OP_BITNOT; } -#line 4203 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4207 "hlsl.tab.c" /* yacc.c:1646 */ break; case 131: -#line 2238 "hlsl.y" /* yacc.c:1646 */ +#line 2242 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4211 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4215 "hlsl.tab.c" /* yacc.c:1646 */ break; case 132: -#line 2242 "hlsl.y" /* yacc.c:1646 */ +#line 2246 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_mul((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4222 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4226 "hlsl.tab.c" /* yacc.c:1646 */ break; case 133: -#line 2249 "hlsl.y" /* yacc.c:1646 */ +#line 2253 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_div((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4233 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4237 "hlsl.tab.c" /* yacc.c:1646 */ break; case 134: -#line 2256 "hlsl.y" /* yacc.c:1646 */ +#line 2260 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_mod((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4244 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4248 "hlsl.tab.c" /* yacc.c:1646 */ break; case 135: -#line 2264 "hlsl.y" /* yacc.c:1646 */ +#line 2268 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4252 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4256 "hlsl.tab.c" /* yacc.c:1646 */ break; case 136: -#line 2268 "hlsl.y" /* yacc.c:1646 */ +#line 2272 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_add((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4263 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4267 "hlsl.tab.c" /* yacc.c:1646 */ break; case 137: -#line 2275 "hlsl.y" /* yacc.c:1646 */ +#line 2279 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_sub((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4274 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4278 "hlsl.tab.c" /* yacc.c:1646 */ break; case 138: -#line 2283 "hlsl.y" /* yacc.c:1646 */ +#line 2287 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4282 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4286 "hlsl.tab.c" /* yacc.c:1646 */ break; case 139: -#line 2287 "hlsl.y" /* yacc.c:1646 */ +#line 2291 "hlsl.y" /* yacc.c:1646 */ { FIXME("Left shift\n"); } -#line 4290 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4294 "hlsl.tab.c" /* yacc.c:1646 */ break; case 140: -#line 2291 "hlsl.y" /* yacc.c:1646 */ +#line 2295 "hlsl.y" /* yacc.c:1646 */ { FIXME("Right shift\n"); } -#line 4298 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4302 "hlsl.tab.c" /* yacc.c:1646 */ break; case 141: -#line 2296 "hlsl.y" /* yacc.c:1646 */ +#line 2300 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4306 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4310 "hlsl.tab.c" /* yacc.c:1646 */ break; case 142: -#line 2300 "hlsl.y" /* yacc.c:1646 */ +#line 2304 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_lt((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4317 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4321 "hlsl.tab.c" /* yacc.c:1646 */ break; case 143: -#line 2307 "hlsl.y" /* yacc.c:1646 */ +#line 2311 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_gt((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4328 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4332 "hlsl.tab.c" /* yacc.c:1646 */ break; case 144: -#line 2314 "hlsl.y" /* yacc.c:1646 */ +#line 2318 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_le((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4339 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4343 "hlsl.tab.c" /* yacc.c:1646 */ break; case 145: -#line 2321 "hlsl.y" /* yacc.c:1646 */ +#line 2325 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_ge((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4350 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4354 "hlsl.tab.c" /* yacc.c:1646 */ break; case 146: -#line 2329 "hlsl.y" /* yacc.c:1646 */ +#line 2333 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4358 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4362 "hlsl.tab.c" /* yacc.c:1646 */ break; case 147: -#line 2333 "hlsl.y" /* yacc.c:1646 */ +#line 2337 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_eq((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4369 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4373 "hlsl.tab.c" /* yacc.c:1646 */ break; case 148: -#line 2340 "hlsl.y" /* yacc.c:1646 */ +#line 2344 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; set_location(&loc, &(yylsp[-1])); (yyval.instr) = &hlsl_ne((yyvsp[-2].instr), (yyvsp[0].instr), &loc)->node; } -#line 4380 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4384 "hlsl.tab.c" /* yacc.c:1646 */ break; case 149: -#line 2348 "hlsl.y" /* yacc.c:1646 */ +#line 2352 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4388 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4392 "hlsl.tab.c" /* yacc.c:1646 */ break; case 150: -#line 2352 "hlsl.y" /* yacc.c:1646 */ +#line 2356 "hlsl.y" /* yacc.c:1646 */ { FIXME("bitwise AND\n"); } -#line 4396 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4400 "hlsl.tab.c" /* yacc.c:1646 */ break; case 151: -#line 2357 "hlsl.y" /* yacc.c:1646 */ +#line 2361 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4404 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4408 "hlsl.tab.c" /* yacc.c:1646 */ break; case 152: -#line 2361 "hlsl.y" /* yacc.c:1646 */ +#line 2365 "hlsl.y" /* yacc.c:1646 */ { FIXME("bitwise XOR\n"); } -#line 4412 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4416 "hlsl.tab.c" /* yacc.c:1646 */ break; case 153: -#line 2366 "hlsl.y" /* yacc.c:1646 */ +#line 2370 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4420 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4424 "hlsl.tab.c" /* yacc.c:1646 */ break; case 154: -#line 2370 "hlsl.y" /* yacc.c:1646 */ +#line 2374 "hlsl.y" /* yacc.c:1646 */ { FIXME("bitwise OR\n"); } -#line 4428 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4432 "hlsl.tab.c" /* yacc.c:1646 */ break; case 155: -#line 2375 "hlsl.y" /* yacc.c:1646 */ +#line 2379 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4436 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4440 "hlsl.tab.c" /* yacc.c:1646 */ break; case 156: -#line 2379 "hlsl.y" /* yacc.c:1646 */ +#line 2383 "hlsl.y" /* yacc.c:1646 */ { FIXME("logic AND\n"); } -#line 4444 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4448 "hlsl.tab.c" /* yacc.c:1646 */ break; case 157: -#line 2384 "hlsl.y" /* yacc.c:1646 */ +#line 2388 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4452 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4456 "hlsl.tab.c" /* yacc.c:1646 */ break; case 158: -#line 2388 "hlsl.y" /* yacc.c:1646 */ +#line 2392 "hlsl.y" /* yacc.c:1646 */ { FIXME("logic OR\n"); } -#line 4460 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4464 "hlsl.tab.c" /* yacc.c:1646 */ break; case 159: -#line 2393 "hlsl.y" /* yacc.c:1646 */ +#line 2397 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4468 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4472 "hlsl.tab.c" /* yacc.c:1646 */ break; case 160: -#line 2397 "hlsl.y" /* yacc.c:1646 */ +#line 2401 "hlsl.y" /* yacc.c:1646 */ { FIXME("ternary operator\n"); } -#line 4476 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4480 "hlsl.tab.c" /* yacc.c:1646 */ break; case 161: -#line 2402 "hlsl.y" /* yacc.c:1646 */ +#line 2406 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4484 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4488 "hlsl.tab.c" /* yacc.c:1646 */ break; case 162: -#line 2406 "hlsl.y" /* yacc.c:1646 */ +#line 2410 "hlsl.y" /* yacc.c:1646 */ { struct source_location loc; @@ -4500,115 +4504,115 @@ yyreduce: return 1; (yyval.instr)->loc = loc; } -#line 4504 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4508 "hlsl.tab.c" /* yacc.c:1646 */ break; case 163: -#line 2423 "hlsl.y" /* yacc.c:1646 */ +#line 2427 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_ASSIGN; } -#line 4512 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4516 "hlsl.tab.c" /* yacc.c:1646 */ break; case 164: -#line 2427 "hlsl.y" /* yacc.c:1646 */ +#line 2431 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_ADD; } -#line 4520 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4524 "hlsl.tab.c" /* yacc.c:1646 */ break; case 165: -#line 2431 "hlsl.y" /* yacc.c:1646 */ +#line 2435 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_SUB; } -#line 4528 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4532 "hlsl.tab.c" /* yacc.c:1646 */ break; case 166: -#line 2435 "hlsl.y" /* yacc.c:1646 */ +#line 2439 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_MUL; } -#line 4536 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4540 "hlsl.tab.c" /* yacc.c:1646 */ break; case 167: -#line 2439 "hlsl.y" /* yacc.c:1646 */ +#line 2443 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_DIV; } -#line 4544 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4548 "hlsl.tab.c" /* yacc.c:1646 */ break; case 168: -#line 2443 "hlsl.y" /* yacc.c:1646 */ +#line 2447 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_MOD; } -#line 4552 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4556 "hlsl.tab.c" /* yacc.c:1646 */ break; case 169: -#line 2447 "hlsl.y" /* yacc.c:1646 */ +#line 2451 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_LSHIFT; } -#line 4560 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4564 "hlsl.tab.c" /* yacc.c:1646 */ break; case 170: -#line 2451 "hlsl.y" /* yacc.c:1646 */ +#line 2455 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_RSHIFT; } -#line 4568 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4572 "hlsl.tab.c" /* yacc.c:1646 */ break; case 171: -#line 2455 "hlsl.y" /* yacc.c:1646 */ +#line 2459 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_AND; } -#line 4576 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4580 "hlsl.tab.c" /* yacc.c:1646 */ break; case 172: -#line 2459 "hlsl.y" /* yacc.c:1646 */ +#line 2463 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_OR; } -#line 4584 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4588 "hlsl.tab.c" /* yacc.c:1646 */ break; case 173: -#line 2463 "hlsl.y" /* yacc.c:1646 */ +#line 2467 "hlsl.y" /* yacc.c:1646 */ { (yyval.assign_op) = ASSIGN_OP_XOR; } -#line 4592 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4596 "hlsl.tab.c" /* yacc.c:1646 */ break; case 174: -#line 2468 "hlsl.y" /* yacc.c:1646 */ +#line 2472 "hlsl.y" /* yacc.c:1646 */ { (yyval.instr) = (yyvsp[0].instr); } -#line 4600 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4604 "hlsl.tab.c" /* yacc.c:1646 */ break; case 175: -#line 2472 "hlsl.y" /* yacc.c:1646 */ +#line 2476 "hlsl.y" /* yacc.c:1646 */ { FIXME("Comma expression\n"); } -#line 4608 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4612 "hlsl.tab.c" /* yacc.c:1646 */ break; -#line 4612 "hlsl.tab.c" /* yacc.c:1646 */ +#line 4616 "hlsl.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4843,7 +4847,7 @@ yyreturn: #endif return yyresult; } -#line 2476 "hlsl.y" /* yacc.c:1906 */ +#line 2480 "hlsl.y" /* yacc.c:1906 */ static void set_location(struct source_location *loc, const struct YYLTYPE *l) diff --git a/dll/directx/wine/d3dcompiler_43/hlsl.tab.h b/dll/directx/wine/d3dcompiler_43/hlsl.tab.h index 8ca95d0a65..9a15a5ebb3 100644 --- a/dll/directx/wine/d3dcompiler_43/hlsl.tab.h +++ b/dll/directx/wine/d3dcompiler_43/hlsl.tab.h @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED -# define YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED +#ifndef YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED +# define YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -155,7 +155,7 @@ extern int hlsl_debug; typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 906 "hlsl.y" /* yacc.c:1909 */ +#line 910 "hlsl.y" /* yacc.c:1909 */ struct hlsl_type *type; INT intval; @@ -200,4 +200,4 @@ extern YYSTYPE hlsl_lval; extern YYLTYPE hlsl_lloc; int hlsl_parse (void); -#endif /* !YY_HLSL_E_REACTOSSYNC3_0_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED */ +#endif /* !YY_HLSL_E_REACTOSSYNC_GCC_DLL_DIRECTX_WINE_D3DCOMPILER_43_HLSL_TAB_H_INCLUDED */ diff --git a/dll/directx/wine/d3dcompiler_43/hlsl.y b/dll/directx/wine/d3dcompiler_43/hlsl.y index f8bcdab979..c2c415f858 100644 --- a/dll/directx/wine/d3dcompiler_43/hlsl.y +++ b/dll/directx/wine/d3dcompiler_43/hlsl.y @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ %{ +#include "config.h" +#include "wine/debug.h" + +#include <stdio.h> #include "d3dcompiler_private.h" diff --git a/dll/directx/wine/d3dcompiler_43/hlsl.yy.c b/dll/directx/wine/d3dcompiler_43/hlsl.yy.c index a3e98d5543..9a91a4dd74 100644 --- a/dll/directx/wine/d3dcompiler_43/hlsl.yy.c +++ b/dll/directx/wine/d3dcompiler_43/hlsl.yy.c @@ -28,7 +28,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -161,15 +161,7 @@ typedef unsigned int flex_uint32_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -181,7 +173,12 @@ typedef unsigned int flex_uint32_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif -extern int hlsl_leng; +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t hlsl_leng; extern FILE *hlsl_in, *hlsl_out; @@ -207,11 +204,6 @@ extern FILE *hlsl_in, *hlsl_out; #define unput(c) yyunput( c, (yytext_ptr) ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -229,7 +221,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -299,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* yy_hold_char holds the character lost when hlsl_text is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int hlsl_leng; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t hlsl_leng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; @@ -328,7 +320,7 @@ static void hlsl__init_buffer (YY_BUFFER_STATE b,FILE *file ); YY_BUFFER_STATE hlsl__scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE hlsl__scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE hlsl__scan_bytes (yyconst char *bytes,int len ); +YY_BUFFER_STATE hlsl__scan_bytes (yyconst char *bytes,yy_size_t len ); void *hlsl_alloc (yy_size_t ); void *hlsl_realloc (void *,yy_size_t ); @@ -360,7 +352,7 @@ void hlsl_free (void * ); /* Begin user sect3 */ -#define hlsl_wrap(n) 1 +#define hlsl_wrap() 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -980,7 +972,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); #define YY_NO_INPUT 1 -#line 984 "hlsl.yy.c" +#line 976 "hlsl.yy.c" #define INITIAL 0 #define pp 1 @@ -995,7 +987,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); */ #include <unistd.h> #endif - + #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif @@ -1023,7 +1015,7 @@ FILE *hlsl_get_out (void ); void hlsl_set_out (FILE * out_str ); -int hlsl_get_leng (void ); +yy_size_t hlsl_get_leng (void ); char *hlsl_get_text (void ); @@ -1063,12 +1055,7 @@ static int input (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -1174,7 +1161,7 @@ YY_DECL #line 60 "hlsl.l" -#line 1178 "hlsl.yy.c" +#line 1165 "hlsl.yy.c" if ( !(yy_init) ) { @@ -1965,7 +1952,7 @@ YY_RULE_SETUP #line 276 "hlsl.l" ECHO; YY_BREAK -#line 1969 "hlsl.yy.c" +#line 1956 "hlsl.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(pp): case YY_STATE_EOF(pp_line): @@ -2156,21 +2143,21 @@ static int yy_get_next_buffer (void) else { - int num_to_read = + yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -2201,7 +2188,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -2297,7 +2284,7 @@ static int yy_get_next_buffer (void) yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 716); - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_INPUT @@ -2324,7 +2311,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -2598,7 +2585,7 @@ void hlsl_pop_buffer_state (void) */ static void hlsl_ensure_buffer_stack (void) { - int num_to_alloc; + yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { @@ -2695,12 +2682,12 @@ YY_BUFFER_STATE hlsl__scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE hlsl__scan_bytes (yyconst char * yybytes, int _yybytes_len ) +YY_BUFFER_STATE hlsl__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; - int i; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2782,7 +2769,7 @@ FILE *hlsl_get_out (void) /** Get the length of the current token. * */ -int hlsl_get_leng (void) +yy_size_t hlsl_get_leng (void) { return hlsl_leng; } @@ -2930,7 +2917,7 @@ void hlsl_free (void * ptr ) #define YYTABLES_NAME "yytables" -#line 276 "hlsl.l" +#line 275 "hlsl.l" diff --git a/dll/directx/wine/d3dcompiler_43/main.c b/dll/directx/wine/d3dcompiler_43/main.c index f67f3a63f4..929cec0a7a 100644 --- a/dll/directx/wine/d3dcompiler_43/main.c +++ b/dll/directx/wine/d3dcompiler_43/main.c @@ -19,6 +19,13 @@ * */ +#include "config.h" + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" + #include "d3dcompiler_private.h" BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) diff --git a/dll/directx/wine/d3dcompiler_43/precomp.h b/dll/directx/wine/d3dcompiler_43/precomp.h new file mode 100644 index 0000000000..149c438b9d --- /dev/null +++ b/dll/directx/wine/d3dcompiler_43/precomp.h @@ -0,0 +1,12 @@ + +#ifndef __WINE_D3DCOMPILER_PRECOMP_H +#define __WINE_D3DCOMPILER_PRECOMP_H + +#include <wine/config.h> +#include <wine/port.h> + +#include <stdio.h> + +#include "d3dcompiler_private.h" + +#endif /* !__WINE_D3DCOMPILER_PRECOMP_H */ diff --git a/dll/directx/wine/d3dcompiler_43/reflection.c b/dll/directx/wine/d3dcompiler_43/reflection.c index 3376f2287c..5a59c64f94 100644 --- a/dll/directx/wine/d3dcompiler_43/reflection.c +++ b/dll/directx/wine/d3dcompiler_43/reflection.c @@ -18,6 +18,9 @@ * */ +#include "config.h" +#include "wine/port.h" + #include "d3dcompiler_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); diff --git a/dll/directx/wine/d3dcompiler_43/utils.c b/dll/directx/wine/d3dcompiler_43/utils.c index fb4f0b7deb..79f3be8840 100644 --- a/dll/directx/wine/d3dcompiler_43/utils.c +++ b/dll/directx/wine/d3dcompiler_43/utils.c @@ -21,6 +21,11 @@ * */ +#include "config.h" +#include "wine/port.h" + +#include <stdio.h> + #include "d3dcompiler_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 24c72fb703..f137ad18a8 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -24,7 +24,7 @@ The following libraries are shared with Wine. reactos/dll/directx/wine/amstream # Synced to Wine-3.0 reactos/dll/directx/wine/d3d8 # Synced to Wine-3.0 reactos/dll/directx/wine/d3d9 # Synced to Wine-3.0 -reactos/dll/directx/wine/d3dcompiler_43 # Synced to Wine-3.0 +reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3 reactos/dll/directx/wine/d3drm # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-3.0 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-2.9
6 years, 9 months
1
0
0
0
← Newer
1
...
38
39
40
41
42
43
44
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Results per page:
10
25
50
100
200