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_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance},
|
||||||
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
|
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
|
||||||
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
|
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
|
||||||
|
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
|
||||||
{0}};
|
{0}};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -21,11 +21,13 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
#define NONAMELESSUNION
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "wincodec.h"
|
#include "wincodec.h"
|
||||||
|
#include "wincodecsdk.h"
|
||||||
|
|
||||||
#include "ungif.h"
|
#include "ungif.h"
|
||||||
|
|
||||||
|
@ -35,6 +37,115 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
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 {
|
typedef struct {
|
||||||
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
|
@ -1518,6 +1518,20 @@ static const struct reader_containers pngtext_containers[] = {
|
||||||
{ NULL } /* list terminator */
|
{ 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[] = {
|
static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||||
{ &CLSID_WICUnknownMetadataReader,
|
{ &CLSID_WICUnknownMetadataReader,
|
||||||
"The Wine Project",
|
"The Wine Project",
|
||||||
|
@ -1529,8 +1543,7 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{
|
{ &CLSID_WICIfdMetadataReader,
|
||||||
&CLSID_WICIfdMetadataReader,
|
|
||||||
"The Wine Project",
|
"The Wine Project",
|
||||||
"Ifd Reader",
|
"Ifd Reader",
|
||||||
"1.0.0.0",
|
"1.0.0.0",
|
||||||
|
@ -1550,6 +1563,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
pngtext_containers
|
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 */
|
{ NULL } /* list terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1287,7 +1287,6 @@ static void test_metadata_LSD(void)
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
||||||
&IID_IWICMetadataReader, (void **)&reader);
|
&IID_IWICMetadataReader, (void **)&reader);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
|
ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */,
|
||||||
"CoCreateInstance error %#x\n", hr);
|
"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 UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT IfdMetadataReader_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 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 */
|
#endif /* WINCODECS_PRIVATE_H */
|
||||||
|
|
|
@ -142,3 +142,10 @@ coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; }
|
||||||
uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7)
|
uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7)
|
||||||
]
|
]
|
||||||
coclass WICPngTextMetadataReader { interface IWICMetadataReader; }
|
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