windowscodecs: Implement Logical Screen Descriptor metadata reader.

This commit is contained in:
Dmitry Timoshkov 2012-09-11 16:48:37 +09:00 committed by Alexandre Julliard
parent d96e32c8a3
commit 500ab2b5c7
6 changed files with 145 additions and 4 deletions

View File

@ -62,6 +62,7 @@ static const classinfo wic_classes[] = {
{&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance},
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
{0}};
typedef struct {

View File

@ -21,11 +21,13 @@
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "ungif.h"
@ -35,6 +37,115 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
static LPWSTR strdupAtoW(const char *src)
{
int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
LPWSTR dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (dst) MultiByteToWideChar(CP_ACP, 0, src, -1, dst, len);
return dst;
}
static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options,
MetadataItem **items, DWORD *count)
{
struct logical_screen_descriptor
{
char signature[6];
USHORT width;
USHORT height;
BYTE packed;
/* global_color_table_flag : 1;
* color_resolution : 3;
* sort_flag : 1;
* global_color_table_size : 3;
*/
BYTE background_color_index;
BYTE pixel_aspect_ratio;
} lsd_data;
HRESULT hr;
ULONG bytesread, i;
MetadataItem *result;
*items = NULL;
*count = 0;
hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread);
if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK;
result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 9);
if (!result) return E_OUTOFMEMORY;
for (i = 0; i < 9; 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("Signature");
result[0].value.vt = VT_UI1|VT_VECTOR;
result[0].value.u.caub.cElems = 6;
result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(lsd_data.signature));
memcpy(result[0].value.u.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature));
result[1].id.vt = VT_LPWSTR;
result[1].id.u.pwszVal = strdupAtoW("Width");
result[1].value.vt = VT_UI2;
result[1].value.u.uiVal = lsd_data.width;
result[2].id.vt = VT_LPWSTR;
result[2].id.u.pwszVal = strdupAtoW("Height");
result[2].value.vt = VT_UI2;
result[2].value.u.uiVal = lsd_data.height;
result[3].id.vt = VT_LPWSTR;
result[3].id.u.pwszVal = strdupAtoW("GlobalColorTableFlag");
result[3].value.vt = VT_BOOL;
result[3].value.u.boolVal = (lsd_data.packed >> 7) & 1;
result[4].id.vt = VT_LPWSTR;
result[4].id.u.pwszVal = strdupAtoW("ColorResolution");
result[4].value.vt = VT_UI1;
result[4].value.u.bVal = (lsd_data.packed >> 6) & 7;
result[5].id.vt = VT_LPWSTR;
result[5].id.u.pwszVal = strdupAtoW("SortFlag");
result[5].value.vt = VT_BOOL;
result[5].value.u.boolVal = (lsd_data.packed >> 3) & 1;
result[6].id.vt = VT_LPWSTR;
result[6].id.u.pwszVal = strdupAtoW("GlobalColorTableSize");
result[6].value.vt = VT_UI1;
result[6].value.u.bVal = lsd_data.packed & 7;
result[7].id.vt = VT_LPWSTR;
result[7].id.u.pwszVal = strdupAtoW("BackgroundColorIndex");
result[7].value.vt = VT_UI1;
result[7].value.u.bVal = lsd_data.background_color_index;
result[8].id.vt = VT_LPWSTR;
result[8].id.u.pwszVal = strdupAtoW("PixelAspectRatio");
result[8].value.vt = VT_UI1;
result[8].value.u.bVal = lsd_data.pixel_aspect_ratio;
*items = result;
*count = 9;
return S_OK;
}
static const MetadataHandlerVtbl LSDReader_Vtbl = {
0,
&CLSID_WICLSDMetadataReader,
load_LSD_metadata
};
HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
{
return MetadataReader_Create(&LSDReader_Vtbl, pUnkOuter, iid, ppv);
}
typedef struct {
IWICBitmapDecoder IWICBitmapDecoder_iface;
LONG ref;

View File

@ -1518,6 +1518,20 @@ static const struct reader_containers pngtext_containers[] = {
{ NULL } /* list terminator */
};
static const struct metadata_pattern lsd_metadata_patterns[] = {
{ 0, 6, gif87a_magic, mask_all, 0 },
{ 0, 6, gif89a_magic, mask_all, 0 },
{ 0 }
};
static const struct reader_containers lsd_containers[] = {
{
&GUID_ContainerFormatGif,
lsd_metadata_patterns
},
{ NULL } /* list terminator */
};
static struct regsvr_metadatareader const metadatareader_list[] = {
{ &CLSID_WICUnknownMetadataReader,
"The Wine Project",
@ -1529,8 +1543,7 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
0, 0, 0,
NULL
},
{
&CLSID_WICIfdMetadataReader,
{ &CLSID_WICIfdMetadataReader,
"The Wine Project",
"Ifd Reader",
"1.0.0.0",
@ -1550,6 +1563,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
0, 0, 0,
pngtext_containers
},
{ &CLSID_WICLSDMetadataReader,
"The Wine Project",
"Logical Screen Descriptor Reader",
"1.0.0.0",
"1.0.0.0",
&GUID_VendorMicrosoft,
&GUID_MetadataFormatLSD,
0, 0, 0,
lsd_containers
},
{ NULL } /* list terminator */
};

View File

@ -1287,7 +1287,6 @@ static void test_metadata_LSD(void)
hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, 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);

View File

@ -94,7 +94,7 @@ extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown
extern HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT IfdMetadataReader_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;
#endif /* WINCODECS_PRIVATE_H */

View File

@ -142,3 +142,10 @@ coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; }
uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7)
]
coclass WICPngTextMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC LSD Metadata Reader"),
threading(both),
uuid(41070793-59e4-479a-a1f7-954adc2ef5fc)
]
coclass WICLSDMetadataReader { interface IWICMetadataReader; }