Vincent Povirk : windowscodecs: Implement TiffEncoder_CreateNewFrame.
Alexandre Julliard
julliard at winehq.org
Wed Apr 6 11:36:35 CDT 2011
Module: wine
Branch: master
Commit: c876357c11ea63a56d15ff001963fa0d11eb6123
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c876357c11ea63a56d15ff001963fa0d11eb6123
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Tue Mar 29 16:24:19 2011 -0500
windowscodecs: Implement TiffEncoder_CreateNewFrame.
---
dlls/windowscodecs/tiffformat.c | 214 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 211 insertions(+), 3 deletions(-)
diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index b1d472d..98e2376 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -64,6 +64,7 @@ MAKE_FUNCPTR(TIFFReadDirectory);
MAKE_FUNCPTR(TIFFReadEncodedStrip);
MAKE_FUNCPTR(TIFFReadEncodedTile);
MAKE_FUNCPTR(TIFFSetDirectory);
+MAKE_FUNCPTR(TIFFWriteDirectory);
#undef MAKE_FUNCPTR
static void *load_libtiff(void)
@@ -92,6 +93,7 @@ static void *load_libtiff(void)
LOAD_FUNCPTR(TIFFReadEncodedStrip);
LOAD_FUNCPTR(TIFFReadEncodedTile);
LOAD_FUNCPTR(TIFFSetDirectory);
+ LOAD_FUNCPTR(TIFFWriteDirectory);
#undef LOAD_FUNCPTR
}
@@ -1118,9 +1120,11 @@ typedef struct TiffEncoder {
IWICBitmapEncoder IWICBitmapEncoder_iface;
LONG ref;
IStream *stream;
- CRITICAL_SECTION lock; /* Must be held when tiff is used or initiailzed is set */
+ CRITICAL_SECTION lock; /* Must be held when tiff is used or fields below are set */
TIFF *tiff;
BOOL initialized;
+ ULONG num_frames;
+ ULONG num_frames_committed;
} TiffEncoder;
static inline TiffEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
@@ -1128,6 +1132,159 @@ static inline TiffEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
return CONTAINING_RECORD(iface, TiffEncoder, IWICBitmapEncoder_iface);
}
+typedef struct TiffFrameEncode {
+ IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
+ LONG ref;
+ TiffEncoder *parent;
+} TiffFrameEncode;
+
+static inline TiffFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
+{
+ return CONTAINING_RECORD(iface, TiffFrameEncode, IWICBitmapFrameEncode_iface);
+}
+
+static HRESULT WINAPI TiffFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
+ void **ppv)
+{
+ TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(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->IWICBitmapFrameEncode_iface;
+ }
+ else
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI TiffFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
+{
+ TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI TiffFrameEncode_Release(IWICBitmapFrameEncode *iface)
+{
+ TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) refcount=%u\n", iface, ref);
+
+ if (ref == 0)
+ {
+ IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI TiffFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
+ IPropertyBag2 *pIEncoderOptions)
+{
+ FIXME("(%p,%p): stub\n", iface, pIEncoderOptions);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
+ UINT uiWidth, UINT uiHeight)
+{
+ FIXME("(%p,%u,%u): stub\n", iface, uiWidth, uiHeight);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
+ double dpiX, double dpiY)
+{
+ FIXME("(%p,%0.2f,%0.2f): stub\n", iface, dpiX, dpiY);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
+ WICPixelFormatGUID *pPixelFormat)
+{
+ FIXME("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
+ UINT cCount, IWICColorContext **ppIColorContext)
+{
+ FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
+ IWICPalette *pIPalette)
+{
+ FIXME("(%p,%p): stub\n", iface, pIPalette);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI TiffFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
+ IWICBitmapSource *pIThumbnail)
+{
+ FIXME("(%p,%p): stub\n", iface, pIThumbnail);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI TiffFrameEncode_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 TiffFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
+ IWICBitmapSource *pIBitmapSource, WICRect *prc)
+{
+ FIXME("(%p,%p,%p): stub\n", iface, pIBitmapSource, prc);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_Commit(IWICBitmapFrameEncode *iface)
+{
+ FIXME("(%p): stub\n", iface);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TiffFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
+ IWICMetadataQueryWriter **ppIMetadataQueryWriter)
+{
+ FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
+ return E_NOTIMPL;
+}
+
+static const IWICBitmapFrameEncodeVtbl TiffFrameEncode_Vtbl = {
+ TiffFrameEncode_QueryInterface,
+ TiffFrameEncode_AddRef,
+ TiffFrameEncode_Release,
+ TiffFrameEncode_Initialize,
+ TiffFrameEncode_SetSize,
+ TiffFrameEncode_SetResolution,
+ TiffFrameEncode_SetPixelFormat,
+ TiffFrameEncode_SetColorContexts,
+ TiffFrameEncode_SetPalette,
+ TiffFrameEncode_SetThumbnail,
+ TiffFrameEncode_WritePixels,
+ TiffFrameEncode_WriteSource,
+ TiffFrameEncode_Commit,
+ TiffFrameEncode_GetMetadataQueryWriter
+};
+
static HRESULT WINAPI TiffEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
{
@@ -1257,8 +1414,57 @@ static HRESULT WINAPI TiffEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitma
static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
- FIXME("(%p,%p,%p): stub\n", iface, ppIFrameEncode, ppIEncoderOptions);
- return E_NOTIMPL;
+ TiffEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ TiffFrameEncode *result;
+
+ HRESULT hr=S_OK;
+
+ TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->num_frames != This->num_frames_committed)
+ {
+ FIXME("New frame created before previous frame was committed\n");
+ hr = E_FAIL;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CreatePropertyBag2(ppIEncoderOptions);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ result = HeapAlloc(GetProcessHeap(), 0, sizeof(*result));
+
+ if (result)
+ {
+ result->IWICBitmapFrameEncode_iface.lpVtbl = &TiffFrameEncode_Vtbl;
+ result->ref = 1;
+ result->parent = This;
+
+ IWICBitmapEncoder_AddRef(iface);
+ *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface;
+
+ if (This->num_frames != 0)
+ pTIFFWriteDirectory(This->tiff);
+
+ This->num_frames++;
+ }
+ else
+ hr = E_OUTOFMEMORY;
+
+ if (FAILED(hr))
+ {
+ IPropertyBag2_Release(*ppIEncoderOptions);
+ *ppIEncoderOptions = NULL;
+ }
+ }
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
}
static HRESULT WINAPI TiffEncoder_Commit(IWICBitmapEncoder *iface)
@@ -1317,6 +1523,8 @@ HRESULT TiffEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffEncoder.lock");
This->tiff = NULL;
This->initialized = FALSE;
+ This->num_frames = 0;
+ This->num_frames_committed = 0;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
More information about the wine-cvs
mailing list