mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
windowscodecs: Create Image Descriptor metadata block for a GIF frame.
This commit is contained in:
parent
fbd5a9aaff
commit
003c20467c
@ -149,25 +149,27 @@ HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
|
||||
return MetadataReader_Create(&LSDReader_Vtbl, pUnkOuter, iid, ppv);
|
||||
}
|
||||
|
||||
#include "pshpack1.h"
|
||||
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;
|
||||
*/
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options,
|
||||
MetadataItem **items, DWORD *count)
|
||||
{
|
||||
#include "pshpack1.h"
|
||||
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;
|
||||
#include "poppack.h"
|
||||
struct image_descriptor imd_data;
|
||||
HRESULT hr;
|
||||
ULONG bytesread, i;
|
||||
MetadataItem *result;
|
||||
@ -353,6 +355,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
|
||||
IWICMetadataBlockReader IWICMetadataBlockReader_iface;
|
||||
LONG ref;
|
||||
SavedImage *frame;
|
||||
GifDecoder *parent;
|
||||
@ -373,6 +376,11 @@ static inline GifFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDec
|
||||
return CONTAINING_RECORD(iface, GifFrameDecode, IWICBitmapFrameDecode_iface);
|
||||
}
|
||||
|
||||
static inline GifFrameDecode *frame_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, GifFrameDecode, IWICMetadataBlockReader_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
@ -387,6 +395,10 @@ static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
|
||||
{
|
||||
*ppv = &This->IWICBitmapFrameDecode_iface;
|
||||
}
|
||||
else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
|
||||
{
|
||||
*ppv = &This->IWICMetadataBlockReader_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppv = NULL;
|
||||
@ -604,6 +616,125 @@ static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl = {
|
||||
GifFrameDecode_GetThumbnail
|
||||
};
|
||||
|
||||
static HRESULT WINAPI GifFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface,
|
||||
REFIID iid, void **ppv)
|
||||
{
|
||||
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
||||
return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI GifFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface)
|
||||
{
|
||||
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
||||
return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI GifFrameDecode_Block_Release(IWICMetadataBlockReader *iface)
|
||||
{
|
||||
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
||||
return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GifFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface,
|
||||
GUID *guid)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, guid);
|
||||
|
||||
if (!guid) return E_INVALIDARG;
|
||||
|
||||
*guid = GUID_ContainerFormatGif;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GifFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface,
|
||||
UINT *count)
|
||||
{
|
||||
TRACE("%p,%p\n", iface, count);
|
||||
|
||||
if (!count) return E_INVALIDARG;
|
||||
|
||||
*count = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT create_IMD_metadata_reader(GifFrameDecode *This, IWICMetadataReader **reader)
|
||||
{
|
||||
HRESULT hr;
|
||||
IWICMetadataReader *metadata_reader;
|
||||
IWICPersistStream *persist;
|
||||
IStream *stream;
|
||||
struct image_descriptor IMD_data;
|
||||
|
||||
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, 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;
|
||||
}
|
||||
|
||||
/* recreate IMD structure from GIF decoder data */
|
||||
IMD_data.left = This->frame->ImageDesc.Left;
|
||||
IMD_data.top = This->frame->ImageDesc.Top;
|
||||
IMD_data.width = This->frame->ImageDesc.Width;
|
||||
IMD_data.height = This->frame->ImageDesc.Height;
|
||||
IMD_data.packed = 0;
|
||||
/* interlace_flag */
|
||||
IMD_data.packed |= This->frame->ImageDesc.Interlace ? (1 << 6) : 0;
|
||||
if (This->frame->ImageDesc.ColorMap)
|
||||
{
|
||||
/* local_color_table_flag */
|
||||
IMD_data.packed |= 1 << 7;
|
||||
/* local_color_table_size */
|
||||
IMD_data.packed |= This->frame->ImageDesc.ColorMap->BitsPerPixel;
|
||||
/* FIXME: sort_flag */
|
||||
}
|
||||
|
||||
stream = create_stream(&IMD_data, sizeof(IMD_data));
|
||||
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,
|
||||
UINT index, IWICMetadataReader **reader)
|
||||
{
|
||||
GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface);
|
||||
|
||||
TRACE("(%p,%u,%p)\n", iface, index, reader);
|
||||
|
||||
if (!reader || index != 0) return E_INVALIDARG;
|
||||
|
||||
return create_IMD_metadata_reader(This, reader);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface,
|
||||
IEnumUnknown **enumerator)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, enumerator);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IWICMetadataBlockReaderVtbl GifFrameDecode_BlockVtbl =
|
||||
{
|
||||
GifFrameDecode_Block_QueryInterface,
|
||||
GifFrameDecode_Block_AddRef,
|
||||
GifFrameDecode_Block_Release,
|
||||
GifFrameDecode_Block_GetContainerFormat,
|
||||
GifFrameDecode_Block_GetCount,
|
||||
GifFrameDecode_Block_GetReaderByIndex,
|
||||
GifFrameDecode_Block_GetEnumerator
|
||||
};
|
||||
|
||||
static HRESULT WINAPI GifDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
@ -824,6 +955,7 @@ static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface,
|
||||
if (!result) return E_OUTOFMEMORY;
|
||||
|
||||
result->IWICBitmapFrameDecode_iface.lpVtbl = &GifFrameDecode_Vtbl;
|
||||
result->IWICMetadataBlockReader_iface.lpVtbl = &GifFrameDecode_BlockVtbl;
|
||||
result->ref = 1;
|
||||
result->frame = &This->gif->SavedImages[index];
|
||||
IWICBitmapDecoder_AddRef(iface);
|
||||
|
@ -1088,7 +1088,6 @@ static void test_metadata_gif(void)
|
||||
ok(hr == S_OK, "GetFrame error %#x\n", hr);
|
||||
|
||||
hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader);
|
||||
todo_wine
|
||||
ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
@ -1190,7 +1189,6 @@ todo_wine
|
||||
ok(hr == S_OK, "GetFrame error %#x\n", hr);
|
||||
|
||||
hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader);
|
||||
todo_wine
|
||||
ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
@ -1208,6 +1206,7 @@ todo_wine
|
||||
|
||||
hr = IWICMetadataBlockReader_GetCount(blockreader, &count);
|
||||
ok(hr == S_OK, "GetCount error %#x\n", hr);
|
||||
todo_wine
|
||||
ok(count == 2, "expected 2, got %u\n", count);
|
||||
|
||||
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader);
|
||||
@ -1229,6 +1228,7 @@ todo_wine
|
||||
}
|
||||
|
||||
hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
Loading…
Reference in New Issue
Block a user