From 060ff9c61ae9b7ee5bf84679a88d1bf2a5122cf0 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 24 Sep 2017 11:19:07 +0000 Subject: [PATCH] [PSDK] Update wincodec.idl and winerror.h. [WINDOWSCODECS] Sync with Wine Staging 2.16. CORE-13762 b2229cc windowscodecs: Add support for CMYK to BGR conversion. 22b69e6 windowscodecs: Move JPEG frame image data initialization from Frame::CopyPixels to Decoder::Initialize. (v2) b635fa0 windowscodecs: Move additional processing out of the JPEG decoding loop. 80649c5 windowscodecs: Fix stride calculation in JPEG decoder. 0d88ec1 windowscodecs: Fix IWICBitmapEncoder::SetPalette for a not initialized case in JPEG encoder. 267bca1 windowscodecs: PNGEncoder: Return 32bppRGBA pixel format by default. 8bae213 windowscodecs: Fix 32bppGrayFloat to 8bppGray conversion. 8648aaf wincodecs: Add encoder options for JPEG. 2eeef78 windowscodecs: Fix a memory leak. c092f1a windowscodecs: Add some tests for IWICMetadataQueryReader. 2271ba8 windowscodecs: Add initial implementation of IWICMetadataQueryReader::GetMetadataByName. d3280c8 windowscodecs: Implement IWICBitmapDecoder::GetMetadataQueryReader in the GIF decoder. c94bf3c windowscodecs: Implement IWICMetadataQueryReader::GetLocation. 3059668 windowscodecs: Use PropVariantCompareEx to compare metadata items. f258903 windowscodecs: Implement IWICMetadataQueryReader::GetContainerFormat. 714175e windowscodecs: Implement WICMapSchemaToName. e1eed88 windowscodecs: Implement WICMapShortNameToGuid. 37ae4f2 windowscodecs: Implement WICMapGuidToShortName. cf1269a windowscodecs: Register WICImagingFactory2 interface. svn path=/trunk/; revision=75953 --- reactos/dll/win32/windowscodecs/converter.c | 86 ++- reactos/dll/win32/windowscodecs/gifformat.c | 9 +- reactos/dll/win32/windowscodecs/imgfactory.c | 2 +- reactos/dll/win32/windowscodecs/jpegformat.c | 190 +++--- .../dll/win32/windowscodecs/metadatahandler.c | 29 +- .../dll/win32/windowscodecs/metadataquery.c | 547 +++++++++++++++++- reactos/dll/win32/windowscodecs/pngformat.c | 4 +- reactos/dll/win32/windowscodecs/tiffformat.c | 2 +- .../win32/windowscodecs/wincodecs_private.h | 14 +- .../windowscodecs/windowscodecs_wincodec.idl | 7 + .../windowscodecs/windowscodecs_wincodec.rgs | 8 +- reactos/media/doc/README.WINE | 2 +- reactos/sdk/include/psdk/wincodec.idl | 29 +- reactos/sdk/include/psdk/winerror.h | 39 ++ 14 files changed, 789 insertions(+), 179 deletions(-) diff --git a/reactos/dll/win32/windowscodecs/converter.c b/reactos/dll/win32/windowscodecs/converter.c index 6ef123a1846..23098756a8b 100644 --- a/reactos/dll/win32/windowscodecs/converter.c +++ b/reactos/dll/win32/windowscodecs/converter.c @@ -1072,6 +1072,48 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } return S_OK; + case format_32bppCMYK: + if (prc) + { + BYTE *srcdata; + UINT srcstride, srcdatasize; + + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if (SUCCEEDED(hr)) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y = 0; y < prc->Height; y++) + { + BYTE *cmyk = src; + BYTE *bgr = dst; + + for (x = 0; x < prc->Width; x++) + { + BYTE c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3]; + bgr[0] = (255 - y) * (255 - k) / 255; /* B */ + bgr[1] = (255 - m) * (255 - k) / 255; /* G */ + bgr[2] = (255 - c) * (255 - k) / 255; /* R */ + cmyk += 4; + bgr += 3; + } + src += srcstride; + dst += cbStride; + } + } + + HeapFree(GetProcessHeap(), 0, srcdata); + return hr; + } + return S_OK; + default: FIXME("Unimplemented conversion path!\n"); return WINCODEC_ERR_UNSUPPORTEDOPERATION; @@ -1209,6 +1251,43 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec return S_OK; } + if (source_format == format_32bppGrayFloat) + { + hr = S_OK; + + if (prc) + { + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if (SUCCEEDED(hr)) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y=0; y < prc->Height; y++) + { + float *srcpixel = (float*)src; + BYTE *dstpixel = dst; + + for (x=0; x < prc->Width; x++) + *dstpixel++ = (BYTE)floorf(to_sRGB_component(*srcpixel++) * 255.0f + 0.51f); + + src += srcstride; + dst += cbStride; + } + } + + HeapFree(GetProcessHeap(), 0, srcdata); + } + + return hr; + } + srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; @@ -1229,12 +1308,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec { float gray = (bgr[2] * 0.2126f + bgr[1] * 0.7152f + bgr[0] * 0.0722f) / 255.0f; - /* conversion from 32bppGrayFloat to 24bppBGR has already applied sRGB gamma */ - if (source_format == format_32bppGrayFloat) - gray *= 255.0f; - else - gray = to_sRGB_component(gray) * 255.0f; - + gray = to_sRGB_component(gray) * 255.0f; dst[x] = (BYTE)floorf(gray + 0.51f); bgr += 3; } diff --git a/reactos/dll/win32/windowscodecs/gifformat.c b/reactos/dll/win32/windowscodecs/gifformat.c index d080b88f93b..3a023d49631 100644 --- a/reactos/dll/win32/windowscodecs/gifformat.c +++ b/reactos/dll/win32/windowscodecs/gifformat.c @@ -810,7 +810,7 @@ static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecod if (!ppIMetadataQueryReader) return E_INVALIDARG; - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); } static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, @@ -1239,8 +1239,13 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet static HRESULT WINAPI GifDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, IWICMetadataQueryReader **ppIMetadataQueryReader) { + GifDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + if (!ppIMetadataQueryReader) return E_INVALIDARG; + + return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); } static HRESULT WINAPI GifDecoder_GetPreview(IWICBitmapDecoder *iface, diff --git a/reactos/dll/win32/windowscodecs/imgfactory.c b/reactos/dll/win32/windowscodecs/imgfactory.c index db1bbbc3101..cfb7fc1bf12 100644 --- a/reactos/dll/win32/windowscodecs/imgfactory.c +++ b/reactos/dll/win32/windowscodecs/imgfactory.c @@ -1113,7 +1113,7 @@ static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComp if (!block_reader || !query_reader) return E_INVALIDARG; - return MetadataQueryReader_CreateInstance(block_reader, query_reader); + return MetadataQueryReader_CreateInstance(block_reader, NULL, query_reader); } static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface, diff --git a/reactos/dll/win32/windowscodecs/jpegformat.c b/reactos/dll/win32/windowscodecs/jpegformat.c index 910669abc28..ecbfc01c3cf 100644 --- a/reactos/dll/win32/windowscodecs/jpegformat.c +++ b/reactos/dll/win32/windowscodecs/jpegformat.c @@ -42,6 +42,13 @@ WINE_DECLARE_DEBUG_CHANNEL(jpeg); static void *libjpeg_handle; +static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0}; +static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0}; +static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0}; +static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0}; +static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0}; +static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0}; + #define MAKE_FUNCPTR(f) static typeof(f) * p##f MAKE_FUNCPTR(jpeg_CreateCompress); MAKE_FUNCPTR(jpeg_CreateDecompress); @@ -130,6 +137,7 @@ typedef struct { struct jpeg_error_mgr jerr; struct jpeg_source_mgr source_mgr; BYTE source_buffer[1024]; + UINT bpp, stride; BYTE *image_data; CRITICAL_SECTION lock; } JpegDecoder; @@ -278,6 +286,8 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * int ret; LARGE_INTEGER seek; jmp_buf jmpbuf; + UINT data_size, i; + TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); EnterCriticalSection(&This->lock); @@ -356,6 +366,55 @@ static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream * return E_FAIL; } + if (This->cinfo.out_color_space == JCS_GRAYSCALE) This->bpp = 8; + else if (This->cinfo.out_color_space == JCS_CMYK) This->bpp = 32; + else This->bpp = 24; + + This->stride = (This->bpp * This->cinfo.output_width + 7) / 8; + data_size = This->stride * This->cinfo.output_height; + + This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size); + if (!This->image_data) + { + LeaveCriticalSection(&This->lock); + return E_OUTOFMEMORY; + } + + while (This->cinfo.output_scanline < This->cinfo.output_height) + { + UINT first_scanline = This->cinfo.output_scanline; + UINT max_rows; + JSAMPROW out_rows[4]; + JDIMENSION ret; + + max_rows = min(This->cinfo.output_height-first_scanline, 4); + for (i=0; iimage_data + This->stride * (first_scanline+i); + + ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows); + if (ret == 0) + { + ERR("read_scanlines failed\n"); + LeaveCriticalSection(&This->lock); + return E_FAIL; + } + } + + if (This->bpp == 24) + { + /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ + reverse_bgr8(3, This->image_data, + This->cinfo.output_width, This->cinfo.output_height, + This->stride); + } + + if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) + { + /* Adobe JPEG's have inverted CMYK data. */ + for (i=0; iimage_data[i] ^= 0xff; + } + This->initialized = TRUE; LeaveCriticalSection(&This->lock); @@ -576,98 +635,11 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - UINT bpp; - UINT stride; - UINT data_size; - UINT max_row_needed; - jmp_buf jmpbuf; - WICRect rect; + TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); - if (!prc) - { - rect.X = 0; - rect.Y = 0; - rect.Width = This->cinfo.output_width; - rect.Height = This->cinfo.output_height; - prc = ▭ - } - else - { - if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->cinfo.output_width || - prc->Y+prc->Height > This->cinfo.output_height) - return E_INVALIDARG; - } - - if (This->cinfo.out_color_space == JCS_GRAYSCALE) bpp = 8; - else if (This->cinfo.out_color_space == JCS_CMYK) bpp = 32; - else bpp = 24; - - stride = bpp * This->cinfo.output_width; - data_size = stride * This->cinfo.output_height; - - max_row_needed = prc->Y + prc->Height; - if (max_row_needed > This->cinfo.output_height) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (!This->image_data) - { - This->image_data = HeapAlloc(GetProcessHeap(), 0, data_size); - if (!This->image_data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - } - - This->cinfo.client_data = jmpbuf; - - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - while (max_row_needed > This->cinfo.output_scanline) - { - UINT first_scanline = This->cinfo.output_scanline; - UINT max_rows; - JSAMPROW out_rows[4]; - UINT i; - JDIMENSION ret; - - max_rows = min(This->cinfo.output_height-first_scanline, 4); - for (i=0; iimage_data + stride * (first_scanline+i); - - ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows); - - if (ret == 0) - { - ERR("read_scanlines failed\n"); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - if (bpp == 24) - { - /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ - reverse_bgr8(3, This->image_data + stride * first_scanline, - This->cinfo.output_width, This->cinfo.output_scanline - first_scanline, - stride); - } - - if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) - /* Adobe JPEG's have inverted CMYK data. */ - for (i=0; iimage_data[i] ^= 0xff; - } - - LeaveCriticalSection(&This->lock); - - return copy_pixels(bpp, This->image_data, - This->cinfo.output_width, This->cinfo.output_height, stride, + return copy_pixels(This->bpp, This->image_data, + This->cinfo.output_width, This->cinfo.output_height, This->stride, prc, cbStride, cbBufferSize, pbBuffer); } @@ -681,7 +653,7 @@ static HRESULT WINAPI JpegDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDe if (!ppIMetadataQueryReader) return E_INVALIDARG; - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); } static HRESULT WINAPI JpegDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, @@ -1062,7 +1034,7 @@ static HRESULT WINAPI JpegEncoder_Frame_SetPalette(IWICBitmapFrameEncode *iface, EnterCriticalSection(&This->lock); - if (This->initialized) + if (This->frame_initialized) hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); else hr = WINCODEC_ERR_NOTINITIALIZED; @@ -1399,8 +1371,18 @@ static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface, static HRESULT WINAPI JpegEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette) { + JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + TRACE("(%p,%p)\n", iface, pIPalette); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + EnterCriticalSection(&This->lock); + + hr = This->initialized ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + + return hr; } static HRESULT WINAPI JpegEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) @@ -1420,6 +1402,7 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, { JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); HRESULT hr; + PROPBAG2 opts[6] = {{0}}; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -1437,9 +1420,28 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, return WINCODEC_ERR_NOTINITIALIZED; } + opts[0].pstrName = (LPOLESTR)wszImageQuality; + opts[0].vt = VT_R4; + opts[0].dwType = PROPBAG2_TYPE_DATA; + opts[1].pstrName = (LPOLESTR)wszBitmapTransform; + opts[1].vt = VT_UI1; + opts[1].dwType = PROPBAG2_TYPE_DATA; + opts[2].pstrName = (LPOLESTR)wszLuminance; + opts[2].vt = VT_I4|VT_ARRAY; + opts[2].dwType = PROPBAG2_TYPE_DATA; + opts[3].pstrName = (LPOLESTR)wszChrominance; + opts[3].vt = VT_I4|VT_ARRAY; + opts[3].dwType = PROPBAG2_TYPE_DATA; + opts[4].pstrName = (LPOLESTR)wszJpegYCrCbSubsampling; + opts[4].vt = VT_UI1; + opts[4].dwType = PROPBAG2_TYPE_DATA; + opts[5].pstrName = (LPOLESTR)wszSuppressApp0; + opts[5].vt = VT_BOOL; + opts[5].dwType = PROPBAG2_TYPE_DATA; + if (ppIEncoderOptions) { - hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); + hr = CreatePropertyBag2(opts, 6, ppIEncoderOptions); if (FAILED(hr)) { LeaveCriticalSection(&This->lock); diff --git a/reactos/dll/win32/windowscodecs/metadatahandler.c b/reactos/dll/win32/windowscodecs/metadatahandler.c index 73825a0d625..25f4314720e 100644 --- a/reactos/dll/win32/windowscodecs/metadatahandler.c +++ b/reactos/dll/win32/windowscodecs/metadatahandler.c @@ -198,29 +198,6 @@ static HRESULT WINAPI MetadataHandler_GetValueByIndex(IWICMetadataWriter *iface, return hr; } -/* FiXME: Use propsys.PropVariantCompareEx once it's implemented */ -static int propvar_cmp(const PROPVARIANT *v1, const PROPVARIANT *v2) -{ - LONGLONG value1, value2; - - if (v1->vt == VT_LPSTR && v2->vt == VT_LPSTR) - { - return lstrcmpA(v1->u.pszVal, v2->u.pszVal); - } - - if (v1->vt == VT_LPWSTR && v2->vt == VT_LPWSTR) - { - return lstrcmpiW(v1->u.pwszVal, v2->u.pwszVal); - } - - if (PropVariantToInt64(v1, &value1) != S_OK) return -1; - if (PropVariantToInt64(v2, &value2) != S_OK) return -1; - - value1 -= value2; - if (value1) return value1 < 0 ? -1 : 1; - return 0; -} - static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, const PROPVARIANT *schema, const PROPVARIANT *id, PROPVARIANT *value) { @@ -228,7 +205,7 @@ static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, HRESULT hr = WINCODEC_ERR_PROPERTYNOTFOUND; MetadataHandler *This = impl_from_IWICMetadataWriter(iface); - TRACE("(%p,%p,%p,%p)\n", iface, schema, id, value); + TRACE("(%p,%s,%s,%p)\n", iface, wine_dbgstr_variant((const VARIANT *)schema), wine_dbgstr_variant((const VARIANT *)id), value); if (!id) return E_INVALIDARG; @@ -238,10 +215,10 @@ static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, { if (schema && This->items[i].schema.vt != VT_EMPTY) { - if (propvar_cmp(schema, &This->items[i].schema) != 0) continue; + if (PropVariantCompareEx(schema, &This->items[i].schema, 0, PVCF_USESTRCMPI) != 0) continue; } - if (propvar_cmp(id, &This->items[i].id) != 0) continue; + if (PropVariantCompareEx(id, &This->items[i].id, 0, PVCF_USESTRCMPI) != 0) continue; hr = value ? PropVariantCopy(value, &This->items[i].value) : S_OK; break; diff --git a/reactos/dll/win32/windowscodecs/metadataquery.c b/reactos/dll/win32/windowscodecs/metadataquery.c index 43102daad3e..c45082b2024 100644 --- a/reactos/dll/win32/windowscodecs/metadataquery.c +++ b/reactos/dll/win32/windowscodecs/metadataquery.c @@ -19,12 +19,15 @@ #include "wincodecs_private.h" +#include + +static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name); + typedef struct { IWICMetadataQueryReader IWICMetadataQueryReader_iface; - LONG ref; - IWICMetadataBlockReader *block; + WCHAR *root; } QueryReader; static inline QueryReader *impl_from_IWICMetadataQueryReader(IWICMetadataQueryReader *iface) @@ -70,6 +73,7 @@ static ULONG WINAPI mqr_Release(IWICMetadataQueryReader *iface) if (!ref) { IWICMetadataBlockReader_Release(This->block); + HeapFree(GetProcessHeap(), 0, This->root); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -84,20 +88,501 @@ static HRESULT WINAPI mqr_GetContainerFormat(IWICMetadataQueryReader *iface, GUI return IWICMetadataBlockReader_GetContainerFormat(This->block, format); } -static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, - UINT cchMaxLength, WCHAR *wzNamespace, UINT *pcchActualLength) +static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, UINT len, WCHAR *location, UINT *ret_len) { + static const WCHAR rootW[] = { '/',0 }; QueryReader *This = impl_from_IWICMetadataQueryReader(iface); - FIXME("(%p,%u,%p,%p)\n", This, cchMaxLength, wzNamespace, pcchActualLength); - return E_NOTIMPL; + const WCHAR *root; + UINT actual_len; + + TRACE("(%p,%u,%p,%p)\n", This, len, location, ret_len); + + if (!ret_len) return E_INVALIDARG; + + root = This->root ? This->root : rootW; + actual_len = lstrlenW(root) + 1; + + if (location) + { + if (len < actual_len) + return WINCODEC_ERR_INSUFFICIENTBUFFER; + + memcpy(location, root, actual_len * sizeof(WCHAR)); + } + + *ret_len = actual_len; + + return S_OK; } -static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, - LPCWSTR wzName, PROPVARIANT *pvarValue) +struct string_t +{ + const WCHAR *str; + int len; +}; + +static const struct +{ + int len; + WCHAR str[10]; + VARTYPE vt; +} str2vt[] = +{ + { 4, {'c','h','a','r'}, VT_I1 }, + { 5, {'u','c','h','a','r'}, VT_UI1 }, + { 5, {'s','h','o','r','t'}, VT_I2 }, + { 6, {'u','s','h','o','r','t'}, VT_UI2 }, + { 4, {'l','o','n','g'}, VT_I4 }, + { 5, {'u','l','o','n','g'}, VT_UI4 }, + { 3, {'i','n','t'}, VT_I4 }, + { 4, {'u','i','n','t'}, VT_UI4 }, + { 8, {'l','o','n','g','l','o','n','g'}, VT_I8 }, + { 9, {'u','l','o','n','g','l','o','n','g'}, VT_UI8 }, + { 5, {'f','l','o','a','t'}, VT_R4 }, + { 6, {'d','o','u','b','l','e'}, VT_R8 }, + { 3, {'s','t','r'}, VT_LPSTR }, + { 4, {'w','s','t','r'}, VT_LPWSTR }, + { 4, {'g','u','i','d'}, VT_CLSID }, + { 4, {'b','o','o','l'}, VT_BOOL } +}; + +static VARTYPE map_type(struct string_t *str) +{ + UINT i; + + for (i = 0; i < sizeof(str2vt)/sizeof(str2vt[0]); i++) + { + if (str2vt[i].len == str->len) + { + if (CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, + str->str, str->len, str2vt[i].str, str2vt[i].len) == CSTR_EQUAL) + return str2vt[i].vt; + } + } + + WARN("type %s is not recognized\n", wine_dbgstr_wn(str->str, str->len)); + + return VT_ILLEGAL; +} + +static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *schema, int *idx) +{ + const WCHAR *start, *end, *p; + WCHAR *bstr; + struct string_t next_elem; + HRESULT hr; + + TRACE("%s, len %d\n", wine_dbgstr_wn(elem->str, elem->len), elem->len); + + PropVariantInit(id); + PropVariantInit(schema); + + if (!elem->len) return S_OK; + + start = elem->str; + + if (*start == '[') + { + WCHAR *idx_end; + + if (start[1] < '0' || start[1] > '9') return DISP_E_TYPEMISMATCH; + + *idx = strtolW(start + 1, &idx_end, 10); + if (idx_end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; + if (*idx_end != ']') return WINCODEC_ERR_INVALIDQUERYREQUEST; + if (*idx < 0) return WINCODEC_ERR_INVALIDQUERYREQUEST; + end = idx_end + 1; + + next_elem.str = end; + next_elem.len = elem->len - (end - start); + hr = get_token(&next_elem, id, schema, idx); + if (hr != S_OK) + { + TRACE("get_token error %#x\n", hr); + return hr; + } + elem->len = (end - start) + next_elem.len; + + TRACE("indexed %s [%d]\n", wine_dbgstr_wn(elem->str, elem->len), *idx); + return S_OK; + } + else if (*start == '{') + { + VARTYPE vt; + PROPVARIANT next_token; + + end = memchrW(start + 1, '=', elem->len - 1); + if (!end) return WINCODEC_ERR_INVALIDQUERYREQUEST; + if (end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; + + next_elem.str = start + 1; + next_elem.len = end - start - 1; + vt = map_type(&next_elem); + TRACE("type %s => %d\n", wine_dbgstr_wn(next_elem.str, next_elem.len), vt); + if (vt == VT_ILLEGAL) return WINCODEC_ERR_WRONGSTATE; + + next_token.vt = VT_BSTR; + next_token.u.bstrVal = SysAllocStringLen(NULL, elem->len - (end - start) + 1); + if (!next_token.u.bstrVal) return E_OUTOFMEMORY; + + bstr = next_token.u.bstrVal; + + end++; + p = end; + while (*end && *end != '}' && end - start < elem->len) + { + if (*end == '\\') end++; + *bstr++ = *end++; + } + if (*end != '}') + { + PropVariantClear(&next_token); + return WINCODEC_ERR_INVALIDQUERYREQUEST; + } + *bstr = 0; + TRACE("schema/id %s\n", wine_dbgstr_w(next_token.u.bstrVal)); + + if (vt == VT_CLSID) + { + id->vt = VT_CLSID; + id->u.puuid = CoTaskMemAlloc(sizeof(GUID)); + if (!id->u.puuid) + { + PropVariantClear(&next_token); + return E_OUTOFMEMORY; + } + + hr = UuidFromStringW(next_token.u.bstrVal, id->u.puuid); + } + else + hr = PropVariantChangeType(id, &next_token, 0, vt); + PropVariantClear(&next_token); + if (hr != S_OK) + { + PropVariantClear(id); + PropVariantClear(schema); + return hr; + } + + end++; + if (*end == ':') + { + PROPVARIANT next_id, next_schema; + int next_idx = 0; + + next_elem.str = end + 1; + next_elem.len = elem->len - (end - start + 1); + hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); + if (hr != S_OK) + { + TRACE("get_token error %#x\n", hr); + return hr; + } + elem->len = (end - start + 1) + next_elem.len; + + TRACE("id %s [%d]\n", wine_dbgstr_wn(elem->str, elem->len), *idx); + + if (next_schema.vt != VT_EMPTY) + { + PropVariantClear(&next_id); + PropVariantClear(&next_schema); + return WINCODEC_ERR_WRONGSTATE; + } + + *schema = *id; + *id = next_id; + + return S_OK; + } + + elem->len = end - start; + return S_OK; + } + + end = memchrW(start, '/', elem->len); + if (!end) end = start + elem->len; + + p = memchrW(start, ':', end - start); + if (p) + { + next_elem.str = p + 1; + next_elem.len = end - p - 1; + + elem->len = p - start; + } + else + elem->len = end - start; + + id->vt = VT_BSTR; + id->u.bstrVal = SysAllocStringLen(NULL, elem->len + 1); + if (!id->u.bstrVal) return E_OUTOFMEMORY; + + bstr = id->u.bstrVal; + p = elem->str; + while (p - elem->str < elem->len) + { + if (*p == '\\') p++; + *bstr++ = *p++; + } + *bstr = 0; + TRACE("%s [%d]\n", wine_dbgstr_variant((VARIANT *)id), *idx); + + if (*p == ':') + { + PROPVARIANT next_id, next_schema; + int next_idx = 0; + + hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); + if (hr != S_OK) + { + TRACE("get_token error %#x\n", hr); + PropVariantClear(id); + PropVariantClear(schema); + return hr; + } + elem->len += next_elem.len + 1; + + TRACE("id %s [%d]\n", wine_dbgstr_wn(elem->str, elem->len), *idx); + + if (next_schema.vt != VT_EMPTY) + { + PropVariantClear(&next_id); + PropVariantClear(&next_schema); + PropVariantClear(id); + PropVariantClear(schema); + return WINCODEC_ERR_WRONGSTATE; + } + + *schema = *id; + *id = next_id; + } + + return S_OK; +} + +static HRESULT find_reader_from_block(IWICMetadataBlockReader *block_reader, UINT index, + GUID *guid, IWICMetadataReader **reader) +{ + HRESULT hr; + GUID format; + IWICMetadataReader *new_reader; + UINT count, i, matched_index; + + *reader = NULL; + + hr = IWICMetadataBlockReader_GetCount(block_reader, &count); + if (hr != S_OK) return hr; + + matched_index = 0; + + for (i = 0; i < count; i++) + { + hr = IWICMetadataBlockReader_GetReaderByIndex(block_reader, i, &new_reader); + if (hr != S_OK) return hr; + + hr = IWICMetadataReader_GetMetadataFormat(new_reader, &format); + if (hr == S_OK) + { + if (IsEqualGUID(&format, guid)) + { + if (matched_index == index) + { + *reader = new_reader; + return S_OK; + } + + matched_index++; + } + } + + IWICMetadataReader_Release(new_reader); + if (hr != S_OK) return hr; + } + + return WINCODEC_ERR_PROPERTYNOTFOUND; +} + +static HRESULT get_next_reader(IWICMetadataReader *reader, UINT index, + GUID *guid, IWICMetadataReader **new_reader) +{ + HRESULT hr; + PROPVARIANT schema, id, value; + + *new_reader = NULL; + + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + + if (index) + { + schema.vt = VT_UI2; + schema.u.uiVal = index; + } + + id.vt = VT_CLSID; + id.u.puuid = guid; + hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); + if (hr != S_OK) return hr; + + if (value.vt == VT_UNKNOWN) + hr = IUnknown_QueryInterface(value.u.punkVal, &IID_IWICMetadataReader, (void **)new_reader); + else + hr = WINCODEC_ERR_UNEXPECTEDMETADATATYPE; + + PropVariantClear(&value); + return hr; +} + +static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCWSTR query, PROPVARIANT *value) { QueryReader *This = impl_from_IWICMetadataQueryReader(iface); - FIXME("(%p,%s,%p)\n", This, wine_dbgstr_w(wzName), pvarValue); - return WINCODEC_ERR_PROPERTYNOTFOUND; + struct string_t elem; + WCHAR *full_query; + const WCHAR *p; + int index, len; + PROPVARIANT tk_id, tk_schema, new_value; + GUID guid; + IWICMetadataReader *reader; + HRESULT hr = S_OK; + + TRACE("(%p,%s,%p)\n", This, wine_dbgstr_w(query), value); + + len = lstrlenW(query) + 1; + if (This->root) len += lstrlenW(This->root); + full_query = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + full_query[0] = 0; + if (This->root) + lstrcpyW(full_query, This->root); + lstrcatW(full_query, query); + + PropVariantInit(&tk_id); + PropVariantInit(&tk_schema); + PropVariantInit(&new_value); + + reader = NULL; + p = full_query; + + while (*p) + { + if (*p != '/') + { + WARN("query should start with '/'\n"); + hr = WINCODEC_ERR_PROPERTYNOTSUPPORTED; + break; + } + + p++; + + index = 0; + elem.str = p; + elem.len = lstrlenW(p); + hr = get_token(&elem, &tk_id, &tk_schema, &index); + if (hr != S_OK) + { + WARN("get_token error %#x\n", hr); + break; + } + TRACE("parsed %d characters: %s, index %d\n", elem.len, wine_dbgstr_wn(elem.str, elem.len), index); + TRACE("id %s, schema %s\n", wine_dbgstr_variant((VARIANT *)&tk_id), wine_dbgstr_variant((VARIANT *)&tk_schema)); + + if (!elem.len) break; + + if (tk_id.vt == VT_CLSID || (tk_id.vt == VT_BSTR && WICMapShortNameToGuid(tk_id.u.bstrVal, &guid) == S_OK)) + { + WCHAR *root; + + if (tk_schema.vt != VT_EMPTY) + { + FIXME("unsupported schema vt %u\n", tk_schema.vt); + PropVariantClear(&tk_schema); + } + + if (tk_id.vt == VT_CLSID) guid = *tk_id.u.puuid; + + if (reader) + { + IWICMetadataReader *new_reader; + + hr = get_next_reader(reader, index, &guid, &new_reader); + IWICMetadataReader_Release(reader); + reader = new_reader; + } + else + hr = find_reader_from_block(This->block, index, &guid, &reader); + + if (hr != S_OK) break; + + root = SysAllocStringLen(NULL, elem.str + elem.len - full_query + 2); + if (!root) + { + hr = E_OUTOFMEMORY; + break; + } + lstrcpynW(root, full_query, p - full_query + elem.len + 1); + + PropVariantClear(&new_value); + new_value.vt = VT_UNKNOWN; + hr = MetadataQueryReader_CreateInstance(This->block, root, (IWICMetadataQueryReader **)&new_value.u.punkVal); + SysFreeString(root); + if (hr != S_OK) break; + } + else + { + PROPVARIANT schema, id; + + if (!reader) + { + hr = WINCODEC_ERR_INVALIDQUERYREQUEST; + break; + } + + if (tk_schema.vt == VT_BSTR) + { + hr = IWICMetadataReader_GetMetadataFormat(reader, &guid); + if (hr != S_OK) break; + + schema.vt = VT_LPWSTR; + schema.u.pwszVal = (LPWSTR)map_shortname_to_schema(&guid, tk_schema.u.bstrVal); + if (!schema.u.pwszVal) + schema.u.pwszVal = tk_schema.u.bstrVal; + } + else + schema = tk_schema; + + if (tk_id.vt == VT_BSTR) + { + id.vt = VT_LPWSTR; + id.u.pwszVal = tk_id.u.bstrVal; + } + else + id = tk_id; + + PropVariantClear(&new_value); + hr = IWICMetadataReader_GetValue(reader, &schema, &id, &new_value); + if (hr != S_OK) break; + } + + p += elem.len; + + PropVariantClear(&tk_id); + PropVariantClear(&tk_schema); + } + + if (reader) + IWICMetadataReader_Release(reader); + + PropVariantClear(&tk_id); + PropVariantClear(&tk_schema); + + if (hr == S_OK) + *value = new_value; + else + PropVariantClear(&new_value); + + HeapFree(GetProcessHeap(), 0, full_query); + + return hr; } static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface, @@ -118,7 +603,7 @@ static IWICMetadataQueryReaderVtbl mqr_vtbl = { mqr_GetEnumerator }; -HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, IWICMetadataQueryReader **out) +HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const WCHAR *root, IWICMetadataQueryReader **out) { QueryReader *obj; @@ -132,6 +617,8 @@ HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, IWICMet IWICMetadataBlockReader_AddRef(mbr); obj->block = mbr; + obj->root = root ? heap_strdupW(root) : NULL; + *out = &obj->IWICMetadataQueryReader_iface; return S_OK; @@ -250,14 +737,14 @@ HRESULT WINAPI WICMapGuidToShortName(REFGUID guid, UINT len, WCHAR *name, UINT * { if (!len) return E_INVALIDARG; - len = min(len - 1, strlenW(guid2name[i].name)); + len = min(len - 1, lstrlenW(guid2name[i].name)); memcpy(name, guid2name[i].name, len * sizeof(WCHAR)); name[len] = 0; - if (len < strlenW(guid2name[i].name)) + if (len < lstrlenW(guid2name[i].name)) return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } - if (ret_len) *ret_len = strlenW(guid2name[i].name) + 1; + if (ret_len) *ret_len = lstrlenW(guid2name[i].name) + 1; return S_OK; } } @@ -265,7 +752,7 @@ HRESULT WINAPI WICMapGuidToShortName(REFGUID guid, UINT len, WCHAR *name, UINT * return WINCODEC_ERR_PROPERTYNOTFOUND; } -HRESULT WINAPI WICMapShortNameToGuid(const WCHAR *name, GUID *guid) +HRESULT WINAPI WICMapShortNameToGuid(PCWSTR name, GUID *guid) { UINT i; @@ -275,7 +762,7 @@ HRESULT WINAPI WICMapShortNameToGuid(const WCHAR *name, GUID *guid) for (i = 0; i < sizeof(guid2name)/sizeof(guid2name[0]); i++) { - if (!strcmpiW(name, guid2name[i].name)) + if (!lstrcmpiW(name, guid2name[i].name)) { *guid = *guid2name[i].guid; return S_OK; @@ -372,7 +859,27 @@ static const struct { MPReg, MPReg_scheme } }; -HRESULT WINAPI WICMapSchemaToName(REFGUID format, const WCHAR *schema, UINT len, WCHAR *name, UINT *ret_len) +static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name) +{ + UINT i; + + /* It appears that the only metadata formats + * that support schemas are xmp and xmpstruct. + */ + if (!IsEqualGUID(format, &GUID_MetadataFormatXMP) && + !IsEqualGUID(format, &GUID_MetadataFormatXMPStruct)) + return NULL; + + for (i = 0; i < sizeof(name2schema)/sizeof(name2schema[0]); i++) + { + if (!lstrcmpW(name2schema[i].name, name)) + return name2schema[i].schema; + } + + return NULL; +} + +HRESULT WINAPI WICMapSchemaToName(REFGUID format, LPWSTR schema, UINT len, WCHAR *name, UINT *ret_len) { UINT i; @@ -390,13 +897,13 @@ HRESULT WINAPI WICMapSchemaToName(REFGUID format, const WCHAR *schema, UINT len, for (i = 0; i < sizeof(name2schema)/sizeof(name2schema[0]); i++) { - if (!strcmpW(name2schema[i].schema, schema)) + if (!lstrcmpW(name2schema[i].schema, schema)) { if (name) { if (!len) return E_INVALIDARG; - len = min(len - 1, strlenW(name2schema[i].name)); + len = min(len - 1, lstrlenW(name2schema[i].name)); memcpy(name, name2schema[i].name, len * sizeof(WCHAR)); name[len] = 0; @@ -404,7 +911,7 @@ HRESULT WINAPI WICMapSchemaToName(REFGUID format, const WCHAR *schema, UINT len, return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } - if (ret_len) *ret_len = strlenW(name2schema[i].name) + 1; + if (ret_len) *ret_len = lstrlenW(name2schema[i].name) + 1; return S_OK; } } diff --git a/reactos/dll/win32/windowscodecs/pngformat.c b/reactos/dll/win32/windowscodecs/pngformat.c index 65e2da4d86b..175642b2952 100644 --- a/reactos/dll/win32/windowscodecs/pngformat.c +++ b/reactos/dll/win32/windowscodecs/pngformat.c @@ -1085,7 +1085,7 @@ static HRESULT WINAPI PngDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDec if (!ppIMetadataQueryReader) return E_INVALIDARG; - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); } static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, @@ -1307,6 +1307,7 @@ struct png_pixelformat { }; static const struct png_pixelformat formats[] = { + {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1}, {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0}, {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0}, @@ -1314,7 +1315,6 @@ static const struct png_pixelformat formats[] = { {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0}, {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0}, {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1}, - {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0}, {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0}, {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0}, diff --git a/reactos/dll/win32/windowscodecs/tiffformat.c b/reactos/dll/win32/windowscodecs/tiffformat.c index da5a82ea0df..740de4955b9 100644 --- a/reactos/dll/win32/windowscodecs/tiffformat.c +++ b/reactos/dll/win32/windowscodecs/tiffformat.c @@ -1373,7 +1373,7 @@ static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDeco if (!ppIMetadataQueryReader) return E_INVALIDARG; - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); } static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, diff --git a/reactos/dll/win32/windowscodecs/wincodecs_private.h b/reactos/dll/win32/windowscodecs/wincodecs_private.h index 6f9a6f5bf92..96ee8fd0696 100644 --- a/reactos/dll/win32/windowscodecs/wincodecs_private.h +++ b/reactos/dll/win32/windowscodecs/wincodecs_private.h @@ -251,9 +251,17 @@ extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; - -extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, IWICMetadataQueryReader **out) DECLSPEC_HIDDEN; - +extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, const WCHAR *, IWICMetadataQueryReader **) DECLSPEC_HIDDEN; extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile) DECLSPEC_HIDDEN; +static inline WCHAR *heap_strdupW(const WCHAR *src) +{ + WCHAR *dst; + SIZE_T len; + if (!src) return NULL; + len = (strlenW(src) + 1) * sizeof(WCHAR); + if ((dst = HeapAlloc(GetProcessHeap(), 0, len))) memcpy(dst, src, len); + return dst; +} + #endif /* WINCODECS_PRIVATE_H */ diff --git a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl index 1681b1de19e..fec63d04e13 100644 --- a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl +++ b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.idl @@ -34,6 +34,13 @@ coclass PSFactoryBuffer { interface IFactoryBuffer; } ] coclass WICImagingFactory { interface IWICImagingFactory; } +[ + helpstring("WIC Imaging Factory 2"), + threading(both), + uuid(317d06e8-5f24-433d-bdf7-79ce68d8abc2) +] +coclass WICImagingFactory2 { interface IWICImagingFactory2; } + [ helpstring("WIC BMP Decoder"), threading(both), diff --git a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs index e619dfc39b1..adfe66edd1e 100644 --- a/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs +++ b/reactos/dll/win32/windowscodecs/windowscodecs_wincodec.rgs @@ -143,6 +143,10 @@ HKCR { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } } + '{317D06E8-5F24-433D-BDF7-79CE68D8ABC2}' = s 'WIC Imaging Factory 2' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } '{6B462062-7CBF-400D-9FDB-813DD10F2778}' = s 'WIC BMP Decoder' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } @@ -163,10 +167,6 @@ HKCR { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } } - '{114F5598-0B22-40A0-86A1-C83EA495ADBD}' = s 'WIC GIF Encoder' - { - InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } - } '{C61BFCDF-2E0F-4AAD-A8D7-E06BAFEBCDFE}' = s 'WIC ICO Decoder' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 6b4eb57990c..dcfaa1f6383 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -196,7 +196,7 @@ reactos/dll/win32/version # Synced to WineStaging-2.9 reactos/dll/win32/vssapi # Synced to WineStaging-2.9 reactos/dll/win32/wbemdisp # Synced to WineStaging-2.16 reactos/dll/win32/wbemprox # Synced to WineStaging-2.16 -reactos/dll/win32/windowscodecs # Synced to WineStaging-2.9 +reactos/dll/win32/windowscodecs # Synced to WineStaging-2.16 reactos/dll/win32/windowscodecsext # Synced to WineStaging-2.9 reactos/dll/win32/winemp3.acm # Synced to WineStaging-2.16 reactos/dll/win32/wing32 # Synced to WineStaging-2.9 diff --git a/reactos/sdk/include/psdk/wincodec.idl b/reactos/sdk/include/psdk/wincodec.idl index 15d64a59c93..3bb635067bd 100644 --- a/reactos/sdk/include/psdk/wincodec.idl +++ b/reactos/sdk/include/psdk/wincodec.idl @@ -146,6 +146,14 @@ typedef enum WICComponentEnumerateOptions { WICComponentEnumerateDisabled = 0x80000000 } WICComponentEnumerateOptions; +typedef enum WICJpegYCrCbSubsamplingOption { + WICJpegYCrCbSubsamplingDefault = 0x00000000, + WICJpegYCrCbSubsampling420 = 0x00000001, + WICJpegYCrCbSubsampling422 = 0x00000002, + WICJpegYCrCbSubsampling444 = 0x00000003, + WICJpegYCrCbSubsampling440 = 0x00000004 +} WICJpegYCrCbSubsamplingOption; + typedef enum WICPixelFormatNumericRepresentation { WICPixelFormatNumericRepresentationUnspecified = 0x00000000, WICPixelFormatNumericRepresentationIndexed = 0x00000001, @@ -241,23 +249,6 @@ typedef struct WICBitmapPattern { typedef UINT32 WICColor; -cpp_quote("#define WINCODEC_ERR_WRONGSTATE 0x88982f04") -cpp_quote("#define WINCODEC_ERR_VALUEOUTOFRANGE 0x88982f05") -cpp_quote("#define WINCODEC_ERR_NOTINITIALIZED 0x88982f0c") -cpp_quote("#define WINCODEC_ERR_ALREADYLOCKED 0x88982f0d") -cpp_quote("#define WINCODEC_ERR_PROPERTYNOTFOUND 0x88982f40") -cpp_quote("#define WINCODEC_ERR_CODECNOTHUMBNAIL 0x88982f44") -cpp_quote("#define WINCODEC_ERR_PALETTEUNAVAILABLE 0x88982f45") -cpp_quote("#define WINCODEC_ERR_COMPONENTNOTFOUND 0x88982f50") -cpp_quote("#define WINCODEC_ERR_BADIMAGE 0x88982f60") -cpp_quote("#define WINCODEC_ERR_FRAMEMISSING 0x88982f62") -cpp_quote("#define WINCODEC_ERR_BADMETADATAHEADER 0x88982f63") -cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT 0x88982f80") -cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDOPERATION 0x88982f81") -cpp_quote("#define WINCODEC_ERR_INSUFFICIENTBUFFER 0x88982f8c") -cpp_quote("#define WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE 0x88982f8e") -cpp_quote("#define WINCODEC_ERR_WIN32ERROR 0x88982f94") - interface IWICPalette; [ @@ -1024,8 +1015,8 @@ cpp_quote("HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, RE cpp_quote("HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, WICSectionAccessLevel access, IWICBitmap **bitmap);") cpp_quote("HRESULT WINAPI WICMapGuidToShortName(REFGUID,UINT,WCHAR *,UINT *);") -cpp_quote("HRESULT WINAPI WICMapShortNameToGuid(const WCHAR *,GUID *);") -cpp_quote("HRESULT WINAPI WICMapSchemaToName(REFGUID,const WCHAR *,UINT,WCHAR *,UINT *);") +cpp_quote("HRESULT WINAPI WICMapShortNameToGuid(PCWSTR,GUID *);") +cpp_quote("HRESULT WINAPI WICMapSchemaToName(REFGUID,LPWSTR,UINT,WCHAR *,UINT *);") cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);") cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);") diff --git a/reactos/sdk/include/psdk/winerror.h b/reactos/sdk/include/psdk/winerror.h index 0dd17ccf0e6..c1ce98d1d38 100644 --- a/reactos/sdk/include/psdk/winerror.h +++ b/reactos/sdk/include/psdk/winerror.h @@ -3268,7 +3268,46 @@ #define SCARD_W_CACHE_ITEM_STALE _HRESULT_TYPEDEF_(0x80100071L) #define SCARD_W_CACHE_ITEM_TOO_BIG _HRESULT_TYPEDEF_(0x80100072L) +#define WINCODEC_ERR_WRONGSTATE _HRESULT_TYPEDEF_(0x88982f04) +#define WINCODEC_ERR_VALUEOUTOFRANGE _HRESULT_TYPEDEF_(0x88982f05) #define WINCODEC_ERR_UNKNOWNIMAGEFORMAT _HRESULT_TYPEDEF_(0x88982f07) +#define WINCODEC_ERR_UNSUPPORTEDVERSION _HRESULT_TYPEDEF_(0x88982f0b) +#define WINCODEC_ERR_NOTINITIALIZED _HRESULT_TYPEDEF_(0x88982f0c) +#define WINCODEC_ERR_ALREADYLOCKED _HRESULT_TYPEDEF_(0x88982f0d) +#define WINCODEC_ERR_PROPERTYNOTFOUND _HRESULT_TYPEDEF_(0x88982f40) +#define WINCODEC_ERR_PROPERTYNOTSUPPORTED _HRESULT_TYPEDEF_(0x88982f41) +#define WINCODEC_ERR_PROPERTYSIZE _HRESULT_TYPEDEF_(0x88982f42) +#define WINCODEC_ERR_CODECPRESENT _HRESULT_TYPEDEF_(0x88982f43) +#define WINCODEC_ERR_CODECNOTHUMBNAIL _HRESULT_TYPEDEF_(0x88982f44) +#define WINCODEC_ERR_PALETTEUNAVAILABLE _HRESULT_TYPEDEF_(0x88982f45) +#define WINCODEC_ERR_CODECTOOMANYSCANLINES _HRESULT_TYPEDEF_(0x88982f46) +#define WINCODEC_ERR_INTERNALERROR _HRESULT_TYPEDEF_(0x88982f48) +#define WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS _HRESULT_TYPEDEF_(0x88982f49) +#define WINCODEC_ERR_COMPONENTNOTFOUND _HRESULT_TYPEDEF_(0x88982f50) +#define WINCODEC_ERR_IMAGESIZEOUTOFRANGE _HRESULT_TYPEDEF_(0x88982f51) +#define WINCODEC_ERR_TOOMUCHMETADATA _HRESULT_TYPEDEF_(0x88982f52) +#define WINCODEC_ERR_BADIMAGE _HRESULT_TYPEDEF_(0x88982f60) +#define WINCODEC_ERR_BADHEADER _HRESULT_TYPEDEF_(0x88982f61) +#define WINCODEC_ERR_FRAMEMISSING _HRESULT_TYPEDEF_(0x88982f62) +#define WINCODEC_ERR_BADMETADATAHEADER _HRESULT_TYPEDEF_(0x88982f63) +#define WINCODEC_ERR_BADSTREAMDATA _HRESULT_TYPEDEF_(0x88982f70) +#define WINCODEC_ERR_STREAMWRITE _HRESULT_TYPEDEF_(0x88982f71) +#define WINCODEC_ERR_STREAMREAD _HRESULT_TYPEDEF_(0x88982f72) +#define WINCODEC_ERR_STREAMNOTAVAILABLE _HRESULT_TYPEDEF_(0x88982f73) +#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT _HRESULT_TYPEDEF_(0x88982f80) +#define WINCODEC_ERR_UNSUPPORTEDOPERATION _HRESULT_TYPEDEF_(0x88982f81) +#define WINCODEC_ERR_INVALIDREGISTRATION _HRESULT_TYPEDEF_(0x88982f8a) +#define WINCODEC_ERR_COMPONENTINITIALIZEFAILURE _HRESULT_TYPEDEF_(0x88982f8b) +#define WINCODEC_ERR_INSUFFICIENTBUFFER _HRESULT_TYPEDEF_(0x88982f8c) +#define WINCODEC_ERR_DUPLICATEMETADATAPRESENT _HRESULT_TYPEDEF_(0x88982f8d) +#define WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE _HRESULT_TYPEDEF_(0x88982f8e) +#define WINCODEC_ERR_UNEXPECTEDSIZE _HRESULT_TYPEDEF_(0x88982f8f) +#define WINCODEC_ERR_INVALIDQUERYREQUEST _HRESULT_TYPEDEF_(0x88982f90) +#define WINCODEC_ERR_UNEXPECTEDMETADATATYPE _HRESULT_TYPEDEF_(0x88982f91) +#define WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT _HRESULT_TYPEDEF_(0x88982f92) +#define WINCODEC_ERR_INVALIDQUERYCHARACTER _HRESULT_TYPEDEF_(0x88982f93) +#define WINCODEC_ERR_WIN32ERROR _HRESULT_TYPEDEF_(0x88982f94) +#define WINCODEC_ERR_INVALIDPROGRESSIVELEVEL _HRESULT_TYPEDEF_(0x88982f95) #define ERROR_AUDITING_DISABLED _HRESULT_TYPEDEF_(0xC0090001L) #define ERROR_ALL_SIDS_FILTERED _HRESULT_TYPEDEF_(0xC0090002L)