windowscodecs: Add locking to the format converter.
This commit is contained in:
parent
7871033a40
commit
c1beb63609
|
@ -71,6 +71,7 @@ typedef struct FormatConverter {
|
||||||
WICBitmapDitherType dither;
|
WICBitmapDitherType dither;
|
||||||
double alpha_threshold;
|
double alpha_threshold;
|
||||||
WICBitmapPaletteType palette_type;
|
WICBitmapPaletteType palette_type;
|
||||||
|
CRITICAL_SECTION lock; /* must be held when initialized */
|
||||||
} FormatConverter;
|
} FormatConverter;
|
||||||
|
|
||||||
static void make_grayscale_palette(WICColor *colors, UINT num_colors)
|
static void make_grayscale_palette(WICColor *colors, UINT num_colors)
|
||||||
|
@ -765,6 +766,8 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
|
||||||
|
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
{
|
{
|
||||||
|
This->lock.DebugInfo->Spare[0] = 0;
|
||||||
|
DeleteCriticalSection(&This->lock);
|
||||||
if (This->source) IWICBitmapSource_Release(This->source);
|
if (This->source) IWICBitmapSource_Release(This->source);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -841,38 +844,56 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||||
const struct pixelformatinfo *srcinfo, *dstinfo;
|
const struct pixelformatinfo *srcinfo, *dstinfo;
|
||||||
static INT fixme=0;
|
static INT fixme=0;
|
||||||
GUID srcFormat;
|
GUID srcFormat;
|
||||||
HRESULT res;
|
HRESULT res=S_OK;
|
||||||
|
|
||||||
TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
||||||
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
||||||
|
|
||||||
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
||||||
|
|
||||||
if (This->source) return WINCODEC_ERR_WRONGSTATE;
|
EnterCriticalSection(&This->lock);
|
||||||
|
|
||||||
|
if (This->source)
|
||||||
|
{
|
||||||
|
res = WINCODEC_ERR_WRONGSTATE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
|
res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
|
||||||
if (FAILED(res)) return res;
|
if (FAILED(res)) goto end;
|
||||||
|
|
||||||
srcinfo = get_formatinfo(&srcFormat);
|
srcinfo = get_formatinfo(&srcFormat);
|
||||||
if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
if (!srcinfo)
|
||||||
|
{
|
||||||
|
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
dstinfo = get_formatinfo(dstFormat);
|
dstinfo = get_formatinfo(dstFormat);
|
||||||
if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
if (!dstinfo)
|
||||||
|
{
|
||||||
|
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (dstinfo->copy_function)
|
if (dstinfo->copy_function)
|
||||||
{
|
{
|
||||||
IWICBitmapSource_AddRef(pISource);
|
IWICBitmapSource_AddRef(pISource);
|
||||||
This->source = pISource;
|
|
||||||
This->src_format = srcinfo;
|
This->src_format = srcinfo;
|
||||||
This->dst_format = dstinfo;
|
This->dst_format = dstinfo;
|
||||||
This->dither = dither;
|
This->dither = dither;
|
||||||
This->alpha_threshold = alphaThresholdPercent;
|
This->alpha_threshold = alphaThresholdPercent;
|
||||||
This->palette_type = paletteTranslate;
|
This->palette_type = paletteTranslate;
|
||||||
|
This->source = pISource;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
res = WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||||
|
|
||||||
return S_OK;
|
end:
|
||||||
|
|
||||||
|
LeaveCriticalSection(&This->lock);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
|
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
|
||||||
|
@ -930,6 +951,8 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
|
||||||
This->lpVtbl = &FormatConverter_Vtbl;
|
This->lpVtbl = &FormatConverter_Vtbl;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
This->source = NULL;
|
This->source = NULL;
|
||||||
|
InitializeCriticalSection(&This->lock);
|
||||||
|
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
|
||||||
|
|
||||||
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
|
||||||
IUnknown_Release((IUnknown*)This);
|
IUnknown_Release((IUnknown*)This);
|
||||||
|
|
|
@ -781,7 +781,7 @@ static struct regsvr_coclass const coclass_list[] = {
|
||||||
"WIC Default Format Converter",
|
"WIC Default Format Converter",
|
||||||
NULL,
|
NULL,
|
||||||
"windowscodecs.dll",
|
"windowscodecs.dll",
|
||||||
"Apartment"
|
"Both"
|
||||||
},
|
},
|
||||||
{ NULL } /* list terminator */
|
{ NULL } /* list terminator */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue