Commit 26628b4c authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

windowscodecs: Implement Graphic Control Extension metadata reader.

parent 97fc6be6
......@@ -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 {
......
......@@ -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;
......
......@@ -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 */
};
......
......@@ -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);
......
......@@ -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 */
......@@ -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; }
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