From: Nikolay Sivov <nsivov(a)codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> --- dlls/windowscodecs/gifformat.c | 55 +++++------- dlls/windowscodecs/metadatahandler.c | 112 ++++++++++--------------- dlls/windowscodecs/pngformat.c | 45 +++++----- dlls/windowscodecs/wincodecs_private.h | 22 ++++- 4 files changed, 111 insertions(+), 123 deletions(-) diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index 25403955284..d3d8678e9f8 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -78,17 +78,13 @@ struct image_descriptor #include "poppack.h" -static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_LSD_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { struct logical_screen_descriptor 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; @@ -149,8 +145,9 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti result[8].value.vt = VT_UI1; result[8].value.bVal = lsd_data.pixel_aspect_ratio; - *items = result; - *count = 9; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 9; return S_OK; } @@ -166,17 +163,13 @@ HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&LSDReader_Vtbl, iid, ppv); } -static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_IMD_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { struct image_descriptor imd_data; HRESULT hr; ULONG bytesread, i; MetadataItem *result; - *items = NULL; - *count = 0; - hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK; @@ -230,8 +223,9 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti result[7].value.vt = VT_UI1; result[7].value.bVal = imd_data.packed & 7; - *items = result; - *count = 8; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 8; return S_OK; } @@ -247,8 +241,7 @@ HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&IMDReader_Vtbl, iid, ppv); } -static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_GCE_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct graphic_control_extension @@ -267,9 +260,6 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti ULONG bytesread, i; MetadataItem *result; - *items = NULL; - *count = 0; - hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK; @@ -308,8 +298,9 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti result[4].value.vt = VT_UI1; result[4].value.bVal = gce_data.transparent_color_index; - *items = result; - *count = 5; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 5; return S_OK; } @@ -325,8 +316,7 @@ HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&GCEReader_Vtbl, iid, ppv); } -static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_APE_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct application_extension @@ -343,9 +333,6 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti BYTE subblock_size; BYTE *data; - *items = NULL; - *count = 0; - hr = IStream_Read(stream, &ape_data, sizeof(ape_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(ape_data)) return S_OK; if (ape_data.extension_introducer != 0x21 || @@ -415,8 +402,9 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti result[1].value.caub.cElems = data_size; result[1].value.caub.pElems = data; - *items = result; - *count = 2; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 2; return S_OK; } @@ -432,8 +420,7 @@ HRESULT APEReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&APEReader_Vtbl, iid, ppv); } -static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_GifComment_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct gif_extension @@ -448,9 +435,6 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO BYTE subblock_size; char *data; - *items = NULL; - *count = 0; - hr = IStream_Read(stream, &ext_data, sizeof(ext_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(ext_data)) return S_OK; if (ext_data.extension_introducer != 0x21 || @@ -509,8 +493,9 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO result->value.vt = VT_LPSTR; result->value.pszVal = data; - *items = result; - *count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; return S_OK; } diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index a33abb48ce1..ebb7a08b0b6 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -33,20 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -typedef struct MetadataHandler { - IWICMetadataWriter IWICMetadataWriter_iface; - LONG ref; - IWICPersistStream IWICPersistStream_iface; - IWICStreamProvider IWICStreamProvider_iface; - const MetadataHandlerVtbl *vtable; - MetadataItem *items; - DWORD item_count; - DWORD persist_options; - IStream *stream; - ULARGE_INTEGER origin; - CRITICAL_SECTION lock; -} MetadataHandler; - static inline MetadataHandler *impl_from_IWICMetadataWriter(IWICMetadataWriter *iface) { return CONTAINING_RECORD(iface, MetadataHandler, IWICMetadataWriter_iface); @@ -69,7 +55,7 @@ static void clear_metadata_item(MetadataItem *item) PropVariantClear(&item->value); } -static void MetadataHandler_FreeItems(MetadataHandler *This) +void MetadataHandler_FreeItems(MetadataHandler *This) { DWORD i; @@ -516,8 +502,6 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, { MetadataHandler *This = impl_from_IWICPersistStream(iface); HRESULT hr = S_OK; - MetadataItem *new_items=NULL; - DWORD item_count=0; LARGE_INTEGER move; TRACE("(%p,%p,%s,%lx)\n", iface, stream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); @@ -530,8 +514,7 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, move.QuadPart = 0; hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, &This->origin); if (SUCCEEDED(hr)) - hr = This->vtable->fnLoad(stream, pguidPreferredVendor, dwPersistOptions, - &new_items, &item_count); + hr = This->vtable->fnLoad(This, stream, pguidPreferredVendor, dwPersistOptions); } if (This->stream) @@ -546,13 +529,6 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, } This->persist_options = dwPersistOptions & WICPersistOptionMask; - if (new_items) - { - MetadataHandler_FreeItems(This); - This->items = new_items; - This->item_count = item_count; - } - LeaveCriticalSection(&This->lock); return hr; @@ -892,8 +868,8 @@ static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, return S_OK; } -static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadUnknownMetadata(MetadataHandler *handler, IStream *input, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; MetadataItem *result; @@ -933,8 +909,9 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, result[0].value.blob.cbSize = bytesread; result[0].value.blob.pBlobData = data; - *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; return S_OK; } @@ -1398,8 +1375,8 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, return hr; } -static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor, - DWORD persist_options, bool resolve_pointer_tags, bool is_writer, MetadataItem **items, DWORD *item_count) +static HRESULT load_ifd_metadata_internal(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD persist_options, bool resolve_pointer_tags, bool is_writer) { HRESULT hr; MetadataItem *result; @@ -1489,64 +1466,66 @@ static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor, free(entry); - *items = result; - *item_count = count; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = count; return S_OK; } -static HRESULT LoadIfdMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadIfdMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, true, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, true, false); } -static HRESULT LoadIfdMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadIfdMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, true, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, true, true); } -static HRESULT LoadExifMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadExifMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, false, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, false); } -static HRESULT LoadExifMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadExifMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, false, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, true); } -static HRESULT LoadGpsMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadGpsMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, false, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, false); } -static HRESULT LoadGpsMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadGpsMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, false, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, true); } -static HRESULT load_app1_metadata_internal(IStream *input, const GUID *vendor, DWORD options, - bool is_writer, MetadataItem **items, DWORD *item_count) +static HRESULT load_app1_metadata_internal(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options, + bool is_writer) { static const char exif_header[] = {'E','x','i','f',0,0}; IWICMetadataReader *ifd_reader = NULL; BOOL native_byte_order; + MetadataItem *result; LARGE_INTEGER move; #include "pshpack2.h" @@ -1613,31 +1592,32 @@ static HRESULT load_app1_metadata_internal(IStream *input, const GUID *vendor, D return hr; } - if (!(*items = calloc(1, sizeof(**items)))) + if (!(result = calloc(1, sizeof(*result)))) { IWICMetadataReader_Release(ifd_reader); return E_OUTOFMEMORY; } - (*items)[0].id.vt = VT_UI2; - (*items)[0].id.uiVal = 0; - (*items)[0].value.vt = VT_UNKNOWN; - (*items)[0].value.punkVal = (IUnknown *)ifd_reader; - *item_count = 1; + result->id.vt = VT_UI2; + result->id.uiVal = 0; + result->value.vt = VT_UNKNOWN; + result->value.punkVal = (IUnknown *)ifd_reader; + + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; return S_OK; } -static HRESULT LoadApp1MetadataReader(IStream *input, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *item_count) +static HRESULT LoadApp1MetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options) { - return load_app1_metadata_internal(input, vendor, options, false, items, item_count); + return load_app1_metadata_internal(handler, input, vendor, options, false); } -static HRESULT LoadApp1MetadataWriter(IStream *input, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *item_count) +static HRESULT LoadApp1MetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options) { - return load_app1_metadata_internal(input, vendor, options, true, items, item_count); + return load_app1_metadata_internal(handler, input, vendor, options, true); } static const MetadataHandlerVtbl IfdMetadataReader_Vtbl = { diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c index 0e69671c9b8..51613f538c3 100644 --- a/dlls/windowscodecs/pngformat.c +++ b/dlls/windowscodecs/pngformat.c @@ -40,8 +40,8 @@ static inline ULONG read_ulong_be(BYTE* data) return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; } -static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadTextMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -92,8 +92,9 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.vt = VT_LPSTR; result[0].value.pszVal = value; - *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; free(data); @@ -111,8 +112,8 @@ 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) +static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -153,8 +154,9 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.vt = VT_UI4; result[0].value.ulVal = gamma; - *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; return S_OK; } @@ -170,8 +172,8 @@ 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) +static HRESULT LoadChrmMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -228,8 +230,9 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, result[i].value.ulVal = read_ulong_be(&data[i*4]); } - *items = result; - *item_count = 8; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 8; free(data); @@ -247,8 +250,8 @@ HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); } -static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadHistMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -293,8 +296,9 @@ static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.caui.cElems = element_count; result[0].value.caui.pElems = elements; - *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1; return S_OK; } @@ -310,8 +314,8 @@ HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&HistReader_Vtbl, iid, ppv); } -static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadTimeMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -377,8 +381,9 @@ static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, result[5].value.vt = VT_UI1; result[5].value.bVal = data[6]; - *items = result; - *item_count = 6; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 6; free(data); diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 89ada4e024c..5cc86d5d663 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -205,15 +205,33 @@ enum metadatahandler_flags METADATAHANDLER_FIXED_ITEMS = 0x2, /* Items cannot be added or removed. */ }; +typedef struct MetadataHandler MetadataHandler; + typedef struct _MetadataHandlerVtbl { DWORD flags; const CLSID *clsid; - HRESULT (*fnLoad)(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count); + HRESULT (*fnLoad)(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options); } MetadataHandlerVtbl; +typedef struct MetadataHandler +{ + IWICMetadataWriter IWICMetadataWriter_iface; + LONG ref; + IWICPersistStream IWICPersistStream_iface; + IWICStreamProvider IWICStreamProvider_iface; + const MetadataHandlerVtbl *vtable; + MetadataItem *items; + DWORD item_count; + DWORD persist_options; + IStream *stream; + ULARGE_INTEGER origin; + CRITICAL_SECTION lock; +} MetadataHandler; + extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv); +extern void MetadataHandler_FreeItems(MetadataHandler *handler); extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv); extern HRESULT UnknownMetadataWriter_CreateInstance(REFIID iid, void** ppv); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7776