Author: akhaldi Date: Wed Jul 22 00:45:26 2015 New Revision: 68543
URL: http://svn.reactos.org/svn/reactos?rev=68543&view=rev Log: [WINDOWSCODECS] Sync with Wine Staging 1.7.47. CORE-9924
Modified: trunk/reactos/dll/win32/windowscodecs/clsfactory.c trunk/reactos/dll/win32/windowscodecs/gifformat.c trunk/reactos/dll/win32/windowscodecs/icnsformat.c trunk/reactos/dll/win32/windowscodecs/imgfactory.c trunk/reactos/dll/win32/windowscodecs/info.c trunk/reactos/dll/win32/windowscodecs/metadatahandler.c trunk/reactos/dll/win32/windowscodecs/pngformat.c trunk/reactos/dll/win32/windowscodecs/regsvr.c trunk/reactos/dll/win32/windowscodecs/stream.c trunk/reactos/dll/win32/windowscodecs/tiffformat.c trunk/reactos/dll/win32/windowscodecs/ungif.c trunk/reactos/dll/win32/windowscodecs/wincodecs_private.h trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/windowscodecs/clsfactory.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/cls... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/clsfactory.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/clsfactory.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -22,7 +22,7 @@
typedef struct { REFCLSID classid; - HRESULT (*constructor)(REFIID,void**); + class_constructor constructor; } classinfo;
static const classinfo wic_classes[] = { @@ -42,6 +42,7 @@ {&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}, @@ -183,3 +184,14 @@ TRACE("<-- %08X\n", ret); return ret; } + +HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) +{ + int i; + + for (i=0; wic_classes[i].classid; i++) + if (IsEqualCLSID(wic_classes[i].classid, clsid)) + return wic_classes[i].constructor(iid, ppv); + + return CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, ppv); +}
Modified: trunk/reactos/dll/win32/windowscodecs/gifformat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/gif... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/gifformat.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/gifformat.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -60,7 +60,7 @@ hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK;
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 9); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 9); if (!result) return E_OUTOFMEMORY;
for (i = 0; i < 9; i++) @@ -165,7 +165,7 @@ hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK;
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 8); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 8); if (!result) return E_OUTOFMEMORY;
for (i = 0; i < 8; i++) @@ -258,7 +258,7 @@ hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK;
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 5); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 5); if (!result) return E_OUTOFMEMORY;
for (i = 0; i < 5; i++) @@ -373,7 +373,7 @@ data_size += subblock_size + 1; }
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 2); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 2); if (!result) { HeapFree(GetProcessHeap(), 0, data); @@ -478,7 +478,7 @@
data[data_size] = 0;
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem)); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); if (!result) { HeapFree(GetProcessHeap(), 0, data); @@ -530,7 +530,8 @@ }
static HRESULT create_metadata_reader(const void *data, int data_size, - const CLSID *clsid, IWICMetadataReader **reader) + class_constructor constructor, + IWICMetadataReader **reader) { HRESULT hr; IWICMetadataReader *metadata_reader; @@ -539,8 +540,7 @@
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void **)&metadata_reader); + hr = constructor(&IID_IWICMetadataReader, (void**)&metadata_reader); if (FAILED(hr)) return hr;
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist); @@ -563,6 +563,7 @@ typedef struct { IWICBitmapDecoder IWICBitmapDecoder_iface; IWICMetadataBlockReader IWICMetadataBlockReader_iface; + IStream *stream; BYTE LSD_data[13]; /* Logical Screen Descriptor */ LONG ref; BOOL initialized; @@ -885,8 +886,7 @@
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
- hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void **)&metadata_reader); + hr = IMDReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader); if (FAILED(hr)) return hr;
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist); @@ -942,7 +942,7 @@
for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++) { - const CLSID *clsid; + class_constructor constructor; const void *data; int data_size;
@@ -956,24 +956,24 @@ } else if (This->frame->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE) { - clsid = &CLSID_WICGifCommentMetadataReader; + constructor = GifCommentReader_CreateInstance; data = This->frame->Extensions.ExtensionBlocks[i].Bytes; data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; } else { - clsid = &CLSID_WICUnknownMetadataReader; + constructor = UnknownMetadataReader_CreateInstance; data = This->frame->Extensions.ExtensionBlocks[i].Bytes; data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; } - return create_metadata_reader(data, data_size, clsid, reader); + return create_metadata_reader(data, data_size, constructor, reader); }
if (gce_index == -1) return E_INVALIDARG;
return create_metadata_reader(This->frame->Extensions.ExtensionBlocks[gce_index].Bytes + 3, This->frame->Extensions.ExtensionBlocks[gce_index].ByteCount - 4, - &CLSID_WICGCEMetadataReader, reader); + GCEReader_CreateInstance, reader); }
static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, @@ -1040,6 +1040,7 @@
if (ref == 0) { + IStream_Release(This->stream); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); DGifCloseFile(This->gif); @@ -1126,6 +1127,9 @@ seek.QuadPart = 0; IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); IStream_Read(pIStream, This->LSD_data, sizeof(This->LSD_data), NULL); + + This->stream = pIStream; + IStream_AddRef(This->stream);
This->initialized = TRUE;
@@ -1361,24 +1365,24 @@
if (index == 0) return create_metadata_reader(This->LSD_data, sizeof(This->LSD_data), - &CLSID_WICLSDMetadataReader, reader); + LSDReader_CreateInstance, reader);
for (i = 0; i < This->gif->Extensions.ExtensionBlockCount; i++) { - const CLSID *clsid; + class_constructor constructor;
if (index != i + 1) continue;
if (This->gif->Extensions.ExtensionBlocks[i].Function == APPLICATION_EXT_FUNC_CODE) - clsid = &CLSID_WICAPEMetadataReader; + constructor = APEReader_CreateInstance; else if (This->gif->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE) - clsid = &CLSID_WICGifCommentMetadataReader; + constructor = GifCommentReader_CreateInstance; else - clsid = &CLSID_WICUnknownMetadataReader; + constructor = UnknownMetadataReader_CreateInstance;
return create_metadata_reader(This->gif->Extensions.ExtensionBlocks[i].Bytes, This->gif->Extensions.ExtensionBlocks[i].ByteCount, - clsid, reader); + constructor, reader); }
return E_INVALIDARG;
Modified: trunk/reactos/dll/win32/windowscodecs/icnsformat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/icn... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/icnsformat.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/icnsformat.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -162,7 +162,7 @@ if (This->icns_image != NULL) HeapFree(GetProcessHeap(), 0, This->icns_image);
- IUnknown_Release((IUnknown*)This->encoder); + IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); HeapFree(GetProcessHeap(), 0, This); }
@@ -380,7 +380,7 @@ if (!This->initialized) return WINCODEC_ERR_WRONGSTATE;
- hr = configure_write_source(iface, pIBitmapSource, &prc, + hr = configure_write_source(iface, pIBitmapSource, prc, &GUID_WICPixelFormat32bppBGRA, This->size, This->size, 1.0, 1.0);
@@ -472,7 +472,7 @@ if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapEncoder, iid)) { - *ppv = This; + *ppv = &This->IWICBitmapEncoder_iface; } else { @@ -622,7 +622,7 @@ frameEncode->committed = FALSE; *ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface; This->outstanding_commits++; - IUnknown_AddRef((IUnknown*)This); + IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface);
end: LeaveCriticalSection(&This->lock); @@ -708,8 +708,8 @@ InitializeCriticalSection(&This->lock); This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock");
- ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); - IUnknown_Release((IUnknown*)This); + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
return ret; }
Modified: trunk/reactos/dll/win32/windowscodecs/imgfactory.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/img... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/imgfactory.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/imgfactory.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -694,7 +694,7 @@ return E_INVALIDARG; }
- hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, option, bitmap); + hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, WICBitmapCacheOnLoad, bitmap); if (hr != S_OK) return hr;
hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
Modified: trunk/reactos/dll/win32/windowscodecs/info.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/inf... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/info.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/info.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -213,7 +213,7 @@ IsEqualIID(&IID_IWICBitmapCodecInfo, iid) || IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid)) { - *ppv = This; + *ppv = &This->IWICBitmapDecoderInfo_iface; } else { @@ -606,8 +606,7 @@
TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
- return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder); + return create_instance(&This->clsid, &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder); }
static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = { @@ -655,7 +654,7 @@ This->classkey = classkey; memcpy(&This->clsid, clsid, sizeof(CLSID));
- *ppIInfo = (IWICComponentInfo*)This; + *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapDecoderInfo_iface; return S_OK; }
@@ -684,7 +683,7 @@ IsEqualIID(&IID_IWICBitmapCodecInfo, iid) || IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid)) { - *ppv = This; + *ppv = &This->IWICBitmapEncoderInfo_iface; } else { @@ -900,8 +899,7 @@
TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
- return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder); + return create_instance(&This->clsid, &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder); }
static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = { @@ -947,7 +945,7 @@ This->classkey = classkey; memcpy(&This->clsid, clsid, sizeof(CLSID));
- *ppIInfo = (IWICComponentInfo*)This; + *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapEncoderInfo_iface; return S_OK; }
@@ -975,7 +973,7 @@ IsEqualIID(&IID_IWICComponentInfo, iid) || IsEqualIID(&IID_IWICFormatConverterInfo ,iid)) { - *ppv = This; + *ppv = &This->IWICFormatConverterInfo_iface; } else { @@ -1108,8 +1106,8 @@
TRACE("(%p,%p)\n", iface, ppIFormatConverter);
- return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICFormatConverter, (void**)ppIFormatConverter); + return create_instance(&This->clsid, &IID_IWICFormatConverter, + (void**)ppIFormatConverter); }
static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid) @@ -1164,7 +1162,7 @@ This->classkey = classkey; memcpy(&This->clsid, clsid, sizeof(CLSID));
- *ppIInfo = (IWICComponentInfo*)This; + *ppIInfo = (IWICComponentInfo *)&This->IWICFormatConverterInfo_iface; return S_OK; }
@@ -1193,7 +1191,7 @@ IsEqualIID(&IID_IWICPixelFormatInfo, iid) || IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid)) { - *ppv = This; + *ppv = &This->IWICPixelFormatInfo2_iface; } else { @@ -1458,7 +1456,7 @@ This->classkey = classkey; memcpy(&This->clsid, clsid, sizeof(CLSID));
- *ppIInfo = (IWICComponentInfo*)This; + *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface; return S_OK; }
@@ -1489,7 +1487,7 @@ IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) || IsEqualIID(&IID_IWICMetadataReaderInfo, riid)) { - *ppv = This; + *ppv = &This->IWICMetadataReaderInfo_iface; } else { @@ -1854,8 +1852,7 @@
TRACE("(%p,%p)\n", iface, reader);
- return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void **)reader); + return create_instance(&This->clsid, &IID_IWICMetadataReader, (void **)reader); }
static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = { @@ -1898,7 +1895,7 @@ This->classkey = classkey; This->clsid = *clsid;
- *info = (IWICComponentInfo *)This; + *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface; return S_OK; }
Modified: trunk/reactos/dll/win32/windowscodecs/metadatahandler.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/met... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/metadatahandler.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/metadatahandler.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -680,7 +680,7 @@ return hr; }
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem)); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); if (!result) { HeapFree(GetProcessHeap(), 0, data); @@ -1110,7 +1110,7 @@ return WINCODEC_ERR_BADMETADATAHEADER; }
- result = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*result)); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(*result)); if (!result) { HeapFree(GetProcessHeap(), 0, entry);
Modified: trunk/reactos/dll/win32/windowscodecs/pngformat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/png... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/pngformat.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/pngformat.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -24,6 +24,11 @@
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]; @@ -38,7 +43,7 @@ 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);
@@ -92,7 +97,7 @@
value_len = data_size - name_len - 1;
- result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem)); + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); name = HeapAlloc(GetProcessHeap(), 0, name_len + 1); value = HeapAlloc(GetProcessHeap(), 0, value_len + 1); if (!result || !name || !value) @@ -134,6 +139,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 @@ -273,10 +340,16 @@ }
typedef struct { + ULARGE_INTEGER ofs, len; + IWICMetadataReader* reader; +} metadata_block_info; + +typedef struct { IWICBitmapDecoder IWICBitmapDecoder_iface; IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; IWICMetadataBlockReader IWICMetadataBlockReader_iface; LONG ref; + IStream *stream; png_structp png_ptr; png_infop info_ptr; png_infop end_info; @@ -287,6 +360,8 @@ const WICPixelFormatGUID *format; BYTE *image_bits; CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */ + ULONG metadata_count; + metadata_block_info* metadata_blocks; } PngDecoder;
static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) @@ -342,16 +417,25 @@ { PngDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); + ULONG i;
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0) { + if (This->stream) + IStream_Release(This->stream); if (This->png_ptr) ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, This->image_bits); + for (i=0; i<This->metadata_count; i++) + { + if (This->metadata_blocks[i].reader) + IWICMetadataReader_Release(This->metadata_blocks[i].reader); + } + HeapFree(GetProcessHeap(), 0, This->metadata_blocks); HeapFree(GetProcessHeap(), 0, This); }
@@ -404,6 +488,10 @@ png_uint_32 transparency; png_color_16p trans_values; jmp_buf jmpbuf; + BYTE chunk_type[4]; + ULONG chunk_size; + ULARGE_INTEGER chunk_start; + ULONG metadata_blocks_size = 0;
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
@@ -586,10 +674,60 @@
ppng_read_end(This->png_ptr, This->end_info);
+ /* Find the metadata chunks in the file. */ + seek.QuadPart = 8; + hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start); + if (FAILED(hr)) goto end; + + do + { + hr = read_png_chunk(pIStream, chunk_type, NULL, &chunk_size); + if (FAILED(hr)) goto end; + + if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' && + memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4)) + { + /* This chunk is considered metadata. */ + if (This->metadata_count == metadata_blocks_size) + { + metadata_block_info* new_metadata_blocks; + ULONG new_metadata_blocks_size; + + new_metadata_blocks_size = 4 + metadata_blocks_size * 2; + new_metadata_blocks = HeapAlloc(GetProcessHeap(), 0, + new_metadata_blocks_size * sizeof(*new_metadata_blocks)); + + if (!new_metadata_blocks) + { + hr = E_OUTOFMEMORY; + goto end; + } + + memcpy(new_metadata_blocks, This->metadata_blocks, + This->metadata_count * sizeof(*new_metadata_blocks)); + + HeapFree(GetProcessHeap(), 0, This->metadata_blocks); + This->metadata_blocks = new_metadata_blocks; + metadata_blocks_size = new_metadata_blocks_size; + } + + This->metadata_blocks[This->metadata_count].ofs = chunk_start; + This->metadata_blocks[This->metadata_count].len.QuadPart = chunk_size + 12; + This->metadata_blocks[This->metadata_count].reader = NULL; + This->metadata_count++; + } + + seek.QuadPart = chunk_start.QuadPart + chunk_size + 12; /* skip data and CRC */ + hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start); + if (FAILED(hr)) goto end; + } while (memcmp(chunk_type, "IEND", 4)); + + This->stream = pIStream; + IStream_AddRef(This->stream); + This->initialized = TRUE;
end: - LeaveCriticalSection(&This->lock);
return hr; @@ -959,17 +1097,65 @@ static HRESULT WINAPI PngDecoder_Block_GetCount(IWICMetadataBlockReader *iface, UINT *pcCount) { - static int once; + PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); + TRACE("%p,%p\n", iface, pcCount); - if (!once++) FIXME("stub\n"); - return E_NOTIMPL; + + if (!pcCount) return E_INVALIDARG; + + *pcCount = This->metadata_count; + + return S_OK; }
static HRESULT WINAPI PngDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT nIndex, IWICMetadataReader **ppIMetadataReader) { - FIXME("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); - return E_NOTIMPL; + PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); + HRESULT hr; + IWICComponentFactory* factory; + IWICStream* stream; + + TRACE("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); + + if (nIndex >= This->metadata_count || !ppIMetadataReader) + return E_INVALIDARG; + + if (!This->metadata_blocks[nIndex].reader) + { + hr = StreamImpl_Create(&stream); + + if (SUCCEEDED(hr)) + { + hr = IWICStream_InitializeFromIStreamRegion(stream, This->stream, + This->metadata_blocks[nIndex].ofs, This->metadata_blocks[nIndex].len); + + if (SUCCEEDED(hr)) + hr = ComponentFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + { + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &GUID_ContainerFormatPng, NULL, WICMetadataCreationAllowUnknown, + (IStream*)stream, &This->metadata_blocks[nIndex].reader); + + IWICComponentFactory_Release(factory); + } + + IWICStream_Release(stream); + } + + if (FAILED(hr)) + { + *ppIMetadataReader = NULL; + return hr; + } + } + + *ppIMetadataReader = This->metadata_blocks[nIndex].reader; + IWICMetadataReader_AddRef(*ppIMetadataReader); + + return S_OK; }
static HRESULT WINAPI PngDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, @@ -1014,10 +1200,13 @@ This->png_ptr = NULL; This->info_ptr = NULL; This->end_info = NULL; + This->stream = NULL; This->initialized = FALSE; This->image_bits = NULL; InitializeCriticalSection(&This->lock); This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock"); + This->metadata_count = 0; + This->metadata_blocks = NULL;
ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
Modified: trunk/reactos/dll/win32/windowscodecs/regsvr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/reg... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/regsvr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/regsvr.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -1483,6 +1483,21 @@ { 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 }, @@ -1577,6 +1592,16 @@ &GUID_MetadataFormatIfd, 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",
Modified: trunk/reactos/dll/win32/windowscodecs/stream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/str... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/stream.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/stream.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -748,7 +748,7 @@ if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IStream, iid) || IsEqualIID(&IID_ISequentialStream, iid) || IsEqualIID(&IID_IWICStream, iid)) { - *ppv = This; + *ppv = &This->IWICStream_iface; IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
Modified: trunk/reactos/dll/win32/windowscodecs/tiffformat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/tif... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/tiffformat.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/tiffformat.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -219,7 +219,7 @@ const WICPixelFormatGUID *format; int bps; int samples; - int bpp; + int bpp, source_bpp; int planar; int indexed; int reverse_bgr; @@ -318,26 +318,54 @@ extra_sample = 0; extra_samples = &extra_sample; } - else - FIXME("ignoring extra alpha %u/%u bps %u\n", extra_sample_count, extra_samples[0], bps); } else if (samples != 1) { - FIXME("unhandled grayscale sample count %u\n", samples); + FIXME("unhandled %dbpp sample count %u\n", bps, samples); return E_FAIL; }
- decode_info->bpp = bps; + decode_info->bpp = bps * samples; + decode_info->source_bpp = decode_info->bpp; switch (bps) { case 1: + if (samples != 1) + { + FIXME("unhandled 1bpp sample count %u\n", samples); + return E_FAIL; + } decode_info->format = &GUID_WICPixelFormatBlackWhite; break; case 4: + if (samples != 1) + { + FIXME("unhandled 4bpp grayscale sample count %u\n", samples); + return E_FAIL; + } decode_info->format = &GUID_WICPixelFormat4bppGray; break; case 8: - decode_info->format = &GUID_WICPixelFormat8bppGray; + if (samples == 1) + decode_info->format = &GUID_WICPixelFormat8bppGray; + else + { + decode_info->bpp = 32; + + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->format = &GUID_WICPixelFormat32bppPBGRA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->format = &GUID_WICPixelFormat32bppBGRA; + break; + default: + FIXME("unhandled extra sample type %u\n", extra_samples[0]); + return E_FAIL; + } + } break; default: FIXME("unhandled greyscale bit count %u\n", bps); @@ -938,6 +966,22 @@ hr = E_FAIL; }
+ /* 8bpp grayscale with extra alpha */ + if (hr == S_OK && This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { + BYTE *src; + DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; + + src = This->cached_tile + This->decode_info.tile_width * This->decode_info.tile_height * 2 - 2; + dst = (DWORD *)(This->cached_tile + This->decode_info.tile_size - 4); + + while (count--) + { + *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24); + src -= 2; + } + } + if (hr == S_OK && This->decode_info.reverse_bgr) { if (This->decode_info.bps == 8) @@ -1218,8 +1262,7 @@
/* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */
- hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void **)&metadata_reader); + hr = IfdMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader); if (FAILED(hr)) return hr;
hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist);
Modified: trunk/reactos/dll/win32/windowscodecs/ungif.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/ung... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/ungif.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/ungif.c [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -491,7 +491,7 @@ * image until empty block (size 0) detected. We use GetCodeNext. */ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) - return GIF_ERROR; + break; while (Dummy != NULL) ; } return GIF_OK;
Modified: trunk/reactos/dll/win32/windowscodecs/wincodecs_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/win... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/wincodecs_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/wincodecs_private.h [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -94,6 +94,9 @@ }; #undef INTERFACE
+HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) DECLSPEC_HIDDEN; + +typedef HRESULT(*class_constructor)(REFIID,void**); extern HRESULT FormatConverter_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT ComponentFactory_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT BmpDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; @@ -175,6 +178,7 @@
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;
Modified: trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/win... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -140,6 +140,13 @@ 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), uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7)
Modified: trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/windowscodecs/win... ============================================================================== --- trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs [iso-8859-1] (original) +++ trunk/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -203,6 +203,10 @@ { 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' } + } '{4B59AFCC-B8C3-408A-B670-89E5FAB6FDA7}' = s 'WIC Png tEXt Metadata Reader' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } @@ -228,4 +232,4 @@ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } } } -} +}
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=6... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Wed Jul 22 00:45:26 2015 @@ -202,7 +202,7 @@ reactos/dll/win32/version # Synced to WineStaging-1.7.47 reactos/dll/win32/wbemdisp # Synced to WineStaging-1.7.47 reactos/dll/win32/wbemprox # Synced to WineStaging-1.7.47 -reactos/dll/win32/windowscodecs # Synced to WineStaging-1.7.37 +reactos/dll/win32/windowscodecs # Synced to WineStaging-1.7.47 reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.7.37 reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.7.47 reactos/dll/win32/wing32 # Out of sync