windowscodecs: Add locking to the BMP decoder.

This commit is contained in:
Vincent Povirk 2010-04-09 13:44:23 -05:00 committed by Alexandre Julliard
parent 3d914c4f8d
commit 5f6d99f513
2 changed files with 31 additions and 8 deletions

View File

@ -75,6 +75,7 @@ typedef struct BmpDecoder {
INT stride; INT stride;
BYTE *imagedata; BYTE *imagedata;
BYTE *imagedatastart; BYTE *imagedatastart;
CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */
} BmpDecoder; } BmpDecoder;
static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface) static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
@ -190,6 +191,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
TRACE("(%p,%p)\n", iface, pIPalette); TRACE("(%p,%p)\n", iface, pIPalette);
EnterCriticalSection(&This->lock);
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER)) if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
{ {
BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih; BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
@ -231,7 +234,8 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
} }
else else
{ {
return WINCODEC_ERR_PALETTEUNAVAILABLE; hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
goto end;
} }
} }
else else
@ -249,7 +253,11 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
tablesize = sizeof(WICColor) * count; tablesize = sizeof(WICColor) * count;
wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
if (!wiccolors) return E_OUTOFMEMORY; if (!wiccolors)
{
hr = E_OUTOFMEMORY;
goto end;
}
offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size; offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL); hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
@ -268,13 +276,18 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
} }
else else
{ {
return WINCODEC_ERR_PALETTEUNAVAILABLE; hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
goto end;
} }
} }
hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
end: end:
LeaveCriticalSection(&This->lock);
if (SUCCEEDED(hr))
hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);
HeapFree(GetProcessHeap(), 0, wiccolors); HeapFree(GetProcessHeap(), 0, wiccolors);
HeapFree(GetProcessHeap(), 0, bgrcolors); HeapFree(GetProcessHeap(), 0, bgrcolors);
return hr; return hr;
@ -284,15 +297,17 @@ static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{ {
BmpDecoder *This = impl_from_frame(iface); BmpDecoder *This = impl_from_frame(iface);
HRESULT hr; HRESULT hr=S_OK;
UINT width, height; UINT width, height;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
EnterCriticalSection(&This->lock);
if (!This->imagedata) if (!This->imagedata)
{ {
hr = This->read_data_func(This); hr = This->read_data_func(This);
if (FAILED(hr)) return hr;
} }
LeaveCriticalSection(&This->lock);
if (FAILED(hr)) return hr;
hr = BmpFrameDecode_GetSize(iface, &width, &height); hr = BmpFrameDecode_GetSize(iface, &width, &height);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
@ -854,6 +869,8 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
{ {
if (This->stream) IStream_Release(This->stream); if (This->stream) IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This->imagedata); HeapFree(GetProcessHeap(), 0, This->imagedata);
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
@ -866,7 +883,9 @@ static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre
HRESULT hr; HRESULT hr;
BmpDecoder *This = (BmpDecoder*)iface; BmpDecoder *This = (BmpDecoder*)iface;
EnterCriticalSection(&This->lock);
hr = BmpDecoder_ReadHeaders(This, pIStream); hr = BmpDecoder_ReadHeaders(This, pIStream);
LeaveCriticalSection(&This->lock);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
if (This->read_data_func == BmpFrameDecode_ReadUnsupported) if (This->read_data_func == BmpFrameDecode_ReadUnsupported)
@ -883,6 +902,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
HRESULT hr; HRESULT hr;
BmpDecoder *This = (BmpDecoder*)iface; BmpDecoder *This = (BmpDecoder*)iface;
EnterCriticalSection(&This->lock);
hr = BmpDecoder_ReadHeaders(This, pIStream); hr = BmpDecoder_ReadHeaders(This, pIStream);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -890,6 +910,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
This->stream = pIStream; This->stream = pIStream;
IStream_AddRef(pIStream); IStream_AddRef(pIStream);
} }
LeaveCriticalSection(&This->lock);
return hr; return hr;
} }
@ -1015,6 +1036,8 @@ HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->initialized = FALSE; This->initialized = FALSE;
This->stream = NULL; This->stream = NULL;
This->imagedata = NULL; This->imagedata = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This); IUnknown_Release((IUnknown*)This);

View File

@ -733,7 +733,7 @@ static struct regsvr_coclass const coclass_list[] = {
"WIC BMP Decoder", "WIC BMP Decoder",
NULL, NULL,
"windowscodecs.dll", "windowscodecs.dll",
"Apartment" "Both"
}, },
{ &CLSID_WICPngDecoder, { &CLSID_WICPngDecoder,
"WIC PNG Decoder", "WIC PNG Decoder",