Vincent Povirk : windowscodecs: Implement Initialize for the TIFF decoder.

Alexandre Julliard julliard at winehq.org
Mon Mar 22 11:12:02 CDT 2010


Module: wine
Branch: master
Commit: 0d285eac802829bc333603801067e6176006dc8d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0d285eac802829bc333603801067e6176006dc8d

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Mar 17 15:44:28 2010 -0500

windowscodecs: Implement Initialize for the TIFF decoder.

---

 dlls/windowscodecs/tiffformat.c |  139 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 136 insertions(+), 3 deletions(-)

diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 1c6b75a..38edf70 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -20,7 +20,9 @@
 #include "wine/port.h"
 
 #include <stdarg.h>
-
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #ifdef HAVE_TIFFIO_H
 #include <tiffio.h>
 #endif
@@ -54,6 +56,7 @@ static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
 static void *libtiff_handle;
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
 MAKE_FUNCPTR(TIFFClientOpen);
+MAKE_FUNCPTR(TIFFClose);
 #undef MAKE_FUNCPTR
 
 static void *load_libtiff(void)
@@ -74,6 +77,7 @@ static void *load_libtiff(void)
         return NULL; \
     }
         LOAD_FUNCPTR(TIFFClientOpen);
+        LOAD_FUNCPTR(TIFFClose);
 #undef LOAD_FUNCPTR
 
     }
@@ -84,9 +88,101 @@ static void *load_libtiff(void)
     return result;
 }
 
+static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
+{
+    IStream *stream = (IStream*)client_data;
+    ULONG bytes_read;
+    HRESULT hr;
+
+    hr = IStream_Read(stream, data, size, &bytes_read);
+    if (FAILED(hr)) bytes_read = 0;
+    return bytes_read;
+}
+
+static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
+{
+    IStream *stream = (IStream*)client_data;
+    ULONG bytes_written;
+    HRESULT hr;
+
+    hr = IStream_Write(stream, data, size, &bytes_written);
+    if (FAILED(hr)) bytes_written = 0;
+    return bytes_written;
+}
+
+static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
+{
+    IStream *stream = (IStream*)client_data;
+    LARGE_INTEGER move;
+    DWORD origin;
+    ULARGE_INTEGER new_position;
+    HRESULT hr;
+
+    move.QuadPart = offset;
+    switch (whence)
+    {
+        case SEEK_SET:
+            origin = STREAM_SEEK_SET;
+            break;
+        case SEEK_CUR:
+            origin = STREAM_SEEK_CUR;
+            break;
+        case SEEK_END:
+            origin = STREAM_SEEK_END;
+            break;
+        default:
+            ERR("unknown whence value %i\n", whence);
+            return -1;
+    }
+
+    hr = IStream_Seek(stream, move, origin, &new_position);
+    if (SUCCEEDED(hr)) return new_position.QuadPart;
+    else return -1;
+}
+
+static int tiff_stream_close(thandle_t client_data)
+{
+    /* Caller is responsible for releasing the stream object. */
+    return 0;
+}
+
+static toff_t tiff_stream_size(thandle_t client_data)
+{
+    IStream *stream = (IStream*)client_data;
+    STATSTG statstg;
+    HRESULT hr;
+
+    hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME);
+
+    if (SUCCEEDED(hr)) return statstg.cbSize.QuadPart;
+    else return -1;
+}
+
+static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
+{
+    /* Cannot mmap streams */
+    return 0;
+}
+
+static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
+{
+    /* No need to ever do this, since we can't map things. */
+}
+
+static TIFF* tiff_open_stream(IStream *stream, const char *mode)
+{
+    return pTIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
+        tiff_stream_write, tiff_stream_seek, tiff_stream_close,
+        tiff_stream_size, tiff_stream_map, tiff_stream_unmap);
+}
+
 typedef struct {
     const IWICBitmapDecoderVtbl *lpVtbl;
     LONG ref;
+    IStream *stream;
+    CRITICAL_SECTION lock; /* Must be held when tiff is used or initiailzed is set */
+    TIFF *tiff;
+    BOOL initialized;
 } TiffDecoder;
 
 static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
@@ -130,6 +226,10 @@ static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface)
 
     if (ref == 0)
     {
+        if (This->tiff) pTIFFClose(This->tiff);
+        if (This->stream) IStream_Release(This->stream);
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -146,8 +246,36 @@ static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStr
 static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
     WICDecodeOptions cacheOptions)
 {
-    FIXME("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions);
-    return E_NOTIMPL;
+    TiffDecoder *This = (TiffDecoder*)iface;
+    TIFF *tiff;
+    HRESULT hr=S_OK;
+
+    TRACE("(%p,%p,%x): stub\n", iface, pIStream, cacheOptions);
+
+    EnterCriticalSection(&This->lock);
+
+    if (This->initialized)
+    {
+        hr = WINCODEC_ERR_WRONGSTATE;
+        goto exit;
+    }
+
+    tiff = tiff_open_stream(pIStream, "r");
+
+    if (!tiff)
+    {
+        hr = E_FAIL;
+        goto exit;
+    }
+
+    This->tiff = tiff;
+    This->stream = pIStream;
+    IStream_AddRef(pIStream);
+    This->initialized = TRUE;
+
+exit:
+    LeaveCriticalSection(&This->lock);
+    return hr;
 }
 
 static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
@@ -252,6 +380,11 @@ HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
 
     This->lpVtbl = &TiffDecoder_Vtbl;
     This->ref = 1;
+    This->stream = NULL;
+    InitializeCriticalSection(&This->lock);
+    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock");
+    This->tiff = NULL;
+    This->initialized = FALSE;
 
     ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
     IUnknown_Release((IUnknown*)This);




More information about the wine-cvs mailing list