[3/4] windowscodecs: Implement Image Descriptor metadata reader.
Dmitry Timoshkov
dmitry at baikal.ru
Tue Sep 11 02:49:50 CDT 2012
---
dlls/windowscodecs/clsfactory.c | 1 +
dlls/windowscodecs/gifformat.c | 94 +++++++++++++++++++++++++++
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, 128 insertions(+), 1 deletion(-)
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c
index 3f1328c..dc70c04 100644
--- a/dlls/windowscodecs/clsfactory.c
+++ b/dlls/windowscodecs/clsfactory.c
@@ -63,6 +63,7 @@ static const classinfo wic_classes[] = {
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
+ {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
{0}};
typedef struct {
diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c
index c4ee566..f6a7d27 100644
--- a/dlls/windowscodecs/gifformat.c
+++ b/dlls/windowscodecs/gifformat.c
@@ -146,6 +146,100 @@ HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
return MetadataReader_Create(&LSDReader_Vtbl, pUnkOuter, iid, ppv);
}
+static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options,
+ MetadataItem **items, DWORD *count)
+{
+ struct image_descriptor
+ {
+ USHORT left;
+ USHORT top;
+ USHORT width;
+ USHORT height;
+ BYTE packed;
+ /* local_color_table_flag : 1;
+ * interlace_flag : 1;
+ * sort_flag : 1;
+ * reserved : 2;
+ * local_color_table_size : 3;
+ */
+ } imd_data;
+ HRESULT hr;
+ ULONG bytesread, i;
+ MetadataItem *result;
+
+ *items = NULL;
+ *count = 0;
+
+ hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread);
+ if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK;
+
+ result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 8);
+ if (!result) return E_OUTOFMEMORY;
+
+ for (i = 0; i < 8; 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("Left");
+ result[0].value.vt = VT_UI2;
+ result[0].value.u.uiVal = imd_data.left;
+
+ result[1].id.vt = VT_LPWSTR;
+ result[1].id.u.pwszVal = strdupAtoW("Top");
+ result[1].value.vt = VT_UI2;
+ result[1].value.u.uiVal = imd_data.top;
+
+ result[2].id.vt = VT_LPWSTR;
+ result[2].id.u.pwszVal = strdupAtoW("Width");
+ result[2].value.vt = VT_UI2;
+ result[2].value.u.uiVal = imd_data.width;
+
+ result[3].id.vt = VT_LPWSTR;
+ result[3].id.u.pwszVal = strdupAtoW("Height");
+ result[3].value.vt = VT_UI2;
+ result[3].value.u.uiVal = imd_data.height;
+
+ result[4].id.vt = VT_LPWSTR;
+ result[4].id.u.pwszVal = strdupAtoW("LocalColorTableFlag");
+ result[4].value.vt = VT_BOOL;
+ result[4].value.u.boolVal = (imd_data.packed >> 7) & 1;
+
+ result[5].id.vt = VT_LPWSTR;
+ result[5].id.u.pwszVal = strdupAtoW("InterlaceFlag");
+ result[5].value.vt = VT_BOOL;
+ result[5].value.u.boolVal = (imd_data.packed >> 6) & 1;
+
+ result[6].id.vt = VT_LPWSTR;
+ result[6].id.u.pwszVal = strdupAtoW("SortFlag");
+ result[6].value.vt = VT_BOOL;
+ result[6].value.u.boolVal = (imd_data.packed >> 5) & 1;
+
+ result[7].id.vt = VT_LPWSTR;
+ result[7].id.u.pwszVal = strdupAtoW("LocalColorTableSize");
+ result[7].value.vt = VT_UI1;
+ result[7].value.u.bVal = imd_data.packed & 7;
+
+ *items = result;
+ *count = 8;
+
+ return S_OK;
+}
+
+static const MetadataHandlerVtbl IMDReader_Vtbl = {
+ 0,
+ &CLSID_WICIMDMetadataReader,
+ load_IMD_metadata
+};
+
+HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
+{
+ return MetadataReader_Create(&IMDReader_Vtbl, pUnkOuter, iid, ppv);
+}
+
typedef struct {
IWICBitmapDecoder IWICBitmapDecoder_iface;
LONG ref;
diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c
index cb48d63..c232778 100644
--- a/dlls/windowscodecs/regsvr.c
+++ b/dlls/windowscodecs/regsvr.c
@@ -1532,6 +1532,21 @@ static const struct reader_containers lsd_containers[] = {
{ NULL } /* list terminator */
};
+static const BYTE imd_magic[] = { 0x2c };
+
+static const struct metadata_pattern imd_metadata_pattern[] = {
+ { 0, 1, imd_magic, mask_all, 1 },
+ { 0 }
+};
+
+static const struct reader_containers imd_containers[] = {
+ {
+ &GUID_ContainerFormatGif,
+ imd_metadata_pattern
+ },
+ { NULL } /* list terminator */
+};
+
static struct regsvr_metadatareader const metadatareader_list[] = {
{ &CLSID_WICUnknownMetadataReader,
"The Wine Project",
@@ -1573,6 +1588,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
0, 0, 0,
lsd_containers
},
+ { &CLSID_WICIMDMetadataReader,
+ "The Wine Project",
+ "Image Descriptor Reader",
+ "1.0.0.0",
+ "1.0.0.0",
+ &GUID_VendorMicrosoft,
+ &GUID_MetadataFormatIMD,
+ 0, 0, 0,
+ imd_containers
+ },
{ NULL } /* list terminator */
};
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c
index fd81e6f..bfa9116 100644
--- a/dlls/windowscodecs/tests/metadata.c
+++ b/dlls/windowscodecs/tests/metadata.c
@@ -1365,7 +1365,6 @@ static void test_metadata_IMD(void)
hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, 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 908b2e6..e26eec0 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -96,5 +96,6 @@ extern HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID
extern HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
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;
#endif /* WINCODECS_PRIVATE_H */
diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl
index d360ae5..942cbb7 100644
--- a/dlls/windowscodecs/windowscodecs_wincodec.idl
+++ b/dlls/windowscodecs/windowscodecs_wincodec.idl
@@ -149,3 +149,10 @@ coclass WICPngTextMetadataReader { interface IWICMetadataReader; }
uuid(41070793-59e4-479a-a1f7-954adc2ef5fc)
]
coclass WICLSDMetadataReader { interface IWICMetadataReader; }
+
+[
+ helpstring("WIC IMD Metadata Reader"),
+ threading(both),
+ uuid(7447a267-0015-42c8-a8f1-fb3b94c68361)
+]
+coclass WICIMDMetadataReader { interface IWICMetadataReader; }
--
1.7.11.5
More information about the wine-patches
mailing list