Dmitry Timoshkov : windowscodecs: Implement Graphic Control Extension metadata reader.

Alexandre Julliard julliard at winehq.org
Tue Sep 11 16:59:06 CDT 2012


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

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Sep 11 16:50:42 2012 +0900

windowscodecs: Implement Graphic Control Extension metadata reader.

---

 dlls/windowscodecs/clsfactory.c               |    1 +
 dlls/windowscodecs/gifformat.c                |   78 +++++++++++++++++++++++++
 dlls/windowscodecs/regsvr.c                   |   25 ++++++++
 dlls/windowscodecs/tests/metadata.c           |    1 -
 dlls/windowscodecs/wincodecs_private.h        |    1 +
 dlls/windowscodecs/windowscodecs_wincodec.idl |    7 ++
 6 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c
index dc70c04..a42aeab 100644
--- a/dlls/windowscodecs/clsfactory.c
+++ b/dlls/windowscodecs/clsfactory.c
@@ -64,6 +64,7 @@ static const classinfo wic_classes[] = {
     {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
     {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
     {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
+    {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance},
     {0}};
 
 typedef struct {
diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c
index f6a7d27..318dc5d 100644
--- a/dlls/windowscodecs/gifformat.c
+++ b/dlls/windowscodecs/gifformat.c
@@ -240,6 +240,84 @@ HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
     return MetadataReader_Create(&IMDReader_Vtbl, pUnkOuter, iid, ppv);
 }
 
+static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options,
+                                 MetadataItem **items, DWORD *count)
+{
+#include "pshpack1.h"
+    struct graphic_control_extenstion
+    {
+        BYTE packed;
+        /* reservred: 3;
+         * disposal : 3;
+         * user_input_flag : 1;
+         * transparency_flag : 1;
+         */
+         USHORT delay;
+         BYTE transparent_color_index;
+    } gce_data;
+#include "poppack.h"
+    HRESULT hr;
+    ULONG bytesread, i;
+    MetadataItem *result;
+
+    *items = NULL;
+    *count = 0;
+
+    hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread);
+    if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK;
+
+    result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 5);
+    if (!result) return E_OUTOFMEMORY;
+
+    for (i = 0; i < 5; i++)
+    {
+        PropVariantInit(&result[i].schema);
+        PropVariantInit(&result[i].id);
+        PropVariantInit(&result[i].value);
+    }
+
+    result[0].id.vt = VT_LPWSTR;
+    result[0].id.u.pwszVal = strdupAtoW("Disposal");
+    result[0].value.vt = VT_UI1;
+    result[0].value.u.bVal = (gce_data.packed >> 2) & 7;
+
+    result[1].id.vt = VT_LPWSTR;
+    result[1].id.u.pwszVal = strdupAtoW("UserInputFlag");
+    result[1].value.vt = VT_BOOL;
+    result[1].value.u.boolVal = (gce_data.packed >> 1) & 1;
+
+    result[2].id.vt = VT_LPWSTR;
+    result[2].id.u.pwszVal = strdupAtoW("TransparencyFlag");
+    result[2].value.vt = VT_BOOL;
+    result[2].value.u.boolVal = gce_data.packed & 1;
+
+    result[3].id.vt = VT_LPWSTR;
+    result[3].id.u.pwszVal = strdupAtoW("Delay");
+    result[3].value.vt = VT_UI2;
+    result[3].value.u.uiVal = gce_data.delay;
+
+    result[4].id.vt = VT_LPWSTR;
+    result[4].id.u.pwszVal = strdupAtoW("TransparentColorIndex");
+    result[4].value.vt = VT_UI1;
+    result[4].value.u.bVal = gce_data.transparent_color_index;
+
+    *items = result;
+    *count = 5;
+
+    return S_OK;
+}
+
+static const MetadataHandlerVtbl GCEReader_Vtbl = {
+    0,
+    &CLSID_WICGCEMetadataReader,
+    load_GCE_metadata
+};
+
+HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
+{
+    return MetadataReader_Create(&GCEReader_Vtbl, pUnkOuter, iid, ppv);
+}
+
 typedef struct {
     IWICBitmapDecoder IWICBitmapDecoder_iface;
     LONG ref;
diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c
index c232778..a7ac4b2 100644
--- a/dlls/windowscodecs/regsvr.c
+++ b/dlls/windowscodecs/regsvr.c
@@ -1547,6 +1547,21 @@ static const struct reader_containers imd_containers[] = {
     { NULL } /* list terminator */
 };
 
+static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
+
+static const struct metadata_pattern gce_metadata_pattern[] = {
+    { 0, 3, gce_magic, mask_all, 3 },
+    { 0 }
+};
+
+static const struct reader_containers gce_containers[] = {
+    {
+        &GUID_ContainerFormatGif,
+        gce_metadata_pattern
+    },
+    { NULL } /* list terminator */
+};
+
 static struct regsvr_metadatareader const metadatareader_list[] = {
     {   &CLSID_WICUnknownMetadataReader,
         "The Wine Project",
@@ -1598,6 +1613,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
         0, 0, 0,
         imd_containers
     },
+    {   &CLSID_WICGCEMetadataReader,
+        "The Wine Project",
+        "Graphic Control Extension Reader",
+        "1.0.0.0",
+        "1.0.0.0",
+        &GUID_VendorMicrosoft,
+        &GUID_MetadataFormatGCE,
+        0, 0, 0,
+        gce_containers
+    },
     { NULL }			/* list terminator */
 };
 
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c
index bfa9116..e274106 100644
--- a/dlls/windowscodecs/tests/metadata.c
+++ b/dlls/windowscodecs/tests/metadata.c
@@ -1440,7 +1440,6 @@ static void test_metadata_GCE(void)
 
     hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
                           &IID_IWICMetadataReader, (void **)&reader);
-todo_wine
     ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
        "CoCreateInstance error %#x\n", hr);
 
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index e26eec0..b712b2f 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -97,5 +97,6 @@ extern HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid,
 extern HRESULT PngTextReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
 extern HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
 extern HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
+extern HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
 
 #endif /* WINCODECS_PRIVATE_H */
diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl
index 942cbb7..e109bf2 100644
--- a/dlls/windowscodecs/windowscodecs_wincodec.idl
+++ b/dlls/windowscodecs/windowscodecs_wincodec.idl
@@ -156,3 +156,10 @@ coclass WICLSDMetadataReader { interface IWICMetadataReader; }
     uuid(7447a267-0015-42c8-a8f1-fb3b94c68361)
 ]
 coclass WICIMDMetadataReader { interface IWICMetadataReader; }
+
+[
+    helpstring("WIC GCE Metadata Reader"),
+    threading(both),
+    uuid(b92e345d-f52d-41f3-b562-081bc772e3b9)
+]
+coclass WICGCEMetadataReader { interface IWICMetadataReader; }




More information about the wine-cvs mailing list