Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2020
- 73 participants
- 650 discussions
[PATCH v2 1/2] d3dx10/tests: Add tests for D3DX10GetImageInfoFromResource{A, W}().
by Ziqing Hui 16 Nov '20
by Ziqing Hui 16 Nov '20
16 Nov '20
Signed-off-by: Ziqing Hui <zhui(a)codeweavers.com>
---
v2: * Use ok() after CopyFile.
* Replace FILE_ATTRIBUTE_ARCHIVE with FILE_ATTRIBUTE_NORMAL
dlls/d3dx10_43/tests/d3dx10.c | 75 +++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
1
0
[PATCH v4 1/2] amstream/tests: Add comments to AMDirectDrawStream::CompletionStatus tests.
by Anton Baskanov 16 Nov '20
by Anton Baskanov 16 Nov '20
16 Nov '20
Signed-off-by: Anton Baskanov <baskanov(a)gmail.com>
---
dlls/amstream/tests/amstream.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
index da5ef8f56a1..6b1a9e4575f 100644
--- a/dlls/amstream/tests/amstream.c
+++ b/dlls/amstream/tests/amstream.c
@@ -7951,12 +7951,14 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample2);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* Initial status is S_OK. */
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* Update changes the status to MS_S_PENDING. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -7966,6 +7968,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 100);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
+ /* Each Receive call changes the status of one queued sample to S_OK in the same order Update was called. */
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -7996,6 +7999,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* COMPSTAT_NOUPDATEOK removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8020,6 +8024,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* COMPSTAT_ABORT removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8044,18 +8049,21 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_NOUPDATEOK. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
+ /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_ABORT. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT | COMPSTAT_WAIT, INFINITE);
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
+ /* EndOfStream changes the status of the queued samples to MS_S_ENDOFSTREAM. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8068,6 +8076,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
+ /* Update after EndOfStream changes the status to MS_S_ENDOFSTREAM. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
@@ -8082,18 +8091,22 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* Continuous update can be canceled by COMPSTAT_NOUPDATEOK. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
+ /* Continuous update can be canceled by COMPSTAT_ABORT. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
+ /* If a sample is in countinuous update mode, when Receive is called it's status remains MS_S_PENDING
+ * and the sample is moved to the end of the queue. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8136,6 +8149,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* In continuous update mode, flushing does not affect the status. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8151,6 +8165,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
+ /* In continuous update mode, stopping and running the stream does not affect the status. */
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -8163,6 +8178,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
+ /* In continuous update mode, EndOfStream changes the status to MS_S_ENDOFSTREAM. */
hr = IPin_EndOfStream(pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -8174,6 +8190,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* COMPSTAT_WAIT resets the sample to the non-continuous update mode. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8189,6 +8206,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* In continuous update mode, CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8216,6 +8234,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8235,6 +8254,7 @@ static void test_ddrawstreamsample_completion_status(void)
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
CloseHandle(thread);
+ /* CompletionStatus with COMPSTAT_WAIT returns when EndOfStream is called. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8256,6 +8276,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* Stopping and running the stream does not affect the status and does not remove the sample from the queue. */
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
@@ -8277,6 +8298,7 @@ static void test_ddrawstreamsample_completion_status(void)
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* When the stream is stopped Update does not change the status. */
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr);
--
2.17.1
2
3
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/inetcpl.cpl/connections.c | 37 +++++++++++++---------------------
dlls/inetcpl.cpl/general.c | 19 +++++++----------
2 files changed, 21 insertions(+), 35 deletions(-)
diff --git a/dlls/inetcpl.cpl/connections.c b/dlls/inetcpl.cpl/connections.c
index 04e26ead6a7..4327c33b420 100644
--- a/dlls/inetcpl.cpl/connections.c
+++ b/dlls/inetcpl.cpl/connections.c
@@ -31,16 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
-static const WCHAR auto_config_url[] = {'A','u','t','o','C','o','n','f','i','g','U','R','L',0};
-static const WCHAR internet_settings[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
-static const WCHAR proxy_enable[] = {'P','r','o','x','y','E','n','a','b','l','e',0};
-static const WCHAR proxy_server[] = {'P','r','o','x','y','S','e','r','v','e','r',0};
-static const WCHAR connections[] = {'C','o','n','n','e','c','t','i','o','n','s',0};
-static const WCHAR default_connection_settings[] = {'D','e','f','a','u','l','t',
- 'C','o','n','n','e','c','t','i','o','n','S','e','t','t','i','n','g','s',0};
+static const WCHAR internet_settings[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
static BOOL initdialog_done;
@@ -71,7 +62,7 @@ static DWORD create_connection_settings(BOOL manual_proxy, const WCHAR *proxy_se
DWORD pac_url_len;
size += sizeof(DWORD);
- if(proxy_server)
+ if(L"ProxyServer")
{
proxy_server_len = WideCharToMultiByte(CP_UTF8, 0, proxy_server, -1,
NULL, 0, NULL, NULL);
@@ -139,26 +130,26 @@ static void connections_on_initdialog(HWND hwnd)
return;
size = sizeof(enabled);
- res = RegQueryValueExW(hkey, proxy_enable, NULL, &type, (BYTE*)&enabled, &size);
+ res = RegQueryValueExW(hkey, L"ProxyEnable", NULL, &type, (BYTE*)&enabled, &size);
if(res || type != REG_DWORD)
enabled = 0;
size = sizeof(address);
- res = RegQueryValueExW(hkey, proxy_server, NULL, &type, (BYTE*)address, &size);
+ res = RegQueryValueExW(hkey, L"ProxyServer", NULL, &type, (BYTE*)address, &size);
if(res || type != REG_SZ)
address[0] = 0;
size = sizeof(pac_url);
- res = RegQueryValueExW(hkey, auto_config_url, NULL, &type, (BYTE*)pac_url, &size);
+ res = RegQueryValueExW(hkey, L"AutoConfigURL", NULL, &type, (BYTE*)pac_url, &size);
if(res || type != REG_SZ)
pac_url[0] = 0;
- res = RegOpenKeyW(hkey, connections, &con);
+ res = RegOpenKeyW(hkey, L"Connections", &con);
RegCloseKey(hkey);
if(!res)
{
connection_settings *settings = NULL;
size = 0;
- while((res = RegQueryValueExW(con, default_connection_settings, NULL, &type,
+ while((res = RegQueryValueExW(con, L"DefaultConnectionSettings", NULL, &type,
(BYTE*)settings, &size)) == ERROR_MORE_DATA || !settings)
{
connection_settings *new_settings = heap_realloc(settings, size);
@@ -264,7 +255,7 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
return FALSE;
use_proxy = IsDlgButtonChecked(hwnd, IDC_USE_PROXY_SERVER);
- res = RegSetValueExW(hkey, proxy_enable, 0, REG_DWORD,
+ res = RegSetValueExW(hkey, L"ProxyEnable", 0, REG_DWORD,
(BYTE*)&use_proxy, sizeof(use_proxy));
if(res)
{
@@ -286,12 +277,12 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
proxy[proxy_len] = 0;
}
- res = RegSetValueExW(hkey, proxy_server, 0, REG_SZ,
+ res = RegSetValueExW(hkey, L"ProxyServer", 0, REG_SZ,
(BYTE*)proxy, (proxy_len+port_len)*sizeof(WCHAR));
}
else
{
- res = RegDeleteValueW(hkey, proxy_server);
+ res = RegDeleteValueW(hkey, L"ProxyServer");
if(res == ERROR_FILE_NOT_FOUND)
res = ERROR_SUCCESS;
}
@@ -308,12 +299,12 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
if(!pac_script_len) use_pac_script = FALSE;
if(use_pac_script)
{
- res = RegSetValueExW(hkey, auto_config_url, 0, REG_SZ,
+ res = RegSetValueExW(hkey, L"AutoConfigURL", 0, REG_SZ,
(BYTE*)pac_script, pac_script_len*sizeof(WCHAR));
}
else
{
- res = RegDeleteValueW(hkey, auto_config_url);
+ res = RegDeleteValueW(hkey, L"AutoConfigURL");
if(res == ERROR_FILE_NOT_FOUND)
res = ERROR_SUCCESS;
}
@@ -326,7 +317,7 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
use_wpad = IsDlgButtonChecked(hwnd, IDC_USE_WPAD);
- res = RegCreateKeyExW(hkey, connections, 0, NULL, 0, KEY_WRITE, NULL, &con, NULL);
+ res = RegCreateKeyExW(hkey, L"Connections", 0, NULL, 0, KEY_WRITE, NULL, &con, NULL);
RegCloseKey(hkey);
if(res)
return FALSE;
@@ -339,7 +330,7 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
return FALSE;
}
- res = RegSetValueExW(con, default_connection_settings, 0, REG_BINARY,
+ res = RegSetValueExW(con, L"DefaultConnectionSettings", 0, REG_BINARY,
(BYTE*)default_connection, size);
heap_free(default_connection);
RegCloseKey(con);
diff --git a/dlls/inetcpl.cpl/general.c b/dlls/inetcpl.cpl/general.c
index b9fbf1eb0ae..53e2d1d4fca 100644
--- a/dlls/inetcpl.cpl/general.c
+++ b/dlls/inetcpl.cpl/general.c
@@ -33,14 +33,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
-
-static const WCHAR about_blank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
-static const WCHAR start_page[] = {'S','t','a','r','t',' ','P','a','g','e',0};
-static const WCHAR default_page[] = {'D','e','f','a','u','l','t','_','P','a','g','e','_','U','R','L',0};
-static const WCHAR reg_ie_main[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
- 'M','a','i','n',0};
+static const WCHAR reg_ie_main[] = L"Software\\Microsoft\\Internet Explorer\\Main";
/* list of unimplemented buttons */
static DWORD disabled_general_buttons[] = {IDC_HOME_CURRENT,
@@ -188,13 +181,14 @@ static INT_PTR general_on_command(HWND hwnd, WPARAM wparam)
break;
case MAKEWPARAM(IDC_HOME_BLANK, BN_CLICKED):
- SetDlgItemTextW(hwnd, IDC_HOME_EDIT, about_blank);
+ SetDlgItemTextW(hwnd, IDC_HOME_EDIT, L"about:blank");
break;
case MAKEWPARAM(IDC_HOME_DEFAULT, BN_CLICKED):
len = sizeof(buffer);
type = REG_SZ;
- res = SHRegGetUSValueW(reg_ie_main, default_page, &type, buffer, &len, FALSE, (LPBYTE) about_blank, sizeof(about_blank));
+ res = SHRegGetUSValueW(reg_ie_main, L"Default_Page_URL", &type, buffer, &len, FALSE,
+ (BYTE *)L"about:blank", sizeof(L"about:blank"));
if (!res && (type == REG_SZ)) SetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer);
break;
@@ -235,7 +229,8 @@ static VOID general_on_initdialog(HWND hwnd)
*buffer = 0;
len = sizeof(buffer);
type = REG_SZ;
- res = SHRegGetUSValueW(reg_ie_main, start_page, &type, buffer, &len, FALSE, (LPBYTE) about_blank, sizeof(about_blank));
+ res = SHRegGetUSValueW(reg_ie_main, L"Start Page", &type, buffer, &len, FALSE,
+ (BYTE *)L"about:blank", sizeof(L"about:blank"));
if (!res && (type == REG_SZ))
{
@@ -281,7 +276,7 @@ static INT_PTR general_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
res = RegOpenKeyW(HKEY_CURRENT_USER, reg_ie_main, &hkey);
if (!res)
{
- res = RegSetValueExW(hkey, start_page, 0, REG_SZ, (const BYTE *)parsed,
+ res = RegSetValueExW(hkey, L"Start Page", 0, REG_SZ, (const BYTE *)parsed,
(lstrlenW(parsed) + 1) * sizeof(WCHAR));
RegCloseKey(hkey);
return !res;
--
2.26.2
1
0
[PATCH 1/2] inetcpl.cpl: Trace the actual AutoConfigURL and not the value name.
by Michael Stefaniuc 15 Nov '20
by Michael Stefaniuc 15 Nov '20
15 Nov '20
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
Current code always prints "AutoConfigURL = AutoConfigURL".
dlls/inetcpl.cpl/connections.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/inetcpl.cpl/connections.c b/dlls/inetcpl.cpl/connections.c
index c24374fd2a5..04e26ead6a7 100644
--- a/dlls/inetcpl.cpl/connections.c
+++ b/dlls/inetcpl.cpl/connections.c
@@ -184,7 +184,7 @@ static void connections_on_initdialog(HWND hwnd)
TRACE("ProxyEnable = %x\n", enabled);
TRACE("ProxyServer = %s\n", wine_dbgstr_w(address));
- TRACE("AutoConfigURL = %s\n", wine_dbgstr_w(auto_config_url));
+ TRACE("AutoConfigURL = %s\n", wine_dbgstr_w(pac_url));
if(enabled)
{
--
2.26.2
1
0
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/hidclass.sys/device.c | 8 ++------
dlls/hidclass.sys/pnp.c | 13 +++++--------
2 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 0e905c8322f..fc1dfd07db1 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -38,9 +38,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(hid);
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
-static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e',
- '\\','H','I','D','#','%','p','&','%','p',0};
-
NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT **device)
{
WCHAR dev_name[255];
@@ -48,7 +45,7 @@ NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRAT
NTSTATUS status;
BASE_DEVICE_EXTENSION *ext;
- swprintf(dev_name, ARRAY_SIZE(dev_name), device_name_fmtW, driver->DriverObject, native_device);
+ swprintf(dev_name, ARRAY_SIZE(dev_name), L"\\Device\\HID#%p&%p", driver->DriverObject, native_device);
RtlInitUnicodeString( &nameW, dev_name );
TRACE("Create base hid device %s\n", debugstr_w(dev_name));
@@ -76,7 +73,6 @@ NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRAT
NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
{
- static const WCHAR backslashW[] = {'\\',0};
WCHAR device_instance_id[MAX_DEVICE_ID_LEN];
SP_DEVINFO_DATA Data;
UNICODE_STRING nameW;
@@ -91,7 +87,7 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
RtlInitUnicodeString( &nameW, ext->device_name);
lstrcpyW(device_instance_id, ext->device_id);
- lstrcatW(device_instance_id, backslashW);
+ lstrcatW(device_instance_id, L"\\");
lstrcatW(device_instance_id, ext->instance_id);
devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_HIDCLASS, NULL);
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 1c130e8dd80..27de1e1b04b 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -30,9 +30,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(hid);
-static const WCHAR device_enumeratorW[] = {'H','I','D',0};
-static const WCHAR separator_W[] = {'\\',0};
-
static NTSTATUS WINAPI internalComplete(DEVICE_OBJECT *deviceObject, IRP *irp,
void *context)
{
@@ -193,8 +190,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
lstrcpyW(ext->instance_id, instance_id);
- lstrcpyW(ext->device_id, device_enumeratorW);
- lstrcatW(ext->device_id, separator_W);
+ lstrcpyW(ext->device_id, L"HID");
+ lstrcatW(ext->device_id, L"\\");
lstrcatW(ext->device_id, wcschr(device_id, '\\') + 1);
HID_LinkDevice(device);
@@ -264,7 +261,7 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
/* Device instance ID */
lstrcpyW(ptr, ext->device_id);
ptr += lstrlenW(ext->device_id);
- lstrcpyW(ptr, separator_W);
+ lstrcpyW(ptr, L"\\");
ptr += 1;
lstrcpyW(ptr, ext->instance_id);
ptr += lstrlenW(ext->instance_id) + 1;
@@ -272,8 +269,8 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
lstrcpyW(ptr, ext->device_id);
ptr += lstrlenW(ext->device_id) + 1;
/* Bus ID */
- lstrcpyW(ptr, device_enumeratorW);
- ptr += lstrlenW(device_enumeratorW) + 1;
+ lstrcpyW(ptr, L"HID");
+ ptr += lstrlenW(L"HID") + 1;
*ptr = 0;
irp->IoStatus.Information = (ULONG_PTR)id;
rc = STATUS_SUCCESS;
--
2.26.2
1
0
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/mscms/tests/profile.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/mscms/tests/profile.c b/dlls/mscms/tests/profile.c
index 063ea22420d..be4eaa66c00 100644
--- a/dlls/mscms/tests/profile.c
+++ b/dlls/mscms/tests/profile.c
@@ -772,7 +772,6 @@ static void test_InstallColorProfileA( char *standardprofile, char *testprofile
{
CHAR dest[MAX_PATH], base[MAX_PATH];
DWORD size = sizeof(dest);
- CHAR slash[] = "\\";
HANDLE handle;
SetLastError(0xdeadbeef);
@@ -789,7 +788,7 @@ static void test_InstallColorProfileA( char *standardprofile, char *testprofile
MSCMS_basenameA( testprofile, base );
- lstrcatA( dest, slash );
+ lstrcatA( dest, "\\" );
lstrcatA( dest, base );
/* Check if the profile is really there */
@@ -1157,7 +1156,6 @@ static void test_UninstallColorProfileA( char *testprofile )
{
CHAR dest[MAX_PATH], base[MAX_PATH];
DWORD size = sizeof(dest);
- CHAR slash[] = "\\";
HANDLE handle;
SetLastError(0xdeadbeef);
@@ -1174,7 +1172,7 @@ static void test_UninstallColorProfileA( char *testprofile )
MSCMS_basenameA( testprofile, base );
- lstrcatA( dest, slash );
+ lstrcatA( dest, "\\" );
lstrcatA( dest, base );
ret = pUninstallColorProfileA( NULL, dest, TRUE );
--
2.26.2
1
0
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/mscms/profile.c | 8 +++-----
dlls/mscms/tests/profile.c | 15 +++++----------
2 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/dlls/mscms/profile.c b/dlls/mscms/profile.c
index bc7f200006b..26a2eacd597 100644
--- a/dlls/mscms/profile.c
+++ b/dlls/mscms/profile.c
@@ -615,7 +615,6 @@ BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profi
static BOOL header_from_file( LPCWSTR file, PPROFILEHEADER header )
{
- static const WCHAR slash[] = {'\\',0};
BOOL ret;
PROFILE profile;
WCHAR path[MAX_PATH];
@@ -628,13 +627,13 @@ static BOOL header_from_file( LPCWSTR file, PPROFILEHEADER header )
WARN( "Can't retrieve color directory\n" );
return FALSE;
}
- if (size + sizeof(slash) + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path))
+ if (size + sizeof(L"\\") + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path))
{
WARN( "Filename too long\n" );
return FALSE;
}
- lstrcatW( path, slash );
+ lstrcatW( path, L"\\" );
lstrcatW( path, file );
profile.dwType = PROFILE_FILENAME;
@@ -1058,7 +1057,6 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
{
WCHAR dest[MAX_PATH], base[MAX_PATH];
DWORD size = sizeof(dest);
- static const WCHAR slash[] = { '\\', 0 };
TRACE( "( %s )\n", debugstr_w(profile) );
@@ -1068,7 +1066,7 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
basename( profile, base );
- lstrcatW( dest, slash );
+ lstrcatW( dest, L"\\" );
lstrcatW( dest, base );
/* Is source equal to destination? */
diff --git a/dlls/mscms/tests/profile.c b/dlls/mscms/tests/profile.c
index 15a0533145d..063ea22420d 100644
--- a/dlls/mscms/tests/profile.c
+++ b/dlls/mscms/tests/profile.c
@@ -102,7 +102,7 @@ static BOOL init_function_ptrs( void )
}
static const char machine[] = "dummy";
-static const WCHAR machineW[] = { 'd','u','m','m','y',0 };
+static const WCHAR machineW[] = L"dummy";
/* To do any real functionality testing with this suite you need a copy of
* the freely distributable standard RGB color space profile. It comes
@@ -119,12 +119,9 @@ static const char profile2[] =
"\\spool\\drivers\\color\\srgb color space profile.icm";
static const WCHAR profile1W[] =
-{ '\\','c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
- 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
+L"\\color\\srgb color space profile.icm";
static const WCHAR profile2W[] =
-{ '\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',
- 'c','o','l','o','r','\\','s','r','g','b',' ','c','o','l','o','r',' ',
- 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 };
+L"\\spool\\drivers\\color\\srgb color space profile.icm";
static BOOL have_color_profile;
@@ -832,7 +829,6 @@ static void test_InstallColorProfileW( WCHAR *standardprofileW, WCHAR *testprofi
{
WCHAR dest[MAX_PATH], base[MAX_PATH];
DWORD size = sizeof(dest);
- WCHAR slash[] = { '\\', 0 };
HANDLE handle;
SetLastError(0xdeadbeef);
@@ -849,7 +845,7 @@ static void test_InstallColorProfileW( WCHAR *standardprofileW, WCHAR *testprofi
MSCMS_basenameW( testprofileW, base );
- lstrcatW( dest, slash );
+ lstrcatW( dest, L"\\" );
lstrcatW( dest, base );
/* Check if the profile is really there */
@@ -1210,7 +1206,6 @@ static void test_UninstallColorProfileW( WCHAR *testprofileW )
WCHAR dest[MAX_PATH], base[MAX_PATH];
char destA[MAX_PATH];
DWORD size = sizeof(dest);
- WCHAR slash[] = { '\\', 0 };
HANDLE handle;
int bytes_copied;
@@ -1228,7 +1223,7 @@ static void test_UninstallColorProfileW( WCHAR *testprofileW )
MSCMS_basenameW( testprofileW, base );
- lstrcatW( dest, slash );
+ lstrcatW( dest, L"\\" );
lstrcatW( dest, base );
ret = pUninstallColorProfileW( NULL, dest, TRUE );
--
2.26.2
1
0
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/mstask/task.c | 10 ++++------
dlls/mstask/task_scheduler.c | 15 +++++----------
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c
index a15e0164b43..398cefc58e4 100644
--- a/dlls/mstask/task.c
+++ b/dlls/mstask/task.c
@@ -1617,8 +1617,8 @@ static BOOL write_unicode_string(HANDLE hfile, const WCHAR *str)
static HRESULT WINAPI MSTASK_IPersistFile_Save(IPersistFile *iface, LPCOLESTR task_name, BOOL remember)
{
- static WCHAR authorW[] = { 'W','i','n','e',0 };
- static WCHAR commentW[] = { 'C','r','e','a','t','e','d',' ','b','y',' ','W','i','n','e',0 };
+ static WCHAR authorW[] = L"Wine";
+ static WCHAR commentW[] = L"Created by Wine";
FIXDLEN_DATA fixed;
WORD word, user_data_size = 0;
HANDLE hfile;
@@ -1883,8 +1883,6 @@ static const IPersistFileVtbl MSTASK_IPersistFileVtbl =
HRESULT TaskConstructor(ITaskService *service, const WCHAR *name, ITask **task)
{
- static const WCHAR tasksW[] = { '\\','T','a','s','k','s','\\',0 };
- static const WCHAR jobW[] = { '.','j','o','b',0 };
TaskImpl *This;
WCHAR task_name[MAX_PATH];
ITaskDefinition *taskdef;
@@ -1896,9 +1894,9 @@ HRESULT TaskConstructor(ITaskService *service, const WCHAR *name, ITask **task)
if (wcschr(name, '.')) return E_INVALIDARG;
GetWindowsDirectoryW(task_name, MAX_PATH);
- lstrcatW(task_name, tasksW);
+ lstrcatW(task_name, L"\\Tasks\\");
lstrcatW(task_name, name);
- lstrcatW(task_name, jobW);
+ lstrcatW(task_name, L".job");
hr = ITaskService_NewTask(service, 0, &taskdef);
if (hr != S_OK) return hr;
diff --git a/dlls/mstask/task_scheduler.c b/dlls/mstask/task_scheduler.c
index 54ca3609ff4..12eeae3565c 100644
--- a/dlls/mstask/task_scheduler.c
+++ b/dlls/mstask/task_scheduler.c
@@ -124,7 +124,6 @@ static inline BOOL is_file(const WIN32_FIND_DATAW *data)
static HRESULT WINAPI EnumWorkItems_Next(IEnumWorkItems *iface, ULONG count, LPWSTR **names, ULONG *fetched)
{
- static const WCHAR tasksW[] = { '\\','T','a','s','k','s','\\','*',0 };
EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
WCHAR path[MAX_PATH];
WIN32_FIND_DATAW data;
@@ -146,7 +145,7 @@ static HRESULT WINAPI EnumWorkItems_Next(IEnumWorkItems *iface, ULONG count, LPW
if (This->handle == INVALID_HANDLE_VALUE)
{
GetWindowsDirectoryW(path, MAX_PATH);
- lstrcatW(path, tasksW);
+ lstrcatW(path, L"\\Tasks\\*");
This->handle = FindFirstFileW(path, &data);
if (This->handle == INVALID_HANDLE_VALUE)
return S_FALSE;
@@ -417,8 +416,6 @@ static HRESULT WINAPI MSTASK_ITaskScheduler_Activate(ITaskScheduler *iface,
static HRESULT WINAPI MSTASK_ITaskScheduler_Delete(ITaskScheduler *iface, LPCWSTR name)
{
- static const WCHAR tasksW[] = { '\\','T','a','s','k','s','\\',0 };
- static const WCHAR jobW[] = { '.','j','o','b',0 };
WCHAR task_name[MAX_PATH];
TRACE("%p, %s\n", iface, debugstr_w(name));
@@ -426,9 +423,9 @@ static HRESULT WINAPI MSTASK_ITaskScheduler_Delete(ITaskScheduler *iface, LPCWST
if (wcschr(name, '.')) return E_INVALIDARG;
GetWindowsDirectoryW(task_name, MAX_PATH);
- lstrcatW(task_name, tasksW);
+ lstrcatW(task_name, L"\\Tasks\\");
lstrcatW(task_name, name);
- lstrcatW(task_name, jobW);
+ lstrcatW(task_name, L".job");
if (!DeleteFileW(task_name))
return HRESULT_FROM_WIN32(GetLastError());
@@ -459,8 +456,6 @@ static HRESULT WINAPI MSTASK_ITaskScheduler_NewWorkItem(
static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem(ITaskScheduler *iface, LPCWSTR name, IScheduledWorkItem *item)
{
- static const WCHAR tasksW[] = { '\\','T','a','s','k','s','\\',0 };
- static const WCHAR jobW[] = { '.','j','o','b',0 };
WCHAR task_name[MAX_PATH];
IPersistFile *pfile;
HRESULT hr;
@@ -470,9 +465,9 @@ static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem(ITaskScheduler *iface, L
if (wcschr(name, '.')) return E_INVALIDARG;
GetWindowsDirectoryW(task_name, MAX_PATH);
- lstrcatW(task_name, tasksW);
+ lstrcatW(task_name, L"\\Tasks\\");
lstrcatW(task_name, name);
- lstrcatW(task_name, jobW);
+ lstrcatW(task_name, L".job");
hr = IScheduledWorkItem_QueryInterface(item, &IID_IPersistFile, (void **)&pfile);
if (hr == S_OK)
--
2.26.2
1
0
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/gdi32/uniscribe/usp10.c | 259 ++++++++++++-----------------------
1 file changed, 86 insertions(+), 173 deletions(-)
diff --git a/dlls/gdi32/uniscribe/usp10.c b/dlls/gdi32/uniscribe/usp10.c
index 7dbb513a47e..50f38f957b2 100644
--- a/dlls/gdi32/uniscribe/usp10.c
+++ b/dlls/gdi32/uniscribe/usp10.c
@@ -302,332 +302,250 @@ script_ranges[] =
const scriptData scriptInformation[] = {
{{SCRIPT_UNDEFINED, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Latin, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('l','a','t','n'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('l','a','t','n'), L"Microsoft Sans Serif"},
{{Script_CR, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 1, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- 0x00000000,
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ 0x00000000, L"Microsoft Sans Serif"},
{{Script_Control, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 1, 0, 0, ANSI_CHARSET, 1, 0, 0, 0, 0, 0, 1, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Punctuation, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- 0x00000000,
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ 0x00000000, L"Microsoft Sans Serif"},
{{Script_Arabic, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
{LANG_ARABIC, 0, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 1, 1, 0},
- MS_MAKE_TAG('a','r','a','b'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('a','r','a','b'), L"Microsoft Sans Serif"},
{{Script_Arabic_Numeric, 0, 1, 0, 0, 0, 0, { 2,0,0,0,0,0,0,0,0,0,0}},
{LANG_ARABIC, 1, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('a','r','a','b'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('a','r','a','b'), L"Microsoft Sans Serif"},
{{Script_Hebrew, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
{LANG_HEBREW, 0, 1, 0, 1, HEBREW_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('h','e','b','r'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('h','e','b','r'), L"Microsoft Sans Serif"},
{{Script_Syriac, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
{LANG_SYRIAC, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 1, 0},
- MS_MAKE_TAG('s','y','r','c'),
- {'E','s','t','r','a','n','g','e','l','o',' ','E','d','e','s','s','a',0}},
+ MS_MAKE_TAG('s','y','r','c'), L"Estrangelo Edessa"},
{{Script_Persian, 0, 1, 0, 0, 0, 0, { 2,0,0,0,0,0,0,0,0,0,0}},
{LANG_PERSIAN, 1, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('a','r','a','b'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('a','r','a','b'), L"Microsoft Sans Serif"},
{{Script_Thaana, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
{LANG_DIVEHI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','h','a','a'),
- {'M','V',' ','B','o','l','i',0}},
+ MS_MAKE_TAG('t','h','a','a'), L"MV Boli"},
{{Script_Greek, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_GREEK, 0, 0, 0, 0, GREEK_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('g','r','e','k'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('g','r','e','k'), L"Microsoft Sans Serif"},
{{Script_Cyrillic, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_RUSSIAN, 0, 0, 0, 0, RUSSIAN_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('c','y','r','l'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('c','y','r','l'), L"Microsoft Sans Serif"},
{{Script_Armenian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ARMENIAN, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('a','r','m','n'),
- {'S','y','l','f','a','e','n',0}},
+ MS_MAKE_TAG('a','r','m','n'), L"Sylfaen"},
{{Script_Georgian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_GEORGIAN, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('g','e','o','r'),
- {'S','y','l','f','a','e','n',0}},
+ MS_MAKE_TAG('g','e','o','r'), L"Sylfaen"},
{{Script_Sinhala, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_SINHALESE, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('s','i','n','h'),
- {'I','s','k','o','o','l','a',' ','P','o','t','a',0}},
+ MS_MAKE_TAG('s','i','n','h'), L"Iskoola Pota"},
{{Script_Tibetan, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TIBETAN, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 1, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('t','i','b','t'),
- {'M','i','c','r','o','s','o','f','t',' ','H','i','m','a','l','a','y','a',0}},
+ MS_MAKE_TAG('t','i','b','t'), L"Microsoft Himalaya"},
{{Script_Tibetan_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TIBETAN, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','i','b','t'),
- {'M','i','c','r','o','s','o','f','t',' ','H','i','m','a','l','a','y','a',0}},
+ MS_MAKE_TAG('t','i','b','t'), L"Microsoft Himalaya"},
{{Script_Phags_pa, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MONGOLIAN, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('p','h','a','g'),
- {'M','i','c','r','o','s','o','f','t',' ','P','h','a','g','s','P','a',0}},
+ MS_MAKE_TAG('p','h','a','g'), L"Microsoft PhagsPa"},
{{Script_Thai, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_THAI, 0, 1, 1, 1, THAI_CHARSET, 0, 0, 1, 0, 1, 0, 0, 0, 1},
- MS_MAKE_TAG('t','h','a','i'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('t','h','a','i'), L"Microsoft Sans Serif"},
{{Script_Thai_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_THAI, 1, 1, 0, 0, THAI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','h','a','i'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('t','h','a','i'), L"Microsoft Sans Serif"},
{{Script_Lao, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_LAO, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 1, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('l','a','o',' '),
- {'D','o','k','C','h','a','m','p','a',0}},
+ MS_MAKE_TAG('l','a','o',' '), L"DokChampa"},
{{Script_Lao_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_LAO, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('l','a','o',' '),
- {'D','o','k','C','h','a','m','p','a',0}},
+ MS_MAKE_TAG('l','a','o',' '), L"DokChampa"},
{{Script_Devanagari, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_HINDI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('d','e','v','a'),
- {'M','a','n','g','a','l',0}},
+ MS_MAKE_TAG('d','e','v','a'), L"Mangal"},
{{Script_Devanagari_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_HINDI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('d','e','v','a'),
- {'M','a','n','g','a','l',0}},
+ MS_MAKE_TAG('d','e','v','a'), L"Mangal"},
{{Script_Bengali, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_BENGALI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('b','e','n','g'),
- {'V','r','i','n','d','a',0}},
+ MS_MAKE_TAG('b','e','n','g'), L"Vrinda"},
{{Script_Bengali_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_BENGALI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('b','e','n','g'),
- {'V','r','i','n','d','a',0}},
+ MS_MAKE_TAG('b','e','n','g'), L"Vrinda"},
{{Script_Bengali_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_BENGALI, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('b','e','n','g'),
- {'V','r','i','n','d','a',0}},
+ MS_MAKE_TAG('b','e','n','g'), L"Vrinda"},
{{Script_Gurmukhi, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_PUNJABI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('g','u','r','u'),
- {'R','a','a','v','i',0}},
+ MS_MAKE_TAG('g','u','r','u'), L"Raavi"},
{{Script_Gurmukhi_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_PUNJABI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('g','u','r','u'),
- {'R','a','a','v','i',0}},
+ MS_MAKE_TAG('g','u','r','u'), L"Raavi"},
{{Script_Gujarati, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_GUJARATI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('g','u','j','r'),
- {'S','h','r','u','t','i',0}},
+ MS_MAKE_TAG('g','u','j','r'), L"Shruti"},
{{Script_Gujarati_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_GUJARATI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('g','u','j','r'),
- {'S','h','r','u','t','i',0}},
+ MS_MAKE_TAG('g','u','j','r'), L"Shruti"},
{{Script_Gujarati_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_GUJARATI, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('g','u','j','r'),
- {'S','h','r','u','t','i',0}},
+ MS_MAKE_TAG('g','u','j','r'), L"Shruti"},
{{Script_Oriya, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ORIYA, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('o','r','y','a'),
- {'K','a','l','i','n','g','a',0}},
+ MS_MAKE_TAG('o','r','y','a'), L"Kalinga"},
{{Script_Oriya_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ORIYA, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('o','r','y','a'),
- {'K','a','l','i','n','g','a',0}},
+ MS_MAKE_TAG('o','r','y','a'), L"Kalinga"},
{{Script_Tamil, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TAMIL, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('t','a','m','l'),
- {'L','a','t','h','a',0}},
+ MS_MAKE_TAG('t','a','m','l'), L"Latha"},
{{Script_Tamil_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TAMIL, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','a','m','l'),
- {'L','a','t','h','a',0}},
+ MS_MAKE_TAG('t','a','m','l'), L"Latha"},
{{Script_Telugu, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TELUGU, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('t','e','l','u'),
- {'G','a','u','t','a','m','i',0}},
+ MS_MAKE_TAG('t','e','l','u'), L"Gautami"},
{{Script_Telugu_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_TELUGU, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','e','l','u'),
- {'G','a','u','t','a','m','i',0}},
+ MS_MAKE_TAG('t','e','l','u'), L"Gautami"},
{{Script_Kannada, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_KANNADA, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('k','n','d','a'),
- {'T','u','n','g','a',0}},
+ MS_MAKE_TAG('k','n','d','a'), L"Tunga"},
{{Script_Kannada_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_KANNADA, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('k','n','d','a'),
- {'T','u','n','g','a',0}},
+ MS_MAKE_TAG('k','n','d','a'), L"Tunga"},
{{Script_Malayalam, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MALAYALAM, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('m','l','y','m'),
- {'K','a','r','t','i','k','a',0}},
+ MS_MAKE_TAG('m','l','y','m'), L"Kartika"},
{{Script_Malayalam_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MALAYALAM, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('m','l','y','m'),
- {'K','a','r','t','i','k','a',0}},
+ MS_MAKE_TAG('m','l','y','m'), L"Kartika"},
{{Script_Diacritical, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 1, 0, 1, ANSI_CHARSET, 0, 0, 0, 0, 0, 1, 1, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Punctuation2, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('l','a','t','n'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('l','a','t','n'), L"Microsoft Sans Serif"},
{{Script_Numeric2, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 1, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Myanmar, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x55, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('m','y','m','r'),
- {'M','y','a','n','m','a','r',' ','T','e','x','t',0}},
+ MS_MAKE_TAG('m','y','m','r'), L"Myanmar Text"},
{{Script_Myanmar_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x55, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('m','y','m','r'),
- {0}},
+ MS_MAKE_TAG('m','y','m','r'), L""},
{{Script_Tai_Le, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','a','l','e'),
- {'M','i','c','r','o','s','o','f','t',' ','T','a','i',' ','L','e',0}},
+ MS_MAKE_TAG('t','a','l','e'), L"Microsoft Tai Le"},
{{Script_New_Tai_Lue, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','a','l','u'),
- {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e',0}},
+ MS_MAKE_TAG('t','a','l','u'), L"Microsoft New Tai Lue"},
{{Script_New_Tai_Lue_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','a','l','u'),
- {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e',0}},
+ MS_MAKE_TAG('t','a','l','u'), L"Microsoft New Tai Lue"},
{{Script_Khmer, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x53, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
- MS_MAKE_TAG('k','h','m','r'),
- {'D','a','u','n','P','e','n','h',0}},
+ MS_MAKE_TAG('k','h','m','r'), L"DaunPenh"},
{{Script_Khmer_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x53, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('k','h','m','r'),
- {'D','a','u','n','P','e','n','h',0}},
+ MS_MAKE_TAG('k','h','m','r'), L"DaunPenh"},
{{Script_CJK_Han, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('h','a','n','i'),
- {0}},
+ MS_MAKE_TAG('h','a','n','i'), L""},
{{Script_Ideograph, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('h','a','n','i'),
- {0}},
+ MS_MAKE_TAG('h','a','n','i'), L""},
{{Script_Bopomofo, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('b','o','p','o'),
- {0}},
+ MS_MAKE_TAG('b','o','p','o'), L""},
{{Script_Kana, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('k','a','n','a'),
- {0}},
+ MS_MAKE_TAG('k','a','n','a'), L""},
{{Script_Hangul, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_KOREAN, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('h','a','n','g'),
- {0}},
+ MS_MAKE_TAG('h','a','n','g'), L""},
{{Script_Yi, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- MS_MAKE_TAG('y','i',' ',' '),
- {'M','i','c','r','o','s','o','f','t',' ','Y','i',' ','B','a','i','t','i',0}},
+ MS_MAKE_TAG('y','i',' ',' '), L"Microsoft Yi Baiti"},
{{Script_Ethiopic, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x5e, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('e','t','h','i'),
- {'N','y','a','l','a',0}},
+ MS_MAKE_TAG('e','t','h','i'), L"Nyala"},
{{Script_Ethiopic_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x5e, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('e','t','h','i'),
- {'N','y','a','l','a',0}},
+ MS_MAKE_TAG('e','t','h','i'), L"Nyala"},
{{Script_Mongolian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MONGOLIAN, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('m','o','n','g'),
- {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i',0}},
+ MS_MAKE_TAG('m','o','n','g'), L"Mongolian Baiti"},
{{Script_Mongolian_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MONGOLIAN, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('m','o','n','g'),
- {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i',0}},
+ MS_MAKE_TAG('m','o','n','g'), L"Mongolian Baiti"},
{{Script_Tifinagh, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','f','n','g'),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('t','f','n','g'), L"Ebrima"},
{{Script_NKo, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('n','k','o',' '),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('n','k','o',' '), L"Ebrima"},
{{Script_Vai, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('v','a','i',' '),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('v','a','i',' '), L"Ebrima"},
{{Script_Vai_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('v','a','i',' '),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('v','a','i',' '), L"Ebrima"},
{{Script_Cherokee, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x5c, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('c','h','e','r'),
- {'P','l','a','n','t','a','g','e','n','e','t',' ','C','h','e','r','o','k','e','e',0}},
+ MS_MAKE_TAG('c','h','e','r'), L"Plantagenet Cherokee"},
{{Script_Canadian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0x5d, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('c','a','n','s'),
- {'E','u','p','h','e','m','i','a',0}},
+ MS_MAKE_TAG('c','a','n','s'), L"Euphemia"},
{{Script_Ogham, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('o','g','a','m'),
- {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
+ MS_MAKE_TAG('o','g','a','m'), L"Segoe UI Symbol"},
{{Script_Runic, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('r','u','n','r'),
- {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
+ MS_MAKE_TAG('r','u','n','r'), L"Segoe UI Symbol"},
{{Script_Braille, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('b','r','a','i'),
- {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
+ MS_MAKE_TAG('b','r','a','i'), L"Segoe UI Symbol"},
{{Script_Surrogates, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_ENGLISH, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Private, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 1, 0, 0, 0, 0, 1, 0, 0},
- 0x00000000,
- {0}},
+ 0x00000000, L""},
{{Script_Deseret, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('d','s','r','t'),
- {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
+ MS_MAKE_TAG('d','s','r','t'), L"Segoe UI Symbol"},
{{Script_Osmanya, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('o','s','m','a'),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('o','s','m','a'), L"Ebrima"},
{{Script_Osmanya_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('o','s','m','a'),
- {'E','b','r','i','m','a',0}},
+ MS_MAKE_TAG('o','s','m','a'), L"Ebrima"},
{{Script_MathAlpha, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('m','a','t','h'),
- {'C','a','m','b','r','i','a',' ','M','a','t','h',0}},
+ MS_MAKE_TAG('m','a','t','h'), L"Cambria Math"},
{{Script_Hebrew_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_HEBREW, 0, 1, 0, 0, HEBREW_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('h','e','b','r'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('h','e','b','r'), L"Microsoft Sans Serif"},
{{Script_Vietnamese_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_VIETNAMESE, 0, 0, 0, 0, VIETNAMESE_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('l','a','t','n'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('l','a','t','n'), L"Microsoft Sans Serif"},
{{Script_Thai_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_THAI, 0, 1, 0, 0, THAI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- MS_MAKE_TAG('t','h','a','i'),
- {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
+ MS_MAKE_TAG('t','h','a','i'), L"Microsoft Sans Serif"},
};
static const SCRIPT_PROPERTIES *script_props[] =
@@ -967,7 +885,6 @@ static int __cdecl usp10_compare_script_range(const void *key, const void *value
static enum usp10_script get_char_script(const WCHAR *str, unsigned int index,
unsigned int end, unsigned int *consumed)
{
- static const WCHAR latin_punc[] = {'#','$','&','\'',',',';','<','>','?','@','\\','^','_','`','{','|','}','~', 0x00a0, 0};
struct usp10_script_range *range;
WORD type = 0, type2 = 0;
DWORD ch;
@@ -978,7 +895,7 @@ static enum usp10_script get_char_script(const WCHAR *str, unsigned int index,
return Script_CR;
/* These punctuation characters are separated out as Latin punctuation */
- if (wcschr(latin_punc,str[index]))
+ if (wcschr(L"#$&',;<>?@\\^_`{|}~\x00a0", str[index]))
return Script_Punctuation2;
/* These chars are itemized as Punctuation by Windows */
@@ -1513,9 +1430,6 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
}
else
{
- static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
- static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0};
-
if (!(strength = heap_calloc(cInChars, sizeof(*strength))))
goto nomemory;
BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
@@ -1534,7 +1448,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
{
if (i > 0 && i < cInChars-1 &&
script_is_numeric(scripts[i-1]) &&
- wcschr(math_punc, pwcInChars[i]))
+ wcschr(L"#$%+,-./:\x2212\x2044\x00a0", pwcInChars[i]))
{
if (script_is_numeric(scripts[i+1]))
{
@@ -1543,7 +1457,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
strength[i] = strength[i-1];
i++;
}
- else if (wcschr(repeatable_math_punc, pwcInChars[i]))
+ else if (wcschr(L"#$%+-/\x2212\x2044", pwcInChars[i]))
{
int j;
for (j = i+1; j < cInChars; j++)
@@ -1962,12 +1876,11 @@ static void find_fallback_font(enum usp10_script scriptid, WCHAR *FaceName)
if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Uniscribe\\Fallback", &hkey))
{
- static const WCHAR szFmt[] = {'%','x',0};
WCHAR value[10];
DWORD count = LF_FACESIZE * sizeof(WCHAR);
DWORD type;
- swprintf(value, ARRAY_SIZE(value), szFmt, scriptInformation[scriptid].scriptTag);
+ swprintf(value, ARRAY_SIZE(value), L"%x", scriptInformation[scriptid].scriptTag);
if (RegQueryValueExW(hkey, value, 0, &type, (BYTE *)FaceName, &count))
lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
RegCloseKey(hkey);
--
2.26.2
1
0
Signed-off-by: Esme Povirk <esme(a)codeweavers.com>
---
Unfortunately, I don't think I can split this up any further. We can't
have multiple encoder implementations splitting up tasks and writing
to the same file.
dlls/windowscodecs/Makefile.in | 1 +
dlls/windowscodecs/encoder.c | 744 +++++++++++++++++
dlls/windowscodecs/libpng.c | 346 ++++++++
dlls/windowscodecs/main.c | 5 +
dlls/windowscodecs/pngformat.c | 1028 +-----------------------
dlls/windowscodecs/unix_iface.c | 45 +-
dlls/windowscodecs/unix_lib.c | 11 +
dlls/windowscodecs/wincodecs_common.h | 30 +
dlls/windowscodecs/wincodecs_private.h | 40 +
9 files changed, 1230 insertions(+), 1020 deletions(-)
create mode 100644 dlls/windowscodecs/encoder.c
diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in
index 94b75b62596..e175359ab9d 100644
--- a/dlls/windowscodecs/Makefile.in
+++ b/dlls/windowscodecs/Makefile.in
@@ -15,6 +15,7 @@ C_SRCS = \
converter.c \
ddsformat.c \
decoder.c \
+ encoder.c \
fliprotate.c \
gifformat.c \
icnsformat.c \
diff --git a/dlls/windowscodecs/encoder.c b/dlls/windowscodecs/encoder.c
new file mode 100644
index 00000000000..a051480bbab
--- /dev/null
+++ b/dlls/windowscodecs/encoder.c
@@ -0,0 +1,744 @@
+/*
+ * Copyright 2020 Esme Povirk
+ *
+ * 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 "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+
+#include "wincodecs_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
+static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
+static const WCHAR wszPngFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
+
+static const PROPBAG2 encoder_option_properties[ENCODER_OPTION_END] = {
+ { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption },
+ { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption }
+};
+
+typedef struct CommonEncoder {
+ IWICBitmapEncoder IWICBitmapEncoder_iface;
+ LONG ref;
+ CRITICAL_SECTION lock; /* must be held when stream or encoder is accessed */
+ IStream *stream;
+ struct encoder *encoder;
+ struct encoder_info encoder_info;
+ UINT frame_count;
+ BOOL uncommitted_frame;
+ BOOL committed;
+} CommonEncoder;
+
+typedef struct CommonEncoderFrame {
+ IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
+ LONG ref;
+ CommonEncoder *parent;
+ struct encoder_frame encoder_frame;
+ BOOL initialized;
+ BOOL frame_created;
+ UINT lines_written;
+ BOOL committed;
+} CommonEncoderFrame;
+
+static inline CommonEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
+{
+ return CONTAINING_RECORD(iface, CommonEncoder, IWICBitmapEncoder_iface);
+}
+
+static inline CommonEncoderFrame *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
+{
+ return CONTAINING_RECORD(iface, CommonEncoderFrame, IWICBitmapFrameEncode_iface);
+}
+
+static HRESULT WINAPI CommonEncoderFrame_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
+ void **ppv)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
+ {
+ *ppv = &This->IWICBitmapFrameEncode_iface;
+ }
+ else
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI CommonEncoderFrame_AddRef(IWICBitmapFrameEncode *iface)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI CommonEncoderFrame_Release(IWICBitmapFrameEncode *iface)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ if (ref == 0)
+ {
+ IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_Initialize(IWICBitmapFrameEncode *iface,
+ IPropertyBag2 *pIEncoderOptions)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr=S_OK;
+ struct encoder_frame options = {0};
+ PROPBAG2 opts[7]= {{0}};
+ VARIANT opt_values[7];
+ HRESULT opt_hres[7];
+ DWORD num_opts, i;
+
+ TRACE("(%p,%p)\n", iface, pIEncoderOptions);
+
+ if (pIEncoderOptions)
+ {
+ for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++)
+ opts[i] = encoder_option_properties[This->parent->encoder_info.encoder_options[i]];
+ num_opts = i;
+
+ hr = IPropertyBag2_Read(pIEncoderOptions, num_opts, opts, NULL, opt_values, opt_hres);
+
+ if (FAILED(hr))
+ return hr;
+
+ for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++)
+ {
+ VARIANT *val = &opt_values[i];
+
+ switch (This->parent->encoder_info.encoder_options[i])
+ {
+ case ENCODER_OPTION_INTERLACE:
+ if (V_VT(val) == VT_EMPTY)
+ options.interlace = FALSE;
+ else
+ options.interlace = (V_BOOL(val) != 0);
+ break;
+ case ENCODER_OPTION_FILTER:
+ options.filter = V_UI1(val);
+ if (options.filter > WICPngFilterAdaptive)
+ {
+ WARN("Unrecognized filter option value %u.\n", options.filter);
+ options.filter = WICPngFilterUnspecified;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ options.interlace = FALSE;
+ options.filter = WICPngFilterUnspecified;
+ }
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (This->initialized)
+ hr = WINCODEC_ERR_WRONGSTATE;
+ else
+ {
+ This->encoder_frame = options;
+ This->initialized = TRUE;
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetSize(IWICBitmapFrameEncode *iface,
+ UINT uiWidth, UINT uiHeight)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->initialized || This->frame_created)
+ {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ }
+ else
+ {
+ This->encoder_frame.width = uiWidth;
+ This->encoder_frame.height = uiHeight;
+ hr = S_OK;
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetResolution(IWICBitmapFrameEncode *iface,
+ double dpiX, double dpiY)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->initialized || This->frame_created)
+ {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ }
+ else
+ {
+ This->encoder_frame.dpix = dpiX;
+ This->encoder_frame.dpiy = dpiY;
+ hr = S_OK;
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetPixelFormat(IWICBitmapFrameEncode *iface,
+ WICPixelFormatGUID *pPixelFormat)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+ GUID pixel_format;
+ DWORD bpp;
+ BOOL indexed;
+
+ TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->initialized || This->frame_created)
+ {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ }
+ else
+ {
+ pixel_format = *pPixelFormat;
+ hr = encoder_get_supported_format(This->parent->encoder, &pixel_format, &bpp, &indexed);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ TRACE("<-- %s bpp=%i indexed=%i\n", wine_dbgstr_guid(&pixel_format), bpp, indexed);
+ *pPixelFormat = pixel_format;
+ This->encoder_frame.pixel_format = pixel_format;
+ This->encoder_frame.bpp = bpp;
+ This->encoder_frame.indexed = indexed;
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetColorContexts(IWICBitmapFrameEncode *iface,
+ UINT cCount, IWICColorContext **ppIColorContext)
+{
+ FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetPalette(IWICBitmapFrameEncode *iface,
+ IWICPalette *palette)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("(%p,%p)\n", iface, palette);
+
+ if (!palette)
+ return E_INVALIDARG;
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->initialized)
+ hr = WINCODEC_ERR_NOTINITIALIZED;
+ else if (This->frame_created)
+ hr = WINCODEC_ERR_WRONGSTATE;
+ else
+ hr = IWICPalette_GetColors(palette, 256, This->encoder_frame.palette,
+ &This->encoder_frame.num_colors);
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_SetThumbnail(IWICBitmapFrameEncode *iface,
+ IWICBitmapSource *pIThumbnail)
+{
+ FIXME("(%p,%p): stub\n", iface, pIThumbnail);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_WritePixels(IWICBitmapFrameEncode *iface,
+ UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr=S_OK;
+ DWORD required_stride;
+
+ TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->initialized || !This->encoder_frame.height || !This->encoder_frame.width ||
+ !This->encoder_frame.bpp)
+ {
+ LeaveCriticalSection(&This->parent->lock);
+ return WINCODEC_ERR_WRONGSTATE;
+ }
+
+ required_stride = (This->encoder_frame.width * This->encoder_frame.bpp + 7)/8;
+
+ if (lineCount == 0 || This->encoder_frame.height - This->lines_written < lineCount ||
+ cbStride < required_stride || cbBufferSize < cbStride * (lineCount - 1) + required_stride ||
+ !pbPixels)
+ {
+ LeaveCriticalSection(&This->parent->lock);
+ return E_INVALIDARG;
+ }
+
+ if (!This->frame_created)
+ {
+ hr = encoder_create_frame(This->parent->encoder, &This->encoder_frame);
+ if (SUCCEEDED(hr))
+ This->frame_created = TRUE;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = encoder_write_lines(This->parent->encoder, pbPixels, lineCount, cbStride);
+ if (SUCCEEDED(hr))
+ This->lines_written += lineCount;
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_WriteSource(IWICBitmapFrameEncode *iface,
+ IWICBitmapSource *pIBitmapSource, WICRect *prc)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+ TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc));
+
+ if (!This->initialized)
+ return WINCODEC_ERR_WRONGSTATE;
+
+ hr = configure_write_source(iface, pIBitmapSource, prc,
+ This->encoder_frame.bpp ? &This->encoder_frame.pixel_format : NULL,
+ This->encoder_frame.width, This->encoder_frame.height,
+ This->encoder_frame.dpix, This->encoder_frame.dpiy);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = write_source(iface, pIBitmapSource, prc,
+ &This->encoder_frame.pixel_format, This->encoder_frame.bpp,
+ !This->encoder_frame.num_colors && This->encoder_frame.indexed,
+ This->encoder_frame.width, This->encoder_frame.height);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_Commit(IWICBitmapFrameEncode *iface)
+{
+ CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("(%p)\n", iface);
+
+ EnterCriticalSection(&This->parent->lock);
+
+ if (!This->frame_created || This->lines_written != This->encoder_frame.height ||
+ This->committed)
+ {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ }
+ else
+ {
+ hr = encoder_commit_frame(This->parent->encoder);
+ if (SUCCEEDED(hr))
+ {
+ This->committed = TRUE;
+ This->parent->uncommitted_frame = FALSE;
+ }
+ }
+
+ LeaveCriticalSection(&This->parent->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoderFrame_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
+ IWICMetadataQueryWriter **ppIMetadataQueryWriter)
+{
+ FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
+ return E_NOTIMPL;
+}
+
+static const IWICBitmapFrameEncodeVtbl CommonEncoderFrame_Vtbl = {
+ CommonEncoderFrame_QueryInterface,
+ CommonEncoderFrame_AddRef,
+ CommonEncoderFrame_Release,
+ CommonEncoderFrame_Initialize,
+ CommonEncoderFrame_SetSize,
+ CommonEncoderFrame_SetResolution,
+ CommonEncoderFrame_SetPixelFormat,
+ CommonEncoderFrame_SetColorContexts,
+ CommonEncoderFrame_SetPalette,
+ CommonEncoderFrame_SetThumbnail,
+ CommonEncoderFrame_WritePixels,
+ CommonEncoderFrame_WriteSource,
+ CommonEncoderFrame_Commit,
+ CommonEncoderFrame_GetMetadataQueryWriter
+};
+
+static HRESULT WINAPI CommonEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
+ void **ppv)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_IWICBitmapEncoder, iid))
+ {
+ *ppv = &This->IWICBitmapEncoder_iface;
+ }
+ else
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI CommonEncoder_AddRef(IWICBitmapEncoder *iface)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI CommonEncoder_Release(IWICBitmapEncoder *iface)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ if (ref == 0)
+ {
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
+ if (This->stream)
+ IStream_Release(This->stream);
+ encoder_destroy(This->encoder);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI CommonEncoder_Initialize(IWICBitmapEncoder *iface,
+ IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
+
+ if (!pIStream)
+ return E_POINTER;
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->stream)
+ {
+ LeaveCriticalSection(&This->lock);
+ return WINCODEC_ERR_WRONGSTATE;
+ }
+
+ hr = encoder_initialize(This->encoder, pIStream);
+
+ if (SUCCEEDED(hr))
+ {
+ This->stream = pIStream;
+ IStream_AddRef(This->stream);
+ }
+
+ LeaveCriticalSection(&This->lock);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI CommonEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ TRACE("(%p,%p)\n", iface, format);
+
+ if (!format)
+ return E_INVALIDARG;
+
+ memcpy(format, &This->encoder_info.container_format, sizeof(*format));
+ return S_OK;
+}
+
+static HRESULT WINAPI CommonEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ IWICComponentInfo *comp_info;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", iface, info);
+
+ if (!info) return E_INVALIDARG;
+
+ hr = CreateComponentInfo(&This->encoder_info.clsid, &comp_info);
+ if (hr == S_OK)
+ {
+ hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
+ IWICComponentInfo_Release(comp_info);
+ }
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoder_SetColorContexts(IWICBitmapEncoder *iface,
+ UINT cCount, IWICColorContext **ppIColorContext)
+{
+ FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CommonEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("(%p,%p)\n", iface, palette);
+
+ EnterCriticalSection(&This->lock);
+
+ hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
+{
+ TRACE("(%p,%p)\n", iface, pIThumbnail);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI CommonEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
+{
+ TRACE("(%p,%p)\n", iface, pIPreview);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI CommonEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
+ IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ CommonEncoderFrame *result;
+ HRESULT hr;
+ DWORD opts_length;
+ PROPBAG2 opts[6];
+
+ TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->frame_count != 0 && !(This->encoder_info.flags & ENCODER_FLAGS_MULTI_FRAME))
+ {
+ LeaveCriticalSection(&This->lock);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+ }
+
+ if (!This->stream || This->committed || This->uncommitted_frame)
+ {
+ LeaveCriticalSection(&This->lock);
+ return WINCODEC_ERR_NOTINITIALIZED;
+ }
+
+ result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*result));
+ if (!result)
+ {
+ LeaveCriticalSection(&This->lock);
+ return E_OUTOFMEMORY;
+ }
+
+ result->IWICBitmapFrameEncode_iface.lpVtbl = &CommonEncoderFrame_Vtbl;
+ result->ref = 1;
+ result->parent = This;
+
+ if (ppIEncoderOptions)
+ {
+ for (opts_length = 0; This->encoder_info.encoder_options[opts_length] < ENCODER_OPTION_END; opts_length++)
+ {
+ opts[opts_length] = encoder_option_properties[This->encoder_info.encoder_options[opts_length]];
+ }
+
+ hr = CreatePropertyBag2(opts, opts_length, ppIEncoderOptions);
+ if (FAILED(hr))
+ {
+ LeaveCriticalSection(&This->lock);
+ HeapFree(GetProcessHeap(), 0, result);
+ return hr;
+ }
+ }
+
+ IWICBitmapEncoder_AddRef(iface);
+ This->frame_count++;
+ This->uncommitted_frame = TRUE;
+
+ LeaveCriticalSection(&This->lock);
+
+ *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI CommonEncoder_Commit(IWICBitmapEncoder *iface)
+{
+ CommonEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("(%p)\n", iface);
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->committed || This->uncommitted_frame)
+ hr = WINCODEC_ERR_WRONGSTATE;
+ else
+ {
+ hr = encoder_commit_file(This->encoder);
+ if (SUCCEEDED(hr))
+ This->committed = TRUE;
+ }
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI CommonEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
+ IWICMetadataQueryWriter **ppIMetadataQueryWriter)
+{
+ FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
+ return E_NOTIMPL;
+}
+
+static const IWICBitmapEncoderVtbl CommonEncoder_Vtbl = {
+ CommonEncoder_QueryInterface,
+ CommonEncoder_AddRef,
+ CommonEncoder_Release,
+ CommonEncoder_Initialize,
+ CommonEncoder_GetContainerFormat,
+ CommonEncoder_GetEncoderInfo,
+ CommonEncoder_SetColorContexts,
+ CommonEncoder_SetPalette,
+ CommonEncoder_SetThumbnail,
+ CommonEncoder_SetPreview,
+ CommonEncoder_CreateNewFrame,
+ CommonEncoder_Commit,
+ CommonEncoder_GetMetadataQueryWriter
+};
+
+HRESULT CommonEncoder_CreateInstance(struct encoder *encoder,
+ const struct encoder_info *encoder_info, REFIID iid, void** ppv)
+{
+ CommonEncoder *This;
+ HRESULT ret;
+
+ TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
+
+ *ppv = NULL;
+
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(CommonEncoder));
+ if (!This)
+ {
+ encoder_destroy(encoder);
+ return E_OUTOFMEMORY;
+ }
+
+ This->IWICBitmapEncoder_iface.lpVtbl = &CommonEncoder_Vtbl;
+ This->ref = 1;
+ This->stream = NULL;
+ This->encoder = encoder;
+ This->encoder_info = *encoder_info;
+ This->frame_count = 0;
+ This->uncommitted_frame = FALSE;
+ This->committed = FALSE;
+ InitializeCriticalSection(&This->lock);
+ This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CommonEncoder.lock");
+
+ ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
+ IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
+
+ return ret;
+}
diff --git a/dlls/windowscodecs/libpng.c b/dlls/windowscodecs/libpng.c
index fd1ee679ec3..ee02d493f57 100644
--- a/dlls/windowscodecs/libpng.c
+++ b/dlls/windowscodecs/libpng.c
@@ -50,7 +50,9 @@ static void *libpng_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(png_create_info_struct);
MAKE_FUNCPTR(png_create_read_struct);
+MAKE_FUNCPTR(png_create_write_struct);
MAKE_FUNCPTR(png_destroy_read_struct);
+MAKE_FUNCPTR(png_destroy_write_struct);
MAKE_FUNCPTR(png_error);
MAKE_FUNCPTR(png_get_bit_depth);
MAKE_FUNCPTR(png_get_color_type);
@@ -67,10 +69,21 @@ MAKE_FUNCPTR(png_read_info);
MAKE_FUNCPTR(png_set_bgr);
MAKE_FUNCPTR(png_set_crc_action);
MAKE_FUNCPTR(png_set_error_fn);
+MAKE_FUNCPTR(png_set_filler);
+MAKE_FUNCPTR(png_set_filter);
MAKE_FUNCPTR(png_set_gray_to_rgb);
+MAKE_FUNCPTR(png_set_IHDR);
+MAKE_FUNCPTR(png_set_interlace_handling);
+MAKE_FUNCPTR(png_set_pHYs);
+MAKE_FUNCPTR(png_set_PLTE);
MAKE_FUNCPTR(png_set_read_fn);
MAKE_FUNCPTR(png_set_swap);
+MAKE_FUNCPTR(png_set_tRNS);
MAKE_FUNCPTR(png_set_tRNS_to_alpha);
+MAKE_FUNCPTR(png_set_write_fn);
+MAKE_FUNCPTR(png_write_end);
+MAKE_FUNCPTR(png_write_info);
+MAKE_FUNCPTR(png_write_rows);
#undef MAKE_FUNCPTR
static CRITICAL_SECTION init_png_cs;
@@ -99,7 +112,9 @@ static void *load_libpng(void)
}
LOAD_FUNCPTR(png_create_info_struct);
LOAD_FUNCPTR(png_create_read_struct);
+ LOAD_FUNCPTR(png_create_write_struct);
LOAD_FUNCPTR(png_destroy_read_struct);
+ LOAD_FUNCPTR(png_destroy_write_struct);
LOAD_FUNCPTR(png_error);
LOAD_FUNCPTR(png_get_bit_depth);
LOAD_FUNCPTR(png_get_color_type);
@@ -116,10 +131,21 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_set_bgr);
LOAD_FUNCPTR(png_set_crc_action);
LOAD_FUNCPTR(png_set_error_fn);
+ LOAD_FUNCPTR(png_set_filler);
+ LOAD_FUNCPTR(png_set_filter);
LOAD_FUNCPTR(png_set_gray_to_rgb);
+ LOAD_FUNCPTR(png_set_IHDR);
+ LOAD_FUNCPTR(png_set_interlace_handling);
+ LOAD_FUNCPTR(png_set_pHYs);
+ LOAD_FUNCPTR(png_set_PLTE);
LOAD_FUNCPTR(png_set_read_fn);
LOAD_FUNCPTR(png_set_swap);
+ LOAD_FUNCPTR(png_set_tRNS);
LOAD_FUNCPTR(png_set_tRNS_to_alpha);
+ LOAD_FUNCPTR(png_set_write_fn);
+ LOAD_FUNCPTR(png_write_end);
+ LOAD_FUNCPTR(png_write_info);
+ LOAD_FUNCPTR(png_write_rows);
#undef LOAD_FUNCPTR
}
@@ -611,9 +637,45 @@ HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **res
return S_OK;
}
+struct png_pixelformat {
+ const WICPixelFormatGUID *guid;
+ UINT bpp;
+ int bit_depth;
+ int color_type;
+ BOOL remove_filler;
+ BOOL swap_rgb;
+};
+
+static const struct png_pixelformat formats[] = {
+ {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
+ {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1},
+ {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0},
+ {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0},
+ {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0},
+ {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0},
+ {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0},
+ {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1},
+ {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
+ {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
+ {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
+ {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
+ {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
+ {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
+ {NULL},
+};
+
struct png_encoder
{
struct encoder encoder;
+ IStream *stream;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ struct encoder_frame encoder_frame;
+ const struct png_pixelformat *format;
+ BYTE *data;
+ UINT stride;
+ UINT passes;
+ UINT lines_written;
};
static inline struct png_encoder *impl_from_encoder(struct encoder* iface)
@@ -621,13 +683,294 @@ static inline struct png_encoder *impl_from_encoder(struct encoder* iface)
return CONTAINING_RECORD(iface, struct png_encoder, encoder);
}
+static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ struct png_encoder *This = ppng_get_io_ptr(png_ptr);
+ HRESULT hr;
+ ULONG byteswritten;
+
+ hr = stream_write(This->stream, data, length, &byteswritten);
+ if (FAILED(hr) || byteswritten != length)
+ {
+ ppng_error(png_ptr, "failed writing data");
+ }
+}
+
+static void user_flush(png_structp png_ptr)
+{
+}
+
+static HRESULT CDECL png_encoder_initialize(struct encoder *encoder, IStream *stream)
+{
+ struct png_encoder *This = impl_from_encoder(encoder);
+ jmp_buf jmpbuf;
+
+ TRACE("(%p,%p)\n", encoder, stream);
+
+ /* initialize libpng */
+ This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!This->png_ptr)
+ return E_FAIL;
+
+ This->info_ptr = ppng_create_info_struct(This->png_ptr);
+ if (!This->info_ptr)
+ {
+ ppng_destroy_write_struct(&This->png_ptr, NULL);
+ This->png_ptr = NULL;
+ return E_FAIL;
+ }
+
+ This->stream = stream;
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ {
+ ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
+ This->png_ptr = NULL;
+ This->stream = NULL;
+ return E_FAIL;
+ }
+ ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
+
+ /* set up custom i/o handling */
+ ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
+
+ return S_OK;
+}
+
+HRESULT CDECL png_encoder_get_supported_format(struct encoder* iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
+{
+ int i;
+
+ for (i=0; formats[i].guid; i++)
+ {
+ if (memcmp(formats[i].guid, pixel_format, sizeof(GUID)) == 0)
+ break;
+ }
+
+ if (!formats[i].guid)
+ i = 0;
+
+ *pixel_format = *formats[i].guid;
+ *bpp = formats[i].bpp;
+ *indexed = (formats[i].color_type == PNG_COLOR_TYPE_PALETTE);
+
+ return S_OK;
+}
+
+static HRESULT CDECL png_encoder_create_frame(struct encoder *encoder, const struct encoder_frame *encoder_frame)
+{
+ struct png_encoder *This = impl_from_encoder(encoder);
+ jmp_buf jmpbuf;
+ int i;
+
+ for (i=0; formats[i].guid; i++)
+ {
+ if (memcmp(formats[i].guid, &encoder_frame->pixel_format, sizeof(GUID)) == 0)
+ {
+ This->format = &formats[i];
+ break;
+ }
+ }
+
+ if (!formats[i].guid)
+ {
+ ERR("invalid pixel format %s\n", wine_dbgstr_guid(&encoder_frame->pixel_format));
+ return E_FAIL;
+ }
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ return E_FAIL;
+
+ ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
+
+ This->encoder_frame = *encoder_frame;
+ This->lines_written = 0;
+
+ if (encoder_frame->interlace)
+ {
+ /* libpng requires us to write all data multiple times in this case. */
+ This->stride = (This->format->bpp * encoder_frame->width + 7)/8;
+ This->data = malloc(encoder_frame->height * This->stride);
+ if (!This->data)
+ return E_OUTOFMEMORY;
+ }
+
+ /* Tell PNG we need to byte swap if writing a >8-bpp image */
+ if (This->format->bit_depth > 8)
+ ppng_set_swap(This->png_ptr);
+
+ ppng_set_IHDR(This->png_ptr, This->info_ptr, encoder_frame->width, encoder_frame->height,
+ This->format->bit_depth, This->format->color_type,
+ encoder_frame->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ if (encoder_frame->dpix != 0.0 && encoder_frame->dpiy != 0.0)
+ {
+ ppng_set_pHYs(This->png_ptr, This->info_ptr, (encoder_frame->dpix+0.0127) / 0.0254,
+ (encoder_frame->dpiy+0.0127) / 0.0254, PNG_RESOLUTION_METER);
+ }
+
+ if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && encoder_frame->num_colors)
+ {
+ png_color png_palette[256];
+ png_byte trans[256];
+ UINT i, num_trans = 0, colors;
+
+ /* Newer libpng versions don't accept larger palettes than the declared
+ * bit depth, so we need to generate the palette of the correct length.
+ */
+ colors = min(encoder_frame->num_colors, 1 << This->format->bit_depth);
+
+ for (i = 0; i < colors; i++)
+ {
+ png_palette[i].red = (encoder_frame->palette[i] >> 16) & 0xff;
+ png_palette[i].green = (encoder_frame->palette[i] >> 8) & 0xff;
+ png_palette[i].blue = encoder_frame->palette[i] & 0xff;
+ trans[i] = (encoder_frame->palette[i] >> 24) & 0xff;
+ if (trans[i] != 0xff)
+ num_trans = i+1;
+ }
+
+ ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors);
+
+ if (num_trans)
+ ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL);
+ }
+
+ ppng_write_info(This->png_ptr, This->info_ptr);
+
+ if (This->format->remove_filler)
+ ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);
+
+ if (This->format->swap_rgb)
+ ppng_set_bgr(This->png_ptr);
+
+ if (encoder_frame->interlace)
+ This->passes = ppng_set_interlace_handling(This->png_ptr);
+
+ if (encoder_frame->filter != WICPngFilterUnspecified)
+ {
+ static const int png_filter_map[] =
+ {
+ /* WICPngFilterUnspecified */ PNG_NO_FILTERS,
+ /* WICPngFilterNone */ PNG_FILTER_NONE,
+ /* WICPngFilterSub */ PNG_FILTER_SUB,
+ /* WICPngFilterUp */ PNG_FILTER_UP,
+ /* WICPngFilterAverage */ PNG_FILTER_AVG,
+ /* WICPngFilterPaeth */ PNG_FILTER_PAETH,
+ /* WICPngFilterAdaptive */ PNG_ALL_FILTERS,
+ };
+
+ ppng_set_filter(This->png_ptr, 0, png_filter_map[encoder_frame->filter]);
+ }
+
+ return S_OK;
+}
+
+HRESULT CDECL png_encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride)
+{
+ struct png_encoder *This = impl_from_encoder(encoder);
+ jmp_buf jmpbuf;
+ png_byte **row_pointers=NULL;
+ UINT i;
+
+ if (This->encoder_frame.interlace)
+ {
+ /* Just store the data so we can write it in multiple passes in Commit. */
+ for (i=0; i<line_count; i++)
+ memcpy(This->data + This->stride * (This->lines_written + i),
+ data + stride * i,
+ This->stride);
+
+ This->lines_written += line_count;
+
+ return S_OK;
+ }
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ {
+ free(row_pointers);
+ return E_FAIL;
+ }
+
+ ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
+
+ row_pointers = malloc(line_count * sizeof(png_byte*));
+ if (!row_pointers)
+ return E_OUTOFMEMORY;
+
+ for (i=0; i<line_count; i++)
+ row_pointers[i] = data + stride * i;
+
+ ppng_write_rows(This->png_ptr, row_pointers, line_count);
+ This->lines_written += line_count;
+
+ free(row_pointers);
+
+ return S_OK;
+}
+
+static HRESULT CDECL png_encoder_commit_frame(struct encoder *encoder)
+{
+ struct png_encoder *This = impl_from_encoder(encoder);
+ jmp_buf jmpbuf;
+ png_byte **row_pointers=NULL;
+
+ /* set up setjmp/longjmp error handling */
+ if (setjmp(jmpbuf))
+ {
+ free(row_pointers);
+ return E_FAIL;
+ }
+
+ ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
+
+ if (This->encoder_frame.interlace)
+ {
+ int i;
+
+ row_pointers = malloc(This->encoder_frame.height * sizeof(png_byte*));
+ if (!row_pointers)
+ return E_OUTOFMEMORY;
+
+ for (i=0; i<This->encoder_frame.height; i++)
+ row_pointers[i] = This->data + This->stride * i;
+
+ for (i=0; i<This->passes; i++)
+ ppng_write_rows(This->png_ptr, row_pointers, This->encoder_frame.height);
+ }
+
+ ppng_write_end(This->png_ptr, This->info_ptr);
+
+ free(row_pointers);
+
+ return S_OK;
+}
+
+static HRESULT CDECL png_encoder_commit_file(struct encoder *encoder)
+{
+ return S_OK;
+}
+
static void CDECL png_encoder_destroy(struct encoder *encoder)
{
struct png_encoder *This = impl_from_encoder(encoder);
+ if (This->png_ptr)
+ ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
+ free(This->data);
RtlFreeHeap(GetProcessHeap(), 0, This);
}
static const struct encoder_funcs png_encoder_vtable = {
+ png_encoder_initialize,
+ png_encoder_get_supported_format,
+ png_encoder_create_frame,
+ png_encoder_write_lines,
+ png_encoder_commit_frame,
+ png_encoder_commit_file,
png_encoder_destroy
};
@@ -649,6 +992,9 @@ HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **res
}
This->encoder.vtable = &png_encoder_vtable;
+ This->png_ptr = NULL;
+ This->info_ptr = NULL;
+ This->data = NULL;
*result = &This->encoder;
info->container_format = GUID_ContainerFormatPng;
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c
index 7976b96a393..3817d23eb4c 100644
--- a/dlls/windowscodecs/main.c
+++ b/dlls/windowscodecs/main.c
@@ -223,6 +223,11 @@ HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG
return hr;
}
+HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)
+{
+ return IStream_Write(stream, buffer, write, bytes_written);
+}
+
HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp)
{
HRESULT hr;
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index f0ac83dae1c..b5ea9b48861 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -22,10 +22,6 @@
#include <stdarg.h>
-#ifdef SONAME_LIBPNG
-#include <png.h>
-#endif
-
#define NONAMELESSUNION
#define COBJMACROS
@@ -37,8 +33,6 @@
#include "wine/debug.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];
@@ -255,1034 +249,30 @@ HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv)
return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv);
}
-#ifdef SONAME_LIBPNG
-
-static void *libpng_handle;
-#define MAKE_FUNCPTR(f) static typeof(f) * p##f
-MAKE_FUNCPTR(png_create_read_struct);
-MAKE_FUNCPTR(png_create_info_struct);
-MAKE_FUNCPTR(png_create_write_struct);
-MAKE_FUNCPTR(png_destroy_read_struct);
-MAKE_FUNCPTR(png_destroy_write_struct);
-MAKE_FUNCPTR(png_error);
-MAKE_FUNCPTR(png_get_bit_depth);
-MAKE_FUNCPTR(png_get_color_type);
-MAKE_FUNCPTR(png_get_error_ptr);
-MAKE_FUNCPTR(png_get_iCCP);
-MAKE_FUNCPTR(png_get_image_height);
-MAKE_FUNCPTR(png_get_image_width);
-MAKE_FUNCPTR(png_get_io_ptr);
-MAKE_FUNCPTR(png_get_pHYs);
-MAKE_FUNCPTR(png_get_PLTE);
-MAKE_FUNCPTR(png_get_tRNS);
-MAKE_FUNCPTR(png_set_bgr);
-MAKE_FUNCPTR(png_set_crc_action);
-MAKE_FUNCPTR(png_set_error_fn);
-MAKE_FUNCPTR(png_set_filler);
-MAKE_FUNCPTR(png_set_filter);
-MAKE_FUNCPTR(png_set_gray_to_rgb);
-MAKE_FUNCPTR(png_set_interlace_handling);
-MAKE_FUNCPTR(png_set_IHDR);
-MAKE_FUNCPTR(png_set_pHYs);
-MAKE_FUNCPTR(png_set_PLTE);
-MAKE_FUNCPTR(png_set_read_fn);
-MAKE_FUNCPTR(png_set_strip_16);
-MAKE_FUNCPTR(png_set_tRNS);
-MAKE_FUNCPTR(png_set_tRNS_to_alpha);
-MAKE_FUNCPTR(png_set_write_fn);
-MAKE_FUNCPTR(png_set_swap);
-MAKE_FUNCPTR(png_read_end);
-MAKE_FUNCPTR(png_read_image);
-MAKE_FUNCPTR(png_read_info);
-MAKE_FUNCPTR(png_write_end);
-MAKE_FUNCPTR(png_write_info);
-MAKE_FUNCPTR(png_write_rows);
-#undef MAKE_FUNCPTR
-
-static CRITICAL_SECTION init_png_cs;
-static CRITICAL_SECTION_DEBUG init_png_cs_debug =
-{
- 0, 0, &init_png_cs,
- { &init_png_cs_debug.ProcessLocksList,
- &init_png_cs_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": init_png_cs") }
-};
-static CRITICAL_SECTION init_png_cs = { &init_png_cs_debug, -1, 0, 0, 0, 0 };
-
-static void *load_libpng(void)
-{
- void *result;
-
- EnterCriticalSection(&init_png_cs);
-
- if(!libpng_handle && (libpng_handle = dlopen(SONAME_LIBPNG, RTLD_NOW)) != NULL) {
-
-#define LOAD_FUNCPTR(f) \
- if((p##f = dlsym(libpng_handle, #f)) == NULL) { \
- libpng_handle = NULL; \
- LeaveCriticalSection(&init_png_cs); \
- return NULL; \
- }
- LOAD_FUNCPTR(png_create_read_struct);
- LOAD_FUNCPTR(png_create_info_struct);
- LOAD_FUNCPTR(png_create_write_struct);
- LOAD_FUNCPTR(png_destroy_read_struct);
- LOAD_FUNCPTR(png_destroy_write_struct);
- LOAD_FUNCPTR(png_error);
- LOAD_FUNCPTR(png_get_bit_depth);
- LOAD_FUNCPTR(png_get_color_type);
- LOAD_FUNCPTR(png_get_error_ptr);
- LOAD_FUNCPTR(png_get_iCCP);
- LOAD_FUNCPTR(png_get_image_height);
- LOAD_FUNCPTR(png_get_image_width);
- LOAD_FUNCPTR(png_get_io_ptr);
- LOAD_FUNCPTR(png_get_pHYs);
- LOAD_FUNCPTR(png_get_PLTE);
- LOAD_FUNCPTR(png_get_tRNS);
- LOAD_FUNCPTR(png_set_bgr);
- LOAD_FUNCPTR(png_set_crc_action);
- LOAD_FUNCPTR(png_set_error_fn);
- LOAD_FUNCPTR(png_set_filler);
- LOAD_FUNCPTR(png_set_filter);
- LOAD_FUNCPTR(png_set_gray_to_rgb);
- LOAD_FUNCPTR(png_set_interlace_handling);
- LOAD_FUNCPTR(png_set_IHDR);
- LOAD_FUNCPTR(png_set_pHYs);
- LOAD_FUNCPTR(png_set_PLTE);
- LOAD_FUNCPTR(png_set_read_fn);
- LOAD_FUNCPTR(png_set_strip_16);
- LOAD_FUNCPTR(png_set_tRNS);
- LOAD_FUNCPTR(png_set_tRNS_to_alpha);
- LOAD_FUNCPTR(png_set_write_fn);
- LOAD_FUNCPTR(png_set_swap);
- LOAD_FUNCPTR(png_read_end);
- LOAD_FUNCPTR(png_read_image);
- LOAD_FUNCPTR(png_read_info);
- LOAD_FUNCPTR(png_write_end);
- LOAD_FUNCPTR(png_write_info);
- LOAD_FUNCPTR(png_write_rows);
-
-#undef LOAD_FUNCPTR
- }
-
- result = libpng_handle;
-
- LeaveCriticalSection(&init_png_cs);
-
- return result;
-}
-
-static void user_error_fn(png_structp png_ptr, png_const_charp error_message)
-{
- jmp_buf *pjmpbuf;
-
- /* This uses setjmp/longjmp just like the default. We can't use the
- * default because there's no way to access the jmp buffer in the png_struct
- * that works in 1.2 and 1.4 and allows us to dynamically load libpng. */
- WARN("PNG error: %s\n", debugstr_a(error_message));
- pjmpbuf = ppng_get_error_ptr(png_ptr);
- longjmp(*pjmpbuf, 1);
-}
-
-static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message)
-{
- WARN("PNG warning: %s\n", debugstr_a(warning_message));
-}
-
-static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
-static const WCHAR wszPngFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
-
-static const PROPBAG2 encoder_option_properties[ENCODER_OPTION_END] = {
- { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption },
- { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption }
-};
-
-struct png_pixelformat {
- const WICPixelFormatGUID *guid;
- UINT bpp;
- int bit_depth;
- int color_type;
- BOOL remove_filler;
- BOOL swap_rgb;
-};
-
-static const struct png_pixelformat formats[] = {
- {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
- {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1},
- {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0},
- {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0},
- {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0},
- {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0},
- {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0},
- {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1},
- {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
- {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
- {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
- {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
- {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
- {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
- {NULL},
-};
-
-typedef struct PngEncoder {
- IWICBitmapEncoder IWICBitmapEncoder_iface;
- IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
- LONG ref;
- IStream *stream;
- png_structp png_ptr;
- png_infop info_ptr;
- struct encoder *encoder;
- struct encoder_info encoder_info;
- UINT frame_count;
- BOOL frame_initialized;
- const struct png_pixelformat *format;
- BOOL info_written;
- UINT width, height;
- double xres, yres;
- UINT lines_written;
- BOOL frame_committed;
- BOOL committed;
- CRITICAL_SECTION lock;
- BOOL interlace;
- WICPngFilterOption filter;
- BYTE *data;
- UINT stride;
- UINT passes;
- WICColor palette[256];
- UINT colors;
-} PngEncoder;
-
-static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
-{
- return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapEncoder_iface);
-}
-
-static inline PngEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
-{
- return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapFrameEncode_iface);
-}
-
-static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
- void **ppv)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
-
- if (!ppv) return E_INVALIDARG;
-
- if (IsEqualIID(&IID_IUnknown, iid) ||
- IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
- {
- *ppv = &This->IWICBitmapFrameEncode_iface;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
-static ULONG WINAPI PngFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface);
-}
-
-static ULONG WINAPI PngFrameEncode_Release(IWICBitmapFrameEncode *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
-}
-
-static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
- IPropertyBag2 *pIEncoderOptions)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- WICPngFilterOption filter;
- BOOL interlace;
- PROPBAG2 opts[2]= {{0}};
- VARIANT opt_values[2];
- HRESULT opt_hres[2];
- HRESULT hr;
-
- TRACE("(%p,%p)\n", iface, pIEncoderOptions);
-
- opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption;
- opts[0].vt = VT_BOOL;
- opts[1].pstrName = (LPOLESTR)wszPngFilterOption;
- opts[1].vt = VT_UI1;
-
- if (pIEncoderOptions)
- {
- hr = IPropertyBag2_Read(pIEncoderOptions, ARRAY_SIZE(opts), opts, NULL, opt_values, opt_hres);
-
- if (FAILED(hr))
- return hr;
-
- if (V_VT(&opt_values[0]) == VT_EMPTY)
- interlace = FALSE;
- else
- interlace = (V_BOOL(&opt_values[0]) != 0);
-
- filter = V_UI1(&opt_values[1]);
- if (filter > WICPngFilterAdaptive)
- {
- WARN("Unrecognized filter option value %u.\n", filter);
- filter = WICPngFilterUnspecified;
- }
- }
- else
- {
- interlace = FALSE;
- filter = WICPngFilterUnspecified;
- }
-
- EnterCriticalSection(&This->lock);
-
- if (This->frame_initialized)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- This->interlace = interlace;
- This->filter = filter;
-
- This->frame_initialized = TRUE;
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
- UINT uiWidth, UINT uiHeight)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
-
- EnterCriticalSection(&This->lock);
-
- if (!This->frame_initialized || This->info_written)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- This->width = uiWidth;
- This->height = uiHeight;
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
- double dpiX, double dpiY)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
-
- EnterCriticalSection(&This->lock);
-
- if (!This->frame_initialized || This->info_written)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- This->xres = dpiX;
- This->yres = dpiY;
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
- WICPixelFormatGUID *pPixelFormat)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- int i;
- TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
-
- EnterCriticalSection(&This->lock);
-
- if (!This->frame_initialized || This->info_written)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- for (i=0; formats[i].guid; i++)
- {
- if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0)
- break;
- }
-
- if (!formats[i].guid) i = 0;
-
- This->format = &formats[i];
- memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
- UINT cCount, IWICColorContext **ppIColorContext)
-{
- FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
- IWICPalette *palette)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- HRESULT hr;
-
- TRACE("(%p,%p)\n", iface, palette);
-
- if (!palette) return E_INVALIDARG;
-
- EnterCriticalSection(&This->lock);
-
- if (This->frame_initialized)
- hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
- else
- hr = WINCODEC_ERR_NOTINITIALIZED;
-
- LeaveCriticalSection(&This->lock);
- return hr;
-}
-
-static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
- IWICBitmapSource *pIThumbnail)
-{
- FIXME("(%p,%p): stub\n", iface, pIThumbnail);
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
- UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- png_byte **row_pointers=NULL;
- UINT i;
- jmp_buf jmpbuf;
- TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
-
- EnterCriticalSection(&This->lock);
-
- if (!This->frame_initialized || !This->width || !This->height || !This->format)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- if (lineCount == 0 || lineCount + This->lines_written > This->height)
- {
- LeaveCriticalSection(&This->lock);
- return E_INVALIDARG;
- }
-
- /* set up setjmp/longjmp error handling */
- if (setjmp(jmpbuf))
- {
- LeaveCriticalSection(&This->lock);
- HeapFree(GetProcessHeap(), 0, row_pointers);
- return E_FAIL;
- }
- ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
-
- if (!This->info_written)
- {
- if (This->interlace)
- {
- /* libpng requires us to write all data multiple times in this case. */
- This->stride = (This->format->bpp * This->width + 7)/8;
- This->data = HeapAlloc(GetProcessHeap(), 0, This->height * This->stride);
- if (!This->data)
- {
- LeaveCriticalSection(&This->lock);
- return E_OUTOFMEMORY;
- }
- }
-
- /* Tell PNG we need to byte swap if writing a >8-bpp image */
- if (This->format->bit_depth > 8)
- ppng_set_swap(This->png_ptr);
-
- ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height,
- This->format->bit_depth, This->format->color_type,
- This->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- if (This->xres != 0.0 && This->yres != 0.0)
- {
- ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254,
- (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
- }
-
- if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && This->colors)
- {
- png_color png_palette[256];
- png_byte trans[256];
- UINT i, num_trans = 0, colors;
-
- /* Newer libpng versions don't accept larger palettes than the declared
- * bit depth, so we need to generate the palette of the correct length.
- */
- colors = min(This->colors, 1 << This->format->bit_depth);
-
- for (i = 0; i < colors; i++)
- {
- png_palette[i].red = (This->palette[i] >> 16) & 0xff;
- png_palette[i].green = (This->palette[i] >> 8) & 0xff;
- png_palette[i].blue = This->palette[i] & 0xff;
- trans[i] = (This->palette[i] >> 24) & 0xff;
- if (trans[i] != 0xff)
- num_trans = i+1;
- }
-
- ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors);
-
- if (num_trans)
- ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL);
- }
-
- ppng_write_info(This->png_ptr, This->info_ptr);
-
- if (This->format->remove_filler)
- ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);
-
- if (This->format->swap_rgb)
- ppng_set_bgr(This->png_ptr);
-
- if (This->interlace)
- This->passes = ppng_set_interlace_handling(This->png_ptr);
-
- if (This->filter != WICPngFilterUnspecified)
- {
- static const int png_filter_map[] =
- {
- /* WICPngFilterUnspecified */ PNG_NO_FILTERS,
- /* WICPngFilterNone */ PNG_FILTER_NONE,
- /* WICPngFilterSub */ PNG_FILTER_SUB,
- /* WICPngFilterUp */ PNG_FILTER_UP,
- /* WICPngFilterAverage */ PNG_FILTER_AVG,
- /* WICPngFilterPaeth */ PNG_FILTER_PAETH,
- /* WICPngFilterAdaptive */ PNG_ALL_FILTERS,
- };
-
- ppng_set_filter(This->png_ptr, 0, png_filter_map[This->filter]);
- }
-
- This->info_written = TRUE;
- }
-
- if (This->interlace)
- {
- /* Just store the data so we can write it in multiple passes in Commit. */
- for (i=0; i<lineCount; i++)
- memcpy(This->data + This->stride * (This->lines_written + i),
- pbPixels + cbStride * i,
- This->stride);
-
- This->lines_written += lineCount;
-
- LeaveCriticalSection(&This->lock);
- return S_OK;
- }
-
- row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*));
- if (!row_pointers)
- {
- LeaveCriticalSection(&This->lock);
- return E_OUTOFMEMORY;
- }
-
- for (i=0; i<lineCount; i++)
- row_pointers[i] = pbPixels + cbStride * i;
-
- ppng_write_rows(This->png_ptr, row_pointers, lineCount);
- This->lines_written += lineCount;
-
- LeaveCriticalSection(&This->lock);
-
- HeapFree(GetProcessHeap(), 0, row_pointers);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
- IWICBitmapSource *pIBitmapSource, WICRect *prc)
+HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv)
{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
- TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc));
-
- if (!This->frame_initialized)
- return WINCODEC_ERR_WRONGSTATE;
+ struct decoder *decoder;
+ struct decoder_info decoder_info;
- hr = configure_write_source(iface, pIBitmapSource, prc,
- This->format ? This->format->guid : NULL, This->width, This->height,
- This->xres, This->yres);
+ hr = get_unix_decoder(&CLSID_WICPngDecoder, &decoder_info, &decoder);
if (SUCCEEDED(hr))
- {
- hr = write_source(iface, pIBitmapSource, prc,
- This->format->guid, This->format->bpp,
- !This->colors && This->format->color_type == PNG_COLOR_TYPE_PALETTE,
- This->width, This->height);
- }
-
- return hr;
-}
-
-static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
- png_byte **row_pointers=NULL;
- jmp_buf jmpbuf;
- TRACE("(%p)\n", iface);
-
- EnterCriticalSection(&This->lock);
-
- if (!This->info_written || This->lines_written != This->height || This->frame_committed)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- /* set up setjmp/longjmp error handling */
- if (setjmp(jmpbuf))
- {
- LeaveCriticalSection(&This->lock);
- HeapFree(GetProcessHeap(), 0, row_pointers);
- return E_FAIL;
- }
- ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
-
- if (This->interlace)
- {
- int i;
-
- row_pointers = HeapAlloc(GetProcessHeap(), 0, This->height * sizeof(png_byte*));
- if (!row_pointers)
- {
- LeaveCriticalSection(&This->lock);
- return E_OUTOFMEMORY;
- }
-
- for (i=0; i<This->height; i++)
- row_pointers[i] = This->data + This->stride * i;
-
- for (i=0; i<This->passes; i++)
- ppng_write_rows(This->png_ptr, row_pointers, This->height);
- }
-
- ppng_write_end(This->png_ptr, This->info_ptr);
-
- This->frame_committed = TRUE;
-
- HeapFree(GetProcessHeap(), 0, row_pointers);
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
- IWICMetadataQueryWriter **ppIMetadataQueryWriter)
-{
- FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
- return E_NOTIMPL;
-}
-
-static const IWICBitmapFrameEncodeVtbl PngEncoder_FrameVtbl = {
- PngFrameEncode_QueryInterface,
- PngFrameEncode_AddRef,
- PngFrameEncode_Release,
- PngFrameEncode_Initialize,
- PngFrameEncode_SetSize,
- PngFrameEncode_SetResolution,
- PngFrameEncode_SetPixelFormat,
- PngFrameEncode_SetColorContexts,
- PngFrameEncode_SetPalette,
- PngFrameEncode_SetThumbnail,
- PngFrameEncode_WritePixels,
- PngFrameEncode_WriteSource,
- PngFrameEncode_Commit,
- PngFrameEncode_GetMetadataQueryWriter
-};
-
-static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
- void **ppv)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
-
- if (!ppv) return E_INVALIDARG;
-
- if (IsEqualIID(&IID_IUnknown, iid) ||
- IsEqualIID(&IID_IWICBitmapEncoder, iid))
- {
- *ppv = &This->IWICBitmapEncoder_iface;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
-static ULONG WINAPI PngEncoder_AddRef(IWICBitmapEncoder *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- return ref;
-}
-
-static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p) refcount=%u\n", iface, ref);
-
- if (ref == 0)
- {
- This->lock.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&This->lock);
- if (This->png_ptr)
- ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
- if (This->stream)
- IStream_Release(This->stream);
- HeapFree(GetProcessHeap(), 0, This->data);
- encoder_destroy(This->encoder);
- HeapFree(GetProcessHeap(), 0, This);
- }
-
- return ref;
-}
-
-static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- PngEncoder *This = ppng_get_io_ptr(png_ptr);
- HRESULT hr;
- ULONG byteswritten;
-
- hr = IStream_Write(This->stream, data, length, &byteswritten);
- if (FAILED(hr) || byteswritten != length)
- {
- ppng_error(png_ptr, "failed writing data");
- }
-}
-
-static void user_flush(png_structp png_ptr)
-{
-}
-
-static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
- IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- jmp_buf jmpbuf;
-
- TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
-
- EnterCriticalSection(&This->lock);
-
- if (This->png_ptr)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- /* initialize libpng */
- This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!This->png_ptr)
- {
- LeaveCriticalSection(&This->lock);
- return E_FAIL;
- }
-
- This->info_ptr = ppng_create_info_struct(This->png_ptr);
- if (!This->info_ptr)
- {
- ppng_destroy_write_struct(&This->png_ptr, NULL);
- This->png_ptr = NULL;
- LeaveCriticalSection(&This->lock);
- return E_FAIL;
- }
-
- IStream_AddRef(pIStream);
- This->stream = pIStream;
-
- /* set up setjmp/longjmp error handling */
- if (setjmp(jmpbuf))
- {
- ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr);
- This->png_ptr = NULL;
- IStream_Release(This->stream);
- This->stream = NULL;
- LeaveCriticalSection(&This->lock);
- return E_FAIL;
- }
- ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
-
- /* set up custom i/o handling */
- ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- TRACE("(%p,%p)\n", iface, format);
-
- if (!format)
- return E_INVALIDARG;
-
- memcpy(format, &This->encoder_info.container_format, sizeof(*format));
- return S_OK;
-}
-
-static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- IWICComponentInfo *comp_info;
- HRESULT hr;
-
- TRACE("%p,%p\n", iface, info);
-
- if (!info) return E_INVALIDARG;
-
- hr = CreateComponentInfo(&This->encoder_info.clsid, &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,
- UINT cCount, IWICColorContext **ppIColorContext)
-{
- FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI PngEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- HRESULT hr;
-
- TRACE("(%p,%p)\n", iface, palette);
-
- EnterCriticalSection(&This->lock);
-
- hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED;
-
- LeaveCriticalSection(&This->lock);
+ hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv);
return hr;
}
-static HRESULT WINAPI PngEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
-{
- TRACE("(%p,%p)\n", iface, pIThumbnail);
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI PngEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
-{
- TRACE("(%p,%p)\n", iface, pIPreview);
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
-}
-
-static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
- IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- HRESULT hr;
- DWORD opts_length;
- PROPBAG2 opts[6];
-
- TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
-
- EnterCriticalSection(&This->lock);
-
- if (This->frame_count != 0)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_UNSUPPORTEDOPERATION;
- }
-
- if (!This->stream)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_NOTINITIALIZED;
- }
-
- if (ppIEncoderOptions)
- {
- for (opts_length = 0; This->encoder_info.encoder_options[opts_length] < ENCODER_OPTION_END; opts_length++)
- {
- opts[opts_length] = encoder_option_properties[This->encoder_info.encoder_options[opts_length]];
- }
-
- hr = CreatePropertyBag2(opts, opts_length, ppIEncoderOptions);
- if (FAILED(hr))
- {
- LeaveCriticalSection(&This->lock);
- return hr;
- }
- }
-
- This->frame_count = 1;
-
- LeaveCriticalSection(&This->lock);
-
- IWICBitmapEncoder_AddRef(iface);
- *ppIFrameEncode = &This->IWICBitmapFrameEncode_iface;
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface)
-{
- PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
- TRACE("(%p)\n", iface);
-
- EnterCriticalSection(&This->lock);
-
- if (!This->frame_committed || This->committed)
- {
- LeaveCriticalSection(&This->lock);
- return WINCODEC_ERR_WRONGSTATE;
- }
-
- This->committed = TRUE;
-
- LeaveCriticalSection(&This->lock);
-
- return S_OK;
-}
-
-static HRESULT WINAPI PngEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
- IWICMetadataQueryWriter **ppIMetadataQueryWriter)
-{
- FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
- return E_NOTIMPL;
-}
-
-static const IWICBitmapEncoderVtbl PngEncoder_Vtbl = {
- PngEncoder_QueryInterface,
- PngEncoder_AddRef,
- PngEncoder_Release,
- PngEncoder_Initialize,
- PngEncoder_GetContainerFormat,
- PngEncoder_GetEncoderInfo,
- PngEncoder_SetColorContexts,
- PngEncoder_SetPalette,
- PngEncoder_SetThumbnail,
- PngEncoder_SetPreview,
- PngEncoder_CreateNewFrame,
- PngEncoder_Commit,
- PngEncoder_GetMetadataQueryWriter
-};
-
HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv)
-{
- PngEncoder *This;
- HRESULT ret;
-
- TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
-
- *ppv = NULL;
-
- if (!load_libpng())
- {
- ERR("Failed writing PNG because unable to find %s\n",SONAME_LIBPNG);
- return E_FAIL;
- }
-
- This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngEncoder));
- if (!This) return E_OUTOFMEMORY;
-
- ret = get_unix_encoder(&CLSID_WICPngEncoder, &This->encoder_info, &This->encoder);
-
- if (FAILED(ret))
- {
- HeapFree(GetProcessHeap(), 0, This);
- return ret;
- }
-
- This->IWICBitmapEncoder_iface.lpVtbl = &PngEncoder_Vtbl;
- This->IWICBitmapFrameEncode_iface.lpVtbl = &PngEncoder_FrameVtbl;
- This->ref = 1;
- This->png_ptr = NULL;
- This->info_ptr = NULL;
- This->stream = NULL;
- This->frame_count = 0;
- This->frame_initialized = FALSE;
- This->format = NULL;
- This->info_written = FALSE;
- This->width = 0;
- This->height = 0;
- This->xres = 0.0;
- This->yres = 0.0;
- This->lines_written = 0;
- This->frame_committed = FALSE;
- This->committed = FALSE;
- This->data = NULL;
- This->colors = 0;
- InitializeCriticalSection(&This->lock);
- This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
-
- ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
- IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
-
- return ret;
-}
-
-#else /* !SONAME_LIBPNG */
-
-HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv)
-{
- ERR("Trying to save PNG picture, but PNG support is not compiled in.\n");
- return E_FAIL;
-}
-
-#endif
-
-HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv)
{
HRESULT hr;
- struct decoder *decoder;
- struct decoder_info decoder_info;
+ struct encoder *encoder;
+ struct encoder_info encoder_info;
- hr = get_unix_decoder(&CLSID_WICPngDecoder, &decoder_info, &decoder);
+ hr = get_unix_encoder(&CLSID_WICPngEncoder, &encoder_info, &encoder);
if (SUCCEEDED(hr))
- hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv);
+ hr = CommonEncoder_CreateInstance(encoder, &encoder_info, iid, ppv);
return hr;
}
diff --git a/dlls/windowscodecs/unix_iface.c b/dlls/windowscodecs/unix_iface.c
index 80769b5d560..1f5dec9a6c4 100644
--- a/dlls/windowscodecs/unix_iface.c
+++ b/dlls/windowscodecs/unix_iface.c
@@ -42,7 +42,8 @@ static const struct unix_funcs *unix_funcs;
static const struct win32_funcs win32_funcs = {
stream_getsize,
stream_read,
- stream_seek
+ stream_seek,
+ stream_write
};
static BOOL WINAPI load_unixlib( INIT_ONCE *once, void *param, void **context )
@@ -155,6 +156,42 @@ static inline struct encoder_wrapper *impl_from_encoder(struct encoder* iface)
return CONTAINING_RECORD(iface, struct encoder_wrapper, win32_encoder);
}
+HRESULT CDECL encoder_wrapper_initialize(struct encoder* iface, IStream* stream)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_initialize(This->unix_encoder, stream);
+}
+
+HRESULT CDECL encoder_wrapper_get_supported_format(struct encoder* iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_get_supported_format(This->unix_encoder, pixel_format, bpp, indexed);
+}
+
+HRESULT CDECL encoder_wrapper_create_frame(struct encoder* iface, const struct encoder_frame *frame)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_create_frame(This->unix_encoder, frame);
+}
+
+HRESULT CDECL encoder_wrapper_write_lines(struct encoder* iface, BYTE *data, DWORD line_count, DWORD stride)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_write_lines(This->unix_encoder, data, line_count, stride);
+}
+
+HRESULT CDECL encoder_wrapper_commit_frame(struct encoder* iface)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_commit_frame(This->unix_encoder);
+}
+
+HRESULT CDECL encoder_wrapper_commit_file(struct encoder* iface)
+{
+ struct encoder_wrapper* This = impl_from_encoder(iface);
+ return unix_funcs->encoder_commit_file(This->unix_encoder);
+}
+
void CDECL encoder_wrapper_destroy(struct encoder* iface)
{
struct encoder_wrapper* This = impl_from_encoder(iface);
@@ -163,6 +200,12 @@ void CDECL encoder_wrapper_destroy(struct encoder* iface)
}
static const struct encoder_funcs encoder_wrapper_vtable = {
+ encoder_wrapper_initialize,
+ encoder_wrapper_get_supported_format,
+ encoder_wrapper_create_frame,
+ encoder_wrapper_write_lines,
+ encoder_wrapper_commit_frame,
+ encoder_wrapper_commit_file,
encoder_wrapper_destroy
};
diff --git a/dlls/windowscodecs/unix_lib.c b/dlls/windowscodecs/unix_lib.c
index b0c6b37bfce..7fc5f388697 100644
--- a/dlls/windowscodecs/unix_lib.c
+++ b/dlls/windowscodecs/unix_lib.c
@@ -62,6 +62,11 @@ HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG
return win32_funcs->stream_seek(stream, ofs, origin, new_position);
}
+HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)
+{
+ return win32_funcs->stream_write(stream, buffer, write, bytes_written);
+}
+
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result)
{
if (IsEqualGUID(decoder_clsid, &CLSID_WICPngDecoder))
@@ -93,6 +98,12 @@ static const struct unix_funcs unix_funcs = {
decoder_get_color_context,
decoder_destroy,
encoder_create,
+ encoder_initialize,
+ encoder_get_supported_format,
+ encoder_create_frame,
+ encoder_write_lines,
+ encoder_commit_frame,
+ encoder_commit_file,
encoder_destroy
};
diff --git a/dlls/windowscodecs/wincodecs_common.h b/dlls/windowscodecs/wincodecs_common.h
index 303c2d9f38b..75af544fac7 100644
--- a/dlls/windowscodecs/wincodecs_common.h
+++ b/dlls/windowscodecs/wincodecs_common.h
@@ -48,6 +48,36 @@ void CDECL decoder_destroy(struct decoder *decoder)
decoder->vtable->destroy(decoder);
}
+HRESULT CDECL encoder_initialize(struct encoder *encoder, IStream *stream)
+{
+ return encoder->vtable->initialize(encoder, stream);
+}
+
+HRESULT CDECL encoder_get_supported_format(struct encoder* encoder, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
+{
+ return encoder->vtable->get_supported_format(encoder, pixel_format, bpp, indexed);
+}
+
+HRESULT CDECL encoder_create_frame(struct encoder* encoder, const struct encoder_frame *frame)
+{
+ return encoder->vtable->create_frame(encoder, frame);
+}
+
+HRESULT CDECL encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride)
+{
+ return encoder->vtable->write_lines(encoder, data, line_count, stride);
+}
+
+HRESULT CDECL encoder_commit_frame(struct encoder* encoder)
+{
+ return encoder->vtable->commit_frame(encoder);
+}
+
+HRESULT CDECL encoder_commit_file(struct encoder* encoder)
+{
+ return encoder->vtable->commit_file(encoder);
+}
+
void CDECL encoder_destroy(struct encoder *encoder)
{
encoder->vtable->destroy(encoder);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 8495ea73521..a3d5f5591b0 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -313,12 +313,14 @@ struct decoder_funcs
HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size);
HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
+HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written);
struct win32_funcs
{
HRESULT (CDECL *stream_getsize)(IStream *stream, ULONGLONG *size);
HRESULT (CDECL *stream_read)(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read);
HRESULT (CDECL *stream_seek)(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position);
+ HRESULT (CDECL *stream_write)(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written);
};
HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result);
@@ -342,13 +344,30 @@ enum encoder_option
ENCODER_OPTION_END
};
+#define ENCODER_FLAGS_MULTI_FRAME 0x1
+
struct encoder_info
{
+ DWORD flags;
GUID container_format;
CLSID clsid;
DWORD encoder_options[7];
};
+struct encoder_frame
+{
+ GUID pixel_format;
+ UINT width, height;
+ UINT bpp;
+ BOOL indexed;
+ double dpix, dpiy;
+ DWORD num_colors;
+ WICColor palette[256];
+ /* encoder options */
+ BOOL interlace;
+ DWORD filter;
+};
+
struct encoder
{
const struct encoder_funcs *vtable;
@@ -356,9 +375,21 @@ struct encoder
struct encoder_funcs
{
+ HRESULT (CDECL *initialize)(struct encoder* This, IStream *stream);
+ HRESULT (CDECL *get_supported_format)(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed);
+ HRESULT (CDECL *create_frame)(struct encoder* This, const struct encoder_frame *frame);
+ HRESULT (CDECL *write_lines)(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride);
+ HRESULT (CDECL *commit_frame)(struct encoder* This);
+ HRESULT (CDECL *commit_file)(struct encoder* This);
void (CDECL *destroy)(struct encoder* This);
};
+HRESULT CDECL encoder_initialize(struct encoder* This, IStream *stream);
+HRESULT CDECL encoder_get_supported_format(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed);
+HRESULT CDECL encoder_create_frame(struct encoder* This, const struct encoder_frame *frame);
+HRESULT CDECL encoder_write_lines(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride);
+HRESULT CDECL encoder_commit_frame(struct encoder* This);
+HRESULT CDECL encoder_commit_file(struct encoder* This);
void CDECL encoder_destroy(struct encoder* This);
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result);
@@ -380,6 +411,12 @@ struct unix_funcs
BYTE **data, DWORD *datasize);
void (CDECL *decoder_destroy)(struct decoder* This);
HRESULT (CDECL *encoder_create)(const CLSID *encoder_clsid, struct encoder_info *info, struct encoder **result);
+ HRESULT (CDECL *encoder_initialize)(struct encoder* This, IStream *stream);
+ HRESULT (CDECL *encoder_get_supported_format)(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed);
+ HRESULT (CDECL *encoder_create_frame)(struct encoder* This, const struct encoder_frame *frame);
+ HRESULT (CDECL *encoder_write_lines)(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride);
+ HRESULT (CDECL *encoder_commit_frame)(struct encoder* This);
+ HRESULT (CDECL *encoder_commit_file)(struct encoder* This);
void (CDECL *encoder_destroy)(struct encoder* This);
};
@@ -389,4 +426,7 @@ HRESULT get_unix_encoder(const CLSID *encoder_clsid, struct encoder_info *info,
extern HRESULT CommonDecoder_CreateInstance(struct decoder *decoder,
const struct decoder_info *decoder_info, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
+extern HRESULT CommonEncoder_CreateInstance(struct encoder *encoder,
+ const struct encoder_info *encoder_info, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
+
#endif /* WINCODECS_PRIVATE_H */
--
2.17.1
1
0