mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
- Add windowscodecs.dll from Wine 1.1.28
svn path=/trunk/; revision=42867
This commit is contained in:
parent
9d4ec238ee
commit
fcf26f3471
25 changed files with 9348 additions and 0 deletions
|
@ -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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
1059
reactos/dll/win32/windowscodecs/bmpdecode.c
Normal file
1059
reactos/dll/win32/windowscodecs/bmpdecode.c
Normal file
File diff suppressed because it is too large
Load diff
598
reactos/dll/win32/windowscodecs/bmpencode.c
Normal file
598
reactos/dll/win32/windowscodecs/bmpencode.c
Normal 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;
|
||||
}
|
175
reactos/dll/win32/windowscodecs/clsfactory.c
Normal file
175
reactos/dll/win32/windowscodecs/clsfactory.c
Normal 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;
|
||||
}
|
659
reactos/dll/win32/windowscodecs/converter.c
Normal file
659
reactos/dll/win32/windowscodecs/converter.c
Normal 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;
|
||||
}
|
510
reactos/dll/win32/windowscodecs/gifformat.c
Normal file
510
reactos/dll/win32/windowscodecs/gifformat.c
Normal 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;
|
||||
}
|
797
reactos/dll/win32/windowscodecs/icoformat.c
Normal file
797
reactos/dll/win32/windowscodecs/icoformat.c
Normal 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;
|
||||
}
|
420
reactos/dll/win32/windowscodecs/imgfactory.c
Normal file
420
reactos/dll/win32/windowscodecs/imgfactory.c
Normal 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;
|
||||
}
|
1070
reactos/dll/win32/windowscodecs/info.c
Normal file
1070
reactos/dll/win32/windowscodecs/info.c
Normal file
File diff suppressed because it is too large
Load diff
95
reactos/dll/win32/windowscodecs/main.c
Normal file
95
reactos/dll/win32/windowscodecs/main.c
Normal 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;
|
||||
}
|
||||
}
|
279
reactos/dll/win32/windowscodecs/palette.c
Normal file
279
reactos/dll/win32/windowscodecs/palette.c
Normal 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;
|
||||
}
|
147
reactos/dll/win32/windowscodecs/propertybag.c
Normal file
147
reactos/dll/win32/windowscodecs/propertybag.c
Normal 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;
|
||||
}
|
899
reactos/dll/win32/windowscodecs/regsvr.c
Normal file
899
reactos/dll/win32/windowscodecs/regsvr.c
Normal 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;
|
||||
}
|
512
reactos/dll/win32/windowscodecs/stream.c
Normal file
512
reactos/dll/win32/windowscodecs/stream.c
Normal 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;
|
||||
}
|
999
reactos/dll/win32/windowscodecs/ungif.c
Normal file
999
reactos/dll/win32/windowscodecs/ungif.c
Normal 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;
|
||||
}
|
169
reactos/dll/win32/windowscodecs/ungif.h
Normal file
169
reactos/dll/win32/windowscodecs/ungif.h
Normal 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_ */
|
26
reactos/dll/win32/windowscodecs/version.rc
Normal file
26
reactos/dll/win32/windowscodecs/version.rc
Normal 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"
|
41
reactos/dll/win32/windowscodecs/wincodecs_private.h
Normal file
41
reactos/dll/win32/windowscodecs/wincodecs_private.h
Normal 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 */
|
32
reactos/dll/win32/windowscodecs/windowscodecs.rbuild
Normal file
32
reactos/dll/win32/windowscodecs/windowscodecs.rbuild
Normal 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>
|
116
reactos/dll/win32/windowscodecs/windowscodecs.spec
Normal file
116
reactos/dll/win32/windowscodecs/windowscodecs.spec
Normal 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
|
|
@ -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>
|
||||
|
|
738
reactos/include/psdk/wincodec.idl
Normal file
738
reactos/include/psdk/wincodec.idl
Normal 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);")
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue