windowscodecs: Create frame metadata readers from GIF decoder data.
This commit is contained in:
parent
609b9a4da8
commit
a0ca998e08
|
@ -547,6 +547,37 @@ static IStream *create_stream(const void *data, int data_size)
|
||||||
return FAILED(hr) ? NULL : stream;
|
return FAILED(hr) ? NULL : stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT create_metadata_reader(const void *data, int data_size,
|
||||||
|
const CLSID *clsid, IWICMetadataReader **reader)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IWICMetadataReader *metadata_reader;
|
||||||
|
IWICPersistStream *persist;
|
||||||
|
IStream *stream;
|
||||||
|
|
||||||
|
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
|
||||||
|
|
||||||
|
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IWICMetadataReader, (void **)&metadata_reader);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IWICMetadataReader_Release(metadata_reader);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = create_stream(data, data_size);
|
||||||
|
IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault);
|
||||||
|
IStream_Release(stream);
|
||||||
|
|
||||||
|
IWICPersistStream_Release(persist);
|
||||||
|
|
||||||
|
*reader = metadata_reader;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
||||||
IWICMetadataBlockReader IWICMetadataBlockReader_iface;
|
IWICMetadataBlockReader IWICMetadataBlockReader_iface;
|
||||||
|
@ -850,19 +881,6 @@ static HRESULT WINAPI GifFrameDecode_Block_GetContainerFormat(IWICMetadataBlockR
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void *get_GCE_data(GifFrameDecode *This)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++)
|
|
||||||
{
|
|
||||||
if (This->frame->Extensions.ExtensionBlocks[i].Function == GRAPHICS_EXT_FUNC_CODE &&
|
|
||||||
This->frame->Extensions.ExtensionBlocks[i].ByteCount == 8)
|
|
||||||
return This->frame->Extensions.ExtensionBlocks[i].Bytes + 3;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface,
|
static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface,
|
||||||
UINT *count)
|
UINT *count)
|
||||||
{
|
{
|
||||||
|
@ -872,8 +890,7 @@ static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *ifa
|
||||||
|
|
||||||
if (!count) return E_INVALIDARG;
|
if (!count) return E_INVALIDARG;
|
||||||
|
|
||||||
*count = 1;
|
*count = This->frame->Extensions.ExtensionBlockCount + 1;
|
||||||
if (get_GCE_data(This)) *count += 1;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,64 +943,56 @@ static HRESULT create_IMD_metadata_reader(GifFrameDecode *This, IWICMetadataRead
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_GCE_metadata_reader(const void *GCE_data, IWICMetadataReader **reader)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
IWICMetadataReader *metadata_reader;
|
|
||||||
IWICPersistStream *persist;
|
|
||||||
IStream *stream;
|
|
||||||
|
|
||||||
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
|
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
|
||||||
&IID_IWICMetadataReader, (void **)&metadata_reader);
|
|
||||||
if (FAILED(hr)) return hr;
|
|
||||||
|
|
||||||
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
IWICMetadataReader_Release(metadata_reader);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = create_stream(GCE_data, 4);
|
|
||||||
IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault);
|
|
||||||
IStream_Release(stream);
|
|
||||||
|
|
||||||
IWICPersistStream_Release(persist);
|
|
||||||
|
|
||||||
*reader = metadata_reader;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
|
static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
|
||||||
UINT index, IWICMetadataReader **reader)
|
UINT index, IWICMetadataReader **reader)
|
||||||
{
|
{
|
||||||
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
||||||
UINT block_count = 1;
|
int i, gce_index = -1, gce_skipped = 0;
|
||||||
const void *GCE_data;
|
|
||||||
|
|
||||||
TRACE("(%p,%u,%p)\n", iface, index, reader);
|
TRACE("(%p,%u,%p)\n", iface, index, reader);
|
||||||
|
|
||||||
GCE_data = get_GCE_data(This);
|
if (!reader) return E_INVALIDARG;
|
||||||
if (GCE_data) block_count++;
|
|
||||||
/* FIXME: add support for Application Extension metadata block
|
|
||||||
APE_data = get_APE_data(This);
|
|
||||||
if (APE_data) block_count++;
|
|
||||||
*/
|
|
||||||
if (!reader || index >= block_count) return E_INVALIDARG;
|
|
||||||
|
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return create_IMD_metadata_reader(This, reader);
|
return create_IMD_metadata_reader(This, reader);
|
||||||
|
|
||||||
if (index == 1 && GCE_data)
|
if (index >= This->frame->Extensions.ExtensionBlockCount + 1)
|
||||||
return create_GCE_metadata_reader(GCE_data, reader);
|
return E_INVALIDARG;
|
||||||
|
|
||||||
/* FIXME: add support for Application Extension metadata block
|
for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++)
|
||||||
if (APE_data)
|
{
|
||||||
return create_APE_metadata_reader(APE_data, reader);
|
const CLSID *clsid;
|
||||||
*/
|
const void *data;
|
||||||
return E_INVALIDARG;
|
int data_size;
|
||||||
|
|
||||||
|
if (index != i + 1 - gce_skipped) continue;
|
||||||
|
|
||||||
|
if (This->frame->Extensions.ExtensionBlocks[i].Function == GRAPHICS_EXT_FUNC_CODE)
|
||||||
|
{
|
||||||
|
gce_index = i;
|
||||||
|
gce_skipped = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (This->frame->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE)
|
||||||
|
{
|
||||||
|
clsid = &CLSID_WICGifCommentMetadataReader;
|
||||||
|
data = This->frame->Extensions.ExtensionBlocks[i].Bytes;
|
||||||
|
data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clsid = &CLSID_WICUnknownMetadataReader;
|
||||||
|
data = This->frame->Extensions.ExtensionBlocks[i].Bytes;
|
||||||
|
data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount;
|
||||||
|
}
|
||||||
|
return create_metadata_reader(data, data_size, clsid, reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gce_index == -1) return E_INVALIDARG;
|
||||||
|
|
||||||
|
return create_metadata_reader(This->frame->Extensions.ExtensionBlocks[gce_index].Bytes + 3,
|
||||||
|
This->frame->Extensions.ExtensionBlocks[gce_index].ByteCount - 4,
|
||||||
|
&CLSID_WICGCEMetadataReader, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface,
|
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface,
|
||||||
|
@ -1295,37 +1304,6 @@ static HRESULT WINAPI GifDecoder_Block_GetCount(IWICMetadataBlockReader *iface,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_metadata_reader(const void *data, int data_size,
|
|
||||||
const CLSID *clsid, IWICMetadataReader **reader)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
IWICMetadataReader *metadata_reader;
|
|
||||||
IWICPersistStream *persist;
|
|
||||||
IStream *stream;
|
|
||||||
|
|
||||||
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
|
|
||||||
|
|
||||||
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
|
|
||||||
&IID_IWICMetadataReader, (void **)&metadata_reader);
|
|
||||||
if (FAILED(hr)) return hr;
|
|
||||||
|
|
||||||
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
IWICMetadataReader_Release(metadata_reader);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = create_stream(data, data_size);
|
|
||||||
IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault);
|
|
||||||
IStream_Release(stream);
|
|
||||||
|
|
||||||
IWICPersistStream_Release(persist);
|
|
||||||
|
|
||||||
*reader = metadata_reader;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI GifDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
|
static HRESULT WINAPI GifDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
|
||||||
UINT index, IWICMetadataReader **reader)
|
UINT index, IWICMetadataReader **reader)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1306,7 +1306,6 @@ static void test_metadata_gif(void)
|
||||||
|
|
||||||
hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
|
hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
|
||||||
ok(hr == S_OK, "GetCount error %#x\n", hr);
|
ok(hr == S_OK, "GetCount error %#x\n", hr);
|
||||||
todo_wine
|
|
||||||
ok(count == 4, "expected 4, got %u\n", count);
|
ok(count == 4, "expected 4, got %u\n", count);
|
||||||
|
|
||||||
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
|
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
|
||||||
|
@ -1333,13 +1332,11 @@ todo_wine
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
|
hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
|
||||||
todo_wine
|
|
||||||
ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */
|
ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */
|
||||||
"wrong container format %s\n", debugstr_guid(&format));
|
"wrong container format %s\n", debugstr_guid(&format));
|
||||||
|
|
||||||
hr = IWICMetadataReader_GetCount(reader, &count);
|
hr = IWICMetadataReader_GetCount(reader, &count);
|
||||||
ok(hr == S_OK, "GetCount error %#x\n", hr);
|
ok(hr == S_OK, "GetCount error %#x\n", hr);
|
||||||
todo_wine
|
|
||||||
ok(count == sizeof(animated_gif_comment_2)/sizeof(animated_gif_comment_2[0]), "unexpected count %u\n", count);
|
ok(count == sizeof(animated_gif_comment_2)/sizeof(animated_gif_comment_2[0]), "unexpected count %u\n", count);
|
||||||
|
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
|
@ -1349,7 +1346,6 @@ todo_wine
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader);
|
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
|
ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
@ -1368,7 +1364,6 @@ todo_wine
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader);
|
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
|
ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
Loading…
Reference in New Issue