2016-12-11 19:28:52 -08:00
|
|
|
From 4fb9b87edfb24fe5676f5944fc6aaeff7fdbfdc3 Mon Sep 17 00:00:00 2001
|
2016-03-10 19:25:51 -08:00
|
|
|
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
|
|
|
Date: Fri, 11 Mar 2016 03:48:46 +0100
|
2016-03-13 09:06:48 -07:00
|
|
|
Subject: windowscodecs: Implement WICCreateBitmapFromSection(Ex). (v2)
|
2016-03-10 19:25:51 -08:00
|
|
|
|
|
|
|
---
|
2016-03-13 09:06:48 -07:00
|
|
|
dlls/windowscodecs/bitmap.c | 27 ++++++++-----
|
|
|
|
dlls/windowscodecs/imgfactory.c | 73 ++++++++++++++++++++++++++++++++++-
|
|
|
|
dlls/windowscodecs/windowscodecs.spec | 3 +-
|
|
|
|
include/wincodec.idl | 8 ++++
|
|
|
|
4 files changed, 100 insertions(+), 11 deletions(-)
|
2016-03-10 19:25:51 -08:00
|
|
|
|
2016-03-13 09:06:48 -07:00
|
|
|
diff --git a/dlls/windowscodecs/bitmap.c b/dlls/windowscodecs/bitmap.c
|
2016-12-11 19:28:52 -08:00
|
|
|
index 6adaab0..76298b2 100644
|
2016-03-13 09:06:48 -07:00
|
|
|
--- a/dlls/windowscodecs/bitmap.c
|
|
|
|
+++ b/dlls/windowscodecs/bitmap.c
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -45,6 +45,7 @@ typedef struct BitmapImpl {
|
2016-03-13 09:06:48 -07:00
|
|
|
int palette_set;
|
|
|
|
LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
|
|
|
|
BYTE *data;
|
|
|
|
+ BOOL is_section; /* TRUE if data is a section created by an application */
|
|
|
|
UINT width, height;
|
|
|
|
UINT stride;
|
|
|
|
UINT bpp;
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -284,7 +285,10 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
|
2016-03-13 09:06:48 -07:00
|
|
|
if (This->palette) IWICPalette_Release(This->palette);
|
|
|
|
This->cs.DebugInfo->Spare[0] = 0;
|
|
|
|
DeleteCriticalSection(&This->cs);
|
|
|
|
- HeapFree(GetProcessHeap(), 0, This->data);
|
|
|
|
+ if (This->is_section)
|
|
|
|
+ UnmapViewOfFile(This->data);
|
|
|
|
+ else
|
|
|
|
+ HeapFree(GetProcessHeap(), 0, This->data);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -694,13 +698,12 @@ static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl =
|
2016-03-13 09:06:48 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
|
|
|
|
- UINT stride, UINT datasize, BYTE *bits,
|
|
|
|
+ UINT stride, UINT datasize, BYTE *data,
|
|
|
|
REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
|
|
|
|
IWICBitmap **ppIBitmap)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
BitmapImpl *This;
|
|
|
|
- BYTE *data;
|
|
|
|
UINT bpp;
|
|
|
|
|
|
|
|
hr = get_pixelformat_bpp(pixelFormat, &bpp);
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -713,14 +716,20 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
|
2016-03-13 09:06:48 -07:00
|
|
|
if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG;
|
|
|
|
|
|
|
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
|
|
|
|
- data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
|
|
|
|
- if (!This || !data)
|
|
|
|
+ if (!This) return E_OUTOFMEMORY;
|
|
|
|
+
|
|
|
|
+ if (!data)
|
|
|
|
{
|
|
|
|
- HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
- HeapFree(GetProcessHeap(), 0, data);
|
|
|
|
- return E_OUTOFMEMORY;
|
|
|
|
+ data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
|
|
|
|
+ if (!data)
|
|
|
|
+ {
|
|
|
|
+ HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
+ return E_OUTOFMEMORY;
|
|
|
|
+ }
|
|
|
|
+ This->is_section = FALSE;
|
|
|
|
}
|
|
|
|
- if (bits) memcpy(data, bits, datasize);
|
|
|
|
+ else
|
|
|
|
+ This->is_section = TRUE;
|
|
|
|
|
|
|
|
This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
|
|
|
|
This->IMILBitmapSource_iface.lpVtbl = &IMILBitmapImpl_Vtbl;
|
2016-03-10 19:25:51 -08:00
|
|
|
diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c
|
2016-12-11 19:28:52 -08:00
|
|
|
index 659aa7e..3cd6fd0 100644
|
2016-03-10 19:25:51 -08:00
|
|
|
--- a/dlls/windowscodecs/imgfactory.c
|
|
|
|
+++ b/dlls/windowscodecs/imgfactory.c
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -595,12 +595,36 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto
|
2016-03-13 09:06:48 -07:00
|
|
|
UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
|
|
|
|
UINT size, BYTE *buffer, IWICBitmap **bitmap)
|
|
|
|
{
|
|
|
|
+ HRESULT hr;
|
|
|
|
+
|
|
|
|
TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
|
|
|
|
debugstr_guid(format), stride, size, buffer, bitmap);
|
|
|
|
|
|
|
|
if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
|
|
|
|
|
|
|
|
- return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);
|
|
|
|
+ hr = BitmapImpl_Create(width, height, stride, size, NULL, format, WICBitmapCacheOnLoad, bitmap);
|
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
|
+ {
|
|
|
|
+ IWICBitmapLock *lock;
|
|
|
|
+
|
|
|
|
+ hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
|
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
|
+ {
|
|
|
|
+ UINT buffersize;
|
|
|
|
+ BYTE *data;
|
|
|
|
+
|
|
|
|
+ IWICBitmapLock_GetDataPointer(lock, &buffersize, &data);
|
|
|
|
+ memcpy(data, buffer, buffersize);
|
|
|
|
+
|
|
|
|
+ IWICBitmapLock_Release(lock);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ IWICBitmap_Release(*bitmap);
|
|
|
|
+ *bitmap = NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -1176,3 +1200,50 @@ HRESULT ComponentFactory_CreateInstance(REFIID iid, void** ppv)
|
2016-03-10 19:25:51 -08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height,
|
|
|
|
+ REFWICPixelFormatGUID format, HANDLE section, UINT stride,
|
|
|
|
+ UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap)
|
|
|
|
+{
|
|
|
|
+ DWORD access;
|
2016-03-13 09:06:48 -07:00
|
|
|
+ void *buffer;
|
2016-03-10 19:25:51 -08:00
|
|
|
+ HRESULT hr;
|
|
|
|
+
|
|
|
|
+ TRACE("%u,%u,%s,%p,%u,%#x,%#x,%p\n", width, height, debugstr_guid(format),
|
|
|
|
+ section, stride, offset, wicaccess, bitmap);
|
|
|
|
+
|
|
|
|
+ if (!width || !height || !section || !bitmap) return E_INVALIDARG;
|
|
|
|
+
|
|
|
|
+ switch (wicaccess)
|
|
|
|
+ {
|
|
|
|
+ case WICSectionAccessLevelReadWrite:
|
|
|
|
+ access = FILE_MAP_READ | FILE_MAP_WRITE;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case WICSectionAccessLevelRead:
|
|
|
|
+ access = FILE_MAP_READ;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ FIXME("unsupported access %#x\n", wicaccess);
|
|
|
|
+ return E_INVALIDARG;
|
|
|
|
+ }
|
|
|
|
+
|
2016-03-13 09:06:48 -07:00
|
|
|
+ buffer = MapViewOfFile(section, access, 0, offset, 0);
|
|
|
|
+ if (!buffer) return HRESULT_FROM_WIN32(GetLastError());
|
2016-03-10 19:25:51 -08:00
|
|
|
+
|
2016-03-13 09:06:48 -07:00
|
|
|
+ hr = BitmapImpl_Create(width, height, stride, 0, buffer, format, WICBitmapCacheOnLoad, bitmap);
|
|
|
|
+ if (FAILED(hr)) UnmapViewOfFile(buffer);
|
2016-03-10 19:25:51 -08:00
|
|
|
+ return hr;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height,
|
|
|
|
+ REFWICPixelFormatGUID format, HANDLE section,
|
|
|
|
+ UINT stride, UINT offset, IWICBitmap **bitmap)
|
|
|
|
+{
|
|
|
|
+ TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format),
|
|
|
|
+ section, stride, offset, bitmap);
|
|
|
|
+
|
|
|
|
+ return WICCreateBitmapFromSectionEx(width, height, format, section,
|
|
|
|
+ stride, offset, WICSectionAccessLevelRead, bitmap);
|
|
|
|
+}
|
|
|
|
diff --git a/dlls/windowscodecs/windowscodecs.spec b/dlls/windowscodecs/windowscodecs.spec
|
|
|
|
index 81a827e..7ee76d9 100644
|
|
|
|
--- a/dlls/windowscodecs/windowscodecs.spec
|
|
|
|
+++ b/dlls/windowscodecs/windowscodecs.spec
|
|
|
|
@@ -105,7 +105,8 @@
|
|
|
|
@ stdcall IWICStream_InitializeFromIStream_Proxy(ptr ptr) IWICStream_InitializeFromIStream_Proxy_W
|
|
|
|
@ stdcall IWICStream_InitializeFromMemory_Proxy(ptr ptr long) IWICStream_InitializeFromMemory_Proxy_W
|
|
|
|
@ stdcall WICConvertBitmapSource(ptr ptr ptr)
|
|
|
|
-@ stub WICCreateBitmapFromSection
|
|
|
|
+@ stdcall WICCreateBitmapFromSection(long long ptr long long long ptr)
|
|
|
|
+@ stdcall WICCreateBitmapFromSectionEx(long long ptr long long long long ptr)
|
|
|
|
@ stdcall WICCreateColorContext_Proxy(ptr ptr)
|
|
|
|
@ stdcall WICCreateImagingFactory_Proxy(long ptr)
|
|
|
|
@ stub WICGetMetadataContentSize
|
|
|
|
diff --git a/include/wincodec.idl b/include/wincodec.idl
|
2016-12-11 19:28:52 -08:00
|
|
|
index 406fe6b..c0afe52 100644
|
2016-03-10 19:25:51 -08:00
|
|
|
--- a/include/wincodec.idl
|
|
|
|
+++ b/include/wincodec.idl
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -179,6 +179,12 @@ typedef enum WICPngFilterOption {
|
|
|
|
WICPNFFILTEROPTION_FORCE_DWORD = CODEC_FORCE_DWORD
|
|
|
|
} WICPngFilterOption;
|
2016-03-10 19:25:51 -08:00
|
|
|
|
|
|
|
+typedef enum WICSectionAccessLevel {
|
|
|
|
+ WICSectionAccessLevelRead = 0x00000001,
|
|
|
|
+ WICSectionAccessLevelReadWrite = 0x00000003,
|
|
|
|
+ WICSectionAccessLevel_FORCE_DWORD = CODEC_FORCE_DWORD
|
|
|
|
+} WICSectionAccessLevel;
|
|
|
|
+
|
|
|
|
typedef GUID WICPixelFormatGUID;
|
|
|
|
typedef REFGUID REFWICPixelFormatGUID;
|
|
|
|
|
2016-12-11 19:28:52 -08:00
|
|
|
@@ -994,6 +1000,8 @@ interface IWICEnumMetadataItem : IUnknown
|
2016-03-10 19:25:51 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
cpp_quote("HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);")
|
|
|
|
+cpp_quote("HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, IWICBitmap **bitmap);")
|
|
|
|
+cpp_quote("HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, WICSectionAccessLevel access, IWICBitmap **bitmap);")
|
|
|
|
|
|
|
|
cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);")
|
|
|
|
cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);")
|
|
|
|
--
|
2016-12-11 19:28:52 -08:00
|
|
|
2.9.0
|
2016-03-10 19:25:51 -08:00
|
|
|
|