windowscodecs: Implement GIF Comment Extension metadata reader.
This commit is contained in:
parent
be28f266ff
commit
ec206a843f
|
@ -66,6 +66,7 @@ static const classinfo wic_classes[] = {
|
|||
{&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
|
||||
{&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance},
|
||||
{&CLSID_WICAPEMetadataReader, APEReader_CreateInstance},
|
||||
{&CLSID_WICGifCommentMetadataReader, GifCommentReader_CreateInstance},
|
||||
{0}};
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -434,6 +434,101 @@ HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
|
|||
return MetadataReader_Create(&APEReader_Vtbl, pUnkOuter, iid, ppv);
|
||||
}
|
||||
|
||||
static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options,
|
||||
MetadataItem **items, DWORD *count)
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
struct gif_extenstion
|
||||
{
|
||||
BYTE extension_introducer;
|
||||
BYTE extension_label;
|
||||
} ext_data;
|
||||
#include "poppack.h"
|
||||
HRESULT hr;
|
||||
ULONG bytesread, data_size;
|
||||
MetadataItem *result;
|
||||
BYTE subblock_size;
|
||||
BYTE *data;
|
||||
|
||||
*items = NULL;
|
||||
*count = 0;
|
||||
|
||||
hr = IStream_Read(stream, &ext_data, sizeof(ext_data), &bytesread);
|
||||
if (FAILED(hr) || bytesread != sizeof(ext_data)) return S_OK;
|
||||
if (ext_data.extension_introducer != 0x21 || ext_data.extension_label != 0xfe)
|
||||
return S_OK;
|
||||
|
||||
data = NULL;
|
||||
data_size = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread);
|
||||
if (FAILED(hr) || bytesread != sizeof(subblock_size))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return S_OK;
|
||||
}
|
||||
if (!subblock_size) break;
|
||||
|
||||
if (!data)
|
||||
data = HeapAlloc(GetProcessHeap(), 0, subblock_size);
|
||||
else
|
||||
{
|
||||
BYTE *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size);
|
||||
if (!new_data)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return S_OK;
|
||||
}
|
||||
data = new_data;
|
||||
}
|
||||
hr = IStream_Read(stream, data + data_size, subblock_size, &bytesread);
|
||||
if (FAILED(hr) || bytesread != subblock_size)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return S_OK;
|
||||
}
|
||||
data_size += subblock_size;
|
||||
}
|
||||
|
||||
result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem));
|
||||
if (!result)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
PropVariantInit(&result->schema);
|
||||
PropVariantInit(&result->id);
|
||||
PropVariantInit(&result->value);
|
||||
|
||||
result->id.vt = VT_LPWSTR;
|
||||
result->id.u.pwszVal = strdupAtoW("TextEntry");
|
||||
result->value.vt = VT_LPSTR;
|
||||
result->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, data_size + 1);
|
||||
memcpy(result->value.u.pszVal, data, data_size);
|
||||
result->value.u.pszVal[data_size] = 0;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
|
||||
*items = result;
|
||||
*count = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const MetadataHandlerVtbl GifCommentReader_Vtbl = {
|
||||
0,
|
||||
&CLSID_WICGifCommentMetadataReader,
|
||||
load_GifComment_metadata
|
||||
};
|
||||
|
||||
HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
|
||||
{
|
||||
return MetadataReader_Create(&GifCommentReader_Vtbl, pUnkOuter, iid, ppv);
|
||||
}
|
||||
|
||||
static IStream *create_stream(const void *data, int data_size)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
|
|
@ -1577,6 +1577,21 @@ static const struct reader_containers ape_containers[] = {
|
|||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
|
||||
|
||||
static const struct metadata_pattern gif_comment_metadata_pattern[] = {
|
||||
{ 0, 2, gif_comment_magic, mask_all, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct reader_containers gif_comment_containers[] = {
|
||||
{
|
||||
&GUID_ContainerFormatGif,
|
||||
gif_comment_metadata_pattern
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||
{ &CLSID_WICUnknownMetadataReader,
|
||||
"The Wine Project",
|
||||
|
@ -1648,6 +1663,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
|
|||
0, 0, 0,
|
||||
ape_containers
|
||||
},
|
||||
{ &CLSID_WICGifCommentMetadataReader,
|
||||
"The Wine Project",
|
||||
"Comment Extension Reader",
|
||||
"1.0.0.0",
|
||||
"1.0.0.0",
|
||||
&GUID_VendorMicrosoft,
|
||||
&GUID_MetadataFormatGifComment,
|
||||
0, 0, 0,
|
||||
gif_comment_containers
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
|
|
|
@ -1727,7 +1727,6 @@ static void test_metadata_GIF_comment(void)
|
|||
|
||||
hr = CoCreateInstance(&CLSID_WICGifCommentMetadataReader, 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);
|
||||
|
||||
|
|
|
@ -99,5 +99,6 @@ extern HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **
|
|||
extern HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* WINCODECS_PRIVATE_H */
|
||||
|
|
|
@ -170,3 +170,10 @@ coclass WICGCEMetadataReader { interface IWICMetadataReader; }
|
|||
uuid(1767b93a-b021-44ea-920f-863c11f4f768)
|
||||
]
|
||||
coclass WICAPEMetadataReader { interface IWICMetadataReader; }
|
||||
|
||||
[
|
||||
helpstring("WIC Comment Extension Reader"),
|
||||
threading(both),
|
||||
uuid(32557d3b-69dc-4f95-836e-f5972b2f6159)
|
||||
]
|
||||
coclass WICGifCommentMetadataReader { interface IWICMetadataReader; }
|
||||
|
|
Loading…
Reference in New Issue