From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/metadatahandler.c | 90 ++++++++++++++----- dlls/windowscodecs/regsvr.c | 9 ++ dlls/windowscodecs/tests/metadata.c | 3 - dlls/windowscodecs/wincodecs_private.h | 1 + dlls/windowscodecs/windowscodecs_wincodec.idl | 7 ++ 6 files changed, 87 insertions(+), 24 deletions(-)
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index 5e8912db26a..a306d4fc7d6 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -70,6 +70,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICExifMetadataReader, ExifMetadataReader_CreateInstance}, {&CLSID_WICExifMetadataWriter, ExifMetadataWriter_CreateInstance}, {&CLSID_WICApp1MetadataReader, App1MetadataReader_CreateInstance}, + {&CLSID_WICApp1MetadataWriter, App1MetadataWriter_CreateInstance}, {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, {&CLSID_WICPngHistMetadataReader, PngHistReader_CreateInstance}, diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index d464472b48e..7e00f678e4e 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -870,6 +870,41 @@ static HRESULT create_stream_wrapper(IStream *input, ULONG offset, IStream **wra return hr; }
+static HRESULT create_metadata_handler(IStream *stream, const GUID *format, const GUID *vendor, + DWORD options, bool is_writer, IWICMetadataReader **handler) +{ + IWICPersistStream *persist_stream = NULL; + IWICMetadataReader *reader = NULL; + HRESULT hr; + + if (is_writer) + hr = create_metadata_writer(format, vendor, options | WICMetadataCreationFailUnknown, + (IWICMetadataWriter **)&reader); + else + hr = create_metadata_reader(format, vendor, options | WICMetadataCreationFailUnknown, + NULL, &reader); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); + + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, stream, vendor, options); + + if (persist_stream) + IWICPersistStream_Release(persist_stream); + + if (SUCCEEDED(hr)) + { + *handler = reader; + IWICMetadataReader_AddRef(*handler); + } + + if (reader) + IWICMetadataReader_Release(reader); + + return hr; +} + static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, const struct IFD_entry *entry, MetadataItem *item, bool resolve_pointer_tags, bool is_writer) { @@ -1154,8 +1189,7 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, case IFD_EXIF_TAG: case IFD_GPS_TAG: { - IWICPersistStream *persist_stream = NULL; - IWICMetadataReader *sub_reader; + IWICMetadataReader *sub_reader = NULL;
if (!resolve_pointer_tags) break; @@ -1173,23 +1207,10 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, { const GUID *format = item->id.uiVal == IFD_EXIF_TAG ? &GUID_MetadataFormatExif : &GUID_MetadataFormatGps;
- if (is_writer) - hr = create_metadata_writer(format, vendor, options | WICMetadataCreationFailUnknown, - (IWICMetadataWriter **)&sub_reader); - else - hr = create_metadata_reader(format, vendor, options | WICMetadataCreationFailUnknown, - NULL, &sub_reader); + hr = create_metadata_handler(sub_stream, format, vendor, options | WICMetadataCreationFailUnknown, + is_writer, &sub_reader); }
- if (SUCCEEDED(hr)) - hr = IWICMetadataReader_QueryInterface(sub_reader, &IID_IWICPersistStream, (void **)&persist_stream); - - if (SUCCEEDED(hr)) - hr = IWICPersistStream_LoadEx(persist_stream, sub_stream, vendor, options); - - if (persist_stream) - IWICPersistStream_Release(persist_stream); - if (SUCCEEDED(hr)) { item->value.vt = VT_UNKNOWN; @@ -1351,10 +1372,11 @@ static HRESULT LoadGpsMetadataWriter(IStream *input, const GUID *vendor, return load_ifd_metadata_internal(input, vendor, options, false, true, items, item_count); }
-static HRESULT LoadApp1Metadata(IStream *input, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT load_app1_metadata_internal(IStream *input, const GUID *vendor, DWORD options, + bool is_writer, MetadataItem **items, DWORD *item_count) { static const char exif_header[] = {'E','x','i','f',0,0}; - IWICMetadataReader *ifd_reader; + IWICMetadataReader *ifd_reader = NULL; BOOL native_byte_order; LARGE_INTEGER move;
@@ -1411,7 +1433,9 @@ static HRESULT LoadApp1Metadata(IStream *input, const GUID *vendor, DWORD option return hr; }
- hr = create_metadata_reader(&GUID_MetadataFormatIfd, vendor, options, ifd_stream, &ifd_reader); + if (SUCCEEDED(hr)) + hr = create_metadata_handler(ifd_stream, &GUID_MetadataFormatIfd, vendor, options, is_writer, &ifd_reader); + IStream_Release(ifd_stream);
if (FAILED(hr)) @@ -1435,6 +1459,18 @@ static HRESULT LoadApp1Metadata(IStream *input, const GUID *vendor, DWORD option return S_OK; }
+static HRESULT LoadApp1MetadataReader(IStream *input, const GUID *vendor, DWORD options, + MetadataItem **items, DWORD *item_count) +{ + return load_app1_metadata_internal(input, vendor, options, false, items, item_count); +} + +static HRESULT LoadApp1MetadataWriter(IStream *input, const GUID *vendor, DWORD options, + MetadataItem **items, DWORD *item_count) +{ + return load_app1_metadata_internal(input, vendor, options, true, items, item_count); +} + static const MetadataHandlerVtbl IfdMetadataReader_Vtbl = { 0, &CLSID_WICIfdMetadataReader, @@ -1510,10 +1546,22 @@ static const MetadataHandlerVtbl App1MetadataReader_Vtbl = { 0, &CLSID_WICApp1MetadataReader, - LoadApp1Metadata + LoadApp1MetadataReader };
HRESULT App1MetadataReader_CreateInstance(REFIID iid, void **ppv) { return MetadataReader_Create(&App1MetadataReader_Vtbl, iid, ppv); } + +static const MetadataHandlerVtbl App1MetadataWriter_Vtbl = +{ + .is_writer = true, + &CLSID_WICApp1MetadataWriter, + LoadApp1MetadataWriter +}; + +HRESULT App1MetadataWriter_CreateInstance(REFIID iid, void **ppv) +{ + return MetadataReader_Create(&App1MetadataWriter_Vtbl, iid, ppv); +} diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index 03e1cd19c47..94a1fb7d070 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -2119,6 +2119,15 @@ static struct regsvr_metadatawriter const metadatawriters_list[] = &GUID_VendorMicrosoft, &GUID_MetadataFormatIfd, }, + { + &CLSID_WICApp1MetadataWriter, + "The Wine Project", + "App1 Metadata Writer", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatApp1, + }, { NULL } /* list terminator */ };
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 736923b8146..61a3fb42a96 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -4221,9 +4221,7 @@ static void test_metadata_App1(void)
hr = CoCreateInstance(&CLSID_WICApp1MetadataWriter, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataWriter, (void **)&writer); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (FAILED(hr)) return;
check_interface(writer, &IID_IWICMetadataWriter, TRUE); check_interface(writer, &IID_IWICMetadataReader, TRUE); @@ -4487,7 +4485,6 @@ static void test_CreateMetadataWriter(void) check_persist_options(writer, 0); hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); IWICMetadataWriter_Release(writer);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 028c167687d..bbdb4c36f73 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -226,6 +226,7 @@ extern HRESULT GpsMetadataWriter_CreateInstance(REFIID iid, void **ppv); extern HRESULT ExifMetadataReader_CreateInstance(REFIID iid, void **ppv); extern HRESULT ExifMetadataWriter_CreateInstance(REFIID iid, void **ppv); extern HRESULT App1MetadataReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT App1MetadataWriter_CreateInstance(REFIID iid, void **ppv); extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv); extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv); extern HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv); diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index 438a39fd2be..84bc2d73f79 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -209,6 +209,13 @@ coclass WICExifMetadataWriter { interface IWICMetadataWriter; } ] coclass WICApp1MetadataReader { interface IWICMetadataReader; }
+[ + helpstring("WIC App1 Metadata Writer"), + threading(both), + uuid(ee366069-1832-420f-b381-0479ad066f19) +] +coclass WICApp1MetadataWriter { interface IWICMetadataWriter; } + [ helpstring("WIC Png cHRM Metadata Reader"), threading(both),