windowscodecs: Implement PNG gAMA metadata reader.
This commit is contained in:
parent
5b893587bd
commit
131a7b03e8
|
@ -61,6 +61,7 @@ static const classinfo wic_classes[] = {
|
|||
{&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance},
|
||||
{&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance},
|
||||
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
|
||||
{&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance},
|
||||
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
|
||||
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
|
||||
{&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
|
||||
|
|
|
@ -43,6 +43,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
|||
|
||||
static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
|
||||
|
||||
static inline ULONG read_ulong_be(BYTE* data)
|
||||
{
|
||||
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
}
|
||||
|
||||
static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
|
||||
{
|
||||
BYTE header[8];
|
||||
|
@ -57,7 +62,7 @@ static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *d
|
|||
return hr;
|
||||
}
|
||||
|
||||
*data_size = header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3];
|
||||
*data_size = read_ulong_be(&header[0]);
|
||||
|
||||
memcpy(type, &header[4], 4);
|
||||
|
||||
|
@ -155,6 +160,68 @@ HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv)
|
|||
return MetadataReader_Create(&TextReader_Vtbl, iid, ppv);
|
||||
}
|
||||
|
||||
static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor,
|
||||
DWORD persist_options, MetadataItem **items, DWORD *item_count)
|
||||
{
|
||||
HRESULT hr;
|
||||
BYTE type[4];
|
||||
BYTE *data;
|
||||
ULONG data_size;
|
||||
ULONG gamma;
|
||||
static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0};
|
||||
LPWSTR name;
|
||||
MetadataItem *result;
|
||||
|
||||
hr = read_png_chunk(stream, type, &data, &data_size);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (data_size < 4)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
gamma = read_ulong_be(data);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
|
||||
result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem));
|
||||
name = HeapAlloc(GetProcessHeap(), 0, sizeof(ImageGamma));
|
||||
if (!result || !name)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, result);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
PropVariantInit(&result[0].schema);
|
||||
PropVariantInit(&result[0].id);
|
||||
PropVariantInit(&result[0].value);
|
||||
|
||||
memcpy(name, ImageGamma, sizeof(ImageGamma));
|
||||
|
||||
result[0].id.vt = VT_LPWSTR;
|
||||
result[0].id.u.pwszVal = name;
|
||||
result[0].value.vt = VT_UI4;
|
||||
result[0].value.u.ulVal = gamma;
|
||||
|
||||
*items = result;
|
||||
*item_count = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const MetadataHandlerVtbl GamaReader_Vtbl = {
|
||||
0,
|
||||
&CLSID_WICPngGamaMetadataReader,
|
||||
LoadGamaMetadata
|
||||
};
|
||||
|
||||
HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv)
|
||||
{
|
||||
return MetadataReader_Create(&GamaReader_Vtbl, iid, ppv);
|
||||
}
|
||||
|
||||
#ifdef SONAME_LIBPNG
|
||||
|
||||
static void *libpng_handle;
|
||||
|
|
|
@ -1502,6 +1502,21 @@ static const struct reader_containers pngtext_containers[] = {
|
|||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
static const BYTE gAMA[] = "gAMA";
|
||||
|
||||
static const struct metadata_pattern pnggama_metadata_pattern[] = {
|
||||
{ 4, 4, gAMA, mask_all, 4 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct reader_containers pnggama_containers[] = {
|
||||
{
|
||||
&GUID_ContainerFormatPng,
|
||||
pnggama_metadata_pattern
|
||||
},
|
||||
{ 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 },
|
||||
|
@ -1597,6 +1612,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = {
|
|||
1, 1, 0,
|
||||
ifd_containers
|
||||
},
|
||||
{ &CLSID_WICPngGamaMetadataReader,
|
||||
"The Wine Project",
|
||||
"Chunk gAMA Reader",
|
||||
"1.0.0.0",
|
||||
"1.0.0.0",
|
||||
&GUID_VendorMicrosoft,
|
||||
&GUID_MetadataFormatChunkgAMA,
|
||||
0, 0, 0,
|
||||
pnggama_containers
|
||||
},
|
||||
{ &CLSID_WICPngTextMetadataReader,
|
||||
"The Wine Project",
|
||||
"Chunk tEXt Reader",
|
||||
|
|
|
@ -427,7 +427,7 @@ static void test_metadata_gAMA(void)
|
|||
|
||||
hr = CoCreateInstance(&CLSID_WICPngGamaMetadataReader, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IWICMetadataReader, (void**)&reader);
|
||||
todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr);
|
||||
ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr);
|
||||
if (FAILED(hr)) return;
|
||||
|
||||
load_stream((IUnknown*)reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionsDefault);
|
||||
|
|
|
@ -151,6 +151,7 @@ extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID i
|
|||
|
||||
extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -139,6 +139,13 @@ coclass WICUnknownMetadataReader { interface IWICMetadataReader; }
|
|||
]
|
||||
coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; }
|
||||
|
||||
[
|
||||
helpstring("WIC Png gAMA Metadata Reader"),
|
||||
threading(both),
|
||||
uuid(3692ca39-e082-4350-9e1f-3704cb083cd5)
|
||||
]
|
||||
coclass WICPngGamaMetadataReader { interface IWICMetadataReader; }
|
||||
|
||||
[
|
||||
helpstring("WIC Png tEXt Metadata Reader"),
|
||||
threading(both),
|
||||
|
|
Loading…
Reference in New Issue