From 39d79ad2428b4173f7e33fa36c205541a586cdc0 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 11 Aug 2009 16:10:12 -0500 Subject: [PATCH] windowscodecs: implement CreateNewFrame for BMP encoder --- dlls/windowscodecs/Makefile.in | 1 + dlls/windowscodecs/bmpencode.c | 182 +++++++++++++++++++++++++++++++- dlls/windowscodecs/propertybag.c | 148 ++++++++++++++++++++++++++ dlls/windowscodecs/wincodecs_private.h | 2 + 4 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 dlls/windowscodecs/propertybag.c diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in index 3736ed1..3f652e1 100644 --- a/dlls/windowscodecs/Makefile.in +++ b/dlls/windowscodecs/Makefile.in @@ -14,6 +14,7 @@ C_SRCS = \ info.c \ main.c \ palette.c \ + propertybag.c \ regsvr.c @MAKE_DLL_RULES@ diff --git a/dlls/windowscodecs/bmpencode.c b/dlls/windowscodecs/bmpencode.c index ebc124d..9d53c6f 100644 --- a/dlls/windowscodecs/bmpencode.c +++ b/dlls/windowscodecs/bmpencode.c @@ -35,10 +35,159 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +typedef struct BmpFrameEncode { + const IWICBitmapFrameEncodeVtbl *lpVtbl; + LONG ref; + IStream *stream; +} BmpFrameEncode; + +static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, + void **ppv) +{ + BmpFrameEncode *This = (BmpFrameEncode*)iface; + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + *ppv = This; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface) +{ + BmpFrameEncode *This = (BmpFrameEncode*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface) +{ + BmpFrameEncode *This = (BmpFrameEncode*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + { + if (This->stream) IStream_Release(This->stream); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface, + IPropertyBag2 *pIEncoderOptions) +{ + FIXME("(%p,%p): stub\n", iface, pIEncoderOptions); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface, + UINT uiWidth, UINT uiHeight) +{ + FIXME("(%p,%u,%u): stub\n", iface, uiWidth, uiHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, + double dpiX, double dpiY) +{ + FIXME("(%p,%0.2f,%0.2f): stub\n", iface, dpiX, dpiY); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + FIXME("(%p,%s): stub\n", iface, debugstr_guid(pPixelFormat)); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, + IWICPalette *pIPalette) +{ + FIXME("(%p,%p): stub\n", iface, pIPalette); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIThumbnail) +{ + FIXME("(%p,%p): stub\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, + UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) +{ + FIXME("(%p,%u,%u,%u,%p): stub\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIBitmapSource, WICRect *prc) +{ + FIXME("(%p,%p,%p): stub\n", iface, pIBitmapSource, prc); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI BmpFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = { + BmpFrameEncode_QueryInterface, + BmpFrameEncode_AddRef, + BmpFrameEncode_Release, + BmpFrameEncode_Initialize, + BmpFrameEncode_SetSize, + BmpFrameEncode_SetResolution, + BmpFrameEncode_SetPixelFormat, + BmpFrameEncode_SetColorContexts, + BmpFrameEncode_SetPalette, + BmpFrameEncode_SetThumbnail, + BmpFrameEncode_WritePixels, + BmpFrameEncode_WriteSource, + BmpFrameEncode_Commit, + BmpFrameEncode_GetMetadataQueryWriter +}; + typedef struct BmpEncoder { const IWICBitmapEncoderVtbl *lpVtbl; LONG ref; IStream *stream; + IWICBitmapFrameEncode *frame; } BmpEncoder; static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, @@ -84,6 +233,7 @@ static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface) if (ref == 0) { if (This->stream) IStream_Release(This->stream); + if (This->frame) IWICBitmapFrameEncode_Release(This->frame); HeapFree(GetProcessHeap(), 0, This); } @@ -145,8 +295,35 @@ static HRESULT WINAPI BmpEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmap static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) { - FIXME("(%p,%p,%p): stub\n", iface, ppIFrameEncode, ppIEncoderOptions); - return E_NOTIMPL; + BmpEncoder *This = (BmpEncoder*)iface; + BmpFrameEncode *encode; + HRESULT hr; + + TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); + + if (This->frame) return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED; + + hr = CreatePropertyBag2(ppIEncoderOptions); + if (FAILED(hr)) return hr; + + encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode)); + if (!encode) + { + IPropertyBag2_Release(*ppIEncoderOptions); + *ppIEncoderOptions = NULL; + return E_OUTOFMEMORY; + } + encode->lpVtbl = &BmpFrameEncode_Vtbl; + encode->ref = 2; + IStream_AddRef(This->stream); + encode->stream = This->stream; + + *ppIFrameEncode = (IWICBitmapFrameEncode*)encode; + This->frame = (IWICBitmapFrameEncode*)encode; + + return S_OK; } static HRESULT WINAPI BmpEncoder_Commit(IWICBitmapEncoder *iface) @@ -195,6 +372,7 @@ HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) This->lpVtbl = &BmpEncoder_Vtbl; This->ref = 1; This->stream = NULL; + This->frame = NULL; ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); IUnknown_Release((IUnknown*)This); diff --git a/dlls/windowscodecs/propertybag.c b/dlls/windowscodecs/propertybag.c new file mode 100644 index 0000000..e2cbaa2 --- /dev/null +++ b/dlls/windowscodecs/propertybag.c @@ -0,0 +1,148 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "wincodec.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct PropertyBag { + const IPropertyBag2Vtbl *lpVtbl; + LONG ref; +} PropertyBag; + +static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid, + void **ppv) +{ + PropertyBag *This = (PropertyBag*)iface; + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IPropertyBag2, iid)) + { + *ppv = This; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface) +{ + PropertyBag *This = (PropertyBag*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) +{ + PropertyBag *This = (PropertyBag*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, + PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError) +{ + FIXME("(%p,%u,%p,%p,%p,%p): stub\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); + return E_NOTIMPL; +} + +static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, + PROPBAG2 *pPropBag, VARIANT *pvarValue) +{ + FIXME("(%p,%u,%p,%p): stub\n", iface, cProperties, pPropBag, pvarValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties) +{ + FIXME("(%p,%p): stub\n", iface, pcProperties); + return E_NOTIMPL; +} + +static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, + ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties) +{ + FIXME("(%p,%u,%u,%p,%p): stub\n", iface, iProperty, cProperties, pPropBag, pcProperties); + return E_NOTIMPL; +} + +static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, + DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog) +{ + FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog); + return E_NOTIMPL; +} + +static const IPropertyBag2Vtbl PropertyBag_Vtbl = { + PropertyBag_QueryInterface, + PropertyBag_AddRef, + PropertyBag_Release, + PropertyBag_Read, + PropertyBag_Write, + PropertyBag_CountProperties, + PropertyBag_GetPropertyInfo, + PropertyBag_LoadObject +}; + +extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2) +{ + PropertyBag *This; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag)); + if (!This) return E_OUTOFMEMORY; + + This->lpVtbl = &PropertyBag_Vtbl; + This->ref = 1; + + *ppPropertyBag2 = (IPropertyBag2*)This; + + return S_OK; +} + diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 93bb09d..680dc23 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -29,6 +29,8 @@ extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, UINT srcwidth, UINT srcheight, INT srcstride, const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer); +extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2); + extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo); extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown); -- 1.5.4.3