Commit 97fc6be6 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

windowscodecs: Implement Image Descriptor metadata reader.

parent 500ab2b5
......@@ -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 {
......
......@@ -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;
......
......@@ -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 */
};
......
......@@ -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);
......
......@@ -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 */
......@@ -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; }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment