mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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; i<max_rows; i++)
|
||||
out_rows[i] = This->image_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; i<data_size; i++)
|
||||
This->image_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; i<max_rows; i++)
|
||||
out_rows[i] = This->image_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; i<data_size; i++)
|
||||
This->image_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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -19,12 +19,15 @@
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <propvarutil.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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' }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);")
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user