windowscodecs: Implement Graphic Control Extension metadata reader.
This commit is contained in:
parent
97fc6be67d
commit
26628b4c0a
|
@ -64,6 +64,7 @@ static const classinfo wic_classes[] = {
|
||||||
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
|
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
|
||||||
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
|
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
|
||||||
{&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
|
{&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
|
||||||
|
{&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance},
|
||||||
{0}};
|
{0}};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -240,6 +240,84 @@ HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
|
||||||
return MetadataReader_Create(&IMDReader_Vtbl, pUnkOuter, iid, 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 {
|
typedef struct {
|
||||||
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
|
@ -1547,6 +1547,21 @@ static const struct reader_containers imd_containers[] = {
|
||||||
{ NULL } /* list terminator */
|
{ 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[] = {
|
static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||||
{ &CLSID_WICUnknownMetadataReader,
|
{ &CLSID_WICUnknownMetadataReader,
|
||||||
"The Wine Project",
|
"The Wine Project",
|
||||||
|
@ -1598,6 +1613,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
imd_containers
|
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 */
|
{ NULL } /* list terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1440,7 +1440,6 @@ static void test_metadata_GCE(void)
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
||||||
&IID_IWICMetadataReader, (void **)&reader);
|
&IID_IWICMetadataReader, (void **)&reader);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
|
ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
|
||||||
"CoCreateInstance error %#x\n", hr);
|
"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 PngTextReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT LSDReader_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 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 */
|
#endif /* WINCODECS_PRIVATE_H */
|
||||||
|
|
|
@ -156,3 +156,10 @@ coclass WICLSDMetadataReader { interface IWICMetadataReader; }
|
||||||
uuid(7447a267-0015-42c8-a8f1-fb3b94c68361)
|
uuid(7447a267-0015-42c8-a8f1-fb3b94c68361)
|
||||||
]
|
]
|
||||||
coclass WICIMDMetadataReader { interface IWICMetadataReader; }
|
coclass WICIMDMetadataReader { interface IWICMetadataReader; }
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("WIC GCE Metadata Reader"),
|
||||||
|
threading(both),
|
||||||
|
uuid(b92e345d-f52d-41f3-b562-081bc772e3b9)
|
||||||
|
]
|
||||||
|
coclass WICGCEMetadataReader { interface IWICMetadataReader; }
|
||||||
|
|
Loading…
Reference in New Issue