https://git.reactos.org/?p=reactos.git;a=commitdiff;h=324214f99875727891e3a…
commit 324214f99875727891e3ac3762dd63a5b18df057
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Jun 4 03:55:39 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Mon Jun 4 03:55:39 2018 +0100
[WINDOWSCODECS] Sync with Wine Staging 3.9. CORE-14656
---
dll/win32/windowscodecs/bitmap.c | 29 +-
dll/win32/windowscodecs/bmpdecode.c | 13 +-
dll/win32/windowscodecs/bmpencode.c | 49 +-
dll/win32/windowscodecs/converter.c | 43 ++
dll/win32/windowscodecs/gifformat.c | 13 +-
dll/win32/windowscodecs/icoformat.c | 13 +-
dll/win32/windowscodecs/imgfactory.c | 40 +-
dll/win32/windowscodecs/info.c | 817 +++++++++++++++++-----------
dll/win32/windowscodecs/jpegformat.c | 165 ++----
dll/win32/windowscodecs/main.c | 3 +
dll/win32/windowscodecs/pngformat.c | 13 +-
dll/win32/windowscodecs/precomp.h | 1 +
dll/win32/windowscodecs/tgaformat.c | 13 +-
dll/win32/windowscodecs/tiffformat.c | 13 +-
dll/win32/windowscodecs/wincodecs_private.h | 4 +-
media/doc/README.WINE | 2 +-
16 files changed, 679 insertions(+), 552 deletions(-)
diff --git a/dll/win32/windowscodecs/bitmap.c b/dll/win32/windowscodecs/bitmap.c
index 69ec14fed2..734c211c68 100644
--- a/dll/win32/windowscodecs/bitmap.c
+++ b/dll/win32/windowscodecs/bitmap.c
@@ -45,7 +45,8 @@ typedef struct BitmapImpl {
int palette_set;
LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading
*/
BYTE *data;
- BOOL is_section; /* TRUE if data is a section created by an application */
+ void *view; /* used if data is a section created by an application */
+ UINT offset; /* offset into view */
UINT width, height;
UINT stride;
UINT bpp;
@@ -288,8 +289,8 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
if (This->palette) IWICPalette_Release(This->palette);
This->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->cs);
- if (This->is_section)
- UnmapViewOfFile(This->data);
+ if (This->view)
+ UnmapViewOfFile(This->view);
else
HeapFree(GetProcessHeap(), 0, This->data);
HeapFree(GetProcessHeap(), 0, This);
@@ -805,13 +806,13 @@ static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl =
IMILUnknown2Impl_unknown3
};
-HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
- UINT stride, UINT datasize, BYTE *data,
- REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
+HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasize, void
*view,
+ UINT offset, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap)
{
HRESULT hr;
BitmapImpl *This;
+ BYTE *data;
UINT bpp;
hr = get_pixelformat_bpp(pixelFormat, &bpp);
@@ -826,18 +827,12 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
if (!This) return E_OUTOFMEMORY;
- if (!data)
+ if (view) data = (BYTE *)view + offset;
+ else if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize)))
{
- data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
- if (!data)
- {
- HeapFree(GetProcessHeap(), 0, This);
- return E_OUTOFMEMORY;
- }
- This->is_section = FALSE;
+ HeapFree(GetProcessHeap(), 0, This);
+ return E_OUTOFMEMORY;
}
- else
- This->is_section = TRUE;
This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
This->IMILBitmapSource_iface.lpVtbl = &IMILBitmapImpl_Vtbl;
@@ -848,6 +843,8 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
This->palette_set = 0;
This->lock = 0;
This->data = data;
+ This->view = view;
+ This->offset = offset;
This->width = uiWidth;
This->height = uiHeight;
This->stride = stride;
diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c
index 47f312ffcf..1b8e4d1f37 100644
--- a/dll/win32/windowscodecs/bmpdecode.c
+++ b/dll/win32/windowscodecs/bmpdecode.c
@@ -1068,20 +1068,9 @@ static HRESULT WINAPI
BmpDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI BmpDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICBmpDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICBmpDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI BmpDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dll/win32/windowscodecs/bmpencode.c b/dll/win32/windowscodecs/bmpencode.c
index cb8b4897e4..a81cc53223 100644
--- a/dll/win32/windowscodecs/bmpencode.c
+++ b/dll/win32/windowscodecs/bmpencode.c
@@ -261,8 +261,10 @@ static HRESULT WINAPI
BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ UINT dstbuffersize, bytesperrow, row;
+ BYTE *dst, *src;
HRESULT hr;
- WICRect rc;
+
TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize,
pbPixels);
if (!This->initialized || !This->width || !This->height ||
!This->format)
@@ -271,19 +273,27 @@ static HRESULT WINAPI
BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
hr = BmpFrameEncode_AllocateBits(This);
if (FAILED(hr)) return hr;
- rc.X = 0;
- rc.Y = 0;
- rc.Width = This->width;
- rc.Height = lineCount;
+ bytesperrow = ((This->format->bpp * This->width) + 7) / 8;
- hr = copy_pixels(This->format->bpp, pbPixels, This->width, lineCount,
cbStride,
- &rc, This->stride,
This->stride*(This->height-This->lineswritten),
- This->bits + This->stride*This->lineswritten);
+ if (This->stride < bytesperrow)
+ return E_INVALIDARG;
- if (SUCCEEDED(hr))
- This->lineswritten += lineCount;
+ dstbuffersize = This->stride * (This->height - This->lineswritten);
+ if ((This->stride * (lineCount - 1)) + bytesperrow > dstbuffersize)
+ return E_INVALIDARG;
- return hr;
+ src = pbPixels;
+ dst = This->bits + This->stride * (This->height - This->lineswritten -
1);
+ for (row = 0; row < lineCount; row++)
+ {
+ memcpy(dst, src, bytesperrow);
+ src += cbStride;
+ dst -= This->stride;
+ }
+
+ This->lineswritten += lineCount;
+
+ return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
@@ -314,11 +324,10 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode
*iface)
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
BITMAPFILEHEADER bfh;
BITMAPV5HEADER bih;
- UINT info_size, i;
+ UINT info_size;
LARGE_INTEGER pos;
ULONG byteswritten;
HRESULT hr;
- const BYTE *bits;
TRACE("(%p)\n", iface);
@@ -331,7 +340,7 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode
*iface)
bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER);
bih.bV5Width = This->width;
- bih.bV5Height = This->height; /* bottom-top bitmap */
+ bih.bV5Height = This->height;
bih.bV5Planes = 1;
bih.bV5BitCount = This->format->bpp;
bih.bV5Compression = This->format->compression;
@@ -378,15 +387,9 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode
*iface)
if (byteswritten != This->colors * sizeof(WICColor)) return E_FAIL;
}
- /* write the image bits as a bottom-top array */
- bits = This->bits + bih.bV5SizeImage;
- for (i = 0; i < This->height; i++)
- {
- bits -= This->stride;
- hr = IStream_Write(This->stream, bits, This->stride, &byteswritten);
- if (FAILED(hr)) return hr;
- if (byteswritten != This->stride) return E_FAIL;
- }
+ hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage,
&byteswritten);
+ if (FAILED(hr)) return hr;
+ if (byteswritten != bih.bV5SizeImage) return E_FAIL;
This->committed = TRUE;
diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c
index c3bcce89e0..0d3414a146 100644
--- a/dll/win32/windowscodecs/converter.c
+++ b/dll/win32/windowscodecs/converter.c
@@ -30,6 +30,7 @@
#include "wincodecs_private.h"
+#include "wine/heap.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
@@ -1087,6 +1088,48 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This,
const WICRec
}
return S_OK;
+ case format_32bppCMYK:
+ if (prc)
+ {
+ BYTE *srcdata;
+ UINT srcstride, srcdatasize;
+
+ srcstride = 4 * prc->Width;
+ srcdatasize = srcstride * prc->Height;
+
+ srcdata = heap_alloc(srcdatasize);
+ if (!srcdata) return E_OUTOFMEMORY;
+
+ hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride,
srcdatasize, srcdata);
+ if (SUCCEEDED(hr))
+ {
+ INT x, y;
+ BYTE *src = srcdata, *dst = pbBuffer;
+
+ for (y = 0; y < prc->Height; y++)
+ {
+ BYTE *cmyk = src;
+ BYTE *bgr = dst;
+
+ for (x = 0; x < prc->Width; x++)
+ {
+ BYTE c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
+ bgr[0] = (255 - y) * (255 - k) / 255; /* B */
+ bgr[1] = (255 - m) * (255 - k) / 255; /* G */
+ bgr[2] = (255 - c) * (255 - k) / 255; /* R */
+ cmyk += 4;
+ bgr += 3;
+ }
+ src += srcstride;
+ dst += cbStride;
+ }
+ }
+
+ heap_free(srcdata);
+ return hr;
+ }
+ return S_OK;
+
default:
FIXME("Unimplemented conversion path!\n");
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
diff --git a/dll/win32/windowscodecs/gifformat.c b/dll/win32/windowscodecs/gifformat.c
index e898d9c852..78ac427d9a 100644
--- a/dll/win32/windowscodecs/gifformat.c
+++ b/dll/win32/windowscodecs/gifformat.c
@@ -1176,20 +1176,9 @@ static HRESULT WINAPI
GifDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI GifDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICGifDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICGifDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalette
*palette)
diff --git a/dll/win32/windowscodecs/icoformat.c b/dll/win32/windowscodecs/icoformat.c
index 1b1c79291b..5e38ee0d0f 100644
--- a/dll/win32/windowscodecs/icoformat.c
+++ b/dll/win32/windowscodecs/icoformat.c
@@ -556,20 +556,9 @@ static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder
*iface,
static HRESULT WINAPI IcoDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICIcoDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICIcoDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI IcoDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dll/win32/windowscodecs/imgfactory.c b/dll/win32/windowscodecs/imgfactory.c
index 88ce00e651..180e745f46 100644
--- a/dll/win32/windowscodecs/imgfactory.c
+++ b/dll/win32/windowscodecs/imgfactory.c
@@ -477,7 +477,7 @@ static HRESULT WINAPI
ComponentFactory_CreateBitmap(IWICComponentFactory *iface,
{
TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
debugstr_guid(pixelFormat), option, ppIBitmap);
- return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, pixelFormat, option,
ppIBitmap);
+ return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, 0, pixelFormat, option,
ppIBitmap);
}
static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory
*iface,
@@ -524,7 +524,7 @@ static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSource(IWICComponentFacto
}
if (SUCCEEDED(hr))
- hr = BitmapImpl_Create(width, height, 0, 0, NULL, &pixelformat, option,
&result);
+ hr = BitmapImpl_Create(width, height, 0, 0, NULL, 0, &pixelformat, option,
&result);
if (SUCCEEDED(hr))
{
@@ -606,7 +606,7 @@ static HRESULT WINAPI
ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto
if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
- hr = BitmapImpl_Create(width, height, stride, size, NULL, format,
WICBitmapCacheOnLoad, bitmap);
+ hr = BitmapImpl_Create(width, height, stride, size, NULL, 0, format,
WICBitmapCacheOnLoad, bitmap);
if (SUCCEEDED(hr))
{
IWICBitmapLock *lock;
@@ -738,7 +738,8 @@ static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFact
return E_INVALIDARG;
}
- hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL,
&format, WICBitmapCacheOnLoad, bitmap);
+ hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, 0,
&format,
+ WICBitmapCacheOnLoad, bitmap);
if (hr != S_OK) return hr;
hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
@@ -822,7 +823,7 @@ static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactor
stride = width * 4;
size = stride * height;
- hr = BitmapImpl_Create(width, height, stride, size, NULL,
+ hr = BitmapImpl_Create(width, height, stride, size, NULL, 0,
&GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad,
bitmap);
if (hr != S_OK) goto failed;
@@ -1209,15 +1210,19 @@ HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT
height,
REFWICPixelFormatGUID format, HANDLE section, UINT stride,
UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap)
{
- DWORD access;
- void *buffer;
+ SYSTEM_INFO sysinfo;
+ UINT bpp, access, size, view_offset, view_size;
+ void *view;
HRESULT hr;
- TRACE("%u,%u,%s,%p,%u,%#x,%#x,%p\n", width, height, debugstr_guid(format),
- section, stride, offset, wicaccess, bitmap);
+ TRACE("%u,%u,%s,%p,%u,%u,%#x,%p\n", width, height, debugstr_guid(format),
+ section, stride, offset, wicaccess, bitmap);
if (!width || !height || !section || !bitmap) return E_INVALIDARG;
+ hr = get_pixelformat_bpp(format, &bpp);
+ if (FAILED(hr)) return hr;
+
switch (wicaccess)
{
case WICSectionAccessLevelReadWrite:
@@ -1233,11 +1238,20 @@ HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT
height,
return E_INVALIDARG;
}
- buffer = MapViewOfFile(section, access, 0, offset, 0);
- if (!buffer) return HRESULT_FROM_WIN32(GetLastError());
+ if (!stride) stride = (((bpp * width) + 31) / 32) * 4;
+ size = stride * height;
+ if (size / height != stride) return E_INVALIDARG;
+
+ GetSystemInfo(&sysinfo);
+ view_offset = offset - (offset % sysinfo.dwAllocationGranularity);
+ view_size = size + (offset - view_offset);
+
+ view = MapViewOfFile(section, access, 0, view_offset, view_size);
+ if (!view) return HRESULT_FROM_WIN32(GetLastError());
- hr = BitmapImpl_Create(width, height, stride, 0, buffer, format,
WICBitmapCacheOnLoad, bitmap);
- if (FAILED(hr)) UnmapViewOfFile(buffer);
+ offset -= view_offset;
+ hr = BitmapImpl_Create(width, height, stride, 0, view, offset, format,
WICBitmapCacheOnLoad, bitmap);
+ if (FAILED(hr)) UnmapViewOfFile(view);
return hr;
}
diff --git a/dll/win32/windowscodecs/info.c b/dll/win32/windowscodecs/info.c
index 22a7b83e2c..33d3c3030d 100644
--- a/dll/win32/windowscodecs/info.c
+++ b/dll/win32/windowscodecs/info.c
@@ -33,6 +33,8 @@
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/list.h"
+#include "wine/rbtree.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
@@ -56,6 +58,13 @@ static const WCHAR supportspadding_valuename[] =
{'S','u','p','p','o','r','t','s
static const WCHAR fileextensions_valuename[] =
{'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
static const WCHAR containers_keyname[] =
{'C','o','n','t','a','i','n','e','r','s',0};
+typedef struct {
+ IWICComponentInfo IWICComponentInfo_iface;
+ LONG ref;
+ CLSID clsid;
+ struct wine_rb_entry entry;
+} ComponentInfo;
+
static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
UINT buffer_size, WCHAR *buffer, UINT *actual_size)
{
@@ -204,15 +213,16 @@ static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR
subkeyname,
}
typedef struct {
- IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
- LONG ref;
+ ComponentInfo base;
HKEY classkey;
- CLSID clsid;
+ WICBitmapPattern *patterns;
+ UINT pattern_count;
+ UINT patterns_size;
} BitmapDecoderInfo;
static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo
*iface)
{
- return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
+ return CONTAINING_RECORD(iface, BitmapDecoderInfo, base.IWICComponentInfo_iface);
}
static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface,
REFIID iid,
@@ -228,7 +238,7 @@ static HRESULT WINAPI
BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *if
IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
{
- *ppv = &This->IWICBitmapDecoderInfo_iface;
+ *ppv = &This->base.IWICComponentInfo_iface;
}
else
{
@@ -243,7 +253,7 @@ static HRESULT WINAPI
BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *if
static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
{
BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -253,13 +263,14 @@ static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo
*iface)
static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
{
BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ ULONG ref = InterlockedDecrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
RegCloseKey(This->classkey);
+ heap_free(This->patterns);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -283,8 +294,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo
*iface, C
if (!pclsid)
return E_INVALIDARG;
- memcpy(pclsid, &This->clsid, sizeof(CLSID));
-
+ *pclsid = This->base.clsid;
return S_OK;
}
@@ -445,103 +455,26 @@ static HRESULT WINAPI
BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface
UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT
*pcbPatternsActual)
{
BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
- UINT pattern_count=0, patterns_size=0;
- WCHAR subkeyname[11];
- LONG res;
- HKEY patternskey, patternkey;
- static const WCHAR uintformatW[] = {'%','u',0};
- static const WCHAR patternsW[] =
{'P','a','t','t','e','r','n','s',0};
- static const WCHAR positionW[] =
{'P','o','s','i','t','i','o','n',0};
- static const WCHAR lengthW[] =
{'L','e','n','g','t','h',0};
- static const WCHAR patternW[] =
{'P','a','t','t','e','r','n',0};
- static const WCHAR maskW[] = {'M','a','s','k',0};
- static const WCHAR endofstreamW[] =
{'E','n','d','O','f','S','t','r','e','a','m',0};
- HRESULT hr=S_OK;
- UINT i;
- BYTE *bPatterns=(BYTE*)pPatterns;
- DWORD length, valuesize;
TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns,
pcbPatternsActual);
- res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
- if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
-
- res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
- if (res == ERROR_SUCCESS)
- {
- patterns_size = pattern_count * sizeof(WICBitmapPattern);
-
- for (i=0; i<pattern_count; i++)
- {
- snprintfW(subkeyname, 11, uintformatW, i);
- res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
- if (res == ERROR_SUCCESS)
- {
- valuesize = sizeof(ULONG);
- res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
- &length, &valuesize);
- patterns_size += length*2;
-
- if ((cbSizePatterns >= patterns_size) && (res ==
ERROR_SUCCESS))
- {
- pPatterns[i].Length = length;
-
- pPatterns[i].EndOfStream = 0;
- valuesize = sizeof(BOOL);
- RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
- &pPatterns[i].EndOfStream, &valuesize);
-
- pPatterns[i].Position.QuadPart = 0;
- valuesize = sizeof(ULARGE_INTEGER);
- res = RegGetValueW(patternkey, NULL, positionW,
RRF_RT_DWORD|RRF_RT_QWORD, NULL,
- &pPatterns[i].Position, &valuesize);
-
- if (res == ERROR_SUCCESS)
- {
- pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
- valuesize = length;
- res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY,
NULL,
- pPatterns[i].Pattern, &valuesize);
- }
-
- if (res == ERROR_SUCCESS)
- {
- pPatterns[i].Mask = bPatterns+patterns_size-length;
- valuesize = length;
- res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY,
NULL,
- pPatterns[i].Mask, &valuesize);
- }
- }
-
- RegCloseKey(patternkey);
- }
- if (res != ERROR_SUCCESS)
- {
- hr = HRESULT_FROM_WIN32(res);
- break;
- }
- }
- }
- else hr = HRESULT_FROM_WIN32(res);
+ if (!pcPatterns || !pcbPatternsActual) return E_INVALIDARG;
- RegCloseKey(patternskey);
-
- if (hr == S_OK)
+ *pcPatterns = This->pattern_count;
+ *pcbPatternsActual = This->patterns_size;
+ if (pPatterns)
{
- *pcPatterns = pattern_count;
- *pcbPatternsActual = patterns_size;
- if (pPatterns && cbSizePatterns < patterns_size)
- hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
+ if (This->patterns_size && cbSizePatterns <
This->patterns_size)
+ return WINCODEC_ERR_INSUFFICIENTBUFFER;
+ memcpy(pPatterns, This->patterns, This->patterns_size);
}
-
- return hr;
+ return S_OK;
}
static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
IStream *pIStream, BOOL *pfMatches)
{
- WICBitmapPattern *patterns;
- UINT pattern_count=0, patterns_size=0;
+ BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
HRESULT hr;
UINT i;
ULONG pos;
@@ -552,22 +485,13 @@ static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if
TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
- hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count,
&patterns_size);
- if (FAILED(hr)) return hr;
-
- patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
- if (!patterns) return E_OUTOFMEMORY;
-
- hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns,
&pattern_count, &patterns_size);
- if (FAILED(hr)) goto end;
-
- for (i=0; i<pattern_count; i++)
+ for (i=0; i < This->pattern_count; i++)
{
- if (datasize < patterns[i].Length)
+ if (datasize < This->patterns[i].Length)
{
HeapFree(GetProcessHeap(), 0, data);
- datasize = patterns[i].Length;
- data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
+ datasize = This->patterns[i].Length;
+ data = HeapAlloc(GetProcessHeap(), 0, This->patterns[i].Length);
if (!data)
{
hr = E_OUTOFMEMORY;
@@ -575,25 +499,25 @@ static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if
}
}
- if (patterns[i].EndOfStream)
- seekpos.QuadPart = -patterns[i].Position.QuadPart;
+ if (This->patterns[i].EndOfStream)
+ seekpos.QuadPart = -This->patterns[i].Position.QuadPart;
else
- seekpos.QuadPart = patterns[i].Position.QuadPart;
- hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END :
STREAM_SEEK_SET, NULL);
+ seekpos.QuadPart = This->patterns[i].Position.QuadPart;
+ hr = IStream_Seek(pIStream, seekpos, This->patterns[i].EndOfStream ?
STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
if (FAILED(hr)) break;
- hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
- if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /*
past end of stream */
+ hr = IStream_Read(pIStream, data, This->patterns[i].Length, &bytesread);
+ if (hr == S_FALSE || (hr == S_OK && bytesread !=
This->patterns[i].Length)) /* past end of stream */
continue;
if (FAILED(hr)) break;
- for (pos=0; pos<patterns[i].Length; pos++)
+ for (pos=0; pos < This->patterns[i].Length; pos++)
{
- if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
+ if ((data[pos] & This->patterns[i].Mask[pos]) !=
This->patterns[i].Pattern[pos])
break;
}
- if (pos == patterns[i].Length) /* matches pattern */
+ if (pos == This->patterns[i].Length) /* matches pattern */
{
hr = S_OK;
*pfMatches = TRUE;
@@ -601,16 +525,13 @@ static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if
}
}
- if (i == pattern_count) /* does not match any pattern */
+ if (i == This->pattern_count) /* does not match any pattern */
{
hr = S_OK;
*pfMatches = FALSE;
}
-end:
- HeapFree(GetProcessHeap(), 0, patterns);
HeapFree(GetProcessHeap(), 0, data);
-
return hr;
}
@@ -621,7 +542,7 @@ static HRESULT WINAPI
BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *if
TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
- return create_instance(&This->clsid, &IID_IWICBitmapDecoder,
(void**)ppIBitmapDecoder);
+ return create_instance(&This->base.clsid, &IID_IWICBitmapDecoder,
(void**)ppIBitmapDecoder);
}
static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
@@ -653,36 +574,146 @@ static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
BitmapDecoderInfo_CreateInstance
};
-static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid,
IWICComponentInfo **ppIInfo)
+static void read_bitmap_patterns(BitmapDecoderInfo *info)
+{
+ UINT pattern_count=0, patterns_size=0;
+ WCHAR subkeyname[11];
+ LONG res;
+ HKEY patternskey, patternkey;
+ static const WCHAR uintformatW[] = {'%','u',0};
+ static const WCHAR patternsW[] =
{'P','a','t','t','e','r','n','s',0};
+ static const WCHAR positionW[] =
{'P','o','s','i','t','i','o','n',0};
+ static const WCHAR lengthW[] =
{'L','e','n','g','t','h',0};
+ static const WCHAR patternW[] =
{'P','a','t','t','e','r','n',0};
+ static const WCHAR maskW[] = {'M','a','s','k',0};
+ static const WCHAR endofstreamW[] =
{'E','n','d','O','f','S','t','r','e','a','m',0};
+ UINT i;
+ WICBitmapPattern *patterns;
+ BYTE *patterns_ptr;
+ DWORD length, valuesize;
+
+ res = RegOpenKeyExW(info->classkey, patternsW, 0, KEY_READ, &patternskey);
+ if (res != ERROR_SUCCESS) return;
+
+ res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS)
+ {
+ RegCloseKey(patternskey);
+ return;
+ }
+
+ patterns_size = pattern_count * sizeof(WICBitmapPattern);
+ patterns = heap_alloc(patterns_size);
+ if (!patterns)
+ {
+ RegCloseKey(patternskey);
+ return;
+ }
+
+ for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++)
+ {
+ snprintfW(subkeyname, 11, uintformatW, i);
+ res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
+ if (res != ERROR_SUCCESS) break;
+
+ valuesize = sizeof(ULONG);
+ res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL, &length,
&valuesize);
+ if (res == ERROR_SUCCESS)
+ {
+ patterns_size += length*2;
+ patterns[i].Length = length;
+
+ valuesize = sizeof(BOOL);
+ res = RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
+ &patterns[i].EndOfStream, &valuesize);
+ if (res) patterns[i].EndOfStream = 0;
+
+ patterns[i].Position.QuadPart = 0;
+ valuesize = sizeof(ULARGE_INTEGER);
+ res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD,
NULL,
+ &patterns[i].Position, &valuesize);
+ }
+
+ RegCloseKey(patternkey);
+ }
+
+ if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size)))
+ {
+ heap_free(patterns);
+ RegCloseKey(patternskey);
+ return;
+ }
+ patterns = (WICBitmapPattern*)patterns_ptr;
+ patterns_ptr += pattern_count * sizeof(*patterns);
+
+ for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++)
+ {
+ snprintfW(subkeyname, 11, uintformatW, i);
+ res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
+ if (res != ERROR_SUCCESS) break;
+
+ length = patterns[i].Length;
+ patterns[i].Pattern = patterns_ptr;
+ valuesize = length;
+ res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
+ patterns[i].Pattern, &valuesize);
+ patterns_ptr += length;
+
+ if (res == ERROR_SUCCESS)
+ {
+ patterns[i].Mask = patterns_ptr;
+ valuesize = length;
+ res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
+ patterns[i].Mask, &valuesize);
+ patterns_ptr += length;
+ }
+
+ RegCloseKey(patternkey);
+ }
+
+ RegCloseKey(patternskey);
+
+ if (res != ERROR_SUCCESS)
+ {
+ heap_free(patterns);
+ return;
+ }
+
+ info->pattern_count = pattern_count;
+ info->patterns_size = patterns_size;
+ info->patterns = patterns;
+}
+
+static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, ComponentInfo
**ret)
{
BitmapDecoderInfo *This;
- This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
+ This = heap_alloc_zero(sizeof(BitmapDecoderInfo));
if (!This)
{
RegCloseKey(classkey);
return E_OUTOFMEMORY;
}
- This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
- This->ref = 1;
+ This->base.IWICComponentInfo_iface.lpVtbl = (const
IWICComponentInfoVtbl*)&BitmapDecoderInfo_Vtbl;
+ This->base.ref = 1;
This->classkey = classkey;
- memcpy(&This->clsid, clsid, sizeof(CLSID));
+ This->base.clsid = *clsid;
+
+ read_bitmap_patterns(This);
- *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapDecoderInfo_iface;
+ *ret = &This->base;
return S_OK;
}
typedef struct {
- IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
- LONG ref;
+ ComponentInfo base;
HKEY classkey;
- CLSID clsid;
} BitmapEncoderInfo;
static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo
*iface)
{
- return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
+ return CONTAINING_RECORD(iface, BitmapEncoderInfo, base.IWICComponentInfo_iface);
}
static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface,
REFIID iid,
@@ -698,7 +729,7 @@ static HRESULT WINAPI
BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *if
IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
{
- *ppv = &This->IWICBitmapEncoderInfo_iface;
+ *ppv = &This->base.IWICComponentInfo_iface;
}
else
{
@@ -713,7 +744,7 @@ static HRESULT WINAPI
BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *if
static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
{
BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -723,7 +754,7 @@ static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo
*iface)
static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
{
BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ ULONG ref = InterlockedDecrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -753,8 +784,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo
*iface, C
if (!pclsid)
return E_INVALIDARG;
- memcpy(pclsid, &This->clsid, sizeof(CLSID));
-
+ *pclsid = This->base.clsid;
return S_OK;
}
@@ -918,7 +948,7 @@ static HRESULT WINAPI
BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *if
TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
- return create_instance(&This->clsid, &IID_IWICBitmapEncoder,
(void**)ppIBitmapEncoder);
+ return create_instance(&This->base.clsid, &IID_IWICBitmapEncoder,
(void**)ppIBitmapEncoder);
}
static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
@@ -948,7 +978,7 @@ static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
BitmapEncoderInfo_CreateInstance
};
-static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid,
IWICComponentInfo **ppIInfo)
+static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, ComponentInfo
**ret)
{
BitmapEncoderInfo *This;
@@ -959,25 +989,23 @@ static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID
clsid, IWIC
return E_OUTOFMEMORY;
}
- This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
- This->ref = 1;
+ This->base.IWICComponentInfo_iface.lpVtbl = (const
IWICComponentInfoVtbl*)&BitmapEncoderInfo_Vtbl;
+ This->base.ref = 1;
This->classkey = classkey;
- memcpy(&This->clsid, clsid, sizeof(CLSID));
+ This->base.clsid = *clsid;
- *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapEncoderInfo_iface;
+ *ret = &This->base;
return S_OK;
}
typedef struct {
- IWICFormatConverterInfo IWICFormatConverterInfo_iface;
- LONG ref;
+ ComponentInfo base;
HKEY classkey;
- CLSID clsid;
} FormatConverterInfo;
static inline FormatConverterInfo
*impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
{
- return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
+ return CONTAINING_RECORD(iface, FormatConverterInfo, base.IWICComponentInfo_iface);
}
static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface,
REFIID iid,
@@ -992,7 +1020,7 @@ static HRESULT WINAPI
FormatConverterInfo_QueryInterface(IWICFormatConverterInfo
IsEqualIID(&IID_IWICComponentInfo, iid) ||
IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
{
- *ppv = &This->IWICFormatConverterInfo_iface;
+ *ppv = &This->base.IWICComponentInfo_iface;
}
else
{
@@ -1007,7 +1035,7 @@ static HRESULT WINAPI
FormatConverterInfo_QueryInterface(IWICFormatConverterInfo
static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
{
FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -1017,7 +1045,7 @@ static ULONG WINAPI
FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
{
FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ ULONG ref = InterlockedDecrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -1047,8 +1075,7 @@ static HRESULT WINAPI
FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *ifac
if (!pclsid)
return E_INVALIDARG;
- memcpy(pclsid, &This->clsid, sizeof(CLSID));
-
+ *pclsid = This->base.clsid;
return S_OK;
}
@@ -1125,7 +1152,7 @@ static HRESULT WINAPI
FormatConverterInfo_CreateInstance(IWICFormatConverterInfo
TRACE("(%p,%p)\n", iface, ppIFormatConverter);
- return create_instance(&This->clsid, &IID_IWICFormatConverter,
+ return create_instance(&This->base.clsid, &IID_IWICFormatConverter,
(void**)ppIFormatConverter);
}
@@ -1165,7 +1192,7 @@ static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl =
{
FormatConverterInfo_CreateInstance
};
-static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid,
IWICComponentInfo **ppIInfo)
+static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid,
ComponentInfo **ret)
{
FormatConverterInfo *This;
@@ -1176,25 +1203,23 @@ static HRESULT FormatConverterInfo_Constructor(HKEY classkey,
REFCLSID clsid, IW
return E_OUTOFMEMORY;
}
- This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
- This->ref = 1;
+ This->base.IWICComponentInfo_iface.lpVtbl = (const
IWICComponentInfoVtbl*)&FormatConverterInfo_Vtbl;
+ This->base.ref = 1;
This->classkey = classkey;
- memcpy(&This->clsid, clsid, sizeof(CLSID));
+ This->base.clsid = *clsid;
- *ppIInfo = (IWICComponentInfo *)&This->IWICFormatConverterInfo_iface;
+ *ret = &This->base;
return S_OK;
}
typedef struct {
- IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
- LONG ref;
+ ComponentInfo base;
HKEY classkey;
- CLSID clsid;
} PixelFormatInfo;
static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2
*iface)
{
- return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
+ return CONTAINING_RECORD(iface, PixelFormatInfo, base.IWICComponentInfo_iface);
}
static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID
iid,
@@ -1210,7 +1235,7 @@ static HRESULT WINAPI
PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface
IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
{
- *ppv = &This->IWICPixelFormatInfo2_iface;
+ *ppv = &This->base.IWICComponentInfo_iface;
}
else
{
@@ -1225,7 +1250,7 @@ static HRESULT WINAPI
PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface
static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
{
PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -1235,7 +1260,7 @@ static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2
*iface)
static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
{
PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ ULONG ref = InterlockedDecrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@@ -1265,8 +1290,7 @@ static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2
*iface, CLSI
if (!pclsid)
return E_INVALIDARG;
- memcpy(pclsid, &This->clsid, sizeof(CLSID));
-
+ *pclsid = This->base.clsid;
return S_OK;
}
@@ -1345,8 +1369,7 @@ static HRESULT WINAPI
PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
if (!pFormat)
return E_INVALIDARG;
- *pFormat = This->clsid;
-
+ *pFormat = This->base.clsid;
return S_OK;
}
@@ -1459,7 +1482,7 @@ static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
PixelFormatInfo_GetNumericRepresentation
};
-static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid,
IWICComponentInfo **ppIInfo)
+static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, ComponentInfo
**ret)
{
PixelFormatInfo *This;
@@ -1470,26 +1493,45 @@ static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID
clsid, IWICCo
return E_OUTOFMEMORY;
}
- This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
- This->ref = 1;
+ This->base.IWICComponentInfo_iface.lpVtbl = (const
IWICComponentInfoVtbl*)&PixelFormatInfo_Vtbl;
+ This->base.ref = 1;
This->classkey = classkey;
- memcpy(&This->clsid, clsid, sizeof(CLSID));
+ This->base.clsid = *clsid;
- *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface;
+ *ret = &This->base;
return S_OK;
}
+struct metadata_container
+{
+ WICMetadataPattern *patterns;
+ UINT pattern_count;
+ UINT patterns_size;
+};
+
typedef struct
{
- IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
- LONG ref;
+ ComponentInfo base;
HKEY classkey;
- CLSID clsid;
+ GUID *container_formats;
+ struct metadata_container *containers;
+ UINT container_count;
} MetadataReaderInfo;
+static struct metadata_container *get_metadata_container(MetadataReaderInfo *info, const
GUID *guid)
+{
+ unsigned i;
+
+ for (i = 0; i < info->container_count; i++)
+ if (IsEqualGUID(info->container_formats + i, guid))
+ return info->containers + i;
+
+ return NULL;
+}
+
static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo
*iface)
{
- return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
+ return CONTAINING_RECORD(iface, MetadataReaderInfo, base.IWICComponentInfo_iface);
}
static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
@@ -1506,7 +1548,7 @@ static HRESULT WINAPI
MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *
IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
{
- *ppv = &This->IWICMetadataReaderInfo_iface;
+ *ppv = &This->base.IWICComponentInfo_iface;
}
else
{
@@ -1521,7 +1563,7 @@ static HRESULT WINAPI
MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *
static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
{
MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
@@ -1530,13 +1572,18 @@ static ULONG WINAPI
MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
{
MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ ULONG ref = InterlockedDecrement(&This->base.ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (!ref)
{
+ unsigned i;
RegCloseKey(This->classkey);
+ for (i = 0; i < This->container_count; i++)
+ heap_free(This->containers[i].patterns);
+ heap_free(This->containers);
+ heap_free(This->container_formats);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@@ -1560,7 +1607,7 @@ static HRESULT WINAPI
MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
TRACE("(%p,%p)\n", iface, clsid);
if (!clsid) return E_INVALIDARG;
- *clsid = This->clsid;
+ *clsid = This->base.clsid;
return S_OK;
}
@@ -1637,10 +1684,20 @@ static HRESULT WINAPI
MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderI
UINT length, GUID *formats, UINT *actual_length)
{
MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
+
TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length);
- return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length,
- formats, actual_length);
+ if (!actual_length)
+ return E_INVALIDARG;
+
+ *actual_length = This->container_count;
+ if (formats)
+ {
+ if (This->container_count && length < This->container_count)
+ return WINCODEC_ERR_INSUFFICIENTBUFFER;
+ memcpy(formats, This->container_formats, This->container_count);
+ }
+ return S_OK;
}
static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo
*iface,
@@ -1681,122 +1738,35 @@ static HRESULT WINAPI
MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReader
}
static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
- REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT
*actual_length)
+ REFGUID container_guid, UINT length, WICMetadataPattern *patterns, UINT *count, UINT
*actual_length)
{
MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
- HRESULT hr=S_OK;
- LONG res;
- UINT pattern_count=0, patterns_size=0;
- DWORD valuesize, patternsize;
- BYTE *bPatterns=(BYTE*)patterns;
- HKEY containers_key, guid_key, pattern_key;
- WCHAR subkeyname[11];
- WCHAR guidkeyname[39];
- int i;
- static const WCHAR uintformatW[] = {'%','u',0};
- static const WCHAR patternW[] =
{'P','a','t','t','e','r','n',0};
- static const WCHAR positionW[] =
{'P','o','s','i','t','i','o','n',0};
- static const WCHAR maskW[] = {'M','a','s','k',0};
- static const WCHAR dataoffsetW[] =
{'D','a','t','a','O','f','f','s','e','t',0};
-
- TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length,
patterns, count, actual_length);
+ struct metadata_container *container;
- if (!actual_length || !container) return E_INVALIDARG;
-
- res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ,
&containers_key);
- if (res == ERROR_SUCCESS)
- {
- StringFromGUID2(container, guidkeyname, 39);
-
- res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
- if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
- else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
-
- RegCloseKey(containers_key);
- }
- else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
- else hr = HRESULT_FROM_WIN32(res);
-
- if (SUCCEEDED(hr))
- {
- res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL,
NULL, NULL, NULL, NULL, NULL, NULL);
- if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
-
- if (SUCCEEDED(hr))
- {
- patterns_size = pattern_count * sizeof(WICMetadataPattern);
+ TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container_guid),
length, patterns, count, actual_length);
- for (i=0; i<pattern_count; i++)
- {
- snprintfW(subkeyname, 11, uintformatW, i);
- res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ,
&pattern_key);
- if (res == ERROR_SUCCESS)
- {
- res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY,
NULL,
- NULL, &patternsize);
- patterns_size += patternsize*2;
-
- if ((length >= patterns_size) && (res == ERROR_SUCCESS))
- {
- patterns[i].Length = patternsize;
-
- patterns[i].DataOffset.QuadPart = 0;
- valuesize = sizeof(ULARGE_INTEGER);
- RegGetValueW(pattern_key, NULL, dataoffsetW,
RRF_RT_DWORD|RRF_RT_QWORD, NULL,
- &patterns[i].DataOffset, &valuesize);
-
- patterns[i].Position.QuadPart = 0;
- valuesize = sizeof(ULARGE_INTEGER);
- res = RegGetValueW(pattern_key, NULL, positionW,
RRF_RT_DWORD|RRF_RT_QWORD, NULL,
- &patterns[i].Position, &valuesize);
-
- if (res == ERROR_SUCCESS)
- {
- patterns[i].Pattern = bPatterns+patterns_size-patternsize*2;
- valuesize = patternsize;
- res = RegGetValueW(pattern_key, NULL, patternW,
RRF_RT_REG_BINARY, NULL,
- patterns[i].Pattern, &valuesize);
- }
-
- if (res == ERROR_SUCCESS)
- {
- patterns[i].Mask = bPatterns+patterns_size-patternsize;
- valuesize = patternsize;
- res = RegGetValueW(pattern_key, NULL, maskW,
RRF_RT_REG_BINARY, NULL,
- patterns[i].Mask, &valuesize);
- }
- }
-
- RegCloseKey(pattern_key);
- }
- if (res != ERROR_SUCCESS)
- {
- hr = HRESULT_FROM_WIN32(res);
- break;
- }
- }
- }
+ if (!actual_length || !container_guid) return E_INVALIDARG;
- RegCloseKey(guid_key);
- }
+ if (!(container = get_metadata_container(This, container_guid)))
+ return WINCODEC_ERR_COMPONENTNOTFOUND;
- if (hr == S_OK)
+ *count = container->pattern_count;
+ *actual_length = container->patterns_size;
+ if (patterns)
{
- *count = pattern_count;
- *actual_length = patterns_size;
- if (patterns && length < patterns_size)
- hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
+ if (container->patterns_size && length <
container->patterns_size)
+ return WINCODEC_ERR_INSUFFICIENTBUFFER;
+ memcpy(patterns, container->patterns, container->patterns_size);
}
-
- return hr;
+ return S_OK;
}
static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
- REFGUID container, IStream *stream, BOOL *matches)
+ REFGUID container_guid, IStream *stream, BOOL *matches)
{
+ MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
+ struct metadata_container *container;
HRESULT hr;
- WICMetadataPattern *patterns;
- UINT pattern_count=0, patterns_size=0;
ULONG datasize=0;
BYTE *data=NULL;
ULONG bytesread;
@@ -1804,24 +1774,18 @@ static HRESULT WINAPI
MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *
LARGE_INTEGER seekpos;
ULONG pos;
- TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream,
matches);
+ TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container_guid), stream,
matches);
- hr = MetadataReaderInfo_GetPatterns(iface, container, 0, NULL, &pattern_count,
&patterns_size);
- if (FAILED(hr)) return hr;
-
- patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
- if (!patterns) return E_OUTOFMEMORY;
-
- hr = MetadataReaderInfo_GetPatterns(iface, container, patterns_size, patterns,
&pattern_count, &patterns_size);
- if (FAILED(hr)) goto end;
+ if (!(container = get_metadata_container(This, container_guid)))
+ return WINCODEC_ERR_COMPONENTNOTFOUND;
- for (i=0; i<pattern_count; i++)
+ for (i=0; i < container->pattern_count; i++)
{
- if (datasize < patterns[i].Length)
+ if (datasize < container->patterns[i].Length)
{
HeapFree(GetProcessHeap(), 0, data);
- datasize = patterns[i].Length;
- data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
+ datasize = container->patterns[i].Length;
+ data = HeapAlloc(GetProcessHeap(), 0, container->patterns[i].Length);
if (!data)
{
hr = E_OUTOFMEMORY;
@@ -1829,21 +1793,21 @@ static HRESULT WINAPI
MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *
}
}
- seekpos.QuadPart = patterns[i].Position.QuadPart;
+ seekpos.QuadPart = container->patterns[i].Position.QuadPart;
hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) break;
- hr = IStream_Read(stream, data, patterns[i].Length, &bytesread);
- if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /*
past end of stream */
+ hr = IStream_Read(stream, data, container->patterns[i].Length,
&bytesread);
+ if (hr == S_FALSE || (hr == S_OK && bytesread !=
container->patterns[i].Length)) /* past end of stream */
continue;
if (FAILED(hr)) break;
- for (pos=0; pos<patterns[i].Length; pos++)
+ for (pos=0; pos < container->patterns[i].Length; pos++)
{
- if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
+ if ((data[pos] & container->patterns[i].Mask[pos]) !=
container->patterns[i].Pattern[pos])
break;
}
- if (pos == patterns[i].Length) /* matches pattern */
+ if (pos == container->patterns[i].Length) /* matches pattern */
{
hr = S_OK;
*matches = TRUE;
@@ -1851,14 +1815,12 @@ static HRESULT WINAPI
MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *
}
}
- if (i == pattern_count) /* does not match any pattern */
+ if (i == container->pattern_count) /* does not match any pattern */
{
hr = S_OK;
*matches = FALSE;
}
-end:
- HeapFree(GetProcessHeap(), 0, patterns);
HeapFree(GetProcessHeap(), 0, data);
return hr;
@@ -1871,7 +1833,7 @@ static HRESULT WINAPI
MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *
TRACE("(%p,%p)\n", iface, reader);
- return create_instance(&This->clsid, &IID_IWICMetadataReader, (void
**)reader);
+ return create_instance(&This->base.clsid, &IID_IWICMetadataReader, (void
**)reader);
}
static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
@@ -1898,23 +1860,180 @@ static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl =
{
MetadataReaderInfo_CreateInstance
};
-static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid,
IWICComponentInfo **info)
+static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_guid,
+ struct metadata_container *container)
+{
+ UINT pattern_count=0, patterns_size=0;
+ WCHAR subkeyname[11], guidkeyname[39];
+ LONG res;
+ HKEY containers_key, guid_key, patternkey;
+ static const WCHAR uintformatW[] = {'%','u',0};
+ static const WCHAR patternW[] =
{'P','a','t','t','e','r','n',0};
+ static const WCHAR positionW[] =
{'P','o','s','i','t','i','o','n',0};
+ static const WCHAR maskW[] = {'M','a','s','k',0};
+ static const WCHAR dataoffsetW[] =
{'D','a','t','a','O','f','f','s','e','t',0};
+ UINT i;
+ WICMetadataPattern *patterns;
+ BYTE *patterns_ptr;
+ DWORD length, valuesize;
+
+ res = RegOpenKeyExW(info->classkey, containers_keyname, 0, KEY_READ,
&containers_key);
+ if (res != ERROR_SUCCESS) return;
+
+ StringFromGUID2(container_guid, guidkeyname, 39);
+ res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
+ RegCloseKey(containers_key);
+ if (res != ERROR_SUCCESS) return;
+
+ res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS)
+ {
+ RegCloseKey(guid_key);
+ return;
+ }
+
+ patterns_size = pattern_count * sizeof(WICMetadataPattern);
+ patterns = heap_alloc(patterns_size);
+ if (!patterns)
+ {
+ RegCloseKey(guid_key);
+ return;
+ }
+
+ for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++)
+ {
+ snprintfW(subkeyname, 11, uintformatW, i);
+ res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey);
+ if (res != ERROR_SUCCESS) break;
+
+ res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, NULL,
&length);
+ if (res == ERROR_SUCCESS)
+ {
+ patterns_size += length*2;
+ patterns[i].Length = length;
+
+ valuesize = sizeof(DWORD64);
+ res = RegGetValueW(patternkey, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD,
NULL,
+ &patterns[i].DataOffset, &valuesize);
+ if (res) patterns[i].DataOffset.QuadPart = 0;
+
+ patterns[i].Position.QuadPart = 0;
+ valuesize = sizeof(DWORD64);
+ res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD,
NULL,
+ &patterns[i].Position, &valuesize);
+ }
+
+ RegCloseKey(patternkey);
+ }
+
+ if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size)))
+ {
+ heap_free(patterns);
+ RegCloseKey(guid_key);
+ return;
+ }
+ patterns = (WICMetadataPattern*)patterns_ptr;
+ patterns_ptr += pattern_count * sizeof(*patterns);
+
+ for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++)
+ {
+ snprintfW(subkeyname, 11, uintformatW, i);
+ res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey);
+ if (res != ERROR_SUCCESS) break;
+
+ length = patterns[i].Length;
+ patterns[i].Pattern = patterns_ptr;
+ valuesize = length;
+ res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
+ patterns[i].Pattern, &valuesize);
+ patterns_ptr += length;
+
+ if (res == ERROR_SUCCESS)
+ {
+ patterns[i].Mask = patterns_ptr;
+ valuesize = length;
+ res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
+ patterns[i].Mask, &valuesize);
+ patterns_ptr += length;
+ }
+
+ RegCloseKey(patternkey);
+ }
+
+ RegCloseKey(guid_key);
+
+ if (res != ERROR_SUCCESS)
+ {
+ heap_free(patterns);
+ return;
+ }
+
+ container->pattern_count = pattern_count;
+ container->patterns_size = patterns_size;
+ container->patterns = patterns;
+}
+
+static BOOL read_metadata_info(MetadataReaderInfo *info)
+{
+ UINT format_count;
+ GUID *formats;
+ HRESULT hr;
+
+ hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, 0, NULL,
&format_count);
+ if (FAILED(hr)) return TRUE;
+
+ formats = heap_calloc(format_count, sizeof(*formats));
+ if (!formats) return FALSE;
+
+ hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, format_count,
formats,
+ &format_count);
+ if (FAILED(hr))
+ {
+ heap_free(formats);
+ return FALSE;
+ }
+
+ info->container_formats = formats;
+ info->container_count = format_count;
+
+ if (format_count)
+ {
+ unsigned i;
+
+ info->containers = heap_calloc(format_count, sizeof(*info->containers));
+ if (!info->containers) return FALSE;
+
+ for (i = 0; i < format_count; i++)
+ read_metadata_patterns(info, info->container_formats + i,
info->containers + i);
+ }
+
+ return TRUE;
+}
+
+static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid,
ComponentInfo **info)
{
MetadataReaderInfo *This;
- This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ This = heap_alloc_zero(sizeof(*This));
if (!This)
{
RegCloseKey(classkey);
return E_OUTOFMEMORY;
}
- This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
- This->ref = 1;
+ This->base.IWICComponentInfo_iface.lpVtbl = (const
IWICComponentInfoVtbl*)&MetadataReaderInfo_Vtbl;
+ This->base.ref = 1;
This->classkey = classkey;
- This->clsid = *clsid;
+ This->base.clsid = *clsid;
+
+ if (!read_metadata_info(This))
+ {
+ IWICComponentInfo_Release(&This->base.IWICComponentInfo_iface);
+ return WINCODEC_ERR_COMPONENTNOTFOUND;
+ }
- *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface;
+ *info = &This->base;
return S_OK;
}
@@ -1924,7 +2043,7 @@ static const WCHAR instance_keyname[] =
{'I','n','s','t','a','n','c','e',0};
struct category {
WICComponentType type;
const GUID *catid;
- HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
+ HRESULT (*constructor)(HKEY,REFCLSID,ComponentInfo**);
};
static const struct category categories[] = {
@@ -1936,8 +2055,27 @@ static const struct category categories[] = {
{0}
};
+static int ComponentInfo_Compare(const void *key, const struct wine_rb_entry *entry)
+{
+ ComponentInfo *info = WINE_RB_ENTRY_VALUE(entry, ComponentInfo, entry);
+ return memcmp(key, &info->clsid, sizeof(info->clsid));
+}
+
+static struct wine_rb_tree component_info_cache = { ComponentInfo_Compare };
+
+static CRITICAL_SECTION component_info_cache_cs;
+static CRITICAL_SECTION_DEBUG component_info_cache_cs_dbg =
+{
+ 0, 0, &component_info_cache_cs,
+ { &component_info_cache_cs_dbg.ProcessLocksList,
&component_info_cache_cs_dbg.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": component_info_cache") }
+};
+static CRITICAL_SECTION component_info_cache_cs = { &component_info_cache_cs_dbg, -1,
0, 0, 0, 0 };
+
HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
+ struct wine_rb_entry *cache_entry;
+ ComponentInfo *info;
HKEY clsidkey;
HKEY classkey;
HKEY catidkey;
@@ -1948,9 +2086,23 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo
**ppIInfo)
BOOL found = FALSE;
HRESULT hr;
+ EnterCriticalSection(&component_info_cache_cs);
+
+ cache_entry = wine_rb_get(&component_info_cache, clsid);
+ if(cache_entry)
+ {
+ info = WINE_RB_ENTRY_VALUE(cache_entry, ComponentInfo, entry);
+ IWICComponentInfo_AddRef(*ppIInfo = &info->IWICComponentInfo_iface);
+ LeaveCriticalSection(&component_info_cache_cs);
+ return S_OK;
+ }
+
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
if (res != ERROR_SUCCESS)
+ {
+ LeaveCriticalSection(&component_info_cache_cs);
return HRESULT_FROM_WIN32(res);
+ }
for (category=categories; category->type; category++)
{
@@ -1979,7 +2131,7 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo
**ppIInfo)
{
res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
if (res == ERROR_SUCCESS)
- hr = category->constructor(classkey, clsid, ppIInfo);
+ hr = category->constructor(classkey, clsid, &info);
else
hr = HRESULT_FROM_WIN32(res);
}
@@ -1991,6 +2143,35 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo
**ppIInfo)
RegCloseKey(clsidkey);
+ if (SUCCEEDED(hr))
+ {
+ wine_rb_put(&component_info_cache, clsid, &info->entry);
+ IWICComponentInfo_AddRef(*ppIInfo = &info->IWICComponentInfo_iface);
+ }
+ LeaveCriticalSection(&component_info_cache_cs);
+ return hr;
+}
+
+void ReleaseComponentInfos(void)
+{
+ ComponentInfo *info, *next_info;
+ WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(info, next_info, &component_info_cache,
ComponentInfo, entry)
+ IWICComponentInfo_Release(&info->IWICComponentInfo_iface);
+}
+
+HRESULT get_decoder_info(const CLSID *clsid, IWICBitmapDecoderInfo **info)
+{
+ IWICComponentInfo *compinfo;
+ HRESULT hr;
+
+ hr = CreateComponentInfo(clsid, &compinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
+ (void **)info);
+
+ IWICComponentInfo_Release(compinfo);
+
return hr;
}
diff --git a/dll/win32/windowscodecs/jpegformat.c b/dll/win32/windowscodecs/jpegformat.c
index 0069bdfd89..26dc76c772 100644
--- a/dll/win32/windowscodecs/jpegformat.c
+++ b/dll/win32/windowscodecs/jpegformat.c
@@ -50,6 +50,7 @@
#include "wincodecs_private.h"
+#include "wine/heap.h"
#include "wine/debug.h"
#include "wine/library.h"
@@ -155,6 +156,7 @@ typedef struct {
struct jpeg_error_mgr jerr;
struct jpeg_source_mgr source_mgr;
BYTE source_buffer[1024];
+ UINT bpp, stride;
BYTE *image_data;
CRITICAL_SECTION lock;
} JpegDecoder;
@@ -303,6 +305,8 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface,
IStream *
int ret;
LARGE_INTEGER seek;
jmp_buf jmpbuf;
+ UINT data_size, i;
+
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
EnterCriticalSection(&This->lock);
@@ -381,6 +385,55 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder
*iface, IStream *
return E_FAIL;
}
+ if (This->cinfo.out_color_space == JCS_GRAYSCALE) This->bpp = 8;
+ else if (This->cinfo.out_color_space == JCS_CMYK) This->bpp = 32;
+ else This->bpp = 24;
+
+ This->stride = (This->bpp * This->cinfo.output_width + 7) / 8;
+ data_size = This->stride * This->cinfo.output_height;
+
+ This->image_data = heap_alloc(data_size);
+ if (!This->image_data)
+ {
+ LeaveCriticalSection(&This->lock);
+ return E_OUTOFMEMORY;
+ }
+
+ while (This->cinfo.output_scanline < This->cinfo.output_height)
+ {
+ UINT first_scanline = This->cinfo.output_scanline;
+ UINT max_rows;
+ JSAMPROW out_rows[4];
+ JDIMENSION ret;
+
+ max_rows = min(This->cinfo.output_height-first_scanline, 4);
+ for (i=0; i<max_rows; i++)
+ out_rows[i] = This->image_data + This->stride * (first_scanline+i);
+
+ ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows);
+ if (ret == 0)
+ {
+ ERR("read_scanlines failed\n");
+ LeaveCriticalSection(&This->lock);
+ return E_FAIL;
+ }
+ }
+
+ if (This->bpp == 24)
+ {
+ /* libjpeg gives us RGB data and we want BGR, so byteswap the data */
+ reverse_bgr8(3, This->image_data,
+ This->cinfo.output_width, This->cinfo.output_height,
+ This->stride);
+ }
+
+ if (This->cinfo.out_color_space == JCS_CMYK &&
This->cinfo.saw_Adobe_marker)
+ {
+ /* Adobe JPEG's have inverted CMYK data. */
+ for (i=0; i<data_size; i++)
+ This->image_data[i] ^= 0xff;
+ }
+
This->initialized = TRUE;
LeaveCriticalSection(&This->lock);
@@ -398,20 +451,9 @@ static HRESULT WINAPI
JpegDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI JpegDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICJpegDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICJpegDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface,
@@ -601,104 +643,11 @@ static HRESULT WINAPI
JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
- UINT bpp;
- UINT stride;
- UINT data_size;
- UINT max_row_needed;
- jmp_buf jmpbuf;
- WICRect rect;
- TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
-
- if (!prc)
- {
- rect.X = 0;
- rect.Y = 0;
- rect.Width = This->cinfo.output_width;
- rect.Height = This->cinfo.output_height;
- prc = ▭
- }
- else
- {
- if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width >
This->cinfo.output_width ||
- prc->Y+prc->Height > This->cinfo.output_height)
- return E_INVALIDARG;
- }
-
- if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8;
- else if (This->cinfo.out_color_space == JCS_CMYK) bpp = 32;
- else bpp = 24;
-
- stride = bpp * This->cinfo.output_width;
- data_size = stride * This->cinfo.output_height;
- max_row_needed = prc->Y + prc->Height;
- if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG;
-
- EnterCriticalSection(&This->lock);
-
- if (!This->image_data)
- {
- This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size);
- if (!This->image_data)
- {
- LeaveCriticalSection(&This->lock);
- return E_OUTOFMEMORY;
- }
- }
-
- This->cinfo.client_data = jmpbuf;
-
- if (setjmp(jmpbuf))
- {
- LeaveCriticalSection(&This->lock);
- return E_FAIL;
- }
-
- while (max_row_needed > This->cinfo.output_scanline)
- {
- UINT first_scanline = This->cinfo.output_scanline;
- UINT max_rows;
- JSAMPROW out_rows[4];
- UINT i;
- JDIMENSION ret;
-
- max_rows = min(This->cinfo.output_height-first_scanline, 4);
- for (i=0; i<max_rows; i++)
- out_rows[i] = This->image_data + stride * (first_scanline+i);
-
- ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows);
-
- if (ret == 0)
- {
- ERR("read_scanlines failed\n");
- LeaveCriticalSection(&This->lock);
- return E_FAIL;
- }
-
- if (bpp == 24)
- {
- /* libjpeg gives us RGB data and we want BGR, so byteswap the data */
- reverse_bgr8(3, This->image_data + stride * first_scanline,
- This->cinfo.output_width, This->cinfo.output_scanline -
first_scanline,
- stride);
- }
-
- if (This->cinfo.out_color_space == JCS_CMYK &&
This->cinfo.saw_Adobe_marker)
- {
- DWORD *pDwordData = (DWORD*) (This->image_data + stride *
first_scanline);
- DWORD *pDwordDataEnd = (DWORD*) (This->image_data +
This->cinfo.output_scanline * stride);
-
- /* Adobe JPEG's have inverted CMYK data. */
- while(pDwordData < pDwordDataEnd)
- *pDwordData++ ^= 0xffffffff;
- }
-
- }
-
- LeaveCriticalSection(&This->lock);
+ TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
- return copy_pixels(bpp, This->image_data,
- This->cinfo.output_width, This->cinfo.output_height, stride,
+ return copy_pixels(This->bpp, This->image_data,
+ This->cinfo.output_width, This->cinfo.output_height, This->stride,
prc, cbStride, cbBufferSize, pbBuffer);
}
diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c
index 3bed56536c..6f781b812b 100644
--- a/dll/win32/windowscodecs/main.c
+++ b/dll/win32/windowscodecs/main.c
@@ -42,6 +42,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID
lpvReserved)
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
break;
+ case DLL_PROCESS_DETACH:
+ ReleaseComponentInfos();
+ break;
}
return WIC_DllMain(hinstDLL, fdwReason, lpvReserved);
diff --git a/dll/win32/windowscodecs/pngformat.c b/dll/win32/windowscodecs/pngformat.c
index 54be5edb45..42c905cdac 100644
--- a/dll/win32/windowscodecs/pngformat.c
+++ b/dll/win32/windowscodecs/pngformat.c
@@ -829,20 +829,9 @@ static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder
*iface,
static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICPngDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICPngDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dll/win32/windowscodecs/precomp.h b/dll/win32/windowscodecs/precomp.h
index 7f4c241216..144e085e44 100644
--- a/dll/win32/windowscodecs/precomp.h
+++ b/dll/win32/windowscodecs/precomp.h
@@ -25,6 +25,7 @@
#include "wincodecs_private.h"
#include <wine/debug.h>
+#include <wine/heap.h>
#include <wine/library.h>
#endif /* !WINCODECS_PRECOMP_H */
diff --git a/dll/win32/windowscodecs/tgaformat.c b/dll/win32/windowscodecs/tgaformat.c
index ec7fa23169..b3d9aeae26 100644
--- a/dll/win32/windowscodecs/tgaformat.c
+++ b/dll/win32/windowscodecs/tgaformat.c
@@ -360,20 +360,9 @@ static HRESULT WINAPI TgaDecoder_GetContainerFormat(IWICBitmapDecoder
*iface,
static HRESULT WINAPI TgaDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WineTgaDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WineTgaDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI TgaDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c
index c23594f61f..d1ee44087f 100644
--- a/dll/win32/windowscodecs/tiffformat.c
+++ b/dll/win32/windowscodecs/tiffformat.c
@@ -738,20 +738,9 @@ static HRESULT WINAPI
TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
- HRESULT hr;
- IWICComponentInfo *compinfo;
-
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
- hr = CreateComponentInfo(&CLSID_WICTiffDecoder, &compinfo);
- if (FAILED(hr)) return hr;
-
- hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
- (void**)ppIDecoderInfo);
-
- IWICComponentInfo_Release(compinfo);
-
- return hr;
+ return get_decoder_info(&CLSID_WICTiffDecoder, ppIDecoderInfo);
}
static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
diff --git a/dll/win32/windowscodecs/wincodecs_private.h
b/dll/win32/windowscodecs/wincodecs_private.h
index 2f9f6d0b58..264520492c 100644
--- a/dll/win32/windowscodecs/wincodecs_private.h
+++ b/dll/win32/windowscodecs/wincodecs_private.h
@@ -155,7 +155,7 @@ extern HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv)
DECLSPEC_HIDDE
extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
- UINT stride, UINT datasize, BYTE *bits,
+ UINT stride, UINT datasize, void *view, UINT offset,
REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN;
extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN;
@@ -188,7 +188,9 @@ extern HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT
count,
IPropertyBag2 **property) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
DECLSPEC_HIDDEN;
+extern void ReleaseComponentInfos(void) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options,
IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN;
+extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info)
DECLSPEC_HIDDEN;
typedef struct BmpDecoder BmpDecoder;
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index b3042fd1fb..f78e35a3ba 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -196,7 +196,7 @@ reactos/dll/win32/version # Synced to WineStaging-3.9
reactos/dll/win32/vssapi # Synced to WineStaging-2.9
reactos/dll/win32/wbemdisp # Synced to WineStaging-3.3
reactos/dll/win32/wbemprox # Synced to WineStaging-3.9
-reactos/dll/win32/windowscodecs # Synced to WineStaging-3.3
+reactos/dll/win32/windowscodecs # Synced to WineStaging-3.9
reactos/dll/win32/windowscodecsext # Synced to WineStaging-2.9
reactos/dll/win32/winemp3.acm # Synced to WineStaging-3.3
reactos/dll/win32/wing32 # Synced to WineStaging-3.3