[WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434

This commit is contained in:
Amine Khaldi 2018-03-05 00:19:05 +01:00
parent a8d718da39
commit ae80686d81
34 changed files with 3112 additions and 380 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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},

View file

@ -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;

View file

@ -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;

View file

@ -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");

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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)
{

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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;

View 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 */

View file

@ -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;

View file

@ -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)
{

View file

@ -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 */
};

View file

@ -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;

View file

@ -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

View file

@ -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 {

View file

@ -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))
{

View file

@ -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 )
{

View file

@ -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;

View file

@ -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

View file

@ -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),

View file

@ -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