mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434
This commit is contained in:
parent
a8d718da39
commit
ae80686d81
34 changed files with 3112 additions and 380 deletions
|
@ -23,7 +23,6 @@ spec2def(windowscodecs.dll windowscodecs.spec ADD_IMPORTLIB)
|
|||
add_rpcproxy_files(windowscodecs_wincodec.idl)
|
||||
|
||||
list(APPEND SOURCE
|
||||
bitmap.c
|
||||
bmpdecode.c
|
||||
bmpencode.c
|
||||
clipper.c
|
||||
|
@ -51,7 +50,17 @@ list(APPEND SOURCE
|
|||
tgaformat.c
|
||||
tiffformat.c
|
||||
ungif.c
|
||||
wincodecs_private.h)
|
||||
precomp.h)
|
||||
|
||||
if(MSVC)
|
||||
if(ARCH STREQUAL "i386")
|
||||
list(APPEND SOURCE msvc-thiscall.c)
|
||||
endif()
|
||||
set_source_files_properties(bitmap.c PROPERTIES COMPILE_FLAGS "/FImsvc.h")
|
||||
list(APPEND ADDITIONAL_SOURCE bitmap.c)
|
||||
else()
|
||||
list(APPEND SOURCE bitmap.c)
|
||||
endif()
|
||||
|
||||
list(APPEND ADDITIONAL_SOURCE
|
||||
guid.c
|
||||
|
@ -68,5 +77,5 @@ add_library(windowscodecs SHARED
|
|||
set_module_type(windowscodecs win32dll)
|
||||
target_link_libraries(windowscodecs wine uuid ${PSEH_LIB})
|
||||
add_importlibs(windowscodecs ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll)
|
||||
add_pch(windowscodecs wincodecs_private.h SOURCE)
|
||||
add_pch(windowscodecs precomp.h SOURCE)
|
||||
add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
/* WARNING: .NET Media Integration Layer (MIL) directly dereferences
|
||||
* BitmapImpl members and depends on its exact layout.
|
||||
*/
|
||||
|
@ -31,6 +45,7 @@ typedef struct BitmapImpl {
|
|||
int palette_set;
|
||||
LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
|
||||
BYTE *data;
|
||||
BOOL is_section; /* TRUE if data is a section created by an application */
|
||||
UINT width, height;
|
||||
UINT stride;
|
||||
UINT bpp;
|
||||
|
@ -121,6 +136,7 @@ static HRESULT WINAPI BitmapLockImpl_QueryInterface(IWICBitmapLock *iface, REFII
|
|||
}
|
||||
else
|
||||
{
|
||||
FIXME("unknown interface %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
@ -234,12 +250,14 @@ static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid,
|
|||
{
|
||||
*ppv = &This->IWICBitmap_iface;
|
||||
}
|
||||
else if (IsEqualIID(&IID_IMILBitmapSource, iid))
|
||||
else if (IsEqualIID(&IID_IMILBitmap, iid) ||
|
||||
IsEqualIID(&IID_IMILBitmapSource, iid))
|
||||
{
|
||||
*ppv = &This->IMILBitmapSource_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("unknown interface %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
@ -270,7 +288,10 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
|
|||
if (This->palette) IWICPalette_Release(This->palette);
|
||||
This->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->cs);
|
||||
HeapFree(GetProcessHeap(), 0, This->data);
|
||||
if (This->is_section)
|
||||
UnmapViewOfFile(This->data);
|
||||
else
|
||||
HeapFree(GetProcessHeap(), 0, This->data);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
|
@ -465,13 +486,22 @@ static HRESULT WINAPI IMILBitmapImpl_QueryInterface(IMILBitmapSource *iface, REF
|
|||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid) ||
|
||||
IsEqualIID(&IID_IMILBitmap, iid) ||
|
||||
IsEqualIID(&IID_IMILBitmapSource, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IMILBitmapSource_iface);
|
||||
*ppv = &This->IMILBitmapSource_iface;
|
||||
return S_OK;
|
||||
}
|
||||
else if (IsEqualIID(&IID_IWICBitmap, iid) ||
|
||||
IsEqualIID(&IID_IWICBitmapSource, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IWICBitmap_iface);
|
||||
*ppv = &This->IWICBitmap_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("unknown interface %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
@ -492,6 +522,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetSize(IMILBitmapSource *iface,
|
|||
UINT *width, UINT *height)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p,%p)\n", iface, width, height);
|
||||
return IWICBitmap_GetSize(&This->IWICBitmap_iface, width, height);
|
||||
}
|
||||
|
||||
|
@ -545,6 +576,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetPixelFormat(IMILBitmapSource *iface,
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("=> %u\n", *format);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -552,6 +584,7 @@ static HRESULT WINAPI IMILBitmapImpl_GetResolution(IMILBitmapSource *iface,
|
|||
double *dpix, double *dpiy)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p,%p)\n", iface, dpix, dpiy);
|
||||
return IWICBitmap_GetResolution(&This->IWICBitmap_iface, dpix, dpiy);
|
||||
}
|
||||
|
||||
|
@ -559,6 +592,7 @@ static HRESULT WINAPI IMILBitmapImpl_CopyPalette(IMILBitmapSource *iface,
|
|||
IWICPalette *palette)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
return IWICBitmap_CopyPalette(&This->IWICBitmap_iface, palette);
|
||||
}
|
||||
|
||||
|
@ -566,10 +600,11 @@ static HRESULT WINAPI IMILBitmapImpl_CopyPixels(IMILBitmapSource *iface,
|
|||
const WICRect *rc, UINT stride, UINT size, BYTE *buffer)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p,%u,%u,%p)\n", iface, rc, stride, size, buffer);
|
||||
return IWICBitmap_CopyPixels(&This->IWICBitmap_iface, rc, stride, size, buffer);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_UnknownMethod1(IMILBitmapSource *iface, void **ppv)
|
||||
static HRESULT WINAPI IMILBitmapImpl_unknown1(IMILBitmapSource *iface, void **ppv)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
|
||||
|
@ -577,12 +612,46 @@ static HRESULT WINAPI IMILBitmapImpl_UnknownMethod1(IMILBitmapSource *iface, voi
|
|||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
IUnknown_AddRef(&This->IMILUnknown1_iface);
|
||||
/* reference count is not incremented here */
|
||||
*ppv = &This->IMILUnknown1_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_Lock(IMILBitmapSource *iface, const WICRect *rc, DWORD flags, IWICBitmapLock **lock)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p,%08x,%p)\n", iface, rc, flags, lock);
|
||||
return IWICBitmap_Lock(&This->IWICBitmap_iface, rc, flags, lock);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_Unlock(IMILBitmapSource *iface, IWICBitmapLock *lock)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, lock);
|
||||
IWICBitmapLock_Release(lock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_SetPalette(IMILBitmapSource *iface, IWICPalette *palette)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
return IWICBitmap_SetPalette(&This->IWICBitmap_iface, palette);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_SetResolution(IMILBitmapSource *iface, double dpix, double dpiy)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILBitmapSource(iface);
|
||||
TRACE("(%p,%f,%f)\n", iface, dpix, dpiy);
|
||||
return IWICBitmap_SetResolution(&This->IWICBitmap_iface, dpix, dpiy);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapImpl_AddDirtyRect(IMILBitmapSource *iface, const WICRect *rc)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, rc);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl =
|
||||
{
|
||||
IMILBitmapImpl_QueryInterface,
|
||||
|
@ -593,26 +662,20 @@ static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl =
|
|||
IMILBitmapImpl_GetResolution,
|
||||
IMILBitmapImpl_CopyPalette,
|
||||
IMILBitmapImpl_CopyPixels,
|
||||
IMILBitmapImpl_UnknownMethod1,
|
||||
IMILBitmapImpl_unknown1,
|
||||
IMILBitmapImpl_Lock,
|
||||
IMILBitmapImpl_Unlock,
|
||||
IMILBitmapImpl_SetPalette,
|
||||
IMILBitmapImpl_SetResolution,
|
||||
IMILBitmapImpl_AddDirtyRect
|
||||
};
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_QueryInterface(IMILUnknown1 *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILUnknown1(iface);
|
||||
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IMILUnknown1_iface);
|
||||
*ppv = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv);
|
||||
FIXME("(%p,%s,%p): stub\n", iface, debugstr_guid(iid), ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMILUnknown1Impl_AddRef(IMILUnknown1 *iface)
|
||||
|
@ -627,47 +690,108 @@ static ULONG WINAPI IMILUnknown1Impl_Release(IMILUnknown1 *iface)
|
|||
return IWICBitmap_Release(&This->IWICBitmap_iface);
|
||||
}
|
||||
|
||||
DECLSPEC_HIDDEN void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_unknown2(IMILUnknown1 *iface, void *arg1, void *arg2)
|
||||
{
|
||||
FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_unknown4(IMILUnknown1 *iface, void *arg)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_unknown5(IMILUnknown1 *iface, void *arg)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_unknown6(IMILUnknown1 *iface, DWORD64 arg)
|
||||
{
|
||||
FIXME("(%p,%s): stub\n", iface, wine_dbgstr_longlong(arg));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown1Impl_unknown7(IMILUnknown1 *iface, void *arg)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface)
|
||||
{
|
||||
FIXME("(%p): stub\n", iface);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown1, 8)
|
||||
DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown3, 8)
|
||||
DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown8, 4)
|
||||
|
||||
static const IMILUnknown1Vtbl IMILUnknown1Impl_Vtbl =
|
||||
{
|
||||
IMILUnknown1Impl_QueryInterface,
|
||||
IMILUnknown1Impl_AddRef,
|
||||
IMILUnknown1Impl_Release,
|
||||
THISCALL(IMILUnknown1Impl_unknown1),
|
||||
IMILUnknown1Impl_unknown2,
|
||||
THISCALL(IMILUnknown1Impl_unknown3),
|
||||
IMILUnknown1Impl_unknown4,
|
||||
IMILUnknown1Impl_unknown5,
|
||||
IMILUnknown1Impl_unknown6,
|
||||
IMILUnknown1Impl_unknown7,
|
||||
THISCALL(IMILUnknown1Impl_unknown8)
|
||||
};
|
||||
|
||||
static HRESULT WINAPI IMILUnknown2Impl_QueryInterface(IMILUnknown2 *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILUnknown2(iface);
|
||||
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IMILUnknown2_iface);
|
||||
*ppv = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv);
|
||||
FIXME("(%p,%s,%p): stub\n", iface, debugstr_guid(iid), ppv);
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMILUnknown2Impl_AddRef(IMILUnknown2 *iface)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILUnknown2(iface);
|
||||
return IWICBitmap_AddRef(&This->IWICBitmap_iface);
|
||||
FIXME("(%p): stub\n", iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMILUnknown2Impl_Release(IMILUnknown2 *iface)
|
||||
{
|
||||
BitmapImpl *This = impl_from_IMILUnknown2(iface);
|
||||
return IWICBitmap_Release(&This->IWICBitmap_iface);
|
||||
FIXME("(%p): stub\n", iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown2Impl_UnknownMethod1(IMILUnknown2 *iface, void *arg1, void *arg2)
|
||||
static HRESULT WINAPI IMILUnknown2Impl_unknown1(IMILUnknown2 *iface, void *arg1, void **arg2)
|
||||
{
|
||||
FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2);
|
||||
if (arg2) *arg2 = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown2Impl_unknown2(IMILUnknown2 *iface, void *arg1, void *arg2)
|
||||
{
|
||||
FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILUnknown2Impl_unknown3(IMILUnknown2 *iface, void *arg1)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, arg1);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
@ -676,17 +800,18 @@ static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl =
|
|||
IMILUnknown2Impl_QueryInterface,
|
||||
IMILUnknown2Impl_AddRef,
|
||||
IMILUnknown2Impl_Release,
|
||||
IMILUnknown2Impl_UnknownMethod1,
|
||||
IMILUnknown2Impl_unknown1,
|
||||
IMILUnknown2Impl_unknown2,
|
||||
IMILUnknown2Impl_unknown3
|
||||
};
|
||||
|
||||
HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
|
||||
UINT stride, UINT datasize, BYTE *bits,
|
||||
UINT stride, UINT datasize, BYTE *data,
|
||||
REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
|
||||
IWICBitmap **ppIBitmap)
|
||||
{
|
||||
HRESULT hr;
|
||||
BitmapImpl *This;
|
||||
BYTE *data;
|
||||
UINT bpp;
|
||||
|
||||
hr = get_pixelformat_bpp(pixelFormat, &bpp);
|
||||
|
@ -699,14 +824,20 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
|
|||
if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
|
||||
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
|
||||
if (!This || !data)
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return E_OUTOFMEMORY;
|
||||
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
|
||||
if (!data)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
This->is_section = FALSE;
|
||||
}
|
||||
if (bits) memcpy(data, bits, datasize);
|
||||
else
|
||||
This->is_section = TRUE;
|
||||
|
||||
This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
|
||||
This->IMILBitmapSource_iface.lpVtbl = &IMILBitmapImpl_Vtbl;
|
||||
|
|
|
@ -16,9 +16,24 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "wingdi.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct {
|
||||
DWORD bc2Size;
|
||||
|
@ -256,7 +271,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
|||
if (This->bih.bV5ClrUsed == 0)
|
||||
count = 1 << This->bih.bV5BitCount;
|
||||
else
|
||||
count = This->bih.bV5ClrUsed;
|
||||
count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount);
|
||||
|
||||
tablesize = sizeof(WICColor) * count;
|
||||
wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2009 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2016 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -16,13 +17,28 @@
|
|||
* 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 "winreg.h"
|
||||
#include "wingdi.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <wingdi.h>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
struct bmp_pixelformat {
|
||||
const WICPixelFormatGUID *guid;
|
||||
UINT bpp;
|
||||
UINT colors; /* palette size */
|
||||
DWORD compression;
|
||||
DWORD redmask;
|
||||
DWORD greenmask;
|
||||
|
@ -31,13 +47,18 @@ struct bmp_pixelformat {
|
|||
};
|
||||
|
||||
static const struct bmp_pixelformat formats[] = {
|
||||
{&GUID_WICPixelFormat24bppBGR, 24, BI_RGB},
|
||||
{&GUID_WICPixelFormat16bppBGR555, 16, BI_RGB},
|
||||
{&GUID_WICPixelFormat16bppBGR565, 16, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0},
|
||||
{&GUID_WICPixelFormat32bppBGR, 32, BI_RGB},
|
||||
{&GUID_WICPixelFormat24bppBGR, 24, 0, BI_RGB},
|
||||
{&GUID_WICPixelFormatBlackWhite, 1, 2, BI_RGB},
|
||||
{&GUID_WICPixelFormat1bppIndexed, 1, 2, BI_RGB},
|
||||
{&GUID_WICPixelFormat2bppIndexed, 2, 4, BI_RGB},
|
||||
{&GUID_WICPixelFormat4bppIndexed, 4, 16, BI_RGB},
|
||||
{&GUID_WICPixelFormat8bppIndexed, 8, 256, BI_RGB},
|
||||
{&GUID_WICPixelFormat16bppBGR555, 16, 0, BI_RGB},
|
||||
{&GUID_WICPixelFormat16bppBGR565, 16, 0, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0},
|
||||
{&GUID_WICPixelFormat32bppBGR, 32, 0, BI_RGB},
|
||||
#if 0
|
||||
/* Windows doesn't seem to support this one. */
|
||||
{&GUID_WICPixelFormat32bppBGRA, 32, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000},
|
||||
{&GUID_WICPixelFormat32bppBGRA, 32, 0, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000},
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
@ -58,6 +79,8 @@ typedef struct BmpFrameEncode {
|
|||
BOOL committed;
|
||||
} BmpFrameEncode;
|
||||
|
||||
static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0};
|
||||
|
||||
static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface);
|
||||
|
@ -121,6 +144,9 @@ static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
|
|||
|
||||
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
if (pIEncoderOptions)
|
||||
WARN("ignoring encoder options.\n");
|
||||
|
||||
This->initialized = TRUE;
|
||||
|
||||
return S_OK;
|
||||
|
@ -165,11 +191,13 @@ static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface
|
|||
|
||||
for (i=0; formats[i].guid; i++)
|
||||
{
|
||||
if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0)
|
||||
if (IsEqualGUID(formats[i].guid, pPixelFormat))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!formats[i].guid) i = 0;
|
||||
else if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormatBlackWhite))
|
||||
i = 2; /* GUID_WICPixelFormat1bppIndexed */
|
||||
|
||||
This->format = &formats[i];
|
||||
memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
|
||||
|
@ -188,6 +216,7 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
|
|||
IWICPalette *palette)
|
||||
{
|
||||
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
|
@ -196,7 +225,14 @@ static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
|
|||
if (!This->initialized)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
return IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
|
||||
hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < This->colors; i++)
|
||||
This->palette[i] |= 0xff000000; /* BMP palette has no alpha */
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
|
||||
|
@ -278,10 +314,11 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
|||
BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
|
||||
BITMAPFILEHEADER bfh;
|
||||
BITMAPV5HEADER bih;
|
||||
UINT info_size;
|
||||
UINT info_size, i;
|
||||
LARGE_INTEGER pos;
|
||||
ULONG byteswritten;
|
||||
HRESULT hr;
|
||||
const BYTE *bits;
|
||||
|
||||
TRACE("(%p)\n", iface);
|
||||
|
||||
|
@ -294,15 +331,15 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
|||
|
||||
bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER);
|
||||
bih.bV5Width = This->width;
|
||||
bih.bV5Height = -This->height; /* top-down bitmap */
|
||||
bih.bV5Height = This->height; /* bottom-top bitmap */
|
||||
bih.bV5Planes = 1;
|
||||
bih.bV5BitCount = This->format->bpp;
|
||||
bih.bV5Compression = This->format->compression;
|
||||
bih.bV5SizeImage = This->stride*This->height;
|
||||
bih.bV5XPelsPerMeter = (This->xres+0.0127) / 0.0254;
|
||||
bih.bV5YPelsPerMeter = (This->yres+0.0127) / 0.0254;
|
||||
bih.bV5ClrUsed = 0;
|
||||
bih.bV5ClrImportant = 0;
|
||||
bih.bV5ClrUsed = (This->format->bpp <= 8) ? This->colors : 0;
|
||||
bih.bV5ClrImportant = bih.bV5ClrUsed;
|
||||
|
||||
if (This->format->compression == BI_BITFIELDS)
|
||||
{
|
||||
|
@ -319,6 +356,7 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
|||
|
||||
bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage;
|
||||
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size;
|
||||
bfh.bfOffBits += bih.bV5ClrUsed * sizeof(WICColor);
|
||||
|
||||
pos.QuadPart = 0;
|
||||
hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL);
|
||||
|
@ -332,9 +370,23 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
|
|||
if (FAILED(hr)) return hr;
|
||||
if (byteswritten != info_size) return E_FAIL;
|
||||
|
||||
hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage, &byteswritten);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (byteswritten != bih.bV5SizeImage) return E_FAIL;
|
||||
/* write the palette */
|
||||
if (This->format->colors)
|
||||
{
|
||||
hr = IStream_Write(This->stream, This->palette, This->colors * sizeof(WICColor), &byteswritten);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (byteswritten != This->colors * sizeof(WICColor)) return E_FAIL;
|
||||
}
|
||||
|
||||
/* write the image bits as a bottom-top array */
|
||||
bits = This->bits + bih.bV5SizeImage;
|
||||
for (i = 0; i < This->height; i++)
|
||||
{
|
||||
bits -= This->stride;
|
||||
hr = IStream_Write(This->stream, bits, This->stride, &byteswritten);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (byteswritten != This->stride) return E_FAIL;
|
||||
}
|
||||
|
||||
This->committed = TRUE;
|
||||
|
||||
|
@ -447,11 +499,22 @@ static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
|
||||
return E_NOTIMPL;
|
||||
IWICComponentInfo *comp_info;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", iface, info);
|
||||
|
||||
if (!info) return E_INVALIDARG;
|
||||
|
||||
hr = CreateComponentInfo(&CLSID_WICBmpEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -487,6 +550,10 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
BmpFrameEncode *encode;
|
||||
HRESULT hr;
|
||||
static const PROPBAG2 opts[1] =
|
||||
{
|
||||
{ PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszEnableV5Header32bppBGRA },
|
||||
};
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
|
||||
|
||||
|
@ -494,8 +561,11 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
|
||||
if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
|
||||
if (FAILED(hr)) return hr;
|
||||
if (ppIEncoderOptions)
|
||||
{
|
||||
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
|
||||
encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode));
|
||||
if (!encode)
|
||||
|
|
|
@ -16,8 +16,20 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct BitmapClipper {
|
||||
IWICBitmapClipper IWICBitmapClipper_iface;
|
||||
LONG ref;
|
||||
|
|
|
@ -16,8 +16,25 @@
|
|||
* 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 "winreg.h"
|
||||
#include "objbase.h"
|
||||
#include "ocidl.h"
|
||||
#include "initguid.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct {
|
||||
|
@ -32,6 +49,7 @@ static const classinfo wic_classes[] = {
|
|||
{&CLSID_WICPngEncoder, PngEncoder_CreateInstance},
|
||||
{&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance},
|
||||
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
|
||||
{&CLSID_WICGifEncoder, GifEncoder_CreateInstance},
|
||||
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
|
||||
{&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance},
|
||||
{&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance},
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct ColorContext {
|
||||
IWICColorContext IWICColorContext_iface;
|
||||
LONG ref;
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct ColorTransform {
|
||||
IWICColorTransform IWICColorTransform_iface;
|
||||
LONG ref;
|
||||
|
|
|
@ -17,9 +17,22 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
struct FormatConverter;
|
||||
|
||||
|
@ -40,8 +53,11 @@ enum pixelformat {
|
|||
format_24bppRGB,
|
||||
format_32bppGrayFloat,
|
||||
format_32bppBGR,
|
||||
format_32bppRGB,
|
||||
format_32bppBGRA,
|
||||
format_32bppRGBA,
|
||||
format_32bppPBGRA,
|
||||
format_32bppPRGBA,
|
||||
format_48bppRGB,
|
||||
format_64bppRGBA,
|
||||
format_32bppCMYK,
|
||||
|
@ -63,7 +79,7 @@ typedef struct FormatConverter {
|
|||
const struct pixelformatinfo *dst_format, *src_format;
|
||||
WICBitmapDitherType dither;
|
||||
double alpha_threshold;
|
||||
WICBitmapPaletteType palette_type;
|
||||
IWICPalette *palette;
|
||||
CRITICAL_SECTION lock; /* must be held when initialized */
|
||||
} FormatConverter;
|
||||
|
||||
|
@ -847,6 +863,27 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_32bppRGBA(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
switch (source_format)
|
||||
{
|
||||
case format_32bppRGB:
|
||||
case format_32bppRGBA:
|
||||
case format_32bppPRGBA:
|
||||
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)
|
||||
reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
|
@ -863,6 +900,22 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_32bppRGB(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
switch (source_format)
|
||||
{
|
||||
case format_32bppRGB:
|
||||
case format_32bppRGBA:
|
||||
case format_32bppPRGBA:
|
||||
if (prc)
|
||||
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
return S_OK;
|
||||
default:
|
||||
return copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
|
@ -896,6 +949,39 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
switch (source_format)
|
||||
{
|
||||
case format_32bppPRGBA:
|
||||
if (prc)
|
||||
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
return S_OK;
|
||||
default:
|
||||
hr = copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
|
||||
if (SUCCEEDED(hr) && prc)
|
||||
{
|
||||
INT 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 HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
|
@ -1208,11 +1294,95 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec
|
|||
return hr;
|
||||
}
|
||||
|
||||
static UINT rgb_to_palette_index(BYTE r, BYTE g, BYTE b, WICColor *colors, UINT count)
|
||||
{
|
||||
UINT best_diff, best_index, i;
|
||||
|
||||
best_diff = ~0;
|
||||
best_index = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
BYTE pal_r, pal_g, pal_b;
|
||||
DWORD diff_r, diff_g, diff_b, diff;
|
||||
|
||||
pal_r = colors[i] >> 16;
|
||||
pal_g = colors[i] >> 8;
|
||||
pal_b = colors[i];
|
||||
|
||||
diff_r = r - pal_r;
|
||||
diff_g = g - pal_g;
|
||||
diff_b = b - pal_b;
|
||||
|
||||
diff = diff_r * diff_r + diff_g * diff_g + diff_b * diff_b;
|
||||
if (diff == 0) return i;
|
||||
|
||||
if (diff < best_diff)
|
||||
{
|
||||
best_diff = diff;
|
||||
best_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return best_index;
|
||||
}
|
||||
|
||||
static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WICRect *prc,
|
||||
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
|
||||
{
|
||||
HRESULT hr;
|
||||
BYTE *srcdata;
|
||||
WICColor colors[256];
|
||||
UINT srcstride, srcdatasize, count;
|
||||
|
||||
if (source_format == format_8bppIndexed)
|
||||
{
|
||||
if (prc)
|
||||
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!This->palette) return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
hr = IWICPalette_GetColors(This->palette, 256, colors, &count);
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
srcstride = 3 * prc->Width;
|
||||
srcdatasize = srcstride * prc->Height;
|
||||
|
||||
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
|
||||
if (!srcdata) return E_OUTOFMEMORY;
|
||||
|
||||
hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format);
|
||||
if (SUCCEEDED(hr) && prc)
|
||||
{
|
||||
INT x, y;
|
||||
BYTE *src = srcdata, *dst = pbBuffer;
|
||||
|
||||
for (y = 0; y < prc->Height; y++)
|
||||
{
|
||||
BYTE *bgr = src;
|
||||
|
||||
for (x = 0; x < prc->Width; x++)
|
||||
{
|
||||
dst[x] = rgb_to_palette_index(bgr[2], bgr[1], bgr[0], colors, count);
|
||||
bgr += 3;
|
||||
}
|
||||
src += srcstride;
|
||||
dst += cbStride;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const struct pixelformatinfo supported_formats[] = {
|
||||
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
|
||||
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
|
||||
{format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
|
||||
{format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, NULL},
|
||||
{format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed},
|
||||
{format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
|
||||
{format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
|
||||
{format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
|
||||
|
@ -1225,8 +1395,11 @@ static const struct pixelformatinfo supported_formats[] = {
|
|||
{format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB},
|
||||
{format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat},
|
||||
{format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
|
||||
{format_32bppRGB, &GUID_WICPixelFormat32bppRGB, copypixels_to_32bppRGB},
|
||||
{format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
|
||||
{format_32bppRGBA, &GUID_WICPixelFormat32bppRGBA, copypixels_to_32bppRGBA},
|
||||
{format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA},
|
||||
{format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA},
|
||||
{format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL},
|
||||
{format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL},
|
||||
{format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL},
|
||||
|
@ -1289,6 +1462,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
|
|||
This->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->lock);
|
||||
if (This->source) IWICBitmapSource_Release(This->source);
|
||||
if (This->palette) IWICPalette_Release(This->palette);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
|
@ -1337,10 +1511,27 @@ static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
|
||||
IWICPalette *pIPalette)
|
||||
IWICPalette *palette)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, pIPalette);
|
||||
return E_NOTIMPL;
|
||||
FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!palette) return E_INVALIDARG;
|
||||
if (!This->source) return WINCODEC_ERR_WRONGSTATE;
|
||||
|
||||
if (!This->palette)
|
||||
{
|
||||
HRESULT hr;
|
||||
UINT bpp;
|
||||
|
||||
hr = get_pixelformat_bpp(This->dst_format->guid, &bpp);
|
||||
if (hr != S_OK) return hr;
|
||||
if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE;
|
||||
return IWICBitmapSource_CopyPalette(This->source, palette);
|
||||
}
|
||||
|
||||
return IWICPalette_InitializeFromPalette(palette, This->palette);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
||||
|
@ -1369,23 +1560,59 @@ static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
|
|||
pbBuffer, This->src_format->format);
|
||||
}
|
||||
else
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
return WINCODEC_ERR_WRONGSTATE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||
IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
|
||||
IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
|
||||
IWICBitmapSource *source, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
|
||||
IWICPalette *palette, double alpha_threshold, WICBitmapPaletteType palette_type)
|
||||
{
|
||||
FormatConverter *This = impl_from_IWICFormatConverter(iface);
|
||||
const struct pixelformatinfo *srcinfo, *dstinfo;
|
||||
static INT fixme=0;
|
||||
GUID srcFormat;
|
||||
HRESULT res=S_OK;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
|
||||
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
|
||||
TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
|
||||
dither, palette, alpha_threshold, palette_type);
|
||||
|
||||
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
|
||||
if (!palette)
|
||||
{
|
||||
UINT bpp;
|
||||
res = get_pixelformat_bpp(dstFormat, &bpp);
|
||||
if (res != S_OK) return res;
|
||||
|
||||
res = PaletteImpl_Create(&palette);
|
||||
if (res != S_OK) return res;
|
||||
|
||||
switch (palette_type)
|
||||
{
|
||||
case WICBitmapPaletteTypeCustom:
|
||||
IWICPalette_Release(palette);
|
||||
palette = NULL;
|
||||
if (bpp <= 8) return E_INVALIDARG;
|
||||
break;
|
||||
|
||||
case WICBitmapPaletteTypeMedianCut:
|
||||
{
|
||||
if (bpp <= 8)
|
||||
res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (bpp <= 8)
|
||||
res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (res != S_OK)
|
||||
{
|
||||
IWICPalette_Release(palette);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
IWICPalette_AddRef(palette);
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
|
@ -1395,7 +1622,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
|||
goto end;
|
||||
}
|
||||
|
||||
res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
|
||||
res = IWICBitmapSource_GetPixelFormat(source, &srcFormat);
|
||||
if (FAILED(res)) goto end;
|
||||
|
||||
srcinfo = get_formatinfo(&srcFormat);
|
||||
|
@ -1416,13 +1643,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
|||
|
||||
if (dstinfo->copy_function)
|
||||
{
|
||||
IWICBitmapSource_AddRef(pISource);
|
||||
IWICBitmapSource_AddRef(source);
|
||||
This->src_format = srcinfo;
|
||||
This->dst_format = dstinfo;
|
||||
This->dither = dither;
|
||||
This->alpha_threshold = alphaThresholdPercent;
|
||||
This->palette_type = paletteTranslate;
|
||||
This->source = pISource;
|
||||
This->alpha_threshold = alpha_threshold;
|
||||
This->palette = palette;
|
||||
This->source = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1434,6 +1661,9 @@ end:
|
|||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
if (res != S_OK && palette)
|
||||
IWICPalette_Release(palette);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1501,6 +1731,7 @@ HRESULT FormatConverter_CreateInstance(REFIID iid, void** ppv)
|
|||
This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl;
|
||||
This->ref = 1;
|
||||
This->source = NULL;
|
||||
This->palette = NULL;
|
||||
InitializeCriticalSection(&This->lock);
|
||||
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
|
||||
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct FlipRotator {
|
||||
IWICBitmapFlipRotator IWICBitmapFlipRotator_iface;
|
||||
LONG ref;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,11 @@
|
|||
* 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
|
||||
|
@ -73,8 +78,19 @@
|
|||
#undef DPRINTF
|
||||
#endif
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.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
|
||||
|
||||
|
@ -601,9 +617,12 @@ static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
goto end;
|
||||
}
|
||||
|
||||
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
if (ppIEncoderOptions)
|
||||
{
|
||||
hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
}
|
||||
|
||||
frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode));
|
||||
if (frameEncode == NULL)
|
||||
|
|
|
@ -16,9 +16,24 @@
|
|||
* 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 "wingdi.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <pshpack1.h>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
typedef struct {
|
||||
BYTE bWidth;
|
||||
|
@ -38,7 +53,7 @@ typedef struct
|
|||
WORD idCount;
|
||||
} ICONHEADER;
|
||||
|
||||
#include <poppack.h>
|
||||
#include "poppack.h"
|
||||
|
||||
typedef struct {
|
||||
IWICBitmapDecoder IWICBitmapDecoder_iface;
|
||||
|
|
|
@ -17,8 +17,24 @@
|
|||
* 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 "winreg.h"
|
||||
#include "objbase.h"
|
||||
#include "shellapi.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct {
|
||||
IWICComponentFactory IWICComponentFactory_iface;
|
||||
LONG ref;
|
||||
|
@ -104,22 +120,23 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(
|
|||
return hr;
|
||||
}
|
||||
|
||||
static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
|
||||
WICDecodeOptions metadataOptions)
|
||||
static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor,
|
||||
WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder)
|
||||
{
|
||||
IEnumUnknown *enumdecoders;
|
||||
IUnknown *unkdecoderinfo;
|
||||
IWICBitmapDecoderInfo *decoderinfo;
|
||||
IWICBitmapDecoder *decoder = NULL;
|
||||
GUID vendor;
|
||||
HRESULT res;
|
||||
ULONG num_fetched;
|
||||
BOOL matches;
|
||||
|
||||
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
|
||||
if (FAILED(res)) return NULL;
|
||||
*decoder = NULL;
|
||||
|
||||
while (!decoder)
|
||||
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
|
||||
if (FAILED(res)) return res;
|
||||
|
||||
while (!*decoder)
|
||||
{
|
||||
res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
|
||||
|
||||
|
@ -144,18 +161,21 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
|
|||
|
||||
if (SUCCEEDED(res) && matches)
|
||||
{
|
||||
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
|
||||
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder);
|
||||
|
||||
/* FIXME: should use QueryCapability to choose a decoder */
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);
|
||||
res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
IWICBitmapDecoder_Release(decoder);
|
||||
decoder = NULL;
|
||||
IWICBitmapDecoder_Release(*decoder);
|
||||
IWICBitmapDecoderInfo_Release(decoderinfo);
|
||||
IUnknown_Release(unkdecoderinfo);
|
||||
*decoder = NULL;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +191,7 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
|
|||
|
||||
IEnumUnknown_Release(enumdecoders);
|
||||
|
||||
return decoder;
|
||||
return WINCODEC_ERR_COMPONENTNOTFOUND;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
||||
|
@ -185,9 +205,9 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
|||
metadataOptions, ppIDecoder);
|
||||
|
||||
if (pguidVendor)
|
||||
decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
|
||||
res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder);
|
||||
if (!decoder)
|
||||
decoder = find_decoder(pIStream, NULL, metadataOptions);
|
||||
res = find_decoder(pIStream, NULL, metadataOptions, &decoder);
|
||||
|
||||
if (decoder)
|
||||
{
|
||||
|
@ -202,17 +222,17 @@ static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
|
|||
BYTE data[4];
|
||||
ULONG bytesread;
|
||||
|
||||
WARN("failed to load from a stream\n");
|
||||
WARN("failed to load from a stream %#x\n", res);
|
||||
|
||||
seek.QuadPart = 0;
|
||||
res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
|
||||
if (SUCCEEDED(res))
|
||||
res = IStream_Read(pIStream, data, 4, &bytesread);
|
||||
if (SUCCEEDED(res))
|
||||
WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
|
||||
if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK)
|
||||
{
|
||||
if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK)
|
||||
WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
}
|
||||
*ppIDecoder = NULL;
|
||||
return WINCODEC_ERR_COMPONENTNOTFOUND;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,12 +599,36 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto
|
|||
UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
|
||||
UINT size, BYTE *buffer, IWICBitmap **bitmap)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
|
||||
debugstr_guid(format), stride, size, buffer, bitmap);
|
||||
|
||||
if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
|
||||
|
||||
return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);
|
||||
hr = BitmapImpl_Create(width, height, stride, size, NULL, format, WICBitmapCacheOnLoad, bitmap);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
IWICBitmapLock *lock;
|
||||
|
||||
hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
UINT buffersize;
|
||||
BYTE *data;
|
||||
|
||||
IWICBitmapLock_GetDataPointer(lock, &buffersize, &data);
|
||||
memcpy(data, buffer, buffersize);
|
||||
|
||||
IWICBitmapLock_Release(lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
IWICBitmap_Release(*bitmap);
|
||||
*bitmap = NULL;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)
|
||||
|
@ -1160,3 +1204,50 @@ HRESULT ComponentFactory_CreateInstance(REFIID iid, void** ppv)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height,
|
||||
REFWICPixelFormatGUID format, HANDLE section, UINT stride,
|
||||
UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap)
|
||||
{
|
||||
DWORD access;
|
||||
void *buffer;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%u,%u,%s,%p,%u,%#x,%#x,%p\n", width, height, debugstr_guid(format),
|
||||
section, stride, offset, wicaccess, bitmap);
|
||||
|
||||
if (!width || !height || !section || !bitmap) return E_INVALIDARG;
|
||||
|
||||
switch (wicaccess)
|
||||
{
|
||||
case WICSectionAccessLevelReadWrite:
|
||||
access = FILE_MAP_READ | FILE_MAP_WRITE;
|
||||
break;
|
||||
|
||||
case WICSectionAccessLevelRead:
|
||||
access = FILE_MAP_READ;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unsupported access %#x\n", wicaccess);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
buffer = MapViewOfFile(section, access, 0, offset, 0);
|
||||
if (!buffer) return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
hr = BitmapImpl_Create(width, height, stride, 0, buffer, format, WICBitmapCacheOnLoad, bitmap);
|
||||
if (FAILED(hr)) UnmapViewOfFile(buffer);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height,
|
||||
REFWICPixelFormatGUID format, HANDLE section,
|
||||
UINT stride, UINT offset, IWICBitmap **bitmap)
|
||||
{
|
||||
TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format),
|
||||
section, stride, offset, bitmap);
|
||||
|
||||
return WICCreateBitmapFromSectionEx(width, height, format, section,
|
||||
stride, offset, WICSectionAccessLevelRead, bitmap);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,24 @@
|
|||
* 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 "winreg.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <wine/list.h>
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
|
||||
static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0};
|
||||
|
@ -853,8 +868,12 @@ static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *ifac
|
|||
static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
|
||||
UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
|
||||
{
|
||||
FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
return E_NOTIMPL;
|
||||
BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
|
||||
|
||||
TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
|
||||
return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
|
||||
cchFileExtensions, wzFileExtensions, pcchActual);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
|
||||
|
@ -2265,6 +2284,12 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn
|
|||
return hr;
|
||||
}
|
||||
|
||||
static BOOL is_1bpp_format(const WICPixelFormatGUID *format)
|
||||
{
|
||||
return IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite) ||
|
||||
IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed);
|
||||
}
|
||||
|
||||
HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
|
||||
{
|
||||
HRESULT res;
|
||||
|
@ -2277,10 +2302,12 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma
|
|||
BOOL canconvert;
|
||||
ULONG num_fetched;
|
||||
|
||||
TRACE("%s,%p,%p\n", debugstr_guid(dstFormat), pISrc, ppIDst);
|
||||
|
||||
res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
|
||||
if (FAILED(res)) return res;
|
||||
|
||||
if (IsEqualGUID(&srcFormat, dstFormat))
|
||||
if (IsEqualGUID(&srcFormat, dstFormat) || (is_1bpp_format(&srcFormat) && is_1bpp_format(dstFormat)))
|
||||
{
|
||||
IWICBitmapSource_AddRef(pISrc);
|
||||
*ppIDst = pISrc;
|
||||
|
@ -2317,7 +2344,7 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma
|
|||
|
||||
if (SUCCEEDED(res) && canconvert)
|
||||
res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
|
||||
NULL, 0.0, WICBitmapPaletteTypeCustom);
|
||||
NULL, 0.0, WICBitmapPaletteTypeMedianCut);
|
||||
|
||||
if (FAILED(res) || !canconvert)
|
||||
{
|
||||
|
|
|
@ -16,11 +16,16 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef SONAME_LIBJPEG
|
||||
/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
|
||||
|
@ -37,6 +42,19 @@
|
|||
#undef boolean
|
||||
#endif
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
#ifdef SONAME_LIBJPEG
|
||||
WINE_DECLARE_DEBUG_CHANNEL(jpeg);
|
||||
|
||||
|
@ -405,10 +423,14 @@ static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI JpegDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
IWICMetadataQueryReader **reader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
FIXME("(%p,%p): stub\n", iface, reader);
|
||||
|
||||
if (!reader) return E_INVALIDARG;
|
||||
|
||||
*reader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -662,9 +684,15 @@ static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
|
|||
}
|
||||
|
||||
if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker)
|
||||
{
|
||||
DWORD *pDwordData = (DWORD*) (This->image_data + stride * first_scanline);
|
||||
DWORD *pDwordDataEnd = (DWORD*) (This->image_data + This->cinfo.output_scanline * stride);
|
||||
|
||||
/* Adobe JPEG's have inverted CMYK data. */
|
||||
for (i=0; i<data_size; i++)
|
||||
This->image_data[i] ^= 0xff;
|
||||
while(pDwordData < pDwordDataEnd)
|
||||
*pDwordData++ ^= 0xffffffff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
@ -1375,11 +1403,22 @@ static HRESULT WINAPI JpegEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
|
||||
return E_NOTIMPL;
|
||||
IWICComponentInfo *comp_info;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", iface, info);
|
||||
|
||||
if (!info) return E_INVALIDARG;
|
||||
|
||||
hr = CreateComponentInfo(&CLSID_WICJpegEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -1422,7 +1461,15 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
{
|
||||
JpegEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
HRESULT hr;
|
||||
PROPBAG2 opts[6] = {{0}};
|
||||
static const PROPBAG2 opts[6] =
|
||||
{
|
||||
{ PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszImageQuality },
|
||||
{ PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszBitmapTransform },
|
||||
{ PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszLuminance },
|
||||
{ PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszChrominance },
|
||||
{ PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszJpegYCrCbSubsampling },
|
||||
{ PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszSuppressApp0 },
|
||||
};
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
|
||||
|
||||
|
@ -1440,30 +1487,14 @@ static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
opts[0].pstrName = (LPOLESTR)wszImageQuality;
|
||||
opts[0].vt = VT_R4;
|
||||
opts[0].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[1].pstrName = (LPOLESTR)wszBitmapTransform;
|
||||
opts[1].vt = VT_UI1;
|
||||
opts[1].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[2].pstrName = (LPOLESTR)wszLuminance;
|
||||
opts[2].vt = VT_I4|VT_ARRAY;
|
||||
opts[2].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[3].pstrName = (LPOLESTR)wszChrominance;
|
||||
opts[3].vt = VT_I4|VT_ARRAY;
|
||||
opts[3].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[4].pstrName = (LPOLESTR)wszJpegYCrCbSubsampling;
|
||||
opts[4].vt = VT_UI1;
|
||||
opts[4].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[5].pstrName = (LPOLESTR)wszSuppressApp0;
|
||||
opts[5].vt = VT_BOOL;
|
||||
opts[5].dwType = PROPBAG2_TYPE_DATA;
|
||||
|
||||
hr = CreatePropertyBag2(opts, 6, ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
if (ppIEncoderOptions)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
This->frame_count = 1;
|
||||
|
|
|
@ -16,8 +16,22 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#define COBJMACROS
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
|
|
|
@ -17,11 +17,25 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/winternl.h"
|
||||
#include "objbase.h"
|
||||
#include "propvarutil.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wine/winternl.h>
|
||||
#include <propvarutil.h>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct MetadataHandler {
|
||||
IWICMetadataWriter IWICMetadataWriter_iface;
|
||||
|
@ -704,7 +718,7 @@ static int tag_to_vt(SHORT tag)
|
|||
static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||
MetadataItem *item, BOOL native_byte_order)
|
||||
{
|
||||
ULONG count, value, i, bytesread;
|
||||
ULONG count, value, i;
|
||||
SHORT type;
|
||||
LARGE_INTEGER pos;
|
||||
HRESULT hr;
|
||||
|
@ -746,7 +760,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
|
||||
item->value.vt |= VT_VECTOR;
|
||||
item->value.u.caub.cElems = count;
|
||||
item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
|
||||
item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count);
|
||||
if (!item->value.u.caub.pElems) return E_OUTOFMEMORY;
|
||||
|
||||
pos.QuadPart = value;
|
||||
|
@ -756,9 +770,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread);
|
||||
if (bytesread != count) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
||||
return hr;
|
||||
|
@ -791,7 +804,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
|
||||
item->value.vt |= VT_VECTOR;
|
||||
item->value.u.caui.cElems = count;
|
||||
item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
|
||||
item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2);
|
||||
if (!item->value.u.caui.pElems) return E_OUTOFMEMORY;
|
||||
|
||||
pos.QuadPart = value;
|
||||
|
@ -801,9 +814,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread);
|
||||
if (bytesread != count * 2) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
||||
return hr;
|
||||
|
@ -824,7 +836,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
|
||||
item->value.vt |= VT_VECTOR;
|
||||
item->value.u.caul.cElems = count;
|
||||
item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4);
|
||||
item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4);
|
||||
if (!item->value.u.caul.pElems) return E_OUTOFMEMORY;
|
||||
|
||||
pos.QuadPart = value;
|
||||
|
@ -834,9 +846,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread);
|
||||
if (bytesread != count * 4) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
||||
return hr;
|
||||
|
@ -862,8 +873,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
hr = IStream_Seek(input, pos, SEEK_SET, NULL);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = IStream_Read(input, &ull, sizeof(ull), &bytesread);
|
||||
if (bytesread != sizeof(ull)) hr = E_FAIL;
|
||||
hr = IStream_Read(input, &ull, sizeof(ull), NULL);
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
item->value.u.uhVal.QuadPart = ull;
|
||||
|
@ -881,7 +891,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
{
|
||||
item->value.vt |= VT_VECTOR;
|
||||
item->value.u.cauh.cElems = count;
|
||||
item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8);
|
||||
item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8);
|
||||
if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY;
|
||||
|
||||
pos.QuadPart = value;
|
||||
|
@ -891,9 +901,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread);
|
||||
if (bytesread != count * 8) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
||||
return hr;
|
||||
|
@ -911,7 +920,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
}
|
||||
break;
|
||||
case IFD_ASCII:
|
||||
item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1);
|
||||
item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1);
|
||||
if (!item->value.u.pszVal) return E_OUTOFMEMORY;
|
||||
|
||||
if (count <= 4)
|
||||
|
@ -929,9 +938,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread);
|
||||
if (bytesread != count) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.pszVal, count, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
||||
return hr;
|
||||
|
@ -946,7 +954,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
break;
|
||||
}
|
||||
|
||||
item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), 0, count);
|
||||
item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count);
|
||||
if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY;
|
||||
|
||||
item->value.u.blob.cbSize = count;
|
||||
|
@ -965,9 +973,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
|||
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
||||
return hr;
|
||||
}
|
||||
hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread);
|
||||
if (bytesread != count) hr = E_FAIL;
|
||||
if (hr != S_OK)
|
||||
hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
||||
return hr;
|
||||
|
|
|
@ -17,9 +17,23 @@
|
|||
* 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 "propvarutil.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <propvarutil.h>
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2009 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2012 Dmitry Timoshkov
|
||||
* Copyright 2012,2016 Dmitry Timoshkov
|
||||
* Copyright 2016 Sebastian Lackner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -17,8 +18,23 @@
|
|||
* 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 "winreg.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct {
|
||||
IWICPalette IWICPalette_iface;
|
||||
LONG ref;
|
||||
|
@ -431,11 +447,279 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *iface,
|
||||
IWICBitmapSource *pISurface, UINT colorCount, BOOL fAddTransparentColor)
|
||||
#define R_COUNT (1 << 5)
|
||||
#define R_SHIFT (8 - 5)
|
||||
#define R_SCALE 2
|
||||
|
||||
#define G_COUNT (1 << 6)
|
||||
#define G_SHIFT (8 - 6)
|
||||
#define G_SCALE 3
|
||||
|
||||
#define B_COUNT (1 << 5)
|
||||
#define B_SHIFT (8 - 5)
|
||||
#define B_SCALE 1
|
||||
|
||||
struct histogram
|
||||
{
|
||||
FIXME("(%p,%p,%u,%i): stub\n", iface, pISurface, colorCount, fAddTransparentColor);
|
||||
return E_NOTIMPL;
|
||||
unsigned int data[R_COUNT][G_COUNT][B_COUNT];
|
||||
};
|
||||
|
||||
struct box
|
||||
{
|
||||
int r_min, r_max;
|
||||
int g_min, g_max;
|
||||
int b_min, b_max;
|
||||
unsigned int count;
|
||||
unsigned int score;
|
||||
};
|
||||
|
||||
/* count nonzero elements in the histogram range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */
|
||||
static inline unsigned int histogram_count(struct histogram *h, int r_min, int r_max,
|
||||
int g_min, int g_max, int b_min, int b_max)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
int r, g, b;
|
||||
for (r = r_min; r <= r_max; r++)
|
||||
for (g = g_min; g <= g_max; g++)
|
||||
for (b = b_min; b <= b_max; b++)
|
||||
if (h->data[r][g][b] != 0) count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
/* compute weighted average color in the range [r_min, r_max] x [g_min, g_max] x [b_min, b_max] */
|
||||
static unsigned int histogram_color(struct histogram *h, int r_min, int r_max,
|
||||
int g_min, int g_max, int b_min, int b_max)
|
||||
{
|
||||
unsigned long long r_sum = 0, g_sum = 0, b_sum = 0;
|
||||
unsigned int tmp, count = 0;
|
||||
int r, g, b;
|
||||
|
||||
for (r = r_min; r <= r_max; r++)
|
||||
for (g = g_min; g <= g_max; g++)
|
||||
for (b = b_min; b <= b_max; b++)
|
||||
{
|
||||
if (!(tmp = h->data[r][g][b])) continue;
|
||||
r_sum += ((r << R_SHIFT) + ((1 << R_SHIFT) / 2)) * tmp;
|
||||
g_sum += ((g << G_SHIFT) + ((1 << G_SHIFT) / 2)) * tmp;
|
||||
b_sum += ((b << B_SHIFT) + ((1 << B_SHIFT) / 2)) * tmp;
|
||||
count += tmp;
|
||||
}
|
||||
|
||||
return ((b_sum + (count / 2)) / count) |
|
||||
((g_sum + (count / 2)) / count) << 8 |
|
||||
((r_sum + (count / 2)) / count) << 16 | 0xff000000;
|
||||
}
|
||||
|
||||
/* same as histogram_count */
|
||||
static inline unsigned int box_count(struct histogram *h, struct box *b)
|
||||
{
|
||||
return histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max);
|
||||
}
|
||||
|
||||
/* same as histogram_color */
|
||||
static inline unsigned int box_color(struct histogram *h, struct box *b)
|
||||
{
|
||||
return histogram_color(h, b->r_min, b->r_max, b->g_min, b->g_max, b->b_min, b->b_max);
|
||||
}
|
||||
|
||||
/* compute score used to determine best split (also called "volume") */
|
||||
static inline unsigned int box_score(struct box *b)
|
||||
{
|
||||
unsigned int tmp, sum = 0;
|
||||
tmp = ((b->r_max - b->r_min) << R_SHIFT) * R_SCALE; sum += tmp * tmp;
|
||||
tmp = ((b->g_max - b->g_min) << G_SHIFT) * G_SCALE; sum += tmp * tmp;
|
||||
tmp = ((b->b_max - b->b_min) << B_SHIFT) * B_SCALE; sum += tmp * tmp;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* attempt to shrink a box */
|
||||
static void shrink_box(struct histogram *h, struct box *b)
|
||||
{
|
||||
int i;
|
||||
for (i = b->r_min; i <= b->r_max; i++)
|
||||
if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_min = i; break; }
|
||||
for (i = b->r_max; i >= b->r_min; i--)
|
||||
if (histogram_count(h, i, i, b->g_min, b->g_max, b->b_min, b->b_max)) { b->r_max = i; break; }
|
||||
for (i = b->g_min; i <= b->g_max; i++)
|
||||
if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_min = i; break; }
|
||||
for (i = b->g_max; i >= b->g_min; i--)
|
||||
if (histogram_count(h, b->r_min, b->r_max, i, i, b->b_min, b->b_max)) { b->g_max = i; break; }
|
||||
for (i = b->b_min; i <= b->b_max; i++)
|
||||
if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_min = i; break; }
|
||||
for (i = b->b_max; i >= b->b_min; i--)
|
||||
if (histogram_count(h, b->r_min, b->r_max, b->g_min, b->g_max, i, i)) { b->b_max = i; break; }
|
||||
b->count = box_count(h, b);
|
||||
b->score = box_score(b);
|
||||
}
|
||||
|
||||
/* helper for split_box */
|
||||
static inline void set_avg(int *min, int *max)
|
||||
{
|
||||
int avg = (*min + *max) / 2;
|
||||
*min = avg + 1;
|
||||
*max = avg;
|
||||
}
|
||||
|
||||
/* split a box based on the best axis */
|
||||
static void split_box(struct histogram *h, struct box *b1, struct box *b2)
|
||||
{
|
||||
int r = ((b1->r_max - b1->r_min) << R_SHIFT) * R_SCALE;
|
||||
int g = ((b1->g_max - b1->g_min) << G_SHIFT) * G_SCALE;
|
||||
int b = ((b1->b_max - b1->b_min) << B_SHIFT) * B_SCALE;
|
||||
|
||||
*b2 = *b1;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
if (b > r) set_avg(&b1->b_min, &b2->b_max);
|
||||
else set_avg(&b1->r_min, &b2->r_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b > g) set_avg(&b1->b_min, &b2->b_max);
|
||||
else set_avg(&b1->g_min, &b2->g_max);
|
||||
}
|
||||
|
||||
shrink_box(h, b1);
|
||||
shrink_box(h, b2);
|
||||
}
|
||||
|
||||
/* find box suitable for split based on count */
|
||||
static struct box *find_box_max_count(struct box *b, int count)
|
||||
{
|
||||
struct box *best = NULL;
|
||||
for (; count--; b++)
|
||||
if (b->score && (!best || b->count > best->count)) best = b;
|
||||
return best;
|
||||
}
|
||||
|
||||
/* find box suitable for split based on score */
|
||||
static struct box *find_box_max_score(struct box *b, int count)
|
||||
{
|
||||
struct box *best = NULL;
|
||||
for (; count--; b++)
|
||||
if (b->score && (!best || b->score > best->score)) best = b;
|
||||
return best;
|
||||
}
|
||||
|
||||
/* compute color map with at most 'desired' colors
|
||||
* image must be in 24bpp BGR format and colors are returned in 0xAARRGGBB format */
|
||||
static int median_cut(unsigned char *image, unsigned int width, unsigned int height,
|
||||
unsigned int stride, int desired, unsigned int *colors)
|
||||
{
|
||||
struct box boxes[256];
|
||||
struct histogram *h;
|
||||
unsigned int x, y;
|
||||
unsigned char *p;
|
||||
struct box *b1, *b2;
|
||||
int numboxes, i;
|
||||
|
||||
if (!(h = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*h))))
|
||||
return 0;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0, p = image + y * stride; x < width; x++, p += 3)
|
||||
h->data[p[2] >> R_SHIFT][p[1] >> G_SHIFT][p[0] >> B_SHIFT]++;
|
||||
|
||||
numboxes = 1;
|
||||
boxes[0].r_min = 0; boxes[0].r_max = R_COUNT - 1;
|
||||
boxes[0].g_min = 0; boxes[0].g_max = G_COUNT - 1;
|
||||
boxes[0].b_min = 0; boxes[0].b_max = B_COUNT - 1;
|
||||
shrink_box(h, &boxes[0]);
|
||||
|
||||
while (numboxes <= desired / 2)
|
||||
{
|
||||
if (!(b1 = find_box_max_count(boxes, numboxes))) break;
|
||||
b2 = &boxes[numboxes++];
|
||||
split_box(h, b1, b2);
|
||||
}
|
||||
while (numboxes < desired)
|
||||
{
|
||||
if (!(b1 = find_box_max_score(boxes, numboxes))) break;
|
||||
b2 = &boxes[numboxes++];
|
||||
split_box(h, b1, b2);
|
||||
}
|
||||
|
||||
for (i = 0; i < numboxes; i++)
|
||||
colors[i] = box_color(h, &boxes[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, h);
|
||||
return numboxes;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *palette,
|
||||
IWICBitmapSource *source, UINT desired, BOOL add_transparent)
|
||||
{
|
||||
IWICImagingFactory *factory = NULL;
|
||||
IWICBitmap *rgb24_bitmap = NULL;
|
||||
IWICBitmapSource *rgb24_source;
|
||||
IWICBitmapLock *lock = NULL;
|
||||
WICPixelFormatGUID format;
|
||||
HRESULT hr;
|
||||
UINT width, height, stride, size, actual_number_of_colors;
|
||||
BYTE *src;
|
||||
WICColor colors[256];
|
||||
|
||||
TRACE("(%p,%p,%u,%d)\n", palette, source, desired, add_transparent);
|
||||
|
||||
if (!source || desired < 2 || desired > 256)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hr = IWICBitmapSource_GetPixelFormat(source, &format);
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
/* For interoperability with gdiplus where PixelFormat24bppRGB actully stored
|
||||
* as BGR (and there is no a corresponding RGB format) we have to use 24bppBGR
|
||||
* to avoid format conversions.
|
||||
*/
|
||||
if (!IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR))
|
||||
{
|
||||
hr = WICConvertBitmapSource(&GUID_WICPixelFormat24bppBGR, source, &rgb24_source);
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
else
|
||||
rgb24_source = source;
|
||||
|
||||
hr = ComponentFactory_CreateInstance(&IID_IWICImagingFactory, (void **)&factory);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
hr = IWICImagingFactory_CreateBitmapFromSource(factory, rgb24_source, WICBitmapCacheOnLoad, &rgb24_bitmap);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
hr = IWICBitmap_Lock(rgb24_bitmap, NULL, WICBitmapLockRead, &lock);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
IWICBitmapLock_GetSize(lock, &width, &height);
|
||||
IWICBitmapLock_GetStride(lock, &stride);
|
||||
IWICBitmapLock_GetDataPointer(lock, &size, &src);
|
||||
|
||||
actual_number_of_colors = median_cut(src, width, height, stride, add_transparent ? desired - 1 : desired, colors);
|
||||
TRACE("actual number of colors: %u\n", actual_number_of_colors);
|
||||
|
||||
if (actual_number_of_colors)
|
||||
{
|
||||
if (add_transparent) colors[actual_number_of_colors++] = 0;
|
||||
|
||||
hr = IWICPalette_InitializeCustom(palette, colors, actual_number_of_colors);
|
||||
}
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
fail:
|
||||
if (lock)
|
||||
IWICBitmapLock_Release(lock);
|
||||
|
||||
if (rgb24_bitmap)
|
||||
IWICBitmap_Release(rgb24_bitmap);
|
||||
|
||||
if (factory)
|
||||
IWICImagingFactory_Release(factory);
|
||||
|
||||
if (rgb24_source != source)
|
||||
IWICBitmapSource_Release(rgb24_source);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface,
|
||||
|
|
|
@ -17,12 +17,29 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_PNG_H
|
||||
#include <png.h>
|
||||
#endif
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
static inline ULONG read_ulong_be(BYTE* data)
|
||||
{
|
||||
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
|
@ -605,7 +622,7 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
|
|||
ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info);
|
||||
HeapFree(GetProcessHeap(), 0, row_pointers);
|
||||
This->png_ptr = NULL;
|
||||
hr = E_FAIL;
|
||||
hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT;
|
||||
goto end;
|
||||
}
|
||||
ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn);
|
||||
|
@ -836,10 +853,14 @@ static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
|||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
IWICMetadataQueryReader **reader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
FIXME("(%p,%p): stub\n", iface, reader);
|
||||
|
||||
if (!reader) return E_INVALIDARG;
|
||||
|
||||
*reader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -1969,11 +1990,22 @@ static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
|
||||
return E_NOTIMPL;
|
||||
IWICComponentInfo *comp_info;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", iface, info);
|
||||
|
||||
if (!info) return E_INVALIDARG;
|
||||
|
||||
hr = CreateComponentInfo(&CLSID_WICPngEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -2016,7 +2048,11 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
{
|
||||
PngEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
HRESULT hr;
|
||||
PROPBAG2 opts[2]= {{0}};
|
||||
static const PROPBAG2 opts[2] =
|
||||
{
|
||||
{ PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption },
|
||||
{ PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption },
|
||||
};
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
|
||||
|
||||
|
@ -2034,18 +2070,14 @@ static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption;
|
||||
opts[0].vt = VT_BOOL;
|
||||
opts[0].dwType = PROPBAG2_TYPE_DATA;
|
||||
opts[1].pstrName = (LPOLESTR)wszPngFilterOption;
|
||||
opts[1].vt = VT_UI1;
|
||||
opts[1].dwType = PROPBAG2_TYPE_DATA;
|
||||
|
||||
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
if (ppIEncoderOptions)
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
This->frame_count = 1;
|
||||
|
|
30
dll/win32/windowscodecs/precomp.h
Normal file
30
dll/win32/windowscodecs/precomp.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
#ifndef WINCODECS_PRECOMP_H
|
||||
#define WINCODECS_PRECOMP_H
|
||||
|
||||
#include <wine/config.h>
|
||||
#include <wine/port.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wingdi.h>
|
||||
#include <winreg.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/library.h>
|
||||
|
||||
#endif /* !WINCODECS_PRECOMP_H */
|
|
@ -17,8 +17,23 @@
|
|||
* 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 "wine/unicode.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct PropertyBag {
|
||||
IPropertyBag2 IPropertyBag2_iface;
|
||||
LONG ref;
|
||||
|
@ -198,7 +213,7 @@ static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *p
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT copy_propbag2(PROPBAG2 *dest, PROPBAG2 *src)
|
||||
static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
|
||||
{
|
||||
dest->cfType = src->cfType;
|
||||
dest->clsid = src->clsid;
|
||||
|
@ -263,7 +278,7 @@ static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
|
|||
PropertyBag_LoadObject
|
||||
};
|
||||
|
||||
HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count,
|
||||
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count,
|
||||
IPropertyBag2 **ppPropertyBag2)
|
||||
{
|
||||
UINT i;
|
||||
|
|
|
@ -18,8 +18,22 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
HRESULT WINAPI IPropertyBag2_Write_Proxy(IPropertyBag2 *iface,
|
||||
ULONG cProperties, PROPBAG2 *ppropbag, VARIANT *pvarValue)
|
||||
{
|
||||
|
|
|
@ -16,9 +16,26 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
#include "ocidl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
/***********************************************************************
|
||||
* interface for self-registering
|
||||
|
@ -1194,6 +1211,10 @@ static GUID const * const tiff_decode_formats[] = {
|
|||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat4bppGray,
|
||||
&GUID_WICPixelFormat8bppGray,
|
||||
&GUID_WICPixelFormat16bppGray,
|
||||
&GUID_WICPixelFormat32bppGrayFloat,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
|
@ -1203,6 +1224,9 @@ static GUID const * const tiff_decode_formats[] = {
|
|||
&GUID_WICPixelFormat48bppRGB,
|
||||
&GUID_WICPixelFormat64bppRGBA,
|
||||
&GUID_WICPixelFormat64bppPRGBA,
|
||||
&GUID_WICPixelFormat32bppCMYK,
|
||||
&GUID_WICPixelFormat64bppCMYK,
|
||||
&GUID_WICPixelFormat128bppRGBAFloat,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1328,6 +1352,11 @@ static GUID const * const bmp_encode_formats[] = {
|
|||
&GUID_WICPixelFormat16bppBGR565,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
&GUID_WICPixelFormat32bppBGR,
|
||||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1353,6 +1382,10 @@ static GUID const * const tiff_encode_formats[] = {
|
|||
&GUID_WICPixelFormatBlackWhite,
|
||||
&GUID_WICPixelFormat4bppGray,
|
||||
&GUID_WICPixelFormat8bppGray,
|
||||
&GUID_WICPixelFormat1bppIndexed,
|
||||
&GUID_WICPixelFormat2bppIndexed,
|
||||
&GUID_WICPixelFormat4bppIndexed,
|
||||
&GUID_WICPixelFormat8bppIndexed,
|
||||
&GUID_WICPixelFormat24bppBGR,
|
||||
&GUID_WICPixelFormat32bppBGRA,
|
||||
&GUID_WICPixelFormat32bppPBGRA,
|
||||
|
@ -1378,6 +1411,16 @@ static struct regsvr_encoder const encoder_list[] = {
|
|||
".bmp,.dib,.rle",
|
||||
bmp_encode_formats
|
||||
},
|
||||
{ &CLSID_WICGifEncoder,
|
||||
"The Wine Project",
|
||||
"GIF Encoder",
|
||||
"1.0.0.0",
|
||||
&GUID_VendorMicrosoft,
|
||||
&GUID_ContainerFormatGif,
|
||||
"image/gif",
|
||||
".gif",
|
||||
gif_formats
|
||||
},
|
||||
{ &CLSID_WICJpegEncoder,
|
||||
"The Wine Project",
|
||||
"JPEG Encoder",
|
||||
|
@ -1437,8 +1480,11 @@ static GUID const * const converter_formats[] = {
|
|||
&GUID_WICPixelFormat24bppBGR,
|
||||
&GUID_WICPixelFormat24bppRGB,
|
||||
&GUID_WICPixelFormat32bppBGR,
|
||||
&GUID_WICPixelFormat32bppRGB,
|
||||
&GUID_WICPixelFormat32bppBGRA,
|
||||
&GUID_WICPixelFormat32bppRGBA,
|
||||
&GUID_WICPixelFormat32bppPBGRA,
|
||||
&GUID_WICPixelFormat32bppPRGBA,
|
||||
&GUID_WICPixelFormat32bppGrayFloat,
|
||||
&GUID_WICPixelFormat48bppRGB,
|
||||
&GUID_WICPixelFormat64bppRGBA,
|
||||
|
@ -1710,6 +1756,13 @@ static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
|||
static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||
static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
|
||||
static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
|
||||
|
||||
static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
|
||||
static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
|
||||
static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
|
||||
|
@ -1726,6 +1779,9 @@ static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
|
|||
static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
|
||||
channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
|
||||
|
||||
static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit };
|
||||
static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 };
|
||||
|
||||
static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
|
||||
channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
|
||||
|
||||
|
@ -1742,7 +1798,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
1, /* channel count */
|
||||
channel_masks_1bit,
|
||||
WICPixelFormatNumericRepresentationIndexed,
|
||||
1
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat2bppIndexed,
|
||||
"The Wine Project",
|
||||
|
@ -1753,7 +1809,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
1, /* channel count */
|
||||
channel_masks_2bit,
|
||||
WICPixelFormatNumericRepresentationIndexed,
|
||||
1
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat4bppIndexed,
|
||||
"The Wine Project",
|
||||
|
@ -1764,7 +1820,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
1, /* channel count */
|
||||
channel_masks_4bit,
|
||||
WICPixelFormatNumericRepresentationIndexed,
|
||||
1
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat8bppIndexed,
|
||||
"The Wine Project",
|
||||
|
@ -1775,7 +1831,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
1, /* channel count */
|
||||
channel_masks_8bit,
|
||||
WICPixelFormatNumericRepresentationIndexed,
|
||||
1
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormatBlackWhite,
|
||||
"The Wine Project",
|
||||
|
@ -1898,6 +1954,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppRGB,
|
||||
"The Wine Project",
|
||||
"32bpp RGB",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
32, /* bitsperpixel */
|
||||
3, /* channel count */
|
||||
channel_masks_8bit,
|
||||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppBGRA,
|
||||
"The Wine Project",
|
||||
"32bpp BGRA",
|
||||
|
@ -1909,6 +1976,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppRGBA,
|
||||
"The Wine Project",
|
||||
"32bpp RGBA",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
32, /* bitsperpixel */
|
||||
4, /* channel count */
|
||||
channel_masks_8bit,
|
||||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppPBGRA,
|
||||
"The Wine Project",
|
||||
"32bpp PBGRA",
|
||||
|
@ -1920,6 +1998,28 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppPRGBA,
|
||||
"The Wine Project",
|
||||
"32bpp PRGBA",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
32, /* bitsperpixel */
|
||||
4, /* channel count */
|
||||
channel_masks_8bit,
|
||||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
1
|
||||
},
|
||||
{ &GUID_WICPixelFormat32bppGrayFloat,
|
||||
"The Wine Project",
|
||||
"32bpp GrayFloat",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
32, /* bitsperpixel */
|
||||
1, /* channel count */
|
||||
channel_masks_32bit,
|
||||
WICPixelFormatNumericRepresentationFloat,
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat48bppRGB,
|
||||
"The Wine Project",
|
||||
"48bpp RGB",
|
||||
|
@ -1964,6 +2064,28 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
|
|||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat64bppCMYK,
|
||||
"The Wine Project",
|
||||
"64bpp CMYK",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
64, /* bitsperpixel */
|
||||
4, /* channel count */
|
||||
channel_masks_16bit,
|
||||
WICPixelFormatNumericRepresentationUnsignedInteger,
|
||||
0
|
||||
},
|
||||
{ &GUID_WICPixelFormat128bppRGBAFloat,
|
||||
"The Wine Project",
|
||||
"128bpp RGBAFloat",
|
||||
NULL, /* no version */
|
||||
&GUID_VendorMicrosoft,
|
||||
128, /* bitsperpixel */
|
||||
4, /* channel count */
|
||||
channel_masks_128bit,
|
||||
WICPixelFormatNumericRepresentationFloat,
|
||||
1
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
|
|
|
@ -16,11 +16,26 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
typedef struct BitmapScaler {
|
||||
IWICBitmapScaler IWICBitmapScaler_iface;
|
||||
LONG ref;
|
||||
IMILBitmapScaler IMILBitmapScaler_iface;
|
||||
IWICBitmapSource *source;
|
||||
UINT width, height;
|
||||
UINT src_width, src_height;
|
||||
|
@ -36,6 +51,11 @@ static inline BitmapScaler *impl_from_IWICBitmapScaler(IWICBitmapScaler *iface)
|
|||
return CONTAINING_RECORD(iface, BitmapScaler, IWICBitmapScaler_iface);
|
||||
}
|
||||
|
||||
static inline BitmapScaler *impl_from_IMILBitmapScaler(IMILBitmapScaler *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, BitmapScaler, IMILBitmapScaler_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
|
@ -50,8 +70,13 @@ static HRESULT WINAPI BitmapScaler_QueryInterface(IWICBitmapScaler *iface, REFII
|
|||
{
|
||||
*ppv = &This->IWICBitmapScaler_iface;
|
||||
}
|
||||
else if (IsEqualIID(&IID_IMILBitmapScaler, iid))
|
||||
{
|
||||
*ppv = &This->IMILBitmapScaler_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("unknown interface %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
@ -360,6 +385,163 @@ static const IWICBitmapScalerVtbl BitmapScaler_Vtbl = {
|
|||
BitmapScaler_Initialize
|
||||
};
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_QueryInterface(IMILBitmapScaler *iface, REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
|
||||
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
|
||||
|
||||
if (!ppv) return E_INVALIDARG;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, iid) ||
|
||||
IsEqualIID(&IID_IMILBitmapScaler, iid) ||
|
||||
IsEqualIID(&IID_IMILBitmapSource, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IMILBitmapScaler_iface);
|
||||
*ppv = &This->IMILBitmapScaler_iface;
|
||||
return S_OK;
|
||||
}
|
||||
else if (IsEqualIID(&IID_IWICBitmapScaler, iid) ||
|
||||
IsEqualIID(&IID_IWICBitmapSource, iid))
|
||||
{
|
||||
IUnknown_AddRef(&This->IWICBitmapScaler_iface);
|
||||
*ppv = &This->IWICBitmapScaler_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("unknown interface %s\n", debugstr_guid(iid));
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMILBitmapScaler_AddRef(IMILBitmapScaler *iface)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
return IWICBitmapScaler_AddRef(&This->IWICBitmapScaler_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMILBitmapScaler_Release(IMILBitmapScaler *iface)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
return IWICBitmapScaler_Release(&This->IWICBitmapScaler_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_GetSize(IMILBitmapScaler *iface,
|
||||
UINT *width, UINT *height)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, width, height);
|
||||
|
||||
if (!This->source)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
return IWICBitmapScaler_GetSize(&This->IWICBitmapScaler_iface, width, height);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_GetPixelFormat(IMILBitmapScaler *iface,
|
||||
int *format)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
IMILBitmapSource *source;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", iface, format);
|
||||
|
||||
if (!format) return E_INVALIDARG;
|
||||
|
||||
if (!This->source)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
hr = IWICBitmapSource_QueryInterface(This->source, &IID_IMILBitmapSource, (void **)&source);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = source->lpVtbl->GetPixelFormat(source, format);
|
||||
source->lpVtbl->Release(source);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_GetResolution(IMILBitmapScaler *iface,
|
||||
double *dpix, double *dpiy)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, dpix, dpiy);
|
||||
|
||||
if (!This->source)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
return IWICBitmapScaler_GetResolution(&This->IWICBitmapScaler_iface, dpix, dpiy);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_CopyPalette(IMILBitmapScaler *iface,
|
||||
IWICPalette *palette)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
|
||||
TRACE("(%p,%p)\n", iface, palette);
|
||||
|
||||
if (!This->source)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
return IWICBitmapScaler_CopyPalette(&This->IWICBitmapScaler_iface, palette);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_CopyPixels(IMILBitmapScaler *iface,
|
||||
const WICRect *rc, UINT stride, UINT size, BYTE *buffer)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
|
||||
TRACE("(%p,%p,%u,%u,%p)\n", iface, rc, stride, size, buffer);
|
||||
|
||||
if (!This->source)
|
||||
return WINCODEC_ERR_NOTINITIALIZED;
|
||||
|
||||
return IWICBitmapScaler_CopyPixels(&This->IWICBitmapScaler_iface, rc, stride, size, buffer);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_unknown1(IMILBitmapScaler *iface, void **ppv)
|
||||
{
|
||||
TRACE("(%p,%p)\n", iface, ppv);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IMILBitmapScaler_Initialize(IMILBitmapScaler *iface,
|
||||
IMILBitmapSource *mil_source, UINT width, UINT height,
|
||||
WICBitmapInterpolationMode mode)
|
||||
{
|
||||
BitmapScaler *This = impl_from_IMILBitmapScaler(iface);
|
||||
IWICBitmapSource *wic_source;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%u,%u,%u)\n", iface, mil_source, width, height, mode);
|
||||
|
||||
if (!mil_source) return E_INVALIDARG;
|
||||
|
||||
hr = mil_source->lpVtbl->QueryInterface(mil_source, &IID_IWICBitmapSource, (void **)&wic_source);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICBitmapScaler_Initialize(&This->IWICBitmapScaler_iface, wic_source, width, height, mode);
|
||||
IWICBitmapSource_Release(wic_source);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IMILBitmapScalerVtbl IMILBitmapScaler_Vtbl = {
|
||||
IMILBitmapScaler_QueryInterface,
|
||||
IMILBitmapScaler_AddRef,
|
||||
IMILBitmapScaler_Release,
|
||||
IMILBitmapScaler_GetSize,
|
||||
IMILBitmapScaler_GetPixelFormat,
|
||||
IMILBitmapScaler_GetResolution,
|
||||
IMILBitmapScaler_CopyPalette,
|
||||
IMILBitmapScaler_CopyPixels,
|
||||
IMILBitmapScaler_unknown1,
|
||||
IMILBitmapScaler_Initialize
|
||||
};
|
||||
|
||||
HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
|
||||
{
|
||||
BitmapScaler *This;
|
||||
|
@ -368,6 +550,7 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler)
|
|||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl;
|
||||
This->IMILBitmapScaler_iface.lpVtbl = &IMILBitmapScaler_Vtbl;
|
||||
This->ref = 1;
|
||||
This->source = NULL;
|
||||
This->width = 0;
|
||||
|
|
|
@ -16,9 +16,17 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#define COBJMACROS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "objbase.h"
|
||||
#include "shlwapi.h"
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
/******************************************
|
||||
* StreamOnMemory implementation
|
||||
|
|
|
@ -16,8 +16,24 @@
|
|||
* 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 "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2010 Vincent Povirk for CodeWeavers
|
||||
* Copyright 2016 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -16,8 +17,10 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -25,6 +28,19 @@
|
|||
#include <tiffio.h>
|
||||
#endif
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/library.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
#ifdef SONAME_LIBTIFF
|
||||
|
||||
/* Workaround for broken libtiff 4.x headers on some 64-bit hosts which
|
||||
|
@ -303,6 +319,8 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
}
|
||||
decode_info->planar = planar;
|
||||
|
||||
TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps);
|
||||
|
||||
switch(photometric)
|
||||
{
|
||||
case 0: /* WhiteIsZero */
|
||||
|
@ -367,14 +385,28 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (samples != 1)
|
||||
{
|
||||
FIXME("unhandled 16bpp grayscale sample count %u\n", samples);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
decode_info->format = &GUID_WICPixelFormat16bppGray;
|
||||
break;
|
||||
case 32:
|
||||
if (samples != 1)
|
||||
{
|
||||
FIXME("unhandled 32bpp grayscale sample count %u\n", samples);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
decode_info->format = &GUID_WICPixelFormat32bppGrayFloat;
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled greyscale bit count %u\n", bps);
|
||||
return E_FAIL;
|
||||
WARN("unhandled greyscale bit count %u\n", bps);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
break;
|
||||
case 2: /* RGB */
|
||||
decode_info->bpp = bps * samples;
|
||||
|
||||
if (samples == 4)
|
||||
{
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples);
|
||||
|
@ -391,8 +423,12 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
decode_info->bpp = max(bps, 8) * samples;
|
||||
decode_info->source_bpp = bps * samples;
|
||||
switch(bps)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
decode_info->reverse_bgr = 1;
|
||||
if (samples == 3)
|
||||
|
@ -430,9 +466,17 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (samples != 4)
|
||||
{
|
||||
FIXME("unhandled 32bpp RGB sample count %u\n", samples);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat;
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled RGB bit count %u\n", bps);
|
||||
return E_FAIL;
|
||||
WARN("unhandled RGB bit count %u\n", bps);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
break;
|
||||
case 3: /* RGB Palette */
|
||||
|
@ -446,6 +490,12 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
decode_info->bpp = bps;
|
||||
switch (bps)
|
||||
{
|
||||
case 1:
|
||||
decode_info->format = &GUID_WICPixelFormat1bppIndexed;
|
||||
break;
|
||||
case 2:
|
||||
decode_info->format = &GUID_WICPixelFormat2bppIndexed;
|
||||
break;
|
||||
case 4:
|
||||
decode_info->format = &GUID_WICPixelFormat4bppIndexed;
|
||||
break;
|
||||
|
@ -457,8 +507,31 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
return E_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* Separated */
|
||||
if (samples != 4)
|
||||
{
|
||||
FIXME("unhandled Separated sample count %u\n", samples);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
decode_info->bpp = bps * samples;
|
||||
switch(bps)
|
||||
{
|
||||
case 8:
|
||||
decode_info->format = &GUID_WICPixelFormat32bppCMYK;
|
||||
break;
|
||||
case 16:
|
||||
decode_info->format = &GUID_WICPixelFormat64bppCMYK;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("unhandled Separated bit count %u\n", bps);
|
||||
return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* Transparency mask */
|
||||
case 5: /* CMYK */
|
||||
case 6: /* YCbCr */
|
||||
case 8: /* CIELab */
|
||||
default:
|
||||
|
@ -514,21 +587,27 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info)
|
|||
|
||||
decode_info->resolution_unit = 0;
|
||||
pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &decode_info->resolution_unit);
|
||||
if (decode_info->resolution_unit != 0)
|
||||
{
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing X resolution\n");
|
||||
decode_info->resolution_unit = 0;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing Y resolution\n");
|
||||
decode_info->resolution_unit = 0;
|
||||
}
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing X resolution\n");
|
||||
}
|
||||
/* Emulate the behavior of current libtiff versions (libtiff commit a39f6131)
|
||||
* yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */
|
||||
if (!isfinite(decode_info->xres))
|
||||
{
|
||||
decode_info->xres = 0.0;
|
||||
}
|
||||
|
||||
ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres);
|
||||
if (!ret)
|
||||
{
|
||||
WARN("missing Y resolution\n");
|
||||
}
|
||||
if (!isfinite(decode_info->yres))
|
||||
{
|
||||
decode_info->yres = 0.0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -609,6 +688,7 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
|||
{
|
||||
TiffDecoder *This = impl_from_IWICBitmapDecoder(iface);
|
||||
TIFF *tiff;
|
||||
tiff_decode_info decode_info;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
|
||||
|
@ -622,13 +702,20 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *
|
|||
}
|
||||
|
||||
tiff = tiff_open_stream(pIStream, "r");
|
||||
|
||||
if (!tiff)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* make sure that TIFF format is supported */
|
||||
hr = tiff_get_decode_info(tiff, &decode_info);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
pTIFFClose(tiff);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
This->tiff = tiff;
|
||||
This->stream = pIStream;
|
||||
IStream_AddRef(pIStream);
|
||||
|
@ -677,8 +764,12 @@ static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface,
|
|||
static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
|
||||
IWICMetadataQueryReader **ppIMetadataQueryReader)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
|
||||
|
||||
if (!ppIMetadataQueryReader) return E_INVALIDARG;
|
||||
|
||||
*ppIMetadataQueryReader = NULL;
|
||||
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface,
|
||||
|
@ -878,26 +969,28 @@ static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface
|
|||
{
|
||||
TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
|
||||
|
||||
switch (This->decode_info.resolution_unit)
|
||||
if (This->decode_info.xres == 0 || This->decode_info.yres == 0)
|
||||
{
|
||||
default:
|
||||
FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit);
|
||||
/* fall through */
|
||||
case 0: /* Not set */
|
||||
*pDpiX = *pDpiY = 96.0;
|
||||
break;
|
||||
case 1: /* Relative measurements */
|
||||
*pDpiX = 96.0;
|
||||
*pDpiY = 96.0 * This->decode_info.yres / This->decode_info.xres;
|
||||
break;
|
||||
case 2: /* Inch */
|
||||
*pDpiX = This->decode_info.xres;
|
||||
*pDpiY = This->decode_info.yres;
|
||||
break;
|
||||
case 3: /* Centimeter */
|
||||
*pDpiX = This->decode_info.xres / 2.54;
|
||||
*pDpiY = This->decode_info.yres / 2.54;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (This->decode_info.resolution_unit)
|
||||
{
|
||||
default:
|
||||
FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit);
|
||||
/* fall through */
|
||||
case 0: /* Not set */
|
||||
case 1: /* Relative measurements */
|
||||
case 2: /* Inch */
|
||||
*pDpiX = This->decode_info.xres;
|
||||
*pDpiY = This->decode_info.yres;
|
||||
break;
|
||||
case 3: /* Centimeter */
|
||||
*pDpiX = This->decode_info.xres * 2.54;
|
||||
*pDpiY = This->decode_info.yres * 2.54;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY, This->decode_info.resolution_unit);
|
||||
|
@ -940,34 +1033,183 @@ static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
|
|||
|
||||
static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
tsize_t ret;
|
||||
int swap_bytes;
|
||||
|
||||
swap_bytes = pTIFFIsByteSwapped(This->parent->tiff);
|
||||
|
||||
ret = pTIFFSetDirectory(This->parent->tiff, This->index);
|
||||
if (ret == -1)
|
||||
return E_FAIL;
|
||||
|
||||
if (This->decode_info.tiled)
|
||||
ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size);
|
||||
else
|
||||
ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size);
|
||||
|
||||
if (ret == -1)
|
||||
hr = E_FAIL;
|
||||
return E_FAIL;
|
||||
|
||||
if (hr == S_OK)
|
||||
/* 3bpp RGB */
|
||||
if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24)
|
||||
{
|
||||
if (This->decode_info.tiled)
|
||||
BYTE *srcdata, *src, *dst;
|
||||
DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8;
|
||||
|
||||
count = width_bytes * This->decode_info.tile_height;
|
||||
|
||||
srcdata = HeapAlloc(GetProcessHeap(), 0, count);
|
||||
if (!srcdata) return E_OUTOFMEMORY;
|
||||
memcpy(srcdata, This->cached_tile, count);
|
||||
|
||||
for (y = 0; y < This->decode_info.tile_height; y++)
|
||||
{
|
||||
ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size);
|
||||
src = srcdata + y * width_bytes;
|
||||
dst = This->cached_tile + y * This->decode_info.tile_width * 3;
|
||||
|
||||
for (x = 0; x < This->decode_info.tile_width; x += 8)
|
||||
{
|
||||
dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */
|
||||
dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */
|
||||
dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */
|
||||
if (x + 1 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */
|
||||
dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */
|
||||
dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 2 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */
|
||||
dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */
|
||||
dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 3 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */
|
||||
dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */
|
||||
dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 4 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */
|
||||
dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */
|
||||
dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 5 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */
|
||||
dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */
|
||||
dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 6 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */
|
||||
dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */
|
||||
dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */
|
||||
}
|
||||
if (x + 7 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */
|
||||
dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */
|
||||
dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */
|
||||
}
|
||||
src += 3;
|
||||
dst += 24;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
hr = E_FAIL;
|
||||
HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
}
|
||||
/* 12bpp RGB */
|
||||
else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24)
|
||||
{
|
||||
BYTE *srcdata, *src, *dst;
|
||||
DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8;
|
||||
|
||||
count = width_bytes * This->decode_info.tile_height;
|
||||
|
||||
srcdata = HeapAlloc(GetProcessHeap(), 0, count);
|
||||
if (!srcdata) return E_OUTOFMEMORY;
|
||||
memcpy(srcdata, This->cached_tile, count);
|
||||
|
||||
for (y = 0; y < This->decode_info.tile_height; y++)
|
||||
{
|
||||
src = srcdata + y * width_bytes;
|
||||
dst = This->cached_tile + y * This->decode_info.tile_width * 3;
|
||||
|
||||
for (x = 0; x < This->decode_info.tile_width; x += 2)
|
||||
{
|
||||
dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */
|
||||
dst[1] = (src[0] & 0x0f) * 17; /* G */
|
||||
dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */
|
||||
if (x + 1 < This->decode_info.tile_width)
|
||||
{
|
||||
dst[5] = (src[1] & 0x0f) * 17; /* B */
|
||||
dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */
|
||||
dst[3] = (src[2] & 0x0f) * 17; /* R */
|
||||
}
|
||||
src += 3;
|
||||
dst += 6;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, srcdata);
|
||||
}
|
||||
/* 4bpp RGBA */
|
||||
else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32)
|
||||
{
|
||||
BYTE *src, *dst;
|
||||
DWORD count;
|
||||
|
||||
/* 1 source byte expands to 2 BGRA samples */
|
||||
count = (This->decode_info.tile_width * This->decode_info.tile_height + 1) / 2;
|
||||
|
||||
src = This->cached_tile + count - 1;
|
||||
dst = This->cached_tile + This->decode_info.tile_size;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
BYTE b = *src--;
|
||||
|
||||
dst -= 8;
|
||||
dst[2] = (b & 0x80) ? 0xff : 0; /* R */
|
||||
dst[1] = (b & 0x40) ? 0xff : 0; /* G */
|
||||
dst[0] = (b & 0x20) ? 0xff : 0; /* B */
|
||||
dst[3] = (b & 0x10) ? 0xff : 0; /* A */
|
||||
dst[6] = (b & 0x08) ? 0xff : 0; /* R */
|
||||
dst[5] = (b & 0x04) ? 0xff : 0; /* G */
|
||||
dst[4] = (b & 0x02) ? 0xff : 0; /* B */
|
||||
dst[7] = (b & 0x01) ? 0xff : 0; /* A */
|
||||
}
|
||||
}
|
||||
/* 16bpp RGBA */
|
||||
else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32)
|
||||
{
|
||||
BYTE *src, *dst;
|
||||
DWORD count = This->decode_info.tile_width * This->decode_info.tile_height;
|
||||
|
||||
src = This->cached_tile + count * 2;
|
||||
dst = This->cached_tile + This->decode_info.tile_size;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
BYTE b[2];
|
||||
|
||||
src -= 2;
|
||||
dst -= 4;
|
||||
|
||||
b[0] = src[0];
|
||||
b[1] = src[1];
|
||||
|
||||
dst[0] = ((b[1] & 0xf0) >> 4) * 17; /* B */
|
||||
dst[1] = (b[0] & 0x0f) * 17; /* G */
|
||||
dst[2] = ((b[0] & 0xf0) >> 4) * 17; /* R */
|
||||
dst[3] = (b[1] & 0x0f) * 17; /* A */
|
||||
}
|
||||
}
|
||||
/* 8bpp grayscale with extra alpha */
|
||||
if (hr == S_OK && This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32)
|
||||
else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32)
|
||||
{
|
||||
BYTE *src;
|
||||
DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height;
|
||||
|
@ -982,7 +1224,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT
|
|||
}
|
||||
}
|
||||
|
||||
if (hr == S_OK && This->decode_info.reverse_bgr)
|
||||
if (This->decode_info.reverse_bgr)
|
||||
{
|
||||
if (This->decode_info.bps == 8)
|
||||
{
|
||||
|
@ -993,7 +1235,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT
|
|||
}
|
||||
}
|
||||
|
||||
if (hr == S_OK && swap_bytes && This->decode_info.bps > 8)
|
||||
if (swap_bytes && This->decode_info.bps > 8)
|
||||
{
|
||||
UINT row, i, samples_per_row;
|
||||
BYTE *sample, temp;
|
||||
|
@ -1021,7 +1263,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT
|
|||
}
|
||||
}
|
||||
|
||||
if (hr == S_OK && This->decode_info.invert_grayscale)
|
||||
if (This->decode_info.invert_grayscale)
|
||||
{
|
||||
BYTE *byte, *end;
|
||||
|
||||
|
@ -1037,13 +1279,10 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT
|
|||
*byte = ~(*byte);
|
||||
}
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
This->cached_tile_x = tile_x;
|
||||
This->cached_tile_y = tile_y;
|
||||
}
|
||||
This->cached_tile_x = tile_x;
|
||||
This->cached_tile_y = tile_y;
|
||||
|
||||
return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
||||
|
@ -1080,7 +1319,7 @@ static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
|
|||
if (cbStride < bytesperrow)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((cbStride * prc->Height) > cbBufferSize)
|
||||
if ((cbStride * (prc->Height-1)) + ((prc->Width * This->decode_info.bpp) + 7)/8 > cbBufferSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
min_tile_x = prc->X / This->decode_info.tile_width;
|
||||
|
@ -1394,6 +1633,10 @@ static const struct tiff_encode_format formats[] = {
|
|||
{&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0},
|
||||
{&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0},
|
||||
{&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat2bppIndexed, 3, 2, 1, 2, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0},
|
||||
{&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -1676,6 +1919,21 @@ static HRESULT WINAPI TiffFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
|
|||
pTIFFSetField(This->parent->tiff, TIFFTAG_YRESOLUTION, (float)This->yres);
|
||||
}
|
||||
|
||||
if (This->format->bpp <= 8 && This->colors && !IsEqualGUID(This->format->guid, &GUID_WICPixelFormatBlackWhite))
|
||||
{
|
||||
uint16 red[256], green[256], blue[256];
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < This->colors; i++)
|
||||
{
|
||||
red[i] = (This->palette[i] >> 8) & 0xff00;
|
||||
green[i] = This->palette[i] & 0xff00;
|
||||
blue[i] = (This->palette[i] << 8) & 0xff00;
|
||||
}
|
||||
|
||||
pTIFFSetField(This->parent->tiff, TIFFTAG_COLORMAP, red, green, blue);
|
||||
}
|
||||
|
||||
This->info_written = TRUE;
|
||||
}
|
||||
|
||||
|
@ -1874,11 +2132,22 @@ static HRESULT WINAPI TiffEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
|
||||
IWICBitmapEncoderInfo **ppIEncoderInfo)
|
||||
static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
|
||||
return E_NOTIMPL;
|
||||
IWICComponentInfo *comp_info;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p,%p\n", iface, info);
|
||||
|
||||
if (!info) return E_INVALIDARG;
|
||||
|
||||
hr = CreateComponentInfo(&CLSID_WICTiffEncoder, &comp_info);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info);
|
||||
IWICComponentInfo_Release(comp_info);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface,
|
||||
|
@ -1921,7 +2190,11 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
{
|
||||
TiffEncoder *This = impl_from_IWICBitmapEncoder(iface);
|
||||
TiffFrameEncode *result;
|
||||
|
||||
static const PROPBAG2 opts[2] =
|
||||
{
|
||||
{ PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszTiffCompressionMethod },
|
||||
{ PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszCompressionQuality },
|
||||
};
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
|
||||
|
@ -1938,26 +2211,16 @@ static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
|
|||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
if (ppIEncoderOptions && SUCCEEDED(hr))
|
||||
{
|
||||
PROPBAG2 opts[2]= {{0}};
|
||||
opts[0].pstrName = (LPOLESTR)wszTiffCompressionMethod;
|
||||
opts[0].vt = VT_UI1;
|
||||
opts[0].dwType = PROPBAG2_TYPE_DATA;
|
||||
|
||||
opts[1].pstrName = (LPOLESTR)wszCompressionQuality;
|
||||
opts[1].vt = VT_R4;
|
||||
opts[1].dwType = PROPBAG2_TYPE_DATA;
|
||||
|
||||
hr = CreatePropertyBag2(opts, 2, ppIEncoderOptions);
|
||||
|
||||
hr = CreatePropertyBag2(opts, sizeof(opts)/sizeof(opts[0]), ppIEncoderOptions);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
V_VT(&v) = VT_UI1;
|
||||
V_UNION(&v, bVal) = WICTiffCompressionDontCare;
|
||||
hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, opts, &v);
|
||||
V_UI1(&v) = WICTiffCompressionDontCare;
|
||||
hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, (PROPBAG2 *)opts, &v);
|
||||
VariantClear(&v);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
|
|
@ -47,9 +47,16 @@
|
|||
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wincodecs_private.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ungif.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
|
||||
static void *ungif_alloc( size_t sz )
|
||||
{
|
||||
|
|
|
@ -19,33 +19,9 @@
|
|||
#ifndef WINCODECS_PRIVATE_H
|
||||
#define WINCODECS_PRIVATE_H
|
||||
|
||||
#include <wine/config.h>
|
||||
#include <wine/port.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wingdi.h>
|
||||
#include <winreg.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <wincodec.h>
|
||||
#include <wincodecsdk.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
#include <wine/library.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
|
||||
#include "wincodec.h"
|
||||
#include "wincodecsdk.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
DEFINE_GUID(CLSID_WineTgaDecoder, 0xb11fc79a,0x67cc,0x43e6,0xa9,0xce,0xe3,0xd5,0x49,0x45,0xd3,0x04);
|
||||
|
||||
|
@ -55,7 +31,13 @@ DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47
|
|||
|
||||
DEFINE_GUID(GUID_VendorWine, 0xddf46da1,0x7dc1,0x404e,0x98,0xf2,0xef,0xa4,0x8d,0xfc,0x95,0x0a);
|
||||
|
||||
DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a);
|
||||
DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe);
|
||||
DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd);
|
||||
DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb);
|
||||
DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0);
|
||||
DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f);
|
||||
|
||||
#define INTERFACE IMILBitmapSource
|
||||
DECLARE_INTERFACE_(IMILBitmapSource,IUnknown)
|
||||
{
|
||||
|
@ -63,16 +45,58 @@ DECLARE_INTERFACE_(IMILBitmapSource,IUnknown)
|
|||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID,void **) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IWICBitmapSource methods ***/
|
||||
STDMETHOD_(HRESULT,GetSize)(THIS_ UINT *,UINT *) PURE;
|
||||
STDMETHOD_(HRESULT,GetPixelFormat)(THIS_ int *) PURE;
|
||||
STDMETHOD_(HRESULT,GetResolution)(THIS_ double *,double *) PURE;
|
||||
STDMETHOD_(HRESULT,CopyPalette)(THIS_ IWICPalette *) PURE;
|
||||
STDMETHOD_(HRESULT,CopyPixels)(THIS_ const WICRect *,UINT,UINT,BYTE *) PURE;
|
||||
/*** IMILBitmapSource methods ***/
|
||||
STDMETHOD_(HRESULT,GetSize)(THIS_ UINT *,UINT *);
|
||||
STDMETHOD_(HRESULT,GetPixelFormat)(THIS_ int *);
|
||||
STDMETHOD_(HRESULT,GetResolution)(THIS_ double *,double *);
|
||||
STDMETHOD_(HRESULT,CopyPalette)(THIS_ IWICPalette *);
|
||||
STDMETHOD_(HRESULT,CopyPixels)(THIS_ const WICRect *,UINT,UINT,BYTE *);
|
||||
STDMETHOD_(HRESULT,UnknownMethod1)(THIS_ void **);
|
||||
STDMETHOD_(HRESULT,unknown1)(THIS_ void **) PURE;
|
||||
STDMETHOD_(HRESULT,Lock)(THIS_ const WICRect *,DWORD,IWICBitmapLock **) PURE;
|
||||
STDMETHOD_(HRESULT,Unlock)(THIS_ IWICBitmapLock *) PURE;
|
||||
STDMETHOD_(HRESULT,SetPalette)(THIS_ IWICPalette *) PURE;
|
||||
STDMETHOD_(HRESULT,SetResolution)(THIS_ double,double) PURE;
|
||||
STDMETHOD_(HRESULT,AddDirtyRect)(THIS_ const WICRect *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IMILBitmapScaler
|
||||
DECLARE_INTERFACE_(IMILBitmapScaler,IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID,void **) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IWICBitmapSource methods ***/
|
||||
STDMETHOD_(HRESULT,GetSize)(THIS_ UINT *,UINT *) PURE;
|
||||
STDMETHOD_(HRESULT,GetPixelFormat)(THIS_ int *) PURE;
|
||||
STDMETHOD_(HRESULT,GetResolution)(THIS_ double *,double *) PURE;
|
||||
STDMETHOD_(HRESULT,CopyPalette)(THIS_ IWICPalette *) PURE;
|
||||
STDMETHOD_(HRESULT,CopyPixels)(THIS_ const WICRect *,UINT,UINT,BYTE *) PURE;
|
||||
/*** IMILBitmapScaler methods ***/
|
||||
STDMETHOD_(HRESULT,unknown1)(THIS_ void **) PURE;
|
||||
STDMETHOD_(HRESULT,Initialize)(THIS_ IMILBitmapSource *,UINT,UINT,WICBitmapInterpolationMode);
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#ifdef __i386__ /* thiscall functions are i386-specific */
|
||||
|
||||
#define THISCALL(func) __thiscall_ ## func
|
||||
#define DEFINE_THISCALL_WRAPPER(func,args) \
|
||||
extern typeof(func) THISCALL(func); \
|
||||
__ASM_STDCALL_FUNC(__thiscall_ ## func, args, \
|
||||
"popl %eax\n\t" \
|
||||
"pushl %ecx\n\t" \
|
||||
"pushl %eax\n\t" \
|
||||
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
|
||||
#else /* __i386__ */
|
||||
|
||||
#define THISCALL(func) func
|
||||
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
#define INTERFACE IMILUnknown1
|
||||
DECLARE_INTERFACE_(IMILUnknown1,IUnknown)
|
||||
{
|
||||
|
@ -80,6 +104,19 @@ DECLARE_INTERFACE_(IMILUnknown1,IUnknown)
|
|||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID,void **) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** thiscall method ***/
|
||||
STDMETHOD_(void,unknown1)(THIS_ void*) PURE;
|
||||
/*** stdcall ***/
|
||||
STDMETHOD_(HRESULT,unknown2)(THIS_ void*, void*) PURE;
|
||||
/*** thiscall method ***/
|
||||
STDMETHOD_(HRESULT,unknown3)(THIS_ void*) PURE;
|
||||
/*** stdcall ***/
|
||||
STDMETHOD_(HRESULT,unknown4)(THIS_ void*) PURE;
|
||||
STDMETHOD_(HRESULT,unknown5)(THIS_ void*) PURE;
|
||||
STDMETHOD_(HRESULT,unknown6)(THIS_ DWORD64) PURE;
|
||||
STDMETHOD_(HRESULT,unknown7)(THIS_ void*) PURE;
|
||||
/*** thiscall method ***/
|
||||
STDMETHOD_(HRESULT,unknown8)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
|
@ -91,7 +128,9 @@ DECLARE_INTERFACE_(IMILUnknown2,IUnknown)
|
|||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** unknown methods ***/
|
||||
STDMETHOD_(HRESULT,UnknownMethod1)(THIS_ void *, void *) PURE;
|
||||
STDMETHOD_(HRESULT,unknown1)(THIS_ void *,void **) PURE;
|
||||
STDMETHOD_(HRESULT,unknown2)(THIS_ void *,void *) PURE;
|
||||
STDMETHOD_(HRESULT,unknown3)(THIS_ void *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
|
@ -106,6 +145,7 @@ extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN
|
|||
extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN;
|
||||
|
@ -144,7 +184,7 @@ extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT heigh
|
|||
|
||||
extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count,
|
||||
extern HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count,
|
||||
IPropertyBag2 **property) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -105,7 +105,8 @@
|
|||
@ 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)
|
||||
@ stdcall -stub WICCreateBitmapFromSection(long long ptr long long long ptr)
|
||||
@ stdcall WICCreateBitmapFromSection(long long ptr long long long ptr)
|
||||
@ stdcall WICCreateBitmapFromSectionEx(long long ptr long long long long ptr)
|
||||
@ stdcall WICCreateColorContext_Proxy(ptr ptr)
|
||||
@ stdcall WICCreateImagingFactory_Proxy(long ptr)
|
||||
@ stub WICGetMetadataContentSize
|
||||
|
|
|
@ -76,6 +76,13 @@ coclass WICBmpEncoder { interface IWICBitmapEncoder; }
|
|||
]
|
||||
coclass WICGifDecoder { interface IWICBitmapDecoder; }
|
||||
|
||||
[
|
||||
helpstring("WIC GIF Encoder"),
|
||||
threading(both),
|
||||
uuid(114f5598-0b22-40a0-86a1-c83ea495adbd)
|
||||
]
|
||||
coclass WICGifEncoder { interface IWICBitmapEncoder; }
|
||||
|
||||
[
|
||||
helpstring("WIC ICO Decoder"),
|
||||
threading(both),
|
||||
|
|
|
@ -196,7 +196,7 @@ reactos/dll/win32/version # Synced to Wine-3.0
|
|||
reactos/dll/win32/vssapi # Synced to WineStaging-2.9
|
||||
reactos/dll/win32/wbemdisp # Synced to Wine-3.0
|
||||
reactos/dll/win32/wbemprox # Synced to Wine-3.0
|
||||
reactos/dll/win32/windowscodecs # Synced to Wine-3.0
|
||||
reactos/dll/win32/windowscodecs # Synced to WineStaging-3.3
|
||||
reactos/dll/win32/windowscodecsext # Synced to WineStaging-2.9
|
||||
reactos/dll/win32/winemp3.acm # Synced to Wine-3.0
|
||||
reactos/dll/win32/wing32 # Synced to WineStaging-2.9
|
||||
|
|
Loading…
Reference in a new issue