windowscodecs: Create a IWICMetadataReader when loading a TIFF frame.

Dmitry Timoshkov dmitry at baikal.ru
Mon Jun 18 04:26:44 CDT 2012


---
 dlls/windowscodecs/tiffformat.c | 76 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 6 deletions(-)

diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 669351d..006a618 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -58,9 +58,10 @@ static void *libtiff_handle;
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
 MAKE_FUNCPTR(TIFFClientOpen);
 MAKE_FUNCPTR(TIFFClose);
-MAKE_FUNCPTR(TIFFNumberOfDirectories);
+MAKE_FUNCPTR(TIFFCurrentDirOffset);
 MAKE_FUNCPTR(TIFFGetField);
 MAKE_FUNCPTR(TIFFIsByteSwapped);
+MAKE_FUNCPTR(TIFFNumberOfDirectories);
 MAKE_FUNCPTR(TIFFReadDirectory);
 MAKE_FUNCPTR(TIFFReadEncodedStrip);
 MAKE_FUNCPTR(TIFFReadEncodedTile);
@@ -89,9 +90,10 @@ static void *load_libtiff(void)
     }
         LOAD_FUNCPTR(TIFFClientOpen);
         LOAD_FUNCPTR(TIFFClose);
-        LOAD_FUNCPTR(TIFFNumberOfDirectories);
+        LOAD_FUNCPTR(TIFFCurrentDirOffset);
         LOAD_FUNCPTR(TIFFGetField);
         LOAD_FUNCPTR(TIFFIsByteSwapped);
+        LOAD_FUNCPTR(TIFFNumberOfDirectories);
         LOAD_FUNCPTR(TIFFReadDirectory);
         LOAD_FUNCPTR(TIFFReadEncodedStrip);
         LOAD_FUNCPTR(TIFFReadEncodedTile);
@@ -239,6 +241,7 @@ typedef struct {
     tiff_decode_info decode_info;
     INT cached_tile_x, cached_tile_y;
     BYTE *cached_tile;
+    IWICMetadataReader *metadata_reader;
 } TiffFrameDecode;
 
 static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl;
@@ -695,6 +698,7 @@ static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface,
             result->ref = 1;
             result->parent = This;
             result->index = index;
+            result->metadata_reader = NULL;
             result->decode_info = decode_info;
             result->cached_tile_x = -1;
             result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size);
@@ -732,6 +736,50 @@ static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = {
     TiffDecoder_GetFrame
 };
 
+static void create_metadata_reader(TiffFrameDecode *This)
+{
+    HRESULT hr;
+    LARGE_INTEGER dir_offset;
+    IWICPersistStream *persist;
+
+    /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
+
+    EnterCriticalSection(&This->parent->lock);
+
+    hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IWICMetadataReader, (void **)&This->metadata_reader);
+    if (FAILED(hr))
+    {
+        LeaveCriticalSection(&This->parent->lock);
+        return;
+    }
+    hr = IWICMetadataReader_QueryInterface(This->metadata_reader, &IID_IWICPersistStream, (void **)&persist);
+    if (FAILED(hr))
+    {
+        LeaveCriticalSection(&This->parent->lock);
+        return;
+    }
+
+    dir_offset.QuadPart = pTIFFCurrentDirOffset(This->parent->tiff);
+    hr = IStream_Seek(This->parent->stream, dir_offset, STREAM_SEEK_SET, NULL);
+    if (SUCCEEDED(hr))
+    {
+        BOOL byte_swapped = pTIFFIsByteSwapped(This->parent->tiff);
+#ifdef WORDS_BIGENDIAN
+        DWORD persist_options = byte_swapped ? WICPersistOptionsLittleEndian : WICPersistOptionsBigEndian;
+#else
+        DWORD persist_options = byte_swapped ? WICPersistOptionsBigEndian : WICPersistOptionsLittleEndian;
+#endif
+
+        hr = IWICPersistStream_LoadEx(persist, This->parent->stream, NULL, persist_options);
+        if (FAILED(hr))
+            ERR("IWICPersistStream_LoadEx error %#x\n", hr);
+    }
+
+    IWICPersistStream_Release(persist);
+    LeaveCriticalSection(&This->parent->lock);
+}
+
 static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
     void **ppv)
 {
@@ -748,6 +796,7 @@ static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *ifac
     }
     else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
     {
+        create_metadata_reader(This);
         *ppv = &This->IWICMetadataBlockReader_iface;
     }
     else
@@ -780,6 +829,8 @@ static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface)
     if (ref == 0)
     {
         HeapFree(GetProcessHeap(), 0, This->cached_tile);
+        if (This->metadata_reader)
+            IWICMetadataReader_Release(This->metadata_reader);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -1133,15 +1184,28 @@ static HRESULT WINAPI TiffFrameDecode_Block_GetContainerFormat(IWICMetadataBlock
 static HRESULT WINAPI TiffFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface,
     UINT *count)
 {
-    FIXME("(%p,%p): stub\n", iface, count);
-    return E_NOTIMPL;
+    TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
+
+    TRACE("%p,%p\n", iface, count);
+
+    if (!count) return E_INVALIDARG;
+
+    *count = This->metadata_reader ? 1 : 0;
+    return S_OK;
 }
 
 static HRESULT WINAPI TiffFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
     UINT index, IWICMetadataReader **reader)
 {
-    FIXME("(%p,%u,%p): stub\n", iface, index, reader);
-    return E_NOTIMPL;
+    TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface);
+
+    TRACE("(%p,%u,%p)\n", iface, index, reader);
+
+    if (!reader || index != 0) return E_INVALIDARG;
+
+    IWICMetadataReader_AddRef(This->metadata_reader);
+    *reader = This->metadata_reader;
+    return S_OK;
 }
 
 static HRESULT WINAPI TiffFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface,
-- 
1.7.11




More information about the wine-patches mailing list