From f76f7f14bb81e996c45c2b85a9571be4f3bf1949 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 23 May 2013 16:39:54 +0000 Subject: [PATCH] [WINDOWSCODECS] * Sync with Wine 1.5.26. [PSDK] * Update wincodec.idl. svn path=/trunk/; revision=59071 --- .../dll/win32/windowscodecs/CMakeLists.txt | 3 +- reactos/dll/win32/windowscodecs/bitmap.c | 11 +- reactos/dll/win32/windowscodecs/bmpdecode.c | 29 ++- reactos/dll/win32/windowscodecs/bmpencode.c | 2 +- .../dll/win32/windowscodecs/colorcontext.c | 69 ++++- .../dll/win32/windowscodecs/colortransform.c | 195 ++++++++++++++ reactos/dll/win32/windowscodecs/converter.c | 220 ++++++++++++++-- reactos/dll/win32/windowscodecs/gifformat.c | 2 +- reactos/dll/win32/windowscodecs/icnsformat.c | 2 +- reactos/dll/win32/windowscodecs/icoformat.c | 6 +- reactos/dll/win32/windowscodecs/imgfactory.c | 182 +++++++++++-- reactos/dll/win32/windowscodecs/info.c | 7 +- reactos/dll/win32/windowscodecs/jpegformat.c | 7 +- reactos/dll/win32/windowscodecs/main.c | 5 +- .../dll/win32/windowscodecs/metadatahandler.c | 4 +- reactos/dll/win32/windowscodecs/palette.c | 2 +- reactos/dll/win32/windowscodecs/pngformat.c | 44 ++-- reactos/dll/win32/windowscodecs/propertybag.c | 203 ++++++++++++++- reactos/dll/win32/windowscodecs/regsvr.c | 12 + reactos/dll/win32/windowscodecs/scaler.c | 2 +- reactos/dll/win32/windowscodecs/stream.c | 241 +++++++++++++++++- reactos/dll/win32/windowscodecs/tiffformat.c | 33 ++- reactos/dll/win32/windowscodecs/typeof.h | 1 + .../win32/windowscodecs/wincodecs_private.h | 7 +- reactos/include/psdk/wincodec.idl | 16 ++ reactos/media/doc/README.WINE | 2 +- 26 files changed, 1203 insertions(+), 104 deletions(-) create mode 100644 reactos/dll/win32/windowscodecs/colortransform.c diff --git a/reactos/dll/win32/windowscodecs/CMakeLists.txt b/reactos/dll/win32/windowscodecs/CMakeLists.txt index ee60b101f5d..2eec6703df7 100644 --- a/reactos/dll/win32/windowscodecs/CMakeLists.txt +++ b/reactos/dll/win32/windowscodecs/CMakeLists.txt @@ -29,6 +29,7 @@ list(APPEND SOURCE bmpencode.c clsfactory.c colorcontext.c + colortransform.c converter.c fliprotate.c gifformat.c @@ -63,5 +64,5 @@ endif() add_library(windowscodecs SHARED ${SOURCE} version.rc) set_module_type(windowscodecs win32dll) target_link_libraries(windowscodecs wine uuid ${PSEH_LIB}) -add_importlibs(windowscodecs ole32 oleaut32 shlwapi advapi32 rpcrt4 msvcrt kernel32 ntdll) +add_importlibs(windowscodecs ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/windowscodecs/bitmap.c b/reactos/dll/win32/windowscodecs/bitmap.c index 9a4042ec098..65baa3bc40a 100644 --- a/reactos/dll/win32/windowscodecs/bitmap.c +++ b/reactos/dll/win32/windowscodecs/bitmap.c @@ -451,19 +451,23 @@ static const IWICBitmapVtbl BitmapImpl_Vtbl = { }; HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, + UINT stride, UINT datasize, BYTE *bits, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) { HRESULT hr; BitmapImpl *This; - UINT bpp, stride, datasize; BYTE *data; + UINT bpp; hr = get_pixelformat_bpp(pixelFormat, &bpp); if (FAILED(hr)) return hr; - stride = (((bpp*uiWidth)+31)/32)*4; - datasize = stride * uiHeight; + if (!stride) stride = (((bpp*uiWidth)+31)/32)*4; + if (!datasize) datasize = stride * uiHeight; + + if (datasize < stride * uiHeight) return WINCODEC_ERR_INSUFFICIENTBUFFER; + if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG; This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl)); data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize); @@ -473,6 +477,7 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, HeapFree(GetProcessHeap(), 0, data); return E_OUTOFMEMORY; } + if (bits) memcpy(data, bits, datasize); This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl; This->ref = 1; diff --git a/reactos/dll/win32/windowscodecs/bmpdecode.c b/reactos/dll/win32/windowscodecs/bmpdecode.c index 6dc1249626c..60fc147c4a9 100644 --- a/reactos/dll/win32/windowscodecs/bmpdecode.c +++ b/reactos/dll/win32/windowscodecs/bmpdecode.c @@ -167,22 +167,35 @@ static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, double *pDpiY) { + LONG resx = 0, resy = 0; + switch (bih->bV5Size) { + default: case sizeof(BITMAPCOREHEADER): - *pDpiX = 96.0; - *pDpiY = 96.0; - return S_OK; + break; + case sizeof(BITMAPCOREHEADER2): case sizeof(BITMAPINFOHEADER): case sizeof(BITMAPV4HEADER): case sizeof(BITMAPV5HEADER): - *pDpiX = bih->bV5XPelsPerMeter * 0.0254; - *pDpiY = bih->bV5YPelsPerMeter * 0.0254; - return S_OK; - default: - return E_FAIL; + resx = bih->bV5XPelsPerMeter; + resy = bih->bV5YPelsPerMeter; + break; } + + if (!resx || !resy) + { + *pDpiX = 96.0; + *pDpiY = 96.0; + } + else + { + *pDpiX = resx * 0.0254; + *pDpiY = resy * 0.0254; + } + + return S_OK; } static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, diff --git a/reactos/dll/win32/windowscodecs/bmpencode.c b/reactos/dll/win32/windowscodecs/bmpencode.c index 2bea7863cce..79d5b272a2e 100644 --- a/reactos/dll/win32/windowscodecs/bmpencode.c +++ b/reactos/dll/win32/windowscodecs/bmpencode.c @@ -542,7 +542,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED; - hr = CreatePropertyBag2(ppIEncoderOptions); + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); if (FAILED(hr)) return hr; encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode)); diff --git a/reactos/dll/win32/windowscodecs/colorcontext.c b/reactos/dll/win32/windowscodecs/colorcontext.c index 54434c6ca39..c65f7e083e2 100644 --- a/reactos/dll/win32/windowscodecs/colorcontext.c +++ b/reactos/dll/win32/windowscodecs/colorcontext.c @@ -100,27 +100,82 @@ static ULONG WINAPI ColorContext_Release(IWICColorContext *iface) return ref; } +static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) +{ + HANDLE handle; + DWORD count; + LARGE_INTEGER size; + BOOL ret; + + *len = 0; + *profile = NULL; + handle = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (handle == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError()); + + if (!(GetFileSizeEx(handle, &size))) + { + CloseHandle(handle); + return HRESULT_FROM_WIN32(GetLastError()); + } + if (size.u.HighPart) + { + WARN("file too large\n"); + CloseHandle(handle); + return E_FAIL; + } + if (!(*profile = HeapAlloc(GetProcessHeap(), 0, size.u.LowPart))) + { + CloseHandle(handle); + return E_OUTOFMEMORY; + } + ret = ReadFile(handle, *profile, size.u.LowPart, &count, NULL); + CloseHandle(handle); + if (!ret) return HRESULT_FROM_WIN32(GetLastError()); + if (count != size.u.LowPart) return E_FAIL; + *len = count; + return S_OK; +} + static HRESULT WINAPI ColorContext_InitializeFromFilename(IWICColorContext *iface, LPCWSTR wzFilename) { - FIXME("(%p,%s)\n", iface, debugstr_w(wzFilename)); - return E_NOTIMPL; + ColorContext *This = impl_from_IWICColorContext(iface); + BYTE *profile; + UINT len; + HRESULT hr; + TRACE("(%p,%s)\n", iface, debugstr_w(wzFilename)); + + if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) + return WINCODEC_ERR_WRONGSTATE; + + if (!wzFilename) return E_INVALIDARG; + + hr = load_profile(wzFilename, &profile, &len); + if (FAILED(hr)) return hr; + + HeapFree(GetProcessHeap(), 0, This->profile); + This->profile = profile; + This->profile_len = len; + This->type = WICColorContextProfile; + + return S_OK; } static HRESULT WINAPI ColorContext_InitializeFromMemory(IWICColorContext *iface, const BYTE *pbBuffer, UINT cbBufferSize) { ColorContext *This = impl_from_IWICColorContext(iface); + BYTE *profile; TRACE("(%p,%p,%u)\n", iface, pbBuffer, cbBufferSize); - if (This->type != WICColorContextUninitialized) + if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) return WINCODEC_ERR_WRONGSTATE; - HeapFree(GetProcessHeap(), 0, This->profile); - if (!(This->profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) - return E_OUTOFMEMORY; + if (!(profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) return E_OUTOFMEMORY; + memcpy(profile, pbBuffer, cbBufferSize); - memcpy(This->profile, pbBuffer, cbBufferSize); + HeapFree(GetProcessHeap(), 0, This->profile); + This->profile = profile; This->profile_len = cbBufferSize; This->type = WICColorContextProfile; diff --git a/reactos/dll/win32/windowscodecs/colortransform.c b/reactos/dll/win32/windowscodecs/colortransform.c new file mode 100644 index 00000000000..d0baae01cda --- /dev/null +++ b/reactos/dll/win32/windowscodecs/colortransform.c @@ -0,0 +1,195 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include + +#include + +#define COBJMACROS + +#include +#include +#include +#include + +//#include "wincodecs_private.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct ColorTransform { + IWICColorTransform IWICColorTransform_iface; + LONG ref; + IWICBitmapSource *dst; +} ColorTransform; + +static inline ColorTransform *impl_from_IWICColorTransform(IWICColorTransform *iface) +{ + return CONTAINING_RECORD(iface, ColorTransform, IWICColorTransform_iface); +} + +static HRESULT WINAPI ColorTransform_QueryInterface(IWICColorTransform *iface, REFIID iid, + void **ppv) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICColorTransform, iid)) + { + *ppv = &This->IWICColorTransform_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ColorTransform_AddRef(IWICColorTransform *iface) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI ColorTransform_Release(IWICColorTransform *iface) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + { + if (This->dst) IWICBitmapSource_Release(This->dst); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI ColorTransform_GetSize(IWICColorTransform *iface, + UINT *puiWidth, UINT *puiHeight) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight); + + return IWICBitmapSource_GetSize(This->dst, puiWidth, puiHeight); +} + +static HRESULT WINAPI ColorTransform_GetPixelFormat(IWICColorTransform *iface, + WICPixelFormatGUID *pPixelFormat) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%p)\n", iface, pPixelFormat); + + return IWICBitmapSource_GetPixelFormat(This->dst, pPixelFormat); +} + +static HRESULT WINAPI ColorTransform_GetResolution(IWICColorTransform *iface, + double *pDpiX, double *pDpiY) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY); + + return IWICBitmapSource_GetResolution(This->dst, pDpiX, pDpiY); +} + +static HRESULT WINAPI ColorTransform_CopyPalette(IWICColorTransform *iface, + IWICPalette *pIPalette) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%p)\n", iface, pIPalette); + + return IWICBitmapSource_CopyPalette(This->dst, pIPalette); +} + +static HRESULT WINAPI ColorTransform_CopyPixels(IWICColorTransform *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer); + + return IWICBitmapSource_CopyPixels(This->dst, prc, cbStride, cbBufferSize, pbBuffer); +} + +static HRESULT WINAPI ColorTransform_Initialize(IWICColorTransform *iface, + IWICBitmapSource *pIBitmapSource, IWICColorContext *pIContextSource, + IWICColorContext *pIContextDest, REFWICPixelFormatGUID pixelFmtDest) +{ + ColorTransform *This = impl_from_IWICColorTransform(iface); + IWICBitmapSource *dst; + HRESULT hr; + + TRACE("(%p,%p,%p,%p,%s)\n", iface, pIBitmapSource, pIContextSource, + pIContextDest, debugstr_guid(pixelFmtDest)); + + FIXME("ignoring color contexts\n"); + + hr = WICConvertBitmapSource(pixelFmtDest, pIBitmapSource, &dst); + if (FAILED(hr)) return hr; + + if (This->dst) IWICBitmapSource_Release(This->dst); + This->dst = dst; + return S_OK; +} + +static const IWICColorTransformVtbl ColorTransform_Vtbl = { + ColorTransform_QueryInterface, + ColorTransform_AddRef, + ColorTransform_Release, + ColorTransform_GetSize, + ColorTransform_GetPixelFormat, + ColorTransform_GetResolution, + ColorTransform_CopyPalette, + ColorTransform_CopyPixels, + ColorTransform_Initialize +}; + +HRESULT ColorTransform_Create(IWICColorTransform **colortransform) +{ + ColorTransform *This; + + if (!colortransform) return E_INVALIDARG; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorTransform)); + if (!This) return E_OUTOFMEMORY; + + This->IWICColorTransform_iface.lpVtbl = &ColorTransform_Vtbl; + This->ref = 1; + This->dst = NULL; + + *colortransform = &This->IWICColorTransform_iface; + + return S_OK; +} diff --git a/reactos/dll/win32/windowscodecs/converter.c b/reactos/dll/win32/windowscodecs/converter.c index 73def317f99..09816a41018 100644 --- a/reactos/dll/win32/windowscodecs/converter.c +++ b/reactos/dll/win32/windowscodecs/converter.c @@ -53,6 +53,7 @@ enum pixelformat { format_16bppBGR565, format_16bppBGRA5551, format_24bppBGR, + format_24bppRGB, format_32bppBGR, format_32bppBGRA, format_32bppPBGRA, @@ -96,7 +97,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -163,7 +164,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -226,7 +227,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -286,7 +287,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -328,7 +329,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -381,7 +382,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -423,7 +424,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -471,7 +472,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -519,7 +520,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -567,7 +568,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -606,11 +607,59 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe return res; } return S_OK; + case format_24bppRGB: + if (prc) + { + HRESULT res; + INT x, y; + BYTE *srcdata; + UINT srcstride, srcdatasize; + const BYTE *srcrow; + const BYTE *srcpixel; + BYTE *dstrow; + BYTE *dstpixel; + BYTE tmppixel[3]; + + srcstride = 3 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + + if (SUCCEEDED(res)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y=0; yHeight; y++) { + srcpixel=srcrow; + dstpixel=dstrow; + for (x=0; xWidth; x++) { + tmppixel[0]=*srcpixel++; /* red */ + tmppixel[1]=*srcpixel++; /* green */ + tmppixel[2]=*srcpixel++; /* blue */ + + *dstpixel++=tmppixel[2]; /* blue */ + *dstpixel++=tmppixel[1]; /* green */ + *dstpixel++=tmppixel[0]; /* red */ + *dstpixel++=255; /* alpha */ + } + srcrow += srcstride; + dstrow += cbStride; + } + } + + HeapFree(GetProcessHeap(), 0, srcdata); + + return res; + } + return S_OK; case format_32bppBGR: if (prc) { HRESULT res; - UINT x, y; + INT x, y; res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); if (FAILED(res)) return res; @@ -629,7 +678,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); if (FAILED(res)) return res; @@ -651,7 +700,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -695,7 +744,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe if (prc) { HRESULT res; - UINT x, y; + INT x, y; BYTE *srcdata; UINT srcstride, srcdatasize; const BYTE *srcrow; @@ -793,7 +842,7 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format); if (SUCCEEDED(hr) && prc) { - UINT x, y; + INT x, y; for (y=0; yHeight; y++) for (x=0; xWidth; x++) @@ -811,6 +860,144 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR } } +static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_24bppBGR: + case format_24bppRGB: + if (prc) + { + hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + if (SUCCEEDED(hr) && source_format == format_24bppRGB) + reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride); + return hr; + } + return S_OK; + case format_32bppBGR: + case format_32bppBGRA: + case format_32bppPBGRA: + if (prc) + { + HRESULT res; + INT x, y; + BYTE *srcdata; + UINT srcstride, srcdatasize; + const BYTE *srcrow; + const BYTE *srcpixel; + BYTE *dstrow; + BYTE *dstpixel; + + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + + if (SUCCEEDED(res)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y=0; yHeight; y++) { + srcpixel=srcrow; + dstpixel=dstrow; + for (x=0; xWidth; x++) { + *dstpixel++=*srcpixel++; /* blue */ + *dstpixel++=*srcpixel++; /* green */ + *dstpixel++=*srcpixel++; /* red */ + srcpixel++; /* alpha */ + } + srcrow += srcstride; + dstrow += cbStride; + } + } + + HeapFree(GetProcessHeap(), 0, srcdata); + + return res; + } + return S_OK; + default: + FIXME("Unimplemented conversion path!\n"); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + +static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_24bppBGR: + case format_24bppRGB: + if (prc) + { + hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + if (SUCCEEDED(hr) && source_format == format_24bppBGR) + reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride); + return hr; + } + return S_OK; + case format_32bppBGR: + case format_32bppBGRA: + case format_32bppPBGRA: + if (prc) + { + HRESULT res; + INT x, y; + BYTE *srcdata; + UINT srcstride, srcdatasize; + const BYTE *srcrow; + const BYTE *srcpixel; + BYTE *dstrow; + BYTE *dstpixel; + + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + + if (SUCCEEDED(res)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y=0; yHeight; y++) { + srcpixel=srcrow; + dstpixel=dstrow; + for (x=0; xWidth; x++) { + *dstpixel++=*srcpixel++; /* blue */ + *dstpixel++=*srcpixel++; /* green */ + *dstpixel++=*srcpixel++; /* red */ + srcpixel++; /* alpha */ + } + srcrow += srcstride; + dstrow += cbStride; + } + + reverse_bgr8(3, pbBuffer, prc->Width, prc->Height, cbStride); + } + + HeapFree(GetProcessHeap(), 0, srcdata); + + return res; + } + return S_OK; + default: + FIXME("Unimplemented conversion path!\n"); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + static const struct pixelformatinfo supported_formats[] = { {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL}, {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL}, @@ -824,7 +1011,8 @@ static const struct pixelformatinfo supported_formats[] = { {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL}, {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL}, {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL}, - {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, NULL}, + {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, copypixels_to_24bppBGR}, + {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB}, {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR}, {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA}, {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA}, diff --git a/reactos/dll/win32/windowscodecs/gifformat.c b/reactos/dll/win32/windowscodecs/gifformat.c index 85de0ba1ac5..8799d8e6876 100644 --- a/reactos/dll/win32/windowscodecs/gifformat.c +++ b/reactos/dll/win32/windowscodecs/gifformat.c @@ -1145,7 +1145,7 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p seek.QuadPart = 0; IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - IStream_Read(pIStream, &This->LSD_data, sizeof(This->LSD_data), NULL); + IStream_Read(pIStream, This->LSD_data, sizeof(This->LSD_data), NULL); This->initialized = TRUE; diff --git a/reactos/dll/win32/windowscodecs/icnsformat.c b/reactos/dll/win32/windowscodecs/icnsformat.c index 12db752d189..6f863eba3d7 100644 --- a/reactos/dll/win32/windowscodecs/icnsformat.c +++ b/reactos/dll/win32/windowscodecs/icnsformat.c @@ -667,7 +667,7 @@ static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, goto end; } - hr = CreatePropertyBag2(ppIEncoderOptions); + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); if (FAILED(hr)) goto end; diff --git a/reactos/dll/win32/windowscodecs/icoformat.c b/reactos/dll/win32/windowscodecs/icoformat.c index 704b8f14ce3..5e4eb8ac80a 100644 --- a/reactos/dll/win32/windowscodecs/icoformat.c +++ b/reactos/dll/win32/windowscodecs/icoformat.c @@ -203,8 +203,8 @@ static HRESULT WINAPI IcoFrameDecode_GetColorContexts(IWICBitmapFrameDecode *ifa static HRESULT WINAPI IcoFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, IWICBitmapSource **ppIThumbnail) { - FIXME("(%p,%p)\n", iface, ppIThumbnail); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, ppIThumbnail); + return IWICBitmapFrameDecode_QueryInterface(iface, &IID_IWICBitmapSource, (void **)ppIThumbnail); } static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = { @@ -296,7 +296,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) { /* If the alpha channel is fully transparent, we should ignore it. */ int nonzero_alpha = 0; - int i; + UINT i; for (i=0; i<(result->height*result->width); i++) { diff --git a/reactos/dll/win32/windowscodecs/imgfactory.c b/reactos/dll/win32/windowscodecs/imgfactory.c index 04452e731ee..418b95d6cdc 100644 --- a/reactos/dll/win32/windowscodecs/imgfactory.c +++ b/reactos/dll/win32/windowscodecs/imgfactory.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 2012 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,6 +29,7 @@ #include #include +#include //#include "winreg.h" #include //#include "shellapi.h" @@ -241,9 +243,24 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromFileHandle( IWICComponentFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor, WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder) { - FIXME("(%p,%lx,%s,%u,%p): stub\n", iface, hFile, debugstr_guid(pguidVendor), + IWICStream *stream; + HRESULT hr; + + TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), metadataOptions, ppIDecoder); - return E_NOTIMPL; + + hr = StreamImpl_Create(&stream); + if (SUCCEEDED(hr)) + { + hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile); + if (SUCCEEDED(hr)) + { + hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream, + pguidVendor, metadataOptions, ppIDecoder); + } + IWICStream_Release(stream); + } + return hr; } static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface, @@ -453,8 +470,8 @@ static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory * static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface, IWICColorTransform **ppIColorTransform) { - FIXME("(%p,%p): stub\n", iface, ppIColorTransform); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, ppIColorTransform); + return ColorTransform_Create(ppIColorTransform); } static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface, @@ -463,7 +480,7 @@ static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface, { TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight, debugstr_guid(pixelFormat), option, ppIBitmap); - return BitmapImpl_Create(uiWidth, uiHeight, pixelFormat, option, ppIBitmap); + return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, pixelFormat, option, ppIBitmap); } static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface, @@ -510,7 +527,7 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFacto } if (SUCCEEDED(hr)) - hr = BitmapImpl_Create(width, height, &pixelformat, option, &result); + hr = BitmapImpl_Create(width, height, 0, 0, NULL, &pixelformat, option, &result); if (SUCCEEDED(hr)) { @@ -580,12 +597,15 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentF } static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface, - UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride, - UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap) + UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride, + UINT size, BYTE *buffer, IWICBitmap **bitmap) { - FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight, - debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap); - return E_NOTIMPL; + TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height, + debugstr_guid(format), stride, size, buffer, bitmap); + + if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG; + + return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap); } static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface, @@ -597,10 +617,140 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFact } static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface, - HICON hIcon, IWICBitmap **ppIBitmap) + HICON hicon, IWICBitmap **bitmap) { - FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap); - return E_NOTIMPL; + IWICBitmapLock *lock; + ICONINFO info; + BITMAP bm; + int width, height, x, y; + UINT stride, size; + BYTE *buffer; + DWORD *bits; + BITMAPINFO bi; + HDC hdc; + BOOL has_alpha; + HRESULT hr; + + TRACE("(%p,%p,%p)\n", iface, hicon, bitmap); + + if (!bitmap) return E_INVALIDARG; + + if (!GetIconInfo(hicon, &info)) + return HRESULT_FROM_WIN32(GetLastError()); + + GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm); + + width = bm.bmWidth; + height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2; + stride = width * 4; + size = stride * height; + + hr = BitmapImpl_Create(width, height, stride, size, NULL, + &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap); + if (hr != S_OK) goto failed; + + hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); + if (hr != S_OK) + { + IWICBitmap_Release(*bitmap); + goto failed; + } + IWICBitmapLock_GetDataPointer(lock, &size, &buffer); + + hdc = CreateCompatibleDC(0); + + memset(&bi, 0, sizeof(bi)); + bi.bmiHeader.biSize = sizeof(bi.bmiHeader); + bi.bmiHeader.biWidth = width; + bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + + has_alpha = FALSE; + + if (info.hbmColor) + { + GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS); + + if (bm.bmBitsPixel == 32) + { + /* If any pixel has a non-zero alpha, ignore hbmMask */ + bits = (DWORD *)buffer; + for (x = 0; x < width && !has_alpha; x++, bits++) + { + for (y = 0; y < height; y++) + { + if (*bits & 0xff000000) + { + has_alpha = TRUE; + break; + } + } + } + } + } + else + GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS); + + if (!has_alpha) + { + DWORD *rgba; + + if (info.hbmMask) + { + BYTE *mask; + + mask = HeapAlloc(GetProcessHeap(), 0, size); + if (!mask) + { + IWICBitmapLock_Release(lock); + IWICBitmap_Release(*bitmap); + DeleteDC(hdc); + hr = E_OUTOFMEMORY; + goto failed; + } + + /* read alpha data from the mask */ + GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS); + + for (y = 0; y < height; y++) + { + rgba = (DWORD *)(buffer + y * stride); + bits = (DWORD *)(mask + y * stride); + + for (x = 0; x < width; x++, rgba++, bits++) + { + if (*bits) + *rgba = 0; + else + *rgba |= 0xff000000; + } + } + + HeapFree(GetProcessHeap(), 0, mask); + } + else + { + /* set constant alpha of 255 */ + for (y = 0; y < height; y++) + { + rgba = (DWORD *)(buffer + y * stride); + for (x = 0; x < width; x++, rgba++) + *rgba |= 0xff000000; + } + } + + } + + IWICBitmapLock_Release(lock); + DeleteDC(hdc); + +failed: + DeleteObject(info.hbmColor); + DeleteObject(info.hbmMask); + + return hr; } static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface, @@ -691,8 +841,8 @@ static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComp static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface, PROPBAG2 *options, UINT count, IPropertyBag2 **property) { - FIXME("%p,%p,%u,%p: stub\n", iface, options, count, property); - return E_NOTIMPL; + TRACE("(%p,%p,%u,%p)\n", iface, options, count, property); + return CreatePropertyBag2(options, count, property); } static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = { diff --git a/reactos/dll/win32/windowscodecs/info.c b/reactos/dll/win32/windowscodecs/info.c index 262e6ab9958..934e6b95b47 100644 --- a/reactos/dll/win32/windowscodecs/info.c +++ b/reactos/dll/win32/windowscodecs/info.c @@ -543,7 +543,8 @@ static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if WICBitmapPattern *patterns; UINT pattern_count=0, patterns_size=0; HRESULT hr; - int i, pos; + UINT i; + ULONG pos; BYTE *data=NULL; ULONG datasize=0; ULONG bytesread; @@ -1904,7 +1905,7 @@ static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, IUnknown **rgelt, ULONG *pceltFetched) { ComponentEnum *This = impl_from_IEnumUnknown(iface); - int num_fetched=0; + ULONG num_fetched=0; ComponentEnumItem *item; HRESULT hr=S_OK; @@ -1933,7 +1934,7 @@ static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt) { ComponentEnum *This = impl_from_IEnumUnknown(iface); - int i; + ULONG i; HRESULT hr=S_OK; TRACE("(%p,%u)\n", iface, celt); diff --git a/reactos/dll/win32/windowscodecs/jpegformat.c b/reactos/dll/win32/windowscodecs/jpegformat.c index 6871a131a70..bb7169cdb93 100644 --- a/reactos/dll/win32/windowscodecs/jpegformat.c +++ b/reactos/dll/win32/windowscodecs/jpegformat.c @@ -1002,7 +1002,8 @@ static HRESULT WINAPI JpegEncoder_Frame_WritePixels(IWICBitmapFrameEncode *iface JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); jmp_buf jmpbuf; BYTE *swapped_data = NULL, *current_row; - int line, row_size; + UINT line; + int row_size; TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); EnterCriticalSection(&This->lock); @@ -1065,7 +1066,7 @@ static HRESULT WINAPI JpegEncoder_Frame_WritePixels(IWICBitmapFrameEncode *iface { if (This->format->swap_rgb) { - int x; + UINT x; memcpy(swapped_data, pbPixels + (cbStride * line), row_size); @@ -1393,7 +1394,7 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, return WINCODEC_ERR_NOTINITIALIZED; } - hr = CreatePropertyBag2(ppIEncoderOptions); + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); if (FAILED(hr)) { LeaveCriticalSection(&This->lock); diff --git a/reactos/dll/win32/windowscodecs/main.c b/reactos/dll/win32/windowscodecs/main.c index f12eb12abf7..ebef58de8f8 100644 --- a/reactos/dll/win32/windowscodecs/main.c +++ b/reactos/dll/win32/windowscodecs/main.c @@ -89,7 +89,8 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, return E_INVALIDARG; /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */ - if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && srcstride == dststride) + if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && + srcstride == dststride && srcstride == bytesperrow) { memcpy(dstbuffer, srcbuffer, srcstride * srcheight); return S_OK; @@ -100,7 +101,7 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, if (row_offset % 8 == 0) { /* everything lines up on a byte boundary */ - UINT row; + INT row; const BYTE *src; BYTE *dst; diff --git a/reactos/dll/win32/windowscodecs/metadatahandler.c b/reactos/dll/win32/windowscodecs/metadatahandler.c index f660a8afea9..e8d2ad9d33e 100644 --- a/reactos/dll/win32/windowscodecs/metadatahandler.c +++ b/reactos/dll/win32/windowscodecs/metadatahandler.c @@ -64,7 +64,7 @@ static inline MetadataHandler *impl_from_IWICPersistStream(IWICPersistStream *if static void MetadataHandler_FreeItems(MetadataHandler *This) { - int i; + DWORD i; for (i=0; iitem_count; i++) { @@ -559,7 +559,7 @@ static HRESULT WINAPI MetadataHandlerEnum_Next(IWICEnumMetadataItem *iface, MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface); ULONG new_index; HRESULT hr=S_FALSE; - int i; + ULONG i; TRACE("(%p,%i)\n", iface, celt); diff --git a/reactos/dll/win32/windowscodecs/palette.c b/reactos/dll/win32/windowscodecs/palette.c index 9094063cb15..ff0a4a18590 100644 --- a/reactos/dll/win32/windowscodecs/palette.c +++ b/reactos/dll/win32/windowscodecs/palette.c @@ -596,7 +596,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha) { PaletteImpl *This = impl_from_IWICPalette(iface); - int i; + UINT i; TRACE("(%p,%p)\n", iface, pfHasAlpha); diff --git a/reactos/dll/win32/windowscodecs/pngformat.c b/reactos/dll/win32/windowscodecs/pngformat.c index b0d764943ab..f59011573b8 100644 --- a/reactos/dll/win32/windowscodecs/pngformat.c +++ b/reactos/dll/win32/windowscodecs/pngformat.c @@ -80,7 +80,7 @@ static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *d return hr; } - /* FIXME: Verify the CRC? */ + /* Windows ignores CRC of the chunk */ } return S_OK; @@ -178,6 +178,7 @@ MAKE_FUNCPTR(png_get_pHYs); MAKE_FUNCPTR(png_get_PLTE); MAKE_FUNCPTR(png_get_tRNS); MAKE_FUNCPTR(png_set_bgr); +MAKE_FUNCPTR(png_set_crc_action); MAKE_FUNCPTR(png_set_error_fn); #if HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8 MAKE_FUNCPTR(png_set_expand_gray_1_2_4_to_8); @@ -226,6 +227,7 @@ static void *load_libpng(void) LOAD_FUNCPTR(png_get_PLTE); LOAD_FUNCPTR(png_get_tRNS); LOAD_FUNCPTR(png_set_bgr); + LOAD_FUNCPTR(png_set_crc_action); LOAD_FUNCPTR(png_set_error_fn); #if HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8 LOAD_FUNCPTR(png_set_expand_gray_1_2_4_to_8); @@ -442,6 +444,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p goto end; } ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); + ppng_set_crc_action(This->png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); /* seek to the start of the stream */ seek.QuadPart = 0; @@ -634,8 +637,12 @@ static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface, IWICBitmapSource **ppIBitmapSource) { - FIXME("(%p,%p): stub\n", iface, ppIBitmapSource); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, ppIBitmapSource); + + if (!ppIBitmapSource) return E_INVALIDARG; + + *ppIBitmapSource = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static HRESULT WINAPI PngDecoder_GetColorContexts(IWICBitmapDecoder *iface, @@ -649,6 +656,10 @@ static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface, IWICBitmapSource **ppIThumbnail) { TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; return WINCODEC_ERR_CODECNOTHUMBNAIL; } @@ -791,7 +802,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, png_colorp png_palette; int num_palette; WICColor palette[256]; - png_bytep trans; + png_bytep trans_alpha; int num_trans; png_color_16p trans_values; int i; @@ -815,23 +826,18 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, goto end; } + ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values); + if (!ret) num_trans = 0; + for (i=0; ipng_ptr, This->info_ptr, &trans, &num_trans, &trans_values); - if (ret) - { - for (i=0; ilock); @@ -899,8 +905,12 @@ static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *i static HRESULT WINAPI PngDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface, IWICBitmapSource **ppIThumbnail) { - FIXME("(%p,%p): stub\n", iface, ppIThumbnail); - return E_NOTIMPL; + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; + return WINCODEC_ERR_CODECNOTHUMBNAIL; } static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl = { @@ -1607,7 +1617,7 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, return WINCODEC_ERR_NOTINITIALIZED; } - hr = CreatePropertyBag2(ppIEncoderOptions); + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); if (FAILED(hr)) { LeaveCriticalSection(&This->lock); diff --git a/reactos/dll/win32/windowscodecs/propertybag.c b/reactos/dll/win32/windowscodecs/propertybag.c index 4c71700b86f..147ff0149a4 100644 --- a/reactos/dll/win32/windowscodecs/propertybag.c +++ b/reactos/dll/win32/windowscodecs/propertybag.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 2013 Ludger Sprenker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,8 +29,9 @@ #include #include -#include +#include #include +#include //#include "wincodecs_private.h" @@ -40,6 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); typedef struct PropertyBag { IPropertyBag2 IPropertyBag2_iface; LONG ref; + UINT prop_count; + PROPBAG2 *properties; + VARIANT *values; } PropertyBag; static inline PropertyBag *impl_from_IPropertyBag2(IPropertyBag2 *iface) @@ -89,37 +94,179 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) if (ref == 0) { + ULONG i; + if (This->properties && This->values) + { + for (i=0; i < This->prop_count; i++) + { + HeapFree(GetProcessHeap(), 0, This->properties[i].pstrName); + VariantClear( This->values+i ); + } + } + + HeapFree(GetProcessHeap(), 0, This->properties); + HeapFree(GetProcessHeap(), 0, This->values); HeapFree(GetProcessHeap(), 0, This); } return ref; } +static LONG find_item(PropertyBag *This, LPCOLESTR name) +{ + LONG i; + if (!This->properties) + return -1; + if (!name) + return -1; + + for (i=0; i < This->prop_count; i++) + { + if (strcmpW(name, This->properties[i].pstrName) == 0) + return i; + } + + return -1; +} + static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError) { - FIXME("(%p,%u,%p,%p,%p,%p): stub\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); - return E_NOTIMPL; + HRESULT res = S_OK; + ULONG i; + PropertyBag *This = impl_from_IPropertyBag2(iface); + + TRACE("(%p,%u,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); + + for (i=0; i < cProperties; i++) + { + LONG idx; + if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count) + idx = pPropBag[i].dwHint-1; + else + idx = find_item(This, pPropBag[i].pstrName); + + if (idx > -1) + { + VariantInit(pvarValue+i); + res = VariantCopy(pvarValue+i, This->values+idx); + if (FAILED(res)) + break; + phrError[i] = res; + } + else + { + res = E_FAIL; + break; + } + } + + return res; } static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue) { - FIXME("(%p,%u,%p,%p): stub\n", iface, cProperties, pPropBag, pvarValue); - return E_NOTIMPL; + HRESULT res = S_OK; + ULONG i; + PropertyBag *This = impl_from_IPropertyBag2(iface); + + TRACE("(%p,%u,%p,%p)\n", iface, cProperties, pPropBag, pvarValue); + + for (i=0; i < cProperties; i++) + { + LONG idx; + if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count) + idx = pPropBag[i].dwHint-1; + else + idx = find_item(This, pPropBag[i].pstrName); + + if (idx > -1) + { + if (This->properties[idx].vt != V_VT(pvarValue+i)) + return WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE; + res = VariantCopy(This->values+idx, pvarValue+i); + if (FAILED(res)) + return E_FAIL; + } + else + { + if (pPropBag[i].pstrName) + FIXME("Application tried to set the unknown option %s.\n", + debugstr_w(pPropBag[i].pstrName)); + + /* FIXME: Function is not atomar on error, but MSDN does not say anything about it + * (no reset of items between 0 and i-1) */ + return E_FAIL; + } + } + + return res; } static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties) { - FIXME("(%p,%p): stub\n", iface, pcProperties); - return E_NOTIMPL; + PropertyBag *This = impl_from_IPropertyBag2(iface); + + TRACE("(%p,%p)\n", iface, pcProperties); + + if (!pcProperties) + return E_INVALIDARG; + + *pcProperties = This->prop_count; + + return S_OK; +} + +static HRESULT copy_propbag2(PROPBAG2 *dest, PROPBAG2 *src, BOOL useCoAlloc) +{ + dest->cfType = src->cfType; + dest->clsid = src->clsid; + dest->dwHint = src->dwHint; + dest->dwType = src->dwType; + dest->vt = src->vt; + if(useCoAlloc) + dest->pstrName = CoTaskMemAlloc((strlenW(src->pstrName)+1) * sizeof(WCHAR)); + else + dest->pstrName = HeapAlloc(GetProcessHeap(), 0, (strlenW(src->pstrName)+1) * sizeof(WCHAR)); + + if(!dest->pstrName) + return E_OUTOFMEMORY; + + strcpyW(dest->pstrName, src->pstrName); + + return S_OK; } static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties) { - FIXME("(%p,%u,%u,%p,%p): stub\n", iface, iProperty, cProperties, pPropBag, pcProperties); - return E_NOTIMPL; + HRESULT res = S_OK; + ULONG i; + PropertyBag *This = impl_from_IPropertyBag2(iface); + + TRACE("(%p,%u,%u,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties); + + if (iProperty >= This->prop_count && iProperty > 0) + return WINCODEC_ERR_VALUEOUTOFRANGE; + if (iProperty+cProperties > This->prop_count ) + return WINCODEC_ERR_VALUEOUTOFRANGE; + + *pcProperties = max(cProperties, This->prop_count-iProperty); + + for (i=0; i < *pcProperties; i++) + { + res = copy_propbag2(pPropBag+i, This->properties+iProperty+i, TRUE); + if (FAILED(res)) + { + do { + CoTaskMemFree( pPropBag[--i].pstrName ); + } while (i); + break; + } + } + + return res; } static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, @@ -140,8 +287,11 @@ static const IPropertyBag2Vtbl PropertyBag_Vtbl = { PropertyBag_LoadObject }; -HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2) +HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count, + IPropertyBag2 **ppPropertyBag2) { + UINT i; + HRESULT res = S_OK; PropertyBag *This; This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag)); @@ -149,8 +299,37 @@ HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2) This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl; This->ref = 1; + This->prop_count = count; - *ppPropertyBag2 = &This->IPropertyBag2_iface; + if (count == 0) + { + This->properties = NULL; + This->values = NULL; + } + else + { + This->properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROPBAG2)*count); + This->values = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*count); - return S_OK; + if (!This->properties || !This->values) + res = E_OUTOFMEMORY; + else + for (i=0; i < count; i++) + { + res = copy_propbag2(This->properties+i, options+i, FALSE); + if (FAILED(res)) + break; + This->properties[i].dwHint = i+1; /* 0 means unset, so we start with 1 */ + } + } + + if (FAILED(res)) + { + PropertyBag_Release(&This->IPropertyBag2_iface); + *ppPropertyBag2 = NULL; + } + else + *ppPropertyBag2 = &This->IPropertyBag2_iface; + + return res; } diff --git a/reactos/dll/win32/windowscodecs/regsvr.c b/reactos/dll/win32/windowscodecs/regsvr.c index af41f81d286..a9abe25a1ae 100644 --- a/reactos/dll/win32/windowscodecs/regsvr.c +++ b/reactos/dll/win32/windowscodecs/regsvr.c @@ -1471,6 +1471,7 @@ static GUID const * const converter_formats[] = { &GUID_WICPixelFormat16bppBGR565, &GUID_WICPixelFormat16bppBGRA5551, &GUID_WICPixelFormat24bppBGR, + &GUID_WICPixelFormat24bppRGB, &GUID_WICPixelFormat32bppBGR, &GUID_WICPixelFormat32bppBGRA, &GUID_WICPixelFormat32bppPBGRA, @@ -1860,6 +1861,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 0 }, + { &GUID_WICPixelFormat24bppRGB, + "The Wine Project", + "24bpp RGB", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 24, /* bitsperpixel */ + 3, /* channel count */ + channel_masks_8bit, + WICPixelFormatNumericRepresentationUnsignedInteger, + 0 + }, { &GUID_WICPixelFormat32bppBGR, "The Wine Project", "32bpp BGR", diff --git a/reactos/dll/win32/windowscodecs/scaler.c b/reactos/dll/win32/windowscodecs/scaler.c index eb8540b1fee..68502f602f0 100644 --- a/reactos/dll/win32/windowscodecs/scaler.c +++ b/reactos/dll/win32/windowscodecs/scaler.c @@ -182,7 +182,7 @@ static void NearestNeighbor_CopyScanline(BitmapScaler *This, UINT dst_x, UINT dst_y, UINT dst_width, BYTE **src_data, UINT src_data_x, UINT src_data_y, BYTE *pbBuffer) { - int i; + UINT i; UINT bytesperpixel = This->bpp/8; UINT src_x, src_y; diff --git a/reactos/dll/win32/windowscodecs/stream.c b/reactos/dll/win32/windowscodecs/stream.c index 73b4f8e1761..619c0210f2b 100644 --- a/reactos/dll/win32/windowscodecs/stream.c +++ b/reactos/dll/win32/windowscodecs/stream.c @@ -29,7 +29,7 @@ #include #include #include -//#include "wincodecs_private.h" +#include "wincodecs_private.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); @@ -267,6 +267,175 @@ static const IStreamVtbl StreamOnMemory_Vtbl = StreamOnMemory_Clone, }; +/****************************************** + * StreamOnFileHandle implementation (internal) + * + */ +typedef struct StreamOnFileHandle { + IStream IStream_iface; + LONG ref; + + HANDLE map; + void *mem; + IWICStream *stream; +} StreamOnFileHandle; + +static inline StreamOnFileHandle *StreamOnFileHandle_from_IStream(IStream *iface) +{ + return CONTAINING_RECORD(iface, StreamOnFileHandle, IStream_iface); +} + +static HRESULT WINAPI StreamOnFileHandle_QueryInterface(IStream *iface, + REFIID iid, void **ppv) +{ + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IStream, iid) || + IsEqualIID(&IID_ISequentialStream, iid)) + { + *ppv = iface; + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } +} + +static ULONG WINAPI StreamOnFileHandle_AddRef(IStream *iface) +{ + StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI StreamOnFileHandle_Release(IStream *iface) +{ + StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) { + IWICStream_Release(This->stream); + UnmapViewOfFile(This->mem); + CloseHandle(This->map); + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +static HRESULT WINAPI StreamOnFileHandle_Read(IStream *iface, + void *pv, ULONG cb, ULONG *pcbRead) +{ + StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); + TRACE("(%p)\n", This); + + return IWICStream_Read(This->stream, pv, cb, pcbRead); +} + +static HRESULT WINAPI StreamOnFileHandle_Write(IStream *iface, + void const *pv, ULONG cb, ULONG *pcbWritten) +{ + ERR("(%p)\n", iface); + return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); +} + +static HRESULT WINAPI StreamOnFileHandle_Seek(IStream *iface, + LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); + TRACE("(%p)\n", This); + + return IWICStream_Seek(This->stream, dlibMove, dwOrigin, plibNewPosition); +} + +static HRESULT WINAPI StreamOnFileHandle_SetSize(IStream *iface, + ULARGE_INTEGER libNewSize) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_CopyTo(IStream *iface, + IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_Commit(IStream *iface, + DWORD grfCommitFlags) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_Revert(IStream *iface) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_LockRegion(IStream *iface, + ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_UnlockRegion(IStream *iface, + ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI StreamOnFileHandle_Stat(IStream *iface, + STATSTG *pstatstg, DWORD grfStatFlag) +{ + StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); + TRACE("(%p)\n", This); + + return IWICStream_Stat(This->stream, pstatstg, grfStatFlag); +} + +static HRESULT WINAPI StreamOnFileHandle_Clone(IStream *iface, + IStream **ppstm) +{ + TRACE("(%p)\n", iface); + return E_NOTIMPL; +} + + +static const IStreamVtbl StreamOnFileHandle_Vtbl = +{ + /*** IUnknown methods ***/ + StreamOnFileHandle_QueryInterface, + StreamOnFileHandle_AddRef, + StreamOnFileHandle_Release, + /*** ISequentialStream methods ***/ + StreamOnFileHandle_Read, + StreamOnFileHandle_Write, + /*** IStream methods ***/ + StreamOnFileHandle_Seek, + StreamOnFileHandle_SetSize, + StreamOnFileHandle_CopyTo, + StreamOnFileHandle_Commit, + StreamOnFileHandle_Revert, + StreamOnFileHandle_LockRegion, + StreamOnFileHandle_UnlockRegion, + StreamOnFileHandle_Stat, + StreamOnFileHandle_Clone, +}; + /****************************************** * StreamOnStreamRange implementation * @@ -829,6 +998,76 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, return S_OK; } +static HRESULT map_file(HANDLE file, HANDLE *map, void **mem, LARGE_INTEGER *size) +{ + *map = NULL; + if (!GetFileSizeEx(file, size)) return HRESULT_FROM_WIN32(GetLastError()); + if (size->u.HighPart) + { + WARN("file too large\n"); + return E_FAIL; + } + if (!(*map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, size->u.LowPart, NULL))) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + if (!(*mem = MapViewOfFile(*map, FILE_MAP_READ, 0, 0, size->u.LowPart))) + { + CloseHandle(*map); + return HRESULT_FROM_WIN32(GetLastError()); + } + return S_OK; +} + +HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE file) +{ + IWICStreamImpl *This = impl_from_IWICStream(iface); + StreamOnFileHandle *pObject; + IWICStream *stream = NULL; + HANDLE map; + void *mem; + LARGE_INTEGER size; + HRESULT hr; + TRACE("(%p,%p)\n", iface, file); + + if (This->pStream) return WINCODEC_ERR_WRONGSTATE; + + hr = map_file(file, &map, &mem, &size); + if (FAILED(hr)) return hr; + + hr = StreamImpl_Create(&stream); + if (FAILED(hr)) goto error; + + hr = IWICStreamImpl_InitializeFromMemory(stream, mem, size.u.LowPart); + if (FAILED(hr)) goto error; + + pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnFileHandle)); + if (!pObject) + { + hr = E_OUTOFMEMORY; + goto error; + } + pObject->IStream_iface.lpVtbl = &StreamOnFileHandle_Vtbl; + pObject->ref = 1; + pObject->map = map; + pObject->mem = mem; + pObject->stream = stream; + + if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) + { + /* Some other thread set the stream first. */ + IStream_Release(&pObject->IStream_iface); + return WINCODEC_ERR_WRONGSTATE; + } + return S_OK; + +error: + if (stream) IWICStream_Release(stream); + UnmapViewOfFile(mem); + CloseHandle(map); + return hr; +} + static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *iface, IStream *pIStream, ULARGE_INTEGER ulOffset, ULARGE_INTEGER ulMaxSize) { diff --git a/reactos/dll/win32/windowscodecs/tiffformat.c b/reactos/dll/win32/windowscodecs/tiffformat.c index f18dfa6afbb..f2d8dd73117 100644 --- a/reactos/dll/win32/windowscodecs/tiffformat.c +++ b/reactos/dll/win32/windowscodecs/tiffformat.c @@ -1109,8 +1109,34 @@ static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDeco static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) { - FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; + TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + const BYTE *profile; + UINT len; + HRESULT hr; + + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + + EnterCriticalSection(&This->parent->lock); + + if (pTIFFGetField(This->parent->tiff, TIFFTAG_ICCPROFILE, &len, &profile)) + { + if (cCount && ppIColorContexts) + { + hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); + if (FAILED(hr)) + { + LeaveCriticalSection(&This->parent->lock); + return hr; + } + } + *pcActualCount = 1; + } + else + *pcActualCount = 0; + + LeaveCriticalSection(&This->parent->lock); + + return S_OK; } static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, @@ -1308,6 +1334,7 @@ struct tiff_encode_format { static const struct tiff_encode_format formats[] = { {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1}, + {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0}, {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0}, {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0}, {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0}, @@ -1886,7 +1913,7 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface, if (SUCCEEDED(hr)) { - hr = CreatePropertyBag2(ppIEncoderOptions); + hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); } if (SUCCEEDED(hr)) diff --git a/reactos/dll/win32/windowscodecs/typeof.h b/reactos/dll/win32/windowscodecs/typeof.h index 70cf0fe6a52..f7c68b18273 100644 --- a/reactos/dll/win32/windowscodecs/typeof.h +++ b/reactos/dll/win32/windowscodecs/typeof.h @@ -68,6 +68,7 @@ typedef void (__cdecl typeof(png_write_end))(struct png_struct_def *, struct png typedef void (__cdecl typeof(png_write_info))(struct png_struct_def *, struct png_info_def *); typedef void (__cdecl typeof(png_write_rows))(struct png_struct_def *, unsigned char **row, unsigned int); typedef unsigned int (__cdecl typeof(png_get_iCCP))(struct png_struct_def *, struct png_info_def *, char **, int *, char **, unsigned int *); +typedef void (__cdecl typeof(png_set_crc_action))(struct png_struct_def *, int, int); typedef void *thandle_t_1; typedef int (*TIFFReadWriteProc_1)(thandle_t_1, void *, int); diff --git a/reactos/dll/win32/windowscodecs/wincodecs_private.h b/reactos/dll/win32/windowscodecs/wincodecs_private.h index 6857176dd71..dddb3270000 100644 --- a/reactos/dll/win32/windowscodecs/wincodecs_private.h +++ b/reactos/dll/win32/windowscodecs/wincodecs_private.h @@ -45,6 +45,7 @@ extern HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void* extern HRESULT TgaDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, + UINT stride, UINT datasize, BYTE *bits, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN; extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN; @@ -52,6 +53,7 @@ extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) DECLSPEC_ extern HRESULT PaletteImpl_Create(IWICPalette **palette) DECLSPEC_HIDDEN; extern HRESULT StreamImpl_Create(IWICStream **stream) DECLSPEC_HIDDEN; extern HRESULT ColorContext_Create(IWICColorContext **context) DECLSPEC_HIDDEN; +extern HRESULT ColorTransform_Create(IWICColorTransform **transform) DECLSPEC_HIDDEN; extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, UINT srcwidth, UINT srcheight, INT srcstride, @@ -61,7 +63,8 @@ extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT heigh extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN; -extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2) DECLSPEC_HIDDEN; +extern HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count, + IPropertyBag2 **property) DECLSPEC_HIDDEN; extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN; extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN; @@ -102,4 +105,6 @@ extern HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void ** extern HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; +extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile) DECLSPEC_HIDDEN; + #endif /* WINCODECS_PRIVATE_H */ diff --git a/reactos/include/psdk/wincodec.idl b/reactos/include/psdk/wincodec.idl index a878b2f276c..4e1d039dc85 100644 --- a/reactos/include/psdk/wincodec.idl +++ b/reactos/include/psdk/wincodec.idl @@ -156,6 +156,18 @@ typedef enum WICPixelFormatNumericRepresentation { WICPIXELFORMATNUMERICREPRESENTATION_FORCE_DWORD = CODEC_FORCE_DWORD } WICPixelFormatNumericRepresentation; +typedef enum WICTiffCompressionOption { + WICTiffCompressionDontCare = 0x00000000, + WICTiffCompressionNone = 0x00000001, + WICTiffCompressionCCITT3 = 0x00000002, + WICTiffCompressionCCITT4 = 0x00000003, + WICTiffCompressionLZW = 0x00000004, + WICTiffCompressionRLE = 0x00000005, + WICTiffCompressionZIP = 0x00000006, + WICTiffCompressionLZWHDifferencing = 0x00000007, + WICTIFFCOMPRESSIONOPTION_FORCE_DWORD = CODEC_FORCE_DWORD +} WICTiffCompressionOption; + typedef GUID WICPixelFormatGUID; typedef REFGUID REFWICPixelFormatGUID; @@ -177,6 +189,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppBGR555, 0x6fddc324,0x4e03,0x4bfe, cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppBGR565, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0a);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppBGRA5551, 0x05ec7c2b,0xf1e6,0x4961,0xad,0x46,0xe1,0xcc,0x81,0x0a,0x87,0xd2);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat24bppBGR, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0c);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat24bppRGB, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0d);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGR, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0e);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGRA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0f);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppPBGRA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x10);") @@ -212,11 +225,14 @@ 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; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index be17467c52a..c6b9d4cd1bf 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -187,7 +187,7 @@ reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to Wine-1.5.26 reactos/dll/win32/version # Autosync reactos/dll/win32/wer # Autosync -reactos/dll/win32/windowscodecs # Synced to Wine-1.5.19 +reactos/dll/win32/windowscodecs # Synced to Wine-1.5.26 reactos/dll/win32/winemp3.acm # Synced to Wine-1.5.19 reactos/dll/win32/wing32 # Out of sync reactos/dll/win32/winhttp # Synced to Wine-1.5.26