From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/imgfactory.c | 2 +- dlls/windowscodecs/metadatahandler.c | 32 +++++++++++++++++++++----- dlls/windowscodecs/tests/metadata.c | 7 ++++++ dlls/windowscodecs/wincodecs_private.h | 2 ++ 4 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c index 3813843544f..c941344f1aa 100644 --- a/dlls/windowscodecs/imgfactory.c +++ b/dlls/windowscodecs/imgfactory.c @@ -1576,7 +1576,7 @@ static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICCom return *reader ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; }
-static HRESULT create_metadata_writer(REFGUID format, const GUID *vendor, DWORD options, +HRESULT create_metadata_writer(REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer) { struct iterator_context context = { 0 }; diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index 469fdf9b8ca..d464472b48e 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -871,11 +871,10 @@ static HRESULT create_stream_wrapper(IStream *input, ULONG offset, IStream **wra }
static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, const struct IFD_entry *entry, - MetadataItem *item, BOOL resolve_pointer_tags) + MetadataItem *item, bool resolve_pointer_tags, bool is_writer) { BOOL native_byte_order = !(options & WICPersistOptionBigEndian); ULONG count, value, i, bytesread; - IWICMetadataReader *sub_reader; IStream *sub_stream; SHORT type; LARGE_INTEGER pos; @@ -1154,6 +1153,9 @@ 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;
if (!resolve_pointer_tags) break; @@ -1168,8 +1170,25 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, hr = IStream_Seek(sub_stream, pos, STREAM_SEEK_SET, NULL);
if (SUCCEEDED(hr)) - hr = create_metadata_reader(item->id.uiVal == IFD_EXIF_TAG ? &GUID_MetadataFormatExif : &GUID_MetadataFormatGps, - vendor, options | WICMetadataCreationFailUnknown, sub_stream, &sub_reader); + { + 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); + } + + 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)) { @@ -1181,6 +1200,7 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, IStream_Release(sub_stream);
break; + } default: break; } @@ -1189,7 +1209,7 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, }
static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor, - DWORD persist_options, bool resolve_pointer_tags, bool writer, MetadataItem **items, DWORD *item_count) + DWORD persist_options, bool resolve_pointer_tags, bool is_writer, MetadataItem **items, DWORD *item_count) { HRESULT hr; MetadataItem *result; @@ -1268,7 +1288,7 @@ static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor,
for (i = 0; i < count; i++) { - hr = load_IFD_entry(input, vendor, persist_options, &entry[i], &result[i], resolve_pointer_tags); + hr = load_IFD_entry(input, vendor, persist_options, &entry[i], &result[i], resolve_pointer_tags, is_writer); if (FAILED(hr)) { free(entry); diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 3141eb412c7..736923b8146 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -4485,12 +4485,19 @@ static void test_CreateMetadataWriter(void) hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatApp1, NULL, 0, &writer); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 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);
/* Ifd */ hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatIfd, NULL, 0, &writer); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); check_persist_options(writer, 0); + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); IWICMetadataWriter_Release(writer);
IWICComponentFactory_Release(factory); diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index f23ec9a85ee..028c167687d 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -326,6 +326,8 @@ void CDECL decoder_destroy(struct decoder *This);
HRESULT create_metadata_reader(REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader); +HRESULT create_metadata_writer(REFGUID format, const GUID *vendor, DWORD options, + IWICMetadataWriter **writer);
struct encoder_funcs;