diff --git a/reactos/dll/win32/windowscodecs/clsfactory.c b/reactos/dll/win32/windowscodecs/clsfactory.c index f114d2d51f5..2116ff9e8b4 100644 --- a/reactos/dll/win32/windowscodecs/clsfactory.c +++ b/reactos/dll/win32/windowscodecs/clsfactory.c @@ -42,6 +42,7 @@ static const classinfo wic_classes[] = { {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, + {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, diff --git a/reactos/dll/win32/windowscodecs/icnsformat.c b/reactos/dll/win32/windowscodecs/icnsformat.c index b9764e65f0b..c70b4e752ac 100644 --- a/reactos/dll/win32/windowscodecs/icnsformat.c +++ b/reactos/dll/win32/windowscodecs/icnsformat.c @@ -159,8 +159,7 @@ static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface) This->encoder->outstanding_commits--; LeaveCriticalSection(&This->encoder->lock); } - if (This->icns_image != NULL) - HeapFree(GetProcessHeap(), 0, This->icns_image); + HeapFree(GetProcessHeap(), 0, This->icns_image); IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); HeapFree(GetProcessHeap(), 0, This); diff --git a/reactos/dll/win32/windowscodecs/pngformat.c b/reactos/dll/win32/windowscodecs/pngformat.c index ed22b770667..4e523b07465 100644 --- a/reactos/dll/win32/windowscodecs/pngformat.c +++ b/reactos/dll/win32/windowscodecs/pngformat.c @@ -203,6 +203,84 @@ HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&GamaReader_Vtbl, iid, ppv); } +static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) +{ + HRESULT hr; + BYTE type[4]; + BYTE *data; + ULONG data_size; + static const WCHAR names[8][12] = { + {'W','h','i','t','e','P','o','i','n','t','X',0}, + {'W','h','i','t','e','P','o','i','n','t','Y',0}, + {'R','e','d','X',0}, + {'R','e','d','Y',0}, + {'G','r','e','e','n','X',0}, + {'G','r','e','e','n','Y',0}, + {'B','l','u','e','X',0}, + {'B','l','u','e','Y',0}, + }; + LPWSTR dyn_names[8] = {0}; + MetadataItem *result; + int i; + + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; + + if (data_size < 32) + { + HeapFree(GetProcessHeap(), 0, data); + return E_FAIL; + } + + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)*8); + for (i=0; i<8; i++) + { + dyn_names[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(names[i])+1)); + if (!dyn_names[i]) break; + } + if (!result || i < 8) + { + HeapFree(GetProcessHeap(), 0, result); + for (i=0; i<8; i++) + HeapFree(GetProcessHeap(), 0, dyn_names[i]); + HeapFree(GetProcessHeap(), 0, data); + return E_OUTOFMEMORY; + } + + for (i=0; i<8; i++) + { + PropVariantInit(&result[i].schema); + + PropVariantInit(&result[i].id); + result[i].id.vt = VT_LPWSTR; + result[i].id.u.pwszVal = dyn_names[i]; + lstrcpyW(dyn_names[i], names[i]); + + PropVariantInit(&result[i].value); + result[i].value.vt = VT_UI4; + result[i].value.u.ulVal = read_ulong_be(&data[i*4]); + } + + *items = result; + *item_count = 8; + + HeapFree(GetProcessHeap(), 0, data); + + return S_OK; +} + +static const MetadataHandlerVtbl ChrmReader_Vtbl = { + 0, + &CLSID_WICPngChrmMetadataReader, + LoadChrmMetadata +}; + +HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) +{ + return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); +} + #ifdef SONAME_LIBPNG static void *libpng_handle; diff --git a/reactos/dll/win32/windowscodecs/regsvr.c b/reactos/dll/win32/windowscodecs/regsvr.c index b56295948c4..29807a012de 100644 --- a/reactos/dll/win32/windowscodecs/regsvr.c +++ b/reactos/dll/win32/windowscodecs/regsvr.c @@ -1499,6 +1499,21 @@ static const struct reader_containers pnggama_containers[] = { { NULL } /* list terminator */ }; +static const BYTE cHRM[] = "cHRM"; + +static const struct metadata_pattern pngchrm_metadata_pattern[] = { + { 4, 4, cHRM, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pngchrm_containers[] = { + { + &GUID_ContainerFormatPng, + pngchrm_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 }, @@ -1594,6 +1609,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 1, 1, 0, ifd_containers }, + { &CLSID_WICPngChrmMetadataReader, + "The Wine Project", + "Chunk cHRM Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunkcHRM, + 0, 0, 0, + pngchrm_containers + }, { &CLSID_WICPngGamaMetadataReader, "The Wine Project", "Chunk gAMA Reader", diff --git a/reactos/dll/win32/windowscodecs/wincodecs_private.h b/reactos/dll/win32/windowscodecs/wincodecs_private.h index 6b874e706cb..e31c5930dfb 100644 --- a/reactos/dll/win32/windowscodecs/wincodecs_private.h +++ b/reactos/dll/win32/windowscodecs/wincodecs_private.h @@ -242,6 +242,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 PngChrmReader_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; diff --git a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl index 089bb39dc95..fd7ff01067d 100644 --- a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl +++ b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl @@ -139,6 +139,13 @@ coclass WICUnknownMetadataReader { interface IWICMetadataReader; } ] coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; } +[ + helpstring("WIC Png cHRM Metadata Reader"), + threading(both), + uuid(f90b5f36-367b-402a-9dd1-bc0fd59d8f62) +] +coclass WICPngChrmMetadataReader { interface IWICMetadataReader; } + [ helpstring("WIC Png gAMA Metadata Reader"), threading(both), diff --git a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs index 83fce40bc85..3c63a98314e 100644 --- a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs +++ b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs @@ -203,6 +203,10 @@ HKCR { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } } + '{F90B5F36-367B-402A-9DD1-BC0FD59D8F62}' = s 'WIC Png cHRM Metadata Reader' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } '{3692CA39-E082-4350-9E1F-3704CB083CD5}' = s 'WIC Png gAMA Metadata Reader' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index e31187a3b33..74140573bff 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -200,7 +200,7 @@ reactos/dll/win32/version # Synced to WineStaging-1.9.11 reactos/dll/win32/vssapi # Synced to WineStaging-1.9.11 reactos/dll/win32/wbemdisp # Synced to WineStaging-1.9.16 reactos/dll/win32/wbemprox # Synced to WineStaging-1.9.11 -reactos/dll/win32/windowscodecs # Synced to WineStaging-1.9.11 +reactos/dll/win32/windowscodecs # Synced to WineStaging-1.9.16 reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.9.11 reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.9.11 reactos/dll/win32/wing32 # Synced to WineStaging-1.9.11