windowscodecs: Implement Logical Screen Descriptor metadata reader.
This commit is contained in:
parent
d96e32c8a3
commit
500ab2b5c7
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue