Vincent Povirk : windowscodecs: Implement conversion from 32bppBGR to 32bppBGRA.
Alexandre Julliard
julliard at winehq.org
Fri Aug 14 08:59:42 CDT 2009
Module: wine
Branch: master
Commit: d7d3618414c7b9f71bd104495aefda8646aa9fdf
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d7d3618414c7b9f71bd104495aefda8646aa9fdf
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Aug 13 12:31:39 2009 -0500
windowscodecs: Implement conversion from 32bppBGR to 32bppBGRA.
---
dlls/windowscodecs/converter.c | 135 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 129 insertions(+), 6 deletions(-)
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
index 8ed5b86..c6663d7 100644
--- a/dlls/windowscodecs/converter.c
+++ b/dlls/windowscodecs/converter.c
@@ -33,11 +33,77 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+struct FormatConverter;
+
+enum pixelformat {
+ format_32bppBGR,
+ format_32bppBGRA
+};
+
+typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc,
+ UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format);
+
+struct pixelformatinfo {
+ enum pixelformat format;
+ const WICPixelFormatGUID *guid;
+ copyfunc copy_function;
+};
+
typedef struct FormatConverter {
const IWICFormatConverterVtbl *lpVtbl;
LONG ref;
+ IWICBitmapSource *source;
+ const struct pixelformatinfo *dst_format, *src_format;
+ WICBitmapDitherType dither;
+ double alpha_threshold;
+ WICBitmapPaletteType palette_type;
} FormatConverter;
+static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc,
+ UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
+{
+ switch (source_format)
+ {
+ case format_32bppBGR:
+ if (prc)
+ {
+ HRESULT res;
+ UINT x, y;
+
+ res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+ if (FAILED(res)) return res;
+
+ /* set all alpha values to 255 */
+ for (y=0; y<prc->Height; y++)
+ for (x=0; x<prc->Width; x++)
+ pbBuffer[cbStride*y+4*x+3] = 0xff;
+ }
+ return S_OK;
+ case format_32bppBGRA:
+ if (prc)
+ return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+ return S_OK;
+ default:
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+ }
+}
+
+static const struct pixelformatinfo supported_formats[] = {
+ {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, NULL},
+ {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
+ {0}
+};
+
+static const struct pixelformatinfo *get_formatinfo(const WICPixelFormatGUID *format)
+{
+ UINT i;
+
+ for (i=0; supported_formats[i].guid; i++)
+ if (IsEqualGUID(supported_formats[i].guid, format)) return &supported_formats[i];
+
+ return NULL;
+}
+
static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid,
void **ppv)
{
@@ -81,6 +147,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
if (ref == 0)
{
+ if (This->source) IWICBitmapSource_Release(This->source);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -118,26 +185,81 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
- FIXME("(%p,%p,%u,%u,%p): stub\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
- return E_NOTIMPL;
+ FormatConverter *This = (FormatConverter*)iface;
+ TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
+
+ if (This->source)
+ return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
+ pbBuffer, This->src_format->format);
+ else
+ return WINCODEC_ERR_NOTINITIALIZED;
}
static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
{
- FIXME("(%p,%p,%s,%u,%p,%0.1f,%u): stub\n", iface, pISource, debugstr_guid(dstFormat),
+ FormatConverter *This = (FormatConverter*)iface;
+ const struct pixelformatinfo *srcinfo, *dstinfo;
+ static INT fixme=0;
+ GUID srcFormat;
+ HRESULT res;
+
+ TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
- return E_NOTIMPL;
+
+ if (pIPalette && !fixme++) FIXME("ignoring palette");
+
+ if (This->source) return WINCODEC_ERR_WRONGSTATE;
+
+ res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
+ if (FAILED(res)) return res;
+
+ srcinfo = get_formatinfo(&srcFormat);
+ if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+
+ dstinfo = get_formatinfo(dstFormat);
+ if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+
+ if (dstinfo->copy_function)
+ {
+ IWICBitmapSource_AddRef(pISource);
+ This->source = pISource;
+ This->src_format = srcinfo;
+ This->dst_format = dstinfo;
+ This->dither = dither;
+ This->alpha_threshold = alphaThresholdPercent;
+ This->palette_type = paletteTranslate;
+ }
+ else
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+
+ return S_OK;
}
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat,
BOOL *pfCanConvert)
{
- FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(srcPixelFormat),
+ FormatConverter *This = (FormatConverter*)iface;
+ const struct pixelformatinfo *srcinfo, *dstinfo;
+
+ TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat),
debugstr_guid(dstPixelFormat), pfCanConvert);
- return E_NOTIMPL;
+
+ srcinfo = get_formatinfo(srcPixelFormat);
+ if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+
+ dstinfo = get_formatinfo(dstPixelFormat);
+ if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+
+ if (dstinfo->copy_function &&
+ SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format)))
+ *pfCanConvert = TRUE;
+ else
+ *pfCanConvert = FALSE;
+
+ return S_OK;
}
static const IWICFormatConverterVtbl FormatConverter_Vtbl = {
@@ -169,6 +291,7 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
This->lpVtbl = &FormatConverter_Vtbl;
This->ref = 1;
+ This->source = NULL;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
More information about the wine-cvs
mailing list