- Add windowscodecs.dll from Wine 1.1.28

svn path=/trunk/; revision=42867
This commit is contained in:
Dmitry Chapyshev 2009-08-22 19:03:09 +00:00
parent 9d4ec238ee
commit fcf26f3471
25 changed files with 9348 additions and 0 deletions

View file

@ -6,6 +6,7 @@
<property name="BASEADDRESS_QMGRPRXY" value="0x1F710000" />
<property name="BASEADDRESS_CRYPTDLG" value="0x209C0000" />
<property name="BASEADDRESS_COMCAT" value="0x20A50000" />
<property name="BASEADDRESS_WINDOWSCODECS" value="0x26c40000" />
<property name="BASEADDRESS_DEVENUM" value="0x35680000" />
<property name="BASEADDRESS_RSABASE" value="0x35700000" />
<property name="BASEADDRESS_RSAENH" value="0x35780000" />

View file

@ -439,6 +439,7 @@ dll\win32\usp10\usp10.dll 1
dll\win32\uxtheme\uxtheme.dll 1
dll\win32\vdmdbg\vdmdbg.dll 1
dll\win32\version\version.dll 1
dll\win32\windowscodecs\windowscodecs.dll 1
dll\win32\winemp3.acm\winemp3.acm 1
dll\win32\winfax\winfax.dll 1
dll\win32\winhttp\winhttp.dll 1

View file

@ -583,6 +583,9 @@
<directory name="wdmaud.drv">
<xi:include href="wdmaud.drv/wdmaud.rbuild" />
</directory>
<directory name="windowscodecs">
<xi:include href="windowscodecs/windowscodecs.rbuild" />
</directory>
<directory name="winemp3.acm">
<xi:include href="winemp3.acm/winemp3.acm.rbuild" />
</directory>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,598 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
struct bmp_pixelformat {
const WICPixelFormatGUID *guid;
UINT bpp;
DWORD compression;
DWORD redmask;
DWORD greenmask;
DWORD bluemask;
DWORD alphamask;
};
static const struct bmp_pixelformat formats[] = {
{&GUID_WICPixelFormat24bppBGR, 24, BI_RGB},
{NULL}
};
typedef struct BmpFrameEncode {
const IWICBitmapFrameEncodeVtbl *lpVtbl;
LONG ref;
IStream *stream;
BOOL initialized;
UINT width, height;
BYTE *bits;
const struct bmp_pixelformat *format;
double xres, yres;
UINT lineswritten;
UINT stride;
BOOL committed;
} BmpFrameEncode;
static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
void **ppv)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (This->stream) IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This->bits);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
IPropertyBag2 *pIEncoderOptions)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
TRACE("(%p,%p)\n", iface, pIEncoderOptions);
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
This->initialized = TRUE;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
UINT uiWidth, UINT uiHeight)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;
This->width = uiWidth;
This->height = uiHeight;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
double dpiX, double dpiY)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;
This->xres = dpiX;
This->yres = dpiY;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
WICPixelFormatGUID *pPixelFormat)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
int i;
TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;
for (i=0; formats[i].guid; i++)
{
if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0)
break;
}
if (!formats[i].guid) i = 0;
This->format = &formats[i];
memcpy(pPixelFormat, This->format->guid, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
UINT cCount, IWICColorContext **ppIColorContext)
{
FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
return E_NOTIMPL;
}
static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIThumbnail)
{
FIXME("(%p,%p): stub\n", iface, pIThumbnail);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT BmpFrameEncode_AllocateBits(BmpFrameEncode *This)
{
if (!This->bits)
{
if (!This->initialized || !This->width || !This->height || !This->format)
return WINCODEC_ERR_WRONGSTATE;
This->stride = (((This->width * This->format->bpp)+31)/32)*4;
This->bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->stride * This->height);
if (!This->bits) return E_OUTOFMEMORY;
}
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
HRESULT hr;
WICRect rc;
TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
if (!This->initialized || !This->width || !This->height || !This->format)
return WINCODEC_ERR_WRONGSTATE;
hr = BmpFrameEncode_AllocateBits(This);
if (FAILED(hr)) return hr;
rc.X = 0;
rc.Y = 0;
rc.Width = This->width;
rc.Height = lineCount;
hr = copy_pixels(This->format->bpp, pbPixels, This->width, lineCount, cbStride,
&rc, This->stride, This->stride*(This->height-This->lineswritten),
This->bits + This->stride*This->lineswritten);
if (SUCCEEDED(hr))
This->lineswritten += lineCount;
return hr;
}
static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
HRESULT hr;
WICRect rc;
WICPixelFormatGUID guid;
TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);
if (!This->initialized || !This->width || !This->height)
return WINCODEC_ERR_WRONGSTATE;
if (!This->format)
{
hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
if (FAILED(hr)) return hr;
hr = BmpFrameEncode_SetPixelFormat(iface, &guid);
if (FAILED(hr)) return hr;
}
hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
if (FAILED(hr)) return hr;
if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0)
{
/* should use WICConvertBitmapSource to convert, but that's unimplemented */
ERR("format %s unsupported\n", debugstr_guid(&guid));
return E_FAIL;
}
if (This->xres == 0.0 || This->yres == 0.0)
{
double xres, yres;
hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres);
if (FAILED(hr)) return hr;
hr = BmpFrameEncode_SetResolution(iface, xres, yres);
if (FAILED(hr)) return hr;
}
if (!prc)
{
UINT width, height;
hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
if (FAILED(hr)) return hr;
rc.X = 0;
rc.Y = 0;
rc.Width = width;
rc.Height = height;
prc = &rc;
}
if (prc->Width != This->width) return E_INVALIDARG;
hr = BmpFrameEncode_AllocateBits(This);
if (FAILED(hr)) return hr;
hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, This->stride,
This->stride*(This->height-This->lineswritten),
This->bits + This->stride*This->lineswritten);
This->lineswritten += rc.Height;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
{
BmpFrameEncode *This = (BmpFrameEncode*)iface;
BITMAPFILEHEADER bfh;
BITMAPV5HEADER bih;
UINT info_size;
LARGE_INTEGER pos;
ULONG byteswritten;
HRESULT hr;
TRACE("(%p)\n", iface);
if (!This->bits || This->committed || This->height != This->lineswritten)
return WINCODEC_ERR_WRONGSTATE;
bfh.bfType = 0x4d42; /* "BM" */
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER);
bih.bV5Width = This->width;
bih.bV5Height = -This->height; /* top-down 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;
bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size;
pos.QuadPart = 0;
hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL);\
if (FAILED(hr)) return hr;
hr = IStream_Write(This->stream, &bfh, sizeof(BITMAPFILEHEADER), &byteswritten);
if (FAILED(hr)) return hr;
if (byteswritten != sizeof(BITMAPFILEHEADER)) return E_FAIL;
hr = IStream_Write(This->stream, &bih, info_size, &byteswritten);
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;
This->committed = TRUE;
return S_OK;
}
static HRESULT WINAPI BmpFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
return E_NOTIMPL;
}
static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = {
BmpFrameEncode_QueryInterface,
BmpFrameEncode_AddRef,
BmpFrameEncode_Release,
BmpFrameEncode_Initialize,
BmpFrameEncode_SetSize,
BmpFrameEncode_SetResolution,
BmpFrameEncode_SetPixelFormat,
BmpFrameEncode_SetColorContexts,
BmpFrameEncode_SetPalette,
BmpFrameEncode_SetThumbnail,
BmpFrameEncode_WritePixels,
BmpFrameEncode_WriteSource,
BmpFrameEncode_Commit,
BmpFrameEncode_GetMetadataQueryWriter
};
typedef struct BmpEncoder {
const IWICBitmapEncoderVtbl *lpVtbl;
LONG ref;
IStream *stream;
IWICBitmapFrameEncode *frame;
} BmpEncoder;
static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
void **ppv)
{
BmpEncoder *This = (BmpEncoder*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapEncoder, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (This->stream) IStream_Release(This->stream);
if (This->frame) IWICBitmapFrameEncode_Release(This->frame);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI BmpEncoder_Initialize(IWICBitmapEncoder *iface,
IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
BmpEncoder *This = (BmpEncoder*)iface;
TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
IStream_AddRef(pIStream);
This->stream = pIStream;
return S_OK;
}
static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
GUID *pguidContainerFormat)
{
FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
return E_NOTIMPL;
}
static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
IWICBitmapEncoderInfo **ppIEncoderInfo)
{
FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
return E_NOTIMPL;
}
static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface,
UINT cCount, IWICColorContext **ppIColorContext)
{
FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
return E_NOTIMPL;
}
static HRESULT WINAPI BmpEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
{
TRACE("(%p,%p)\n", iface, pIPalette);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI BmpEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
{
TRACE("(%p,%p)\n", iface, pIThumbnail);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI BmpEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
{
TRACE("(%p,%p)\n", iface, pIPreview);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpFrameEncode *encode;
HRESULT hr;
TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
if (This->frame) return WINCODEC_ERR_UNSUPPORTEDOPERATION;
if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED;
hr = CreatePropertyBag2(ppIEncoderOptions);
if (FAILED(hr)) return hr;
encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode));
if (!encode)
{
IPropertyBag2_Release(*ppIEncoderOptions);
*ppIEncoderOptions = NULL;
return E_OUTOFMEMORY;
}
encode->lpVtbl = &BmpFrameEncode_Vtbl;
encode->ref = 2;
IStream_AddRef(This->stream);
encode->stream = This->stream;
encode->initialized = FALSE;
encode->width = 0;
encode->height = 0;
encode->bits = NULL;
encode->format = NULL;
encode->xres = 0.0;
encode->yres = 0.0;
encode->lineswritten = 0;
encode->committed = FALSE;
*ppIFrameEncode = (IWICBitmapFrameEncode*)encode;
This->frame = (IWICBitmapFrameEncode*)encode;
return S_OK;
}
static HRESULT WINAPI BmpEncoder_Commit(IWICBitmapEncoder *iface)
{
BmpEncoder *This = (BmpEncoder*)iface;
BmpFrameEncode *frame = (BmpFrameEncode*)This->frame;
TRACE("(%p)\n", iface);
if (!frame || !frame->committed) return WINCODEC_ERR_WRONGSTATE;
return S_OK;
}
static HRESULT WINAPI BmpEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
return E_NOTIMPL;
}
static const IWICBitmapEncoderVtbl BmpEncoder_Vtbl = {
BmpEncoder_QueryInterface,
BmpEncoder_AddRef,
BmpEncoder_Release,
BmpEncoder_Initialize,
BmpEncoder_GetContainerFormat,
BmpEncoder_GetEncoderInfo,
BmpEncoder_SetColorContexts,
BmpEncoder_SetPalette,
BmpEncoder_SetThumbnail,
BmpEncoder_SetPreview,
BmpEncoder_CreateNewFrame,
BmpEncoder_Commit,
BmpEncoder_GetMetadataQueryWriter
};
HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
BmpEncoder *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpEncoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &BmpEncoder_Vtbl;
This->ref = 1;
This->stream = NULL;
This->frame = NULL;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}

View file

@ -0,0 +1,175 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "ocidl.h"
#include "initguid.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
REFCLSID classid;
HRESULT (*constructor)(IUnknown*,REFIID,void**);
} classinfo;
static classinfo wic_classes[] = {
{&CLSID_WICImagingFactory, ImagingFactory_CreateInstance},
{&CLSID_WICBmpDecoder, BmpDecoder_CreateInstance},
{&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance},
{&CLSID_WICGifDecoder, GifDecoder_CreateInstance},
{&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance},
{&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance},
{0}};
typedef struct {
const IClassFactoryVtbl *lpIClassFactoryVtbl;
LONG ref;
classinfo *info;
} ClassFactoryImpl;
static HRESULT WINAPI ClassFactoryImpl_QueryInterface(IClassFactory *iface,
REFIID iid, void **ppv)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IClassFactory, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
HeapFree(GetProcessHeap(), 0, This);
return ref;
}
static HRESULT WINAPI ClassFactoryImpl_CreateInstance(IClassFactory *iface,
IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
ClassFactoryImpl *This = (ClassFactoryImpl*)iface;
return This->info->constructor(pUnkOuter, riid, ppv);
}
static HRESULT WINAPI ClassFactoryImpl_LockServer(IClassFactory *iface, BOOL lock)
{
TRACE("(%p, %i): stub\n", iface, lock);
return E_NOTIMPL;
}
static const IClassFactoryVtbl ClassFactoryImpl_Vtbl = {
ClassFactoryImpl_QueryInterface,
ClassFactoryImpl_AddRef,
ClassFactoryImpl_Release,
ClassFactoryImpl_CreateInstance,
ClassFactoryImpl_LockServer
};
static HRESULT ClassFactoryImpl_Constructor(classinfo *info, REFIID riid, LPVOID *ppv)
{
ClassFactoryImpl *This;
HRESULT ret;
*ppv = NULL;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl));
if (!This) return E_OUTOFMEMORY;
This->lpIClassFactoryVtbl = &ClassFactoryImpl_Vtbl;
This->ref = 1;
This->info = info;
ret = IClassFactory_QueryInterface((IClassFactory*)This, riid, ppv);
IClassFactory_Release((IClassFactory*)This);
return ret;
}
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
HRESULT ret;
classinfo *info=NULL;
int i;
TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
if (!rclsid || !iid || !ppv)
return E_INVALIDARG;
*ppv = NULL;
for (i=0; wic_classes[i].classid; i++)
{
if (IsEqualCLSID(wic_classes[i].classid, rclsid))
{
info = &wic_classes[i];
break;
}
}
if (info)
ret = ClassFactoryImpl_Constructor(info, iid, ppv);
else
ret = CLASS_E_CLASSNOTAVAILABLE;
TRACE("<-- %08X\n", ret);
return ret;
}

View file

@ -0,0 +1,659 @@
/*
* Copyright 2009 Vincent Povirk
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
struct FormatConverter;
enum pixelformat {
format_1bppIndexed,
format_4bppIndexed,
format_8bppIndexed,
format_16bppBGR555,
format_16bppBGR565,
format_24bppBGR,
format_32bppBGR,
format_32bppBGRA
};
typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc,
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format);
struct pixelformatinfo {
enum pixelformat format;
const WICPixelFormatGUID *guid;
copyfunc copy_function;
};
typedef struct FormatConverter {
const IWICFormatConverterVtbl *lpVtbl;
LONG ref;
IWICBitmapSource *source;
const struct pixelformatinfo *dst_format, *src_format;
WICBitmapDitherType dither;
double alpha_threshold;
WICBitmapPaletteType palette_type;
} FormatConverter;
static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc,
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
{
switch (source_format)
{
case format_1bppIndexed:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const BYTE *srcbyte;
BYTE *dstrow;
DWORD *dstpixel;
WICColor colors[2];
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = (prc->Width+7)/8;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x+=8) {
BYTE srcval;
srcval=*srcbyte++;
*dstpixel++ = colors[srcval>>7&1];
if (x+1 < prc->Width) *dstpixel++ = colors[srcval>>6&1];
if (x+2 < prc->Width) *dstpixel++ = colors[srcval>>5&1];
if (x+3 < prc->Width) *dstpixel++ = colors[srcval>>4&1];
if (x+4 < prc->Width) *dstpixel++ = colors[srcval>>3&1];
if (x+5 < prc->Width) *dstpixel++ = colors[srcval>>2&1];
if (x+6 < prc->Width) *dstpixel++ = colors[srcval>>1&1];
if (x+7 < prc->Width) *dstpixel++ = colors[srcval&1];
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_4bppIndexed:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const BYTE *srcbyte;
BYTE *dstrow;
DWORD *dstpixel;
WICColor colors[16];
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = (prc->Width+1)/2;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x+=2) {
BYTE srcval;
srcval=*srcbyte++;
*dstpixel++ = colors[srcval>>4];
if (x+1 < prc->Width) *dstpixel++ = colors[srcval&0xf];
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_8bppIndexed:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const BYTE *srcbyte;
BYTE *dstrow;
DWORD *dstpixel;
WICColor colors[256];
IWICPalette *palette;
UINT actualcolors;
res = PaletteImpl_Create(&palette);
if (FAILED(res)) return res;
res = IWICBitmapSource_CopyPalette(This->source, palette);
if (SUCCEEDED(res))
res = IWICPalette_GetColors(palette, 256, colors, &actualcolors);
IWICPalette_Release(palette);
if (FAILED(res)) return res;
srcstride = prc->Width;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcbyte=(const BYTE*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++)
*dstpixel++ = colors[*srcbyte++];
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_16bppBGR555:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const WORD *srcpixel;
BYTE *dstrow;
DWORD *dstpixel;
srcstride = 2 * prc->Width;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcpixel=(const WORD*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++) {
WORD srcval;
srcval=*srcpixel++;
*dstpixel++=0xff000000 | /* constant 255 alpha */
((srcval << 9) & 0xf80000) | /* r */
((srcval << 4) & 0x070000) | /* r - 3 bits */
((srcval << 6) & 0x00f800) | /* g */
((srcval << 1) & 0x000700) | /* g - 3 bits */
((srcval << 3) & 0x0000f8) | /* b */
((srcval >> 2) & 0x000007); /* b - 3 bits */
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_16bppBGR565:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const WORD *srcpixel;
BYTE *dstrow;
DWORD *dstpixel;
srcstride = 2 * prc->Width;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcpixel=(const WORD*)srcrow;
dstpixel=(DWORD*)dstrow;
for (x=0; x<prc->Width; x++) {
WORD srcval;
srcval=*srcpixel++;
*dstpixel++=0xff000000 | /* constant 255 alpha */
((srcval << 8) & 0xf80000) | /* r */
((srcval << 3) & 0x070000) | /* r - 3 bits */
((srcval << 5) & 0x00fc00) | /* g */
((srcval >> 1) & 0x000300) | /* g - 2 bits */
((srcval << 3) & 0x0000f8) | /* b */
((srcval >> 2) & 0x000007); /* b - 3 bits */
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_24bppBGR:
if (prc)
{
HRESULT res;
UINT x, y;
BYTE *srcdata;
UINT srcstride, srcdatasize;
const BYTE *srcrow;
const BYTE *srcpixel;
BYTE *dstrow;
BYTE *dstpixel;
srcstride = 3 * prc->Width;
srcdatasize = srcstride * prc->Height;
srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
if (!srcdata) return E_OUTOFMEMORY;
res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
if (SUCCEEDED(res))
{
srcrow = srcdata;
dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcpixel=srcrow;
dstpixel=dstrow;
for (x=0; x<prc->Width; x++) {
*dstpixel++=*srcpixel++; /* blue */
*dstpixel++=*srcpixel++; /* green */
*dstpixel++=*srcpixel++; /* red */
*dstpixel++=255; /* alpha */
}
srcrow += srcstride;
dstrow += cbStride;
}
}
HeapFree(GetProcessHeap(), 0, srcdata);
return res;
}
return S_OK;
case format_32bppBGR:
if (prc)
{
HRESULT res;
UINT x, y;
res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
if (FAILED(res)) return res;
/* set all alpha values to 255 */
for (y=0; y<prc->Height; y++)
for (x=0; x<prc->Width; x++)
pbBuffer[cbStride*y+4*x+3] = 0xff;
}
return S_OK;
case format_32bppBGRA:
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
default:
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
}
static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc,
UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
{
switch (source_format)
{
case format_32bppBGR:
case format_32bppBGRA:
if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
return S_OK;
default:
return copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
}
}
static const struct pixelformatinfo supported_formats[] = {
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
{format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
{format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, NULL},
{format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL},
{format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL},
{format_24bppBGR, &GUID_WICPixelFormat24bppBGR, NULL},
{format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
{format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
{0}
};
static const struct pixelformatinfo *get_formatinfo(const WICPixelFormatGUID *format)
{
UINT i;
for (i=0; supported_formats[i].guid; i++)
if (IsEqualGUID(supported_formats[i].guid, format)) return &supported_formats[i];
return NULL;
}
static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid,
void **ppv)
{
FormatConverter *This = (FormatConverter*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICFormatConverter, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
{
FormatConverter *This = (FormatConverter*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
{
FormatConverter *This = (FormatConverter*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (This->source) IWICBitmapSource_Release(This->source);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface,
UINT *puiWidth, UINT *puiHeight)
{
FormatConverter *This = (FormatConverter*)iface;
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
if (This->source)
return IWICBitmapSource_GetSize(This->source, puiWidth, puiHeight);
else
return WINCODEC_ERR_NOTINITIALIZED;
}
static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
WICPixelFormatGUID *pPixelFormat)
{
FormatConverter *This = (FormatConverter*)iface;
TRACE("(%p,%p): stub\n", iface, pPixelFormat);
if (This->source)
memcpy(pPixelFormat, This->dst_format->guid, sizeof(GUID));
else
return WINCODEC_ERR_NOTINITIALIZED;
return S_OK;
}
static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
double *pDpiX, double *pDpiY)
{
FormatConverter *This = (FormatConverter*)iface;
TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
if (This->source)
return IWICBitmapSource_GetResolution(This->source, pDpiX, pDpiY);
else
return WINCODEC_ERR_NOTINITIALIZED;
}
static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return E_NOTIMPL;
}
static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
FormatConverter *This = (FormatConverter*)iface;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
if (This->source)
return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
pbBuffer, This->src_format->format);
else
return WINCODEC_ERR_NOTINITIALIZED;
}
static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
{
FormatConverter *This = (FormatConverter*)iface;
const struct pixelformatinfo *srcinfo, *dstinfo;
static INT fixme=0;
GUID srcFormat;
HRESULT res;
TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface, pISource, debugstr_guid(dstFormat),
dither, pIPalette, alphaThresholdPercent, paletteTranslate);
if (pIPalette && !fixme++) FIXME("ignoring palette\n");
if (This->source) return WINCODEC_ERR_WRONGSTATE;
res = IWICBitmapSource_GetPixelFormat(pISource, &srcFormat);
if (FAILED(res)) return res;
srcinfo = get_formatinfo(&srcFormat);
if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
dstinfo = get_formatinfo(dstFormat);
if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
if (dstinfo->copy_function)
{
IWICBitmapSource_AddRef(pISource);
This->source = pISource;
This->src_format = srcinfo;
This->dst_format = dstinfo;
This->dither = dither;
This->alpha_threshold = alphaThresholdPercent;
This->palette_type = paletteTranslate;
}
else
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
return S_OK;
}
static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat,
BOOL *pfCanConvert)
{
FormatConverter *This = (FormatConverter*)iface;
const struct pixelformatinfo *srcinfo, *dstinfo;
TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat),
debugstr_guid(dstPixelFormat), pfCanConvert);
srcinfo = get_formatinfo(srcPixelFormat);
if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
dstinfo = get_formatinfo(dstPixelFormat);
if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
if (dstinfo->copy_function &&
SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format)))
*pfCanConvert = TRUE;
else
*pfCanConvert = FALSE;
return S_OK;
}
static const IWICFormatConverterVtbl FormatConverter_Vtbl = {
FormatConverter_QueryInterface,
FormatConverter_AddRef,
FormatConverter_Release,
FormatConverter_GetSize,
FormatConverter_GetPixelFormat,
FormatConverter_GetResolution,
FormatConverter_CopyPalette,
FormatConverter_CopyPixels,
FormatConverter_Initialize,
FormatConverter_CanConvert
};
HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
FormatConverter *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &FormatConverter_Vtbl;
This->ref = 1;
This->source = NULL;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}

View file

@ -0,0 +1,510 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "ungif.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
const IWICBitmapDecoderVtbl *lpVtbl;
LONG ref;
BOOL initialized;
GifFileType *gif;
} GifDecoder;
typedef struct {
const IWICBitmapFrameDecodeVtbl *lpVtbl;
LONG ref;
SavedImage *frame;
GifDecoder *parent;
} GifFrameDecode;
static HRESULT WINAPI GifFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
void **ppv)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
IUnknown_Release((IUnknown*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI GifFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
*puiWidth = This->frame->ImageDesc.Width;
*puiHeight = This->frame->ImageDesc.Height;
return S_OK;
}
static HRESULT WINAPI GifFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
WICPixelFormatGUID *pPixelFormat)
{
memcpy(pPixelFormat, &GUID_WICPixelFormat8bppIndexed, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
return E_NOTIMPL;
}
static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
WICColor colors[256];
ColorMapObject *cm = This->frame->ImageDesc.ColorMap;
int i, trans;
ExtensionBlock *eb;
TRACE("(%p,%p)\n", iface, pIPalette);
if (!cm) cm = This->parent->gif->SColorMap;
if (cm->ColorCount > 256)
{
ERR("GIF contains %i colors???\n", cm->ColorCount);
return E_FAIL;
}
for (i = 0; i < cm->ColorCount; i++) {
colors[i] = 0xff000000| /* alpha */
cm->Colors[i].Red << 16|
cm->Colors[i].Green << 8|
cm->Colors[i].Blue;
}
/* look for the transparent color extension */
for (i = 0; i < This->frame->ExtensionBlockCount; ++i) {
eb = This->frame->ExtensionBlocks + i;
if (eb->Function == 0xF9 && eb->ByteCount == 4) {
if ((eb->Bytes[0] & 1) == 1) {
trans = (unsigned char)eb->Bytes[3];
colors[trans] &= 0xffffff; /* set alpha to 0 */
break;
}
}
}
IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount);
return S_OK;
}
static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer,
UINT srcwidth, UINT srcheight, INT srcstride, const WICRect *rc,
UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
{
UINT row_offset; /* number of bytes into the source rows where the data starts */
const BYTE *src;
BYTE *dst;
UINT y;
if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
return E_INVALIDARG;
if (dststride < rc->Width)
return E_INVALIDARG;
if ((dststride * rc->Height) > dstbuffersize)
return E_INVALIDARG;
row_offset = rc->X;
dst = dstbuffer;
for (y=rc->Y; y-rc->Y < rc->Height; y++)
{
if (y%8 == 0)
src = srcbuffer + srcstride * (y/8);
else if (y%4 == 0)
src = srcbuffer + srcstride * ((srcheight+7)/8 + y/8);
else if (y%2 == 0)
src = srcbuffer + srcstride * ((srcheight+3)/4 + y/4);
else /* y%2 == 1 */
src = srcbuffer + srcstride * ((srcheight+1)/2 + y/2);
src += row_offset;
memcpy(dst, src, rc->Width);
dst += dststride;
}
return S_OK;
}
static HRESULT WINAPI GifFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
GifFrameDecode *This = (GifFrameDecode*)iface;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
if (This->frame->ImageDesc.Interlace)
{
return copy_interlaced_pixels(This->frame->RasterBits, This->frame->ImageDesc.Width,
This->frame->ImageDesc.Height, This->frame->ImageDesc.Width,
prc, cbStride, cbBufferSize, pbBuffer);
}
else
{
return copy_pixels(8, This->frame->RasterBits, This->frame->ImageDesc.Width,
This->frame->ImageDesc.Height, This->frame->ImageDesc.Width,
prc, cbStride, cbBufferSize, pbBuffer);
}
}
static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI GifFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
IWICBitmapSource **ppIThumbnail)
{
TRACE("(%p,%p)\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static const IWICBitmapFrameDecodeVtbl GifFrameDecode_Vtbl = {
GifFrameDecode_QueryInterface,
GifFrameDecode_AddRef,
GifFrameDecode_Release,
GifFrameDecode_GetSize,
GifFrameDecode_GetPixelFormat,
GifFrameDecode_GetResolution,
GifFrameDecode_CopyPalette,
GifFrameDecode_CopyPixels,
GifFrameDecode_GetMetadataQueryReader,
GifFrameDecode_GetColorContexts,
GifFrameDecode_GetThumbnail
};
static HRESULT WINAPI GifDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
GifDecoder *This = (GifDecoder*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI GifDecoder_AddRef(IWICBitmapDecoder *iface)
{
GifDecoder *This = (GifDecoder*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
{
GifDecoder *This = (GifDecoder*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
DGifCloseFile(This->gif);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI GifDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
DWORD *pdwCapability)
{
FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
return E_NOTIMPL;
}
static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
IStream *stream = gif->UserData;
ULONG bytesread;
HRESULT hr;
if (!stream)
{
ERR("attempting to read file after initialization\n");
return 0;
}
hr = IStream_Read(stream, data, len, &bytesread);
if (hr != S_OK) bytesread = 0;
return bytesread;
}
static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
GifDecoder *This = (GifDecoder*)iface;
LARGE_INTEGER seek;
int ret;
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
if (This->initialized || This->gif)
{
WARN("already initialized\n");
return WINCODEC_ERR_WRONGSTATE;
}
/* seek to start of stream */
seek.QuadPart = 0;
IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
/* read all data from the stream */
This->gif = DGifOpen((void*)pIStream, _gif_inputfunc);
if (!This->gif) return E_FAIL;
ret = DGifSlurp(This->gif);
if (ret == GIF_ERROR) return E_FAIL;
/* make sure we don't use the stream after this method returns */
This->gif->UserData = NULL;
This->initialized = TRUE;
return S_OK;
}
static HRESULT WINAPI GifDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
GUID *pguidContainerFormat)
{
memcpy(pguidContainerFormat, &GUID_ContainerFormatGif, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI GifDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
HRESULT hr;
IWICComponentInfo *compinfo;
TRACE("(%p,%p)\n", iface, ppIDecoderInfo);
hr = CreateComponentInfo(&CLSID_WICGifDecoder, &compinfo);
if (FAILED(hr)) return hr;
hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
(void**)ppIDecoderInfo);
IWICComponentInfo_Release(compinfo);
return hr;
}
static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface,
IWICPalette *pIPalette)
{
TRACE("(%p,%p)\n", iface, pIPalette);
return WINCODEC_ERR_PALETTEUNAVAILABLE;
}
static HRESULT WINAPI GifDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI GifDecoder_GetPreview(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIBitmapSource)
{
TRACE("(%p,%p)\n", iface, ppIBitmapSource);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI GifDecoder_GetColorContexts(IWICBitmapDecoder *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI GifDecoder_GetThumbnail(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIThumbnail)
{
TRACE("(%p,%p)\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static HRESULT WINAPI GifDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
GifDecoder *This = (GifDecoder*)iface;
TRACE("(%p,%p)\n", iface, pCount);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
*pCount = This->gif->ImageCount;
TRACE("<- %u\n", *pCount);
return S_OK;
}
static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
GifDecoder *This = (GifDecoder*)iface;
GifFrameDecode *result;
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
if (index >= This->gif->ImageCount) return E_INVALIDARG;
result = HeapAlloc(GetProcessHeap(), 0, sizeof(GifFrameDecode));
if (!result) return E_OUTOFMEMORY;
result->lpVtbl = &GifFrameDecode_Vtbl;
result->ref = 1;
result->frame = &This->gif->SavedImages[index];
IWICBitmapDecoder_AddRef(iface);
result->parent = This;
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
return S_OK;
}
static const IWICBitmapDecoderVtbl GifDecoder_Vtbl = {
GifDecoder_QueryInterface,
GifDecoder_AddRef,
GifDecoder_Release,
GifDecoder_QueryCapability,
GifDecoder_Initialize,
GifDecoder_GetContainerFormat,
GifDecoder_GetDecoderInfo,
GifDecoder_CopyPalette,
GifDecoder_GetMetadataQueryReader,
GifDecoder_GetPreview,
GifDecoder_GetColorContexts,
GifDecoder_GetThumbnail,
GifDecoder_GetFrameCount,
GifDecoder_GetFrame
};
HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
GifDecoder *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(GifDecoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &GifDecoder_Vtbl;
This->ref = 1;
This->initialized = FALSE;
This->gif = NULL;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}

View file

@ -0,0 +1,797 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
#include "pshpack1.h"
typedef struct {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwDIBSize;
DWORD dwDIBOffset;
} ICONDIRENTRY;
typedef struct
{
WORD idReserved;
WORD idType;
WORD idCount;
} ICONHEADER;
#include "poppack.h"
typedef struct {
const IWICBitmapDecoderVtbl *lpVtbl;
LONG ref;
BOOL initialized;
IStream *stream;
ICONHEADER header;
} IcoDecoder;
typedef struct {
const IWICBitmapFrameDecodeVtbl *lpVtbl;
LONG ref;
ICONDIRENTRY entry;
IcoDecoder *parent;
BYTE *bits;
} IcoFrameDecode;
static HRESULT WINAPI IcoFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
void **ppv)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IWICBitmapSource, iid) ||
IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
IUnknown_Release((IUnknown*)This->parent);
HeapFree(GetProcessHeap(), 0, This->bits);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI IcoFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
UINT *puiWidth, UINT *puiHeight)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
*puiWidth = This->entry.bWidth ? This->entry.bWidth : 256;
*puiHeight = This->entry.bHeight ? This->entry.bHeight : 256;
TRACE("(%p) -> (%i,%i)\n", iface, *puiWidth, *puiHeight);
return S_OK;
}
static HRESULT WINAPI IcoFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
WICPixelFormatGUID *pPixelFormat)
{
memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
return S_OK;
}
static HRESULT WINAPI IcoFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
double *pDpiX, double *pDpiY)
{
FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
return E_NOTIMPL;
}
static HRESULT WINAPI IcoFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
TRACE("(%p,%p)\n", iface, pIPalette);
return WINCODEC_ERR_PALETTEUNAVAILABLE;
}
static inline void pixel_set_trans(DWORD* pixel, BOOL transparent)
{
if (transparent) *pixel = 0;
else *pixel |= 0xff000000;
}
static HRESULT IcoFrameDecode_ReadPixels(IcoFrameDecode *This)
{
BITMAPINFOHEADER bih;
DWORD colors[256];
UINT colorcount=0;
LARGE_INTEGER seek;
ULONG bytesread;
HRESULT hr;
BYTE *tempdata = NULL;
BYTE *bits = NULL;
UINT bitsStride;
UINT bitsSize;
UINT width, height;
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
/* read the BITMAPINFOHEADER */
seek.QuadPart = This->entry.dwDIBOffset;
hr = IStream_Seek(This->parent->stream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) goto fail;
hr = IStream_Read(This->parent->stream, &bih, sizeof(BITMAPINFOHEADER), &bytesread);
if (FAILED(hr) || bytesread != sizeof(BITMAPINFOHEADER)) goto fail;
if (This->entry.wBitCount <= 8)
{
/* read the palette */
colorcount = This->entry.bColorCount ? This->entry.bColorCount : 256;
hr = IStream_Read(This->parent->stream, colors, sizeof(RGBQUAD)*colorcount, &bytesread);
if (FAILED(hr) || bytesread != sizeof(RGBQUAD)*colorcount) goto fail;
}
bitsStride = width * 4;
bitsSize = bitsStride * height;
/* read the XOR data */
switch (This->entry.wBitCount)
{
case 1:
{
UINT xorBytesPerRow = (width+31)/32*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 1-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>7];
if (x+1 < width) *bitsPixel++ = colors[xorVal>>6&1];
if (x+2 < width) *bitsPixel++ = colors[xorVal>>5&1];
if (x+3 < width) *bitsPixel++ = colors[xorVal>>4&1];
if (x+4 < width) *bitsPixel++ = colors[xorVal>>3&1];
if (x+5 < width) *bitsPixel++ = colors[xorVal>>2&1];
if (x+6 < width) *bitsPixel++ = colors[xorVal>>1&1];
if (x+7 < width) *bitsPixel++ = colors[xorVal&1];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 4:
{
UINT xorBytesPerRow = (width+7)/8*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 4-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=2) {
BYTE xorVal;
xorVal=*xorByte++;
*bitsPixel++ = colors[xorVal>>4];
if (x+1 < width) *bitsPixel++ = colors[xorVal&0xf];
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 8:
{
UINT xorBytesPerRow = (width+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* palette-map the 8-bit data */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x++)
*bitsPixel++ = colors[*xorByte++];
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 24:
{
UINT xorBytesPerRow = (width*3+3)/4*4;
UINT xorBytes = xorBytesPerRow * height;
INT xorStride;
BYTE *xorRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
xorStride = -xorBytesPerRow;
xorRow = tempdata + (height-1)*xorBytesPerRow;
}
else /* top-down DIB */
{
xorStride = xorBytesPerRow;
xorRow = tempdata;
}
bits = HeapAlloc(GetProcessHeap(), 0, bitsSize);
/* copy BGR->BGRA */
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *xorByte=xorRow;
BYTE *bitsByte=bitsRow;
for (x=0; x<width; x++)
{
*bitsByte++ = *xorByte++; /* blue */
*bitsByte++ = *xorByte++; /* green */
*bitsByte++ = *xorByte++; /* red */
bitsByte++; /* alpha */
}
xorRow += xorStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
break;
}
case 32:
{
UINT xorBytesPerRow = width*4;
UINT xorBytes = xorBytesPerRow * height;
bits = HeapAlloc(GetProcessHeap(), 0, xorBytes);
if (!bits)
{
hr = E_OUTOFMEMORY;
goto fail;
}
if (bih.biHeight > 0) /* bottom-up DIB */
{
/* read the rows backwards so we get a top-down DIB */
UINT i;
BYTE *xorRow = bits + xorBytesPerRow * (height-1);
for (i=0; i<height; i++)
{
hr = IStream_Read(This->parent->stream, xorRow, xorBytesPerRow, &bytesread);
if (FAILED(hr) || bytesread != xorBytesPerRow) goto fail;
xorRow -= xorBytesPerRow;
}
}
else /* top-down DIB */
{
hr = IStream_Read(This->parent->stream, bits, xorBytes, &bytesread);
if (FAILED(hr) || bytesread != xorBytes) goto fail;
}
break;
}
default:
FIXME("unsupported bitcount: %u\n", This->entry.wBitCount);
goto fail;
}
if (This->entry.wBitCount < 32)
{
/* set alpha data based on the AND mask */
UINT andBytesPerRow = (width+31)/32*4;
UINT andBytes = andBytesPerRow * height;
INT andStride;
BYTE *andRow;
BYTE *bitsRow;
UINT x, y;
tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes);
if (!tempdata)
{
hr = E_OUTOFMEMORY;
goto fail;
}
hr = IStream_Read(This->parent->stream, tempdata, andBytes, &bytesread);
if (FAILED(hr) || bytesread != andBytes) goto fail;
if (bih.biHeight > 0) /* bottom-up DIB */
{
andStride = -andBytesPerRow;
andRow = tempdata + (height-1)*andBytesPerRow;
}
else /* top-down DIB */
{
andStride = andBytesPerRow;
andRow = tempdata;
}
bitsRow = bits;
for (y=0; y<height; y++) {
BYTE *andByte=andRow;
DWORD *bitsPixel=(DWORD*)bitsRow;
for (x=0; x<width; x+=8) {
BYTE andVal=*andByte++;
pixel_set_trans(bitsPixel++, andVal>>7&1);
if (x+1 < width) pixel_set_trans(bitsPixel++, andVal>>6&1);
if (x+2 < width) pixel_set_trans(bitsPixel++, andVal>>5&1);
if (x+3 < width) pixel_set_trans(bitsPixel++, andVal>>4&1);
if (x+4 < width) pixel_set_trans(bitsPixel++, andVal>>3&1);
if (x+5 < width) pixel_set_trans(bitsPixel++, andVal>>2&1);
if (x+6 < width) pixel_set_trans(bitsPixel++, andVal>>1&1);
if (x+7 < width) pixel_set_trans(bitsPixel++, andVal&1);
}
andRow += andStride;
bitsRow += bitsStride;
}
HeapFree(GetProcessHeap(), 0, tempdata);
}
This->bits = bits;
return S_OK;
fail:
HeapFree(GetProcessHeap(), 0, tempdata);
HeapFree(GetProcessHeap(), 0, bits);
if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr);
return hr;
}
static HRESULT WINAPI IcoFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
IcoFrameDecode *This = (IcoFrameDecode*)iface;
HRESULT hr;
UINT width, height, stride;
TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
if (!This->bits)
{
hr = IcoFrameDecode_ReadPixels(This);
if (FAILED(hr)) return hr;
}
width = This->entry.bWidth ? This->entry.bWidth : 256;
height = This->entry.bHeight ? This->entry.bHeight : 256;
stride = width * 4;
return copy_pixels(32, This->bits, width, height, stride,
prc, cbStride, cbBufferSize, pbBuffer);
}
static HRESULT WINAPI IcoFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcoFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcoFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
IWICBitmapSource **ppIThumbnail)
{
TRACE("(%p,%p)\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static const IWICBitmapFrameDecodeVtbl IcoFrameDecode_Vtbl = {
IcoFrameDecode_QueryInterface,
IcoFrameDecode_AddRef,
IcoFrameDecode_Release,
IcoFrameDecode_GetSize,
IcoFrameDecode_GetPixelFormat,
IcoFrameDecode_GetResolution,
IcoFrameDecode_CopyPalette,
IcoFrameDecode_CopyPixels,
IcoFrameDecode_GetMetadataQueryReader,
IcoFrameDecode_GetColorContexts,
IcoFrameDecode_GetThumbnail
};
static HRESULT WINAPI IcoDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
void **ppv)
{
IcoDecoder *This = (IcoDecoder*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface)
{
IcoDecoder *This = (IcoDecoder*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface)
{
IcoDecoder *This = (IcoDecoder*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
if (This->stream) IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI IcoDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
DWORD *pdwCapability)
{
FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
return E_NOTIMPL;
}
static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
IcoDecoder *This = (IcoDecoder*)iface;
LARGE_INTEGER seek;
HRESULT hr;
ULONG bytesread;
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
if (This->initialized) return WINCODEC_ERR_WRONGSTATE;
seek.QuadPart = 0;
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr)) return hr;
hr = IStream_Read(pIStream, &This->header, sizeof(ICONHEADER), &bytesread);
if (FAILED(hr)) return hr;
if (bytesread != sizeof(ICONHEADER) ||
This->header.idReserved != 0 ||
This->header.idType != 1) return E_FAIL;
This->initialized = TRUE;
This->stream = pIStream;
IStream_AddRef(pIStream);
return S_OK;
}
static HRESULT WINAPI IcoDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
GUID *pguidContainerFormat)
{
FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
return E_NOTIMPL;
}
static HRESULT WINAPI IcoDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
IWICBitmapDecoderInfo **ppIDecoderInfo)
{
FIXME("(%p,%p): stub\n", iface, ppIDecoderInfo);
return E_NOTIMPL;
}
static HRESULT WINAPI IcoDecoder_CopyPalette(IWICBitmapDecoder *iface,
IWICPalette *pIPalette)
{
TRACE("(%p,%p)\n", iface, pIPalette);
return WINCODEC_ERR_PALETTEUNAVAILABLE;
}
static HRESULT WINAPI IcoDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
IWICMetadataQueryReader **ppIMetadataQueryReader)
{
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcoDecoder_GetPreview(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIBitmapSource)
{
TRACE("(%p,%p)\n", iface, ppIBitmapSource);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcoDecoder_GetColorContexts(IWICBitmapDecoder *iface,
UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount);
return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}
static HRESULT WINAPI IcoDecoder_GetThumbnail(IWICBitmapDecoder *iface,
IWICBitmapSource **ppIThumbnail)
{
TRACE("(%p,%p)\n", iface, ppIThumbnail);
return WINCODEC_ERR_CODECNOTHUMBNAIL;
}
static HRESULT WINAPI IcoDecoder_GetFrameCount(IWICBitmapDecoder *iface,
UINT *pCount)
{
IcoDecoder *This = (IcoDecoder*)iface;
TRACE("(%p,%p)\n", iface, pCount);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
*pCount = This->header.idCount;
TRACE("<-- %u\n", *pCount);
return S_OK;
}
static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface,
UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
IcoDecoder *This = (IcoDecoder*)iface;
IcoFrameDecode *result;
LARGE_INTEGER seek;
HRESULT hr;
ULONG bytesread;
TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;
if (This->header.idCount < index) return E_INVALIDARG;
result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode));
if (!result) return E_OUTOFMEMORY;
result->lpVtbl = &IcoFrameDecode_Vtbl;
result->ref = 1;
result->parent = This;
result->bits = NULL;
/* read the icon entry */
seek.QuadPart = sizeof(ICONHEADER) + sizeof(ICONDIRENTRY) * index;
hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, 0);
if (FAILED(hr)) goto fail;
hr = IStream_Read(This->stream, &result->entry, sizeof(ICONDIRENTRY), &bytesread);
if (FAILED(hr) || bytesread != sizeof(ICONDIRENTRY)) goto fail;
IWICBitmapDecoder_AddRef(iface);
*ppIBitmapFrame = (IWICBitmapFrameDecode*)result;
return S_OK;
fail:
HeapFree(GetProcessHeap(), 0, result);
if (SUCCEEDED(hr)) hr = E_FAIL;
TRACE("<-- %x\n", hr);
return hr;
}
static const IWICBitmapDecoderVtbl IcoDecoder_Vtbl = {
IcoDecoder_QueryInterface,
IcoDecoder_AddRef,
IcoDecoder_Release,
IcoDecoder_QueryCapability,
IcoDecoder_Initialize,
IcoDecoder_GetContainerFormat,
IcoDecoder_GetDecoderInfo,
IcoDecoder_CopyPalette,
IcoDecoder_GetMetadataQueryReader,
IcoDecoder_GetPreview,
IcoDecoder_GetColorContexts,
IcoDecoder_GetThumbnail,
IcoDecoder_GetFrameCount,
IcoDecoder_GetFrame
};
HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
IcoDecoder *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoDecoder));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &IcoDecoder_Vtbl;
This->ref = 1;
This->stream = NULL;
This->initialized = FALSE;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}

View file

@ -0,0 +1,420 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
const IWICImagingFactoryVtbl *lpIWICImagingFactoryVtbl;
LONG ref;
} ImagingFactory;
static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory *iface, REFIID iid,
void **ppv)
{
ImagingFactory *This = (ImagingFactory*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICImagingFactory, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory *iface)
{
ImagingFactory *This = (ImagingFactory*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory *iface)
{
ImagingFactory *This = (ImagingFactory*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
HeapFree(GetProcessHeap(), 0, This);
return ref;
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
IWICImagingFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
IWICBitmapDecoder **ppIDecoder)
{
FIXME("(%p,%s,%s,%u,%u,%p): stub\n", iface, debugstr_w(wzFilename),
debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
IWICImagingFactory *iface, IStream *pIStream, const GUID *pguidVendor,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
static int fixme=0;
IEnumUnknown *enumdecoders;
IUnknown *unkdecoderinfo;
IWICBitmapDecoderInfo *decoderinfo;
IWICBitmapDecoder *decoder=NULL;
HRESULT res=S_OK;
ULONG num_fetched;
BOOL matches;
TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
metadataOptions, ppIDecoder);
if (pguidVendor && !fixme++)
FIXME("ignoring vendor GUID\n");
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
if (FAILED(res)) return res;
while (!decoder)
{
res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
if (res == S_OK)
{
res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);
if (SUCCEEDED(res))
{
res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);
if (SUCCEEDED(res) && matches)
{
res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
/* FIXME: should use QueryCapability to choose a decoder */
if (SUCCEEDED(res))
{
res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);
if (FAILED(res))
{
IWICBitmapDecoder_Release(decoder);
decoder = NULL;
}
}
}
IWICBitmapDecoderInfo_Release(decoderinfo);
}
IUnknown_Release(unkdecoderinfo);
}
else
break;
}
IEnumUnknown_Release(enumdecoders);
if (decoder)
{
*ppIDecoder = decoder;
return S_OK;
}
else
{
if (WARN_ON(wincodecs))
{
LARGE_INTEGER seek;
BYTE data[4];
ULONG bytesread;
WARN("failed to load from a stream\n");
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]);
}
*ppIDecoder = NULL;
return WINCODEC_ERR_COMPONENTNOTFOUND;
}
}
static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
IWICImagingFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor,
WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
FIXME("(%p,%lx,%s,%u,%p): stub\n", iface, hFile, debugstr_guid(pguidVendor),
metadataOptions, ppIDecoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory *iface,
REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
{
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
return CreateComponentInfo(clsidComponent, ppIInfo);
}
static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory *iface,
REFGUID guidContainerFormat, const GUID *pguidVendor,
IWICBitmapDecoder **ppIDecoder)
{
FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
debugstr_guid(pguidVendor), ppIDecoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory *iface,
REFGUID guidContainerFormat, const GUID *pguidVendor,
IWICBitmapEncoder **ppIEncoder)
{
FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
debugstr_guid(pguidVendor), ppIEncoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory *iface,
IWICPalette **ppIPalette)
{
TRACE("(%p,%p)\n", iface, ppIPalette);
return PaletteImpl_Create(ppIPalette);
}
static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory *iface,
IWICFormatConverter **ppIFormatConverter)
{
FIXME("(%p,%p): stub\n", iface, ppIFormatConverter);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory *iface,
IWICBitmapScaler **ppIBitmapScaler)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapScaler);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory *iface,
IWICBitmapClipper **ppIBitmapClipper)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapClipper);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory *iface,
IWICBitmapFlipRotator **ppIBitmapFlipRotator)
{
FIXME("(%p,%p): stub\n", iface, ppIBitmapFlipRotator);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory *iface,
IWICStream **ppIWICStream)
{
TRACE("(%p,%p)\n", iface, ppIWICStream);
return StreamImpl_Create(ppIWICStream);
}
static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory *iface,
IWICColorContext **ppIColorContext)
{
FIXME("(%p,%p): stub\n", iface, ppIColorContext);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory *iface,
IWICColorTransform **ppIColorTransform)
{
FIXME("(%p,%p): stub\n", iface, ppIColorTransform);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory *iface,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
FIXME("(%p,%u,%u,%s,%u,%p): stub\n", iface, uiWidth, uiHeight,
debugstr_guid(pixelFormat), option, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory *iface,
IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%u,%p): stub\n", iface, piBitmapSource, option, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory *iface,
IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface, piBitmapSource, x, y, width,
height, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory *iface,
UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
{
FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight,
debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory *iface,
HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options,
IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%p,%u,%p): stub\n", iface, hBitmap, hPalette, options, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory *iface,
HICON hIcon, IWICBitmap **ppIBitmap)
{
FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory *iface,
DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
{
TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
}
static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder(
IWICImagingFactory *iface, IWICBitmapDecoder *pIDecoder,
IWICFastMetadataEncoder **ppIFastEncoder)
{
FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(
IWICImagingFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
IWICFastMetadataEncoder **ppIFastEncoder)
{
FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory *iface,
REFGUID guidMetadataFormat, const GUID *pguidVendor,
IWICMetadataQueryWriter **ppIQueryWriter)
{
FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat),
debugstr_guid(pguidVendor), ppIQueryWriter);
return E_NOTIMPL;
}
static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory *iface,
IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
IWICMetadataQueryWriter **ppIQueryWriter)
{
FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor),
ppIQueryWriter);
return E_NOTIMPL;
}
static const IWICImagingFactoryVtbl ImagingFactory_Vtbl = {
ImagingFactory_QueryInterface,
ImagingFactory_AddRef,
ImagingFactory_Release,
ImagingFactory_CreateDecoderFromFilename,
ImagingFactory_CreateDecoderFromStream,
ImagingFactory_CreateDecoderFromFileHandle,
ImagingFactory_CreateComponentInfo,
ImagingFactory_CreateDecoder,
ImagingFactory_CreateEncoder,
ImagingFactory_CreatePalette,
ImagingFactory_CreateFormatConverter,
ImagingFactory_CreateBitmapScaler,
ImagingFactory_CreateBitmapClipper,
ImagingFactory_CreateBitmapFlipRotator,
ImagingFactory_CreateStream,
ImagingFactory_CreateColorContext,
ImagingFactory_CreateColorTransformer,
ImagingFactory_CreateBitmap,
ImagingFactory_CreateBitmapFromSource,
ImagingFactory_CreateBitmapFromSourceRect,
ImagingFactory_CreateBitmapFromMemory,
ImagingFactory_CreateBitmapFromHBITMAP,
ImagingFactory_CreateBitmapFromHICON,
ImagingFactory_CreateComponentEnumerator,
ImagingFactory_CreateFastMetadataEncoderFromDecoder,
ImagingFactory_CreateFastMetadataEncoderFromFrameDecode,
ImagingFactory_CreateQueryWriter,
ImagingFactory_CreateQueryWriterFromReader
};
HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
ImagingFactory *This;
HRESULT ret;
TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
*ppv = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(ImagingFactory));
if (!This) return E_OUTOFMEMORY;
This->lpIWICImagingFactoryVtbl = &ImagingFactory_Vtbl;
This->ref = 1;
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
return ret;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
UINT srcwidth, UINT srcheight, INT srcstride,
const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer)
{
UINT bytesperrow;
UINT row_offset; /* number of bits into the source rows where the data starts */
if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight)
return E_INVALIDARG;
bytesperrow = ((bpp * rc->Width)+7)/8;
if (dststride < bytesperrow)
return E_INVALIDARG;
if ((dststride * rc->Height) > dstbuffersize)
return E_INVALIDARG;
row_offset = rc->X * bpp;
if (row_offset % 8 == 0)
{
/* everything lines up on a byte boundary */
UINT row;
const BYTE *src;
BYTE *dst;
src = srcbuffer + (row_offset / 8) + srcstride * rc->Y;
dst = dstbuffer;
for (row=0; row < rc->Height; row++)
{
memcpy(dst, src, bytesperrow);
src += srcstride;
dst += dststride;
}
return S_OK;
}
else
{
/* we have to do a weird bitwise copy. eww. */
FIXME("cannot reliably copy bitmap data if bpp < 8\n");
return E_FAIL;
}
}

View file

@ -0,0 +1,279 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct {
const IWICPaletteVtbl *lpIWICPaletteVtbl;
LONG ref;
UINT count;
WICColor *colors;
WICBitmapPaletteType type;
} PaletteImpl;
static HRESULT WINAPI PaletteImpl_QueryInterface(IWICPalette *iface, REFIID iid,
void **ppv)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICPalette, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI PaletteImpl_AddRef(IWICPalette *iface)
{
PaletteImpl *This = (PaletteImpl*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface)
{
PaletteImpl *This = (PaletteImpl*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
HeapFree(GetProcessHeap(), 0, This->colors);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface,
WICBitmapPaletteType ePaletteType, BOOL fAddTransparentColor)
{
FIXME("(%p,%u,%i): stub\n", iface, ePaletteType, fAddTransparentColor);
return E_NOTIMPL;
}
static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface,
WICColor *pColors, UINT colorCount)
{
PaletteImpl *This = (PaletteImpl*)iface;
WICColor *new_colors;
TRACE("(%p,%p,%u)\n", iface, pColors, colorCount);
if (colorCount == 0)
{
new_colors = NULL;
}
else
{
if (!pColors) return E_INVALIDARG;
new_colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * colorCount);
if (!new_colors) return E_OUTOFMEMORY;
memcpy(new_colors, pColors, sizeof(WICColor) * colorCount);
}
HeapFree(GetProcessHeap(), 0, This->colors);
This->colors = new_colors;
This->count = colorCount;
This->type = WICBitmapPaletteTypeCustom;
return S_OK;
}
static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *iface,
IWICBitmapSource *pISurface, UINT colorCount, BOOL fAddTransparentColor)
{
FIXME("(%p,%p,%u,%i): stub\n", iface, pISurface, colorCount, fAddTransparentColor);
return E_NOTIMPL;
}
static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface,
IWICPalette *pIPalette)
{
FIXME("(%p,%p): stub\n", iface, pIPalette);
return E_NOTIMPL;
}
static HRESULT WINAPI PaletteImpl_GetType(IWICPalette *iface,
WICBitmapPaletteType *pePaletteType)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%p)\n", iface, pePaletteType);
if (!pePaletteType) return E_INVALIDARG;
*pePaletteType = This->type;
return S_OK;
}
static HRESULT WINAPI PaletteImpl_GetColorCount(IWICPalette *iface, UINT *pcCount)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%p)\n", iface, pcCount);
if (!pcCount) return E_INVALIDARG;
*pcCount = This->count;
return S_OK;
}
static HRESULT WINAPI PaletteImpl_GetColors(IWICPalette *iface, UINT colorCount,
WICColor *pColors, UINT *pcActualColors)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%i,%p,%p)\n", iface, colorCount, pColors, pcActualColors);
if (!pColors || !pcActualColors) return E_INVALIDARG;
if (This->count < colorCount) colorCount = This->count;
memcpy(pColors, This->colors, sizeof(WICColor) * colorCount);
*pcActualColors = colorCount;
return S_OK;
}
static HRESULT WINAPI PaletteImpl_IsBlackWhite(IWICPalette *iface, BOOL *pfIsBlackWhite)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%p)\n", iface, pfIsBlackWhite);
if (!pfIsBlackWhite) return E_INVALIDARG;
if (This->type == WICBitmapPaletteTypeFixedBW)
*pfIsBlackWhite = TRUE;
else
*pfIsBlackWhite = FALSE;
return S_OK;
}
static HRESULT WINAPI PaletteImpl_IsGrayscale(IWICPalette *iface, BOOL *pfIsGrayscale)
{
PaletteImpl *This = (PaletteImpl*)iface;
TRACE("(%p,%p)\n", iface, pfIsGrayscale);
if (!pfIsGrayscale) return E_INVALIDARG;
switch(This->type)
{
case WICBitmapPaletteTypeFixedBW:
case WICBitmapPaletteTypeFixedGray4:
case WICBitmapPaletteTypeFixedGray16:
case WICBitmapPaletteTypeFixedGray256:
*pfIsGrayscale = TRUE;
break;
default:
*pfIsGrayscale = FALSE;
}
return S_OK;
}
static HRESULT WINAPI PaletteImpl_HasAlpha(IWICPalette *iface, BOOL *pfHasAlpha)
{
PaletteImpl *This = (PaletteImpl*)iface;
int i;
TRACE("(%p,%p)\n", iface, pfHasAlpha);
if (!pfHasAlpha) return E_INVALIDARG;
*pfHasAlpha = FALSE;
for (i=0; i<This->count; i++)
if ((This->colors[i]&0xff000000) != 0xff000000)
{
*pfHasAlpha = TRUE;
break;
}
return S_OK;
}
static const IWICPaletteVtbl PaletteImpl_Vtbl = {
PaletteImpl_QueryInterface,
PaletteImpl_AddRef,
PaletteImpl_Release,
PaletteImpl_InitializePredefined,
PaletteImpl_InitializeCustom,
PaletteImpl_InitializeFromBitmap,
PaletteImpl_InitializeFromPalette,
PaletteImpl_GetType,
PaletteImpl_GetColorCount,
PaletteImpl_GetColors,
PaletteImpl_IsBlackWhite,
PaletteImpl_IsGrayscale,
PaletteImpl_HasAlpha
};
HRESULT PaletteImpl_Create(IWICPalette **palette)
{
PaletteImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PaletteImpl));
if (!This) return E_OUTOFMEMORY;
This->lpIWICPaletteVtbl = &PaletteImpl_Vtbl;
This->ref = 1;
This->count = 0;
This->colors = NULL;
This->type = WICBitmapPaletteTypeCustom;
*palette = (IWICPalette*)This;
return S_OK;
}

View file

@ -0,0 +1,147 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
typedef struct PropertyBag {
const IPropertyBag2Vtbl *lpVtbl;
LONG ref;
} PropertyBag;
static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid,
void **ppv)
{
PropertyBag *This = (PropertyBag*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) ||
IsEqualIID(&IID_IPropertyBag2, iid))
{
*ppv = This;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
{
PropertyBag *This = (PropertyBag*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
{
PropertyBag *This = (PropertyBag*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0)
{
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties,
PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
{
FIXME("(%p,%u,%p,%p,%p,%p): stub\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError);
return E_NOTIMPL;
}
static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties,
PROPBAG2 *pPropBag, VARIANT *pvarValue)
{
FIXME("(%p,%u,%p,%p): stub\n", iface, cProperties, pPropBag, pvarValue);
return E_NOTIMPL;
}
static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
{
FIXME("(%p,%p): stub\n", iface, pcProperties);
return E_NOTIMPL;
}
static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty,
ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
{
FIXME("(%p,%u,%u,%p,%p): stub\n", iface, iProperty, cProperties, pPropBag, pcProperties);
return E_NOTIMPL;
}
static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName,
DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
{
FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog);
return E_NOTIMPL;
}
static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
PropertyBag_QueryInterface,
PropertyBag_AddRef,
PropertyBag_Release,
PropertyBag_Read,
PropertyBag_Write,
PropertyBag_CountProperties,
PropertyBag_GetPropertyInfo,
PropertyBag_LoadObject
};
extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2)
{
PropertyBag *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &PropertyBag_Vtbl;
This->ref = 1;
*ppPropertyBag2 = (IPropertyBag2*)This;
return S_OK;
}

View file

@ -0,0 +1,899 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#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 "wincodec.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
/***********************************************************************
* interface for self-registering
*/
struct regsvr_coclass
{
CLSID const *clsid; /* NULL for end of list */
LPCSTR name; /* can be NULL to omit */
LPCSTR ips; /* can be NULL to omit */
LPCSTR ips32; /* can be NULL to omit */
LPCSTR ips32_tmodel; /* can be NULL to omit */
LPCSTR progid; /* can be NULL to omit */
LPCSTR viprogid; /* can be NULL to omit */
LPCSTR progid_extra; /* can be NULL to omit */
};
static HRESULT register_coclasses(struct regsvr_coclass const *list);
static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
struct decoder_pattern
{
DWORD length; /* 0 for end of list */
DWORD position;
const BYTE *pattern;
const BYTE *mask;
DWORD endofstream;
};
struct regsvr_decoder
{
CLSID const *clsid; /* NULL for end of list */
LPCSTR author;
LPCSTR friendlyname;
LPCSTR version;
GUID const *vendor;
LPCSTR mimetypes;
LPCSTR extensions;
GUID const * const *formats;
const struct decoder_pattern *patterns;
};
static HRESULT register_decoders(struct regsvr_decoder const *list);
static HRESULT unregister_decoders(struct regsvr_decoder const *list);
struct regsvr_converter
{
CLSID const *clsid; /* NULL for end of list */
LPCSTR author;
LPCSTR friendlyname;
LPCSTR version;
GUID const *vendor;
GUID const * const *formats;
};
static HRESULT register_converters(struct regsvr_converter const *list);
static HRESULT unregister_converters(struct regsvr_converter const *list);
/***********************************************************************
* static string constants
*/
static WCHAR const clsid_keyname[6] = {
'C', 'L', 'S', 'I', 'D', 0 };
static WCHAR const curver_keyname[7] = {
'C', 'u', 'r', 'V', 'e', 'r', 0 };
static WCHAR const ips_keyname[13] = {
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
0 };
static WCHAR const ips32_keyname[15] = {
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
'3', '2', 0 };
static WCHAR const progid_keyname[7] = {
'P', 'r', 'o', 'g', 'I', 'D', 0 };
static WCHAR const viprogid_keyname[25] = {
'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
0 };
static char const tmodel_valuename[] = "ThreadingModel";
static char const author_valuename[] = "Author";
static char const friendlyname_valuename[] = "FriendlyName";
static WCHAR const vendor_valuename[] = {'V','e','n','d','o','r',0};
static char const version_valuename[] = "Version";
static char const mimetypes_valuename[] = "MimeTypes";
static char const extensions_valuename[] = "FileExtensions";
static WCHAR const formats_keyname[] = {'F','o','r','m','a','t','s',0};
static WCHAR const patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
static WCHAR const instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
static WCHAR const clsid_valuename[] = {'C','L','S','I','D',0};
static char const length_valuename[] = "Length";
static char const position_valuename[] = "Position";
static char const pattern_valuename[] = "Pattern";
static char const mask_valuename[] = "Mask";
static char const endofstream_valuename[] = "EndOfStream";
static WCHAR const pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
/***********************************************************************
* static helper functions
*/
static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
WCHAR const *value);
static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
char const *value);
static LONG register_progid(WCHAR const *clsid,
char const *progid, char const *curver_progid,
char const *name, char const *extra);
/***********************************************************************
* register_coclasses
*/
static HRESULT register_coclasses(struct regsvr_coclass const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
WCHAR buf[39];
HKEY clsid_key;
StringFromGUID2(list->clsid, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->name) {
res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
(CONST BYTE*)(list->name),
strlen(list->name) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->ips) {
res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->ips32) {
HKEY ips32_key;
res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&ips32_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
(CONST BYTE*)list->ips32,
lstrlenA(list->ips32) + 1);
if (res == ERROR_SUCCESS && list->ips32_tmodel)
res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
(CONST BYTE*)list->ips32_tmodel,
strlen(list->ips32_tmodel) + 1);
RegCloseKey(ips32_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->progid) {
res = register_key_defvalueA(clsid_key, progid_keyname,
list->progid);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = register_progid(buf, list->progid, NULL,
list->name, list->progid_extra);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->viprogid) {
res = register_key_defvalueA(clsid_key, viprogid_keyname,
list->viprogid);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = register_progid(buf, list->viprogid, list->progid,
list->name, list->progid_extra);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
error_close_coclass_key:
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* unregister_coclasses
*/
static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
KEY_READ | KEY_WRITE, &coclass_key);
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
WCHAR buf[39];
StringFromGUID2(list->clsid, buf, 39);
res = RegDeleteTreeW(coclass_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->progid) {
res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
if (list->viprogid) {
res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
}
error_close_coclass_key:
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* register_decoders
*/
static HRESULT register_decoders(struct regsvr_decoder const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
WCHAR buf[39];
HKEY decoders_key;
HKEY instance_key;
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
if (res == ERROR_SUCCESS) {
StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
if (res == ERROR_SUCCESS)
{
res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
if (res != ERROR_SUCCESS)
RegCloseKey(coclass_key);
}
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
HKEY clsid_key;
HKEY instance_clsid_key;
StringFromGUID2(list->clsid, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
StringFromGUID2(list->clsid, buf, 39);
res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
if (res == ERROR_SUCCESS) {
res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
(CONST BYTE*)(buf), 78);
RegCloseKey(instance_clsid_key);
}
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
if (list->author) {
res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
(CONST BYTE*)(list->author),
strlen(list->author) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->friendlyname) {
res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
(CONST BYTE*)(list->friendlyname),
strlen(list->friendlyname) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->vendor) {
StringFromGUID2(list->vendor, buf, 39);
res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
(CONST BYTE*)(buf), 78);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->version) {
res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
(CONST BYTE*)(list->version),
strlen(list->version) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->mimetypes) {
res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
(CONST BYTE*)(list->mimetypes),
strlen(list->mimetypes) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->extensions) {
res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
(CONST BYTE*)(list->extensions),
strlen(list->extensions) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->formats) {
HKEY formats_key;
GUID const * const *format;
res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
for (format=list->formats; *format; ++format)
{
HKEY format_key;
StringFromGUID2(*format, buf, 39);
res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
if (res != ERROR_SUCCESS) break;
RegCloseKey(format_key);
}
RegCloseKey(formats_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->patterns) {
HKEY patterns_key;
int i;
res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
for (i=0; list->patterns[i].length; i++)
{
HKEY pattern_key;
static const WCHAR int_format[] = {'%','i',0};
snprintfW(buf, 39, int_format, i);
res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
if (res != ERROR_SUCCESS) break;
res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
(CONST BYTE*)(&list->patterns[i].length), 4);
if (res == ERROR_SUCCESS)
res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
(CONST BYTE*)(&list->patterns[i].position), 4);
if (res == ERROR_SUCCESS)
res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
list->patterns[i].pattern,
list->patterns[i].length);
if (res == ERROR_SUCCESS)
res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
list->patterns[i].mask,
list->patterns[i].length);
if (res == ERROR_SUCCESS)
res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
(CONST BYTE*)&(list->patterns[i].endofstream), 4);
RegCloseKey(pattern_key);
}
RegCloseKey(patterns_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
error_close_coclass_key:
RegCloseKey(instance_key);
RegCloseKey(decoders_key);
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* unregister_decoders
*/
static HRESULT unregister_decoders(struct regsvr_decoder const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
WCHAR buf[39];
HKEY decoders_key;
HKEY instance_key;
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
KEY_READ | KEY_WRITE, &coclass_key);
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
if (res == ERROR_SUCCESS) {
StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
if (res == ERROR_SUCCESS)
{
res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
if (res != ERROR_SUCCESS)
RegCloseKey(coclass_key);
}
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
StringFromGUID2(list->clsid, buf, 39);
res = RegDeleteTreeW(coclass_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
res = RegDeleteTreeW(instance_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
error_close_coclass_key:
RegCloseKey(instance_key);
RegCloseKey(decoders_key);
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* register_converters
*/
static HRESULT register_converters(struct regsvr_converter const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
WCHAR buf[39];
HKEY converters_key;
HKEY instance_key;
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
if (res == ERROR_SUCCESS) {
StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
if (res == ERROR_SUCCESS)
{
res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
if (res != ERROR_SUCCESS)
RegCloseKey(coclass_key);
}
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
HKEY clsid_key;
HKEY instance_clsid_key;
StringFromGUID2(list->clsid, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
StringFromGUID2(list->clsid, buf, 39);
res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
if (res == ERROR_SUCCESS) {
res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
(CONST BYTE*)(buf), 78);
RegCloseKey(instance_clsid_key);
}
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
if (list->author) {
res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
(CONST BYTE*)(list->author),
strlen(list->author) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->friendlyname) {
res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
(CONST BYTE*)(list->friendlyname),
strlen(list->friendlyname) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->vendor) {
StringFromGUID2(list->vendor, buf, 39);
res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
(CONST BYTE*)(buf), 78);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->version) {
res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
(CONST BYTE*)(list->version),
strlen(list->version) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->formats) {
HKEY formats_key;
GUID const * const *format;
res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
for (format=list->formats; *format; ++format)
{
HKEY format_key;
StringFromGUID2(*format, buf, 39);
res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
if (res != ERROR_SUCCESS) break;
RegCloseKey(format_key);
}
RegCloseKey(formats_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
error_close_coclass_key:
RegCloseKey(instance_key);
RegCloseKey(converters_key);
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* unregister_converters
*/
static HRESULT unregister_converters(struct regsvr_converter const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
WCHAR buf[39];
HKEY converters_key;
HKEY instance_key;
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
KEY_READ | KEY_WRITE, &coclass_key);
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
if (res == ERROR_SUCCESS) {
StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
if (res == ERROR_SUCCESS)
{
res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
if (res != ERROR_SUCCESS)
RegCloseKey(coclass_key);
}
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
StringFromGUID2(list->clsid, buf, 39);
res = RegDeleteTreeW(coclass_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
res = RegDeleteTreeW(instance_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
error_close_coclass_key:
RegCloseKey(instance_key);
RegCloseKey(converters_key);
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* register_key_defvalueW
*/
static LONG register_key_defvalueW(
HKEY base,
WCHAR const *name,
WCHAR const *value)
{
LONG res;
HKEY key;
res = RegCreateKeyExW(base, name, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &key, NULL);
if (res != ERROR_SUCCESS) return res;
res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
(lstrlenW(value) + 1) * sizeof(WCHAR));
RegCloseKey(key);
return res;
}
/***********************************************************************
* register_key_defvalueA
*/
static LONG register_key_defvalueA(
HKEY base,
WCHAR const *name,
char const *value)
{
LONG res;
HKEY key;
res = RegCreateKeyExW(base, name, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &key, NULL);
if (res != ERROR_SUCCESS) return res;
res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
lstrlenA(value) + 1);
RegCloseKey(key);
return res;
}
/***********************************************************************
* register_progid
*/
static LONG register_progid(
WCHAR const *clsid,
char const *progid,
char const *curver_progid,
char const *name,
char const *extra)
{
LONG res;
HKEY progid_key;
res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL,
&progid_key, NULL);
if (res != ERROR_SUCCESS) return res;
if (name) {
res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
(CONST BYTE*)name, strlen(name) + 1);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
if (clsid) {
res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
if (curver_progid) {
res = register_key_defvalueA(progid_key, curver_keyname,
curver_progid);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
if (extra) {
HKEY extra_key;
res = RegCreateKeyExA(progid_key, extra, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL,
&extra_key, NULL);
if (res == ERROR_SUCCESS)
RegCloseKey(extra_key);
}
error_close_progid_key:
RegCloseKey(progid_key);
return res;
}
/***********************************************************************
* coclass list
*/
static struct regsvr_coclass const coclass_list[] = {
{ &CLSID_WICImagingFactory,
"WIC Imaging Factory",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ &CLSID_WICBmpDecoder,
"WIC BMP Decoder",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ &CLSID_WICBmpEncoder,
"WIC BMP Encoder",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ &CLSID_WICGifDecoder,
"WIC GIF Decoder",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ &CLSID_WICIcoDecoder,
"WIC ICO Decoder",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ &CLSID_WICDefaultFormatConverter,
"WIC Default Format Converter",
NULL,
"windowscodecs.dll",
"Apartment"
},
{ NULL } /* list terminator */
};
/***********************************************************************
* decoder list
*/
static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff};
static const BYTE bmp_magic[] = {0x42,0x4d};
static GUID const * const bmp_formats[] = {
&GUID_WICPixelFormat1bppIndexed,
&GUID_WICPixelFormat2bppIndexed,
&GUID_WICPixelFormat4bppIndexed,
&GUID_WICPixelFormat8bppIndexed,
&GUID_WICPixelFormat16bppBGR555,
&GUID_WICPixelFormat16bppBGR565,
&GUID_WICPixelFormat24bppBGR,
&GUID_WICPixelFormat32bppBGR,
&GUID_WICPixelFormat32bppBGRA,
NULL
};
static struct decoder_pattern const bmp_patterns[] = {
{2,0,bmp_magic,mask_all,0},
{0}
};
static const BYTE gif87a_magic[6] = "GIF87a";
static const BYTE gif89a_magic[6] = "GIF89a";
static GUID const * const gif_formats[] = {
&GUID_WICPixelFormat8bppIndexed,
NULL
};
static struct decoder_pattern const gif_patterns[] = {
{6,0,gif87a_magic,mask_all,0},
{6,0,gif89a_magic,mask_all,0},
{0}
};
static const BYTE ico_magic[] = {00,00,01,00};
static GUID const * const ico_formats[] = {
&GUID_WICPixelFormat32bppBGRA,
NULL
};
static struct decoder_pattern const ico_patterns[] = {
{4,0,ico_magic,mask_all,0},
{0}
};
static struct regsvr_decoder const decoder_list[] = {
{ &CLSID_WICBmpDecoder,
"The Wine Project",
"BMP Decoder",
"1.0.0.0",
&GUID_VendorMicrosoft,
"image/bmp",
".bmp,.dib,.rle",
bmp_formats,
bmp_patterns
},
{ &CLSID_WICGifDecoder,
"The Wine Project",
"GIF Decoder",
"1.0.0.0",
&GUID_VendorMicrosoft,
"image/gif",
".gif",
gif_formats,
gif_patterns
},
{ &CLSID_WICIcoDecoder,
"The Wine Project",
"ICO Decoder",
"1.0.0.0",
&GUID_VendorMicrosoft,
"image/vnd.microsoft.icon",
".ico",
ico_formats,
ico_patterns
},
{ NULL } /* list terminator */
};
static GUID const * const converter_formats[] = {
&GUID_WICPixelFormat1bppIndexed,
&GUID_WICPixelFormat4bppIndexed,
&GUID_WICPixelFormat8bppIndexed,
&GUID_WICPixelFormat16bppBGR555,
&GUID_WICPixelFormat16bppBGR565,
&GUID_WICPixelFormat24bppBGR,
&GUID_WICPixelFormat32bppBGR,
&GUID_WICPixelFormat32bppBGRA,
NULL
};
static struct regsvr_converter const converter_list[] = {
{ &CLSID_WICDefaultFormatConverter,
"The Wine Project",
"Default Pixel Format Converter",
"1.0.0.0",
&GUID_VendorMicrosoft,
converter_formats
},
{ NULL } /* list terminator */
};
HRESULT WINAPI DllRegisterServer(void)
{
HRESULT hr;
TRACE("\n");
hr = register_coclasses(coclass_list);
if (SUCCEEDED(hr))
register_decoders(decoder_list);
if (SUCCEEDED(hr))
register_converters(converter_list);
return hr;
}
HRESULT WINAPI DllUnregisterServer(void)
{
HRESULT hr;
TRACE("\n");
hr = unregister_coclasses(coclass_list);
if (SUCCEEDED(hr))
unregister_decoders(decoder_list);
if (SUCCEEDED(hr))
unregister_converters(converter_list);
return hr;
}

View file

@ -0,0 +1,512 @@
/*
* Copyright 2009 Tony Wasserka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "wine/debug.h"
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecs_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
/******************************************
* StreamOnMemory implementation
*
* Used by IWICStream_InitializeFromMemory
*
*/
typedef struct StreamOnMemory {
const IStreamVtbl *lpVtbl;
LONG ref;
BYTE *pbMemory;
DWORD dwMemsize;
DWORD dwCurPos;
} StreamOnMemory;
static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
REFIID iid, void **ppv)
{
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IStream, iid) ||
IsEqualIID(&IID_ISequentialStream, iid))
{
*ppv = iface;
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
}
static ULONG WINAPI StreamOnMemory_AddRef(IStream *iface)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0) {
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
void *pv, ULONG cb, ULONG *pcbRead)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
ULONG uBytesRead;
TRACE("(%p)\n", This);
if (!pv) return E_INVALIDARG;
uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
This->dwCurPos += uBytesRead;
if (pcbRead) *pcbRead = uBytesRead;
return S_OK;
}
static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
TRACE("(%p)\n", This);
if (!pv) return E_INVALIDARG;
if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL;
if (cb) {
memcpy(This->pbMemory + This->dwCurPos, pv, cb);
This->dwCurPos += cb;
}
if (pcbWritten) *pcbWritten = cb;
return S_OK;
}
static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
LARGE_INTEGER NewPosition;
TRACE("(%p)\n", This);
if (dlibMove.QuadPart > 0xFFFFFFFF) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart;
else return E_INVALIDARG;
if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG;
if (NewPosition.QuadPart < 0) return E_INVALIDARG;
This->dwCurPos = NewPosition.LowPart;
if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
return S_OK;
}
/* SetSize isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_SetSize(IStream *iface,
ULARGE_INTEGER libNewSize)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* CopyTo isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_CopyTo(IStream *iface,
IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* Commit isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_Commit(IStream *iface,
DWORD grfCommitFlags)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* Revert isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_Revert(IStream *iface)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* LockRegion isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_LockRegion(IStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
/* UnlockRegion isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_UnlockRegion(IStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI StreamOnMemory_Stat(IStream *iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
StreamOnMemory *This = (StreamOnMemory*)iface;
TRACE("(%p)\n", This);
if (!pstatstg) return E_INVALIDARG;
ZeroMemory(pstatstg, sizeof(STATSTG));
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = This->dwMemsize;
return S_OK;
}
/* Clone isn't implemented in the native windowscodecs DLL either */
static HRESULT WINAPI StreamOnMemory_Clone(IStream *iface,
IStream **ppstm)
{
TRACE("(%p)\n", iface);
return E_NOTIMPL;
}
const IStreamVtbl StreamOnMemory_Vtbl =
{
/*** IUnknown methods ***/
StreamOnMemory_QueryInterface,
StreamOnMemory_AddRef,
StreamOnMemory_Release,
/*** ISequentialStream methods ***/
StreamOnMemory_Read,
StreamOnMemory_Write,
/*** IStream methods ***/
StreamOnMemory_Seek,
StreamOnMemory_SetSize,
StreamOnMemory_CopyTo,
StreamOnMemory_Commit,
StreamOnMemory_Revert,
StreamOnMemory_LockRegion,
StreamOnMemory_UnlockRegion,
StreamOnMemory_Stat,
StreamOnMemory_Clone,
};
/******************************************
* IWICStream implementation
*
*/
typedef struct IWICStreamImpl
{
const IWICStreamVtbl *lpVtbl;
LONG ref;
IStream *pStream;
} IWICStreamImpl;
static HRESULT WINAPI IWICStreamImpl_QueryInterface(IWICStream *iface,
REFIID iid, void **ppv)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
if (!ppv) return E_INVALIDARG;
if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IStream, iid) ||
IsEqualIID(&IID_ISequentialStream, iid) || IsEqualIID(&IID_IWICStream, iid))
{
*ppv = This;
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
}
static ULONG WINAPI IWICStreamImpl_AddRef(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
return ref;
}
static ULONG WINAPI IWICStreamImpl_Release(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0) {
if (This->pStream) IStream_Release(This->pStream);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI IWICStreamImpl_Read(IWICStream *iface,
void *pv, ULONG cb, ULONG *pcbRead)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Read(This->pStream, pv, cb, pcbRead);
}
static HRESULT WINAPI IWICStreamImpl_Write(IWICStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Write(This->pStream, pv, cb, pcbWritten);
}
static HRESULT WINAPI IWICStreamImpl_Seek(IWICStream *iface,
LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Seek(This->pStream, dlibMove, dwOrigin, plibNewPosition);
}
static HRESULT WINAPI IWICStreamImpl_SetSize(IWICStream *iface,
ULARGE_INTEGER libNewSize)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_SetSize(This->pStream, libNewSize);
}
static HRESULT WINAPI IWICStreamImpl_CopyTo(IWICStream *iface,
IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_CopyTo(This->pStream, pstm, cb, pcbRead, pcbWritten);
}
static HRESULT WINAPI IWICStreamImpl_Commit(IWICStream *iface,
DWORD grfCommitFlags)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Commit(This->pStream, grfCommitFlags);
}
static HRESULT WINAPI IWICStreamImpl_Revert(IWICStream *iface)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Revert(This->pStream);
}
static HRESULT WINAPI IWICStreamImpl_LockRegion(IWICStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_LockRegion(This->pStream, libOffset, cb, dwLockType);
}
static HRESULT WINAPI IWICStreamImpl_UnlockRegion(IWICStream *iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_UnlockRegion(This->pStream, libOffset, cb, dwLockType);
}
static HRESULT WINAPI IWICStreamImpl_Stat(IWICStream *iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Stat(This->pStream, pstatstg, grfStatFlag);
}
static HRESULT WINAPI IWICStreamImpl_Clone(IWICStream *iface,
IStream **ppstm)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
TRACE("(%p): relay\n", This);
if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
return IStream_Clone(This->pStream, ppstm);
}
static HRESULT WINAPI IWICStreamImpl_InitializeFromIStream(IWICStream *iface,
IStream *pIStream)
{
FIXME("(%p): stub\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface,
LPCWSTR wzFileName, DWORD dwDesiredAccess)
{
FIXME("(%p): stub\n", iface);
return E_NOTIMPL;
}
/******************************************
* IWICStream_InitializeFromMemory
*
* Initializes the internal IStream object to retrieve its data from a memory chunk.
*
* PARAMS
* pbBuffer [I] pointer to the memory chunk
* cbBufferSize [I] number of bytes to use from the memory chunk
*
* RETURNS
* SUCCESS: S_OK
* FAILURE: E_INVALIDARG, if pbBuffer is NULL
* E_OUTOFMEMORY, if we run out of memory
* WINCODEC_ERR_WRONGSTATE, if the IStream object has already been initialized before
*
*/
static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
BYTE *pbBuffer, DWORD cbBufferSize)
{
IWICStreamImpl *This = (IWICStreamImpl*)iface;
StreamOnMemory *pObject;
TRACE("(%p,%p)\n", iface, pbBuffer);
if (!pbBuffer) return E_INVALIDARG;
if (This->pStream) return WINCODEC_ERR_WRONGSTATE;
pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnMemory));
if (!pObject) return E_OUTOFMEMORY;
pObject->lpVtbl = &StreamOnMemory_Vtbl;
pObject->ref = 1;
pObject->pbMemory = pbBuffer;
pObject->dwMemsize = cbBufferSize;
pObject->dwCurPos = 0;
This->pStream = (IStream*)pObject;
return S_OK;
}
static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *iface,
IStream *pIStream, ULARGE_INTEGER ulOffset, ULARGE_INTEGER ulMaxSize)
{
FIXME("(%p): stub\n", iface);
return E_NOTIMPL;
}
const IWICStreamVtbl WICStream_Vtbl =
{
/*** IUnknown methods ***/
IWICStreamImpl_QueryInterface,
IWICStreamImpl_AddRef,
IWICStreamImpl_Release,
/*** ISequentialStream methods ***/
IWICStreamImpl_Read,
IWICStreamImpl_Write,
/*** IStream methods ***/
IWICStreamImpl_Seek,
IWICStreamImpl_SetSize,
IWICStreamImpl_CopyTo,
IWICStreamImpl_Commit,
IWICStreamImpl_Revert,
IWICStreamImpl_LockRegion,
IWICStreamImpl_UnlockRegion,
IWICStreamImpl_Stat,
IWICStreamImpl_Clone,
/*** IWICStream methods ***/
IWICStreamImpl_InitializeFromIStream,
IWICStreamImpl_InitializeFromFilename,
IWICStreamImpl_InitializeFromMemory,
IWICStreamImpl_InitializeFromIStreamRegion,
};
HRESULT StreamImpl_Create(IWICStream **stream)
{
IWICStreamImpl *pObject;
if( !stream ) return E_INVALIDARG;
pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(IWICStreamImpl));
if( !pObject ) {
*stream = NULL;
return E_OUTOFMEMORY;
}
pObject->lpVtbl = &WICStream_Vtbl;
pObject->ref = 1;
pObject->pStream = NULL;
*stream = (IWICStream*)pObject;
return S_OK;
}

View file

@ -0,0 +1,999 @@
/*
* Gif extracting routines - derived from libungif
*
* Portions Copyright 2006 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Original copyright notice:
*
* The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
/******************************************************************************
* "Gif-Lib" - Yet another gif library.
*
* Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
******************************************************************************
* The kernel of the GIF Decoding process can be found here.
******************************************************************************
* History:
* 16 Jun 89 - Version 1.0 by Gershon Elber.
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "ungif.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
static void *ungif_alloc( size_t sz )
{
return HeapAlloc( GetProcessHeap(), 0, sz );
}
static void *ungif_calloc( size_t num, size_t sz )
{
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, num*sz );
}
static void *ungif_realloc( void *ptr, size_t sz )
{
return HeapReAlloc( GetProcessHeap(), 0, ptr, sz );
}
static void ungif_free( void *ptr )
{
HeapFree( GetProcessHeap(), 0, ptr );
}
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
typedef struct GifFilePrivateType {
GifWord BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits, /* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
unsigned long PixelCount; /* Number of pixels in image. */
InputFunc Read; /* function to read gif input (TVT) */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
} GifFilePrivateType;
/* avoid extra function call in case we use fread (TVT) */
#define READ(_gif,_buf,_len) \
((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len)
static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
static int DGifSetupDecompress(GifFileType *GifFile);
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen);
static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode);
static int DGifDecompressInput(GifFileType *GifFile, int *Code);
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
GifByteType *NextByte);
static int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
static int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
/******************************************************************************
* Miscellaneous utility functions
*****************************************************************************/
/* return smallest bitfield size n will fit in */
static int
BitSize(int n) {
register int i;
for (i = 1; i <= 8; i++)
if ((1 << i) >= n)
break;
return (i);
}
/******************************************************************************
* Color map object functions
*****************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
static ColorMapObject *
MakeMapObject(int ColorCount,
const GifColorType * ColorMap) {
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
* make the user know that or should we automatically round up instead? */
if (ColorCount != (1 << BitSize(ColorCount))) {
return NULL;
}
Object = ungif_alloc(sizeof(ColorMapObject));
if (Object == NULL) {
return NULL;
}
Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == NULL) {
return NULL;
}
Object->ColorCount = ColorCount;
Object->BitsPerPixel = BitSize(ColorCount);
if (ColorMap) {
memcpy(Object->Colors, ColorMap, ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*
* Free a color map object
*/
static void
FreeMapObject(ColorMapObject * Object) {
if (Object != NULL) {
ungif_free(Object->Colors);
ungif_free(Object);
/*** FIXME:
* When we are willing to break API we need to make this function
* FreeMapObject(ColorMapObject **Object)
* and do this assignment to NULL here:
* *Object = NULL;
*/
}
}
static int
AddExtensionBlock(SavedImage * New,
int Len,
const unsigned char ExtData[]) {
ExtensionBlock *ep;
if (New->ExtensionBlocks == NULL)
New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock));
else
New->ExtensionBlocks = ungif_realloc(New->ExtensionBlocks,
sizeof(ExtensionBlock) *
(New->ExtensionBlockCount + 1));
if (New->ExtensionBlocks == NULL)
return (GIF_ERROR);
ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
ep->ByteCount=Len;
ep->Bytes = ungif_alloc(ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
if (ExtData) {
memcpy(ep->Bytes, ExtData, Len);
ep->Function = New->Function;
}
return (GIF_OK);
}
static void
FreeExtension(SavedImage * Image)
{
ExtensionBlock *ep;
if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
return;
}
for (ep = Image->ExtensionBlocks;
ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
ungif_free(ep->Bytes);
ungif_free(Image->ExtensionBlocks);
Image->ExtensionBlocks = NULL;
}
/******************************************************************************
* Image block allocation functions
******************************************************************************/
static void
FreeSavedImages(GifFileType * GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
return;
}
for (sp = GifFile->SavedImages;
sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
if (sp->ImageDesc.ColorMap) {
FreeMapObject(sp->ImageDesc.ColorMap);
sp->ImageDesc.ColorMap = NULL;
}
ungif_free(sp->RasterBits);
if (sp->ExtensionBlocks)
FreeExtension(sp);
}
ungif_free(GifFile->SavedImages);
GifFile->SavedImages=NULL;
}
/******************************************************************************
* This routine should be called before any other DGif calls. Note that
* this routine is called automatically from DGif file open routines.
*****************************************************************************/
static int
DGifGetScreenDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType Buf[3];
/* Put the screen descriptor into the file: */
if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
return GIF_ERROR;
if (READ(GifFile, Buf, 3) != 3) {
return GIF_ERROR;
}
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
if (Buf[0] & 0x80) { /* Do we have global color map? */
GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->SColorMap == NULL) {
return GIF_ERROR;
}
/* Get the global color map: */
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->SColorMap);
GifFile->SColorMap = NULL;
return GIF_ERROR;
}
GifFile->SColorMap->Colors[i].Red = Buf[0];
GifFile->SColorMap->Colors[i].Green = Buf[1];
GifFile->SColorMap->Colors[i].Blue = Buf[2];
}
} else {
GifFile->SColorMap = NULL;
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attempt to read an image.
*****************************************************************************/
static int
DGifGetRecordType(GifFileType * GifFile,
GifRecordType * Type) {
GifByteType Buf;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
switch (Buf) {
case ',':
*Type = IMAGE_DESC_RECORD_TYPE;
break;
case '!':
*Type = EXTENSION_RECORD_TYPE;
break;
case ';':
*Type = TERMINATE_RECORD_TYPE;
break;
default:
*Type = UNDEFINED_RECORD_TYPE;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attempt to read an image.
* Note it is assumed the Image desc. header (',') has been read.
*****************************************************************************/
static int
DGifGetImageDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType Buf[3];
GifFilePrivateType *Private = GifFile->Private;
SavedImage *sp;
if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
return GIF_ERROR;
if (READ(GifFile, Buf, 1) != 1) {
return GIF_ERROR;
}
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->Image.Interlace = (Buf[0] & 0x40);
if (Buf[0] & 0x80) { /* Does this image have local color map? */
/*** FIXME: Why do we check both of these in order to do this?
* Why do we have both Image and SavedImages? */
if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->Image.ColorMap == NULL) {
return GIF_ERROR;
}
/* Get the image local color map: */
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
return GIF_ERROR;
}
GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
}
} else if (GifFile->Image.ColorMap) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
}
if (GifFile->SavedImages) {
if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages,
sizeof(SavedImage) *
(GifFile->ImageCount + 1))) == NULL) {
return GIF_ERROR;
}
} else {
if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) {
return GIF_ERROR;
}
}
sp = &GifFile->SavedImages[GifFile->ImageCount];
sp->ImageDesc = GifFile->Image;
if (GifFile->Image.ColorMap != NULL) {
sp->ImageDesc.ColorMap = MakeMapObject(
GifFile->Image.ColorMap->ColorCount,
GifFile->Image.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
return GIF_ERROR;
}
}
sp->RasterBits = NULL;
sp->ExtensionBlockCount = 0;
sp->ExtensionBlocks = NULL;
GifFile->ImageCount++;
Private->PixelCount = (long)GifFile->Image.Width *
(long)GifFile->Image.Height;
DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
return GIF_OK;
}
/******************************************************************************
* Get one full scanned line (Line) of length LineLen from GIF file.
*****************************************************************************/
static int
DGifGetLine(GifFileType * GifFile,
GifPixelType * Line,
int LineLen) {
GifByteType *Dummy;
GifFilePrivateType *Private = GifFile->Private;
if (!LineLen)
LineLen = GifFile->Image.Width;
if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
if (Private->PixelCount == 0) {
/* We probably would not be called any more, so lets clean
* everything before we return: need to flush out all rest of
* image until empty block (size 0) detected. We use GetCodeNext. */
do
if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
while (Dummy != NULL) ;
}
return GIF_OK;
} else
return GIF_ERROR;
}
/******************************************************************************
* Get an extension block (see GIF manual) from gif file. This routine only
* returns the first data block, and DGifGetExtensionNext should be called
* after this one until NULL extension is returned.
* The Extension should NOT be freed by the user (not dynamically allocated).
* Note it is assumed the Extension desc. header ('!') has been read.
*****************************************************************************/
static int
DGifGetExtension(GifFileType * GifFile,
int *ExtCode,
GifByteType ** Extension) {
GifByteType Buf;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
*ExtCode = Buf;
return DGifGetExtensionNext(GifFile, Extension);
}
/******************************************************************************
* Get a following extension block (see GIF manual) from gif file. This
* routine should be called until NULL Extension is returned.
* The Extension should NOT be freed by the user (not dynamically allocated).
*****************************************************************************/
static int
DGifGetExtensionNext(GifFileType * GifFile,
GifByteType ** Extension) {
GifByteType Buf;
GifFilePrivateType *Private = GifFile->Private;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
if (Buf > 0) {
*Extension = Private->Buf; /* Use private unused buffer. */
(*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
return GIF_ERROR;
}
} else
*Extension = NULL;
return GIF_OK;
}
/******************************************************************************
* Get 2 bytes (word) from the given file:
*****************************************************************************/
static int
DGifGetWord(GifFileType * GifFile,
GifWord *Word) {
unsigned char c[2];
if (READ(GifFile, c, 2) != 2) {
return GIF_ERROR;
}
*Word = (((unsigned int)c[1]) << 8) + c[0];
return GIF_OK;
}
/******************************************************************************
* Continue to get the image code in compressed form. This routine should be
* called until NULL block is returned.
* The block should NOT be freed by the user (not dynamically allocated).
*****************************************************************************/
static int
DGifGetCodeNext(GifFileType * GifFile,
GifByteType ** CodeBlock) {
GifByteType Buf;
GifFilePrivateType *Private = GifFile->Private;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
if (Buf > 0) {
*CodeBlock = Private->Buf; /* Use private unused buffer. */
(*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
return GIF_ERROR;
}
} else {
*CodeBlock = NULL;
Private->Buf[0] = 0; /* Make sure the buffer is empty! */
Private->PixelCount = 0; /* And local info. indicate image read. */
}
return GIF_OK;
}
/******************************************************************************
* Setup the LZ decompression for this image:
*****************************************************************************/
static int
DGifSetupDecompress(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType CodeSize;
GifPrefixType *Prefix;
GifFilePrivateType *Private = GifFile->Private;
READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
BitsPerPixel = CodeSize;
Private->Buf[0] = 0; /* Input Buffer empty. */
Private->BitsPerPixel = BitsPerPixel;
Private->ClearCode = (1 << BitsPerPixel);
Private->EOFCode = Private->ClearCode + 1;
Private->RunningCode = Private->EOFCode + 1;
Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
Private->StackPtr = 0; /* No pixels on the pixel stack. */
Private->LastCode = NO_SUCH_CODE;
Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
Private->CrntShiftDWord = 0;
Prefix = Private->Prefix;
for (i = 0; i <= LZ_MAX_CODE; i++)
Prefix[i] = NO_SUCH_CODE;
return GIF_OK;
}
/******************************************************************************
* The LZ decompression routine:
* This version decompress the given gif file into Line of length LineLen.
* This routine can be called few times (one per scan line, for example), in
* order the complete the whole image.
*****************************************************************************/
static int
DGifDecompressLine(GifFileType * GifFile,
GifPixelType * Line,
int LineLen) {
int i = 0;
int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
GifByteType *Stack, *Suffix;
GifPrefixType *Prefix;
GifFilePrivateType *Private = GifFile->Private;
StackPtr = Private->StackPtr;
Prefix = Private->Prefix;
Suffix = Private->Suffix;
Stack = Private->Stack;
EOFCode = Private->EOFCode;
ClearCode = Private->ClearCode;
LastCode = Private->LastCode;
if (StackPtr != 0) {
/* Let pop the stack off before continuing to read the gif file: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
while (i < LineLen) { /* Decode LineLen items. */
if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
return GIF_ERROR;
if (CrntCode == EOFCode) {
/* Note, however, that usually we will not be here as we will stop
* decoding as soon as we got all the pixel, or EOF code will
* not be read at all, and DGifGetLine/Pixel clean everything. */
if (i != LineLen - 1 || Private->PixelCount != 0) {
return GIF_ERROR;
}
i++;
} else if (CrntCode == ClearCode) {
/* We need to start over again: */
for (j = 0; j <= LZ_MAX_CODE; j++)
Prefix[j] = NO_SUCH_CODE;
Private->RunningCode = Private->EOFCode + 1;
Private->RunningBits = Private->BitsPerPixel + 1;
Private->MaxCode1 = 1 << Private->RunningBits;
LastCode = Private->LastCode = NO_SUCH_CODE;
} else {
/* It's a regular code - if in pixel range simply add it to output
* stream, otherwise trace to codes linked list until the prefix
* is in pixel range: */
if (CrntCode < ClearCode) {
/* This is simple - its pixel scalar, so add it to output: */
Line[i++] = CrntCode;
} else {
/* It's a code to be traced: trace the linked list
* until the prefix is a pixel, while pushing the suffix
* pixels on our stack. If we done, pop the stack in reverse
* order (that's what stack is good for!) for output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
if (CrntCode == Private->RunningCode - 2) {
CrntPrefix = LastCode;
Suffix[Private->RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
LastCode,
ClearCode);
} else {
return GIF_ERROR;
}
} else
CrntPrefix = CrntCode;
/* Now (if image is O.K.) we should not get a NO_SUCH_CODE
* during the trace. As we might loop forever, in case of
* defective image, we count the number of loops we trace
* and stop if we got LZ_MAX_CODE. Obviously we cannot
* loop more than that. */
j = 0;
while (j++ <= LZ_MAX_CODE &&
CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
Stack[StackPtr++] = Suffix[CrntPrefix];
CrntPrefix = Prefix[CrntPrefix];
}
if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
return GIF_ERROR;
}
/* Push the last character on stack: */
Stack[StackPtr++] = CrntPrefix;
/* Now lets pop all the stack into output: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
if (LastCode != NO_SUCH_CODE) {
Prefix[Private->RunningCode - 2] = LastCode;
if (CrntCode == Private->RunningCode - 2) {
/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
Suffix[Private->RunningCode - 2] =
DGifGetPrefixChar(Prefix, LastCode, ClearCode);
} else {
Suffix[Private->RunningCode - 2] =
DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
}
}
LastCode = CrntCode;
}
}
Private->LastCode = LastCode;
Private->StackPtr = StackPtr;
return GIF_OK;
}
/******************************************************************************
* Routine to trace the Prefixes linked list until we get a prefix which is
* not code, but a pixel value (less than ClearCode). Returns that pixel value.
* If image is defective, we might loop here forever, so we limit the loops to
* the maximum possible if image O.k. - LZ_MAX_CODE times.
*****************************************************************************/
static int
DGifGetPrefixChar(const GifPrefixType *Prefix,
int Code,
int ClearCode) {
int i = 0;
while (Code > ClearCode && i++ <= LZ_MAX_CODE)
Code = Prefix[Code];
return Code;
}
/******************************************************************************
* The LZ decompression input routine:
* This routine is responsible for the decompression of the bit stream from
* 8 bits (bytes) packets, into the real codes.
* Returns GIF_OK if read successfully.
*****************************************************************************/
static int
DGifDecompressInput(GifFileType * GifFile,
int *Code) {
GifFilePrivateType *Private = GifFile->Private;
GifByteType NextByte;
static const unsigned short CodeMasks[] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000f, 0x001f, 0x003f, 0x007f,
0x00ff, 0x01ff, 0x03ff, 0x07ff,
0x0fff
};
/* The image can't contain more than LZ_BITS per code. */
if (Private->RunningBits > LZ_BITS) {
return GIF_ERROR;
}
while (Private->CrntShiftState < Private->RunningBits) {
/* Needs to get more bytes from input stream for next code: */
if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
return GIF_ERROR;
}
Private->CrntShiftDWord |=
((unsigned long)NextByte) << Private->CrntShiftState;
Private->CrntShiftState += 8;
}
*Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
Private->CrntShiftDWord >>= Private->RunningBits;
Private->CrntShiftState -= Private->RunningBits;
/* If code cannot fit into RunningBits bits, must raise its size. Note
* however that codes above 4095 are used for special signaling.
* If we're using LZ_BITS bits already and we're at the max code, just
* keep using the table as it is, don't increment Private->RunningCode.
*/
if (Private->RunningCode < LZ_MAX_CODE + 2 &&
++Private->RunningCode > Private->MaxCode1 &&
Private->RunningBits < LZ_BITS) {
Private->MaxCode1 <<= 1;
Private->RunningBits++;
}
return GIF_OK;
}
/******************************************************************************
* This routines read one gif data block at a time and buffers it internally
* so that the decompression routine could access it.
* The routine returns the next byte from its internal buffer (or read next
* block in if buffer empty) and returns GIF_OK if successful.
*****************************************************************************/
static int
DGifBufferedInput(GifFileType * GifFile,
GifByteType * Buf,
GifByteType * NextByte) {
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
if (READ(GifFile, Buf, 1) != 1) {
return GIF_ERROR;
}
/* There shouldn't be any empty data blocks here as the LZW spec
* says the LZW termination code should come first. Therefore we
* shouldn't be inside this routine at that point.
*/
if (Buf[0] == 0) {
return GIF_ERROR;
}
if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
return GIF_ERROR;
}
*NextByte = Buf[1];
Buf[1] = 2; /* We use now the second place as last char read! */
Buf[0]--;
} else {
*NextByte = Buf[Buf[1]++];
Buf[0]--;
}
return GIF_OK;
}
/******************************************************************************
* This routine reads an entire GIF into core, hanging all its state info off
* the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
* first to initialize I/O. Its inverse is EGifSpew().
******************************************************************************/
int
DGifSlurp(GifFileType * GifFile) {
int ImageSize;
GifRecordType RecordType;
SavedImage *sp;
GifByteType *ExtData;
SavedImage temp_save;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
do {
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
return (GIF_ERROR);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
return (GIF_ERROR);
sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
return GIF_ERROR;
}
if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
GIF_ERROR)
return (GIF_ERROR);
if (temp_save.ExtensionBlocks) {
sp->ExtensionBlocks = temp_save.ExtensionBlocks;
sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
/* FIXME: The following is wrong. It is left in only for
* backwards compatibility. Someday it should go away. Use
* the sp->ExtensionBlocks->Function variable instead. */
sp->Function = sp->ExtensionBlocks[0].Function;
}
break;
case EXTENSION_RECORD_TYPE:
if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
GIF_ERROR)
return (GIF_ERROR);
while (ExtData != NULL) {
/* Create an extension block with our data */
if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
temp_save.Function = 0;
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType */
break;
}
} while (RecordType != TERMINATE_RECORD_TYPE);
/* Just in case the Gif has an extension block without an associated
* image... (Should we save this into a savefile structure with no image
* instead? Have to check if the present writing code can handle that as
* well.... */
if (temp_save.ExtensionBlocks)
FreeExtension(&temp_save);
return (GIF_OK);
}
/******************************************************************************
* GifFileType constructor with user supplied input function (TVT)
*****************************************************************************/
GifFileType *
DGifOpen(void *userData,
InputFunc readFunc) {
unsigned char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
GifFile = ungif_alloc(sizeof(GifFileType));
if (GifFile == NULL) {
return NULL;
}
memset(GifFile, '\0', sizeof(GifFileType));
Private = ungif_alloc(sizeof(GifFilePrivateType));
if (!Private) {
ungif_free(GifFile);
return NULL;
}
GifFile->Private = (void*)Private;
Private->Read = readFunc; /* TVT */
GifFile->UserData = userData; /* TVT */
/* Lets see if this is a GIF file: */
if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
/* The GIF Version number is ignored at this time. Maybe we should do
* something more useful with it. */
Buf[GIF_STAMP_LEN] = 0;
if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
return GifFile;
}
/******************************************************************************
* This routine should be called last, to close the GIF file.
*****************************************************************************/
int
DGifCloseFile(GifFileType * GifFile) {
GifFilePrivateType *Private;
if (GifFile == NULL)
return GIF_ERROR;
Private = GifFile->Private;
if (GifFile->Image.ColorMap) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
}
if (GifFile->SColorMap) {
FreeMapObject(GifFile->SColorMap);
GifFile->SColorMap = NULL;
}
ungif_free(Private);
Private = NULL;
if (GifFile->SavedImages) {
FreeSavedImages(GifFile);
GifFile->SavedImages = NULL;
}
ungif_free(GifFile);
return GIF_OK;
}

View file

@ -0,0 +1,169 @@
/*
* Gif extracting routines - derived from libungif
*
* Portions Copyright 2006 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Original copyright notice:
*
* The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
/******************************************************************************
* In order to make life a little bit easier when using the GIF file format,
* this library was written, and which does all the dirty work...
*
* Written by Gershon Elber, Jun. 1989
* Hacks by Eric S. Raymond, Sep. 1992
******************************************************************************
* History:
* 14 Jun 89 - Version 1.0 by Gershon Elber.
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names)
* 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to support GIF slurp)
* 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)
* 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code)
*****************************************************************************/
#ifndef _UNGIF_H_
#define _UNGIF_H_ 1
#define GIF_ERROR 0
#define GIF_OK 1
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef NULL
#define NULL 0
#endif /* NULL */
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
typedef unsigned int GifPrefixType;
typedef int GifWord;
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
GifColorType *Colors;
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height, /* Current image dimensions. */
Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct GifFileType {
GifWord SWidth, SHeight, /* Screen dimensions. */
SColorResolution, /* How many colors can we generate? */
SBackGroundColor; /* I hope you understand this one... */
ColorMapObject *SColorMap; /* NULL if not exists. */
int ImageCount; /* Number of current image */
GifImageDesc Image; /* Block describing current image */
struct SavedImage *SavedImages; /* Use this to accumulate file state */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
/* GIF89 extension function codes */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
/* public interface to ungif.c */
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc);
int DGifCloseFile(GifFileType * GifFile);
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/******************************************************************************
* Support for the in-core structures allocation (slurp mode).
*****************************************************************************/
/* This is the in-core version of an extension record */
typedef struct {
int ByteCount;
char *Bytes;
int Function; /* Holds the type of the Extension block. */
} ExtensionBlock;
/* This holds an image header, its unpacked raster bits, and extensions */
typedef struct SavedImage {
GifImageDesc ImageDesc;
unsigned char *RasterBits;
int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
int ExtensionBlockCount;
ExtensionBlock *ExtensionBlocks;
} SavedImage;
#endif /* _UNGIF_H_ */

View file

@ -0,0 +1,26 @@
/*
* Copyright 2008 Louis Lenders
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WINE_FILEDESCRIPTION_STR "Wine Windows Codecs Library"
#define WINE_FILENAME_STR "windowscodecs.dll"
#define WINE_FILEVERSION 6,0,6001,170099
#define WINE_FILEVERSION_STR "6.0.6001.17009"
#define WINE_PRODUCTVERSION 6,0,6001,170099
#define WINE_PRODUCTVERSION_STR "6.0.6001.17009"
#include "wine/wine_common_ver.rc"

View file

@ -0,0 +1,41 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef WINCODECS_PRIVATE_H
#define WINCODECS_PRIVATE_H
extern HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT IcoDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv);
extern HRESULT PaletteImpl_Create(IWICPalette **palette);
extern HRESULT StreamImpl_Create(IWICStream **stream);
extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer,
UINT srcwidth, UINT srcheight, INT srcstride,
const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer);
extern HRESULT CreatePropertyBag2(IPropertyBag2 **ppPropertyBag2);
extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo);
extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown);
#endif /* WINCODECS_PRIVATE_H */

View file

@ -0,0 +1,32 @@
<module name="windowscodecs" type="win32dll" baseaddress="${BASEADDRESS_WINDOWSCODECS}" installbase="system32" installname="windowscodecs.dll" allowwarnings="true">
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
<importlibrary definition="windowscodecs.spec" />
<include base="windowscodecs">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="__WINESRC__" />
<redefine name="_WIN32_WINNT">0x600</redefine>
<library>wine</library>
<library>uuid</library>
<library>ole32</library>
<library>advapi32</library>
<library>kernel32</library>
<file>bmpdecode.c</file>
<file>bmpencode.c</file>
<file>clsfactory.c</file>
<file>converter.c</file>
<file>gifformat.c</file>
<file>icoformat.c</file>
<file>imgfactory.c</file>
<file>info.c</file>
<file>main.c</file>
<file>palette.c</file>
<file>propertybag.c</file>
<file>regsvr.c</file>
<file>stream.c</file>
<file>ungif.c</file>
<file>version.rc</file>
</module>

View file

@ -0,0 +1,116 @@
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()
@ stub IEnumString_Next_WIC_Proxy
@ stub IEnumString_Reset_WIC_Proxy
@ stub IPropertyBag2_Write_Proxy
@ stub IWICBitmapClipper_Initialize_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportAnimation_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportLossless_Proxy
@ stub IWICBitmapCodecInfo_DoesSupportMultiframe_Proxy
@ stub IWICBitmapCodecInfo_GetContainerFormat_Proxy
@ stub IWICBitmapCodecInfo_GetDeviceManufacturer_Proxy
@ stub IWICBitmapCodecInfo_GetDeviceModels_Proxy
@ stub IWICBitmapCodecInfo_GetFileExtensions_Proxy
@ stub IWICBitmapCodecInfo_GetMimeTypes_Proxy
@ stub IWICBitmapDecoder_CopyPalette_Proxy
@ stub IWICBitmapDecoder_GetColorContexts_Proxy
@ stub IWICBitmapDecoder_GetDecoderInfo_Proxy
@ stub IWICBitmapDecoder_GetFrameCount_Proxy
@ stub IWICBitmapDecoder_GetFrame_Proxy
@ stub IWICBitmapDecoder_GetMetadataQueryReader_Proxy
@ stub IWICBitmapDecoder_GetPreview_Proxy
@ stub IWICBitmapDecoder_GetThumbnail_Proxy
@ stub IWICBitmapEncoder_Commit_Proxy
@ stub IWICBitmapEncoder_CreateNewFrame_Proxy
@ stub IWICBitmapEncoder_GetEncoderInfo_Proxy
@ stub IWICBitmapEncoder_GetMetadataQueryWriter_Proxy
@ stub IWICBitmapEncoder_Initialize_Proxy
@ stub IWICBitmapEncoder_SetPalette_Proxy
@ stub IWICBitmapEncoder_SetThumbnail_Proxy
@ stub IWICBitmapFlipRotator_Initialize_Proxy
@ stub IWICBitmapFrameDecode_GetColorContexts_Proxy
@ stub IWICBitmapFrameDecode_GetMetadataQueryReader_Proxy
@ stub IWICBitmapFrameDecode_GetThumbnail_Proxy
@ stub IWICBitmapFrameEncode_Commit_Proxy
@ stub IWICBitmapFrameEncode_GetMetadataQueryWriter_Proxy
@ stub IWICBitmapFrameEncode_Initialize_Proxy
@ stub IWICBitmapFrameEncode_SetColorContexts_Proxy
@ stub IWICBitmapFrameEncode_SetResolution_Proxy
@ stub IWICBitmapFrameEncode_SetSize_Proxy
@ stub IWICBitmapFrameEncode_SetThumbnail_Proxy
@ stub IWICBitmapFrameEncode_WriteSource_Proxy
@ stub IWICBitmapLock_GetDataPointer_STA_Proxy
@ stub IWICBitmapLock_GetStride_Proxy
@ stub IWICBitmapScaler_Initialize_Proxy
@ stub IWICBitmapSource_CopyPalette_Proxy
@ stub IWICBitmapSource_CopyPixels_Proxy
@ stub IWICBitmapSource_GetPixelFormat_Proxy
@ stub IWICBitmapSource_GetResolution_Proxy
@ stub IWICBitmapSource_GetSize_Proxy
@ stub IWICBitmap_Lock_Proxy
@ stub IWICBitmap_SetPalette_Proxy
@ stub IWICBitmap_SetResolution_Proxy
@ stub IWICColorContext_InitializeFromMemory_Proxy
@ stub IWICComponentFactory_CreateMetadataWriterFromReader_Proxy
@ stub IWICComponentFactory_CreateQueryWriterFromBlockWriter_Proxy
@ stub IWICComponentInfo_GetAuthor_Proxy
@ stub IWICComponentInfo_GetCLSID_Proxy
@ stub IWICComponentInfo_GetFriendlyName_Proxy
@ stub IWICComponentInfo_GetSpecVersion_Proxy
@ stub IWICComponentInfo_GetVersion_Proxy
@ stub IWICFastMetadataEncoder_Commit_Proxy
@ stub IWICFastMetadataEncoder_GetMetadataQueryWriter_Proxy
@ stub IWICFormatConverter_Initialize_Proxy
@ stub IWICImagingFactory_CreateBitmapClipper_Proxy
@ stub IWICImagingFactory_CreateBitmapFlipRotator_Proxy
@ stub IWICImagingFactory_CreateBitmapFromHBITMAP_Proxy
@ stub IWICImagingFactory_CreateBitmapFromHICON_Proxy
@ stub IWICImagingFactory_CreateBitmapFromMemory_Proxy
@ stub IWICImagingFactory_CreateBitmapFromSource_Proxy
@ stub IWICImagingFactory_CreateBitmapScaler_Proxy
@ stub IWICImagingFactory_CreateBitmap_Proxy
@ stub IWICImagingFactory_CreateComponentInfo_Proxy
@ stub IWICImagingFactory_CreateDecoderFromFileHandle_Proxy
@ stub IWICImagingFactory_CreateDecoderFromFilename_Proxy
@ stub IWICImagingFactory_CreateDecoderFromStream_Proxy
@ stub IWICImagingFactory_CreateEncoder_Proxy
@ stub IWICImagingFactory_CreateFastMetadataEncoderFromDecoder_Proxy
@ stub IWICImagingFactory_CreateFastMetadataEncoderFromFrameDecode_Proxy
@ stub IWICImagingFactory_CreateFormatConverter_Proxy
@ stub IWICImagingFactory_CreatePalette_Proxy
@ stub IWICImagingFactory_CreateQueryWriterFromReader_Proxy
@ stub IWICImagingFactory_CreateQueryWriter_Proxy
@ stub IWICImagingFactory_CreateStream_Proxy
@ stub IWICMetadataBlockReader_GetCount_Proxy
@ stub IWICMetadataBlockReader_GetReaderByIndex_Proxy
@ stub IWICMetadataQueryReader_GetContainerFormat_Proxy
@ stub IWICMetadataQueryReader_GetEnumerator_Proxy
@ stub IWICMetadataQueryReader_GetLocation_Proxy
@ stub IWICMetadataQueryReader_GetMetadataByName_Proxy
@ stub IWICMetadataQueryWriter_RemoveMetadataByName_Proxy
@ stub IWICMetadataQueryWriter_SetMetadataByName_Proxy
@ stub IWICPalette_GetColorCount_Proxy
@ stub IWICPalette_GetColors_Proxy
@ stub IWICPalette_GetType_Proxy
@ stub IWICPalette_HasAlpha_Proxy
@ stub IWICPalette_InitializeCustom_Proxy
@ stub IWICPalette_InitializeFromBitmap_Proxy
@ stub IWICPalette_InitializeFromPalette_Proxy
@ stub IWICPalette_InitializePredefined_Proxy
@ stub IWICPixelFormatInfo_GetBitsPerPixel_Proxy
@ stub IWICPixelFormatInfo_GetChannelCount_Proxy
@ stub IWICPixelFormatInfo_GetChannelMask_Proxy
@ stub IWICStream_InitializeFromIStream_Proxy
@ stub IWICStream_InitializeFromMemory_Proxy
@ stdcall WICConvertBitmapSource(ptr ptr ptr)
@ stub WICCreateBitmapFromSection
@ stub WICCreateColorContext_Proxy
@ stub WICCreateImagingFactory_Proxy
@ stub WICGetMetadataContentSize
@ stub WICMapGuidToShortName
@ stub WICMapSchemaToName
@ stub WICMapShortNameToGuid
@ stub WICMatchMetadataContent
@ stub WICSerializeMetadataContent
@ stub WICSetEncoderFormat_Proxy

View file

@ -52,6 +52,7 @@
<file>unknwn.idl</file>
<file>urlhist.idl</file>
<file>urlmon.idl</file>
<file>wincodec.idl</file>
<file>mimeole.idl</file>
<file>mscoree.idl</file>
<file>mshtmhst.idl</file>

View file

@ -0,0 +1,738 @@
/*
* Copyright 2009 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "wtypes.idl";
import "propidl.idl";
import "objidl.idl";
import "ocidl.idl";
#define CODEC_FORCE_DWORD 0x7fffffff
typedef enum WICDecodeOptions {
WICDecodeMetadataCacheOnDemand = 0x00000000,
WICDecodeMetadataCacheOnLoad = 0x00000001,
WICMETADATACACHEOPTION_FORCE_DWORD = CODEC_FORCE_DWORD
} WICDecodeOptions;
typedef enum WICBitmapCreateCacheOption {
WICBitmapNoCache = 0x00000000,
WICBitmapCacheOnDemand = 0x00000001,
WICBitmapCacheOnLoad = 0x00000002,
WICBITMAPCREATECACHEOPTION_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapCreateCacheOption;
typedef enum WICBitmapAlphaChannelOption {
WICBitmapUseAlpha = 0x00000000,
WICBitmapUsePremultipliedAlpha = 0x00000001,
WICBitmapIgnoreAlpha = 0x00000002,
WICBITMAPALPHACHANNELOPTIONS_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapAlphaChannelOption;
typedef enum WICBitmapDecoderCapabilities {
WICBitmapDecoderCapabilitySameEncoder = 0x00000001,
WICBitmapDecoderCapabilityCanDecodeAllImages = 0x00000002,
WICBitmapDecoderCapabilityCanDecodeSomeImages = 0x00000004,
WICBitmapDecoderCapabilityCanEnumerateMetadata = 0x00000008,
WICBitmapDecoderCapabilityCanDecodeThumbnail = 0x00000010,
} WICBitmapDecoderCapabilities;
typedef enum WICBitmapDitherType {
WICBitmapDitherTypeNone = 0x00000000,
WICBitmapDitherTypeSolid = 0x00000000,
WICBitmapDitherTypeOrdered4x4 = 0x00000001,
WICBitmapDitherTypeOrdered8x8 = 0x00000002,
WICBitmapDitherTypeOrdered16x16 = 0x00000003,
WICBitmapDitherTypeSpiral4x4 = 0x00000004,
WICBitmapDitherTypeSpiral8x8 = 0x00000005,
WICBitmapDitherTypeDualSpiral4x4 = 0x00000006,
WICBitmapDitherTypeDualSpiral8x8 = 0x00000007,
WICBitmapDitherTypeErrorDiffusion = 0x00000008,
WICBITMAPDITHERTYPE_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapDitherType;
typedef enum WICBitmapEncoderCacheOption {
WICBitmapEncoderCacheInMemory = 0x00000000,
WICBitmapEncoderCacheTempFile = 0x00000001,
WICBitmapEncoderNoCache = 0x00000002,
WICBITMAPENCODERCACHEOPTION_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapEncoderCacheOption;
typedef enum WICBitmapPaletteType {
WICBitmapPaletteTypeCustom = 0x00000000,
WICBitmapPaletteTypeMedianCut = 0x00000001,
WICBitmapPaletteTypeFixedBW = 0x00000002,
WICBitmapPaletteTypeFixedHalftone8 = 0x00000003,
WICBitmapPaletteTypeFixedHalftone27 = 0x00000004,
WICBitmapPaletteTypeFixedHalftone64 = 0x00000005,
WICBitmapPaletteTypeFixedHalftone125 = 0x00000006,
WICBitmapPaletteTypeFixedHalftone216 = 0x00000007,
WICBitmapPaletteTypeFixedWebPalette = WICBitmapPaletteTypeFixedHalftone216,
WICBitmapPaletteTypeFixedHalftone252 = 0x00000008,
WICBitmapPaletteTypeFixedHalftone256 = 0x00000009,
WICBitmapPaletteTypeFixedGray4 = 0x0000000A,
WICBitmapPaletteTypeFixedGray16 = 0x0000000B,
WICBitmapPaletteTypeFixedGray256 = 0x0000000C,
WICBITMAPPALETTETYPE_FORCE_DWORD = CODEC_FORCE_DWORD
} WICBitmapPaletteType;
typedef enum WICComponentType {
WICDecoder = 0x00000001,
WICEncoder = 0x00000002,
WICPixelFormatConverter = 0x00000004,
WICMetadataReader = 0x00000008,
WICMetadataWriter = 0x00000010,
WICPixelFormat = 0x00000020,
WICCOMPONENTTYPE_FORCE_DWORD = CODEC_FORCE_DWORD
} WICComponentType;
typedef enum WICComponentSigning {
WICComponentSigned = 0x00000001,
WICComponentUnsigned = 0x00000002,
WICComponentSafe = 0x00000004,
WICComponentDisabled = 0x80000000
} WICComponentSigning;
typedef enum WICComponentEnumerateOptions {
WICComponentEnumerateDefault = 0x00000000,
WICComponentEnumerateRefresh = 0x00000001,
WICComponentEnumerateBuiltInOnly = 0x20000000,
WICComponentEnumerateUnsigned = 0x40000000,
WICComponentEnumerateDisabled = 0x80000000
} WICComponentEnumerateOptions;
typedef GUID WICPixelFormatGUID;
typedef REFGUID REFWICPixelFormatGUID;
cpp_quote("DEFINE_GUID(GUID_WICPixelFormatDontCare, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x00);")
cpp_quote("#define GUID_WICPixelFormatUndefined GUID_WICPixelFormatDontCare")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat1bppIndexed, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x01);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat2bppIndexed, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x02);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat4bppIndexed, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x03);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppIndexed, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x04);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppBGR555, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x09);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppBGR565, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0a);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat24bppBGR, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0c);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGR, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0e);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGRA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x0f);")
cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppPBGRA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x10);")
typedef struct WICRect {
INT X;
INT Y;
INT Width;
INT Height;
} WICRect;
typedef struct WICBitmapPattern {
ULARGE_INTEGER Position;
ULONG Length;
BYTE *Pattern;
BYTE *Mask;
BOOL EndOfStream;
} WICBitmapPattern;
typedef UINT32 WICColor;
cpp_quote("#define WINCODEC_ERR_WRONGSTATE 0x88982f04")
cpp_quote("#define WINCODEC_ERR_NOTINITIALIZED 0x88982f0c")
cpp_quote("#define WINCODEC_ERR_CODECNOTHUMBNAIL 0x88982f44")
cpp_quote("#define WINCODEC_ERR_PALETTEUNAVAILABLE 0x88982f45")
cpp_quote("#define WINCODEC_ERR_COMPONENTNOTFOUND 0x88982f50")
cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT 0x88982f80")
cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDOPERATION 0x88982f81")
cpp_quote("#define WINCODEC_ERR_INSUFFICIENTBUFFER 0x88982f8c")
interface IWICBitmap;
interface IWICPalette;
interface IWICBitmapScaler;
interface IWICBitmapClipper;
interface IWICBitmapFlipRotator;
interface IWICColorContext;
interface IWICColorTransform;
interface IWICFastMetadataEncoder;
interface IWICMetadataQueryReader;
interface IWICMetadataQueryWriter;
[
object,
uuid(00000120-a8f2-4877-ba0a-fd2b6645fb94)
]
interface IWICBitmapSource : IUnknown
{
HRESULT GetSize(
[out] UINT *puiWidth,
[out] UINT *puiHeight);
HRESULT GetPixelFormat(
[out] WICPixelFormatGUID *pPixelFormat);
HRESULT GetResolution(
[out] double *pDpiX,
[out] double *pDpiY);
HRESULT CopyPalette(
[in] IWICPalette *pIPalette);
HRESULT CopyPixels(
[in] const WICRect *prc,
[in] UINT cbStride,
[in] UINT cbBufferSize,
[out, size_is(cbBufferSize)] BYTE *pbBuffer);
}
[
object,
uuid(00000040-a8f2-4877-ba0a-fd2b6645fb94)
]
interface IWICPalette : IUnknown
{
HRESULT InitializePredefined(
[in] WICBitmapPaletteType ePaletteType,
[in] BOOL fAddTransparentColor);
HRESULT InitializeCustom(
[in, size_is(colorCount)] WICColor *pColors,
[in] UINT colorCount);
HRESULT InitializeFromBitmap(
[in] IWICBitmapSource *pISurface,
[in] UINT colorCount,
[in] BOOL fAddTransparentColor);
HRESULT InitializeFromPalette(
[in] IWICPalette *pIPalette);
HRESULT GetType(
[out] WICBitmapPaletteType *pePaletteType);
HRESULT GetColorCount(
[out] UINT *pcCount);
HRESULT GetColors(
[in] UINT colorCount,
[out, size_is(colorCount)] WICColor *pColors,
[out] UINT *pcActualColors);
HRESULT IsBlackWhite(
[out] BOOL *pfIsBlackWhite);
HRESULT IsGrayscale(
[out] BOOL *pfIsGrayscale);
HRESULT HasAlpha(
[out] BOOL *pfHasAlpha);
}
[
object,
uuid(23bc3f0a-698b-4357-886b-f24d50671334)
]
interface IWICComponentInfo : IUnknown
{
HRESULT GetComponentType(
[out] WICComponentType *pType);
HRESULT GetCLSID(
[out] CLSID *pclsid);
HRESULT GetSigningStatus(
[out] DWORD *pStatus);
HRESULT GetAuthor(
[in] UINT cchAuthor,
[in, out, unique, size_is(cchAuthor)] WCHAR *wzAuthor,
[out] UINT *pcchActual);
HRESULT GetVendorGUID(
[out] GUID *pguidVendor);
HRESULT GetVersion(
[in] UINT cchVersion,
[in, out, unique, size_is(cchVersion)] WCHAR *wzVersion,
[out] UINT *pcchActual);
HRESULT GetSpecVersion(
[in] UINT cchSpecVersion,
[in, out, unique, size_is(cchSpecVersion)] WCHAR *wzSpecVersion,
[out] UINT *pcchActual);
HRESULT GetFriendlyName(
[in] UINT cchFriendlyName,
[in, out, unique, size_is(cchFriendlyName)] WCHAR *wzFriendlyName,
[out] UINT *pcchActual);
}
[
object,
uuid(3b16811b-6a43-4ec9-a813-3d930c13b940)
]
interface IWICBitmapFrameDecode : IWICBitmapSource
{
HRESULT GetMetadataQueryReader(
[out] IWICMetadataQueryReader **ppIMetadataQueryReader);
HRESULT GetColorContexts(
[in] UINT cCount,
[in, out, unique, size_is(cCount)] IWICColorContext **ppIColorContexts,
[out] UINT *pcActualCount);
HRESULT GetThumbnail(
[out] IWICBitmapSource **ppIThumbnail);
}
[
object,
uuid(e87a44c4-b76e-4c47-8b09-298eb12a2714)
]
interface IWICBitmapCodecInfo : IWICComponentInfo
{
HRESULT GetContainerFormat(
[out] GUID *pguidContainerFormat);
HRESULT GetPixelFormats(
[in] UINT cFormats,
[in, out, unique, size_is(cFormats)] GUID *pguidPixelFormats,
[out] UINT *pcActual);
HRESULT GetColorManagementVersion(
[in] UINT cchColorManagementVersion,
[in, out, unique, size_is(cchColorManagementVersion)] WCHAR *wzColorManagementVersion,
[out] UINT *pcchActual);
HRESULT GetDeviceManufacturer(
[in] UINT cchDeviceManufacturer,
[in, out, unique, size_is(cchDeviceManufacturer)] WCHAR *wzDeviceManufacturer,
[out] UINT *pcchActual);
HRESULT GetDeviceModels(
[in] UINT cchDeviceModels,
[in, out, unique, size_is(cchDeviceModels)] WCHAR *wzDeviceModels,
[out] UINT *pcchActual);
HRESULT GetMimeTypes(
[in] UINT cchMimeTypes,
[in, out, unique, size_is(cchMimeTypes)] WCHAR *wzMimeTypes,
[out] UINT *pcchActual);
HRESULT GetFileExtensions(
[in] UINT cchFileExtensions,
[in, out, unique, size_is(cchFileExtensions)] WCHAR *wzFileExtensions,
[out] UINT *pcchActual);
HRESULT DoesSupportAnimation(
[out] BOOL *pfSupportAnimation);
HRESULT DoesSupportChromaKey(
[out] BOOL *pfSupportChromaKey);
HRESULT DoesSupportLossless(
[out] BOOL *pfSupportLossless);
HRESULT DoesSupportMultiframe(
[out] BOOL *pfSupportMultiframe);
HRESULT MatchesMimeType(
[in] LPCWSTR wzMimeType,
[out] BOOL *pfMatches);
}
interface IWICBitmapDecoder;
[
object,
uuid(d8cd007f-d08f-4191-9bfc-236ea7f0e4b5)
]
interface IWICBitmapDecoderInfo : IWICBitmapCodecInfo
{
[local]
HRESULT GetPatterns(
[in] UINT cbSizePatterns,
[in, out, unique] WICBitmapPattern *pPatterns,
[in, out, unique] UINT *pcPatterns,
[in, out, unique] UINT *pcbPatternsActual);
HRESULT MatchesPattern(
[in] IStream *pIStream,
[out] BOOL *pfMatches);
HRESULT CreateInstance(
[out] IWICBitmapDecoder **ppIBitmapDecoder);
}
[
object,
uuid(9edde9e7-8dee-47ea-99df-e6faf2ed44bf)
]
interface IWICBitmapDecoder : IUnknown
{
HRESULT QueryCapability(
[in] IStream *pIStream,
[out] DWORD *pdwCapability);
HRESULT Initialize(
[in] IStream *pIStream,
[in] WICDecodeOptions cacheOptions);
HRESULT GetContainerFormat(
[out] GUID *pguidContainerFormat);
HRESULT GetDecoderInfo(
[out] IWICBitmapDecoderInfo **ppIDecoderInfo);
HRESULT CopyPalette(
[in] IWICPalette *pIPalette);
HRESULT GetMetadataQueryReader(
[out] IWICMetadataQueryReader **ppIMetadataQueryReader);
HRESULT GetPreview(
[out] IWICBitmapSource **ppIBitmapSource);
HRESULT GetColorContexts(
[in] UINT cCount,
[in, out, unique, size_is(cCount)] IWICColorContext **ppIColorContexts,
[out] UINT *pcActualCount);
HRESULT GetThumbnail(
[out] IWICBitmapSource **ppIThumbnail);
HRESULT GetFrameCount(
[out] UINT *pCount);
HRESULT GetFrame(
[in] UINT index,
[out] IWICBitmapFrameDecode **ppIBitmapFrame);
}
[
object,
uuid(00000105-a8f2-4877-ba0a-fd2b6645fb94)
]
interface IWICBitmapFrameEncode : IUnknown
{
HRESULT Initialize(
[in, unique] IPropertyBag2 *pIEncoderOptions);
HRESULT SetSize(
[in] UINT uiWidth,
[in] UINT uiHeight);
HRESULT SetResolution(
[in] double dpiX,
[in] double dpiY);
HRESULT SetPixelFormat(
[in, out] WICPixelFormatGUID *pPixelFormat);
HRESULT SetColorContexts(
[in] UINT cCount,
[in, size_is(cCount)] IWICColorContext **ppIColorContext);
HRESULT SetPalette(
[in] IWICPalette *pIPalette);
HRESULT SetThumbnail(
[in] IWICBitmapSource *pIThumbnail);
HRESULT WritePixels(
[in] UINT lineCount,
[in] UINT cbStride,
[in] UINT cbBufferSize,
[in, size_is(cbBufferSize)] BYTE *pbPixels);
HRESULT WriteSource(
[in] IWICBitmapSource *pIBitmapSource,
[in, unique] WICRect *prc);
HRESULT Commit();
HRESULT GetMetadataQueryWriter(
IWICMetadataQueryWriter **ppIMetadataQueryWriter);
}
interface IWICBitmapEncoder;
[
object,
uuid(94c9b4ee-a09f-4f92-8a1e-4a9bce7e76fb)
]
interface IWICBitmapEncoderInfo : IWICBitmapCodecInfo
{
HRESULT CreateInstance(
[out] IWICBitmapEncoder **ppIBitmapEncoder);
}
[
object,
uuid(00000103-a8f2-4877-ba0a-fd2b6645fb94)
]
interface IWICBitmapEncoder : IUnknown
{
HRESULT Initialize(
[in] IStream *pIStream,
[in] WICBitmapEncoderCacheOption cacheOption);
HRESULT GetContainerFormat(
[out] GUID *pguidContainerFormat);
HRESULT GetEncoderInfo(
[out] IWICBitmapEncoderInfo **ppIEncoderInfo);
HRESULT SetColorContexts(
[in] UINT cCount,
[in, size_is(cCount)] IWICColorContext **ppIColorContext);
HRESULT SetPalette(
[in] IWICPalette *pIPalette);
HRESULT SetThumbnail(
[in] IWICBitmapSource *pIThumbnail);
HRESULT SetPreview(
[in] IWICBitmapSource *pIPreview);
HRESULT CreateNewFrame(
[out] IWICBitmapFrameEncode **ppIFrameEncode,
[in, out, unique] IPropertyBag2 **ppIEncoderOptions);
HRESULT Commit();
HRESULT GetMetadataQueryWriter(
[out] IWICMetadataQueryWriter **ppIMetadataQueryWriter);
}
[
object,
uuid(00000301-a8f2-4877-ba0a-fd2b6645fb94)
]
interface IWICFormatConverter : IWICBitmapSource
{
HRESULT Initialize(
[in] IWICBitmapSource *pISource,
[in] REFWICPixelFormatGUID dstFormat,
[in] WICBitmapDitherType dither,
[in] IWICPalette *pIPalette,
[in] double alphaThresholdPercent,
[in] WICBitmapPaletteType paletteTranslate);
HRESULT CanConvert(
[in] REFWICPixelFormatGUID srcPixelFormat,
[in] REFWICPixelFormatGUID dstPixelFormat,
[out] BOOL *pfCanConvert);
}
[
object,
uuid(9f34fb65-13f4-4f15-bc57-3726b5e53d9f)
]
interface IWICFormatConverterInfo : IWICComponentInfo
{
HRESULT GetPixelFormats(
[in] UINT cFormats,
[in, out, size_is(cFormats)] WICPixelFormatGUID *pPixelFormatGUIDs,
[out] UINT *pcActual);
HRESULT CreateInstance(
[out] IWICFormatConverter **ppIConverter);
}
[
object,
uuid(135ff860-22b7-4ddf-b0f6-218f4f299a43)
]
interface IWICStream : IStream
{
HRESULT InitializeFromIStream(
[in] IStream *pIStream);
HRESULT InitializeFromFilename(
[in] LPCWSTR wzFileName,
[in] DWORD dwAccessMode);
HRESULT InitializeFromMemory(
[in, size_is(cbBufferSize)] BYTE *pbBuffer,
[in] DWORD cbBufferSize);
HRESULT InitializeFromIStreamRegion(
[in] IStream *pIStream,
[in] ULARGE_INTEGER ulOffset,
[in] ULARGE_INTEGER ulMaxSize);
}
cpp_quote("DEFINE_GUID(CLSID_WICImagingFactory, 0xcacaf262,0x9370,0x4615,0xa1,0x3b,0x9f,0x55,0x39,0xda,0x4c,0x0a);")
[
object,
uuid(ec5ec8a9-c395-4314-9c77-54d7a935ff70)
]
interface IWICImagingFactory : IUnknown
{
HRESULT CreateDecoderFromFilename(
[in] LPCWSTR wzFilename,
[in, unique] const GUID *pguidVendor,
[in] DWORD dwDesiredAccess,
[in] WICDecodeOptions metadataOptions,
[out, retval] IWICBitmapDecoder **ppIDecoder);
HRESULT CreateDecoderFromStream(
[in] IStream *pIStream,
[in, unique] const GUID *pguidVendor,
[in] WICDecodeOptions metadataOptions,
[out, retval] IWICBitmapDecoder **ppIDecoder);
HRESULT CreateDecoderFromFileHandle(
[in] ULONG_PTR hFile,
[in, unique] const GUID *pguidVendor,
[in] WICDecodeOptions metadataOptions,
[out, retval] IWICBitmapDecoder **ppIDecoder);
HRESULT CreateComponentInfo(
[in] REFCLSID clsidComponent,
[out] IWICComponentInfo **ppIInfo);
HRESULT CreateDecoder(
[in] REFGUID guidContainerFormat,
[in, unique] const GUID *pguidVendor,
[out, retval] IWICBitmapDecoder **ppIDecoder);
HRESULT CreateEncoder(
[in] REFGUID guidContainerFormat,
[in, unique] const GUID *pguidVendor,
[out, retval] IWICBitmapEncoder **ppIEncoder);
HRESULT CreatePalette(
[out] IWICPalette **ppIPalette);
HRESULT CreateFormatConverter(
[out] IWICFormatConverter **ppIFormatConverter);
HRESULT CreateBitmapScaler(
[out] IWICBitmapScaler **ppIBitmapScaler);
HRESULT CreateBitmapClipper(
[out] IWICBitmapClipper **ppIBitmapClipper);
HRESULT CreateBitmapFlipRotator(
[out] IWICBitmapFlipRotator **ppIBitmapFlipRotator);
HRESULT CreateStream(
[out] IWICStream **ppIWICStream);
HRESULT CreateColorContext(
[out] IWICColorContext **ppIWICColorContext);
HRESULT CreateColorTransformer(
[out] IWICColorTransform **ppIWICColorTransform);
HRESULT CreateBitmap(
[in] UINT uiWidth,
[in] UINT uiHeight,
[in] REFWICPixelFormatGUID pixelFormat,
[in] WICBitmapCreateCacheOption option,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateBitmapFromSource(
[in] IWICBitmapSource *piBitmapSource,
[in] WICBitmapCreateCacheOption option,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateBitmapFromSourceRect(
[in] IWICBitmapSource *piBitmapSource,
[in] UINT x,
[in] UINT y,
[in] UINT width,
[in] UINT height,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateBitmapFromMemory(
[in] UINT uiWidth,
[in] UINT uiHeight,
[in] REFWICPixelFormatGUID pixelFormat,
[in] UINT cbStride,
[in] UINT cbBufferSize,
[in, size_is(cbBufferSize)] BYTE *pbBuffer,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateBitmapFromHBITMAP(
[in] HBITMAP hBitmap,
[in, unique] HPALETTE hPalette,
[in] WICBitmapAlphaChannelOption options,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateBitmapFromHICON(
[in] HICON hIcon,
[out] IWICBitmap **ppIBitmap);
HRESULT CreateComponentEnumerator(
[in] DWORD componentTypes,
[in] DWORD options,
[out] IEnumUnknown **ppIEnumUnknown);
HRESULT CreateFastMetadataEncoderFromDecoder(
[in] IWICBitmapDecoder *pIDecoder,
[out] IWICFastMetadataEncoder **ppIFastEncoder);
HRESULT CreateFastMetadataEncoderFromFrameDecode(
[in] IWICBitmapFrameDecode *pIFrameDecoder,
[out] IWICFastMetadataEncoder **ppIFastEncoder);
HRESULT CreateQueryWriter(
[in] REFGUID guidMetadataFormat,
[in, unique] const GUID *pguidVendor,
[out] IWICMetadataQueryWriter **ppIQueryWriter);
HRESULT CreateQueryWriterFromReader(
[in] IWICMetadataQueryReader *pIQueryReader,
[in, unique] const GUID *pguidVendor,
[out] IWICMetadataQueryWriter **ppIQueryWriter);
}
cpp_quote("HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);")
cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);")
cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);")
cpp_quote("DEFINE_GUID(CLSID_WICIcoDecoder, 0xc61bfcdf,0x2e0f,0x4aad,0xa8,0xd7,0xe0,0x6b,0xaf,0xeb,0xcd,0xfe);")
cpp_quote("DEFINE_GUID(CLSID_WICJpegDecoder, 0x9456a480,0xe88b,0x43ea,0x9e,0x73,0x0b,0x2d,0x9b,0x71,0xb1,0xca);")
cpp_quote("DEFINE_GUID(CLSID_WICGifDecoder, 0x381dda3c,0x9ce9,0x4834,0xa2,0x3e,0x1f,0x98,0xf8,0xfc,0x52,0xbe);")
cpp_quote("DEFINE_GUID(CLSID_WICTiffDecoder, 0xb54e85d9,0xfe23,0x499f,0x8b,0x88,0x6a,0xce,0xa7,0x13,0x75,0x2b);")
cpp_quote("DEFINE_GUID(CLSID_WICWmpDecoder, 0xa26cec36,0x234c,0x4950,0xae,0x16,0xe3,0x4a,0xac,0xe7,0x1d,0x0d);")
cpp_quote("DEFINE_GUID(CLSID_WICBmpEncoder, 0x69be8bb4,0xd66d,0x47c8,0x86,0x5a,0xed,0x15,0x89,0x43,0x37,0x82);")
cpp_quote("DEFINE_GUID(CLSID_WICPngEncoder, 0x27949969,0x876a,0x41d7,0x94,0x47,0x56,0x8f,0x6a,0x35,0xa4,0xdc);")
cpp_quote("DEFINE_GUID(CLSID_WICJpegEncoder, 0x1a34f5c1,0x4a5a,0x46dc,0xb6,0x44,0x1f,0x45,0x67,0xe7,0xa6,0x76);")
cpp_quote("DEFINE_GUID(CLSID_WICGifEncoder, 0x114f5598,0x0b22,0x40a0,0x86,0xa1,0xc8,0x3e,0xa4,0x95,0xad,0xbd);")
cpp_quote("DEFINE_GUID(CLSID_WICTiffEncoder, 0x0131be10,0x2001,0x4c5f,0xa9,0xb0,0xcc,0x88,0xfa,0xb6,0x4c,0xe8);")
cpp_quote("DEFINE_GUID(CLSID_WICWmpEncoder, 0xac4ce3cb,0xe1c1,0x44cd,0x82,0x15,0x5a,0x16,0x65,0x50,0x9e,0xc2);")
cpp_quote("DEFINE_GUID(CLSID_WICDefaultFormatConverter, 0x1a3f11dc,0xb514,0x4b17,0x8c,0x5f,0x21,0x54,0x51,0x38,0x52,0xf1);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatBmp, 0x0af1d87e,0xfcfe,0x4188,0xbd,0xeb,0xa7,0x90,0x64,0x71,0xcb,0xe3);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatPng, 0x1b7cfaf4,0x713f,0x473c,0xbb,0xcd,0x61,0x37,0x42,0x5f,0xae,0xaf);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatIco, 0xa3a860c4,0x338f,0x4c17,0x91,0x9a,0xfb,0xa4,0xb5,0x62,0x8f,0x21);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatJpeg, 0x19e4a5aa,0x5662,0x4fc5,0xa0,0xc0,0x17,0x58,0x02,0x8e,0x10,0x57);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatTiff, 0x163bcc30,0xe2e9,0x4f0b,0x96,0x1d,0xa3,0xe9,0xfd,0xb7,0x88,0xa3);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatGif, 0x1f8a5601,0x7d4d,0x4cbd,0x9c,0x82,0x1b,0xc8,0xd4,0xee,0xb9,0xa5);")
cpp_quote("DEFINE_GUID(GUID_ContainerFormatWmp, 0x57a37caa,0x367a,0x4540,0x91,0x6b,0xf1,0x83,0xc5,0x09,0x3a,0x4b);")
cpp_quote("DEFINE_GUID(GUID_VendorMicrosoft, 0xf0e749ca,0xedef,0x4589,0xa7,0x3a,0xee,0x0e,0x62,0x6a,0x2a,0x2b);")
cpp_quote("DEFINE_GUID(CATID_WICBitmapDecoders, 0x7ed96837,0x96f0,0x4812,0xb2,0x11,0xf1,0x3c,0x24,0x11,0x7e,0xd3);")
cpp_quote("DEFINE_GUID(CATID_WICBitmapEncoders, 0xac757296,0x3522,0x4e11,0x98,0x62,0xc1,0x7b,0xe5,0xa1,0x76,0x7e);")
cpp_quote("DEFINE_GUID(CATID_WICFormatConverters, 0x7835eae8,0xbf14,0x49d1,0x93,0xce,0x53,0x3a,0x40,0x7b,0x22,0x48);")

View file

@ -163,6 +163,7 @@ reactos/dll/win32/urlmon # Autosync
reactos/dll/win32/usp10 # Autosync
reactos/dll/win32/uxtheme # Autosync
reactos/dll/win32/version # Autosync
reactos/dll/win32/windowscodecs # Autosync
reactos/dll/win32/winemp3.acm # Autosync
reactos/dll/win32/wininet # Autosync
reactos/dll/win32/winhttp # Autosync