https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ae80686d816b6383d5e46…
commit ae80686d816b6383d5e46b90ced89b680b62642d
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Mar 5 00:19:05 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Mon Mar 5 00:19:05 2018 +0100
[WINDOWSCODECS] Sync with Wine Staging 3.3. CORE-14434
---
dll/win32/windowscodecs/CMakeLists.txt | 15 +-
dll/win32/windowscodecs/bitmap.c | 225 ++++-
dll/win32/windowscodecs/bmpdecode.c | 19 +-
dll/win32/windowscodecs/bmpencode.c | 112 ++-
dll/win32/windowscodecs/clipper.c | 12 +
dll/win32/windowscodecs/clsfactory.c | 18 +
dll/win32/windowscodecs/colorcontext.c | 14 +
dll/win32/windowscodecs/colortransform.c | 14 +
dll/win32/windowscodecs/converter.c | 269 ++++-
dll/win32/windowscodecs/fliprotate.c | 14 +
dll/win32/windowscodecs/gifformat.c | 1034 +++++++++++++++++++-
dll/win32/windowscodecs/icnsformat.c | 25 +-
dll/win32/windowscodecs/icoformat.c | 19 +-
dll/win32/windowscodecs/imgfactory.c | 131 ++-
dll/win32/windowscodecs/info.c | 37 +-
dll/win32/windowscodecs/jpegformat.c | 99 +-
dll/win32/windowscodecs/main.c | 14 +
dll/win32/windowscodecs/metadatahandler.c | 67 +-
dll/win32/windowscodecs/metadataquery.c | 16 +-
dll/win32/windowscodecs/palette.c | 294 +++++-
dll/win32/windowscodecs/pngformat.c | 74 +-
dll/win32/windowscodecs/precomp.h | 30 +
dll/win32/windowscodecs/propertybag.c | 19 +-
dll/win32/windowscodecs/proxy.c | 14 +
dll/win32/windowscodecs/regsvr.c | 132 ++-
dll/win32/windowscodecs/scaler.c | 183 ++++
dll/win32/windowscodecs/stream.c | 10 +-
dll/win32/windowscodecs/tgaformat.c | 16 +
dll/win32/windowscodecs/tiffformat.c | 425 ++++++--
dll/win32/windowscodecs/ungif.c | 9 +-
dll/win32/windowscodecs/wincodecs_private.h | 110 ++-
dll/win32/windowscodecs/windowscodecs.spec | 3 +-
dll/win32/windowscodecs/windowscodecs_wincodec.idl | 7 +
media/doc/README.WINE | 2 +-
34 files changed, 3107 insertions(+), 375 deletions(-)
diff --git a/dll/win32/windowscodecs/CMakeLists.txt
b/dll/win32/windowscodecs/CMakeLists.txt
index 7ed058d112..6c67bfe1a9 100644
--- a/dll/win32/windowscodecs/CMakeLists.txt
+++ b/dll/win32/windowscodecs/CMakeLists.txt
@@ -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)
diff --git a/dll/win32/windowscodecs/bitmap.c b/dll/win32/windowscodecs/bitmap.c
index dfd7dda89f..69ec14fed2 100644
--- a/dll/win32/windowscodecs/bitmap.c
+++ b/dll/win32/windowscodecs/bitmap.c
@@ -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,66 +690,128 @@ 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_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_UnknownMethod1(IMILUnknown2 *iface, void *arg1,
void *arg2)
+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;
+}
+
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;
diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c
index 5039694a76..47f312ffcf 100644
--- a/dll/win32/windowscodecs/bmpdecode.c
+++ b/dll/win32/windowscodecs/bmpdecode.c
@@ -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);
diff --git a/dll/win32/windowscodecs/bmpencode.c b/dll/win32/windowscodecs/bmpencode.c
index e339324015..cb8b4897e4 100644
--- a/dll/win32/windowscodecs/bmpencode.c
+++ b/dll/win32/windowscodecs/bmpencode.c
@@ -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)
diff --git a/dll/win32/windowscodecs/clipper.c b/dll/win32/windowscodecs/clipper.c
index f7df230247..94127f3df1 100644
--- a/dll/win32/windowscodecs/clipper.c
+++ b/dll/win32/windowscodecs/clipper.c
@@ -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;
diff --git a/dll/win32/windowscodecs/clsfactory.c b/dll/win32/windowscodecs/clsfactory.c
index 2116ff9e8b..98938eb872 100644
--- a/dll/win32/windowscodecs/clsfactory.c
+++ b/dll/win32/windowscodecs/clsfactory.c
@@ -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},
diff --git a/dll/win32/windowscodecs/colorcontext.c
b/dll/win32/windowscodecs/colorcontext.c
index d0c0a3bb36..eb13482cf4 100644
--- a/dll/win32/windowscodecs/colorcontext.c
+++ b/dll/win32/windowscodecs/colorcontext.c
@@ -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;
diff --git a/dll/win32/windowscodecs/colortransform.c
b/dll/win32/windowscodecs/colortransform.c
index 6a3f7d1528..5b1c7e8b70 100644
--- a/dll/win32/windowscodecs/colortransform.c
+++ b/dll/win32/windowscodecs/colortransform.c
@@ -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;
diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c
index d6086b087a..c3bcce89e0 100644
--- a/dll/win32/windowscodecs/converter.c
+++ b/dll/win32/windowscodecs/converter.c
@@ -17,10 +17,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "wincodecs_private.h"
+#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 "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
struct FormatConverter;
enum pixelformat {
@@ -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.3f,%u)\n", iface, source,
debugstr_guid(dstFormat),
+ dither, palette, alpha_threshold, palette_type);
- TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource,
debugstr_guid(dstFormat),
- dither, pIPalette, alphaThresholdPercent, paletteTranslate);
+ if (!palette)
+ {
+ UINT bpp;
+ res = get_pixelformat_bpp(dstFormat, &bpp);
+ if (res != S_OK) return res;
- if (pIPalette && !fixme++) FIXME("ignoring palette\n");
+ 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");
diff --git a/dll/win32/windowscodecs/fliprotate.c b/dll/win32/windowscodecs/fliprotate.c
index e75107161a..72d1e8a287 100644
--- a/dll/win32/windowscodecs/fliprotate.c
+++ b/dll/win32/windowscodecs/fliprotate.c
@@ -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;
diff --git a/dll/win32/windowscodecs/gifformat.c b/dll/win32/windowscodecs/gifformat.c
index 3bc3bac409..e898d9c852 100644
--- a/dll/win32/windowscodecs/gifformat.c
+++ b/dll/win32/windowscodecs/gifformat.c
@@ -1,6 +1,6 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
- * Copyright 2012 Dmitry Timoshkov
+ * Copyright 2012,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
@@ -17,11 +17,62 @@
* 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 "ungif.h"
+
#include "wincodecs_private.h"
+#include "wine/debug.h"
+
+#ifdef __REACTOS__
#include <ole2.h>
+#endif
-#include "ungif.h"
+WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+
+#include "pshpack1.h"
+
+struct logical_screen_descriptor
+{
+ char signature[6];
+ USHORT width;
+ USHORT height;
+ BYTE packed;
+ /* global_color_table_flag : 1;
+ * color_resolution : 3;
+ * sort_flag : 1;
+ * global_color_table_size : 3;
+ */
+ BYTE background_color_index;
+ BYTE pixel_aspect_ratio;
+};
+
+struct image_descriptor
+{
+ USHORT left;
+ USHORT top;
+ USHORT width;
+ USHORT height;
+ BYTE packed;
+ /* local_color_table_flag : 1;
+ * interlace_flag : 1;
+ * sort_flag : 1;
+ * reserved : 2;
+ * local_color_table_size : 3;
+ */
+};
+
+#include "poppack.h"
static LPWSTR strdupAtoW(const char *src)
{
@@ -34,22 +85,7 @@ static LPWSTR strdupAtoW(const char *src)
static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options,
MetadataItem **items, DWORD *count)
{
-#include "pshpack1.h"
- struct logical_screen_descriptor
- {
- char signature[6];
- USHORT width;
- USHORT height;
- BYTE packed;
- /* global_color_table_flag : 1;
- * color_resolution : 3;
- * sort_flag : 1;
- * global_color_table_size : 3;
- */
- BYTE background_color_index;
- BYTE pixel_aspect_ratio;
- } lsd_data;
-#include "poppack.h"
+ struct logical_screen_descriptor lsd_data;
HRESULT hr;
ULONG bytesread, i;
MetadataItem *result;
@@ -134,23 +170,6 @@ HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv)
return MetadataReader_Create(&LSDReader_Vtbl, iid, ppv);
}
-#include "pshpack1.h"
-struct image_descriptor
-{
- USHORT left;
- USHORT top;
- USHORT width;
- USHORT height;
- BYTE packed;
- /* local_color_table_flag : 1;
- * interlace_flag : 1;
- * sort_flag : 1;
- * reserved : 2;
- * local_color_table_size : 3;
- */
-};
-#include "poppack.h"
-
static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options,
MetadataItem **items, DWORD *count)
{
@@ -1183,6 +1202,9 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder
*iface, IWICPalet
TRACE("(%p,%p)\n", iface, palette);
+ if (!This->gif)
+ return WINCODEC_ERR_WRONGSTATE;
+
cm = This->gif->SColorMap;
if (cm)
{
@@ -1447,3 +1469,945 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv)
return ret;
}
+
+typedef struct GifEncoder
+{
+ IWICBitmapEncoder IWICBitmapEncoder_iface;
+ LONG ref;
+ IStream *stream;
+ CRITICAL_SECTION lock;
+ BOOL initialized, info_written, committed;
+ UINT n_frames;
+ WICColor palette[256];
+ UINT colors;
+} GifEncoder;
+
+static inline GifEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
+{
+ return CONTAINING_RECORD(iface, GifEncoder, IWICBitmapEncoder_iface);
+}
+
+typedef struct GifFrameEncode
+{
+ IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
+ LONG ref;
+ GifEncoder *encoder;
+ BOOL initialized, interlace, committed;
+ UINT width, height, lines;
+ double xres, yres;
+ WICColor palette[256];
+ UINT colors;
+ BYTE *image_data;
+} GifFrameEncode;
+
+static inline GifFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode
*iface)
+{
+ return CONTAINING_RECORD(iface, GifFrameEncode, IWICBitmapFrameEncode_iface);
+}
+
+static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID
iid, void **ppv)
+{
+ TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
+ {
+ IWICBitmapFrameEncode_AddRef(iface);
+ *ppv = iface;
+ return S_OK;
+ }
+
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("%p -> %u\n", iface, ref);
+ return ref;
+}
+
+static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("%p -> %u\n", iface, ref);
+
+ if (!ref)
+ {
+ IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface);
+ HeapFree(GetProcessHeap(), 0, This->image_data);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI GifFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
IPropertyBag2 *options)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p\n", iface, options);
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (!This->initialized)
+ {
+ This->initialized = TRUE;
+ hr = S_OK;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT width,
UINT height)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%u,%u\n", iface, width, height);
+
+ if (!width || !height) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized)
+ {
+ HeapFree(GetProcessHeap(), 0, This->image_data);
+
+ This->image_data = HeapAlloc(GetProcessHeap(), 0, width * height);
+ if (This->image_data)
+ {
+ This->width = width;
+ This->height = height;
+ hr = S_OK;
+ }
+ else
+ hr = E_OUTOFMEMORY;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, double
xres, double yres)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%f,%f\n", iface, xres, yres);
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized)
+ {
+ This->xres = xres;
+ This->yres = yres;
+ hr = S_OK;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
WICPixelFormatGUID *format)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%s\n", iface, debugstr_guid(format));
+
+ if (!format) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized)
+ {
+ *format = GUID_WICPixelFormat8bppIndexed;
+ hr = S_OK;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, UINT
count, IWICColorContext **context)
+{
+ FIXME("%p,%u,%p: stub\n", iface, count, context);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, IWICPalette
*palette)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p\n", iface, palette);
+
+ if (!palette) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized)
+ hr = IWICPalette_GetColors(palette, 256, This->palette,
&This->colors);
+ else
+ hr = WINCODEC_ERR_NOTINITIALIZED;
+
+ LeaveCriticalSection(&This->encoder->lock);
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
IWICBitmapSource *thumbnail)
+{
+ FIXME("%p,%p: stub\n", iface, thumbnail);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI GifFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, UINT
lines, UINT stride, UINT size, BYTE *pixels)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%u,%u,%u,%p\n", iface, lines, stride, size, pixels);
+
+ if (!pixels) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized && This->image_data)
+ {
+ if (This->lines + lines <= This->height)
+ {
+ UINT i;
+ BYTE *src, *dst;
+
+ src = pixels;
+ dst = This->image_data + This->lines * This->width;
+
+ for (i = 0; i < lines; i++)
+ {
+ memcpy(dst, src, This->width);
+ src += stride;
+ dst += This->width;
+ }
+
+ This->lines += lines;
+ hr = S_OK;
+ }
+ else
+ hr = E_INVALIDARG;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
IWICBitmapSource *source, WICRect *rc)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p,%p\n", iface, source, rc);
+
+ if (!source) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->initialized)
+ {
+ const GUID *format = &GUID_WICPixelFormat8bppIndexed;
+
+ hr = configure_write_source(iface, source, rc, format,
+ This->width, This->height, This->xres,
This->yres);
+ if (hr == S_OK)
+ hr = write_source(iface, source, rc, format, 8, This->width,
This->height);
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+ return hr;
+}
+
+#define LZW_DICT_SIZE (1 << 12)
+
+struct lzw_dict
+{
+ short prefix[LZW_DICT_SIZE];
+ unsigned char suffix[LZW_DICT_SIZE];
+};
+
+struct lzw_state
+{
+ struct lzw_dict dict;
+ short init_code_bits, code_bits, next_code, clear_code, eof_code;
+ unsigned bits_buf;
+ int bits_count;
+ int (*user_write_data)(void *user_ptr, void *data, int length);
+ void *user_ptr;
+};
+
+struct input_stream
+{
+ unsigned len;
+ const BYTE *in;
+};
+
+struct output_stream
+{
+ struct
+ {
+ unsigned char len;
+ char data[255];
+ } gif_block;
+ IStream *out;
+};
+
+static int lzw_output_code(struct lzw_state *state, short code)
+{
+ state->bits_buf |= code << state->bits_count;
+ state->bits_count += state->code_bits;
+
+ while (state->bits_count >= 8)
+ {
+ unsigned char byte = (unsigned char)state->bits_buf;
+ if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
+ return 0;
+ state->bits_buf >>= 8;
+ state->bits_count -= 8;
+ }
+
+ return 1;
+}
+
+static inline int lzw_output_clear_code(struct lzw_state *state)
+{
+ return lzw_output_code(state, state->clear_code);
+}
+
+static inline int lzw_output_eof_code(struct lzw_state *state)
+{
+ return lzw_output_code(state, state->eof_code);
+}
+
+static int lzw_flush_bits(struct lzw_state *state)
+{
+ unsigned char byte;
+
+ while (state->bits_count >= 8)
+ {
+ byte = (unsigned char)state->bits_buf;
+ if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
+ return 0;
+ state->bits_buf >>= 8;
+ state->bits_count -= 8;
+ }
+
+ if (state->bits_count)
+ {
+ static const char mask[8] = { 0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f };
+
+ byte = (unsigned char)state->bits_buf & mask[state->bits_count];
+ if (state->user_write_data(state->user_ptr, &byte, 1) != 1)
+ return 0;
+ }
+
+ state->bits_buf = 0;
+ state->bits_count = 0;
+
+ return 1;
+}
+
+static void lzw_dict_reset(struct lzw_state *state)
+{
+ int i;
+
+ state->code_bits = state->init_code_bits + 1;
+ state->next_code = (1 << state->init_code_bits) + 2;
+
+ for(i = 0; i < LZW_DICT_SIZE; i++)
+ {
+ state->dict.prefix[i] = 1 << 12; /* impossible LZW code value */
+ state->dict.suffix[i] = 0;
+ }
+}
+
+static void lzw_state_init(struct lzw_state *state, short init_code_bits, void
*user_write_data, void *user_ptr)
+{
+ state->init_code_bits = init_code_bits;
+ state->clear_code = 1 << init_code_bits;
+ state->eof_code = state->clear_code + 1;
+ state->bits_buf = 0;
+ state->bits_count = 0;
+ state->user_write_data = user_write_data;
+ state->user_ptr = user_ptr;
+
+ lzw_dict_reset(state);
+}
+
+static int lzw_dict_add(struct lzw_state *state, short prefix, unsigned char suffix)
+{
+ if (state->next_code < LZW_DICT_SIZE)
+ {
+ state->dict.prefix[state->next_code] = prefix;
+ state->dict.suffix[state->next_code] = suffix;
+
+ if ((state->next_code & (state->next_code - 1)) == 0)
+ state->code_bits++;
+
+ state->next_code++;
+ return state->next_code;
+ }
+
+ return -1;
+}
+
+static short lzw_dict_lookup(const struct lzw_state *state, short prefix, unsigned char
suffix)
+{
+ short i;
+
+ for (i = 0; i < state->next_code; i++)
+ {
+ if (state->dict.prefix[i] == prefix && state->dict.suffix[i] ==
suffix)
+ return i;
+ }
+
+ return -1;
+}
+
+static inline int write_byte(struct output_stream *out, char byte)
+{
+ if (out->gif_block.len == 255)
+ {
+ if (IStream_Write(out->out, &out->gif_block, sizeof(out->gif_block),
NULL) != S_OK)
+ return 0;
+
+ out->gif_block.len = 0;
+ }
+
+ out->gif_block.data[out->gif_block.len++] = byte;
+
+ return 1;
+}
+
+static int write_data(void *user_ptr, void *user_data, int length)
+{
+ unsigned char *data = user_data;
+ struct output_stream *out = user_ptr;
+ int len = length;
+
+ while (len-- > 0)
+ {
+ if (!write_byte(out, *data++)) return 0;
+ }
+
+ return length;
+}
+
+static int flush_output_data(void *user_ptr)
+{
+ struct output_stream *out = user_ptr;
+
+ if (out->gif_block.len)
+ {
+ if (IStream_Write(out->out, &out->gif_block, out->gif_block.len +
sizeof(out->gif_block.len), NULL) != S_OK)
+ return 0;
+ }
+
+ /* write GIF block terminator */
+ out->gif_block.len = 0;
+ return IStream_Write(out->out, &out->gif_block,
sizeof(out->gif_block.len), NULL) == S_OK;
+}
+
+static inline int read_byte(struct input_stream *in, unsigned char *byte)
+{
+ if (in->len)
+ {
+ in->len--;
+ *byte = *in->in++;
+ return 1;
+ }
+
+ return 0;
+}
+
+static HRESULT gif_compress(IStream *out_stream, const BYTE *in_data, ULONG in_size)
+{
+ struct input_stream in;
+ struct output_stream out;
+ struct lzw_state state;
+ short init_code_bits, prefix, code;
+ unsigned char suffix;
+
+ in.in = in_data;
+ in.len = in_size;
+
+ out.gif_block.len = 0;
+ out.out = out_stream;
+
+ init_code_bits = suffix = 8;
+ if (IStream_Write(out.out, &suffix, sizeof(suffix), NULL) != S_OK)
+ return E_FAIL;
+
+ lzw_state_init(&state, init_code_bits, write_data, &out);
+
+ if (!lzw_output_clear_code(&state))
+ return E_FAIL;
+
+ if (read_byte(&in, &suffix))
+ {
+ prefix = suffix;
+
+ while (read_byte(&in, &suffix))
+ {
+ code = lzw_dict_lookup(&state, prefix, suffix);
+ if (code == -1)
+ {
+ if (!lzw_output_code(&state, prefix))
+ return E_FAIL;
+
+ if (lzw_dict_add(&state, prefix, suffix) == -1)
+ {
+ if (!lzw_output_clear_code(&state))
+ return E_FAIL;
+ lzw_dict_reset(&state);
+ }
+
+ prefix = suffix;
+ }
+ else
+ prefix = code;
+ }
+
+ if (!lzw_output_code(&state, prefix))
+ return E_FAIL;
+ if (!lzw_output_eof_code(&state))
+ return E_FAIL;
+ if (!lzw_flush_bits(&state))
+ return E_FAIL;
+ }
+
+ return flush_output_data(&out) ? S_OK : E_FAIL;
+}
+
+static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface)
+{
+ GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
+ HRESULT hr;
+
+ TRACE("%p\n", iface);
+
+ EnterCriticalSection(&This->encoder->lock);
+
+ if (This->image_data && This->lines == This->height &&
!This->committed)
+ {
+ BYTE gif_palette[256][3];
+
+ hr = S_OK;
+
+ if (!This->encoder->info_written)
+ {
+ struct logical_screen_descriptor lsd;
+
+ /* Logical Screen Descriptor */
+ memcpy(lsd.signature, "GIF89a", 6);
+ lsd.width = This->width;
+ lsd.height = This->height;
+ lsd.packed = 0;
+ if (This->encoder->colors)
+ lsd.packed |= 0x80; /* global color table flag */
+ lsd.packed |= 0x07 << 4; /* color resolution */
+ lsd.packed |= 0x07; /* global color table size */
+ lsd.background_color_index = 0; /* FIXME */
+ lsd.pixel_aspect_ratio = 0;
+ hr = IStream_Write(This->encoder->stream, &lsd, sizeof(lsd),
NULL);
+ if (hr == S_OK && This->encoder->colors)
+ {
+ UINT i;
+
+ /* Global Color Table */
+ memset(gif_palette, 0, sizeof(gif_palette));
+ for (i = 0; i < This->encoder->colors; i++)
+ {
+ gif_palette[i][0] = (This->encoder->palette[i] >> 16)
& 0xff;
+ gif_palette[i][1] = (This->encoder->palette[i] >> 8)
& 0xff;
+ gif_palette[i][2] = This->encoder->palette[i] & 0xff;
+ }
+ hr = IStream_Write(This->encoder->stream, gif_palette,
sizeof(gif_palette), NULL);
+ }
+
+ /* FIXME: write GCE, APE, etc. GIF extensions */
+
+ if (hr == S_OK)
+ This->encoder->info_written = TRUE;
+ }
+
+ if (hr == S_OK)
+ {
+ char image_separator = 0x2c;
+
+ hr = IStream_Write(This->encoder->stream, &image_separator,
sizeof(image_separator), NULL);
+ if (hr == S_OK)
+ {
+ struct image_descriptor imd;
+
+ /* Image Descriptor */
+ imd.left = 0;
+ imd.top = 0;
+ imd.width = This->width;
+ imd.height = This->height;
+ imd.packed = 0;
+ if (This->colors)
+ {
+ imd.packed |= 0x80; /* local color table flag */
+ imd.packed |= 0x07; /* local color table size */
+ }
+ /* FIXME: interlace flag */
+ hr = IStream_Write(This->encoder->stream, &imd, sizeof(imd),
NULL);
+ if (hr == S_OK && This->colors)
+ {
+ UINT i;
+
+ /* Local Color Table */
+ memset(gif_palette, 0, sizeof(gif_palette));
+ for (i = 0; i < This->colors; i++)
+ {
+ gif_palette[i][0] = (This->palette[i] >> 16) &
0xff;
+ gif_palette[i][1] = (This->palette[i] >> 8) & 0xff;
+ gif_palette[i][2] = This->palette[i] & 0xff;
+ }
+ hr = IStream_Write(This->encoder->stream, gif_palette,
sizeof(gif_palette), NULL);
+ if (hr == S_OK)
+ {
+ /* Image Data */
+ hr = gif_compress(This->encoder->stream,
This->image_data, This->width * This->height);
+ if (hr == S_OK)
+ This->committed = TRUE;
+ }
+ }
+ }
+ }
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->encoder->lock);
+ return hr;
+}
+
+static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
IWICMetadataQueryWriter **writer)
+{
+ FIXME("%p, %p: stub\n", iface, writer);
+ return E_NOTIMPL;
+}
+
+static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl =
+{
+ GifFrameEncode_QueryInterface,
+ GifFrameEncode_AddRef,
+ GifFrameEncode_Release,
+ GifFrameEncode_Initialize,
+ GifFrameEncode_SetSize,
+ GifFrameEncode_SetResolution,
+ GifFrameEncode_SetPixelFormat,
+ GifFrameEncode_SetColorContexts,
+ GifFrameEncode_SetPalette,
+ GifFrameEncode_SetThumbnail,
+ GifFrameEncode_WritePixels,
+ GifFrameEncode_WriteSource,
+ GifFrameEncode_Commit,
+ GifFrameEncode_GetMetadataQueryWriter
+};
+
+static HRESULT WINAPI GifEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
+{
+ TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_IWICBitmapEncoder, iid))
+ {
+ IWICBitmapEncoder_AddRef(iface);
+ *ppv = iface;
+ return S_OK;
+ }
+
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("%p -> %u\n", iface, ref);
+ return ref;
+}
+
+static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("%p -> %u\n", iface, ref);
+
+ if (!ref)
+ {
+ if (This->stream) IStream_Release(This->stream);
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI GifEncoder_Initialize(IWICBitmapEncoder *iface, IStream *stream,
WICBitmapEncoderCacheOption option)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p,%#x\n", iface, stream, option);
+
+ if (!stream) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->lock);
+
+ if (!This->initialized)
+ {
+ IStream_AddRef(stream);
+ This->stream = stream;
+ This->initialized = TRUE;
+ hr = S_OK;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
+}
+
+static HRESULT WINAPI GifEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID
*format)
+{
+ if (!format) return E_INVALIDARG;
+
+ *format = GUID_ContainerFormatGif;
+ return S_OK;
+}
+
+static HRESULT WINAPI GifEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
IWICBitmapEncoderInfo **info)
+{
+ IWICComponentInfo *comp_info;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", iface, info);
+
+ if (!info) return E_INVALIDARG;
+
+ hr = CreateComponentInfo(&CLSID_WICGifEncoder, &comp_info);
+ if (hr == S_OK)
+ {
+ hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo,
(void **)info);
+ IWICComponentInfo_Release(comp_info);
+ }
+ return hr;
+}
+
+static HRESULT WINAPI GifEncoder_SetColorContexts(IWICBitmapEncoder *iface, UINT count,
IWICColorContext **context)
+{
+ FIXME("%p,%u,%p: stub\n", iface, count, context);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI GifEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette
*palette)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p\n", iface, palette);
+
+ if (!palette) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->initialized)
+ hr = IWICPalette_GetColors(palette, 256, This->palette,
&This->colors);
+ else
+ hr = WINCODEC_ERR_NOTINITIALIZED;
+
+ LeaveCriticalSection(&This->lock);
+ return hr;
+}
+
+static HRESULT WINAPI GifEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource
*thumbnail)
+{
+ TRACE("%p,%p\n", iface, thumbnail);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource
*preview)
+{
+ TRACE("%p,%p\n", iface, preview);
+ return WINCODEC_ERR_UNSUPPORTEDOPERATION;
+}
+
+static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **frame, IPropertyBag2 **options)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("%p,%p,%p\n", iface, frame, options);
+
+ if (!frame) return E_INVALIDARG;
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->initialized && !This->committed)
+ {
+ GifFrameEncode *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
+ if (ret)
+ {
+ This->n_frames++;
+
+ ret->IWICBitmapFrameEncode_iface.lpVtbl = &GifFrameEncode_Vtbl;
+ ret->ref = 1;
+ ret->encoder = This;
+ ret->initialized = FALSE;
+ ret->interlace = FALSE; /* FIXME: read from the properties */
+ ret->committed = FALSE;
+ ret->width = 0;
+ ret->height = 0;
+ ret->lines = 0;
+ ret->xres = 0.0;
+ ret->yres = 0.0;
+ ret->colors = 0;
+ ret->image_data = NULL;
+ IWICBitmapEncoder_AddRef(iface);
+ *frame = &ret->IWICBitmapFrameEncode_iface;
+
+ hr = S_OK;
+
+ if (options)
+ {
+ hr = CreatePropertyBag2(NULL, 0, options);
+ if (hr != S_OK)
+ {
+ IWICBitmapFrameEncode_Release(*frame);
+ *frame = NULL;
+ }
+ }
+ }
+ else
+ hr = E_OUTOFMEMORY;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->lock);
+
+ return hr;
+
+}
+
+static HRESULT WINAPI GifEncoder_Commit(IWICBitmapEncoder *iface)
+{
+ GifEncoder *This = impl_from_IWICBitmapEncoder(iface);
+ HRESULT hr;
+
+ TRACE("%p\n", iface);
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->initialized && !This->committed)
+ {
+ char gif_trailer = 0x3b;
+
+ /* FIXME: write text, comment GIF extensions */
+
+ hr = IStream_Write(This->stream, &gif_trailer, sizeof(gif_trailer),
NULL);
+ if (hr == S_OK)
+ This->committed = TRUE;
+ }
+ else
+ hr = WINCODEC_ERR_WRONGSTATE;
+
+ LeaveCriticalSection(&This->lock);
+ return hr;
+}
+
+static HRESULT WINAPI GifEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
IWICMetadataQueryWriter **writer)
+{
+ FIXME("%p,%p: stub\n", iface, writer);
+ return E_NOTIMPL;
+}
+
+static const IWICBitmapEncoderVtbl GifEncoder_Vtbl =
+{
+ GifEncoder_QueryInterface,
+ GifEncoder_AddRef,
+ GifEncoder_Release,
+ GifEncoder_Initialize,
+ GifEncoder_GetContainerFormat,
+ GifEncoder_GetEncoderInfo,
+ GifEncoder_SetColorContexts,
+ GifEncoder_SetPalette,
+ GifEncoder_SetThumbnail,
+ GifEncoder_SetPreview,
+ GifEncoder_CreateNewFrame,
+ GifEncoder_Commit,
+ GifEncoder_GetMetadataQueryWriter
+};
+
+HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv)
+{
+ GifEncoder *This;
+ HRESULT ret;
+
+ TRACE("%s,%p\n", debugstr_guid(iid), ppv);
+
+ *ppv = NULL;
+
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ if (!This) return E_OUTOFMEMORY;
+
+ This->IWICBitmapEncoder_iface.lpVtbl = &GifEncoder_Vtbl;
+ This->ref = 1;
+ This->stream = NULL;
+ InitializeCriticalSection(&This->lock);
+ This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ":
GifEncoder.lock");
+ This->initialized = FALSE;
+ This->info_written = FALSE;
+ This->committed = FALSE;
+ This->n_frames = 0;
+ This->colors = 0;
+
+ ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid,
ppv);
+ IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
+
+ return ret;
+}
diff --git a/dll/win32/windowscodecs/icnsformat.c b/dll/win32/windowscodecs/icnsformat.c
index e7d6f96226..aa9640417f 100644
--- a/dll/win32/windowscodecs/icnsformat.c
+++ b/dll/win32/windowscodecs/icnsformat.c
@@ -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)
diff --git a/dll/win32/windowscodecs/icoformat.c b/dll/win32/windowscodecs/icoformat.c
index 86629568fd..1b1c79291b 100644
--- a/dll/win32/windowscodecs/icoformat.c
+++ b/dll/win32/windowscodecs/icoformat.c
@@ -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;
diff --git a/dll/win32/windowscodecs/imgfactory.c b/dll/win32/windowscodecs/imgfactory.c
index 623265762a..88ce00e651 100644
--- a/dll/win32/windowscodecs/imgfactory.c
+++ b/dll/win32/windowscodecs/imgfactory.c
@@ -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;
+ *decoder = NULL;
+
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault,
&enumdecoders);
- if (FAILED(res)) return NULL;
+ if (FAILED(res)) return res;
- while (!decoder)
+ 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);
+}
diff --git a/dll/win32/windowscodecs/info.c b/dll/win32/windowscodecs/info.c
index 63cdc07dbc..22a7b83e2c 100644
--- a/dll/win32/windowscodecs/info.c
+++ b/dll/win32/windowscodecs/info.c
@@ -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)
{
diff --git a/dll/win32/windowscodecs/jpegformat.c b/dll/win32/windowscodecs/jpegformat.c
index cfb84c36aa..0069bdfd89 100644
--- a/dll/win32/windowscodecs/jpegformat.c
+++ b/dll/win32/windowscodecs/jpegformat.c
@@ -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;
diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c
index c53e330a21..3bed56536c 100644
--- a/dll/win32/windowscodecs/main.c
+++ b/dll/win32/windowscodecs/main.c
@@ -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)
diff --git a/dll/win32/windowscodecs/metadatahandler.c
b/dll/win32/windowscodecs/metadatahandler.c
index dff5ed3c7f..3d48924a44 100644
--- a/dll/win32/windowscodecs/metadatahandler.c
+++ b/dll/win32/windowscodecs/metadatahandler.c
@@ -17,11 +17,25 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "wincodecs_private.h"
+#include "config.h"
+#include <stdarg.h>
#include <stdio.h>
-#include <wine/winternl.h>
-#include <propvarutil.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 "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;
diff --git a/dll/win32/windowscodecs/metadataquery.c
b/dll/win32/windowscodecs/metadataquery.c
index c45082b202..e33884881b 100644
--- a/dll/win32/windowscodecs/metadataquery.c
+++ b/dll/win32/windowscodecs/metadataquery.c
@@ -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);
diff --git a/dll/win32/windowscodecs/palette.c b/dll/win32/windowscodecs/palette.c
index 89b10b7ba9..a8370ff103 100644
--- a/dll/win32/windowscodecs/palette.c
+++ b/dll/win32/windowscodecs/palette.c
@@ -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
+{
+ 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)
{
- FIXME("(%p,%p,%u,%i): stub\n", iface, pISurface, colorCount,
fAddTransparentColor);
- return E_NOTIMPL;
+ 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,
diff --git a/dll/win32/windowscodecs/pngformat.c b/dll/win32/windowscodecs/pngformat.c
index 6946721b77..54be5edb45 100644
--- a/dll/win32/windowscodecs/pngformat.c
+++ b/dll/win32/windowscodecs/pngformat.c
@@ -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;
diff --git a/dll/win32/windowscodecs/precomp.h b/dll/win32/windowscodecs/precomp.h
new file mode 100644
index 0000000000..7f4c241216
--- /dev/null
+++ b/dll/win32/windowscodecs/precomp.h
@@ -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 */
diff --git a/dll/win32/windowscodecs/propertybag.c
b/dll/win32/windowscodecs/propertybag.c
index 29f7ac969b..e9d1af9670 100644
--- a/dll/win32/windowscodecs/propertybag.c
+++ b/dll/win32/windowscodecs/propertybag.c
@@ -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;
diff --git a/dll/win32/windowscodecs/proxy.c b/dll/win32/windowscodecs/proxy.c
index 2482d4900e..a28b38681e 100644
--- a/dll/win32/windowscodecs/proxy.c
+++ b/dll/win32/windowscodecs/proxy.c
@@ -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)
{
diff --git a/dll/win32/windowscodecs/regsvr.c b/dll/win32/windowscodecs/regsvr.c
index 756fb19651..328ea54c84 100644
--- a/dll/win32/windowscodecs/regsvr.c
+++ b/dll/win32/windowscodecs/regsvr.c
@@ -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 */
};
diff --git a/dll/win32/windowscodecs/scaler.c b/dll/win32/windowscodecs/scaler.c
index 8e267e314a..3801ea5ecd 100644
--- a/dll/win32/windowscodecs/scaler.c
+++ b/dll/win32/windowscodecs/scaler.c
@@ -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;
diff --git a/dll/win32/windowscodecs/stream.c b/dll/win32/windowscodecs/stream.c
index f585036ede..308ef8e02b 100644
--- a/dll/win32/windowscodecs/stream.c
+++ b/dll/win32/windowscodecs/stream.c
@@ -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
diff --git a/dll/win32/windowscodecs/tgaformat.c b/dll/win32/windowscodecs/tgaformat.c
index 52b5877095..ec7fa23169 100644
--- a/dll/win32/windowscodecs/tgaformat.c
+++ b/dll/win32/windowscodecs/tgaformat.c
@@ -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 {
diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c
index 55423028a4..c23594f61f 100644
--- a/dll/win32/windowscodecs/tiffformat.c
+++ b/dll/win32/windowscodecs/tiffformat.c
@@ -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)
{
- ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres);
- if (!ret)
- {
- WARN("missing X resolution\n");
- decode_info->resolution_unit = 0;
- }
+ 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");
- decode_info->resolution_unit = 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);
+ 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;
+ }
}
- else
+
+ 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++)
{
- 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 += 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;
+ }
}
- if (ret == -1)
- hr = E_FAIL;
+ 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))
{
diff --git a/dll/win32/windowscodecs/ungif.c b/dll/win32/windowscodecs/ungif.c
index 28d76e5ace..c6711c8e24 100644
--- a/dll/win32/windowscodecs/ungif.c
+++ b/dll/win32/windowscodecs/ungif.c
@@ -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 )
{
diff --git a/dll/win32/windowscodecs/wincodecs_private.h
b/dll/win32/windowscodecs/wincodecs_private.h
index 99daf093ad..2f9f6d0b58 100644
--- a/dll/win32/windowscodecs/wincodecs_private.h
+++ b/dll/win32/windowscodecs/wincodecs_private.h
@@ -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;
... 156 lines suppressed ...