[WINDOWSCODECS]

* Sync with Wine 1.5.19.
[PSDK]
* Update some headers.
* Import wincodecsdk.idl from Wine.

svn path=/trunk/; revision=57881
This commit is contained in:
Amine Khaldi 2012-12-11 21:17:47 +00:00
parent 2c155d89bc
commit 3552b8c127
38 changed files with 13986 additions and 1587 deletions

View file

@ -1,5 +1,9 @@
add_definitions(-D__WINESRC__)
add_definitions(
-D__WINESRC__
-DENTRY_PREFIX=WIC_
-DPROXY_DELEGATION
-DWINE_REGISTER_DLL)
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x600)
@ -17,32 +21,47 @@ endif()
spec2def(windowscodecs.dll windowscodecs.spec ADD_IMPORTLIB)
add_rpcproxy_files(windowscodecs_wincodec.idl)
list(APPEND SOURCE
bitmap.c
bmpdecode.c
bmpencode.c
clsfactory.c
colorcontext.c
converter.c
fliprotate.c
gifformat.c
icnsformat.c
icoformat.c
imgfactory.c
info.c
jpegformat.c
main.c
metadatahandler.c
palette.c
pngformat.c
propertybag.c
proxy.c
regsvr.c
scaler.c
stream.c
tgaformat.c
tiffformat.c
ungif.c
version.rc
${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c
${CMAKE_CURRENT_BINARY_DIR}/windowscodecs_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/windowscodecs.def)
${CMAKE_CURRENT_BINARY_DIR}/windowscodecs.def
${CMAKE_CURRENT_BINARY_DIR}/windowscodecs_wincodec_p.c)
add_library(windowscodecs SHARED ${SOURCE})
if(NOT MSVC)
# FIXME: http://www.cmake.org/Bug/view.php?id=12998
#allow_warnings(windowscodecs)
set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error")
endif()
add_library(windowscodecs SHARED ${SOURCE} version.rc)
set_module_type(windowscodecs win32dll)
target_link_libraries(windowscodecs wine uuid)
add_importlibs(windowscodecs ole32 shlwapi advapi32 msvcrt kernel32 ntdll)
target_link_libraries(windowscodecs wine uuid ${PSEH_LIB})
add_importlibs(windowscodecs ole32 oleaut32 shlwapi advapi32 rpcrt4 msvcrt kernel32 ntdll)
add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,491 @@
/*
* Copyright 2012 Vincent Povirk 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
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct BitmapImpl {
IWICBitmap IWICBitmap_iface;
LONG ref;
IWICPalette *palette;
int palette_set;
LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
BYTE *data;
UINT width, height;
UINT stride;
UINT bpp;
WICPixelFormatGUID pixelformat;
double dpix, dpiy;
CRITICAL_SECTION cs;
} BitmapImpl;
typedef struct BitmapLockImpl {
IWICBitmapLock IWICBitmapLock_iface;
LONG ref;
BitmapImpl *parent;
UINT width, height;
BYTE *data;
} BitmapLockImpl;
static inline BitmapImpl *impl_from_IWICBitmap(IWICBitmap *iface)
{
return CONTAINING_RECORD(iface, BitmapImpl, IWICBitmap_iface);
}
static inline BitmapLockImpl *impl_from_IWICBitmapLock(IWICBitmapLock *iface)
{
return CONTAINING_RECORD(iface, BitmapLockImpl, IWICBitmapLock_iface);
}
static BOOL BitmapImpl_AcquireLock(BitmapImpl *This, int write)
{
if (write)
{
return 0 == InterlockedCompareExchange(&This->lock, -1, 0);
}
else
{
while (1)
{
LONG prev_val = This->lock;
if (prev_val == -1)
return FALSE;
if (prev_val == InterlockedCompareExchange(&This->lock, prev_val+1, prev_val))
return TRUE;
}
}
}
static void BitmapImpl_ReleaseLock(BitmapImpl *This)
{
while (1)
{
LONG prev_val = This->lock, new_val;
if (prev_val == -1)
new_val = 0;
else
new_val = prev_val - 1;
if (prev_val == InterlockedCompareExchange(&This->lock, new_val, prev_val))
break;
}
}
static HRESULT WINAPI BitmapLockImpl_QueryInterface(IWICBitmapLock *iface, REFIID iid,
void **ppv)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapLock, iid))
{
*ppv = &This->IWICBitmapLock_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI BitmapLockImpl_AddRef(IWICBitmapLock *iface)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI BitmapLockImpl_Release(IWICBitmapLock *iface)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
BitmapImpl_ReleaseLock(This->parent);
IWICBitmap_Release(&This->parent->IWICBitmap_iface);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI BitmapLockImpl_GetSize(IWICBitmapLock *iface,
UINT *puiWidth, UINT *puiHeight)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (!puiWidth || !puiHeight)
return E_INVALIDARG;
*puiWidth = This->width;
*puiHeight = This->height;
return S_OK;
}
static HRESULT WINAPI BitmapLockImpl_GetStride(IWICBitmapLock *iface,
UINT *pcbStride)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
TRACE("(%p,%p)\n", iface, pcbStride);
if (!pcbStride)
return E_INVALIDARG;
*pcbStride = This->parent->stride;
return S_OK;
}
static HRESULT WINAPI BitmapLockImpl_GetDataPointer(IWICBitmapLock *iface,
UINT *pcbBufferSize, BYTE **ppbData)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
TRACE("(%p,%p,%p)\n", iface, pcbBufferSize, ppbData);
if (!pcbBufferSize || !ppbData)
return E_INVALIDARG;
*pcbBufferSize = This->parent->stride * (This->height - 1) +
((This->parent->bpp * This->width) + 7)/8;
*ppbData = This->data;
return S_OK;
}
static HRESULT WINAPI BitmapLockImpl_GetPixelFormat(IWICBitmapLock *iface,
WICPixelFormatGUID *pPixelFormat)
{
BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
return IWICBitmap_GetPixelFormat(&This->parent->IWICBitmap_iface, pPixelFormat);
}
static const IWICBitmapLockVtbl BitmapLockImpl_Vtbl = {
BitmapLockImpl_QueryInterface,
BitmapLockImpl_AddRef,
BitmapLockImpl_Release,
BitmapLockImpl_GetSize,
BitmapLockImpl_GetStride,
BitmapLockImpl_GetDataPointer,
BitmapLockImpl_GetPixelFormat
};
static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid,
void **ppv)
{
BitmapImpl *This = impl_from_IWICBitmap(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_IWICBitmap, iid))
{
*ppv = &This->IWICBitmap_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI BitmapImpl_AddRef(IWICBitmap *iface)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (This->palette) IWICPalette_Release(This->palette);
This->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->cs);
HeapFree(GetProcessHeap(), 0, This->data);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI BitmapImpl_GetSize(IWICBitmap *iface,
UINT *puiWidth, UINT *puiHeight)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (!puiWidth || !puiHeight)
return E_INVALIDARG;
*puiWidth = This->width;
*puiHeight = This->height;
return S_OK;
}
static HRESULT WINAPI BitmapImpl_GetPixelFormat(IWICBitmap *iface,
WICPixelFormatGUID *pPixelFormat)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
if (!pPixelFormat)
return E_INVALIDARG;
memcpy(pPixelFormat, &This->pixelformat, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI BitmapImpl_GetResolution(IWICBitmap *iface,
double *pDpiX, double *pDpiY)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
if (!pDpiX || !pDpiY)
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
*pDpiX = This->dpix;
*pDpiY = This->dpiy;
LeaveCriticalSection(&This->cs);
return S_OK;
}
static HRESULT WINAPI BitmapImpl_CopyPalette(IWICBitmap *iface,
IWICPalette *pIPalette)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%p)\n", iface, pIPalette);
if (!This->palette_set)
return WINCODEC_ERR_PALETTEUNAVAILABLE;
return IWICPalette_InitializeFromPalette(pIPalette, This->palette);
}
static HRESULT WINAPI BitmapImpl_CopyPixels(IWICBitmap *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
return copy_pixels(This->bpp, This->data, This->width, This->height,
This->stride, prc, cbStride, cbBufferSize, pbBuffer);
}
static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock,
DWORD flags, IWICBitmapLock **ppILock)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
BitmapLockImpl *result;
WICRect rc;
TRACE("(%p,%p,%x,%p)\n", iface, prcLock, flags, ppILock);
if (!(flags & (WICBitmapLockRead|WICBitmapLockWrite)) || !ppILock)
return E_INVALIDARG;
if (!prcLock)
{
rc.X = rc.Y = 0;
rc.Width = This->width;
rc.Height = This->height;
prcLock = &rc;
}
else if (prcLock->X >= This->width || prcLock->Y >= This->height ||
prcLock->X + prcLock->Width > This->width ||
prcLock->Y + prcLock->Height > This->height ||
prcLock->Width <= 0 || prcLock->Height <= 0)
return E_INVALIDARG;
else if (((prcLock->X * This->bpp) % 8) != 0)
{
FIXME("Cannot lock at an X coordinate not at a full byte\n");
return E_FAIL;
}
result = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl));
if (!result)
return E_OUTOFMEMORY;
if (!BitmapImpl_AcquireLock(This, flags & WICBitmapLockWrite))
{
HeapFree(GetProcessHeap(), 0, result);
return WINCODEC_ERR_ALREADYLOCKED;
}
result->IWICBitmapLock_iface.lpVtbl = &BitmapLockImpl_Vtbl;
result->ref = 1;
result->parent = This;
result->width = prcLock->Width;
result->height = prcLock->Height;
result->data = This->data + This->stride * prcLock->Y +
(This->bpp * prcLock->X)/8;
IWICBitmap_AddRef(&This->IWICBitmap_iface);
*ppILock = &result->IWICBitmapLock_iface;
return S_OK;
}
static HRESULT WINAPI BitmapImpl_SetPalette(IWICBitmap *iface, IWICPalette *pIPalette)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
HRESULT hr;
TRACE("(%p,%p)\n", iface, pIPalette);
if (!This->palette)
{
IWICPalette *new_palette;
hr = PaletteImpl_Create(&new_palette);
if (FAILED(hr)) return hr;
if (InterlockedCompareExchangePointer((void**)&This->palette, new_palette, NULL))
{
/* someone beat us to it */
IWICPalette_Release(new_palette);
}
}
hr = IWICPalette_InitializeFromPalette(This->palette, pIPalette);
if (SUCCEEDED(hr))
This->palette_set = 1;
return S_OK;
}
static HRESULT WINAPI BitmapImpl_SetResolution(IWICBitmap *iface,
double dpiX, double dpiY)
{
BitmapImpl *This = impl_from_IWICBitmap(iface);
TRACE("(%p,%f,%f)\n", iface, dpiX, dpiY);
EnterCriticalSection(&This->cs);
This->dpix = dpiX;
This->dpiy = dpiY;
LeaveCriticalSection(&This->cs);
return S_OK;
}
static const IWICBitmapVtbl BitmapImpl_Vtbl = {
BitmapImpl_QueryInterface,
BitmapImpl_AddRef,
BitmapImpl_Release,
BitmapImpl_GetSize,
BitmapImpl_GetPixelFormat,
BitmapImpl_GetResolution,
BitmapImpl_CopyPalette,
BitmapImpl_CopyPixels,
BitmapImpl_Lock,
BitmapImpl_SetPalette,
BitmapImpl_SetResolution
};
HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap)
{
HRESULT hr;
BitmapImpl *This;
UINT bpp, stride, datasize;
BYTE *data;
hr = get_pixelformat_bpp(pixelFormat, &bpp);
if (FAILED(hr)) return hr;
stride = (((bpp*uiWidth)+31)/32)*4;
datasize = stride * uiHeight;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
if (!This || !data)
{
HeapFree(GetProcessHeap(), 0, This);
HeapFree(GetProcessHeap(), 0, data);
return E_OUTOFMEMORY;
}
This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
This->ref = 1;
This->palette = NULL;
This->palette_set = 0;
This->lock = 0;
This->data = data;
This->width = uiWidth;
This->height = uiHeight;
This->stride = stride;
This->bpp = bpp;
memcpy(&This->pixelformat, pixelFormat, sizeof(GUID));
This->dpix = This->dpiy = 0.0;
InitializeCriticalSection(&This->cs);
This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapImpl.lock");
*ppIBitmap = &This->IWICBitmap_iface;
return S_OK;
}

View file

@ -18,6 +18,7 @@
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#define COBJMACROS
@ -58,16 +59,16 @@ typedef struct {
DWORD bc2AppData;
} BITMAPCOREHEADER2;
struct BmpDecoder;
typedef HRESULT (*ReadDataFunc)(struct BmpDecoder* This);
typedef HRESULT (*ReadDataFunc)(BmpDecoder* This);
typedef struct BmpDecoder {
const IWICBitmapDecoderVtbl *lpVtbl;
const IWICBitmapFrameDecodeVtbl *lpFrameVtbl;
struct BmpDecoder {
IWICBitmapDecoder IWICBitmapDecoder_iface;
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
LONG ref;
BOOL initialized;
IStream *stream;
BITMAPFILEHEADER bfh;
ULONG palette_offset;
ULONG image_offset;
BITMAPV5HEADER bih;
const WICPixelFormatGUID *pixelformat;
int bitsperpixel;
@ -76,16 +77,25 @@ typedef struct BmpDecoder {
BYTE *imagedata;
BYTE *imagedatastart;
CRITICAL_SECTION lock; /* must be held when initialized/imagedata is set or stream is accessed */
} BmpDecoder;
int packed; /* If TRUE, don't look for a file header and assume a packed DIB. */
int icoframe; /* If TRUE, this is a frame of a .ico file. */
};
static inline BmpDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
static inline BmpDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
return CONTAINING_RECORD(iface, BmpDecoder, lpFrameVtbl);
return CONTAINING_RECORD(iface, BmpDecoder, IWICBitmapDecoder_iface);
}
static inline BmpDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
{
return CONTAINING_RECORD(iface, BmpDecoder, IWICBitmapFrameDecode_iface);
}
static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
void **ppv)
{
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -94,7 +104,7 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = iface;
*ppv = &This->IWICBitmapFrameDecode_iface;
}
else
{
@ -108,22 +118,22 @@ static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
static ULONG WINAPI BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IUnknown_AddRef((IUnknown*)This);
return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
}
static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IUnknown_Release((IUnknown*)This);
return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
}
static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
@ -143,7 +153,7 @@ static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
WICPixelFormatGUID *pPixelFormat)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
memcpy(pPixelFormat, This->pixelformat, sizeof(GUID));
@ -174,7 +184,7 @@ static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, doubl
static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY);
@ -184,7 +194,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
HRESULT hr;
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
int count;
WICColor *wiccolors=NULL;
RGBTRIPLE *bgrcolors=NULL;
@ -213,7 +223,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
goto end;
}
offset.QuadPart = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER);
offset.QuadPart = This->palette_offset;
hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto end;
@ -259,7 +269,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
goto end;
}
offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
offset.QuadPart = This->palette_offset;
hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto end;
@ -296,7 +306,7 @@ end:
static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
BmpDecoder *This = impl_from_frame(iface);
BmpDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
HRESULT hr=S_OK;
UINT width, height;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
@ -369,7 +379,7 @@ static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This)
This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
if (!This->imagedata) return E_OUTOFMEMORY;
offbits.QuadPart = This->bfh.bfOffBits;
offbits.QuadPart = This->image_offset;
hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
@ -395,6 +405,27 @@ fail:
return hr;
}
static HRESULT BmpFrameDecode_ReadRGB8(BmpDecoder* This)
{
HRESULT hr;
UINT width, height;
hr = IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height);
if (SUCCEEDED(hr))
{
hr = BmpFrameDecode_ReadUncompressed(This);
}
if (SUCCEEDED(hr))
{
reverse_bgr8(This->bitsperpixel/8, This->imagedatastart,
width, height, This->stride);
}
return hr;
}
static HRESULT ReadByte(IStream *stream, BYTE *buffer, ULONG buffer_size,
ULONG *cursor, ULONG *bytesread, BYTE *result)
{
@ -447,7 +478,7 @@ static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This)
}
/* read palette */
offbits.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
offbits.QuadPart = This->palette_offset;
hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
@ -455,7 +486,7 @@ static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This)
if (FAILED(hr) || bytesread != palettesize) goto fail;
/* read RLE data */
offbits.QuadPart = This->bfh.bfOffBits;
offbits.QuadPart = This->image_offset;
hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
@ -571,7 +602,7 @@ static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This)
}
/* read palette */
offbits.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
offbits.QuadPart = This->palette_offset;
hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
@ -579,7 +610,7 @@ static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This)
if (FAILED(hr) || bytesread != palettesize) goto fail;
/* read RLE data */
offbits.QuadPart = This->bfh.bfOffBits;
offbits.QuadPart = This->image_offset;
hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
@ -701,6 +732,7 @@ static const struct bitfields_format bitfields_formats[] = {
{16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed},
{32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed},
{32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed},
{32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8},
{0}
};
@ -730,10 +762,15 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) return hr;
hr = IStream_Read(stream, &This->bfh, sizeof(BITMAPFILEHEADER), &bytesread);
if (FAILED(hr)) return hr;
if (bytesread != sizeof(BITMAPFILEHEADER) ||
This->bfh.bfType != 0x4d42 /* "BM" */) return E_FAIL;
if (!This->packed)
{
BITMAPFILEHEADER bfh;
hr = IStream_Read(stream, &bfh, sizeof(BITMAPFILEHEADER), &bytesread);
if (FAILED(hr)) return hr;
if (bytesread != sizeof(BITMAPFILEHEADER) ||
bfh.bfType != 0x4d42 /* "BM" */) return E_FAIL;
This->image_offset = bfh.bfOffBits;
}
hr = IStream_Read(stream, &This->bih.bV5Size, sizeof(DWORD), &bytesread);
if (FAILED(hr)) return hr;
@ -749,6 +786,24 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
if (FAILED(hr)) return hr;
if (bytestoread != bytesread) return E_FAIL;
if (This->packed)
This->palette_offset = This->bih.bV5Size;
else
This->palette_offset = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
if (This->icoframe)
{
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
bch->bcHeight /= 2;
}
else
{
This->bih.bV5Height /= 2;
}
}
/* if this is a BITMAPINFOHEADER with BI_BITFIELDS compression, we need to
read the extra fields */
if (This->bih.bV5Size == sizeof(BITMAPINFOHEADER) &&
@ -758,6 +813,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
if (FAILED(hr)) return hr;
if (bytesread != 12) return E_FAIL;
This->bih.bV5AlphaMask = 0;
This->palette_offset += 12;
}
/* decide what kind of bitmap this is and how/if we can read it */
@ -880,6 +936,23 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
}
}
if (This->packed)
{
/* In a packed DIB, the image follows the palette. */
ULONG palette_count, palette_size;
if (This->bih.bV5ClrUsed)
palette_count = This->bih.bV5ClrUsed;
else if (This->bih.bV5BitCount <= 8)
palette_count = 1 << This->bih.bV5BitCount;
else
palette_count = 0;
if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
palette_size = sizeof(RGBTRIPLE) * palette_count;
else
palette_size = sizeof(RGBQUAD) * palette_count;
This->image_offset = This->palette_offset + palette_size;
}
This->initialized = TRUE;
return S_OK;
@ -888,14 +961,15 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
static HRESULT WINAPI BmpDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapDecoder_iface;
}
else
{
@ -909,7 +983,7 @@ static HRESULT WINAPI BmpDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID
static ULONG WINAPI BmpDecoder_AddRef(IWICBitmapDecoder *iface)
{
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -919,7 +993,7 @@ static ULONG WINAPI BmpDecoder_AddRef(IWICBitmapDecoder *iface)
static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
{
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -936,22 +1010,20 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
return ref;
}
static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
DWORD *pdwCapability)
static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
DWORD *capability)
{
HRESULT hr;
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
EnterCriticalSection(&This->lock);
hr = BmpDecoder_ReadHeaders(This, pIStream);
LeaveCriticalSection(&This->lock);
if (FAILED(hr)) return hr;
TRACE("(%p,%p,%p)\n", iface, stream, capability);
if (This->read_data_func == BmpFrameDecode_ReadUnsupported)
*pdwCapability = 0;
else
*pdwCapability = WICBitmapDecoderCapabilityCanDecodeAllImages;
if (!stream || !capability) return E_INVALIDARG;
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
if (hr != S_OK) return hr;
*capability = This->read_data_func == BmpFrameDecode_ReadUnsupported ? 0 : WICBitmapDecoderCapabilityCanDecodeAllImages;
return S_OK;
}
@ -959,7 +1031,7 @@ static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
WICDecodeOptions cacheOptions)
{
HRESULT hr;
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
EnterCriticalSection(&This->lock);
hr = BmpDecoder_ReadHeaders(This, pIStream);
@ -1039,6 +1111,8 @@ static HRESULT WINAPI BmpDecoder_GetThumbnail(IWICBitmapDecoder *iface,
static HRESULT WINAPI BmpDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
if (!pCount) return E_INVALIDARG;
*pCount = 1;
return S_OK;
}
@ -1046,13 +1120,13 @@ static HRESULT WINAPI BmpDecoder_GetFrameCount(IWICBitmapDecoder *iface,
static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
BmpDecoder *This = (BmpDecoder*)iface;
BmpDecoder *This = impl_from_IWICBitmapDecoder(iface);
if (index != 0) return E_INVALIDARG;
if (!This->stream) return WINCODEC_ERR_WRONGSTATE;
if (!This->stream) return WINCODEC_ERR_FRAMEMISSING;
*ppIBitmapFrame = (IWICBitmapFrameDecode*)&This->lpFrameVtbl;
*ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;
IWICBitmapDecoder_AddRef(iface);
return S_OK;
@ -1075,7 +1149,30 @@ static const IWICBitmapDecoderVtbl BmpDecoder_Vtbl = {
BmpDecoder_GetFrame
};
HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecoder)
{
BmpDecoder *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder));
if (!This) return E_OUTOFMEMORY;
This->IWICBitmapDecoder_iface.lpVtbl = &BmpDecoder_Vtbl;
This->IWICBitmapFrameDecode_iface.lpVtbl = &BmpDecoder_FrameVtbl;
This->ref = 1;
This->initialized = FALSE;
This->stream = NULL;
This->imagedata = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
This->packed = packed;
This->icoframe = icoframe;
*ppDecoder = This;
return S_OK;
}
static HRESULT BmpDecoder_Construct(int packed, int icoframe, IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
BmpDecoder *This;
HRESULT ret;
@ -1086,20 +1183,51 @@ HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder));
if (!This) return E_OUTOFMEMORY;
ret = BmpDecoder_Create(packed, icoframe, &This);
if (FAILED(ret)) return ret;
This->lpVtbl = &BmpDecoder_Vtbl;
This->lpFrameVtbl = &BmpDecoder_FrameVtbl;
This->ref = 1;
This->initialized = FALSE;
This->stream = NULL;
This->imagedata = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
return ret;
}
HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
return BmpDecoder_Construct(FALSE, FALSE, pUnkOuter, iid, ppv);
}
HRESULT DibDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
return BmpDecoder_Construct(TRUE, FALSE, pUnkOuter, iid, ppv);
}
HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder)
{
return BmpDecoder_Create(TRUE, TRUE, ppDecoder);
}
void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder)
{
*ppDecoder = &This->IWICBitmapDecoder_iface;
}
/* Return the offset where the mask of an icon might be, or 0 for failure. */
void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown)
{
assert(This->stream != NULL);
if (This->read_data_func == BmpFrameDecode_ReadUncompressed)
{
/* RGB or BITFIELDS data */
ULONG width, height, bytesperrow, datasize;
IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height);
bytesperrow = (((width * This->bitsperpixel)+31)/32)*4;
datasize = bytesperrow * height;
*mask_offset = This->image_offset + datasize;
}
else
*mask_offset = 0;
*topdown = This->stride > 0;
}

View file

@ -58,7 +58,7 @@ static const struct bmp_pixelformat formats[] = {
};
typedef struct BmpFrameEncode {
const IWICBitmapFrameEncodeVtbl *lpVtbl;
IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
LONG ref;
IStream *stream;
BOOL initialized;
@ -71,10 +71,15 @@ typedef struct BmpFrameEncode {
BOOL committed;
} BmpFrameEncode;
static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
{
return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface);
}
static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
void **ppv)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -82,7 +87,7 @@ static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapFrameEncode_iface;
}
else
{
@ -96,7 +101,7 @@ static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface
static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -106,7 +111,7 @@ static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -124,7 +129,7 @@ static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface)
static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
IPropertyBag2 *pIEncoderOptions)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%p)\n", iface, pIEncoderOptions);
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
@ -137,7 +142,7 @@ static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
UINT uiWidth, UINT uiHeight)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;
@ -151,7 +156,7 @@ static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
double dpiX, double dpiY)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;
@ -165,7 +170,7 @@ static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
WICPixelFormatGUID *pPixelFormat)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
int i;
TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
@ -224,7 +229,7 @@ static HRESULT BmpFrameEncode_AllocateBits(BmpFrameEncode *This)
static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
WICRect rc;
TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
@ -253,7 +258,7 @@ static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
WICRect rc;
WICPixelFormatGUID guid;
@ -309,14 +314,14 @@ static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
This->stride*(This->height-This->lineswritten),
This->bits + This->stride*This->lineswritten);
This->lineswritten += rc.Height;
This->lineswritten += prc->Height;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
BITMAPFILEHEADER bfh;
BITMAPV5HEADER bih;
UINT info_size;
@ -407,16 +412,21 @@ static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = {
};
typedef struct BmpEncoder {
const IWICBitmapEncoderVtbl *lpVtbl;
IWICBitmapEncoder IWICBitmapEncoder_iface;
LONG ref;
IStream *stream;
IWICBitmapFrameEncode *frame;
BmpFrameEncode *frame;
} BmpEncoder;
static inline BmpEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
{
return CONTAINING_RECORD(iface, BmpEncoder, IWICBitmapEncoder_iface);
}
static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -424,7 +434,7 @@ static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapEncoder, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapEncoder_iface;
}
else
{
@ -438,7 +448,7 @@ static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID
static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -448,7 +458,7 @@ static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface)
static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -456,7 +466,7 @@ static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface)
if (ref == 0)
{
if (This->stream) IStream_Release(This->stream);
if (This->frame) IWICBitmapFrameEncode_Release(This->frame);
if (This->frame) IWICBitmapFrameEncode_Release(&This->frame->IWICBitmapFrameEncode_iface);
HeapFree(GetProcessHeap(), 0, This);
}
@ -466,7 +476,7 @@ static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface)
static HRESULT WINAPI BmpEncoder_Initialize(IWICBitmapEncoder *iface,
IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
@ -479,8 +489,8 @@ static HRESULT WINAPI BmpEncoder_Initialize(IWICBitmapEncoder *iface,
static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
GUID *pguidContainerFormat)
{
FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
return E_NOTIMPL;
memcpy(pguidContainerFormat, &GUID_ContainerFormatBmp, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
@ -518,7 +528,7 @@ static HRESULT WINAPI BmpEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmap
static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
BmpFrameEncode *encode;
HRESULT hr;
@ -538,7 +548,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
*ppIEncoderOptions = NULL;
return E_OUTOFMEMORY;
}
encode->lpVtbl = &BmpFrameEncode_Vtbl;
encode->IWICBitmapFrameEncode_iface.lpVtbl = &BmpFrameEncode_Vtbl;
encode->ref = 2;
IStream_AddRef(This->stream);
encode->stream = This->stream;
@ -552,19 +562,18 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
encode->lineswritten = 0;
encode->committed = FALSE;
*ppIFrameEncode = (IWICBitmapFrameEncode*)encode;
This->frame = (IWICBitmapFrameEncode*)encode;
*ppIFrameEncode = &encode->IWICBitmapFrameEncode_iface;
This->frame = encode;
return S_OK;
}
static HRESULT WINAPI BmpEncoder_Commit(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpFrameEncode *frame = (BmpFrameEncode*)This->frame;
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p)\n", iface);
if (!frame || !frame->committed) return WINCODEC_ERR_WRONGSTATE;
if (!This->frame || !This->frame->committed) return WINCODEC_ERR_WRONGSTATE;
return S_OK;
}
@ -606,13 +615,13 @@ HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpEncoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &BmpEncoder_Vtbl;
This->IWICBitmapEncoder_iface.lpVtbl = &BmpEncoder_Vtbl;
This->ref = 1;
This->stream = NULL;
This->frame = NULL;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
return ret;
}

View file

@ -29,6 +29,7 @@
#include "ocidl.h"
#include "initguid.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "wincodecs_private.h"
@ -36,13 +37,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
typedef struct {
REFCLSID classid;
HRESULT (*constructor)(IUnknown*,REFIID,void**);
} classinfo;
static classinfo wic_classes[] = {
{&CLSID_WICImagingFactory, ImagingFactory_CreateInstance},
static const classinfo wic_classes[] = {
{&CLSID_WICImagingFactory, ComponentFactory_CreateInstance},
{&CLSID_WICBmpDecoder, BmpDecoder_CreateInstance},
{&CLSID_WICPngDecoder, PngDecoder_CreateInstance},
{&CLSID_WICPngEncoder, PngEncoder_CreateInstance},
@ -50,27 +53,45 @@ static classinfo wic_classes[] = {
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
{&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
{&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance},
{&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance},
{&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance},
{&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance},
{&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance},
{&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance},
{&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance},
{&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance},
{&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance},
{&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance},
{&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance},
{&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance},
{&CLSID_WICAPEMetadataReader, APEReader_CreateInstance},
{&CLSID_WICGifCommentMetadataReader, GifCommentReader_CreateInstance},
{0}};
typedef struct {
const IClassFactoryVtbl *lpIClassFactoryVtbl;
IClassFactory IClassFactory_iface;
LONG ref;
classinfo *info;
const classinfo *info;
} ClassFactoryImpl;
static inline ClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
{
return CONTAINING_RECORD(iface, ClassFactoryImpl, IClassFactory_iface);
}
static HRESULT WINAPI ClassFactoryImpl_QueryInterface(IClassFactory *iface,
REFIID iid, void **ppv)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ClassFactoryImpl *This = impl_from_IClassFactory(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IClassFactory, iid))
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IClassFactory, iid))
{
*ppv = This;
*ppv = &This->IClassFactory_iface;
}
else
{
@ -84,7 +105,7 @@ static HRESULT WINAPI ClassFactoryImpl_QueryInterface(IClassFactory *iface,
static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ClassFactoryImpl *This = impl_from_IClassFactory(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -94,7 +115,7 @@ static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface)
static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ClassFactoryImpl *This = impl_from_IClassFactory(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -108,7 +129,7 @@ static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface)
static HRESULT WINAPI ClassFactoryImpl_CreateInstance(IClassFactory *iface,
IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ClassFactoryImpl *This = impl_from_IClassFactory(iface);
return This->info->constructor(pUnkOuter, riid, ppv);
}
@ -127,7 +148,7 @@ static const IClassFactoryVtbl ClassFactoryImpl_Vtbl = {
ClassFactoryImpl_LockServer
};
static HRESULT ClassFactoryImpl_Constructor(classinfo *info, REFIID riid, LPVOID *ppv)
static HRESULT ClassFactoryImpl_Constructor(const classinfo *info, REFIID riid, LPVOID *ppv)
{
ClassFactoryImpl *This;
HRESULT ret;
@ -137,12 +158,12 @@ static HRESULT ClassFactoryImpl_Constructor(classinfo *info, REFIID riid, LPVOID
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl));
if (!This) return E_OUTOFMEMORY;
This->lpIClassFactoryVtbl = &ClassFactoryImpl_Vtbl;
This->IClassFactory_iface.lpVtbl = &ClassFactoryImpl_Vtbl;
This->ref = 1;
This->info = info;
ret = IClassFactory_QueryInterface((IClassFactory*)This, riid, ppv);
IClassFactory_Release((IClassFactory*)This);
ret = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
IClassFactory_Release(&This->IClassFactory_iface);
return ret;
}
@ -150,7 +171,7 @@ static HRESULT ClassFactoryImpl_Constructor(classinfo *info, REFIID riid, LPVOID
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
HRESULT ret;
classinfo *info=NULL;
const classinfo *info=NULL;
int i;
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
@ -172,7 +193,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
if (info)
ret = ClassFactoryImpl_Constructor(info, iid, ppv);
else
ret = CLASS_E_CLASSNOTAVAILABLE;
ret = WIC_DllGetClassObject(rclsid, iid, ppv);
TRACE("<-- %08X\n", ret);
return ret;

View file

@ -0,0 +1,215 @@
/*
* Copyright 2012 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
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct ColorContext {
IWICColorContext IWICColorContext_iface;
LONG ref;
WICColorContextType type;
BYTE *profile;
UINT profile_len;
UINT exif_color_space;
} ColorContext;
static inline ColorContext *impl_from_IWICColorContext(IWICColorContext *iface)
{
return CONTAINING_RECORD(iface, ColorContext, IWICColorContext_iface);
}
static HRESULT WINAPI ColorContext_QueryInterface(IWICColorContext *iface, REFIID iid,
void **ppv)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICColorContext, iid))
{
*ppv = &This->IWICColorContext_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ColorContext_AddRef(IWICColorContext *iface)
{
ColorContext *This = impl_from_IWICColorContext(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI ColorContext_Release(IWICColorContext *iface)
{
ColorContext *This = impl_from_IWICColorContext(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
HeapFree(GetProcessHeap(), 0, This->profile);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI ColorContext_InitializeFromFilename(IWICColorContext *iface,
LPCWSTR wzFilename)
{
FIXME("(%p,%s)\n", iface, debugstr_w(wzFilename));
return E_NOTIMPL;
}
static HRESULT WINAPI ColorContext_InitializeFromMemory(IWICColorContext *iface,
const BYTE *pbBuffer, UINT cbBufferSize)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%p,%u)\n", iface, pbBuffer, cbBufferSize);
if (This->type != WICColorContextUninitialized)
return WINCODEC_ERR_WRONGSTATE;
HeapFree(GetProcessHeap(), 0, This->profile);
if (!(This->profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize)))
return E_OUTOFMEMORY;
memcpy(This->profile, pbBuffer, cbBufferSize);
This->profile_len = cbBufferSize;
This->type = WICColorContextProfile;
return S_OK;
}
static HRESULT WINAPI ColorContext_InitializeFromExifColorSpace(IWICColorContext *iface,
UINT value)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%u)\n", iface, value);
if (This->type != WICColorContextUninitialized && This->type != WICColorContextExifColorSpace)
return WINCODEC_ERR_WRONGSTATE;
This->exif_color_space = value;
This->type = WICColorContextExifColorSpace;
return S_OK;
}
static HRESULT WINAPI ColorContext_GetType(IWICColorContext *iface,
WICColorContextType *pType)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%p)\n", iface, pType);
if (!pType) return E_INVALIDARG;
*pType = This->type;
return S_OK;
}
static HRESULT WINAPI ColorContext_GetProfileBytes(IWICColorContext *iface,
UINT cbBuffer, BYTE *pbBuffer, UINT *pcbActual)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%u,%p,%p)\n", iface, cbBuffer, pbBuffer, pcbActual);
if (This->type != WICColorContextProfile)
return WINCODEC_ERR_NOTINITIALIZED;
if (!pcbActual) return E_INVALIDARG;
if (cbBuffer >= This->profile_len && pbBuffer)
memcpy(pbBuffer, This->profile, This->profile_len);
*pcbActual = This->profile_len;
return S_OK;
}
static HRESULT WINAPI ColorContext_GetExifColorSpace(IWICColorContext *iface,
UINT *pValue)
{
ColorContext *This = impl_from_IWICColorContext(iface);
TRACE("(%p,%p)\n", iface, pValue);
if (!pValue) return E_INVALIDARG;
*pValue = This->exif_color_space;
return S_OK;
}
static const IWICColorContextVtbl ColorContext_Vtbl = {
ColorContext_QueryInterface,
ColorContext_AddRef,
ColorContext_Release,
ColorContext_InitializeFromFilename,
ColorContext_InitializeFromMemory,
ColorContext_InitializeFromExifColorSpace,
ColorContext_GetType,
ColorContext_GetProfileBytes,
ColorContext_GetExifColorSpace
};
HRESULT ColorContext_Create(IWICColorContext **colorcontext)
{
ColorContext *This;
if (!colorcontext) return E_INVALIDARG;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext));
if (!This) return E_OUTOFMEMORY;
This->IWICColorContext_iface.lpVtbl = &ColorContext_Vtbl;
This->ref = 1;
This->type = 0;
This->profile = NULL;
This->profile_len = 0;
This->exif_color_space = ~0u;
*colorcontext = &This->IWICColorContext_iface;
return S_OK;
}

View file

@ -47,11 +47,14 @@ enum pixelformat {
format_16bppGray,
format_16bppBGR555,
format_16bppBGR565,
format_16bppBGRA5551,
format_24bppBGR,
format_32bppBGR,
format_32bppBGRA,
format_32bppPBGRA,
format_48bppRGB,
format_64bppRGBA,
format_32bppCMYK,
};
typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc,
@ -64,7 +67,7 @@ struct pixelformatinfo {
};
typedef struct FormatConverter {
const IWICFormatConverterVtbl *lpVtbl;
IWICFormatConverter IWICFormatConverter_iface;
LONG ref;
IWICBitmapSource *source;
const struct pixelformatinfo *dst_format, *src_format;
@ -74,14 +77,9 @@ typedef struct FormatConverter {
CRITICAL_SECTION lock; /* must be held when initialized */
} FormatConverter;
static void make_grayscale_palette(WICColor *colors, UINT num_colors)
static inline FormatConverter *impl_from_IWICFormatConverter(IWICFormatConverter *iface)
{
int i, v;
for (i=0; i<num_colors; i++)
{
v = i * 255 / (num_colors-1);
colors[i] = 0xff000000 | v<<16 | v<<8 | v;
}
return CONTAINING_RECORD(iface, FormatConverter, IWICFormatConverter_iface);
}
static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc,
@ -105,24 +103,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
if (source_format == format_1bppIndexed)
{
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
}
else
{
colors[0] = 0xff000000;
colors[1] = 0xffffffff;
}
res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedBW, FALSE);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = (prc->Width+7)/8;
srcdatasize = srcstride * prc->Height;
@ -137,7 +130,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x+=8) {
BYTE srcval;
@ -177,21 +170,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
if (source_format == format_2bppIndexed)
{
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 4, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
}
else
make_grayscale_palette(colors, 4);
res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 4, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = (prc->Width+3)/4;
srcdatasize = srcstride * prc->Height;
@ -206,7 +197,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x+=4) {
BYTE srcval;
@ -242,21 +233,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
if (source_format == format_4bppIndexed)
{
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
}
else
make_grayscale_palette(colors, 16);
res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray16, FALSE);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = (prc->Width+1)/2;
srcdatasize = srcstride * prc->Height;
@ -271,7 +260,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x+=2) {
BYTE srcval;
@ -314,7 +303,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++)
{
@ -370,7 +359,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++)
*dstpixel++ = colors[*srcbyte++];
@ -409,7 +398,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
srcbyte = srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++)
{
@ -522,6 +511,54 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
return res;
}
return S_OK;
case format_16bppBGRA5551:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const WORD *srcpixel;
BYTE *dstrow;
DWORD *dstpixel;
srcstride = 2 * 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; y<prc->Height; y++) {
srcpixel=(const WORD*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++) {
WORD srcval;
srcval=*srcpixel++;
*dstpixel++=((srcval & 0x8000) ? 0xff000000 : 0) | /* alpha */
((srcval << 9) & 0xf80000) | /* r */
((srcval << 4) & 0x070000) | /* r - 3 bits */
((srcval << 6) & 0x00f800) | /* g */
((srcval << 1) & 0x000700) | /* g - 3 bits */
((srcval << 3) & 0x0000f8) | /* b */
((srcval >> 2) & 0x000007); /* b - 3 bits */
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_24bppBGR:
if (prc)
{
@ -584,6 +621,28 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
case format_32bppPBGRA:
if (prc)
{
HRESULT res;
UINT x, y;
res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
if (FAILED(res)) return res;
for (y=0; y<prc->Height; y++)
for (x=0; x<prc->Width; x++)
{
BYTE alpha = pbBuffer[cbStride*y+4*x+3];
if (alpha != 0 && alpha != 255)
{
pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * 255 / alpha;
pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * 255 / alpha;
pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * 255 / alpha;
}
}
}
return S_OK;
case format_48bppRGB:
if (prc)
{
@ -673,6 +732,27 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
return res;
}
return S_OK;
case format_32bppCMYK:
if (prc)
{
HRESULT res;
UINT x, y;
res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
if (FAILED(res)) return res;
for (y=0; y<prc->Height; y++)
for (x=0; x<prc->Width; x++)
{
BYTE *pixel = pbBuffer+cbStride*y+4*x;
BYTE c=pixel[0], m=pixel[1], y=pixel[2], k=pixel[3];
pixel[0] = (255-y)*(255-k)/255; /* blue */
pixel[1] = (255-m)*(255-k)/255; /* green */
pixel[2] = (255-c)*(255-k)/255; /* red */
pixel[3] = 255; /* alpha */
}
}
return S_OK;
default:
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
@ -685,6 +765,7 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
{
case format_32bppBGR:
case format_32bppBGRA:
case format_32bppPBGRA:
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
@ -693,6 +774,39 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
}
}
static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc,
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
{
HRESULT hr;
switch (source_format)
{
case format_32bppPBGRA:
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
default:
hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
if (SUCCEEDED(hr) && prc)
{
UINT x, y;
for (y=0; y<prc->Height; y++)
for (x=0; x<prc->Width; x++)
{
BYTE alpha = pbBuffer[cbStride*y+4*x+3];
if (alpha != 255)
{
pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255;
pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255;
pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255;
}
}
}
return hr;
}
}
static const struct pixelformatinfo supported_formats[] = {
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
@ -705,11 +819,14 @@ static const struct pixelformatinfo supported_formats[] = {
{format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL},
{format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL},
{format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL},
{format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL},
{format_24bppBGR, &GUID_WICPixelFormat24bppBGR, NULL},
{format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
{format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
{format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA},
{format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL},
{format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL},
{format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL},
{0}
};
@ -726,7 +843,7 @@ static const struct pixelformatinfo *get_formatinfo(const WICPixelFormatGUID *fo
static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid,
void **ppv)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -735,7 +852,7 @@ static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface,
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICFormatConverter, iid))
{
*ppv = This;
*ppv = &This->IWICFormatConverter_iface;
}
else
{
@ -749,7 +866,7 @@ static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface,
static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -759,7 +876,7 @@ static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -778,7 +895,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface,
UINT *puiWidth, UINT *puiHeight)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
@ -791,7 +908,7 @@ static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface,
static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
WICPixelFormatGUID *pPixelFormat)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
TRACE("(%p,%p): stub\n", iface, pPixelFormat);
@ -806,7 +923,7 @@ static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
double *pDpiX, double *pDpiY)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
@ -826,12 +943,28 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
WICRect rc;
HRESULT hr;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
if (This->source)
{
if (!prc)
{
UINT width, height;
hr = IWICBitmapSource_GetSize(This->source, &width, &height);
if (FAILED(hr)) return hr;
rc.X = 0;
rc.Y = 0;
rc.Width = width;
rc.Height = height;
prc = &rc;
}
return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
pbBuffer, This->src_format->format);
}
else
return WINCODEC_ERR_NOTINITIALIZED;
}
@ -840,7 +973,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
const struct pixelformatinfo *srcinfo, *dstinfo;
static INT fixme=0;
GUID srcFormat;
@ -866,6 +999,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
if (!srcinfo)
{
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
FIXME("Unsupported source format %s\n", debugstr_guid(&srcFormat));
goto end;
}
@ -873,6 +1007,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
if (!dstinfo)
{
res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat));
goto end;
}
@ -887,7 +1022,10 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
This->source = pISource;
}
else
{
FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
res = WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
end:
@ -900,23 +1038,34 @@ static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat,
BOOL *pfCanConvert)
{
FormatConverter *This = (FormatConverter*)iface;
FormatConverter *This = impl_from_IWICFormatConverter(iface);
const struct pixelformatinfo *srcinfo, *dstinfo;
TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat),
debugstr_guid(dstPixelFormat), pfCanConvert);
srcinfo = get_formatinfo(srcPixelFormat);
if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
if (!srcinfo)
{
FIXME("Unsupported source format %s\n", debugstr_guid(srcPixelFormat));
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
}
dstinfo = get_formatinfo(dstPixelFormat);
if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
if (!dstinfo)
{
FIXME("Unsupported destination format %s\n", debugstr_guid(dstPixelFormat));
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
}
if (dstinfo->copy_function &&
SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format)))
*pfCanConvert = TRUE;
else
{
FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(srcPixelFormat), debugstr_guid(dstPixelFormat));
*pfCanConvert = FALSE;
}
return S_OK;
}
@ -948,14 +1097,14 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &FormatConverter_Vtbl;
This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl;
This->ref = 1;
This->source = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICFormatConverter_QueryInterface(&This->IWICFormatConverter_iface, iid, ppv);
IWICFormatConverter_Release(&This->IWICFormatConverter_iface);
return ret;
}

View file

@ -34,7 +34,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct FlipRotator {
const IWICBitmapFlipRotatorVtbl *lpVtbl;
IWICBitmapFlipRotator IWICBitmapFlipRotator_iface;
LONG ref;
IWICBitmapSource *source;
int flip_x;
@ -43,10 +43,15 @@ typedef struct FlipRotator {
CRITICAL_SECTION lock; /* must be held when initialized */
} FlipRotator;
static inline FlipRotator *impl_from_IWICBitmapFlipRotator(IWICBitmapFlipRotator *iface)
{
return CONTAINING_RECORD(iface, FlipRotator, IWICBitmapFlipRotator_iface);
}
static HRESULT WINAPI FlipRotator_QueryInterface(IWICBitmapFlipRotator *iface, REFIID iid,
void **ppv)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -55,7 +60,7 @@ static HRESULT WINAPI FlipRotator_QueryInterface(IWICBitmapFlipRotator *iface, R
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFlipRotator, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapFlipRotator_iface;
}
else
{
@ -69,7 +74,7 @@ static HRESULT WINAPI FlipRotator_QueryInterface(IWICBitmapFlipRotator *iface, R
static ULONG WINAPI FlipRotator_AddRef(IWICBitmapFlipRotator *iface)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -79,7 +84,7 @@ static ULONG WINAPI FlipRotator_AddRef(IWICBitmapFlipRotator *iface)
static ULONG WINAPI FlipRotator_Release(IWICBitmapFlipRotator *iface)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -98,7 +103,7 @@ static ULONG WINAPI FlipRotator_Release(IWICBitmapFlipRotator *iface)
static HRESULT WINAPI FlipRotator_GetSize(IWICBitmapFlipRotator *iface,
UINT *puiWidth, UINT *puiHeight)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (!This->source)
@ -112,34 +117,50 @@ static HRESULT WINAPI FlipRotator_GetSize(IWICBitmapFlipRotator *iface,
static HRESULT WINAPI FlipRotator_GetPixelFormat(IWICBitmapFlipRotator *iface,
WICPixelFormatGUID *pPixelFormat)
{
FIXME("(%p,%p): stub\n", iface, pPixelFormat);
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
return E_NOTIMPL;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
else
return IWICBitmapSource_GetPixelFormat(This->source, pPixelFormat);
}
static HRESULT WINAPI FlipRotator_GetResolution(IWICBitmapFlipRotator *iface,
double *pDpiX, double *pDpiY)
{
FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
return E_NOTIMPL;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
else if (This->swap_xy)
return IWICBitmapSource_GetResolution(This->source, pDpiY, pDpiX);
else
return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY);
}
static HRESULT WINAPI FlipRotator_CopyPalette(IWICBitmapFlipRotator *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return E_NOTIMPL;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
TRACE("(%p,%p)\n", iface, pIPalette);
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
else
return IWICBitmapSource_CopyPalette(This->source, pIPalette);
}
static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
HRESULT hr;
UINT y;
UINT srcy, srcwidth, srcheight;
WICRect rc;
WICRect rect;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
@ -155,6 +176,18 @@ static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
hr = IWICBitmapSource_GetSize(This->source, &srcwidth, &srcheight);
if (FAILED(hr)) return hr;
if (!prc)
{
UINT width, height;
hr = IWICBitmapFlipRotator_GetSize(iface, &width, &height);
if (FAILED(hr)) return hr;
rect.X = 0;
rect.Y = 0;
rect.Width = width;
rect.Height = height;
prc = &rect;
}
for (y=prc->Y; y - prc->Y < prc->Height; y++)
{
if (This->flip_y)
@ -181,7 +214,7 @@ static HRESULT WINAPI FlipRotator_CopyPixels(IWICBitmapFlipRotator *iface,
static HRESULT WINAPI FlipRotator_Initialize(IWICBitmapFlipRotator *iface,
IWICBitmapSource *pISource, WICBitmapTransformOptions options)
{
FlipRotator *This = (FlipRotator*)iface;
FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface);
HRESULT hr=S_OK;
TRACE("(%p,%p,%u)\n", iface, pISource, options);
@ -240,7 +273,7 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(FlipRotator));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &FlipRotator_Vtbl;
This->IWICBitmapFlipRotator_iface.lpVtbl = &FlipRotator_Vtbl;
This->ref = 1;
This->source = NULL;
This->flip_x = 0;
@ -249,7 +282,7 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator)
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FlipRotator.lock");
*fliprotator = (IWICBitmapFlipRotator*)This;
*fliprotator = &This->IWICBitmapFlipRotator_iface;
return S_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,789 @@
/*
* Copyright 2010 Damjan Jovanovic
*
* 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
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H
#define GetCurrentProcess GetCurrentProcess_Mac
#define GetCurrentThread GetCurrentThread_Mac
#define LoadResource LoadResource_Mac
#define AnimatePalette AnimatePalette_Mac
#define EqualRgn EqualRgn_Mac
#define FillRgn FillRgn_Mac
#define FrameRgn FrameRgn_Mac
#define GetPixel GetPixel_Mac
#define InvertRgn InvertRgn_Mac
#define LineTo LineTo_Mac
#define OffsetRgn OffsetRgn_Mac
#define PaintRgn PaintRgn_Mac
#define Polygon Polygon_Mac
#define ResizePalette ResizePalette_Mac
#define SetRectRgn SetRectRgn_Mac
#define EqualRect EqualRect_Mac
#define FillRect FillRect_Mac
#define FrameRect FrameRect_Mac
#define GetCursor GetCursor_Mac
#define InvertRect InvertRect_Mac
#define OffsetRect OffsetRect_Mac
#define PtInRect PtInRect_Mac
#define SetCursor SetCursor_Mac
#define SetRect SetRect_Mac
#define ShowCursor ShowCursor_Mac
#define UnionRect UnionRect_Mac
#include <ApplicationServices/ApplicationServices.h>
#undef GetCurrentProcess
#undef GetCurrentThread
#undef LoadResource
#undef AnimatePalette
#undef EqualRgn
#undef FillRgn
#undef FrameRgn
#undef GetPixel
#undef InvertRgn
#undef LineTo
#undef OffsetRgn
#undef PaintRgn
#undef Polygon
#undef ResizePalette
#undef SetRectRgn
#undef EqualRect
#undef FillRect
#undef FrameRect
#undef GetCursor
#undef InvertRect
#undef OffsetRect
#undef PtInRect
#undef SetCursor
#undef SetRect
#undef ShowCursor
#undef UnionRect
#undef DPRINTF
#endif
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
#include "wine/library.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \
MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
typedef struct IcnsEncoder {
IWICBitmapEncoder IWICBitmapEncoder_iface;
LONG ref;
IStream *stream;
IconFamilyHandle icns_family;
BOOL any_frame_committed;
int outstanding_commits;
BOOL committed;
CRITICAL_SECTION lock;
} IcnsEncoder;
static inline IcnsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
{
return CONTAINING_RECORD(iface, IcnsEncoder, IWICBitmapEncoder_iface);
}
typedef struct IcnsFrameEncode {
IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
IcnsEncoder *encoder;
LONG ref;
BOOL initialized;
UINT size;
OSType icns_type;
BYTE* icns_image;
int lines_written;
BOOL committed;
} IcnsFrameEncode;
static inline IcnsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
{
return CONTAINING_RECORD(iface, IcnsFrameEncode, IWICBitmapFrameEncode_iface);
}
static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
void **ppv)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
{
*ppv = &This->IWICBitmapFrameEncode_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (!This->committed)
{
EnterCriticalSection(&This->encoder->lock);
This->encoder->outstanding_commits--;
LeaveCriticalSection(&This->encoder->lock);
}
if (This->icns_image != NULL)
HeapFree(GetProcessHeap(), 0, This->icns_image);
IUnknown_Release((IUnknown*)This->encoder);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
IPropertyBag2 *pIEncoderOptions)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr = S_OK;
TRACE("(%p,%p)\n", iface, pIEncoderOptions);
EnterCriticalSection(&This->encoder->lock);
if (This->initialized)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
This->initialized = TRUE;
end:
LeaveCriticalSection(&This->encoder->lock);
return hr;
}
static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
UINT uiWidth, UINT uiHeight)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr = S_OK;
TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
EnterCriticalSection(&This->encoder->lock);
if (!This->initialized || This->icns_image)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
if (uiWidth != uiHeight)
{
WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight);
hr = E_INVALIDARG;
goto end;
}
switch (uiWidth)
{
case 16:
case 32:
case 48:
case 128:
case 256:
case 512:
break;
default:
WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
hr = E_INVALIDARG;
goto end;
}
This->size = uiWidth;
end:
LeaveCriticalSection(&This->encoder->lock);
return hr;
}
static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
double dpiX, double dpiY)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr = S_OK;
TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
EnterCriticalSection(&This->encoder->lock);
if (!This->initialized || This->icns_image)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
end:
LeaveCriticalSection(&This->encoder->lock);
return S_OK;
}
static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
WICPixelFormatGUID *pPixelFormat)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr = S_OK;
TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
EnterCriticalSection(&This->encoder->lock);
if (!This->initialized || This->icns_image)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
end:
LeaveCriticalSection(&This->encoder->lock);
return S_OK;
}
static HRESULT WINAPI IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
UINT cCount, IWICColorContext **ppIColorContext)
{
FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
return E_NOTIMPL;
}
static HRESULT WINAPI IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIThumbnail)
{
FIXME("(%p,%p): stub\n", iface, pIThumbnail);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr = S_OK;
UINT i;
TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
EnterCriticalSection(&This->encoder->lock);
if (!This->initialized || !This->size)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
if (lineCount == 0 || lineCount + This->lines_written > This->size)
{
hr = E_INVALIDARG;
goto end;
}
if (!This->icns_image)
{
switch (This->size)
{
case 16: This->icns_type = kIconServices16PixelDataARGB; break;
case 32: This->icns_type = kIconServices32PixelDataARGB; break;
case 48: This->icns_type = kIconServices48PixelDataARGB; break;
case 128: This->icns_type = kIconServices128PixelDataARGB; break;
case 256: This->icns_type = kIconServices256PixelDataARGB; break;
case 512: This->icns_type = kIconServices512PixelDataARGB; break;
default:
WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
hr = E_INVALIDARG;
goto end;
}
This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4);
if (!This->icns_image)
{
WARN("failed to allocate image buffer\n");
hr = E_FAIL;
goto end;
}
}
for (i = 0; i < lineCount; i++)
{
BYTE *src_row, *dst_row;
UINT j;
src_row = pbPixels + cbStride * i;
dst_row = This->icns_image + (This->lines_written + i)*(This->size*4);
/* swap bgr -> rgb */
for (j = 0; j < This->size*4; j += 4)
{
dst_row[j] = src_row[j+3];
dst_row[j+1] = src_row[j+2];
dst_row[j+2] = src_row[j+1];
dst_row[j+3] = src_row[j];
}
}
This->lines_written += lineCount;
end:
LeaveCriticalSection(&This->encoder->lock);
return hr;
}
static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
WICRect rc;
WICPixelFormatGUID guid;
UINT stride;
BYTE *pixeldata = NULL;
TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);
if (!This->initialized || !This->size)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
if (FAILED(hr))
goto end;
if (!IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA))
{
FIXME("format %s unsupported, could use WICConvertBitmapSource to convert\n", debugstr_guid(&guid));
hr = E_FAIL;
goto end;
}
if (!prc)
{
UINT width, height;
hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
if (FAILED(hr))
goto end;
rc.X = 0;
rc.Y = 0;
rc.Width = width;
rc.Height = height;
prc = &rc;
}
if (prc->Width != This->size)
{
hr = E_INVALIDARG;
goto end;
}
stride = (32 * This->size + 7)/8;
pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height);
if (!pixeldata)
{
hr = E_OUTOFMEMORY;
goto end;
}
hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, stride,
stride*prc->Height, pixeldata);
if (SUCCEEDED(hr))
{
hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride,
stride*prc->Height, pixeldata);
}
end:
HeapFree(GetProcessHeap(), 0, pixeldata);
return hr;
}
static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface)
{
IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
Handle handle;
OSErr ret;
HRESULT hr = S_OK;
TRACE("(%p): stub\n", iface);
EnterCriticalSection(&This->encoder->lock);
if (!This->icns_image || This->lines_written != This->size || This->committed)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4);
if (ret != noErr || !handle)
{
WARN("PtrToHand failed with error %d\n", ret);
hr = E_FAIL;
goto end;
}
ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle);
DisposeHandle(handle);
if (ret != noErr)
{
WARN("SetIconFamilyData failed for image with error %d\n", ret);
hr = E_FAIL;
goto end;
}
This->committed = TRUE;
This->encoder->any_frame_committed = TRUE;
This->encoder->outstanding_commits--;
end:
LeaveCriticalSection(&This->encoder->lock);
return hr;
}
static HRESULT WINAPI IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
return E_NOTIMPL;
}
static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl = {
IcnsFrameEncode_QueryInterface,
IcnsFrameEncode_AddRef,
IcnsFrameEncode_Release,
IcnsFrameEncode_Initialize,
IcnsFrameEncode_SetSize,
IcnsFrameEncode_SetResolution,
IcnsFrameEncode_SetPixelFormat,
IcnsFrameEncode_SetColorContexts,
IcnsFrameEncode_SetPalette,
IcnsFrameEncode_SetThumbnail,
IcnsFrameEncode_WritePixels,
IcnsFrameEncode_WriteSource,
IcnsFrameEncode_Commit,
IcnsFrameEncode_GetMetadataQueryWriter
};
static HRESULT WINAPI IcnsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapEncoder, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI IcnsEncoder_AddRef(IWICBitmapEncoder *iface)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI IcnsEncoder_Release(IWICBitmapEncoder *iface)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
if (This->icns_family)
DisposeHandle((Handle)This->icns_family);
if (This->stream)
IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI IcnsEncoder_Initialize(IWICBitmapEncoder *iface,
IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
HRESULT hr = S_OK;
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
EnterCriticalSection(&This->lock);
if (This->icns_family)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
This->icns_family = (IconFamilyHandle)NewHandle(0);
if (!This->icns_family)
{
WARN("error creating icns family\n");
hr = E_FAIL;
goto end;
}
IStream_AddRef(pIStream);
This->stream = pIStream;
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI IcnsEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
GUID *pguidContainerFormat)
{
FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
return E_NOTIMPL;
}
static HRESULT WINAPI IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
IWICBitmapEncoderInfo **ppIEncoderInfo)
{
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
return E_NOTIMPL;
}
static HRESULT WINAPI IcnsEncoder_SetColorContexts(IWICBitmapEncoder *iface,
UINT cCount, IWICColorContext **ppIColorContext)
{
FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
return E_NOTIMPL;
}
static HRESULT WINAPI IcnsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
{
TRACE("(%p,%p)\n", iface, pIPalette);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcnsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
{
TRACE("(%p,%p)\n", iface, pIThumbnail);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcnsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
{
TRACE("(%p,%p)\n", iface, pIPreview);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
HRESULT hr = S_OK;
IcnsFrameEncode *frameEncode = NULL;
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
EnterCriticalSection(&This->lock);
if (!This->icns_family)
{
hr = WINCODEC_ERR_NOTINITIALIZED;
goto end;
}
hr = CreatePropertyBag2(ppIEncoderOptions);
if (FAILED(hr))
goto end;
frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode));
if (frameEncode == NULL)
{
hr = E_OUTOFMEMORY;
goto end;
}
frameEncode->IWICBitmapFrameEncode_iface.lpVtbl = &IcnsEncoder_FrameVtbl;
frameEncode->encoder = This;
frameEncode->ref = 1;
frameEncode->initialized = FALSE;
frameEncode->size = 0;
frameEncode->icns_image = NULL;
frameEncode->lines_written = 0;
frameEncode->committed = FALSE;
*ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface;
This->outstanding_commits++;
IUnknown_AddRef((IUnknown*)This);
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI IcnsEncoder_Commit(IWICBitmapEncoder *iface)
{
IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
size_t buffer_size;
HRESULT hr = S_OK;
ULONG byteswritten;
TRACE("(%p)\n", iface);
EnterCriticalSection(&This->lock);
if (!This->any_frame_committed || This->outstanding_commits > 0 || This->committed)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
buffer_size = GetHandleSize((Handle)This->icns_family);
hr = IStream_Write(This->stream, *This->icns_family, buffer_size, &byteswritten);
if (FAILED(hr) || byteswritten != buffer_size)
{
WARN("writing file failed, hr = 0x%08X\n", hr);
hr = E_FAIL;
goto end;
}
This->committed = TRUE;
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
return E_NOTIMPL;
}
static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl = {
IcnsEncoder_QueryInterface,
IcnsEncoder_AddRef,
IcnsEncoder_Release,
IcnsEncoder_Initialize,
IcnsEncoder_GetContainerFormat,
IcnsEncoder_GetEncoderInfo,
IcnsEncoder_SetColorContexts,
IcnsEncoder_SetPalette,
IcnsEncoder_SetThumbnail,
IcnsEncoder_SetPreview,
IcnsEncoder_CreateNewFrame,
IcnsEncoder_Commit,
IcnsEncoder_GetMetadataQueryWriter
};
HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
IcnsEncoder *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder));
if (!This) return E_OUTOFMEMORY;
This->IWICBitmapEncoder_iface.lpVtbl = &IcnsEncoder_Vtbl;
This->ref = 1;
This->stream = NULL;
This->icns_family = NULL;
This->any_frame_committed = FALSE;
This->outstanding_commits = 0;
This->committed = FALSE;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}
#else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) ||
MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */
HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n");
return E_FAIL;
}
#endif

View file

@ -57,7 +57,7 @@ typedef struct
#include "poppack.h"
typedef struct {
const IWICBitmapDecoderVtbl *lpVtbl;
IWICBitmapDecoder IWICBitmapDecoder_iface;
LONG ref;
BOOL initialized;
IStream *stream;
@ -66,17 +66,27 @@ typedef struct {
} IcoDecoder;
typedef struct {
const IWICBitmapFrameDecodeVtbl *lpVtbl;
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
LONG ref;
ICONDIRENTRY entry;
IcoDecoder *parent;
UINT width, height;
double dpiX, dpiY;
BYTE *bits;
} IcoFrameDecode;
static inline IcoDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
return CONTAINING_RECORD(iface, IcoDecoder, IWICBitmapDecoder_iface);
}
static inline IcoFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
{
return CONTAINING_RECORD(iface, IcoFrameDecode, IWICBitmapFrameDecode_iface);
}
static HRESULT WINAPI IcoFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
void **ppv)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -85,7 +95,7 @@ static HRESULT WINAPI IcoFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapFrameDecode_iface;
}
else
{
@ -99,7 +109,7 @@ static HRESULT WINAPI IcoFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface
static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -109,14 +119,13 @@ static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
IUnknown_Release((IUnknown*)This->parent);
HeapFree(GetProcessHeap(), 0, This->bits);
HeapFree(GetProcessHeap(), 0, This);
}
@ -127,10 +136,10 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
*puiWidth = This->entry.bWidth ? This->entry.bWidth : 256;
*puiHeight = This->entry.bHeight ? This->entry.bHeight : 256;
*puiWidth = This->width;
*puiHeight = This->height;
TRACE("(%p) -> (%i,%i)\n", iface, *puiWidth, *puiHeight);
@ -147,8 +156,14 @@ static HRESULT WINAPI IcoFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface
static HRESULT WINAPI IcoFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
return E_NOTIMPL;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
*pDpiX = This->dpiX;
*pDpiY = This->dpiY;
TRACE("(%p) -> (%f,%f)\n", iface, *pDpiX, *pDpiY);
return S_OK;
}
static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
@ -158,378 +173,13 @@ static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
return WINCODEC_ERR_PALETTEUNAVAILABLE;
}
static inline void pixel_set_trans(DWORD* pixel, BOOL transparent)
{
if (transparent) *pixel = 0;
else *pixel |= 0xff000000;
}
static HRESULT IcoFrameDecode_ReadPixels(IcoFrameDecode *This)
{
BITMAPINFOHEADER bih;
DWORD colors[256];
UINT colorcount=0;
LARGE_INTEGER seek;
ULONG bytesread;
HRESULT hr;
BYTE *tempdata = NULL;
BYTE *bits = NULL;
UINT bitsStride;
UINT bitsSize;
UINT width, height;
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
/* read the BITMAPINFOHEADER */
seek.QuadPart = This->entry.dwDIBOffset;
hr = IStream_Seek(This->parent->stream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
hr = IStream_Read(This->parent->stream, &bih, sizeof(BITMAPINFOHEADER), &bytesread);
if (FAILED(hr) || bytesread != sizeof(BITMAPINFOHEADER)) goto fail;
if (bih.biBitCount <= 8)
{
/* read the palette */
colorcount = bih.biClrUsed ? bih.biClrUsed : 1 << bih.biBitCount;
hr = IStream_Read(This->parent->stream, colors, sizeof(RGBQUAD)*colorcount, &bytesread);
if (FAILED(hr) || bytesread != sizeof(RGBQUAD)*colorcount) goto fail;
}
bitsStride = width * 4;
bitsSize = bitsStride * height;
/* read the XOR data */
switch (bih.biBitCount)
{
case 1:
{
UINT xorBytesPerRow = (width+31)/32*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 1-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>7];
if (x+1 < width) *bitsPixel++ = colors[xorVal>>6&1];
if (x+2 < width) *bitsPixel++ = colors[xorVal>>5&1];
if (x+3 < width) *bitsPixel++ = colors[xorVal>>4&1];
if (x+4 < width) *bitsPixel++ = colors[xorVal>>3&1];
if (x+5 < width) *bitsPixel++ = colors[xorVal>>2&1];
if (x+6 < width) *bitsPixel++ = colors[xorVal>>1&1];
if (x+7 < width) *bitsPixel++ = colors[xorVal&1];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 4:
{
UINT xorBytesPerRow = (width+7)/8*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 4-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=2) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>4];
if (x+1 < width) *bitsPixel++ = colors[xorVal&0xf];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 8:
{
UINT xorBytesPerRow = (width+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 8-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x++)
*bitsPixel++ = colors[*xorByte++];
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 24:
{
UINT xorBytesPerRow = (width*3+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* copy BGR->BGRA */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
BYTE *bitsByte=bitsRow;
for (x=0; x<width; x++)
{
*bitsByte++ = *xorByte++; /* blue */
*bitsByte++ = *xorByte++; /* green */
*bitsByte++ = *xorByte++; /* red */
bitsByte++; /* alpha */
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 32:
{
UINT xorBytesPerRow = width*4;
UINT xorBytes = xorBytesPerRow * height;
bits = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!bits)
{
hr = E_OUTOFMEMORY;
goto fail;
}
if (bih.biHeight > 0) /* bottom-up DIB */
{
/* read the rows backwards so we get a top-down DIB */
UINT i;
BYTE *xorRow = bits + xorBytesPerRow * (height-1);
for (i=0; i<height; i++)
{
hr = IStream_Read(This->parent->stream, xorRow, xorBytesPerRow, &bytesread);
if (FAILED(hr) || bytesread != xorBytesPerRow) goto fail;
xorRow -= xorBytesPerRow;
}
}
else /* top-down DIB */
{
hr = IStream_Read(This->parent->stream, bits, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
}
break;
}
default:
FIXME("unsupported bitcount: %u\n", bih.biBitCount);
goto fail;
}
if (bih.biBitCount < 32)
{
/* set alpha data based on the AND mask */
UINT andBytesPerRow = (width+31)/32*4;
UINT andBytes = andBytesPerRow * height;
INT andStride;
BYTE *andRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, andBytes, &bytesread);
if (FAILED(hr) || bytesread != andBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
andStride = -andBytesPerRow;
andRow = tempdata + (height-1)*andBytesPerRow;
}
else /* top-down DIB */
{
andStride = andBytesPerRow;
andRow = tempdata;
}
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *andByte=andRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE andVal=*andByte++;
pixel_set_trans(bitsPixel++, andVal>>7&1);
if (x+1 < width) pixel_set_trans(bitsPixel++, andVal>>6&1);
if (x+2 < width) pixel_set_trans(bitsPixel++, andVal>>5&1);
if (x+3 < width) pixel_set_trans(bitsPixel++, andVal>>4&1);
if (x+4 < width) pixel_set_trans(bitsPixel++, andVal>>3&1);
if (x+5 < width) pixel_set_trans(bitsPixel++, andVal>>2&1);
if (x+6 < width) pixel_set_trans(bitsPixel++, andVal>>1&1);
if (x+7 < width) pixel_set_trans(bitsPixel++, andVal&1);
}
andRow += andStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
}
This->bits = bits;
return S_OK;
fail:
HeapFree(GetProcessHeap(), 0, tempdata);
HeapFree(GetProcessHeap(), 0, bits);
if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr);
return hr;
}
static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
HRESULT hr=S_OK;
UINT width, height, stride;
IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
EnterCriticalSection(&This->parent->lock);
if (!This->bits)
{
hr = IcoFrameDecode_ReadPixels(This);
}
LeaveCriticalSection(&This->parent->lock);
if (FAILED(hr)) return hr;
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
stride = width * 4;
return copy_pixels(32, This->bits, width, height, stride,
return copy_pixels(32, This->bits, This->width, This->height, This->width * 4,
prc, cbStride, cbBufferSize, pbBuffer);
}
@ -550,8 +200,8 @@ static HRESULT WINAPI IcoFrameDecode_GetColorContexts(IWICBitmapFrameDecode *ifa
static HRESULT WINAPI IcoFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
IWICBitmapSource **ppIThumbnail)
{
TRACE("(%p,%p)\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
FIXME("(%p,%p)\n", iface, ppIThumbnail);
return E_NOTIMPL;
}
static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = {
@ -568,17 +218,238 @@ static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = {
IcoFrameDecode_GetThumbnail
};
static inline void pixel_set_trans(DWORD* pixel, BOOL transparent)
{
if (transparent) *pixel = 0;
else *pixel |= 0xff000000;
}
static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result)
{
HRESULT hr;
BmpDecoder *bmp_decoder;
IWICBitmapDecoder *decoder;
IWICBitmapFrameDecode *framedecode;
WICPixelFormatGUID pixelformat;
IWICBitmapSource *source;
int has_alpha=FALSE; /* if TRUE, alpha data might be in the image data */
WICRect rc;
hr = IcoDibDecoder_CreateInstance(&bmp_decoder);
if (SUCCEEDED(hr))
{
BmpDecoder_GetWICDecoder(bmp_decoder, &decoder);
hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
if (SUCCEEDED(hr))
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
if (SUCCEEDED(hr))
{
hr = IWICBitmapFrameDecode_GetSize(framedecode, &result->width, &result->height);
if (SUCCEEDED(hr))
{
result->bits = HeapAlloc(GetProcessHeap(), 0, result->width * result->height * 4);
if (!result->bits) hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat);
if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat32bppBGR) ||
IsEqualGUID(&pixelformat, &GUID_WICPixelFormat32bppBGRA))
{
source = (IWICBitmapSource*)framedecode;
IWICBitmapSource_AddRef(source);
has_alpha = TRUE;
}
else
{
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
(IWICBitmapSource*)framedecode, &source);
has_alpha = FALSE;
}
if (SUCCEEDED(hr))
{
rc.X = 0;
rc.Y = 0;
rc.Width = result->width;
rc.Height = result->height;
hr = IWICBitmapSource_CopyPixels(source, &rc, result->width * 4,
result->width * result->height * 4, result->bits);
IWICBitmapSource_Release(source);
}
if (SUCCEEDED(hr))
hr = IWICBitmapFrameDecode_GetResolution(framedecode, &result->dpiX, &result->dpiY);
IWICBitmapFrameDecode_Release(framedecode);
}
if (SUCCEEDED(hr) && has_alpha)
{
/* If the alpha channel is fully transparent, we should ignore it. */
int nonzero_alpha = 0;
int i;
for (i=0; i<(result->height*result->width); i++)
{
if (result->bits[i*4+3] != 0)
{
nonzero_alpha = 1;
break;
}
}
if (!nonzero_alpha)
{
for (i=0; i<(result->height*result->width); i++)
result->bits[i*4+3] = 0xff;
has_alpha = FALSE;
}
}
if (SUCCEEDED(hr) && !has_alpha)
{
/* set alpha data based on the AND mask */
UINT andBytesPerRow = (result->width+31)/32*4;
UINT andBytes = andBytesPerRow * result->height;
INT andStride;
BYTE *tempdata=NULL;
BYTE *andRow;
BYTE *bitsRow;
UINT bitsStride = result->width * 4;
UINT x, y;
ULONG offset;
ULONG bytesread;
LARGE_INTEGER seek;
int topdown;
BmpDecoder_FindIconMask(bmp_decoder, &offset, &topdown);
if (offset)
{
seek.QuadPart = offset;
hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, 0);
if (SUCCEEDED(hr))
{
tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes);
if (!tempdata) hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
hr = IStream_Read(stream, tempdata, andBytes, &bytesread);
if (SUCCEEDED(hr) && bytesread == andBytes)
{
if (topdown)
{
andStride = andBytesPerRow;
andRow = tempdata;
}
else
{
andStride = -andBytesPerRow;
andRow = tempdata + (result->height-1)*andBytesPerRow;
}
bitsRow = result->bits;
for (y=0; y<result->height; y++) {
BYTE *andByte=andRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<result->width; x+=8) {
BYTE andVal=*andByte++;
pixel_set_trans(bitsPixel++, andVal>>7&1);
if (x+1 < result->width) pixel_set_trans(bitsPixel++, andVal>>6&1);
if (x+2 < result->width) pixel_set_trans(bitsPixel++, andVal>>5&1);
if (x+3 < result->width) pixel_set_trans(bitsPixel++, andVal>>4&1);
if (x+4 < result->width) pixel_set_trans(bitsPixel++, andVal>>3&1);
if (x+5 < result->width) pixel_set_trans(bitsPixel++, andVal>>2&1);
if (x+6 < result->width) pixel_set_trans(bitsPixel++, andVal>>1&1);
if (x+7 < result->width) pixel_set_trans(bitsPixel++, andVal&1);
}
andRow += andStride;
bitsRow += bitsStride;
}
}
HeapFree(GetProcessHeap(), 0, tempdata);
}
}
IWICBitmapDecoder_Release(decoder);
}
return hr;
}
static HRESULT ReadIcoPng(IStream *stream, IcoFrameDecode *result)
{
IWICBitmapDecoder *decoder = NULL;
IWICBitmapFrameDecode *sourceFrame = NULL;
IWICBitmapSource *sourceBitmap = NULL;
WICRect rect;
HRESULT hr;
hr = PngDecoder_CreateInstance(NULL, &IID_IWICBitmapDecoder, (void**)&decoder);
if (FAILED(hr))
goto end;
hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad);
if (FAILED(hr))
goto end;
hr = IWICBitmapDecoder_GetFrame(decoder, 0, &sourceFrame);
if (FAILED(hr))
goto end;
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, (IWICBitmapSource*)sourceFrame, &sourceBitmap);
if (FAILED(hr))
goto end;
hr = IWICBitmapFrameDecode_GetSize(sourceFrame, &result->width, &result->height);
if (FAILED(hr))
goto end;
hr = IWICBitmapFrameDecode_GetResolution(sourceFrame, &result->dpiX, &result->dpiY);
if (FAILED(hr))
goto end;
result->bits = HeapAlloc(GetProcessHeap(), 0, 4 * result->width * result->height);
if (result->bits == NULL)
{
hr = E_OUTOFMEMORY;
goto end;
}
rect.X = 0;
rect.Y = 0;
rect.Width = result->width;
rect.Height = result->height;
hr = IWICBitmapSource_CopyPixels(sourceBitmap, &rect, 4*result->width,
4*result->width*result->height, result->bits);
end:
if (decoder != NULL)
IWICBitmapDecoder_Release(decoder);
if (sourceFrame != NULL)
IWICBitmapFrameDecode_Release(sourceFrame);
if (sourceBitmap != NULL)
IWICBitmapSource_Release(sourceBitmap);
return hr;
}
static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapDecoder_iface;
}
else
{
@ -592,7 +463,7 @@ static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID
static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -602,7 +473,7 @@ static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface)
static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -618,17 +489,26 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface)
return ref;
}
static HRESULT WINAPI IcoDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
DWORD *pdwCapability)
static HRESULT WINAPI IcoDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
DWORD *capability)
{
FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
return E_NOTIMPL;
HRESULT hr;
TRACE("(%p,%p,%p)\n", iface, stream, capability);
if (!stream || !capability) return E_INVALIDARG;
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
if (hr != S_OK) return hr;
*capability = WICBitmapDecoderCapabilityCanDecodeAllImages;
return S_OK;
}
static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
LARGE_INTEGER seek;
HRESULT hr;
ULONG bytesread;
@ -670,15 +550,27 @@ end:
static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
GUID *pguidContainerFormat)
{
FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
return E_NOTIMPL;
memcpy(pguidContainerFormat, &GUID_ContainerFormatIco, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI IcoDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo);
return E_NOTIMPL;
HRESULT hr;
IWICComponentInfo *compinfo;
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
hr = CreateComponentInfo(&CLSID_WICIcoDecoder, &compinfo);
if (FAILED(hr)) return hr;
hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
(void**)ppIDecoderInfo);
IWICComponentInfo_Release(compinfo);
return hr;
}
static HRESULT WINAPI IcoDecoder_CopyPalette(IWICBitmapDecoder *iface,
@ -719,13 +611,15 @@ static HRESULT WINAPI IcoDecoder_GetThumbnail(IWICBitmapDecoder *iface,
static HRESULT WINAPI IcoDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
IcoDecoder *This = (IcoDecoder*)iface;
TRACE("(%p,%p)\n", iface, pCount);
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
if (!pCount) return E_INVALIDARG;
*pCount = This->header.idCount;
TRACE("<-- %u\n", *pCount);
EnterCriticalSection(&This->lock);
*pCount = This->initialized ? This->header.idCount : 0;
LeaveCriticalSection(&This->lock);
TRACE("(%p) <-- %d\n", iface, *pCount);
return S_OK;
}
@ -733,18 +627,22 @@ static HRESULT WINAPI IcoDecoder_GetFrameCount(IWICBitmapDecoder *iface,
static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoDecoder *This = impl_from_IWICBitmapDecoder(iface);
IcoFrameDecode *result=NULL;
LARGE_INTEGER seek;
ULARGE_INTEGER offset, length;
HRESULT hr;
ULONG bytesread;
ICONDIRENTRY entry;
IWICStream *substream=NULL;
DWORD magic;
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
EnterCriticalSection(&This->lock);
if (!This->initialized)
{
hr = WINCODEC_ERR_NOTINITIALIZED;
hr = WINCODEC_ERR_FRAMEMISSING;
goto fail;
}
@ -761,9 +659,8 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
goto fail;
}
result->lpVtbl = &IcoFrameDecode_Vtbl;
result->IWICBitmapFrameDecode_iface.lpVtbl = &IcoFrameDecode_Vtbl;
result->ref = 1;
result->parent = This;
result->bits = NULL;
/* read the icon entry */
@ -771,20 +668,54 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, 0);
if (FAILED(hr)) goto fail;
hr = IStream_Read(This->stream, &result->entry, sizeof(ICONDIRENTRY), &bytesread);
hr = IStream_Read(This->stream, &entry, sizeof(ICONDIRENTRY), &bytesread);
if (FAILED(hr) || bytesread != sizeof(ICONDIRENTRY)) goto fail;
IWICBitmapDecoder_AddRef(iface);
/* create a stream object for this icon */
hr = StreamImpl_Create(&substream);
if (FAILED(hr)) goto fail;
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
offset.QuadPart = entry.dwDIBOffset;
length.QuadPart = entry.dwDIBSize;
hr = IWICStream_InitializeFromIStreamRegion(substream, This->stream, offset, length);
if (FAILED(hr)) goto fail;
/* read the bitmapinfo size or magic number */
hr = IWICStream_Read(substream, &magic, sizeof(magic), &bytesread);
if (FAILED(hr) || bytesread != sizeof(magic)) goto fail;
/* forward to the appropriate decoding function based on the magic number */
switch (magic)
{
case sizeof(BITMAPCOREHEADER):
case 64: /* sizeof(BITMAPCOREHEADER2) */
case sizeof(BITMAPINFOHEADER):
case sizeof(BITMAPV4HEADER):
case sizeof(BITMAPV5HEADER):
hr = ReadIcoDib((IStream*)substream, result);
break;
case 0x474e5089:
hr = ReadIcoPng((IStream*)substream, result);
break;
default:
FIXME("Unrecognized ICO frame magic: %x\n", magic);
hr = E_FAIL;
break;
}
if (FAILED(hr)) goto fail;
*ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface;
LeaveCriticalSection(&This->lock);
IWICStream_Release(substream);
return S_OK;
fail:
LeaveCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, result);
if (substream) IWICStream_Release(substream);
if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr);
return hr;
@ -821,15 +752,15 @@ HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoDecoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &IcoDecoder_Vtbl;
This->IWICBitmapDecoder_iface.lpVtbl = &IcoDecoder_Vtbl;
This->ref = 1;
This->stream = NULL;
This->initialized = FALSE;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
return ret;
}

View file

@ -28,6 +28,7 @@
#include "objbase.h"
#include "shellapi.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "wincodecs_private.h"
@ -36,21 +37,28 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
const IWICImagingFactoryVtbl *lpIWICImagingFactoryVtbl;
IWICComponentFactory IWICComponentFactory_iface;
LONG ref;
} ImagingFactory;
} ComponentFactory;
static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory *iface, REFIID iid,
static inline ComponentFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
{
return CONTAINING_RECORD(iface, ComponentFactory, IWICComponentFactory_iface);
}
static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid,
void **ppv)
{
ImagingFactory *This = (ImagingFactory*)iface;
ComponentFactory *This = impl_from_IWICComponentFactory(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICImagingFactory, iid))
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICImagingFactory, iid) ||
IsEqualIID(&IID_IWICComponentFactory, iid))
{
*ppv = This;
*ppv = &This->IWICComponentFactory_iface;
}
else
{
@ -62,9 +70,9 @@ static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory *iface, R
return S_OK;
}
static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory *iface)
static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface)
{
ImagingFactory *This = (ImagingFactory*)iface;
ComponentFactory *This = impl_from_IWICComponentFactory(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -72,9 +80,9 @@ static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory *iface)
return ref;
}
static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory *iface)
static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface)
{
ImagingFactory *This = (ImagingFactory*)iface;
ComponentFactory *This = impl_from_IWICComponentFactory(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -85,8 +93,8 @@ static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory *iface)
return ref;
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
IWICImagingFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(
IWICComponentFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
IWICBitmapDecoder **ppIDecoder)
{
@ -103,7 +111,7 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
if (SUCCEEDED(hr))
{
hr = IWICImagingFactory_CreateDecoderFromStream(iface, (IStream*)stream,
hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream,
pguidVendor, metadataOptions, ppIDecoder);
}
@ -113,27 +121,20 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
return hr;
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
IWICImagingFactory *iface, IStream *pIStream, const GUID *pguidVendor,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
WICDecodeOptions metadataOptions)
{
static int fixme=0;
IEnumUnknown *enumdecoders;
IUnknown *unkdecoderinfo;
IWICBitmapDecoderInfo *decoderinfo;
IWICBitmapDecoder *decoder=NULL;
HRESULT res=S_OK;
IWICBitmapDecoder *decoder = NULL;
GUID vendor;
HRESULT res;
ULONG num_fetched;
BOOL matches;
TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
metadataOptions, ppIDecoder);
if (pguidVendor && !fixme++)
FIXME("ignoring vendor GUID\n");
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
if (FAILED(res)) return res;
if (FAILED(res)) return NULL;
while (!decoder)
{
@ -145,6 +146,17 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
if (SUCCEEDED(res))
{
if (pguidVendor)
{
res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor))
{
IWICBitmapDecoderInfo_Release(decoderinfo);
IUnknown_Release(unkdecoderinfo);
continue;
}
}
res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);
if (SUCCEEDED(res) && matches)
@ -176,6 +188,24 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
IEnumUnknown_Release(enumdecoders);
return decoder;
}
static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
IWICComponentFactory *iface, IStream *pIStream, const GUID *pguidVendor,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
HRESULT res;
IWICBitmapDecoder *decoder = NULL;
TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
metadataOptions, ppIDecoder);
if (pguidVendor)
decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
if (!decoder)
decoder = find_decoder(pIStream, NULL, metadataOptions);
if (decoder)
{
*ppIDecoder = decoder;
@ -203,8 +233,8 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
}
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
IWICImagingFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor,
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),
@ -212,104 +242,331 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface,
REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
{
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
return CreateComponentInfo(clsidComponent, ppIInfo);
}
static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface,
REFGUID guidContainerFormat, const GUID *pguidVendor,
IWICBitmapDecoder **ppIDecoder)
{
FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
IEnumUnknown *enumdecoders;
IUnknown *unkdecoderinfo;
IWICBitmapDecoderInfo *decoderinfo;
IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL;
GUID vendor;
HRESULT res;
ULONG num_fetched;
TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
debugstr_guid(pguidVendor), ppIDecoder);
return E_NOTIMPL;
if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG;
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
if (FAILED(res)) return res;
while (!preferred_decoder)
{
res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
if (res != S_OK) break;
res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo);
if (SUCCEEDED(res))
{
GUID container_guid;
res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid);
if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat))
{
IWICBitmapDecoder *new_decoder;
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder);
if (SUCCEEDED(res))
{
if (pguidVendor)
{
res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor))
{
preferred_decoder = new_decoder;
new_decoder = NULL;
}
}
if (new_decoder && !decoder)
{
decoder = new_decoder;
new_decoder = NULL;
}
if (new_decoder) IWICBitmapDecoder_Release(new_decoder);
}
}
IWICBitmapDecoderInfo_Release(decoderinfo);
}
IUnknown_Release(unkdecoderinfo);
}
IEnumUnknown_Release(enumdecoders);
if (preferred_decoder)
{
*ppIDecoder = preferred_decoder;
if (decoder) IWICBitmapDecoder_Release(decoder);
return S_OK;
}
if (decoder)
{
*ppIDecoder = decoder;
return S_OK;
}
*ppIDecoder = NULL;
return WINCODEC_ERR_COMPONENTNOTFOUND;
}
static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface,
REFGUID guidContainerFormat, const GUID *pguidVendor,
IWICBitmapEncoder **ppIEncoder)
{
FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
static int fixme=0;
IEnumUnknown *enumencoders;
IUnknown *unkencoderinfo;
IWICBitmapEncoderInfo *encoderinfo;
IWICBitmapEncoder *encoder=NULL;
HRESULT res=S_OK;
ULONG num_fetched;
GUID actual_containerformat;
TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
debugstr_guid(pguidVendor), ppIEncoder);
return E_NOTIMPL;
if (pguidVendor && !fixme++)
FIXME("ignoring vendor GUID\n");
res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders);
if (FAILED(res)) return res;
while (!encoder)
{
res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched);
if (res == S_OK)
{
res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo);
if (SUCCEEDED(res))
{
res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat);
if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat))
{
res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder);
if (FAILED(res))
encoder = NULL;
}
IWICBitmapEncoderInfo_Release(encoderinfo);
}
IUnknown_Release(unkencoderinfo);
}
else
break;
}
IEnumUnknown_Release(enumencoders);
if (encoder)
{
*ppIEncoder = encoder;
return S_OK;
}
else
{
WARN("failed to create encoder\n");
*ppIEncoder = NULL;
return WINCODEC_ERR_COMPONENTNOTFOUND;
}
}
static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface,
IWICPalette **ppIPalette)
{
TRACE("(%p,%p)\n", iface, ppIPalette);
return PaletteImpl_Create(ppIPalette);
}
static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface,
IWICFormatConverter **ppIFormatConverter)
{
return FormatConverter_CreateInstance(NULL, &IID_IWICFormatConverter, (void**)ppIFormatConverter);
}
static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface,
IWICBitmapScaler **ppIBitmapScaler)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapScaler);
return E_NOTIMPL;
TRACE("(%p,%p)\n", iface, ppIBitmapScaler);
return BitmapScaler_Create(ppIBitmapScaler);
}
static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface,
IWICBitmapClipper **ppIBitmapClipper)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapClipper);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface,
IWICBitmapFlipRotator **ppIBitmapFlipRotator)
{
TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator);
return FlipRotator_Create(ppIBitmapFlipRotator);
}
static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface,
IWICStream **ppIWICStream)
{
TRACE("(%p,%p)\n", iface, ppIWICStream);
return StreamImpl_Create(ppIWICStream);
}
static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface,
IWICColorContext **ppIColorContext)
{
FIXME("(%p,%p): stub\n", iface, ppIColorContext);
return E_NOTIMPL;
TRACE("(%p,%p)\n", iface, ppIColorContext);
return ColorContext_Create(ppIColorContext);
}
static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface,
IWICColorTransform **ppIColorTransform)
{
FIXME("(%p,%p): stub\n", iface, ppIColorTransform);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
FIXME("(%p,%u,%u,%s,%u,%p): stub\n", iface, uiWidth, uiHeight,
TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
debugstr_guid(pixelFormat), option, ppIBitmap);
return E_NOTIMPL;
return BitmapImpl_Create(uiWidth, uiHeight, pixelFormat, option, ppIBitmap);
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%u,%p): stub\n", iface, piBitmapSource, option, ppIBitmap);
return E_NOTIMPL;
IWICBitmap *result;
IWICBitmapLock *lock;
IWICPalette *palette;
UINT width, height;
WICPixelFormatGUID pixelformat = {0};
HRESULT hr;
WICRect rc;
double dpix, dpiy;
IWICComponentInfo *info;
IWICPixelFormatInfo2 *formatinfo;
WICPixelFormatNumericRepresentation format_type;
TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);
if (!piBitmapSource || !ppIBitmap)
return E_INVALIDARG;
hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);
if (SUCCEEDED(hr))
hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);
if (SUCCEEDED(hr))
hr = CreateComponentInfo(&pixelformat, &info);
if (SUCCEEDED(hr))
{
hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);
if (SUCCEEDED(hr))
{
hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);
IWICPixelFormatInfo2_Release(formatinfo);
}
IWICComponentInfo_Release(info);
}
if (SUCCEEDED(hr))
hr = BitmapImpl_Create(width, height, &pixelformat, option, &result);
if (SUCCEEDED(hr))
{
hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
if (SUCCEEDED(hr))
{
UINT stride, buffersize;
BYTE *buffer;
rc.X = rc.Y = 0;
rc.Width = width;
rc.Height = height;
hr = IWICBitmapLock_GetStride(lock, &stride);
if (SUCCEEDED(hr))
hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);
if (SUCCEEDED(hr))
hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
buffersize, buffer);
IWICBitmapLock_Release(lock);
}
if (SUCCEEDED(hr))
hr = PaletteImpl_Create(&palette);
if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
format_type == WICPixelFormatNumericRepresentationIndexed))
{
hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);
if (SUCCEEDED(hr))
hr = IWICBitmap_SetPalette(result, palette);
else
hr = S_OK;
IWICPalette_Release(palette);
}
if (SUCCEEDED(hr))
{
hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);
if (SUCCEEDED(hr))
hr = IWICBitmap_SetResolution(result, dpix, dpiy);
else
hr = S_OK;
}
if (SUCCEEDED(hr))
*ppIBitmap = result;
else
IWICBitmap_Release(result);
}
return hr;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *iface,
IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
IWICBitmap **ppIBitmap)
{
@ -318,7 +575,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFacto
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
{
@ -327,7 +584,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory *
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options,
IWICBitmap **ppIBitmap)
{
@ -335,37 +592,37 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface,
HICON hIcon, IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface,
DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
{
TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
}
static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder(
IWICImagingFactory *iface, IWICBitmapDecoder *pIDecoder,
static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromDecoder(
IWICComponentFactory *iface, IWICBitmapDecoder *pIDecoder,
IWICFastMetadataEncoder **ppIFastEncoder)
{
FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(
IWICImagingFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
IWICComponentFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
IWICFastMetadataEncoder **ppIFastEncoder)
{
FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *iface,
REFGUID guidMetadataFormat, const GUID *pguidVendor,
IWICMetadataQueryWriter **ppIQueryWriter)
{
@ -374,7 +631,7 @@ static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory *iface
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory *iface,
static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *iface,
IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
IWICMetadataQueryWriter **ppIQueryWriter)
{
@ -383,40 +640,98 @@ static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFact
return E_NOTIMPL;
}
static const IWICImagingFactoryVtbl ImagingFactory_Vtbl = {
ImagingFactory_QueryInterface,
ImagingFactory_AddRef,
ImagingFactory_Release,
ImagingFactory_CreateDecoderFromFilename,
ImagingFactory_CreateDecoderFromStream,
ImagingFactory_CreateDecoderFromFileHandle,
ImagingFactory_CreateComponentInfo,
ImagingFactory_CreateDecoder,
ImagingFactory_CreateEncoder,
ImagingFactory_CreatePalette,
ImagingFactory_CreateFormatConverter,
ImagingFactory_CreateBitmapScaler,
ImagingFactory_CreateBitmapClipper,
ImagingFactory_CreateBitmapFlipRotator,
ImagingFactory_CreateStream,
ImagingFactory_CreateColorContext,
ImagingFactory_CreateColorTransformer,
ImagingFactory_CreateBitmap,
ImagingFactory_CreateBitmapFromSource,
ImagingFactory_CreateBitmapFromSourceRect,
ImagingFactory_CreateBitmapFromMemory,
ImagingFactory_CreateBitmapFromHBITMAP,
ImagingFactory_CreateBitmapFromHICON,
ImagingFactory_CreateComponentEnumerator,
ImagingFactory_CreateFastMetadataEncoderFromDecoder,
ImagingFactory_CreateFastMetadataEncoderFromFrameDecode,
ImagingFactory_CreateQueryWriter,
ImagingFactory_CreateQueryWriterFromReader
static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
{
FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
options, stream, reader);
return E_NOTIMPL;
}
static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
{
FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
options, stream, reader);
return E_NOTIMPL;
}
static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer)
{
FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer);
return E_NOTIMPL;
}
static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface,
IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer)
{
FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer);
return E_NOTIMPL;
}
static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface,
IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader)
{
FIXME("%p,%p,%p: stub\n", iface, block_reader, query_reader);
return E_NOTIMPL;
}
static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface,
IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer)
{
FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer);
return E_NOTIMPL;
}
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;
}
static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = {
ComponentFactory_QueryInterface,
ComponentFactory_AddRef,
ComponentFactory_Release,
ComponentFactory_CreateDecoderFromFilename,
ComponentFactory_CreateDecoderFromStream,
ComponentFactory_CreateDecoderFromFileHandle,
ComponentFactory_CreateComponentInfo,
ComponentFactory_CreateDecoder,
ComponentFactory_CreateEncoder,
ComponentFactory_CreatePalette,
ComponentFactory_CreateFormatConverter,
ComponentFactory_CreateBitmapScaler,
ComponentFactory_CreateBitmapClipper,
ComponentFactory_CreateBitmapFlipRotator,
ComponentFactory_CreateStream,
ComponentFactory_CreateColorContext,
ComponentFactory_CreateColorTransformer,
ComponentFactory_CreateBitmap,
ComponentFactory_CreateBitmapFromSource,
ComponentFactory_CreateBitmapFromSourceRect,
ComponentFactory_CreateBitmapFromMemory,
ComponentFactory_CreateBitmapFromHBITMAP,
ComponentFactory_CreateBitmapFromHICON,
ComponentFactory_CreateComponentEnumerator,
ComponentFactory_CreateFastMetadataEncoderFromDecoder,
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode,
ComponentFactory_CreateQueryWriter,
ComponentFactory_CreateQueryWriterFromReader,
ComponentFactory_CreateMetadataReader,
ComponentFactory_CreateMetadataReaderFromContainer,
ComponentFactory_CreateMetadataWriter,
ComponentFactory_CreateMetadataWriterFromReader,
ComponentFactory_CreateQueryReaderFromBlockReader,
ComponentFactory_CreateQueryWriterFromBlockWriter,
ComponentFactory_CreateEncoderPropertyBag
};
HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
HRESULT ComponentFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
ImagingFactory *This;
ComponentFactory *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
@ -425,14 +740,14 @@ HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** pp
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ImagingFactory));
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory));
if (!This) return E_OUTOFMEMORY;
This->lpIWICImagingFactoryVtbl = &ImagingFactory_Vtbl;
This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl;
This->ref = 1;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICComponentFactory_QueryInterface(&This->IWICComponentFactory_iface, iid, ppv);
IWICComponentFactory_Release(&This->IWICComponentFactory_iface);
return ret;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
*/
#define COBJMACROS
#include "config.h"
#include <stdarg.h>
@ -32,13 +33,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
break;
@ -46,7 +47,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
break;
}
return TRUE;
return WIC_DllMain(hinstDLL, fdwReason, lpvReserved);
}
HRESULT WINAPI DllCanUnloadNow(void)
{
return S_FALSE;
}
HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
@ -55,18 +61,37 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
{
UINT bytesperrow;
UINT row_offset; /* number of bits into the source rows where the data starts */
WICRect rect;
if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
return E_INVALIDARG;
if (!rc)
{
rect.X = 0;
rect.Y = 0;
rect.Width = srcwidth;
rect.Height = srcheight;
rc = &rect;
}
else
{
if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
return E_INVALIDARG;
}
bytesperrow = ((bpp * rc->Width)+7)/8;
if (dststride < bytesperrow)
return E_INVALIDARG;
if ((dststride * rc->Height) > dstbuffersize)
if ((dststride * (rc->Height-1)) + ((rc->Width * bpp) + 7)/8 > dstbuffersize)
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)
{
memcpy(dstbuffer, srcbuffer, srcstride * srcheight);
return S_OK;
}
row_offset = rc->X * bpp;
if (row_offset % 8 == 0)
@ -93,3 +118,46 @@ HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
return E_FAIL;
}
}
void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride)
{
UINT x, y;
BYTE *pixel, temp;
for (y=0; y<height; y++)
{
pixel = bits + stride * y;
for (x=0; x<width; x++)
{
temp = pixel[2];
pixel[2] = pixel[0];
pixel[0] = temp;
pixel += bytesperpixel;
}
}
}
HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp)
{
HRESULT hr;
IWICComponentInfo *info;
IWICPixelFormatInfo *formatinfo;
hr = CreateComponentInfo(pixelformat, &info);
if (SUCCEEDED(hr))
{
hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void**)&formatinfo);
if (SUCCEEDED(hr))
{
hr = IWICPixelFormatInfo_GetBitsPerPixel(formatinfo, bpp);
IWICPixelFormatInfo_Release(formatinfo);
}
IWICComponentInfo_Release(info);
}
return hr;
}

File diff suppressed because it is too large Load diff

View file

@ -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
@ -35,7 +36,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
const IWICPaletteVtbl *lpIWICPaletteVtbl;
IWICPalette IWICPalette_iface;
LONG ref;
UINT count;
WICColor *colors;
@ -43,17 +44,22 @@ typedef struct {
CRITICAL_SECTION lock; /* must be held when count, colors, or type is accessed */
} PaletteImpl;
static inline PaletteImpl *impl_from_IWICPalette(IWICPalette *iface)
{
return CONTAINING_RECORD(iface, PaletteImpl, IWICPalette_iface);
}
static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid,
void **ppv)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICPalette, iid))
{
*ppv = This;
*ppv = &This->IWICPalette_iface;
}
else
{
@ -67,7 +73,7 @@ static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid,
static ULONG WINAPI PaletteImpl_AddRef(IWICPalette *iface)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -77,7 +83,7 @@ static ULONG WINAPI PaletteImpl_AddRef(IWICPalette *iface)
static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -93,17 +99,328 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface)
return ref;
}
static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface,
WICBitmapPaletteType ePaletteType, BOOL fAddTransparentColor)
static WICColor *generate_gray16_palette(UINT *count)
{
FIXME("(%p,%u,%i): stub\n", iface, ePaletteType, fAddTransparentColor);
return E_NOTIMPL;
WICColor *entries;
UINT i;
*count = 16;
entries = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 16; i++)
{
entries[i] = 0xff000000;
entries[i] |= (i<<20) | (i<<16) | (i<<12) | (i<<8) | (i<<4) | i;
}
return entries;
}
static WICColor *generate_gray256_palette(UINT *count)
{
WICColor *entries;
UINT i;
*count = 256;
entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 256; i++)
{
entries[i] = 0xff000000;
entries[i] |= (i<<16) | (i<<8) | i;
}
return entries;
}
static WICColor *generate_halftone8_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 17 : 16;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 8; i++)
{
entries[i] = 0xff000000;
if (i & 1) entries[i] |= 0xff;
if (i & 2) entries[i] |= 0xff00;
if (i & 4) entries[i] |= 0xff0000;
}
for (i = 8; i < 16; i++)
{
static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
0x000080, 0x808000, 0x800080, 0x008080 };
entries[i] = 0xff000000;
entries[i] |= halftone[i-8];
}
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone27_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 29 : 28;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 27; i++)
{
static const BYTE halftone_values[4] = { 0x00,0x80,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values[i%3];
entries[i] |= halftone_values[(i/3)%3] << 8;
entries[i] |= halftone_values[(i/9)%3] << 16;
}
entries[i++] = 0xffc0c0c0;
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone64_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 73 : 72;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 64; i++)
{
static const BYTE halftone_values[4] = { 0x00,0x55,0xaa,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values[i%4];
entries[i] |= halftone_values[(i/4)%4] << 8;
entries[i] |= halftone_values[(i/16)%4] << 16;
}
for (i = 64; i < 72; i++)
{
static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
0x000080, 0x808000, 0x800080, 0x008080 };
entries[i] = 0xff000000;
entries[i] |= halftone[i-64];
}
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone125_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 127 : 126;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 125; i++)
{
static const BYTE halftone_values[5] = { 0x00,0x40,0x80,0xbf,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values[i%5];
entries[i] |= halftone_values[(i/5)%5] << 8;
entries[i] |= halftone_values[(i/25)%5] << 16;
}
entries[i++] = 0xffc0c0c0;
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone216_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 225 : 224;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 216; i++)
{
static const BYTE halftone_values[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values[i%6];
entries[i] |= halftone_values[(i/6)%6] << 8;
entries[i] |= halftone_values[(i/36)%6] << 16;
}
for (i = 216; i < 224; i++)
{
static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
0x000080, 0x808000, 0x800080, 0x008080 };
entries[i] = 0xff000000;
entries[i] |= halftone[i-216];
}
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone252_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = add_transparent ? 253 : 252;
entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 252; i++)
{
static const BYTE halftone_values_rb[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff };
static const BYTE halftone_values_g[7] = { 0x00,0x2b,0x55,0x80,0xaa,0xd5,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values_rb[i%6];
entries[i] |= halftone_values_g[(i/6)%7] << 8;
entries[i] |= halftone_values_rb[(i/42)%6] << 16;
}
if (add_transparent)
entries[i] = 0;
return entries;
}
static WICColor *generate_halftone256_palette(UINT *count, BOOL add_transparent)
{
WICColor *entries;
UINT i;
*count = 256;
entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor));
if (!entries) return NULL;
for (i = 0; i < 256; i++)
{
static const BYTE halftone_values_b[4] = { 0x00,0x55,0xaa,0xff };
static const BYTE halftone_values_gr[8] = { 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff };
entries[i] = 0xff000000;
entries[i] |= halftone_values_b[i%4];
entries[i] |= halftone_values_gr[(i/4)%8] << 8;
entries[i] |= halftone_values_gr[(i/32)%8] << 16;
}
if (add_transparent)
entries[255] = 0;
return entries;
}
static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface,
WICBitmapPaletteType type, BOOL add_transparent)
{
PaletteImpl *This = impl_from_IWICPalette(iface);
WICColor *colors;
UINT count;
TRACE("(%p,%u,%d)\n", iface, type, add_transparent);
switch (type)
{
case WICBitmapPaletteTypeFixedBW:
count = 2;
colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor));
if (!colors) return E_OUTOFMEMORY;
colors[0] = 0xff000000;
colors[1] = 0xffffffff;
break;
case WICBitmapPaletteTypeFixedGray4:
count = 4;
colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor));
if (!colors) return E_OUTOFMEMORY;
colors[0] = 0xff000000;
colors[1] = 0xff555555;
colors[2] = 0xffaaaaaa;
colors[3] = 0xffffffff;
break;
case WICBitmapPaletteTypeFixedGray16:
colors = generate_gray16_palette(&count);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedGray256:
colors = generate_gray256_palette(&count);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone8:
colors = generate_halftone8_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone27:
colors = generate_halftone27_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone64:
colors = generate_halftone64_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone125:
colors = generate_halftone125_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone216:
colors = generate_halftone216_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone252:
colors = generate_halftone252_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
case WICBitmapPaletteTypeFixedHalftone256:
colors = generate_halftone256_palette(&count, add_transparent);
if (!colors) return E_OUTOFMEMORY;
break;
default:
WARN("invalid palette type %u\n", type);
return E_INVALIDARG;
}
EnterCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This->colors);
This->colors = colors;
This->count = count;
This->type = type;
LeaveCriticalSection(&This->lock);
return S_OK;
}
static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
WICColor *pColors, UINT colorCount)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
WICColor *new_colors;
TRACE("(%p,%p,%u)\n", iface, pColors, colorCount);
@ -138,16 +455,48 @@ static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *iface,
}
static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface,
IWICPalette *pIPalette)
IWICPalette *source)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return E_NOTIMPL;
PaletteImpl *This = impl_from_IWICPalette(iface);
UINT count;
WICColor *colors = NULL;
WICBitmapPaletteType type;
HRESULT hr;
TRACE("(%p,%p)\n", iface, source);
if (!source) return E_INVALIDARG;
hr = IWICPalette_GetType(source, &type);
if (hr != S_OK) return hr;
hr = IWICPalette_GetColorCount(source, &count);
if (hr != S_OK) return hr;
if (count)
{
colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count);
if (!colors) return E_OUTOFMEMORY;
hr = IWICPalette_GetColors(source, count, colors, &count);
if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, colors);
return hr;
}
}
EnterCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This->colors);
This->colors = colors;
This->count = count;
This->type = type;
LeaveCriticalSection(&This->lock);
return S_OK;
}
static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface,
WICBitmapPaletteType *pePaletteType)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%p)\n", iface, pePaletteType);
@ -162,7 +511,7 @@ static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface,
static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCount)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%p)\n", iface, pcCount);
@ -178,7 +527,7 @@ static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCoun
static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount,
WICColor *pColors, UINT *pcActualColors)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%i,%p,%p)\n", iface, colorCount, pColors, pcActualColors);
@ -199,7 +548,7 @@ static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount,
static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBlackWhite)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%p)\n", iface, pfIsBlackWhite);
@ -217,7 +566,7 @@ static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBla
static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGrayscale)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
TRACE("(%p,%p)\n", iface, pfIsGrayscale);
@ -242,7 +591,7 @@ static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGray
static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha)
{
PaletteImpl *This = (PaletteImpl*)iface;
PaletteImpl *This = impl_from_IWICPalette(iface);
int i;
TRACE("(%p,%p)\n", iface, pfHasAlpha);
@ -286,7 +635,7 @@ HRESULT PaletteImpl_Create(IWICPalette **palette)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PaletteImpl));
if (!This) return E_OUTOFMEMORY;
This->lpIWICPaletteVtbl = &PaletteImpl_Vtbl;
This->IWICPalette_iface.lpVtbl = &PaletteImpl_Vtbl;
This->ref = 1;
This->count = 0;
This->colors = NULL;
@ -294,7 +643,7 @@ HRESULT PaletteImpl_Create(IWICPalette **palette)
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock");
*palette = (IWICPalette*)This;
*palette = &This->IWICPalette_iface;
return S_OK;
}

View file

@ -25,12 +25,14 @@
#include <png.h>
#endif
#define NONAMELESSUNION
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "wincodecs_private.h"
@ -39,6 +41,118 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
{
BYTE header[8];
HRESULT hr;
ULONG bytesread;
hr = IStream_Read(stream, header, 8, &bytesread);
if (FAILED(hr) || bytesread < 8)
{
if (SUCCEEDED(hr))
hr = E_FAIL;
return hr;
}
*data_size = header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3];
memcpy(type, &header[4], 4);
if (data)
{
*data = HeapAlloc(GetProcessHeap(), 0, *data_size);
if (!*data)
return E_OUTOFMEMORY;
hr = IStream_Read(stream, *data, *data_size, &bytesread);
if (FAILED(hr) || bytesread < *data_size)
{
if (SUCCEEDED(hr))
hr = E_FAIL;
HeapFree(GetProcessHeap(), 0, *data);
*data = NULL;
return hr;
}
/* FIXME: Verify the CRC? */
}
return S_OK;
}
static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor,
DWORD persist_options, MetadataItem **items, DWORD *item_count)
{
HRESULT hr;
BYTE type[4];
BYTE *data;
ULONG data_size;
ULONG name_len, value_len;
BYTE *name_end_ptr;
LPSTR name, value;
MetadataItem *result;
hr = read_png_chunk(stream, type, &data, &data_size);
if (FAILED(hr)) return hr;
name_end_ptr = memchr(data, 0, data_size);
name_len = name_end_ptr - data;
if (!name_end_ptr || name_len > 79)
{
HeapFree(GetProcessHeap(), 0, data);
return E_FAIL;
}
value_len = data_size - name_len - 1;
result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem));
name = HeapAlloc(GetProcessHeap(), 0, name_len + 1);
value = HeapAlloc(GetProcessHeap(), 0, value_len + 1);
if (!result || !name || !value)
{
HeapFree(GetProcessHeap(), 0, data);
HeapFree(GetProcessHeap(), 0, result);
HeapFree(GetProcessHeap(), 0, name);
HeapFree(GetProcessHeap(), 0, value);
return E_OUTOFMEMORY;
}
PropVariantInit(&result[0].schema);
PropVariantInit(&result[0].id);
PropVariantInit(&result[0].value);
memcpy(name, data, name_len + 1);
memcpy(value, name_end_ptr + 1, value_len);
value[value_len] = 0;
result[0].id.vt = VT_LPSTR;
result[0].id.u.pszVal = name;
result[0].value.vt = VT_LPSTR;
result[0].value.u.pszVal = value;
*items = result;
*item_count = 1;
HeapFree(GetProcessHeap(), 0, data);
return S_OK;
}
static const MetadataHandlerVtbl TextReader_Vtbl = {
0,
&CLSID_WICPngTextMetadataReader,
LoadTextMetadata
};
HRESULT PngTextReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
return MetadataReader_Create(&TextReader_Vtbl, pUnkOuter, iid, ppv);
}
#ifdef SONAME_LIBPNG
static void *libpng_handle;
@ -52,6 +166,7 @@ MAKE_FUNCPTR(png_error);
MAKE_FUNCPTR(png_get_bit_depth);
MAKE_FUNCPTR(png_get_color_type);
MAKE_FUNCPTR(png_get_error_ptr);
MAKE_FUNCPTR(png_get_iCCP);
MAKE_FUNCPTR(png_get_image_height);
MAKE_FUNCPTR(png_get_image_width);
MAKE_FUNCPTR(png_get_io_ptr);
@ -99,6 +214,7 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_get_bit_depth);
LOAD_FUNCPTR(png_get_color_type);
LOAD_FUNCPTR(png_get_error_ptr);
LOAD_FUNCPTR(png_get_iCCP);
LOAD_FUNCPTR(png_get_image_height);
LOAD_FUNCPTR(png_get_image_width);
LOAD_FUNCPTR(png_get_io_ptr);
@ -150,8 +266,9 @@ static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message
}
typedef struct {
const IWICBitmapDecoderVtbl *lpVtbl;
const IWICBitmapFrameDecodeVtbl *lpFrameVtbl;
IWICBitmapDecoder IWICBitmapDecoder_iface;
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
IWICMetadataBlockReader IWICMetadataBlockReader_iface;
LONG ref;
png_structp png_ptr;
png_infop info_ptr;
@ -165,9 +282,19 @@ typedef struct {
CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */
} PngDecoder;
static inline PngDecoder *impl_from_frame(IWICBitmapFrameDecode *iface)
static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
return CONTAINING_RECORD(iface, PngDecoder, lpFrameVtbl);
return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapDecoder_iface);
}
static inline PngDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
{
return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapFrameDecode_iface);
}
static inline PngDecoder *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface)
{
return CONTAINING_RECORD(iface, PngDecoder, IWICMetadataBlockReader_iface);
}
static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl;
@ -175,14 +302,14 @@ static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl;
static HRESULT WINAPI PngDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
PngDecoder *This = (PngDecoder*)iface;
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapDecoder_iface;
}
else
{
@ -196,7 +323,7 @@ static HRESULT WINAPI PngDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID
static ULONG WINAPI PngDecoder_AddRef(IWICBitmapDecoder *iface)
{
PngDecoder *This = (PngDecoder*)iface;
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -206,7 +333,7 @@ static ULONG WINAPI PngDecoder_AddRef(IWICBitmapDecoder *iface)
static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
{
PngDecoder *This = (PngDecoder*)iface;
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -224,11 +351,22 @@ static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface)
return ref;
}
static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
DWORD *pdwCapability)
static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
DWORD *capability)
{
FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
return E_NOTIMPL;
HRESULT hr;
TRACE("(%p,%p,%p)\n", iface, stream, capability);
if (!stream || !capability) return E_INVALIDARG;
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
if (hr != S_OK) return hr;
*capability = WICBitmapDecoderCapabilityCanDecodeAllImages |
WICBitmapDecoderCapabilityCanDecodeSomeImages;
/* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */
return S_OK;
}
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
@ -247,7 +385,7 @@ static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t lengt
static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
PngDecoder *This = (PngDecoder*)iface;
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
LARGE_INTEGER seek;
HRESULT hr=S_OK;
png_bytep *row_pointers=NULL;
@ -299,7 +437,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
hr = E_FAIL;
goto end;
}
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
/* seek to the start of the stream */
seek.QuadPart = 0;
@ -359,6 +497,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
case PNG_COLOR_TYPE_GRAY_ALPHA:
/* WIC does not support grayscale alpha formats so use RGBA */
ppng_set_gray_to_rgb(This->png_ptr);
/* fall through */
case PNG_COLOR_TYPE_RGB_ALPHA:
This->bpp = bit_depth * 4;
switch (bit_depth)
@ -458,8 +597,20 @@ static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo);
return E_NOTIMPL;
HRESULT hr;
IWICComponentInfo *compinfo;
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
hr = CreateComponentInfo(&CLSID_WICPngDecoder, &compinfo);
if (FAILED(hr)) return hr;
hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
(void**)ppIDecoderInfo);
IWICComponentInfo_Release(compinfo);
return hr;
}
static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
@ -486,8 +637,8 @@ static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface,
static HRESULT WINAPI PngDecoder_GetColorContexts(IWICBitmapDecoder *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return E_NOTIMPL;
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface,
@ -500,6 +651,8 @@ static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface,
static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
if (!pCount) return E_INVALIDARG;
*pCount = 1;
return S_OK;
}
@ -507,16 +660,16 @@ static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface,
static HRESULT WINAPI PngDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
PngDecoder *This = (PngDecoder*)iface;
PngDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING;
if (index != 0) return E_INVALIDARG;
IWICBitmapDecoder_AddRef(iface);
*ppIBitmapFrame = (void*)(&This->lpFrameVtbl);
*ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;
return S_OK;
}
@ -541,13 +694,18 @@ static const IWICBitmapDecoderVtbl PngDecoder_Vtbl = {
static HRESULT WINAPI PngDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
void **ppv)
{
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = iface;
*ppv = &This->IWICBitmapFrameDecode_iface;
}
else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid))
{
*ppv = &This->IWICMetadataBlockReader_iface;
}
else
{
@ -561,20 +719,20 @@ static HRESULT WINAPI PngDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *ifa
static ULONG WINAPI PngDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface)
{
PngDecoder *This = impl_from_frame(iface);
return IUnknown_AddRef((IUnknown*)This);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
}
static ULONG WINAPI PngDecoder_Frame_Release(IWICBitmapFrameDecode *iface)
{
PngDecoder *This = impl_from_frame(iface);
return IUnknown_Release((IUnknown*)This);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
}
static HRESULT WINAPI PngDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
PngDecoder *This = impl_from_frame(iface);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
*puiWidth = This->width;
*puiHeight = This->height;
TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight);
@ -584,7 +742,7 @@ static HRESULT WINAPI PngDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface,
static HRESULT WINAPI PngDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface,
WICPixelFormatGUID *pPixelFormat)
{
PngDecoder *This = impl_from_frame(iface);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
memcpy(pPixelFormat, This->format, sizeof(GUID));
@ -595,7 +753,7 @@ static HRESULT WINAPI PngDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *ifa
static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
PngDecoder *This = impl_from_frame(iface);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
png_uint_32 ret, xres, yres;
int unit_type;
@ -624,7 +782,7 @@ static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *ifac
static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
PngDecoder *This = impl_from_frame(iface);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
png_uint_32 ret;
png_colorp png_palette;
int num_palette;
@ -683,7 +841,7 @@ end:
static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
PngDecoder *This = impl_from_frame(iface);
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
return copy_pixels(This->bpp, This->image_bits,
@ -701,8 +859,37 @@ static HRESULT WINAPI PngDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDec
static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
return E_NOTIMPL;
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
png_charp name, profile;
png_uint_32 len;
int compression_type;
HRESULT hr;
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
if (!pcActualCount) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
if (ppng_get_iCCP(This->png_ptr, This->info_ptr, &name, &compression_type, &profile, &len))
{
if (cCount && ppIColorContexts)
{
hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, (const BYTE *)profile, len);
if (FAILED(hr))
{
LeaveCriticalSection(&This->lock);
return hr;
}
}
*pcActualCount = 1;
}
else
*pcActualCount = 0;
LeaveCriticalSection(&This->lock);
return S_OK;
}
static HRESULT WINAPI PngDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface,
@ -726,6 +913,64 @@ static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl = {
PngDecoder_Frame_GetThumbnail
};
static HRESULT WINAPI PngDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid,
void **ppv)
{
PngDecoder *This = impl_from_IWICMetadataBlockReader(iface);
return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv);
}
static ULONG WINAPI PngDecoder_Block_AddRef(IWICMetadataBlockReader *iface)
{
PngDecoder *This = impl_from_IWICMetadataBlockReader(iface);
return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
}
static ULONG WINAPI PngDecoder_Block_Release(IWICMetadataBlockReader *iface)
{
PngDecoder *This = impl_from_IWICMetadataBlockReader(iface);
return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
}
static HRESULT WINAPI PngDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface,
GUID *pguidContainerFormat)
{
if (!pguidContainerFormat) return E_INVALIDARG;
memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI PngDecoder_Block_GetCount(IWICMetadataBlockReader *iface,
UINT *pcCount)
{
FIXME("%p,%p: stub\n", iface, pcCount);
return E_NOTIMPL;
}
static HRESULT WINAPI PngDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface,
UINT nIndex, IWICMetadataReader **ppIMetadataReader)
{
FIXME("%p,%d,%p\n", iface, nIndex, ppIMetadataReader);
return E_NOTIMPL;
}
static HRESULT WINAPI PngDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface,
IEnumUnknown **ppIEnumMetadata)
{
FIXME("%p,%p\n", iface, ppIEnumMetadata);
return E_NOTIMPL;
}
static const IWICMetadataBlockReaderVtbl PngDecoder_BlockVtbl = {
PngDecoder_Block_QueryInterface,
PngDecoder_Block_AddRef,
PngDecoder_Block_Release,
PngDecoder_Block_GetContainerFormat,
PngDecoder_Block_GetCount,
PngDecoder_Block_GetReaderByIndex,
PngDecoder_Block_GetEnumerator,
};
HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
PngDecoder *This;
@ -746,8 +991,9 @@ HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngDecoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &PngDecoder_Vtbl;
This->lpFrameVtbl = &PngDecoder_FrameVtbl;
This->IWICBitmapDecoder_iface.lpVtbl = &PngDecoder_Vtbl;
This->IWICBitmapFrameDecode_iface.lpVtbl = &PngDecoder_FrameVtbl;
This->IWICMetadataBlockReader_iface.lpVtbl = &PngDecoder_BlockVtbl;
This->ref = 1;
This->png_ptr = NULL;
This->info_ptr = NULL;
@ -757,8 +1003,8 @@ HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
return ret;
}
@ -787,8 +1033,8 @@ static const struct png_pixelformat formats[] = {
};
typedef struct PngEncoder {
const IWICBitmapEncoderVtbl *lpVtbl;
const IWICBitmapFrameEncodeVtbl *lpFrameVtbl;
IWICBitmapEncoder IWICBitmapEncoder_iface;
IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
LONG ref;
IStream *stream;
png_structp png_ptr;
@ -805,15 +1051,20 @@ typedef struct PngEncoder {
CRITICAL_SECTION lock;
} PngEncoder;
static inline PngEncoder *encoder_from_frame(IWICBitmapFrameEncode *iface)
static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
{
return CONTAINING_RECORD(iface, PngEncoder, lpFrameVtbl);
return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapEncoder_iface);
}
static inline PngEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
{
return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapFrameEncode_iface);
}
static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
void **ppv)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -821,7 +1072,7 @@ static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
{
*ppv = &This->lpFrameVtbl;
*ppv = &This->IWICBitmapFrameEncode_iface;
}
else
{
@ -835,20 +1086,20 @@ static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface
static ULONG WINAPI PngFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
{
PngEncoder *This = encoder_from_frame(iface);
return IUnknown_AddRef((IUnknown*)This);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface);
}
static ULONG WINAPI PngFrameEncode_Release(IWICBitmapFrameEncode *iface)
{
PngEncoder *This = encoder_from_frame(iface);
return IUnknown_Release((IUnknown*)This);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
}
static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
IPropertyBag2 *pIEncoderOptions)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%p)\n", iface, pIEncoderOptions);
EnterCriticalSection(&This->lock);
@ -869,7 +1120,7 @@ static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
UINT uiWidth, UINT uiHeight)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
EnterCriticalSection(&This->lock);
@ -891,7 +1142,7 @@ static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
double dpiX, double dpiY)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
EnterCriticalSection(&This->lock);
@ -913,7 +1164,7 @@ static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
WICPixelFormatGUID *pPixelFormat)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
int i;
TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
@ -965,7 +1216,7 @@ static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
png_byte **row_pointers=NULL;
UINT i;
jmp_buf jmpbuf;
@ -992,7 +1243,7 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
HeapFree(GetProcessHeap(), 0, row_pointers);
return E_FAIL;
}
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
if (!This->info_written)
{
@ -1040,7 +1291,7 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
HRESULT hr;
WICRect rc;
WICPixelFormatGUID guid;
@ -1112,7 +1363,7 @@ static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
{
PngEncoder *This = encoder_from_frame(iface);
PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface);
jmp_buf jmpbuf;
TRACE("(%p)\n", iface);
@ -1130,7 +1381,7 @@ static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface)
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
ppng_write_end(This->png_ptr, This->info_ptr);
@ -1168,7 +1419,7 @@ static const IWICBitmapFrameEncodeVtbl PngEncoder_FrameVtbl = {
static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -1176,7 +1427,7 @@ static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapEncoder, iid))
{
*ppv = This;
*ppv = &This->IWICBitmapEncoder_iface;
}
else
{
@ -1190,7 +1441,7 @@ static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID
static ULONG WINAPI PngEncoder_AddRef(IWICBitmapEncoder *iface)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -1200,7 +1451,7 @@ static ULONG WINAPI PngEncoder_AddRef(IWICBitmapEncoder *iface)
static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -1239,7 +1490,7 @@ static void user_flush(png_structp png_ptr)
static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
jmp_buf jmpbuf;
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
@ -1282,7 +1533,7 @@ static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface,
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
ppng_set_error_fn(This->png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
/* set up custom i/o handling */
ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
@ -1334,7 +1585,7 @@ static HRESULT WINAPI PngEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmap
static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
HRESULT hr;
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
@ -1364,14 +1615,14 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
LeaveCriticalSection(&This->lock);
IWICBitmapEncoder_AddRef(iface);
*ppIFrameEncode = (IWICBitmapFrameEncode*)&This->lpFrameVtbl;
*ppIFrameEncode = &This->IWICBitmapFrameEncode_iface;
return S_OK;
}
static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface)
{
PngEncoder *This = (PngEncoder*)iface;
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
TRACE("(%p)\n", iface);
EnterCriticalSection(&This->lock);
@ -1432,8 +1683,8 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngEncoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &PngEncoder_Vtbl;
This->lpFrameVtbl = &PngEncoder_FrameVtbl;
This->IWICBitmapEncoder_iface.lpVtbl = &PngEncoder_Vtbl;
This->IWICBitmapFrameEncode_iface.lpVtbl = &PngEncoder_FrameVtbl;
This->ref = 1;
This->png_ptr = NULL;
This->info_ptr = NULL;
@ -1452,8 +1703,8 @@ HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
return ret;
}

View file

@ -34,14 +34,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct PropertyBag {
const IPropertyBag2Vtbl *lpVtbl;
IPropertyBag2 IPropertyBag2_iface;
LONG ref;
} PropertyBag;
static inline PropertyBag *impl_from_IPropertyBag2(IPropertyBag2 *iface)
{
return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag2_iface);
}
static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid,
void **ppv)
{
PropertyBag *This = (PropertyBag*)iface;
PropertyBag *This = impl_from_IPropertyBag2(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -49,7 +54,7 @@ static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID ii
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IPropertyBag2, iid))
{
*ppv = This;
*ppv = &This->IPropertyBag2_iface;
}
else
{
@ -63,7 +68,7 @@ static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID ii
static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
{
PropertyBag *This = (PropertyBag*)iface;
PropertyBag *This = impl_from_IPropertyBag2(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -73,7 +78,7 @@ static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
{
PropertyBag *This = (PropertyBag*)iface;
PropertyBag *This = impl_from_IPropertyBag2(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -131,17 +136,17 @@ static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
PropertyBag_LoadObject
};
extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2)
HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2)
{
PropertyBag *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &PropertyBag_Vtbl;
This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl;
This->ref = 1;
*ppPropertyBag2 = (IPropertyBag2*)This;
*ppPropertyBag2 = &This->IPropertyBag2_iface;
return S_OK;
}

View file

@ -0,0 +1,635 @@
/*
* Misleadingly named convenience functions for accessing WIC.
*
* Copyright 2012 Vincent Povirk 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
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
HRESULT WINAPI IWICBitmapClipper_Initialize_Proxy_W(IWICBitmapClipper *iface,
IWICBitmapSource *pISource, const WICRect *prc)
{
return IWICBitmapClipper_Initialize(iface, pISource, prc);
}
HRESULT WINAPI IWICBitmapCodecInfo_GetContainerFormat_Proxy_W(IWICBitmapCodecInfo *iface,
GUID *pguidContainerFormat)
{
return IWICBitmapCodecInfo_GetContainerFormat(iface, pguidContainerFormat);
}
HRESULT WINAPI IWICBitmapCodecInfo_GetDeviceManufacturer_Proxy_W(IWICBitmapCodecInfo *iface,
UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
{
return IWICBitmapCodecInfo_GetDeviceManufacturer(iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
}
HRESULT WINAPI IWICBitmapCodecInfo_GetDeviceModels_Proxy_W(IWICBitmapCodecInfo *iface,
UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
{
return IWICBitmapCodecInfo_GetDeviceModels(iface, cchDeviceModels, wzDeviceModels, pcchActual);
}
HRESULT WINAPI IWICBitmapCodecInfo_GetMimeTypes_Proxy_W(IWICBitmapCodecInfo *iface,
UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
{
return IWICBitmapCodecInfo_GetMimeTypes(iface, cchMimeTypes, wzMimeTypes, pcchActual);
}
HRESULT WINAPI IWICBitmapCodecInfo_GetFileExtensions_Proxy_W(IWICBitmapCodecInfo *iface,
UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
{
return IWICBitmapCodecInfo_GetFileExtensions(iface, cchFileExtensions, wzFileExtensions, pcchActual);
}
HRESULT WINAPI IWICBitmapCodecInfo_DoesSupportAnimation_Proxy_W(IWICBitmapCodecInfo *iface,
BOOL *pfSupportAnimation)
{
return IWICBitmapCodecInfo_DoesSupportAnimation(iface, pfSupportAnimation);
}
HRESULT WINAPI IWICBitmapCodecInfo_DoesSupportLossless_Proxy_W(IWICBitmapCodecInfo *iface,
BOOL *pfSupportLossless)
{
return IWICBitmapCodecInfo_DoesSupportLossless(iface, pfSupportLossless);
}
HRESULT WINAPI IWICBitmapCodecInfo_DoesSupportMultiframe_Proxy_W(IWICBitmapCodecInfo *iface,
BOOL *pfSupportMultiframe)
{
return IWICBitmapCodecInfo_DoesSupportMultiframe(iface, pfSupportMultiframe);
}
HRESULT WINAPI IWICBitmapDecoder_GetDecoderInfo_Proxy_W(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
return IWICBitmapDecoder_GetDecoderInfo(iface, ppIDecoderInfo);
}
HRESULT WINAPI IWICBitmapDecoder_CopyPalette_Proxy_W(IWICBitmapDecoder *iface,
IWICPalette *pIPalette)
{
return IWICBitmapDecoder_CopyPalette(iface, pIPalette);
}
HRESULT WINAPI IWICBitmapDecoder_GetMetadataQueryReader_Proxy_W(IWICBitmapDecoder *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
return IWICBitmapDecoder_GetMetadataQueryReader(iface, ppIMetadataQueryReader);
}
HRESULT WINAPI IWICBitmapDecoder_GetPreview_Proxy_W(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIBitmapSource)
{
return IWICBitmapDecoder_GetPreview(iface, ppIBitmapSource);
}
HRESULT WINAPI IWICBitmapDecoder_GetColorContexts_Proxy_W(IWICBitmapDecoder *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
return IWICBitmapDecoder_GetColorContexts(iface, cCount, ppIColorContexts, pcActualCount);
}
HRESULT WINAPI IWICBitmapDecoder_GetThumbnail_Proxy_W(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIThumbnail)
{
return IWICBitmapDecoder_GetThumbnail(iface, ppIThumbnail);
}
HRESULT WINAPI IWICBitmapDecoder_GetFrameCount_Proxy_W(IWICBitmapDecoder *iface,
UINT *pCount)
{
return IWICBitmapDecoder_GetFrameCount(iface, pCount);
}
HRESULT WINAPI IWICBitmapDecoder_GetFrame_Proxy_W(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
return IWICBitmapDecoder_GetFrame(iface, index, ppIBitmapFrame);
}
HRESULT WINAPI IWICBitmapEncoder_Initialize_Proxy_W(IWICBitmapEncoder *iface,
IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
return IWICBitmapEncoder_Initialize(iface, pIStream, cacheOption);
}
HRESULT WINAPI IWICBitmapEncoder_GetEncoderInfo_Proxy_W(IWICBitmapEncoder *iface,
IWICBitmapEncoderInfo **ppIEncoderInfo)
{
return IWICBitmapEncoder_GetEncoderInfo(iface, ppIEncoderInfo);
}
HRESULT WINAPI IWICBitmapEncoder_SetPalette_Proxy_W(IWICBitmapEncoder *iface,
IWICPalette *pIPalette)
{
return IWICBitmapEncoder_SetPalette(iface, pIPalette);
}
HRESULT WINAPI IWICBitmapEncoder_SetThumbnail_Proxy_W(IWICBitmapEncoder *iface,
IWICBitmapSource *pIThumbnail)
{
return IWICBitmapEncoder_SetThumbnail(iface, pIThumbnail);
}
HRESULT WINAPI IWICBitmapEncoder_CreateNewFrame_Proxy_W(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
return IWICBitmapEncoder_CreateNewFrame(iface, ppIFrameEncode, ppIEncoderOptions);
}
HRESULT WINAPI IWICBitmapEncoder_Commit_Proxy_W(IWICBitmapEncoder *iface)
{
return IWICBitmapEncoder_Commit(iface);
}
HRESULT WINAPI IWICBitmapEncoder_GetMetadataQueryWriter_Proxy_W(IWICBitmapEncoder *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
return IWICBitmapEncoder_GetMetadataQueryWriter(iface, ppIMetadataQueryWriter);
}
HRESULT WINAPI IWICBitmapFlipRotator_Initialize_Proxy_W(IWICBitmapFlipRotator *iface,
IWICBitmapSource *pISource, WICBitmapTransformOptions options)
{
return IWICBitmapFlipRotator_Initialize(iface, pISource, options);
}
HRESULT WINAPI IWICBitmapFrameEncode_Initialize_Proxy_W(IWICBitmapFrameEncode *iface,
IPropertyBag2 *pIEncoderOptions)
{
return IWICBitmapFrameEncode_Initialize(iface, pIEncoderOptions);
}
HRESULT WINAPI IWICBitmapFrameEncode_SetSize_Proxy_W(IWICBitmapFrameEncode *iface,
UINT uiWidth, UINT uiHeight)
{
return IWICBitmapFrameEncode_SetSize(iface, uiWidth, uiHeight);
}
HRESULT WINAPI IWICBitmapFrameEncode_SetResolution_Proxy_W(IWICBitmapFrameEncode *iface,
double dpiX, double dpiY)
{
return IWICBitmapFrameEncode_SetResolution(iface, dpiX, dpiY);
}
HRESULT WINAPI IWICBitmapFrameEncode_SetColorContexts_Proxy_W(IWICBitmapFrameEncode *iface,
UINT cCount, IWICColorContext **ppIColorContext)
{
return IWICBitmapFrameEncode_SetColorContexts(iface, cCount, ppIColorContext);
}
HRESULT WINAPI IWICBitmapFrameEncode_SetThumbnail_Proxy_W(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIThumbnail)
{
return IWICBitmapFrameEncode_SetThumbnail(iface, pIThumbnail);
}
HRESULT WINAPI IWICBitmapFrameEncode_WriteSource_Proxy_W(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
return IWICBitmapFrameEncode_WriteSource(iface, pIBitmapSource, prc);
}
HRESULT WINAPI IWICBitmapFrameEncode_Commit_Proxy_W(IWICBitmapFrameEncode *iface)
{
return IWICBitmapFrameEncode_Commit(iface);
}
HRESULT WINAPI IWICBitmapFrameEncode_GetMetadataQueryWriter_Proxy_W(IWICBitmapFrameEncode *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
return IWICBitmapFrameEncode_GetMetadataQueryWriter(iface, ppIMetadataQueryWriter);
}
HRESULT WINAPI IWICBitmapLock_GetDataPointer_Proxy_W(IWICBitmapLock *iface,
UINT *pcbBufferSize, BYTE **ppbData)
{
return IWICBitmapLock_GetDataPointer(iface, pcbBufferSize, ppbData);
}
HRESULT WINAPI IWICBitmapLock_GetStride_Proxy_W(IWICBitmapLock *iface,
UINT *pcbStride)
{
return IWICBitmapLock_GetStride(iface, pcbStride);
}
HRESULT WINAPI IWICBitmapScaler_Initialize_Proxy_W(IWICBitmapScaler *iface,
IWICBitmapSource *pISource, UINT uiWidth, UINT uiHeight, WICBitmapInterpolationMode mode)
{
return IWICBitmapScaler_Initialize(iface, pISource, uiWidth, uiHeight, mode);
}
HRESULT WINAPI IWICBitmapSource_GetSize_Proxy_W(IWICBitmapSource *iface,
UINT *puiWidth, UINT *puiHeight)
{
return IWICBitmapSource_GetSize(iface, puiWidth, puiHeight);
}
HRESULT WINAPI IWICBitmapSource_GetPixelFormat_Proxy_W(IWICBitmapSource *iface,
WICPixelFormatGUID *pPixelFormat)
{
return IWICBitmapSource_GetPixelFormat(iface, pPixelFormat);
}
HRESULT WINAPI IWICBitmapSource_GetResolution_Proxy_W(IWICBitmapSource *iface,
double *pDpiX, double *pDpiY)
{
return IWICBitmapSource_GetResolution(iface, pDpiX, pDpiY);
}
HRESULT WINAPI IWICBitmapSource_CopyPalette_Proxy_W(IWICBitmapSource *iface,
IWICPalette *pIPalette)
{
return IWICBitmapSource_CopyPalette(iface, pIPalette);
}
HRESULT WINAPI IWICBitmapSource_CopyPixels_Proxy_W(IWICBitmapSource *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
return IWICBitmapSource_CopyPixels(iface, prc, cbStride, cbBufferSize, pbBuffer);
}
HRESULT WINAPI IWICBitmap_Lock_Proxy_W(IWICBitmap *iface,
const WICRect *prcLock, DWORD flags, IWICBitmapLock **ppILock)
{
return IWICBitmap_Lock(iface, prcLock, flags, ppILock);
}
HRESULT WINAPI IWICBitmap_SetPalette_Proxy_W(IWICBitmap *iface,
IWICPalette *pIPalette)
{
return IWICBitmap_SetPalette(iface, pIPalette);
}
HRESULT WINAPI IWICBitmap_SetResolution_Proxy_W(IWICBitmap *iface,
double dpiX, double dpiY)
{
return IWICBitmap_SetResolution(iface, dpiX, dpiY);
}
HRESULT WINAPI IWICColorContext_InitializeFromMemory_Proxy_W(IWICColorContext *iface,
const BYTE *pbBuffer, UINT cbBufferSize)
{
return IWICColorContext_InitializeFromMemory(iface, pbBuffer, cbBufferSize);
}
HRESULT WINAPI IWICComponentFactory_CreateMetadataWriterFromReader_Proxy_W(IWICComponentFactory *iface,
IWICMetadataReader *pIReader, const GUID *pguidVendor, IWICMetadataWriter **ppIWriter)
{
return IWICComponentFactory_CreateMetadataWriterFromReader(iface, pIReader, pguidVendor, ppIWriter);
}
HRESULT WINAPI IWICComponentFactory_CreateQueryWriterFromBlockWriter_Proxy_W(IWICComponentFactory *iface,
IWICMetadataBlockWriter *pIBlockWriter, IWICMetadataQueryWriter **ppIQueryWriter)
{
return IWICComponentFactory_CreateQueryWriterFromBlockWriter(iface, pIBlockWriter, ppIQueryWriter);
}
HRESULT WINAPI IWICComponentInfo_GetCLSID_Proxy_W(IWICComponentInfo *iface,
CLSID *pclsid)
{
return IWICComponentInfo_GetCLSID(iface, pclsid);
}
HRESULT WINAPI IWICComponentInfo_GetAuthor_Proxy_W(IWICComponentInfo *iface,
UINT cchAuthor, WCHAR *wzAuthor, UINT *pcchActual)
{
return IWICComponentInfo_GetAuthor(iface, cchAuthor, wzAuthor, pcchActual);
}
HRESULT WINAPI IWICComponentInfo_GetVersion_Proxy_W(IWICComponentInfo *iface,
UINT cchVersion, WCHAR *wzVersion, UINT *pcchActual)
{
return IWICComponentInfo_GetVersion(iface, cchVersion, wzVersion, pcchActual);
}
HRESULT WINAPI IWICComponentInfo_GetSpecVersion_Proxy_W(IWICComponentInfo *iface,
UINT cchSpecVersion, WCHAR *wzSpecVersion, UINT *pcchActual)
{
return IWICComponentInfo_GetSpecVersion(iface, cchSpecVersion, wzSpecVersion, pcchActual);
}
HRESULT WINAPI IWICComponentInfo_GetFriendlyName_Proxy_W(IWICComponentInfo *iface,
UINT cchFriendlyName, WCHAR *wzFriendlyName, UINT *pcchActual)
{
return IWICComponentInfo_GetFriendlyName(iface, cchFriendlyName, wzFriendlyName, pcchActual);
}
HRESULT WINAPI IWICFastMetadataEncoder_Commit_Proxy_W(IWICFastMetadataEncoder *iface)
{
return IWICFastMetadataEncoder_Commit(iface);
}
HRESULT WINAPI IWICFastMetadataEncoder_GetMetadataQueryWriter_Proxy_W(IWICFastMetadataEncoder *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
return IWICFastMetadataEncoder_GetMetadataQueryWriter(iface, ppIMetadataQueryWriter);
}
HRESULT WINAPI IWICBitmapFrameDecode_GetMetadataQueryReader_Proxy_W(IWICBitmapFrameDecode *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
return IWICBitmapFrameDecode_GetMetadataQueryReader(iface, ppIMetadataQueryReader);
}
HRESULT WINAPI IWICBitmapFrameDecode_GetColorContexts_Proxy_W(IWICBitmapFrameDecode *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
return IWICBitmapFrameDecode_GetColorContexts(iface, cCount, ppIColorContexts, pcActualCount);
}
HRESULT WINAPI IWICBitmapFrameDecode_GetThumbnail_Proxy_W(IWICBitmapFrameDecode *iface,
IWICBitmapSource **ppIThumbnail)
{
return IWICBitmapFrameDecode_GetThumbnail(iface, ppIThumbnail);
}
HRESULT WINAPI IWICFormatConverter_Initialize_Proxy_W(IWICFormatConverter *iface,
IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
{
return IWICFormatConverter_Initialize(iface, pISource, dstFormat, dither,
pIPalette, alphaThresholdPercent, paletteTranslate);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapClipper_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapClipper **ppIBitmapClipper)
{
return IWICImagingFactory_CreateBitmapClipper(pFactory, ppIBitmapClipper);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapFlipRotator_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapFlipRotator **ppIBitmapFlipRotator)
{
return IWICImagingFactory_CreateBitmapFlipRotator(pFactory, ppIBitmapFlipRotator);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapFromHBITMAP_Proxy_W(IWICImagingFactory *pFactory,
HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options, IWICBitmap **ppIBitmap)
{
return IWICImagingFactory_CreateBitmapFromHBITMAP(pFactory, hBitmap, hPalette, options, ppIBitmap);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapFromHICON_Proxy_W(IWICImagingFactory *pFactory,
HICON hIcon, IWICBitmap **ppIBitmap)
{
return IWICImagingFactory_CreateBitmapFromHICON(pFactory, hIcon, ppIBitmap);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapFromMemory_Proxy_W(IWICImagingFactory *pFactory,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
{
return IWICImagingFactory_CreateBitmapFromMemory(pFactory, uiWidth, uiHeight,
pixelFormat, cbStride, cbBufferSize, pbBuffer, ppIBitmap);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapFromSource_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
return IWICImagingFactory_CreateBitmapFromSource(pFactory, piBitmapSource, option, ppIBitmap);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmapScaler_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapScaler **ppIBitmapScaler)
{
return IWICImagingFactory_CreateBitmapScaler(pFactory, ppIBitmapScaler);
}
HRESULT WINAPI IWICImagingFactory_CreateBitmap_Proxy_W(IWICImagingFactory *pFactory,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
return IWICImagingFactory_CreateBitmap(pFactory, uiWidth, uiHeight,
pixelFormat, option, ppIBitmap);
}
HRESULT WINAPI IWICImagingFactory_CreateComponentInfo_Proxy_W(IWICImagingFactory *pFactory,
REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
{
return IWICImagingFactory_CreateComponentInfo(pFactory, clsidComponent, ppIInfo);
}
HRESULT WINAPI IWICImagingFactory_CreateDecoderFromFileHandle_Proxy_W(IWICImagingFactory *pFactory,
ULONG_PTR hFile, const GUID *pguidVendor, WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
return IWICImagingFactory_CreateDecoderFromFileHandle(pFactory, hFile, pguidVendor, metadataOptions, ppIDecoder);
}
HRESULT WINAPI IWICImagingFactory_CreateDecoderFromFilename_Proxy_W(IWICImagingFactory *pFactory,
LPCWSTR wzFilename, const GUID *pguidVendor, DWORD dwDesiredAccess,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
return IWICImagingFactory_CreateDecoderFromFilename(pFactory, wzFilename,
pguidVendor, dwDesiredAccess, metadataOptions, ppIDecoder);
}
HRESULT WINAPI IWICImagingFactory_CreateDecoderFromStream_Proxy_W(IWICImagingFactory *pFactory,
IStream *pIStream, const GUID *pguidVendor,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
return IWICImagingFactory_CreateDecoderFromStream(pFactory, pIStream, pguidVendor, metadataOptions, ppIDecoder);
}
HRESULT WINAPI IWICImagingFactory_CreateEncoder_Proxy_W(IWICImagingFactory *pFactory,
REFGUID guidContainerFormat, const GUID *pguidVendor, IWICBitmapEncoder **ppIEncoder)
{
return IWICImagingFactory_CreateEncoder(pFactory, guidContainerFormat, pguidVendor, ppIEncoder);
}
HRESULT WINAPI IWICImagingFactory_CreateFastMetadataEncoderFromDecoder_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapDecoder *pIDecoder, IWICFastMetadataEncoder **ppIFastEncoder)
{
return IWICImagingFactory_CreateFastMetadataEncoderFromDecoder(pFactory, pIDecoder, ppIFastEncoder);
}
HRESULT WINAPI IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode_Proxy_W(IWICImagingFactory *pFactory,
IWICBitmapFrameDecode *pIFrameDecoder, IWICFastMetadataEncoder **ppIFastEncoder)
{
return IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode(pFactory, pIFrameDecoder, ppIFastEncoder);
}
HRESULT WINAPI IWICImagingFactory_CreateFormatConverter_Proxy_W(IWICImagingFactory *pFactory,
IWICFormatConverter **ppIFormatConverter)
{
return IWICImagingFactory_CreateFormatConverter(pFactory, ppIFormatConverter);
}
HRESULT WINAPI IWICImagingFactory_CreatePalette_Proxy_W(IWICImagingFactory *pFactory,
IWICPalette **ppIPalette)
{
return IWICImagingFactory_CreatePalette(pFactory, ppIPalette);
}
HRESULT WINAPI IWICImagingFactory_CreateQueryWriterFromReader_Proxy_W(IWICImagingFactory *pFactory,
IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
IWICMetadataQueryWriter **ppIQueryWriter)
{
return IWICImagingFactory_CreateQueryWriterFromReader(pFactory, pIQueryReader, pguidVendor, ppIQueryWriter);
}
HRESULT WINAPI IWICImagingFactory_CreateQueryWriter_Proxy_W(IWICImagingFactory *pFactory,
REFGUID guidMetadataFormat, const GUID *pguidVendor, IWICMetadataQueryWriter **ppIQueryWriter)
{
return IWICImagingFactory_CreateQueryWriter(pFactory, guidMetadataFormat, pguidVendor, ppIQueryWriter);
}
HRESULT WINAPI IWICImagingFactory_CreateStream_Proxy_W(IWICImagingFactory *pFactory,
IWICStream **ppIWICStream)
{
return IWICImagingFactory_CreateStream(pFactory, ppIWICStream);
}
HRESULT WINAPI IWICMetadataBlockReader_GetCount_Proxy_W(IWICMetadataBlockReader *iface,
UINT *pcCount)
{
return IWICMetadataBlockReader_GetCount(iface, pcCount);
}
HRESULT WINAPI IWICMetadataBlockReader_GetReaderByIndex_Proxy_W(IWICMetadataBlockReader *iface,
UINT nIndex, IWICMetadataReader **ppIMetadataReader)
{
return IWICMetadataBlockReader_GetReaderByIndex(iface, nIndex, ppIMetadataReader);
}
HRESULT WINAPI IWICMetadataQueryReader_GetContainerFormat_Proxy_W(IWICMetadataQueryReader *iface,
GUID *pguidContainerFormat)
{
return IWICMetadataQueryReader_GetContainerFormat(iface, pguidContainerFormat);
}
HRESULT WINAPI IWICMetadataQueryReader_GetLocation_Proxy_W(IWICMetadataQueryReader *iface,
UINT cchMaxLength, WCHAR *wzNamespace, UINT *pcchActualLength)
{
return IWICMetadataQueryReader_GetLocation(iface, cchMaxLength, wzNamespace, pcchActualLength);
}
HRESULT WINAPI IWICMetadataQueryReader_GetMetadataByName_Proxy_W(IWICMetadataQueryReader *iface,
LPCWSTR wzName, PROPVARIANT *pvarValue)
{
return IWICMetadataQueryReader_GetMetadataByName(iface, wzName, pvarValue);
}
HRESULT WINAPI IWICMetadataQueryReader_GetEnumerator_Proxy_W(IWICMetadataQueryReader *iface,
IEnumString **ppIEnumString)
{
return IWICMetadataQueryReader_GetEnumerator(iface, ppIEnumString);
}
HRESULT WINAPI IWICMetadataQueryWriter_SetMetadataByName_Proxy_W(IWICMetadataQueryWriter *iface,
LPCWSTR wzName, const PROPVARIANT *pvarValue)
{
return IWICMetadataQueryWriter_SetMetadataByName(iface, wzName, pvarValue);
}
HRESULT WINAPI IWICMetadataQueryWriter_RemoveMetadataByName_Proxy_W(IWICMetadataQueryWriter *iface,
LPCWSTR wzName)
{
return IWICMetadataQueryWriter_RemoveMetadataByName(iface, wzName);
}
HRESULT WINAPI IWICPalette_InitializePredefined_Proxy_W(IWICPalette *iface,
WICBitmapPaletteType ePaletteType, BOOL fAddTransparentColor)
{
return IWICPalette_InitializePredefined(iface, ePaletteType, fAddTransparentColor);
}
HRESULT WINAPI IWICPalette_InitializeCustom_Proxy_W(IWICPalette *iface,
WICColor *pColors, UINT colorCount)
{
return IWICPalette_InitializeCustom(iface, pColors, colorCount);
}
HRESULT WINAPI IWICPalette_InitializeFromBitmap_Proxy_W(IWICPalette *iface,
IWICBitmapSource *pISurface, UINT colorCount, BOOL fAddTransparentColor)
{
return IWICPalette_InitializeFromBitmap(iface, pISurface, colorCount, fAddTransparentColor);
}
HRESULT WINAPI IWICPalette_InitializeFromPalette_Proxy_W(IWICPalette *iface,
IWICPalette *pIPalette)
{
return IWICPalette_InitializeFromPalette(iface, pIPalette);
}
HRESULT WINAPI IWICPalette_GetType_Proxy_W(IWICPalette *iface,
WICBitmapPaletteType *pePaletteType)
{
return IWICPalette_GetType(iface, pePaletteType);
}
HRESULT WINAPI IWICPalette_GetColorCount_Proxy_W(IWICPalette *iface,
UINT *pcCount)
{
return IWICPalette_GetColorCount(iface, pcCount);
}
HRESULT WINAPI IWICPalette_GetColors_Proxy_W(IWICPalette *iface,
UINT colorCount, WICColor *pColors, UINT *pcActualColors)
{
return IWICPalette_GetColors(iface, colorCount, pColors, pcActualColors);
}
HRESULT WINAPI IWICPalette_HasAlpha_Proxy_W(IWICPalette *iface,
BOOL *pfHasAlpha)
{
return IWICPalette_HasAlpha(iface, pfHasAlpha);
}
HRESULT WINAPI IWICStream_InitializeFromIStream_Proxy_W(IWICStream *iface,
IStream *pIStream)
{
return IWICStream_InitializeFromIStream(iface, pIStream);
}
HRESULT WINAPI IWICStream_InitializeFromMemory_Proxy_W(IWICStream *iface,
BYTE *pbBuffer, DWORD cbBufferSize)
{
return IWICStream_InitializeFromMemory(iface, pbBuffer, cbBufferSize);
}
HRESULT WINAPI WICCreateColorContext_Proxy(IWICImagingFactory *iface, IWICColorContext **ppIWICColorContext)
{
TRACE("%p, %p\n", iface, ppIWICColorContext);
return IWICImagingFactory_CreateColorContext(iface, ppIWICColorContext);
}
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT SDKVersion, IWICImagingFactory **ppIImagingFactory)
{
TRACE("%x, %p\n", SDKVersion, ppIImagingFactory);
return ComponentFactory_CreateInstance(NULL, &IID_IWICImagingFactory, (void**)ppIImagingFactory);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,400 @@
/*
* Copyright 2010 Vincent Povirk 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
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct BitmapScaler {
IWICBitmapScaler IWICBitmapScaler_iface;
LONG ref;
IWICBitmapSource *source;
UINT width, height;
UINT src_width, src_height;
WICBitmapInterpolationMode mode;
UINT bpp;
void (*fn_get_required_source_rect)(struct BitmapScaler*,UINT,UINT,WICRect*);
void (*fn_copy_scanline)(struct BitmapScaler*,UINT,UINT,UINT,BYTE**,UINT,UINT,BYTE*);
CRITICAL_SECTION lock; /* must be held when initialized */
} BitmapScaler;
static inline BitmapScaler *impl_from_IWICBitmapScaler(IWICBitmapScaler *iface)
{
return CONTAINING_RECORD(iface, BitmapScaler, IWICBitmapScaler_iface);
}
static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFIID iid,
void **ppv)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(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_IWICBitmapScaler, iid))
{
*ppv = &This->IWICBitmapScaler_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI BitmapScaler_AddRef(IWICBitmapScaler *iface)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI BitmapScaler_Release(IWICBitmapScaler *iface)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
if (This->source) IWICBitmapSource_Release(This->source);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI BitmapScaler_GetSize(IWICBitmapScaler *iface,
UINT *puiWidth, UINT *puiHeight)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (!puiWidth || !puiHeight)
return E_INVALIDARG;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
*puiWidth = This->width;
*puiHeight = This->height;
return S_OK;
}
static HRESULT WINAPI BitmapScaler_GetPixelFormat(IWICBitmapScaler *iface,
WICPixelFormatGUID *pPixelFormat)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
TRACE("(%p,%p)\n", iface, pPixelFormat);
if (!pPixelFormat)
return E_INVALIDARG;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
return IWICBitmapSource_GetPixelFormat(This->source, pPixelFormat);
}
static HRESULT WINAPI BitmapScaler_GetResolution(IWICBitmapScaler *iface,
double *pDpiX, double *pDpiY)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);
if (!pDpiX || !pDpiY)
return E_INVALIDARG;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY);
}
static HRESULT WINAPI BitmapScaler_CopyPalette(IWICBitmapScaler *iface,
IWICPalette *pIPalette)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
TRACE("(%p,%p)\n", iface, pIPalette);
if (!pIPalette)
return E_INVALIDARG;
if (!This->source)
return WINCODEC_ERR_WRONGSTATE;
return IWICBitmapSource_CopyPalette(This->source, pIPalette);
}
static void NearestNeighbor_GetRequiredSourceRect(BitmapScaler *This,
UINT x, UINT y, WICRect *src_rect)
{
src_rect->X = x * This->src_width / This->width;
src_rect->Y = y * This->src_height / This->height;
src_rect->Width = src_rect->Height = 1;
}
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 bytesperpixel = This->bpp/8;
UINT src_x, src_y;
src_y = dst_y * This->src_height / This->height - src_data_y;
for (i=0; i<dst_width; i++)
{
src_x = (dst_x + i) * This->src_width / This->width - src_data_x;
memcpy(pbBuffer + bytesperpixel * i, src_data[src_y] + bytesperpixel * src_x, bytesperpixel);
}
}
static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
HRESULT hr;
WICRect dest_rect;
WICRect src_rect_ul, src_rect_br, src_rect;
BYTE **src_rows;
BYTE *src_bits;
ULONG bytesperrow;
ULONG src_bytesperrow;
ULONG buffer_size;
UINT y;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
EnterCriticalSection(&This->lock);
if (!This->source)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
if (prc)
dest_rect = *prc;
else
{
dest_rect.X = dest_rect.Y = 0;
dest_rect.Width = This->width;
dest_rect.Height = This->height;
}
if (dest_rect.X < 0 || dest_rect.Y < 0 ||
dest_rect.X+dest_rect.Width > This->width|| dest_rect.Y+dest_rect.Height > This->height)
{
hr = E_INVALIDARG;
goto end;
}
bytesperrow = ((This->bpp * dest_rect.Width)+7)/8;
if (cbStride < bytesperrow)
{
hr = E_INVALIDARG;
goto end;
}
if ((cbStride * dest_rect.Height) > cbBufferSize)
{
hr = E_INVALIDARG;
goto end;
}
/* MSDN recommends calling CopyPixels once for each scanline from top to
* bottom, and claims codecs optimize for this. Ideally, when called in this
* way, we should avoid requesting a scanline from the source more than
* once, by saving the data that will be useful for the next scanline after
* the call returns. The GetRequiredSourceRect/CopyScanline functions are
* designed to make it possible to do this in a generic way, but for now we
* just grab all the data we need in each call. */
This->fn_get_required_source_rect(This, dest_rect.X, dest_rect.Y, &src_rect_ul);
This->fn_get_required_source_rect(This, dest_rect.X+dest_rect.Width-1,
dest_rect.Y+dest_rect.Height-1, &src_rect_br);
src_rect.X = src_rect_ul.X;
src_rect.Y = src_rect_ul.Y;
src_rect.Width = src_rect_br.Width + src_rect_br.X - src_rect_ul.X;
src_rect.Height = src_rect_br.Height + src_rect_br.Y - src_rect_ul.Y;
src_bytesperrow = (src_rect.Width * This->bpp + 7)/8;
buffer_size = src_bytesperrow * src_rect.Height;
src_rows = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE*) * src_rect.Height);
src_bits = HeapAlloc(GetProcessHeap(), 0, buffer_size);
if (!src_rows || !src_bits)
{
HeapFree(GetProcessHeap(), 0, src_rows);
HeapFree(GetProcessHeap(), 0, src_bits);
hr = E_OUTOFMEMORY;
goto end;
}
for (y=0; y<src_rect.Height; y++)
src_rows[y] = src_bits + y * src_bytesperrow;
hr = IWICBitmapSource_CopyPixels(This->source, &src_rect, src_bytesperrow,
buffer_size, src_bits);
if (SUCCEEDED(hr))
{
for (y=0; y < dest_rect.Height; y++)
{
This->fn_copy_scanline(This, dest_rect.X, dest_rect.Y+y, dest_rect.Width,
src_rows, src_rect.X, src_rect.Y, pbBuffer + cbStride * y);
}
}
HeapFree(GetProcessHeap(), 0, src_rows);
HeapFree(GetProcessHeap(), 0, src_bits);
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI BitmapScaler_Initialize(IWICBitmapScaler *iface,
IWICBitmapSource *pISource, UINT uiWidth, UINT uiHeight,
WICBitmapInterpolationMode mode)
{
BitmapScaler *This = impl_from_IWICBitmapScaler(iface);
HRESULT hr;
GUID src_pixelformat;
TRACE("(%p,%p,%u,%u,%u)\n", iface, pISource, uiWidth, uiHeight, mode);
EnterCriticalSection(&This->lock);
if (This->source)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
This->width = uiWidth;
This->height = uiHeight;
This->mode = mode;
hr = IWICBitmapSource_GetSize(pISource, &This->src_width, &This->src_height);
if (SUCCEEDED(hr))
hr = IWICBitmapSource_GetPixelFormat(pISource, &src_pixelformat);
if (SUCCEEDED(hr))
{
hr = get_pixelformat_bpp(&src_pixelformat, &This->bpp);
}
if (SUCCEEDED(hr))
{
switch (mode)
{
default:
FIXME("unsupported mode %i\n", mode);
/* fall-through */
case WICBitmapInterpolationModeNearestNeighbor:
if ((This->bpp % 8) == 0)
{
IWICBitmapSource_AddRef(pISource);
This->source = pISource;
}
else
{
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA,
pISource, &This->source);
This->bpp = 32;
}
This->fn_get_required_source_rect = NearestNeighbor_GetRequiredSourceRect;
This->fn_copy_scanline = NearestNeighbor_CopyScanline;
break;
}
}
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static const IWICBitmapScalerVtbl BitmapScaler_Vtbl = {
BitmapScaler_QueryInterface,
BitmapScaler_AddRef,
BitmapScaler_Release,
BitmapScaler_GetSize,
BitmapScaler_GetPixelFormat,
BitmapScaler_GetResolution,
BitmapScaler_CopyPalette,
BitmapScaler_CopyPixels,
BitmapScaler_Initialize
};
HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
{
BitmapScaler *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapScaler));
if (!This) return E_OUTOFMEMORY;
This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl;
This->ref = 1;
This->source = NULL;
This->width = 0;
This->height = 0;
This->src_width = 0;
This->src_height = 0;
This->mode = 0;
This->bpp = 0;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapScaler.lock");
*scaler = &This->IWICBitmapScaler_iface;
return S_OK;
}

View file

@ -36,7 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
*
*/
typedef struct StreamOnMemory {
const IStreamVtbl *lpVtbl;
IStream IStream_iface;
LONG ref;
BYTE *pbMemory;
@ -46,6 +46,11 @@ typedef struct StreamOnMemory {
CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */
} StreamOnMemory;
static inline StreamOnMemory *StreamOnMemory_from_IStream(IStream *iface)
{
return CONTAINING_RECORD(iface, StreamOnMemory, IStream_iface);
}
static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
REFIID iid, void **ppv)
{
@ -69,7 +74,7 @@ static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
static ULONG WINAPI StreamOnMemory_AddRef(IStream *iface)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -79,7 +84,7 @@ static ULONG WINAPI StreamOnMemory_AddRef(IStream *iface)
static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -95,7 +100,7 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
void *pv, ULONG cb, ULONG *pcbRead)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
ULONG uBytesRead;
TRACE("(%p)\n", This);
@ -103,7 +108,7 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
EnterCriticalSection(&This->lock);
uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
memmove(pv, This->pbMemory + This->dwCurPos, uBytesRead);
This->dwCurPos += uBytesRead;
LeaveCriticalSection(&This->lock);
@ -115,7 +120,7 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
HRESULT hr;
TRACE("(%p)\n", This);
@ -126,7 +131,7 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
hr = STG_E_MEDIUMFULL;
}
else {
memcpy(This->pbMemory + This->dwCurPos, pv, cb);
memmove(This->pbMemory + This->dwCurPos, pv, cb);
This->dwCurPos += cb;
hr = S_OK;
if (pcbWritten) *pcbWritten = cb;
@ -139,7 +144,7 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
LARGE_INTEGER NewPosition;
HRESULT hr=S_OK;
TRACE("(%p)\n", This);
@ -216,7 +221,7 @@ static HRESULT WINAPI StreamOnMemory_UnlockRegion(IStream *iface,
static HRESULT WINAPI StreamOnMemory_Stat(IStream *iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
StreamOnMemory *This = StreamOnMemory_from_IStream(iface);
TRACE("(%p)\n", This);
if (!pstatstg) return E_INVALIDARG;
@ -237,7 +242,7 @@ static HRESULT WINAPI StreamOnMemory_Clone(IStream *iface,
}
const IStreamVtbl StreamOnMemory_Vtbl =
static const IStreamVtbl StreamOnMemory_Vtbl =
{
/*** IUnknown methods ***/
StreamOnMemory_QueryInterface,
@ -258,22 +263,324 @@ const IStreamVtbl StreamOnMemory_Vtbl =
StreamOnMemory_Clone,
};
/******************************************
* StreamOnStreamRange implementation
*
* Used by IWICStream_InitializeFromIStreamRegion
*
*/
typedef struct StreamOnStreamRange {
IStream IStream_iface;
LONG ref;
IStream *stream;
ULARGE_INTEGER pos;
ULARGE_INTEGER offset;
ULARGE_INTEGER max_size;
CRITICAL_SECTION lock;
} StreamOnStreamRange;
static inline StreamOnStreamRange *StreamOnStreamRange_from_IStream(IStream *iface)
{
return CONTAINING_RECORD(iface, StreamOnStreamRange, IStream_iface);
}
static HRESULT WINAPI StreamOnStreamRange_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 StreamOnStreamRange_AddRef(IStream *iface)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI StreamOnStreamRange_Release(IStream *iface)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0) {
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI StreamOnStreamRange_Read(IStream *iface,
void *pv, ULONG cb, ULONG *pcbRead)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
ULONG uBytesRead=0;
HRESULT hr;
ULARGE_INTEGER OldPosition;
LARGE_INTEGER SetPosition;
TRACE("(%p)\n", This);
if (!pv) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
SetPosition.QuadPart = 0;
hr = IStream_Seek(This->stream, SetPosition, STREAM_SEEK_CUR, &OldPosition);
if (SUCCEEDED(hr))
{
SetPosition.QuadPart = This->pos.QuadPart + This->offset.QuadPart;
hr = IStream_Seek(This->stream, SetPosition, STREAM_SEEK_SET, NULL);
}
if (SUCCEEDED(hr))
{
if (This->pos.QuadPart + cb > This->max_size.QuadPart)
{
/* This would read past the end of the stream. */
if (This->pos.QuadPart > This->max_size.QuadPart)
cb = 0;
else
cb = This->max_size.QuadPart - This->pos.QuadPart;
}
hr = IStream_Read(This->stream, pv, cb, &uBytesRead);
SetPosition.QuadPart = OldPosition.QuadPart;
IStream_Seek(This->stream, SetPosition, STREAM_SEEK_SET, NULL);
}
if (SUCCEEDED(hr))
This->pos.QuadPart += uBytesRead;
LeaveCriticalSection(&This->lock);
if (SUCCEEDED(hr) && pcbRead) *pcbRead = uBytesRead;
return hr;
}
static HRESULT WINAPI StreamOnStreamRange_Write(IStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
HRESULT hr;
ULARGE_INTEGER OldPosition;
LARGE_INTEGER SetPosition;
ULONG uBytesWritten=0;
TRACE("(%p)\n", This);
if (!pv) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
SetPosition.QuadPart = 0;
hr = IStream_Seek(This->stream, SetPosition, STREAM_SEEK_CUR, &OldPosition);
if (SUCCEEDED(hr))
{
SetPosition.QuadPart = This->pos.QuadPart + This->offset.QuadPart;
hr = IStream_Seek(This->stream, SetPosition, STREAM_SEEK_SET, NULL);
}
if (SUCCEEDED(hr))
{
if (This->pos.QuadPart + cb > This->max_size.QuadPart)
{
/* This would read past the end of the stream. */
if (This->pos.QuadPart > This->max_size.QuadPart)
cb = 0;
else
cb = This->max_size.QuadPart - This->pos.QuadPart;
}
hr = IStream_Write(This->stream, pv, cb, &uBytesWritten);
SetPosition.QuadPart = OldPosition.QuadPart;
IStream_Seek(This->stream, SetPosition, STREAM_SEEK_SET, NULL);
}
if (SUCCEEDED(hr))
This->pos.QuadPart += uBytesWritten;
LeaveCriticalSection(&This->lock);
if (SUCCEEDED(hr) && pcbWritten) *pcbWritten = uBytesWritten;
return hr;
}
static HRESULT WINAPI StreamOnStreamRange_Seek(IStream *iface,
LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
ULARGE_INTEGER NewPosition, actual_size;
HRESULT hr=S_OK;
STATSTG statstg;
TRACE("(%p)\n", This);
EnterCriticalSection(&This->lock);
actual_size = This->max_size;
if (dwOrigin == STREAM_SEEK_SET)
NewPosition.QuadPart = dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_CUR)
NewPosition.QuadPart = This->pos.QuadPart + dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_END)
{
hr = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME);
if (SUCCEEDED(hr))
{
if (This->max_size.QuadPart + This->offset.QuadPart > statstg.cbSize.QuadPart)
actual_size.QuadPart = statstg.cbSize.QuadPart - This->offset.QuadPart;
NewPosition.QuadPart = dlibMove.QuadPart + actual_size.QuadPart;
}
}
else hr = E_INVALIDARG;
if (SUCCEEDED(hr) && (NewPosition.u.HighPart != 0 || NewPosition.QuadPart > actual_size.QuadPart))
hr = WINCODEC_ERR_VALUEOUTOFRANGE;
if (SUCCEEDED(hr)) {
This->pos.QuadPart = NewPosition.QuadPart;
if(plibNewPosition) plibNewPosition->QuadPart = This->pos.QuadPart;
}
LeaveCriticalSection(&This->lock);
return hr;
}
/* SetSize isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_SetSize(IStream *iface,
ULARGE_INTEGER libNewSize)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* CopyTo isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_CopyTo(IStream *iface,
IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* Commit isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_Commit(IStream *iface,
DWORD grfCommitFlags)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* Revert isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_Revert(IStream *iface)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* LockRegion isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_LockRegion(IStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* UnlockRegion isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_UnlockRegion(IStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI StreamOnStreamRange_Stat(IStream *iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface);
HRESULT hr;
TRACE("(%p)\n", This);
if (!pstatstg) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
hr = IStream_Stat(This->stream, pstatstg, grfStatFlag);
if (SUCCEEDED(hr))
{
pstatstg->cbSize.QuadPart -= This->offset.QuadPart;
if (This->max_size.QuadPart < pstatstg->cbSize.QuadPart)
pstatstg->cbSize.QuadPart = This->max_size.QuadPart;
}
LeaveCriticalSection(&This->lock);
return hr;
}
/* Clone isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnStreamRange_Clone(IStream *iface,
IStream **ppstm)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
static const IStreamVtbl StreamOnStreamRange_Vtbl =
{
/*** IUnknown methods ***/
StreamOnStreamRange_QueryInterface,
StreamOnStreamRange_AddRef,
StreamOnStreamRange_Release,
/*** ISequentialStream methods ***/
StreamOnStreamRange_Read,
StreamOnStreamRange_Write,
/*** IStream methods ***/
StreamOnStreamRange_Seek,
StreamOnStreamRange_SetSize,
StreamOnStreamRange_CopyTo,
StreamOnStreamRange_Commit,
StreamOnStreamRange_Revert,
StreamOnStreamRange_LockRegion,
StreamOnStreamRange_UnlockRegion,
StreamOnStreamRange_Stat,
StreamOnStreamRange_Clone,
};
/******************************************
* IWICStream implementation
*
*/
typedef struct IWICStreamImpl
{
const IWICStreamVtbl *lpVtbl;
IWICStream IWICStream_iface;
LONG ref;
IStream *pStream;
} IWICStreamImpl;
static inline IWICStreamImpl *impl_from_IWICStream(IWICStream *iface)
{
return CONTAINING_RECORD(iface, IWICStreamImpl, IWICStream_iface);
}
static HRESULT WINAPI IWICStreamImpl_QueryInterface(IWICStream *iface,
REFIID iid, void **ppv)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
@ -294,7 +601,7 @@ static HRESULT WINAPI IWICStreamImpl_QueryInterface(IWICStream *iface,
static ULONG WINAPI IWICStreamImpl_AddRef(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -304,7 +611,7 @@ static ULONG WINAPI IWICStreamImpl_AddRef(IWICStream *iface)
static ULONG WINAPI IWICStreamImpl_Release(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
@ -319,7 +626,7 @@ static ULONG WINAPI IWICStreamImpl_Release(IWICStream *iface)
static HRESULT WINAPI IWICStreamImpl_Read(IWICStream *iface,
void *pv, ULONG cb, ULONG *pcbRead)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -329,7 +636,7 @@ static HRESULT WINAPI IWICStreamImpl_Read(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Write(IWICStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -339,7 +646,7 @@ static HRESULT WINAPI IWICStreamImpl_Write(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Seek(IWICStream *iface,
LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -349,7 +656,7 @@ static HRESULT WINAPI IWICStreamImpl_Seek(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_SetSize(IWICStream *iface,
ULARGE_INTEGER libNewSize)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -359,7 +666,7 @@ static HRESULT WINAPI IWICStreamImpl_SetSize(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_CopyTo(IWICStream *iface,
IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -369,7 +676,7 @@ static HRESULT WINAPI IWICStreamImpl_CopyTo(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Commit(IWICStream *iface,
DWORD grfCommitFlags)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -378,7 +685,7 @@ static HRESULT WINAPI IWICStreamImpl_Commit(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Revert(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -388,7 +695,7 @@ static HRESULT WINAPI IWICStreamImpl_Revert(IWICStream *iface)
static HRESULT WINAPI IWICStreamImpl_LockRegion(IWICStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -398,7 +705,7 @@ static HRESULT WINAPI IWICStreamImpl_LockRegion(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_UnlockRegion(IWICStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -408,7 +715,7 @@ static HRESULT WINAPI IWICStreamImpl_UnlockRegion(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Stat(IWICStream *iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -418,7 +725,7 @@ static HRESULT WINAPI IWICStreamImpl_Stat(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_Clone(IWICStream *iface,
IStream **ppstm)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
@ -428,14 +735,19 @@ static HRESULT WINAPI IWICStreamImpl_Clone(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_InitializeFromIStream(IWICStream *iface,
IStream *pIStream)
{
FIXME("(%p): stub\n", iface);
return E_NOTIMPL;
ULARGE_INTEGER offset, size;
TRACE("(%p): relay\n", iface);
offset.QuadPart = 0;
size.u.LowPart = 0xffffffff;
size.u.HighPart = 0xffffffff;
return IWICStream_InitializeFromIStreamRegion(iface, pIStream, offset, size);
}
static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface,
LPCWSTR wzFileName, DWORD dwDesiredAccess)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
HRESULT hr;
DWORD dwMode;
IStream *stream;
@ -485,7 +797,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
BYTE *pbBuffer, DWORD cbBufferSize)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
IWICStreamImpl *This = impl_from_IWICStream(iface);
StreamOnMemory *pObject;
TRACE("(%p,%p)\n", iface, pbBuffer);
@ -495,7 +807,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnMemory));
if (!pObject) return E_OUTOFMEMORY;
pObject->lpVtbl = &StreamOnMemory_Vtbl;
pObject->IStream_iface.lpVtbl = &StreamOnMemory_Vtbl;
pObject->ref = 1;
pObject->pbMemory = pbBuffer;
pObject->dwMemsize = cbBufferSize;
@ -506,7 +818,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL))
{
/* Some other thread set the stream first. */
IStream_Release((IStream*)pObject);
IStream_Release(&pObject->IStream_iface);
return WINCODEC_ERR_WRONGSTATE;
}
@ -516,12 +828,38 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *iface,
IStream *pIStream, ULARGE_INTEGER ulOffset, ULARGE_INTEGER ulMaxSize)
{
FIXME("(%p): stub\n", iface);
return E_NOTIMPL;
IWICStreamImpl *This = impl_from_IWICStream(iface);
StreamOnStreamRange *pObject;
TRACE("(%p,%p)\n", iface, pIStream);
if (!pIStream) return E_INVALIDARG;
if (This->pStream) return WINCODEC_ERR_WRONGSTATE;
pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnStreamRange));
if (!pObject) return E_OUTOFMEMORY;
pObject->IStream_iface.lpVtbl = &StreamOnStreamRange_Vtbl;
pObject->ref = 1;
IStream_AddRef(pIStream);
pObject->stream = pIStream;
pObject->pos.QuadPart = 0;
pObject->offset = ulOffset;
pObject->max_size = ulMaxSize;
InitializeCriticalSection(&pObject->lock);
pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnStreamRange.lock");
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;
}
const IWICStreamVtbl WICStream_Vtbl =
static const IWICStreamVtbl WICStream_Vtbl =
{
/*** IUnknown methods ***/
IWICStreamImpl_QueryInterface,
@ -559,11 +897,11 @@ HRESULT StreamImpl_Create(IWICStream **stream)
return E_OUTOFMEMORY;
}
pObject->lpVtbl = &WICStream_Vtbl;
pObject->IWICStream_iface.lpVtbl = &WICStream_Vtbl;
pObject->ref = 1;
pObject->pStream = NULL;
*stream = (IWICStream*)pObject;
*stream = &pObject->IWICStream_iface;
return S_OK;
}

View file

@ -0,0 +1,981 @@
/*
* Copyright 2010 Vincent Povirk 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
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
#include "wine/library.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#include "pshpack1.h"
typedef struct {
BYTE id_length;
BYTE colormap_type;
BYTE image_type;
/* Colormap Specification */
WORD colormap_firstentry;
WORD colormap_length;
BYTE colormap_entrysize;
/* Image Specification */
WORD xorigin;
WORD yorigin;
WORD width;
WORD height;
BYTE depth;
BYTE image_descriptor;
} tga_header;
#define IMAGETYPE_COLORMAPPED 1
#define IMAGETYPE_TRUECOLOR 2
#define IMAGETYPE_GRAYSCALE 3
#define IMAGETYPE_RLE 8
#define IMAGE_ATTRIBUTE_BITCOUNT_MASK 0xf
#define IMAGE_RIGHTTOLEFT 0x10
#define IMAGE_TOPTOBOTTOM 0x20
typedef struct {
DWORD extension_area_offset;
DWORD developer_directory_offset;
char magic[18];
} tga_footer;
static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
typedef struct {
WORD size;
char author_name[41];
char author_comments[324];
WORD timestamp[6];
char job_name[41];
WORD job_timestamp[6];
char software_id[41];
WORD software_version;
char software_version_letter;
DWORD key_color;
WORD pixel_width;
WORD pixel_height;
WORD gamma_numerator;
WORD gamma_denominator;
DWORD color_correction_offset;
DWORD thumbnail_offset;
DWORD scanline_offset;
BYTE attributes_type;
} tga_extension_area;
#define ATTRIBUTE_NO_ALPHA 0
#define ATTRIBUTE_UNDEFINED 1
#define ATTRIBUTE_UNDEFINED_PRESERVE 2
#define ATTRIBUTE_ALPHA 3
#define ATTRIBUTE_PALPHA 4
#include "poppack.h"
typedef struct {
IWICBitmapDecoder IWICBitmapDecoder_iface;
IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
LONG ref;
BOOL initialized;
IStream *stream;
tga_header header;
tga_extension_area extension_area;
BYTE *imagebits;
BYTE *origin;
int stride;
ULONG id_offset;
ULONG colormap_length;
ULONG colormap_offset;
ULONG image_offset;
ULONG extension_area_offset;
ULONG developer_directory_offset;
CRITICAL_SECTION lock;
} TgaDecoder;
static inline TgaDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
return CONTAINING_RECORD(iface, TgaDecoder, IWICBitmapDecoder_iface);
}
static inline TgaDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
{
return CONTAINING_RECORD(iface, TgaDecoder, IWICBitmapFrameDecode_iface);
}
static HRESULT WINAPI TgaDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = &This->IWICBitmapDecoder_iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI TgaDecoder_AddRef(IWICBitmapDecoder *iface)
{
TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface)
{
TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
if (This->stream)
IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This->imagebits);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI TgaDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream,
DWORD *capability)
{
HRESULT hr;
TRACE("(%p,%p,%p)\n", iface, stream, capability);
if (!stream || !capability) return E_INVALIDARG;
hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand);
if (hr != S_OK) return hr;
*capability = WICBitmapDecoderCapabilityCanDecodeAllImages |
WICBitmapDecoderCapabilityCanDecodeSomeImages;
return S_OK;
}
static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
HRESULT hr=S_OK;
DWORD bytesread;
LARGE_INTEGER seek;
tga_footer footer;
int attribute_bitcount;
int mapped_depth=0;
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
EnterCriticalSection(&This->lock);
if (This->initialized)
{
hr = WINCODEC_ERR_WRONGSTATE;
goto end;
}
seek.QuadPart = 0;
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto end;
hr = IStream_Read(pIStream, &This->header, sizeof(tga_header), &bytesread);
if (SUCCEEDED(hr) && bytesread != sizeof(tga_header))
{
TRACE("got only %u bytes\n", bytesread);
hr = E_FAIL;
}
if (FAILED(hr)) goto end;
TRACE("imagetype=%u, colormap type=%u, depth=%u, image descriptor=0x%x\n",
This->header.image_type, This->header.colormap_type,
This->header.depth, This->header.image_descriptor);
/* Sanity checking. Since TGA has no clear identifying markers, we need
* to be careful to not load a non-TGA image. */
switch (This->header.image_type)
{
case IMAGETYPE_COLORMAPPED:
case IMAGETYPE_COLORMAPPED|IMAGETYPE_RLE:
if (This->header.colormap_type != 1)
hr = E_FAIL;
mapped_depth = This->header.colormap_entrysize;
break;
case IMAGETYPE_TRUECOLOR:
case IMAGETYPE_TRUECOLOR|IMAGETYPE_RLE:
if (This->header.colormap_type != 0 && This->header.colormap_type != 1)
hr = E_FAIL;
mapped_depth = This->header.depth;
break;
case IMAGETYPE_GRAYSCALE:
case IMAGETYPE_GRAYSCALE|IMAGETYPE_RLE:
if (This->header.colormap_type != 0)
hr = E_FAIL;
mapped_depth = 0;
break;
default:
hr = E_FAIL;
}
if (This->header.depth != 8 && This->header.depth != 16 &&
This->header.depth != 24 && This->header.depth != 32)
hr = E_FAIL;
if ((This->header.image_descriptor & 0xc0) != 0)
hr = E_FAIL;
attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;
if (attribute_bitcount &&
!((mapped_depth == 32 && attribute_bitcount == 8) ||
(mapped_depth == 16 && attribute_bitcount == 1)))
hr = E_FAIL;
if (FAILED(hr))
{
WARN("bad tga header\n");
goto end;
}
/* Locate data in the file based on the header. */
This->id_offset = sizeof(tga_header);
This->colormap_offset = This->id_offset + This->header.id_length;
if (This->header.colormap_type == 1)
This->colormap_length = ((This->header.colormap_entrysize+7)/8) * This->header.colormap_length;
else
This->colormap_length = 0;
This->image_offset = This->colormap_offset + This->colormap_length;
/* Read footer if there is one */
seek.QuadPart = -sizeof(tga_footer);
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_END, NULL);
if (SUCCEEDED(hr)) {
hr = IStream_Read(pIStream, &footer, sizeof(tga_footer), &bytesread);
if (SUCCEEDED(hr) && bytesread != sizeof(tga_footer))
{
TRACE("got only %u footer bytes\n", bytesread);
hr = E_FAIL;
}
if (memcmp(footer.magic, tga_footer_magic, sizeof(tga_footer_magic)) == 0)
{
This->extension_area_offset = footer.extension_area_offset;
This->developer_directory_offset = footer.developer_directory_offset;
}
else
{
This->extension_area_offset = 0;
This->developer_directory_offset = 0;
}
}
else
{
/* File is too small to have a footer. */
This->extension_area_offset = 0;
This->developer_directory_offset = 0;
hr = S_OK;
}
if (This->extension_area_offset)
{
seek.QuadPart = This->extension_area_offset;
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto end;
hr = IStream_Read(pIStream, &This->extension_area, sizeof(tga_extension_area), &bytesread);
if (SUCCEEDED(hr) && bytesread != sizeof(tga_extension_area))
{
TRACE("got only %u extension area bytes\n", bytesread);
hr = E_FAIL;
}
if (SUCCEEDED(hr) && This->extension_area.size < 495)
{
TRACE("extension area is only %u bytes long\n", This->extension_area.size);
hr = E_FAIL;
}
if (FAILED(hr)) goto end;
}
IStream_AddRef(pIStream);
This->stream = pIStream;
This->initialized = TRUE;
end:
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI TgaDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
GUID *pguidContainerFormat)
{
memcpy(pguidContainerFormat, &GUID_WineContainerFormatTga, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI TgaDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
HRESULT hr;
IWICComponentInfo *compinfo;
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
hr = CreateComponentInfo(&CLSID_WineTgaDecoder, &compinfo);
if (FAILED(hr)) return hr;
hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
(void**)ppIDecoderInfo);
IWICComponentInfo_Release(compinfo);
return hr;
}
static HRESULT WINAPI TgaDecoder_CopyPalette(IWICBitmapDecoder *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return E_NOTIMPL;
}
static HRESULT WINAPI TgaDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
return E_NOTIMPL;
}
static HRESULT WINAPI TgaDecoder_GetPreview(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIBitmapSource)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapSource);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI TgaDecoder_GetColorContexts(IWICBitmapDecoder *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI TgaDecoder_GetThumbnail(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIThumbnail)
{
FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static HRESULT WINAPI TgaDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
if (!pCount) return E_INVALIDARG;
*pCount = 1;
return S_OK;
}
static HRESULT WINAPI TgaDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
TRACE("(%p,%p)\n", iface, ppIBitmapFrame);
if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING;
if (index != 0) return E_INVALIDARG;
IWICBitmapDecoder_AddRef(iface);
*ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;
return S_OK;
}
static const IWICBitmapDecoderVtbl TgaDecoder_Vtbl = {
TgaDecoder_QueryInterface,
TgaDecoder_AddRef,
TgaDecoder_Release,
TgaDecoder_QueryCapability,
TgaDecoder_Initialize,
TgaDecoder_GetContainerFormat,
TgaDecoder_GetDecoderInfo,
TgaDecoder_CopyPalette,
TgaDecoder_GetMetadataQueryReader,
TgaDecoder_GetPreview,
TgaDecoder_GetColorContexts,
TgaDecoder_GetThumbnail,
TgaDecoder_GetFrameCount,
TgaDecoder_GetFrame
};
static HRESULT WINAPI TgaDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *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_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = iface;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI TgaDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
}
static ULONG WINAPI TgaDecoder_Frame_Release(IWICBitmapFrameDecode *iface)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
}
static HRESULT WINAPI TgaDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
*puiWidth = This->header.width;
*puiHeight = This->header.height;
TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight);
return S_OK;
}
static HRESULT WINAPI TgaDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface,
WICPixelFormatGUID *pPixelFormat)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
int attribute_bitcount;
byte attribute_type;
TRACE("(%p,%p)\n", iface, pPixelFormat);
attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;
if (attribute_bitcount && This->extension_area_offset)
attribute_type = This->extension_area.attributes_type;
else if (attribute_bitcount)
attribute_type = ATTRIBUTE_ALPHA;
else
attribute_type = ATTRIBUTE_NO_ALPHA;
switch (This->header.image_type & ~IMAGETYPE_RLE)
{
case IMAGETYPE_COLORMAPPED:
switch (This->header.depth)
{
case 8:
memcpy(pPixelFormat, &GUID_WICPixelFormat8bppIndexed, sizeof(GUID));
break;
default:
FIXME("Unhandled indexed color depth %u\n", This->header.depth);
return E_NOTIMPL;
}
break;
case IMAGETYPE_TRUECOLOR:
switch (This->header.depth)
{
case 16:
switch (attribute_type)
{
case ATTRIBUTE_NO_ALPHA:
case ATTRIBUTE_UNDEFINED:
case ATTRIBUTE_UNDEFINED_PRESERVE:
memcpy(pPixelFormat, &GUID_WICPixelFormat16bppBGR555, sizeof(GUID));
break;
case ATTRIBUTE_ALPHA:
case ATTRIBUTE_PALPHA:
memcpy(pPixelFormat, &GUID_WICPixelFormat16bppBGRA5551, sizeof(GUID));
break;
default:
FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
return E_NOTIMPL;
}
break;
case 24:
memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID));
break;
case 32:
switch (attribute_type)
{
case ATTRIBUTE_NO_ALPHA:
case ATTRIBUTE_UNDEFINED:
case ATTRIBUTE_UNDEFINED_PRESERVE:
memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGR, sizeof(GUID));
break;
case ATTRIBUTE_ALPHA:
memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
break;
case ATTRIBUTE_PALPHA:
memcpy(pPixelFormat, &GUID_WICPixelFormat32bppPBGRA, sizeof(GUID));
break;
default:
FIXME("Unhandled 32-bit attribute type %u\n", attribute_type);
return E_NOTIMPL;
}
break;
default:
FIXME("Unhandled truecolor depth %u\n", This->header.depth);
return E_NOTIMPL;
}
break;
case IMAGETYPE_GRAYSCALE:
switch (This->header.depth)
{
case 8:
memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID));
break;
case 16:
memcpy(pPixelFormat, &GUID_WICPixelFormat16bppGray, sizeof(GUID));
break;
default:
FIXME("Unhandled grayscale depth %u\n", This->header.depth);
return E_NOTIMPL;
}
break;
default:
ERR("Unknown image type %u\n", This->header.image_type);
return E_FAIL;
}
return S_OK;
}
static HRESULT WINAPI TgaDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
return E_NOTIMPL;
}
static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
HRESULT hr=S_OK;
WICColor colors[256], *color;
BYTE *colormap_data;
WORD *wcolormap_data;
DWORD *dwcolormap_data;
LARGE_INTEGER seek;
ULONG bytesread;
int depth, attribute_bitcount, attribute_type;
int i;
TRACE("(%p,%p)\n", iface, pIPalette);
if (!This->colormap_length)
{
WARN("no colormap present in this file\n");
return WINCODEC_ERR_PALETTEUNAVAILABLE;
}
if (This->header.colormap_firstentry + This->header.colormap_length > 256)
{
FIXME("cannot read colormap with %i entries starting at %i\n",
This->header.colormap_firstentry + This->header.colormap_length,
This->header.colormap_firstentry);
return E_FAIL;
}
colormap_data = HeapAlloc(GetProcessHeap(), 0, This->colormap_length);
if (!colormap_data) return E_OUTOFMEMORY;
wcolormap_data = (WORD*)colormap_data;
dwcolormap_data = (DWORD*)colormap_data;
EnterCriticalSection(&This->lock);
seek.QuadPart = This->colormap_offset;
hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL);
if (SUCCEEDED(hr))
{
hr = IStream_Read(This->stream, colormap_data, This->colormap_length, &bytesread);
if (SUCCEEDED(hr) && bytesread != This->colormap_length)
{
WARN("expected %i bytes in colormap, got %i\n", This->colormap_length, bytesread);
hr = E_FAIL;
}
}
LeaveCriticalSection(&This->lock);
if (SUCCEEDED(hr))
{
attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;
if (attribute_bitcount && This->extension_area_offset)
attribute_type = This->extension_area.attributes_type;
else if (attribute_bitcount)
attribute_type = ATTRIBUTE_ALPHA;
else
attribute_type = ATTRIBUTE_NO_ALPHA;
depth = This->header.colormap_entrysize;
if (depth == 15)
{
depth = 16;
attribute_type = ATTRIBUTE_NO_ALPHA;
}
memset(colors, 0, sizeof(colors));
color = &colors[This->header.colormap_firstentry];
/* Colormap entries can be in any truecolor format, and we have to convert them. */
switch (depth)
{
case 16:
switch (attribute_type)
{
case ATTRIBUTE_NO_ALPHA:
case ATTRIBUTE_UNDEFINED:
case ATTRIBUTE_UNDEFINED_PRESERVE:
for (i=0; i<This->header.colormap_length; i++)
{
WORD srcval = wcolormap_data[i];
*color++=0xff000000 | /* constant 255 alpha */
((srcval << 9) & 0xf80000) | /* r */
((srcval << 4) & 0x070000) | /* r - 3 bits */
((srcval << 6) & 0x00f800) | /* g */
((srcval << 1) & 0x000700) | /* g - 3 bits */
((srcval << 3) & 0x0000f8) | /* b */
((srcval >> 2) & 0x000007); /* b - 3 bits */
}
break;
case ATTRIBUTE_ALPHA:
case ATTRIBUTE_PALPHA:
for (i=0; i<This->header.colormap_length; i++)
{
WORD srcval = wcolormap_data[i];
*color++=((srcval & 0x8000) ? 0xff000000 : 0) | /* alpha */
((srcval << 9) & 0xf80000) | /* r */
((srcval << 4) & 0x070000) | /* r - 3 bits */
((srcval << 6) & 0x00f800) | /* g */
((srcval << 1) & 0x000700) | /* g - 3 bits */
((srcval << 3) & 0x0000f8) | /* b */
((srcval >> 2) & 0x000007); /* b - 3 bits */
}
break;
default:
FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
hr = E_NOTIMPL;
}
break;
case 24:
for (i=0; i<This->header.colormap_length; i++)
{
*color++=0xff000000 | /* alpha */
colormap_data[i*3+2] | /* red */
colormap_data[i*3+1] | /* green */
colormap_data[i*3]; /* blue */
}
break;
case 32:
switch (attribute_type)
{
case ATTRIBUTE_NO_ALPHA:
case ATTRIBUTE_UNDEFINED:
case ATTRIBUTE_UNDEFINED_PRESERVE:
for (i=0; i<This->header.colormap_length; i++)
*color++=dwcolormap_data[i]|0xff000000;
break;
case ATTRIBUTE_ALPHA:
for (i=0; i<This->header.colormap_length; i++)
*color++=dwcolormap_data[i];
break;
case ATTRIBUTE_PALPHA:
/* FIXME: Unpremultiply alpha */
default:
FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
hr = E_NOTIMPL;
}
break;
default:
FIXME("Unhandled truecolor depth %u\n", This->header.depth);
hr = E_NOTIMPL;
}
}
HeapFree(GetProcessHeap(), 0, colormap_data);
if (SUCCEEDED(hr))
hr = IWICPalette_InitializeCustom(pIPalette, colors, 256);
return hr;
}
static HRESULT TgaDecoder_ReadRLE(TgaDecoder *This, BYTE *imagebits, int datasize)
{
int i=0, j, bytesperpixel;
ULONG bytesread;
HRESULT hr=S_OK;
bytesperpixel = This->header.depth / 8;
while (i<datasize)
{
BYTE rc;
int count, size;
BYTE pixeldata[4];
hr = IStream_Read(This->stream, &rc, 1, &bytesread);
if (bytesread != 1) hr = E_FAIL;
if (FAILED(hr)) break;
count = (rc&0x7f)+1;
size = count * bytesperpixel;
if (size + i > datasize)
{
WARN("RLE packet too large\n");
hr = E_FAIL;
break;
}
if (rc&0x80)
{
/* Run-length packet */
hr = IStream_Read(This->stream, pixeldata, bytesperpixel, &bytesread);
if (bytesread != bytesperpixel) hr = E_FAIL;
if (FAILED(hr)) break;
if (bytesperpixel == 1)
memset(&imagebits[i], pixeldata[0], count);
else
{
for (j=0; j<count; j++)
memcpy(&imagebits[i+j*bytesperpixel], pixeldata, bytesperpixel);
}
}
else
{
/* Raw packet */
hr = IStream_Read(This->stream, &imagebits[i], size, &bytesread);
if (bytesread != size) hr = E_FAIL;
if (FAILED(hr)) break;
}
i += size;
}
return hr;
}
static HRESULT TgaDecoder_ReadImage(TgaDecoder *This)
{
HRESULT hr=S_OK;
int datasize;
LARGE_INTEGER seek;
ULONG bytesread;
if (This->imagebits)
return S_OK;
EnterCriticalSection(&This->lock);
if (!This->imagebits)
{
if (This->header.image_descriptor & IMAGE_RIGHTTOLEFT)
{
FIXME("Right to left image reading not implemented\n");
hr = E_NOTIMPL;
}
if (SUCCEEDED(hr))
{
datasize = This->header.width * This->header.height * (This->header.depth / 8);
This->imagebits = HeapAlloc(GetProcessHeap(), 0, datasize);
if (!This->imagebits) hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
seek.QuadPart = This->image_offset;
hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL);
}
if (SUCCEEDED(hr))
{
if (This->header.image_type & IMAGETYPE_RLE)
{
hr = TgaDecoder_ReadRLE(This, This->imagebits, datasize);
}
else
{
hr = IStream_Read(This->stream, This->imagebits, datasize, &bytesread);
if (SUCCEEDED(hr) && bytesread != datasize)
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
if (This->header.image_descriptor & IMAGE_TOPTOBOTTOM)
{
This->origin = This->imagebits;
This->stride = This->header.width * (This->header.depth / 8);
}
else
{
This->stride = -This->header.width * (This->header.depth / 8);
This->origin = This->imagebits + This->header.width * (This->header.height - 1) * (This->header.depth / 8);
}
}
else
{
HeapFree(GetProcessHeap(), 0, This->imagebits);
This->imagebits = NULL;
}
}
LeaveCriticalSection(&This->lock);
return hr;
}
static HRESULT WINAPI TgaDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
HRESULT hr;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
hr = TgaDecoder_ReadImage(This);
if (SUCCEEDED(hr))
{
hr = copy_pixels(This->header.depth, This->origin,
This->header.width, This->header.height, This->stride,
prc, cbStride, cbBufferSize, pbBuffer);
}
return hr;
}
static HRESULT WINAPI TgaDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI TgaDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI TgaDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface,
IWICBitmapSource **ppIThumbnail)
{
FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static const IWICBitmapFrameDecodeVtbl TgaDecoder_Frame_Vtbl = {
TgaDecoder_Frame_QueryInterface,
TgaDecoder_Frame_AddRef,
TgaDecoder_Frame_Release,
TgaDecoder_Frame_GetSize,
TgaDecoder_Frame_GetPixelFormat,
TgaDecoder_Frame_GetResolution,
TgaDecoder_Frame_CopyPalette,
TgaDecoder_Frame_CopyPixels,
TgaDecoder_Frame_GetMetadataQueryReader,
TgaDecoder_Frame_GetColorContexts,
TgaDecoder_Frame_GetThumbnail
};
HRESULT TgaDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
TgaDecoder *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(TgaDecoder));
if (!This) return E_OUTOFMEMORY;
This->IWICBitmapDecoder_iface.lpVtbl = &TgaDecoder_Vtbl;
This->IWICBitmapFrameDecode_iface.lpVtbl = &TgaDecoder_Frame_Vtbl;
This->ref = 1;
This->initialized = FALSE;
This->stream = NULL;
This->imagebits = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TgaDecoder.lock");
ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
return ret;
}

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,12 @@ typedef unsigned int (__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompres
typedef int (__cdecl typeof(jpeg_finish_decompress))(struct jpeg_decompress_struct *);
typedef void (__cdecl typeof(jpeg_destroy_decompress))(struct jpeg_decompress_struct *);
typedef unsigned char (__cdecl typeof(jpeg_resync_to_restart))(struct jpeg_decompress_struct *, int);
typedef void (__cdecl typeof(jpeg_CreateCompress))(struct jpeg_compress_struct *, int, __typeof_size);
typedef void (__cdecl typeof(jpeg_start_compress))(struct jpeg_compress_struct *, unsigned char);
typedef void (__cdecl typeof(jpeg_destroy_compress))(struct jpeg_compress_struct *);
typedef void (__cdecl typeof(jpeg_finish_compress))(struct jpeg_decompress_struct *);
typedef void (__cdecl typeof(jpeg_set_defaults))(struct jpeg_decompress_struct *);
typedef unsigned int (__cdecl typeof(jpeg_write_scanlines))(struct jpeg_compress_struct *, char **, unsigned int);
typedef void (*png_error_ptr_1)(struct png_struct_def *, const char *);
typedef void (*png_rw_ptr_1)(struct png_struct_def *, unsigned char *, unsigned int);
@ -61,6 +67,7 @@ typedef void (__cdecl typeof(png_read_info))(struct png_struct_def *, struct png
typedef void (__cdecl typeof(png_write_end))(struct png_struct_def *, struct png_info_def *);
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 *thandle_t_1;
typedef int (*TIFFReadWriteProc_1)(thandle_t_1, void *, int);
@ -76,6 +83,13 @@ typedef int (__cdecl typeof(TIFFGetField))(struct tiff *, unsigned int, ...);
typedef int (__cdecl typeof(TIFFReadDirectory))(struct tiff *);
typedef int (__cdecl typeof(TIFFReadEncodedStrip))(struct tiff *, unsigned int, void *, int);
typedef int (__cdecl typeof(TIFFSetDirectory))(struct tiff *, unsigned short);
typedef unsigned int (__cdecl typeof(TIFFCurrentDirOffset))(struct tiff *);
typedef int (__cdecl typeof(TIFFIsByteSwapped))(struct tiff *);
typedef unsigned short (__cdecl typeof(TIFFNumberOfDirectories))(struct tiff *);
typedef long (__cdecl typeof(TIFFReadEncodedTile))(struct tiff *, unsigned long, void *, long);
typedef int (__cdecl typeof(TIFFSetField))(struct tiff *, unsigned long, ...);
typedef int (__cdecl typeof(TIFFWriteDirectory))(struct tiff *);
typedef int (__cdecl typeof(TIFFWriteScanline))(struct tiff *, void *, unsigned long, unsigned short);
#undef __typeof_intptr
#undef __typeof_longptr

View file

@ -49,12 +49,13 @@
#include <stdlib.h>
#include <string.h>
#include "ungif.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "ungif.h"
static void *ungif_alloc( size_t sz )
{
return HeapAlloc( GetProcessHeap(), 0, sz );
@ -158,6 +159,7 @@ MakeMapObject(int ColorCount,
Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == NULL) {
ungif_free(Object);
return NULL;
}
@ -190,7 +192,7 @@ FreeMapObject(ColorMapObject * Object) {
}
static int
AddExtensionBlock(SavedImage * New,
AddExtensionBlock(Extensions *New,
int Len,
const unsigned char ExtData[]) {
@ -208,32 +210,63 @@ AddExtensionBlock(SavedImage * New,
ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
ep->ByteCount=Len;
ep->Bytes = ungif_alloc(ep->ByteCount);
ep->ByteCount=Len + 3;
ep->Bytes = ungif_alloc(ep->ByteCount + 3);
if (ep->Bytes == NULL)
return (GIF_ERROR);
/* Extension Header */
ep->Bytes[0] = 0x21;
ep->Bytes[1] = New->Function;
ep->Bytes[2] = Len;
if (ExtData) {
memcpy(ep->Bytes, ExtData, Len);
memcpy(ep->Bytes + 3, ExtData, Len);
ep->Function = New->Function;
}
return (GIF_OK);
}
static void
FreeExtension(SavedImage * Image)
static int
AppendExtensionBlock(Extensions *New,
int Len,
const unsigned char ExtData[])
{
ExtensionBlock *ep;
if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
if (New->ExtensionBlocks == NULL)
return (GIF_ERROR);
ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1];
ep->Bytes = ungif_realloc(ep->Bytes, ep->ByteCount + Len + 1);
if (ep->Bytes == NULL)
return (GIF_ERROR);
ep->Bytes[ep->ByteCount] = Len;
if (ExtData)
memcpy(ep->Bytes + ep->ByteCount + 1, ExtData, Len);
ep->ByteCount += Len + 1;
return (GIF_OK);
}
static void
FreeExtension(Extensions *Extensions)
{
ExtensionBlock *ep;
if ((Extensions == NULL) || (Extensions->ExtensionBlocks == NULL)) {
return;
}
for (ep = Image->ExtensionBlocks;
ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
for (ep = Extensions->ExtensionBlocks;
ep < (Extensions->ExtensionBlocks + Extensions->ExtensionBlockCount); ep++)
ungif_free(ep->Bytes);
ungif_free(Image->ExtensionBlocks);
Image->ExtensionBlocks = NULL;
ungif_free(Extensions->ExtensionBlocks);
Extensions->ExtensionBlocks = NULL;
}
/******************************************************************************
@ -257,8 +290,8 @@ FreeSavedImages(GifFileType * GifFile) {
ungif_free(sp->RasterBits);
if (sp->ExtensionBlocks)
FreeExtension(sp);
if (sp->Extensions.ExtensionBlocks)
FreeExtension(&sp->Extensions);
}
ungif_free(GifFile->SavedImages);
GifFile->SavedImages=NULL;
@ -271,7 +304,7 @@ FreeSavedImages(GifFileType * GifFile) {
static int
DGifGetScreenDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
int i, BitsPerPixel, SortFlag;
GifByteType Buf[3];
/* Put the screen descriptor into the file: */
@ -283,8 +316,10 @@ DGifGetScreenDesc(GifFileType * GifFile) {
return GIF_ERROR;
}
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
SortFlag = (Buf[0] & 0x08) != 0;
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
GifFile->SAspectRatio = Buf[2];
if (Buf[0] & 0x80) { /* Do we have global color map? */
GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
@ -293,6 +328,7 @@ DGifGetScreenDesc(GifFileType * GifFile) {
}
/* Get the global color map: */
GifFile->SColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->SColorMap);
@ -351,7 +387,7 @@ DGifGetRecordType(GifFileType * GifFile,
static int
DGifGetImageDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
int i, BitsPerPixel, SortFlag;
GifByteType Buf[3];
GifFilePrivateType *Private = GifFile->Private;
SavedImage *sp;
@ -365,6 +401,7 @@ DGifGetImageDesc(GifFileType * GifFile) {
return GIF_ERROR;
}
BitsPerPixel = (Buf[0] & 0x07) + 1;
SortFlag = (Buf[0] & 0x20) != 0;
GifFile->Image.Interlace = (Buf[0] & 0x40);
if (Buf[0] & 0x80) { /* Does this image have local color map? */
@ -379,6 +416,7 @@ DGifGetImageDesc(GifFileType * GifFile) {
}
/* Get the image local color map: */
GifFile->Image.ColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->Image.ColorMap);
@ -415,10 +453,11 @@ DGifGetImageDesc(GifFileType * GifFile) {
if (sp->ImageDesc.ColorMap == NULL) {
return GIF_ERROR;
}
sp->ImageDesc.ColorMap->SortFlag = GifFile->Image.ColorMap->SortFlag;
}
sp->RasterBits = NULL;
sp->ExtensionBlockCount = 0;
sp->ExtensionBlocks = NULL;
sp->Extensions.ExtensionBlockCount = 0;
sp->Extensions.ExtensionBlocks = NULL;
GifFile->ImageCount++;
@ -838,7 +877,7 @@ DGifSlurp(GifFileType * GifFile) {
GifRecordType RecordType;
SavedImage *sp;
GifByteType *ExtData;
SavedImage temp_save;
Extensions temp_save;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
@ -863,8 +902,8 @@ DGifSlurp(GifFileType * GifFile) {
GIF_ERROR)
return (GIF_ERROR);
if (temp_save.ExtensionBlocks) {
sp->ExtensionBlocks = temp_save.ExtensionBlocks;
sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
sp->Extensions.ExtensionBlocks = temp_save.ExtensionBlocks;
sp->Extensions.ExtensionBlockCount = temp_save.ExtensionBlockCount;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
@ -872,26 +911,52 @@ DGifSlurp(GifFileType * GifFile) {
/* FIXME: The following is wrong. It is left in only for
* backwards compatibility. Someday it should go away. Use
* the sp->ExtensionBlocks->Function variable instead. */
sp->Function = sp->ExtensionBlocks[0].Function;
sp->Extensions.Function = sp->Extensions.ExtensionBlocks[0].Function;
}
break;
case EXTENSION_RECORD_TYPE:
if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
GIF_ERROR)
return (GIF_ERROR);
while (ExtData != NULL) {
{
int Function;
Extensions *Extensions;
/* Create an extension block with our data */
if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
if (DGifGetExtension(GifFile, &Function, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
if (GifFile->ImageCount || Function == GRAPHICS_EXT_FUNC_CODE)
Extensions = &temp_save;
else
Extensions = &GifFile->Extensions;
Extensions->Function = Function;
/* Create an extension block with our data */
if (AddExtensionBlock(Extensions, ExtData[0], &ExtData[1]) == GIF_ERROR)
return (GIF_ERROR);
while (ExtData != NULL) {
int Len;
GifByteType *Data;
if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
temp_save.Function = 0;
if (ExtData)
{
Len = ExtData[0];
Data = &ExtData[1];
}
else
{
Len = 0;
Data = NULL;
}
if (AppendExtensionBlock(Extensions, Len, Data) == GIF_ERROR)
return (GIF_ERROR);
}
break;
}
case TERMINATE_RECORD_TYPE:
break;
@ -996,6 +1061,8 @@ DGifCloseFile(GifFileType * GifFile) {
GifFile->SavedImages = NULL;
}
FreeExtension(&GifFile->Extensions);
ungif_free(GifFile);
return GIF_OK;

View file

@ -88,6 +88,7 @@ typedef struct GifColorType {
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
int SortFlag;
GifColorType *Colors;
} ColorMapObject;
@ -97,11 +98,26 @@ typedef struct GifImageDesc {
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
/* This is the in-core version of an extension record */
typedef struct {
int Function; /* Holds the type of the Extension block. */
int ByteCount;
char *Bytes;
} ExtensionBlock;
typedef struct {
int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
int ExtensionBlockCount;
ExtensionBlock *ExtensionBlocks;
} Extensions;
typedef struct GifFileType {
GifWord SWidth, SHeight, /* Screen dimensions. */
SColorResolution, /* How many colors can we generate? */
SBackGroundColor; /* I hope you understand this one... */
SBackGroundColor, /* I hope you understand this one... */
SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */
ColorMapObject *SColorMap; /* NULL if not exists. */
Extensions Extensions;
int ImageCount; /* Number of current image */
GifImageDesc Image; /* Block describing current image */
struct SavedImage *SavedImages; /* Use this to accumulate file state */
@ -128,9 +144,9 @@ typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
/* public interface to ungif.c */
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc);
int DGifCloseFile(GifFileType * GifFile);
int DGifSlurp(GifFileType * GifFile) DECLSPEC_HIDDEN;
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc) DECLSPEC_HIDDEN;
int DGifCloseFile(GifFileType * GifFile) DECLSPEC_HIDDEN;
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
@ -150,20 +166,11 @@ int DGifCloseFile(GifFileType * GifFile);
* Support for the in-core structures allocation (slurp mode).
*****************************************************************************/
/* This is the in-core version of an extension record */
typedef struct {
int ByteCount;
char *Bytes;
int Function; /* Holds the type of the Extension block. */
} ExtensionBlock;
/* This holds an image header, its unpacked raster bits, and extensions */
typedef struct SavedImage {
GifImageDesc ImageDesc;
unsigned char *RasterBits;
int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
int ExtensionBlockCount;
ExtensionBlock *ExtensionBlocks;
Extensions Extensions;
} SavedImage;
#endif /* _UNGIF_H_ */

View file

@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
1 WINE_REGISTRY windowscodecs_wincodec.rgs
#define WINE_FILEDESCRIPTION_STR "Wine Windows Codecs Library"
#define WINE_FILENAME_STR "windowscodecs.dll"
#define WINE_FILEVERSION 6,0,6001,170099

View file

@ -19,28 +19,87 @@
#ifndef WINCODECS_PRIVATE_H
#define WINCODECS_PRIVATE_H
extern HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
DEFINE_GUID(CLSID_WineTgaDecoder, 0xb11fc79a,0x67cc,0x43e6,0xa9,0xce,0xe3,0xd5,0x49,0x45,0xd3,0x04);
extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator);
extern HRESULT PaletteImpl_Create(IWICPalette **palette);
extern HRESULT StreamImpl_Create(IWICStream **stream);
DEFINE_GUID(CLSID_WICIcnsEncoder, 0x312fb6f1,0xb767,0x409d,0x8a,0x6d,0x0f,0xc1,0x54,0xd4,0xf0,0x5c);
DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22);
DEFINE_GUID(GUID_VendorWine, 0xddf46da1,0x7dc1,0x404e,0x98,0xf2,0xef,0xa4,0x8d,0xfc,0x95,0x0a);
extern HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT ComponentFactory_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT PngDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT PngEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT DibDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT JpegDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT JpegEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT TiffDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT TiffEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT TgaDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN;
extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN;
extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) DECLSPEC_HIDDEN;
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 copy_pixels(UINT bpp, const BYTE *srcbuffer,
UINT srcwidth, UINT srcheight, INT srcstride,
const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer);
const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) DECLSPEC_HIDDEN;
extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2);
extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo);
extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown);
extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN;
extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN;
extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN;
typedef struct BmpDecoder BmpDecoder;
extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder) DECLSPEC_HIDDEN;
extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder) DECLSPEC_HIDDEN;
extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) DECLSPEC_HIDDEN;
typedef struct _MetadataItem
{
PROPVARIANT schema;
PROPVARIANT id;
PROPVARIANT value;
} MetadataItem;
typedef struct _MetadataHandlerVtbl
{
int is_writer;
const CLSID *clsid;
HRESULT (*fnLoad)(IStream *stream, const GUID *preferred_vendor,
DWORD persist_options, MetadataItem **items, DWORD *item_count);
HRESULT (*fnSave)(IStream *stream, DWORD persist_options,
const MetadataItem *items, DWORD item_count);
HRESULT (*fnGetSizeMax)(const MetadataItem *items, DWORD item_count,
ULARGE_INTEGER *size);
} MetadataHandlerVtbl;
extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT PngTextReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
extern HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
extern HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
#endif /* WINCODECS_PRIVATE_H */

View file

@ -1,112 +1,113 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()
@ stub IEnumString_Next_WIC_Proxy
@ stub IEnumString_Reset_WIC_Proxy
@ stub IPropertyBag2_Write_Proxy
@ stub IWICBitmapClipper_Initialize_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportAnimation_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportLossless_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportMultiframe_Proxy
@ stub IWICBitmapCodecInfo_GetContainerFormat_Proxy
@ stub IWICBitmapCodecInfo_GetDeviceManufacturer_Proxy
@ stub IWICBitmapCodecInfo_GetDeviceModels_Proxy
@ stub IWICBitmapCodecInfo_GetFileExtensions_Proxy
@ stub IWICBitmapCodecInfo_GetMimeTypes_Proxy
@ stub IWICBitmapDecoder_CopyPalette_Proxy
@ stub IWICBitmapDecoder_GetColorContexts_Proxy
@ stub IWICBitmapDecoder_GetDecoderInfo_Proxy
@ stub IWICBitmapDecoder_GetFrameCount_Proxy
@ stub IWICBitmapDecoder_GetFrame_Proxy
@ stub IWICBitmapDecoder_GetMetadataQueryReader_Proxy
@ stub IWICBitmapDecoder_GetPreview_Proxy
@ stub IWICBitmapDecoder_GetThumbnail_Proxy
@ stub IWICBitmapEncoder_Commit_Proxy
@ stub IWICBitmapEncoder_CreateNewFrame_Proxy
@ stub IWICBitmapEncoder_GetEncoderInfo_Proxy
@ stub IWICBitmapEncoder_GetMetadataQueryWriter_Proxy
@ stub IWICBitmapEncoder_Initialize_Proxy
@ stub IWICBitmapEncoder_SetPalette_Proxy
@ stub IWICBitmapEncoder_SetThumbnail_Proxy
@ stub IWICBitmapFlipRotator_Initialize_Proxy
@ stub IWICBitmapFrameDecode_GetColorContexts_Proxy
@ stub IWICBitmapFrameDecode_GetMetadataQueryReader_Proxy
@ stub IWICBitmapFrameDecode_GetThumbnail_Proxy
@ stub IWICBitmapFrameEncode_Commit_Proxy
@ stub IWICBitmapFrameEncode_GetMetadataQueryWriter_Proxy
@ stub IWICBitmapFrameEncode_Initialize_Proxy
@ stub IWICBitmapFrameEncode_SetColorContexts_Proxy
@ stub IWICBitmapFrameEncode_SetResolution_Proxy
@ stub IWICBitmapFrameEncode_SetSize_Proxy
@ stub IWICBitmapFrameEncode_SetThumbnail_Proxy
@ stub IWICBitmapFrameEncode_WriteSource_Proxy
@ stub IWICBitmapLock_GetDataPointer_STA_Proxy
@ stub IWICBitmapLock_GetStride_Proxy
@ stub IWICBitmapScaler_Initialize_Proxy
@ stub IWICBitmapSource_CopyPalette_Proxy
@ stub IWICBitmapSource_CopyPixels_Proxy
@ stub IWICBitmapSource_GetPixelFormat_Proxy
@ stub IWICBitmapSource_GetResolution_Proxy
@ stub IWICBitmapSource_GetSize_Proxy
@ stub IWICBitmap_Lock_Proxy
@ stub IWICBitmap_SetPalette_Proxy
@ stub IWICBitmap_SetResolution_Proxy
@ stub IWICColorContext_InitializeFromMemory_Proxy
@ stub IWICComponentFactory_CreateMetadataWriterFromReader_Proxy
@ stub IWICComponentFactory_CreateQueryWriterFromBlockWriter_Proxy
@ stub IWICComponentInfo_GetAuthor_Proxy
@ stub IWICComponentInfo_GetCLSID_Proxy
@ stub IWICComponentInfo_GetFriendlyName_Proxy
@ stub IWICComponentInfo_GetSpecVersion_Proxy
@ stub IWICComponentInfo_GetVersion_Proxy
@ stub IWICFastMetadataEncoder_Commit_Proxy
@ stub IWICFastMetadataEncoder_GetMetadataQueryWriter_Proxy
@ stub IWICFormatConverter_Initialize_Proxy
@ stub IWICImagingFactory_CreateBitmapClipper_Proxy
@ stub IWICImagingFactory_CreateBitmapFlipRotator_Proxy
@ stub IWICImagingFactory_CreateBitmapFromHBITMAP_Proxy
@ stub IWICImagingFactory_CreateBitmapFromHICON_Proxy
@ stub IWICImagingFactory_CreateBitmapFromMemory_Proxy
@ stub IWICImagingFactory_CreateBitmapFromSource_Proxy
@ stub IWICImagingFactory_CreateBitmapScaler_Proxy
@ stub IWICImagingFactory_CreateBitmap_Proxy
@ stub IWICImagingFactory_CreateComponentInfo_Proxy
@ stub IWICImagingFactory_CreateDecoderFromFileHandle_Proxy
@ stub IWICImagingFactory_CreateDecoderFromFilename_Proxy
@ stub IWICImagingFactory_CreateDecoderFromStream_Proxy
@ stub IWICImagingFactory_CreateEncoder_Proxy
@ stub IWICImagingFactory_CreateFastMetadataEncoderFromDecoder_Proxy
@ stub IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode_Proxy
@ stub IWICImagingFactory_CreateFormatConverter_Proxy
@ stub IWICImagingFactory_CreatePalette_Proxy
@ stub IWICImagingFactory_CreateQueryWriterFromReader_Proxy
@ stub IWICImagingFactory_CreateQueryWriter_Proxy
@ stub IWICImagingFactory_CreateStream_Proxy
@ stub IWICMetadataBlockReader_GetCount_Proxy
@ stub IWICMetadataBlockReader_GetReaderByIndex_Proxy
@ stub IWICMetadataQueryReader_GetContainerFormat_Proxy
@ stub IWICMetadataQueryReader_GetEnumerator_Proxy
@ stub IWICMetadataQueryReader_GetLocation_Proxy
@ stub IWICMetadataQueryReader_GetMetadataByName_Proxy
@ stub IWICMetadataQueryWriter_RemoveMetadataByName_Proxy
@ stub IWICMetadataQueryWriter_SetMetadataByName_Proxy
@ stub IWICPalette_GetColorCount_Proxy
@ stub IWICPalette_GetColors_Proxy
@ stub IWICPalette_GetType_Proxy
@ stub IWICPalette_HasAlpha_Proxy
@ stub IWICPalette_InitializeCustom_Proxy
@ stub IWICPalette_InitializeFromBitmap_Proxy
@ stub IWICPalette_InitializeFromPalette_Proxy
@ stub IWICPalette_InitializePredefined_Proxy
@ stub IWICPixelFormatInfo_GetBitsPerPixel_Proxy
@ stub IWICPixelFormatInfo_GetChannelCount_Proxy
@ stub IWICPixelFormatInfo_GetChannelMask_Proxy
@ stub IWICStream_InitializeFromIStream_Proxy
@ stub IWICStream_InitializeFromMemory_Proxy
@ stdcall IWICBitmapClipper_Initialize_Proxy(ptr ptr ptr) IWICBitmapClipper_Initialize_Proxy_W
@ stdcall IWICBitmapCodecInfo_DoesSupportAnimation_Proxy(ptr ptr) IWICBitmapCodecInfo_DoesSupportAnimation_Proxy_W
@ stdcall IWICBitmapCodecInfo_DoesSupportLossless_Proxy(ptr ptr) IWICBitmapCodecInfo_DoesSupportLossless_Proxy_W
@ stdcall IWICBitmapCodecInfo_DoesSupportMultiframe_Proxy(ptr ptr) IWICBitmapCodecInfo_DoesSupportMultiframe_Proxy_W
@ stdcall IWICBitmapCodecInfo_GetContainerFormat_Proxy(ptr ptr) IWICBitmapCodecInfo_GetContainerFormat_Proxy_W
@ stdcall IWICBitmapCodecInfo_GetDeviceManufacturer_Proxy(ptr long ptr ptr) IWICBitmapCodecInfo_GetDeviceManufacturer_Proxy_W
@ stdcall IWICBitmapCodecInfo_GetDeviceModels_Proxy(ptr long ptr ptr) IWICBitmapCodecInfo_GetDeviceModels_Proxy_W
@ stdcall IWICBitmapCodecInfo_GetFileExtensions_Proxy(ptr long ptr ptr) IWICBitmapCodecInfo_GetFileExtensions_Proxy_W
@ stdcall IWICBitmapCodecInfo_GetMimeTypes_Proxy(ptr long ptr ptr) IWICBitmapCodecInfo_GetMimeTypes_Proxy_W
@ stdcall IWICBitmapDecoder_CopyPalette_Proxy(ptr ptr) IWICBitmapDecoder_CopyPalette_Proxy_W
@ stdcall IWICBitmapDecoder_GetColorContexts_Proxy(ptr long ptr ptr) IWICBitmapDecoder_GetColorContexts_Proxy_W
@ stdcall IWICBitmapDecoder_GetDecoderInfo_Proxy(ptr ptr) IWICBitmapDecoder_GetDecoderInfo_Proxy_W
@ stdcall IWICBitmapDecoder_GetFrameCount_Proxy(ptr ptr) IWICBitmapDecoder_GetFrameCount_Proxy_W
@ stdcall IWICBitmapDecoder_GetFrame_Proxy(ptr long ptr) IWICBitmapDecoder_GetFrame_Proxy_W
@ stdcall IWICBitmapDecoder_GetMetadataQueryReader_Proxy(ptr ptr) IWICBitmapDecoder_GetMetadataQueryReader_Proxy_W
@ stdcall IWICBitmapDecoder_GetPreview_Proxy(ptr ptr) IWICBitmapDecoder_GetPreview_Proxy_W
@ stdcall IWICBitmapDecoder_GetThumbnail_Proxy(ptr ptr) IWICBitmapDecoder_GetThumbnail_Proxy_W
@ stdcall IWICBitmapEncoder_Commit_Proxy(ptr) IWICBitmapEncoder_Commit_Proxy_W
@ stdcall IWICBitmapEncoder_CreateNewFrame_Proxy(ptr ptr ptr) IWICBitmapEncoder_CreateNewFrame_Proxy_W
@ stdcall IWICBitmapEncoder_GetEncoderInfo_Proxy(ptr ptr) IWICBitmapEncoder_GetEncoderInfo_Proxy_W
@ stdcall IWICBitmapEncoder_GetMetadataQueryWriter_Proxy(ptr ptr) IWICBitmapEncoder_GetMetadataQueryWriter_Proxy_W
@ stdcall IWICBitmapEncoder_Initialize_Proxy(ptr ptr long) IWICBitmapEncoder_Initialize_Proxy_W
@ stdcall IWICBitmapEncoder_SetPalette_Proxy(ptr ptr) IWICBitmapEncoder_SetPalette_Proxy_W
@ stdcall IWICBitmapEncoder_SetThumbnail_Proxy(ptr ptr) IWICBitmapEncoder_SetThumbnail_Proxy_W
@ stdcall IWICBitmapFlipRotator_Initialize_Proxy(ptr ptr long) IWICBitmapFlipRotator_Initialize_Proxy_W
@ stdcall IWICBitmapFrameDecode_GetColorContexts_Proxy(ptr long ptr ptr) IWICBitmapFrameDecode_GetColorContexts_Proxy_W
@ stdcall IWICBitmapFrameDecode_GetMetadataQueryReader_Proxy(ptr ptr) IWICBitmapFrameDecode_GetMetadataQueryReader_Proxy_W
@ stdcall IWICBitmapFrameDecode_GetThumbnail_Proxy(ptr ptr) IWICBitmapFrameDecode_GetThumbnail_Proxy_W
@ stdcall IWICBitmapFrameEncode_Commit_Proxy(ptr) IWICBitmapFrameEncode_Commit_Proxy_W
@ stdcall IWICBitmapFrameEncode_GetMetadataQueryWriter_Proxy(ptr ptr) IWICBitmapFrameEncode_GetMetadataQueryWriter_Proxy_W
@ stdcall IWICBitmapFrameEncode_Initialize_Proxy(ptr ptr) IWICBitmapFrameEncode_Initialize_Proxy_W
@ stdcall IWICBitmapFrameEncode_SetColorContexts_Proxy(ptr long ptr) IWICBitmapFrameEncode_SetColorContexts_Proxy_W
@ stdcall IWICBitmapFrameEncode_SetResolution_Proxy(ptr double double) IWICBitmapFrameEncode_SetResolution_Proxy_W
@ stdcall IWICBitmapFrameEncode_SetSize_Proxy(ptr long long) IWICBitmapFrameEncode_SetSize_Proxy_W
@ stdcall IWICBitmapFrameEncode_SetThumbnail_Proxy(ptr ptr) IWICBitmapFrameEncode_SetThumbnail_Proxy_W
@ stdcall IWICBitmapFrameEncode_WriteSource_Proxy(ptr ptr ptr) IWICBitmapFrameEncode_WriteSource_Proxy_W
@ stdcall IWICBitmapLock_GetDataPointer_STA_Proxy(ptr ptr ptr) IWICBitmapLock_GetDataPointer_Proxy_W
@ stdcall IWICBitmapLock_GetStride_Proxy(ptr ptr) IWICBitmapLock_GetStride_Proxy_W
@ stdcall IWICBitmapScaler_Initialize_Proxy(ptr ptr long long long) IWICBitmapScaler_Initialize_Proxy_W
@ stdcall IWICBitmapSource_CopyPalette_Proxy(ptr ptr) IWICBitmapSource_CopyPalette_Proxy_W
@ stdcall IWICBitmapSource_CopyPixels_Proxy(ptr ptr long long ptr) IWICBitmapSource_CopyPixels_Proxy_W
@ stdcall IWICBitmapSource_GetPixelFormat_Proxy(ptr ptr) IWICBitmapSource_GetPixelFormat_Proxy_W
@ stdcall IWICBitmapSource_GetResolution_Proxy(ptr ptr ptr) IWICBitmapSource_GetResolution_Proxy_W
@ stdcall IWICBitmapSource_GetSize_Proxy(ptr ptr ptr) IWICBitmapSource_GetSize_Proxy_W
@ stdcall IWICBitmap_Lock_Proxy(ptr ptr long ptr) IWICBitmap_Lock_Proxy_W
@ stdcall IWICBitmap_SetPalette_Proxy(ptr ptr) IWICBitmap_SetPalette_Proxy_W
@ stdcall IWICBitmap_SetResolution_Proxy(ptr double double) IWICBitmap_SetResolution_Proxy_W
@ stdcall IWICColorContext_InitializeFromMemory_Proxy(ptr ptr long) IWICColorContext_InitializeFromMemory_Proxy_W
@ stdcall IWICComponentFactory_CreateMetadataWriterFromReader_Proxy(ptr ptr ptr ptr) IWICComponentFactory_CreateMetadataWriterFromReader_Proxy_W
@ stdcall IWICComponentFactory_CreateQueryWriterFromBlockWriter_Proxy(ptr ptr ptr) IWICComponentFactory_CreateQueryWriterFromBlockWriter_Proxy_W
@ stdcall IWICComponentInfo_GetAuthor_Proxy(ptr long ptr ptr) IWICComponentInfo_GetAuthor_Proxy_W
@ stdcall IWICComponentInfo_GetCLSID_Proxy(ptr ptr) IWICComponentInfo_GetCLSID_Proxy_W
@ stdcall IWICComponentInfo_GetFriendlyName_Proxy(ptr long ptr ptr) IWICComponentInfo_GetFriendlyName_Proxy_W
@ stdcall IWICComponentInfo_GetSpecVersion_Proxy(ptr long ptr ptr) IWICComponentInfo_GetSpecVersion_Proxy_W
@ stdcall IWICComponentInfo_GetVersion_Proxy(ptr long ptr ptr) IWICComponentInfo_GetVersion_Proxy_W
@ stdcall IWICFastMetadataEncoder_Commit_Proxy(ptr) IWICFastMetadataEncoder_Commit_Proxy_W
@ stdcall IWICFastMetadataEncoder_GetMetadataQueryWriter_Proxy(ptr ptr) IWICFastMetadataEncoder_GetMetadataQueryWriter_Proxy_W
@ stdcall IWICFormatConverter_Initialize_Proxy(ptr ptr ptr long ptr double long) IWICFormatConverter_Initialize_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapClipper_Proxy(ptr ptr) IWICImagingFactory_CreateBitmapClipper_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapFlipRotator_Proxy(ptr ptr) IWICImagingFactory_CreateBitmapFlipRotator_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapFromHBITMAP_Proxy(ptr ptr ptr long ptr) IWICImagingFactory_CreateBitmapFromHBITMAP_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapFromHICON_Proxy(ptr ptr ptr) IWICImagingFactory_CreateBitmapFromHICON_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapFromMemory_Proxy(ptr long long ptr long long ptr ptr) IWICImagingFactory_CreateBitmapFromMemory_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapFromSource_Proxy(ptr ptr long ptr) IWICImagingFactory_CreateBitmapFromSource_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmapScaler_Proxy(ptr ptr) IWICImagingFactory_CreateBitmapScaler_Proxy_W
@ stdcall IWICImagingFactory_CreateBitmap_Proxy(ptr long long ptr long ptr) IWICImagingFactory_CreateBitmap_Proxy_W
@ stdcall IWICImagingFactory_CreateComponentInfo_Proxy(ptr ptr ptr) IWICImagingFactory_CreateComponentInfo_Proxy_W
@ stdcall IWICImagingFactory_CreateDecoderFromFileHandle_Proxy(ptr ptr ptr long ptr) IWICImagingFactory_CreateDecoderFromFileHandle_Proxy_W
@ stdcall IWICImagingFactory_CreateDecoderFromFilename_Proxy(ptr wstr ptr long long ptr) IWICImagingFactory_CreateDecoderFromFilename_Proxy_W
@ stdcall IWICImagingFactory_CreateDecoderFromStream_Proxy(ptr ptr ptr long ptr) IWICImagingFactory_CreateDecoderFromStream_Proxy_W
@ stdcall IWICImagingFactory_CreateEncoder_Proxy(ptr ptr ptr ptr) IWICImagingFactory_CreateEncoder_Proxy_W
@ stdcall IWICImagingFactory_CreateFastMetadataEncoderFromDecoder_Proxy(ptr ptr ptr) IWICImagingFactory_CreateFastMetadataEncoderFromDecoder_Proxy_W
@ stdcall IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode_Proxy(ptr ptr ptr) IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode_Proxy_W
@ stdcall IWICImagingFactory_CreateFormatConverter_Proxy(ptr ptr) IWICImagingFactory_CreateFormatConverter_Proxy_W
@ stdcall IWICImagingFactory_CreatePalette_Proxy(ptr ptr) IWICImagingFactory_CreatePalette_Proxy_W
@ stdcall IWICImagingFactory_CreateQueryWriterFromReader_Proxy(ptr ptr ptr ptr) IWICImagingFactory_CreateQueryWriterFromReader_Proxy_W
@ stdcall IWICImagingFactory_CreateQueryWriter_Proxy(ptr ptr ptr ptr) IWICImagingFactory_CreateQueryWriter_Proxy_W
@ stdcall IWICImagingFactory_CreateStream_Proxy(ptr ptr) IWICImagingFactory_CreateStream_Proxy_W
@ stdcall IWICMetadataBlockReader_GetCount_Proxy(ptr ptr) IWICMetadataBlockReader_GetCount_Proxy_W
@ stdcall IWICMetadataBlockReader_GetReaderByIndex_Proxy(ptr long ptr) IWICMetadataBlockReader_GetReaderByIndex_Proxy_W
@ stdcall IWICMetadataQueryReader_GetContainerFormat_Proxy(ptr ptr) IWICMetadataQueryReader_GetContainerFormat_Proxy_W
@ stdcall IWICMetadataQueryReader_GetEnumerator_Proxy(ptr ptr) IWICMetadataQueryReader_GetEnumerator_Proxy_W
@ stdcall IWICMetadataQueryReader_GetLocation_Proxy(ptr long ptr ptr) IWICMetadataQueryReader_GetLocation_Proxy_W
@ stdcall IWICMetadataQueryReader_GetMetadataByName_Proxy(ptr wstr ptr) IWICMetadataQueryReader_GetMetadataByName_Proxy_W
@ stdcall IWICMetadataQueryWriter_RemoveMetadataByName_Proxy(ptr wstr) IWICMetadataQueryWriter_RemoveMetadataByName_Proxy_W
@ stdcall IWICMetadataQueryWriter_SetMetadataByName_Proxy(ptr wstr ptr) IWICMetadataQueryWriter_SetMetadataByName_Proxy_W
@ stdcall IWICPalette_GetColorCount_Proxy(ptr ptr) IWICPalette_GetColorCount_Proxy_W
@ stdcall IWICPalette_GetColors_Proxy(ptr long ptr ptr) IWICPalette_GetColors_Proxy_W
@ stdcall IWICPalette_GetType_Proxy(ptr ptr) IWICPalette_GetType_Proxy_W
@ stdcall IWICPalette_HasAlpha_Proxy(ptr ptr) IWICPalette_HasAlpha_Proxy_W
@ stdcall IWICPalette_InitializeCustom_Proxy(ptr ptr long) IWICPalette_InitializeCustom_Proxy_W
@ stdcall IWICPalette_InitializeFromBitmap_Proxy(ptr ptr long long) IWICPalette_InitializeFromBitmap_Proxy_W
@ stdcall IWICPalette_InitializeFromPalette_Proxy(ptr ptr) IWICPalette_InitializeFromPalette_Proxy_W
@ stdcall IWICPalette_InitializePredefined_Proxy(ptr long long) IWICPalette_InitializePredefined_Proxy_W
@ stdcall IWICPixelFormatInfo_GetBitsPerPixel_Proxy(ptr ptr)
@ stdcall IWICPixelFormatInfo_GetChannelCount_Proxy(ptr ptr)
@ stdcall IWICPixelFormatInfo_GetChannelMask_Proxy(ptr long long ptr ptr)
@ stdcall IWICStream_InitializeFromIStream_Proxy(ptr ptr) IWICStream_InitializeFromIStream_Proxy_W
@ stdcall IWICStream_InitializeFromMemory_Proxy(ptr ptr long) IWICStream_InitializeFromMemory_Proxy_W
@ stdcall WICConvertBitmapSource(ptr ptr ptr)
@ stub WICCreateBitmapFromSection
@ stub WICCreateColorContext_Proxy
@ stub WICCreateImagingFactory_Proxy
@ stdcall WICCreateColorContext_Proxy(ptr ptr)
@ stdcall WICCreateImagingFactory_Proxy(long ptr)
@ stub WICGetMetadataContentSize
@ stub WICMapGuidToShortName
@ stub WICMapSchemaToName

View file

@ -0,0 +1,179 @@
/*
* Copyright 2010 Damjan Jovanovic
*
* 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
*/
#include "wincodec.idl"
[
threading(both),
uuid(00000301-a8f2-4877-ba0a-fd2b6645fb94) /* IWICFormatConverter */
]
coclass PSFactoryBuffer { interface IFactoryBuffer; }
[
helpstring("WIC Imaging Factory"),
threading(both),
uuid(cacaf262-9370-4615-a13b-9f5539da4c0a)
]
coclass WICImagingFactory { interface IWICImagingFactory; }
[
helpstring("WIC BMP Decoder"),
threading(both),
uuid(6b462062-7cbf-400d-9fdb-813dd10f2778)
]
coclass WICBmpDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC PNG Decoder"),
threading(both),
uuid(389ea17b-5078-4cde-b6ef-25c15175c751)
]
coclass WICPngDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC PNG Encoder"),
threading(both),
uuid(27949969-876a-41d7-9447-568f6a35a4dc)
]
coclass WICPngEncoder { interface IWICBitmapEncoder; }
[
helpstring("WIC BMP Encoder"),
threading(apartment),
uuid(69be8bb4-d66d-47c8-865a-ed1589433782)
]
coclass WICBmpEncoder { interface IWICBitmapEncoder; }
[
helpstring("WIC GIF Decoder"),
threading(both),
uuid(381dda3c-9ce9-4834-a23e-1f98f8fc52be)
]
coclass WICGifDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC ICO Decoder"),
threading(both),
uuid(c61bfcdf-2e0f-4aad-a8d7-e06bafebcdfe)
]
coclass WICIcoDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC JPEG Decoder"),
threading(both),
uuid(9456a480-e88b-43ea-9e73-0b2d9b71b1ca)
]
coclass WICJpegDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC JPEG Encoder"),
threading(both),
uuid(1a34f5c1-4a5a-46dc-b644-1f4567e7a676)
]
coclass WICJpegEncoder { interface IWICBitmapEncoder; }
[
helpstring("WIC TIFF Decoder"),
threading(both),
uuid(b54e85d9-fe23-499f-8b88-6acea713752b)
]
coclass WICTiffDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC TIFF Encoder"),
threading(both),
uuid(0131be10-2001-4c5f-a9b0-cc88fab64ce8)
]
coclass WICTiffEncoder { interface IWICBitmapEncoder; }
[
helpstring("WIC ICNS Encoder"),
threading(both),
uuid(312fb6f1-b767-409d-8a6d-0fc154d4f05c)
]
coclass WICIcnsEncoder { interface IWICBitmapEncoder; }
[
helpstring("WIC Default Format Converter"),
threading(both),
uuid(1a3f11dc-b514-4b17-8c5f-2154513852f1)
]
coclass WICDefaultFormatConverter { interface IWICFormatConverter; }
[
helpstring("WIC TGA Decoder"),
threading(both),
uuid(b11fc79a-67cc-43e6-a9ce-e3d54945d304)
]
coclass WineTgaDecoder { interface IWICBitmapDecoder; }
[
helpstring("WIC Unknown Metadata Reader"),
threading(both),
uuid(699745c2-5066-4b82-a8e3-d40478dbec8c)
]
coclass WICUnknownMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC Ifd Metadata Reader"),
threading(both),
uuid(8f914656-9d0a-4eb2-9019-0bf96d8a9ee6)
]
coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; }
[
helpstring("WIC Png tEXt Metadata Reader"),
threading(both),
uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7)
]
coclass WICPngTextMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC LSD Metadata Reader"),
threading(both),
uuid(41070793-59e4-479a-a1f7-954adc2ef5fc)
]
coclass WICLSDMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC IMD Metadata Reader"),
threading(both),
uuid(7447a267-0015-42c8-a8f1-fb3b94c68361)
]
coclass WICIMDMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC GCE Metadata Reader"),
threading(both),
uuid(b92e345d-f52d-41f3-b562-081bc772e3b9)
]
coclass WICGCEMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC Application Extension Reader"),
threading(both),
uuid(1767b93a-b021-44ea-920f-863c11f4f768)
]
coclass WICAPEMetadataReader { interface IWICMetadataReader; }
[
helpstring("WIC Comment Extension Reader"),
threading(both),
uuid(32557d3b-69dc-4f95-836e-f5972b2f6159)
]
coclass WICGifCommentMetadataReader { interface IWICMetadataReader; }

View file

@ -0,0 +1,231 @@
HKCR
{
NoRemove Interface
{
'{3C613A02-34B2-44EA-9A7C-45AEA9C6FD6D}' = s 'IWICColorContext'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000120-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmapSource'
{
NumMethods = s 8
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000123-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmapLock'
{
NumMethods = s 7
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{5009834F-2D6A-41CE-9E1B-17C5AFF7A782}' = s 'IWICBitmapFlipRotator'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000121-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmap'
{
NumMethods = s 11
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000040-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICPalette'
{
NumMethods = s 13
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{23BC3F0A-698B-4357-886B-F24D50671334}' = s 'IWICComponentInfo'
{
NumMethods = s 11
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{30989668-E1C9-4597-B395-458EEDB808DF}' = s 'IWICMetadataQueryReader'
{
NumMethods = s 7
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{A721791A-0DEF-4D06-BD91-2118BF1DB10B}' = s 'IWICMetadataQueryWriter'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{3B16811B-6A43-4EC9-A813-3D930C13B940}' = s 'IWICBitmapFrameDecode'
{
NumMethods = s 11
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{E8EDA601-3D48-431A-AB44-69059BE88BBE}' = s 'IWICPixelFormatInfo'
{
NumMethods = s 16
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{A9DB33A2-AF5F-43C7-B679-74F5984B5AA4}' = s 'IWICPixelFormatInfo2'
{
NumMethods = s 18
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{E87A44C4-B76E-4C47-8B09-298EB12A2714}' = s 'IWICBitmapCodecInfo'
{
NumMethods = s 23
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{D8CD007F-D08F-4191-9BFC-236EA7F0E4B5}' = s 'IWICBitmapDecoderInfo'
{
NumMethods = s 26
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{9EDDE9E7-8DEE-47EA-99DF-E6FAF2ED44BF}' = s 'IWICBitmapDecoder'
{
NumMethods = s 14
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000105-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmapFrameEncode'
{
NumMethods = s 14
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{94C9B4EE-A09F-4F92-8A1E-4A9BCE7E76FB}' = s 'IWICBitmapEncoderInfo'
{
NumMethods = s 24
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000103-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmapEncoder'
{
NumMethods = s 13
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000301-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICFormatConverter'
{
NumMethods = s 10
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{9F34FB65-13F4-4F15-BC57-3726B5E53D9F}' = s 'IWICFormatConverterInfo'
{
NumMethods = s 13
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{135FF860-22B7-4DDF-B0F6-218F4F299A43}' = s 'IWICStream'
{
NumMethods = s 18
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{00000302-A8F2-4877-BA0A-FD2B6645FB94}' = s 'IWICBitmapScaler'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{E4FBCF03-223D-4E81-9333-D635556DD1B5}' = s 'IWICBitmapClipper'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{B66F034F-D0E2-40AB-B436-6DE39E321A94}' = s 'IWICColorTransform'
{
NumMethods = s 9
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{B84E2C09-78C9-4AC4-8BD3-524AE1663A2F}' = s 'IWICFastMetadataEncoder'
{
NumMethods = s 5
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
'{EC5EC8A9-C395-4314-9C77-54D7A935FF70}' = s 'IWICImagingFactory'
{
NumMethods = s 28
ProxyStubClsid32 = s '{00000301-A8F2-4877-BA0A-FD2B6645FB94}'
}
}
NoRemove CLSID
{
'{00000301-A8F2-4877-BA0A-FD2B6645FB94}' = s 'PSFactoryBuffer'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{CACAF262-9370-4615-A13B-9F5539DA4C0A}' = s 'WIC Imaging Factory'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{6B462062-7CBF-400D-9FDB-813DD10F2778}' = s 'WIC BMP Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{389EA17B-5078-4CDE-B6EF-25C15175C751}' = s 'WIC PNG Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{27949969-876A-41D7-9447-568F6A35A4DC}' = s 'WIC PNG Encoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{69BE8BB4-D66D-47C8-865A-ED1589433782}' = s 'WIC BMP Encoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
}
'{381DDA3C-9CE9-4834-A23E-1F98F8FC52BE}' = s 'WIC GIF Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{C61BFCDF-2E0F-4AAD-A8D7-E06BAFEBCDFE}' = s 'WIC ICO Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{9456A480-E88B-43EA-9E73-0B2D9B71B1CA}' = s 'WIC JPEG Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{1A34F5C1-4A5A-46DC-B644-1F4567E7A676}' = s 'WIC JPEG Encoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{B54E85D9-FE23-499F-8B88-6ACEA713752B}' = s 'WIC TIFF Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{0131BE10-2001-4C5F-A9B0-CC88FAB64CE8}' = s 'WIC TIFF Encoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{312FB6F1-B767-409D-8A6D-0FC154D4F05C}' = s 'WIC ICNS Encoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{1A3F11DC-B514-4B17-8C5F-2154513852F1}' = s 'WIC Default Format Converter'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{B11FC79A-67CC-43E6-A9CE-E3D54945D304}' = s 'WIC TGA Decoder'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{699745C2-5066-4B82-A8E3-D40478DBEC8C}' = s 'WIC Unknown Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{8F914656-9D0A-4EB2-9019-0BF96D8A9EE6}' = s 'WIC Ifd Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{4B59AFCC-B8C3-408A-B670-89E5FAB6FDA7}' = s 'WIC Png tEXt Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{41070793-59E4-479A-A1F7-954ADC2EF5FC}' = s 'WIC LSD Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{7447A267-0015-42C8-A8F1-FB3B94C68361}' = s 'WIC IMD Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{B92E345D-F52D-41F3-B562-081BC772E3B9}' = s 'WIC GCE Metadata Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{1767B93A-B021-44EA-920F-863C11F4F768}' = s 'WIC Application Extension Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
'{32557D3B-69DC-4F95-836E-F5972B2F6159}' = s 'WIC Comment Extension Reader'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
}
}
}

View file

@ -105,6 +105,7 @@ list(APPEND SOURCE
wia_lh.idl
wia_xp.idl
wincodec.idl
wincodecsdk.idl
winsxs.idl
wtypes.idl
wuapi.idl

View file

@ -18,7 +18,6 @@
import "wtypes.idl";
import "propidl.idl";
import "objidl.idl";
import "ocidl.idl";
cpp_quote("#define WINCODEC_SDK_VERSION 0x0236")
@ -78,10 +77,16 @@ typedef enum WICBitmapInterpolationMode {
WICBitmapInterpolationModeNearestNeighbor = 0x00000000,
WICBitmapInterpolationModeLinear = 0x00000001,
WICBitmapInterpolationModeCubic = 0x00000002,
WICBitmapInterpolationModeFaint = 0x00000003,
WICBitmapInterpolationModeFant = 0x00000003,
WICBITMAPINTERPOLATIONMODE_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapInterpolationMode;
typedef enum WICBitmapLockFlags {
WICBitmapLockRead = 0x00000001,
WICBitmapLockWrite = 0x00000002,
WICBITMAPLOCKFLAGS_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapLockFlags;
typedef enum WICBitmapPaletteType {
WICBitmapPaletteTypeCustom = 0x00000000,
WICBitmapPaletteTypeMedianCut = 0x00000001,
@ -141,6 +146,16 @@ typedef enum WICComponentEnumerateOptions {
WICComponentEnumerateDisabled = 0x80000000
} WICComponentEnumerateOptions;
typedef enum WICPixelFormatNumericRepresentation {
WICPixelFormatNumericRepresentationUnspecified = 0x00000000,
WICPixelFormatNumericRepresentationIndexed = 0x00000001,
WICPixelFormatNumericRepresentationUnsignedInteger = 0x00000002,
WICPixelFormatNumericRepresentationSignedInteger = 0x00000003,
WICPixelFormatNumericRepresentationFixed = 0x00000004,
WICPixelFormatNumericRepresentationFloat = 0x00000005,
WICPIXELFORMATNUMERICREPRESENTATION_FORCE_DWORD = CODEC_FORCE_DWORD
} WICPixelFormatNumericRepresentation;
typedef GUID WICPixelFormatGUID;
typedef REFGUID REFWICPixelFormatGUID;
@ -192,10 +207,13 @@ 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_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")
@ -444,6 +462,44 @@ interface IWICBitmapFrameDecode : IWICBitmapSource
[out] IWICBitmapSource **ppIThumbnail);
}
[
object,
uuid(e8eda601-3d48-431a-ab44-69059be88bbe)
]
interface IWICPixelFormatInfo : IWICComponentInfo
{
HRESULT GetFormatGUID(
[out] GUID* pFormat);
HRESULT GetColorContext(
[out] IWICColorContext **ppIColorContext);
HRESULT GetBitsPerPixel(
[out] UINT *puiBitsPerPixel);
HRESULT GetChannelCount(
[out] UINT *puiChannelCount);
HRESULT GetChannelMask(
[in] UINT uiChannelIndex,
[in] UINT cbMaskBuffer,
[in, out, unique, size_is(cbMaskBuffer)] BYTE *pbMaskBuffer,
[out] UINT *pcbActual);
}
[
object,
uuid(a9db33a2-af5f-43c7-b679-74f5984b5aa4)
]
interface IWICPixelFormatInfo2 : IWICPixelFormatInfo
{
HRESULT SupportsTransparency(
[out] BOOL *pfSupportsTransparency);
HRESULT GetNumericRepresentation(
[out] WICPixelFormatNumericRepresentation *pNumericRepresentation);
}
[
object,
uuid(e87a44c4-b76e-4c47-8b09-298eb12a2714)
@ -900,6 +956,29 @@ interface IWICImagingFactory : IUnknown
[out] IWICMetadataQueryWriter **ppIQueryWriter);
}
[
local,
object,
uuid(dc2bb46d-3f07-481e-8625-220c4aedbb33)
]
interface IWICEnumMetadataItem : IUnknown
{
HRESULT Next(
[in] ULONG celt,
[in, out, unique, size_is(celt)] PROPVARIANT *rgeltSchema,
[in, out, size_is(celt)] PROPVARIANT *rgeltId,
[in, out, optional, size_is(celt)] PROPVARIANT *rgeltValue,
[out, optional] ULONG *pceltFetched);
HRESULT Skip(
[in] ULONG celt);
HRESULT Reset();
HRESULT Clone(
[out] IWICEnumMetadataItem **ppIEnumMetadataItem);
}
cpp_quote("HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);")
cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);")
@ -929,6 +1008,9 @@ cpp_quote("DEFINE_GUID(GUID_ContainerFormatWmp, 0x57a37caa,0x367a,0x4540,0x91,0x
cpp_quote("DEFINE_GUID(GUID_VendorMicrosoft, 0xf0e749ca,0xedef,0x4589,0xa7,0x3a,0xee,0x0e,0x62,0x6a,0x2a,0x2b);")
cpp_quote("DEFINE_GUID(CLSID_WICImagingCategories, 0xfae3d380,0xfea4,0x4623,0x8c,0x75,0xc6,0xb6,0x11,0x10,0xb6,0x81);")
cpp_quote("DEFINE_GUID(CATID_WICBitmapDecoders, 0x7ed96837,0x96f0,0x4812,0xb2,0x11,0xf1,0x3c,0x24,0x11,0x7e,0xd3);")
cpp_quote("DEFINE_GUID(CATID_WICBitmapEncoders, 0xac757296,0x3522,0x4e11,0x98,0x62,0xc1,0x7b,0xe5,0xa1,0x76,0x7e);")
cpp_quote("DEFINE_GUID(CATID_WICFormatConverters, 0x7835eae8,0xbf14,0x49d1,0x93,0xce,0x53,0x3a,0x40,0x7b,0x22,0x48);")
cpp_quote("DEFINE_GUID(CATID_WICMetadataReader, 0x05af94d8,0x7174,0x4cd2,0xbe,0x4a,0x41,0x24,0xb8,0x0e,0xe4,0xb8);")
cpp_quote("DEFINE_GUID(CATID_WICPixelFormats, 0x2b46e70f,0xcda7,0x473e,0x89,0xf6,0xdc,0x96,0x30,0xa2,0x39,0x0b);")

View file

@ -0,0 +1,321 @@
/*
* Copyright 2011 Vincent Povirk 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
*/
import "wtypes.idl";
import "wincodec.idl";
typedef enum WICPersistOptions {
WICPersistOptionsDefault = 0x00000000,
WICPersistOptionsLittleEndian = 0x00000000,
WICPersistOptionsBigEndian = 0x00000001,
WICPersistOptionsStrictFormat = 0x00000002,
WICPersistOptionsNoCacheStream = 0x00000004,
WICPersistOptionPreferUTF8 = 0x00000008,
WICPersistOptionsMask = 0x0000FFFF
} WICPersistOptions;
typedef enum WICMetadataCreationOptions {
WICMetadataCreationDefault = 0x00000000,
WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
WICMetadataCreationFailUnknown = 0x00010000,
WICMetadataCreationMask = 0xFFFF0000
} WICMetadataCreationOptions;
cpp_quote("DEFINE_GUID(GUID_MetadataFormatUnknown, 0xa45e592f,0x9078,0x4a7c,0xad,0xb5,0x4e,0xdc,0x4f,0xd6,0x1b,0x1f);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunktEXt, 0x568d8936,0xc0a9,0x4923,0x90,0x5d,0xdf,0x2b,0x38,0x23,0x8f,0xbc);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunktIME, 0x6b00ae2d,0xe24b,0x460a,0x98,0xb6,0x87,0x8b,0xd0,0x30,0x72,0xfd);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatIfd, 0x537396c6,0x2d8a,0x4bb6,0x9b,0xf8,0x2f,0x0a,0x8e,0x2a,0x3a,0xdf);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatExif, 0x1c3c4f9d,0xb84a,0x467d,0x94,0x93,0x36,0xcf,0xbd,0x59,0xea,0x57);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatXMP, 0xbb5acc38,0xf216,0x4cec,0xa6,0xc5,0x5f,0x6e,0x73,0x97,0x63,0xa9);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatXMPStruct, 0x22383cf1,0xed17,0x4e2e,0xaf,0x17,0xd8,0x5b,0x8f,0x6b,0x30,0xd0);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatIMD, 0xbd2bb086,0x4d52,0x48dd,0x96,0x77,0xdb,0x48,0x3e,0x85,0xae,0x8f);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatLSD, 0xe256031e,0x6299,0x4929,0xb9,0x8d,0x5a,0xc8,0x84,0xaf,0xba,0x92);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatGCE, 0x2a25cad8,0xdeeb,0x4c69,0xa7,0x88,0x0e,0xc2,0x26,0x6d,0xca,0xfd);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatAPE, 0x2e043dc2,0xc967,0x4e05,0x87,0x5e,0x61,0x8b,0xf6,0x7e,0x85,0xc3);")
cpp_quote("DEFINE_GUID(GUID_MetadataFormatGifComment, 0xc4b6e0e0,0xcfb4,0x4ad3,0xab,0x33,0x9a,0xad,0x23,0x55,0xa3,0x4a);")
cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataReader, 0x699745c2,0x5066,0x4b82,0xa8,0xe3,0xd4,0x04,0x78,0xdb,0xec,0x8c);")
cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataWriter, 0xa09cca86,0x27ba,0x4f39,0x90,0x53,0x12,0x1f,0xa4,0xdc,0x08,0xfc);")
cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataReader, 0x4b59afcc,0xb8c3,0x408a,0xb6,0x70,0x89,0xe5,0xfa,0xb6,0xfd,0xa7);")
cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataWriter, 0xb5ebafb9,0x253e,0x4a72,0xa7,0x44,0x07,0x62,0xd2,0x68,0x56,0x83);")
cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataReader, 0x8f914656,0x9d0a,0x4eb2,0x90,0x19,0x0b,0xf9,0x6d,0x8a,0x9e,0xe6);")
cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataWriter, 0xb1ebfc28,0xc9bd,0x47a2,0x8d,0x33,0xb9,0x48,0x76,0x97,0x77,0xa7);")
cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataReader, 0xd9403860,0x297f,0x4a49,0xbf,0x9b,0x77,0x89,0x81,0x50,0xa4,0x42);")
cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataWriter, 0xc9a14cda,0xc339,0x460b,0x90,0x78,0xd4,0xde,0xbc,0xfa,0xbe,0x91);")
cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataReader, 0x01b90d9a,0x8209,0x47f7,0x9c,0x52,0xe1,0x24,0x4b,0xf5,0x0c,0xed);")
cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataWriter, 0x22c21f93,0x7ddb,0x411c,0x9b,0x17,0xc5,0xb7,0xbd,0x06,0x4a,0xbc);")
cpp_quote("DEFINE_GUID(CLSID_WICLSDMetadataReader, 0x41070793,0x59e4,0x479a,0xa1,0xf7,0x95,0x4a,0xdc,0x2e,0xf5,0xfc);")
cpp_quote("DEFINE_GUID(CLSID_WICLSDMetadataWriter, 0x73c037e7,0xe5d9,0x4954,0x87,0x6a,0x6d,0xa8,0x1d,0x6e,0x57,0x68);")
cpp_quote("DEFINE_GUID(CLSID_WICIMDMetadataReader, 0x7447a267,0x0015,0x42c8,0xa8,0xf1,0xfb,0x3b,0x94,0xc6,0x83,0x61);")
cpp_quote("DEFINE_GUID(CLSID_WICIMDMetadataWriter, 0x8c89071f,0x452e,0x4e95,0x96,0x82,0x9d,0x10,0x24,0x62,0x71,0x72);")
cpp_quote("DEFINE_GUID(CLSID_WICGCEMetadataReader, 0xb92e345d,0xf52d,0x41f3,0xb5,0x62,0x08,0x1b,0xc7,0x72,0xe3,0xb9);")
cpp_quote("DEFINE_GUID(CLSID_WICGCEMetadataWriter, 0xaf95dc76,0x16b2,0x47f4,0xb3,0xea,0x3c,0x31,0x79,0x66,0x93,0xe7);")
cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataReader, 0x1767b93a,0xb021,0x44ea,0x92,0x0f,0x86,0x3c,0x11,0xf4,0xf7,0x68);")
cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataWriter, 0xbd6edfca,0x2890,0x482f,0xb2,0x33,0x8d,0x73,0x39,0xa1,0xcf,0x8d);")
cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataReader, 0x32557d3b,0x69dc,0x4f95,0x83,0x6e,0xf5,0x97,0x2b,0x2f,0x61,0x59);")
cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataWriter, 0xa02797fc,0xc4ae,0x418c,0xaf,0x95,0xe6,0x37,0xc7,0xea,0xd2,0xa1);")
typedef struct WICMetadataPattern {
ULARGE_INTEGER Position;
ULONG Length;
BYTE *Pattern;
BYTE *Mask;
ULARGE_INTEGER DataOffset;
} WICMetadataPattern;
typedef struct WICMetadataHeader {
ULARGE_INTEGER Position;
ULONG Length;
BYTE *Header;
ULARGE_INTEGER DataOffset;
} WICMetadataHeader;
[
object,
uuid(aba958bf-c672-44d1-8d61-ce6df2e682c2)
]
interface IWICMetadataHandlerInfo : IWICComponentInfo
{
HRESULT GetMetadataFormat(
[out] GUID *pguidMetadataFormat);
HRESULT GetContainerFormats(
[in] UINT cContainerFormats,
[in, out, unique, size_is(cContainerFormats)] GUID *pguidContainerFormats,
[out] UINT *pcchActual);
HRESULT GetDeviceManufacturer(
[in] UINT cchDeviceManufacturer,
[in, out, unique, size_is(cchDeviceManufacturer)] WCHAR *wzDeviceManufacturer,
[out] UINT *pcchActual);
HRESULT GetDeviceModels(
[in] UINT cchDeviceModels,
[in, out, unique, size_is(cchDeviceModels)] WCHAR *wzDeviceModels,
[out] UINT *pcchActual);
HRESULT DoesRequireFullStream(
[out] BOOL *pfRequiresFullStream);
HRESULT DoesSupportPadding(
[out] BOOL *pfSupportsPadding);
HRESULT DoesRequireFixedSize(
[out] BOOL *pfFixedSize);
}
[
object,
uuid(9204fe99-d8fc-4fd5-a001-9536b067a899)
]
interface IWICMetadataReader : IUnknown
{
HRESULT GetMetadataFormat(
[out] GUID *pguidMetadataFormat);
HRESULT GetMetadataHandlerInfo(
[out] IWICMetadataHandlerInfo **ppIHandler);
HRESULT GetCount(
[out] UINT *pcCount);
HRESULT GetValueByIndex(
[in] UINT nIndex,
[in, out, unique] PROPVARIANT *pvarSchema,
[in, out, unique] PROPVARIANT *pvarId,
[in, out, unique] PROPVARIANT *pvarValue);
HRESULT GetValue(
[in] const PROPVARIANT *pvarSchema,
[in] const PROPVARIANT *pvarId,
[in, out, unique] PROPVARIANT *pvarValue);
HRESULT GetEnumerator(
[out] IWICEnumMetadataItem **ppIEnumMetadata);
}
[
object,
uuid(eebf1f5b-07c1-4447-a3ab-22acaf78a804)
]
interface IWICMetadataReaderInfo : IWICMetadataHandlerInfo
{
[local]
HRESULT GetPatterns(
[in] REFGUID guidContainerFormat,
[in] UINT cbSize,
[out, unique] WICMetadataPattern *pPattern,
[out, unique] UINT *pcCount,
[out, unique] UINT *pcbActual);
HRESULT MatchesPattern(
[in] REFGUID guidContainerFormat,
[in] IStream *pIStream,
[out] BOOL *pfMatches);
HRESULT CreateInstance(
[out] IWICMetadataReader **ppIReader);
}
[
object,
uuid(f7836e16-3be0-470b-86bb-160d0aecd7de)
]
interface IWICMetadataWriter : IWICMetadataReader
{
HRESULT SetValue(
[in, unique] const PROPVARIANT *pvarSchema,
[in] const PROPVARIANT *pvarId,
[in] const PROPVARIANT *pvarValue);
HRESULT SetValueByIndex(
[in] UINT nIndex,
[in, unique] const PROPVARIANT *pvarSchema,
[in] const PROPVARIANT *pvarId,
[in] const PROPVARIANT *pvarValue);
HRESULT RemoveValue(
[in, unique] const PROPVARIANT *pvarSchema,
[in] const PROPVARIANT *pvarId);
HRESULT RemoveValueByIndex(
[in] UINT nIndex);
}
[
object,
uuid(b22e3fba-3925-4323-b5c1-9ebfc430f236)
]
interface IWICMetadataWriterInfo : IWICMetadataHandlerInfo
{
[local]
HRESULT GetHeader(
[in] REFGUID guidContainerFormat,
[in] UINT cbSize,
[out, unique] WICMetadataHeader *pHeader,
[out, unique] UINT *pcbActual);
HRESULT CreateInstance(
[out] IWICMetadataWriter **ppIWriter);
}
[
object,
uuid(feaa2a8d-b3f3-43e4-b25c-d1de990a1ae1)
]
interface IWICMetadataBlockReader : IUnknown
{
HRESULT GetContainerFormat(
[out] GUID *pguidContainerFormat);
HRESULT GetCount(
[out] UINT *pcCount);
HRESULT GetReaderByIndex(
[in] UINT nIndex,
[out] IWICMetadataReader **ppIMetadataReader);
HRESULT GetEnumerator(
[out] IEnumUnknown **ppIEnumMetadata);
}
[
object,
uuid(08fb9676-b444-41e8-8dbe-6a53a542bff1)
]
interface IWICMetadataBlockWriter : IWICMetadataBlockReader
{
HRESULT InitializeFromBlockReader(
[in] IWICMetadataBlockReader *pIMDBlockReader);
HRESULT GetWriterByIndex(
[in] UINT nIndex,
[out] IWICMetadataWriter **ppIMetadataWriter);
HRESULT AddWriter(
[in] IWICMetadataWriter *pIMetadataWriter);
HRESULT SetWriterByIndex(
[in] UINT nIndex,
[in] IWICMetadataWriter *pIMetadataWriter);
HRESULT RemoveWriterByIndex(
[in] UINT nIndex);
}
[
object,
uuid(00675040-6908-45f8-86a3-49c7dfd6d9ad)
]
interface IWICPersistStream : IPersistStream
{
HRESULT LoadEx(
[in, unique] IStream *pIStream,
[in, unique] const GUID *pguidPreferredVendor,
[in] DWORD dwPersistOptions);
HRESULT SaveEx(
[in] IStream *pIStream,
[in] DWORD dwPersistOptions,
[in] BOOL fClearDirty);
}
[
object,
uuid(412d0c3a-9650-44fa-af5b-dd2a06c8e8fb)
]
interface IWICComponentFactory : IWICImagingFactory
{
HRESULT CreateMetadataReader(
[in] REFGUID guidMetadataFormat,
[in, unique] const GUID *pguidVendor,
[in] DWORD dwOptions,
[in] IStream *pIStream,
[out] IWICMetadataReader **ppIReader);
HRESULT CreateMetadataReaderFromContainer(
[in] REFGUID guidMetadataFormat,
[in, unique] const GUID *pguidVendor,
[in] DWORD dwOptions,
[in] IStream *pIStream,
[out] IWICMetadataReader **ppIReader);
HRESULT CreateMetadataWriter(
[in] REFGUID guidMetadataFormat,
[in, unique] const GUID *pguidVendor,
[in] DWORD dwMetadataOptions,
[out] IWICMetadataWriter **ppIWriter);
HRESULT CreateMetadataWriterFromReader(
[in] IWICMetadataReader *pIReader,
[in, unique] const GUID *pguidVendor,
[out] IWICMetadataWriter **ppIWriter);
HRESULT CreateQueryReaderFromBlockReader(
[in] IWICMetadataBlockReader *pIBlockReader,
[out] IWICMetadataQueryReader **ppIQueryReader);
HRESULT CreateQueryWriterFromBlockWriter(
[in] IWICMetadataBlockWriter *pIBlockWriter,
[out] IWICMetadataQueryWriter **ppIQueryWriter);
HRESULT CreateEncoderPropertyBag(
[in, unique, size_is(cCount)] PROPBAG2 *ppropOptions,
[in] UINT cCount,
[out] IPropertyBag2 **ppIPropertyBag);
}

View file

@ -2302,7 +2302,7 @@ BOOLEAN WINAPI RtlTimeToSecondsSince1970(const LARGE_INTEGER *,LPDWORD);
BOOLEAN WINAPI RtlTimeToSecondsSince1980(const LARGE_INTEGER *,LPDWORD);
BOOL WINAPI RtlTryEnterCriticalSection(RTL_CRITICAL_SECTION *);
ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG);
ULONGLONG __fastcall RtlUlonglongByteSwap(ULONGLONG);
DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING*);
NTSTATUS WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING,PCUNICODE_STRING,BOOLEAN);
NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING *,ULONG,ULONG *);

View file

@ -182,7 +182,7 @@ reactos/dll/win32/usp10 # Synced to Wine-1.5.4
reactos/dll/win32/uxtheme # Forked
reactos/dll/win32/version # Autosync
reactos/dll/win32/wer # Autosync
reactos/dll/win32/windowscodecs # Autosync
reactos/dll/win32/windowscodecs # Synced to Wine-1.5.19
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.4