/*
 * Copyright 2012 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);

/* WARNING: .NET Media Integration Layer (MIL) directly dereferences
 * BitmapImpl members and depends on its exact layout.
 */
typedef struct BitmapImpl {
    IMILUnknown1 IMILUnknown1_iface;
    LONG ref;
    IMILBitmapSource IMILBitmapSource_iface;
    IWICBitmap IWICBitmap_iface;
    IMILUnknown2 IMILUnknown2_iface;
    IWICPalette *palette;
    int palette_set;
    LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
    BYTE *data;
    UINT width, height;
    UINT stride;
    UINT bpp;
    WICPixelFormatGUID pixelformat;
    double dpix, dpiy;
    CRITICAL_SECTION cs;
} BitmapImpl;

typedef struct BitmapLockImpl {
    IWICBitmapLock IWICBitmapLock_iface;
    LONG ref;
    BitmapImpl *parent;
    UINT width, height;
    BYTE *data;
} BitmapLockImpl;

static inline BitmapImpl *impl_from_IWICBitmap(IWICBitmap *iface)
{
    return CONTAINING_RECORD(iface, BitmapImpl, IWICBitmap_iface);
}

static inline BitmapImpl *impl_from_IMILBitmapSource(IMILBitmapSource *iface)
{
    return CONTAINING_RECORD(iface, BitmapImpl, IMILBitmapSource_iface);
}

static inline BitmapImpl *impl_from_IMILUnknown1(IMILUnknown1 *iface)
{
    return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown1_iface);
}

static inline BitmapImpl *impl_from_IMILUnknown2(IMILUnknown2 *iface)
{
    return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown2_iface);
}

static inline BitmapLockImpl *impl_from_IWICBitmapLock(IWICBitmapLock *iface)
{
    return CONTAINING_RECORD(iface, BitmapLockImpl, IWICBitmapLock_iface);
}

static BOOL BitmapImpl_AcquireLock(BitmapImpl *This, int write)
{
    if (write)
    {
        return 0 == InterlockedCompareExchange(&This->lock, -1, 0);
    }
    else
    {
        while (1)
        {
            LONG prev_val = This->lock;
            if (prev_val == -1)
                return FALSE;
            if (prev_val == InterlockedCompareExchange(&This->lock, prev_val+1, prev_val))
                return TRUE;
        }
    }
}

static void BitmapImpl_ReleaseLock(BitmapImpl *This)
{
    while (1)
    {
        LONG prev_val = This->lock, new_val;
        if (prev_val == -1)
            new_val = 0;
        else
            new_val = prev_val - 1;
        if (prev_val == InterlockedCompareExchange(&This->lock, new_val, prev_val))
            break;
    }
}


static HRESULT WINAPI BitmapLockImpl_QueryInterface(IWICBitmapLock *iface, REFIID iid,
    void **ppv)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICBitmapLock, iid))
    {
        *ppv = &This->IWICBitmapLock_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI BitmapLockImpl_AddRef(IWICBitmapLock *iface)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI BitmapLockImpl_Release(IWICBitmapLock *iface)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        BitmapImpl_ReleaseLock(This->parent);
        IWICBitmap_Release(&This->parent->IWICBitmap_iface);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BitmapLockImpl_GetSize(IWICBitmapLock *iface,
    UINT *puiWidth, UINT *puiHeight)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);

    if (!puiWidth || !puiHeight)
        return E_INVALIDARG;

    *puiWidth = This->width;
    *puiHeight = This->height;

    return S_OK;
}

static HRESULT WINAPI BitmapLockImpl_GetStride(IWICBitmapLock *iface,
    UINT *pcbStride)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    TRACE("(%p,%p)\n", iface, pcbStride);

    if (!pcbStride)
        return E_INVALIDARG;

    *pcbStride = This->parent->stride;

    return S_OK;
}

static HRESULT WINAPI BitmapLockImpl_GetDataPointer(IWICBitmapLock *iface,
    UINT *pcbBufferSize, BYTE **ppbData)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    TRACE("(%p,%p,%p)\n", iface, pcbBufferSize, ppbData);

    if (!pcbBufferSize || !ppbData)
        return E_INVALIDARG;

    *pcbBufferSize = This->parent->stride * (This->height - 1) +
        ((This->parent->bpp * This->width) + 7)/8;
    *ppbData = This->data;

    return S_OK;
}

static HRESULT WINAPI BitmapLockImpl_GetPixelFormat(IWICBitmapLock *iface,
    WICPixelFormatGUID *pPixelFormat)
{
    BitmapLockImpl *This = impl_from_IWICBitmapLock(iface);
    TRACE("(%p,%p)\n", iface, pPixelFormat);

    return IWICBitmap_GetPixelFormat(&This->parent->IWICBitmap_iface, pPixelFormat);
}

static const IWICBitmapLockVtbl BitmapLockImpl_Vtbl = {
    BitmapLockImpl_QueryInterface,
    BitmapLockImpl_AddRef,
    BitmapLockImpl_Release,
    BitmapLockImpl_GetSize,
    BitmapLockImpl_GetStride,
    BitmapLockImpl_GetDataPointer,
    BitmapLockImpl_GetPixelFormat
};

static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid,
    void **ppv)
{
    BitmapImpl *This = impl_from_IWICBitmap(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_IWICBitmap, iid))
    {
        *ppv = &This->IWICBitmap_iface;
    }
    else if (IsEqualIID(&IID_IMILBitmapSource, iid))
    {
        *ppv = &This->IMILBitmapSource_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI BitmapImpl_AddRef(IWICBitmap *iface)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        if (This->palette) IWICPalette_Release(This->palette);
        This->cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->cs);
        HeapFree(GetProcessHeap(), 0, This->data);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BitmapImpl_GetSize(IWICBitmap *iface,
    UINT *puiWidth, UINT *puiHeight)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);

    if (!puiWidth || !puiHeight)
        return E_INVALIDARG;

    *puiWidth = This->width;
    *puiHeight = This->height;

    return S_OK;
}

static HRESULT WINAPI BitmapImpl_GetPixelFormat(IWICBitmap *iface,
    WICPixelFormatGUID *pPixelFormat)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%p)\n", iface, pPixelFormat);

    if (!pPixelFormat)
        return E_INVALIDARG;

    memcpy(pPixelFormat, &This->pixelformat, sizeof(GUID));

    return S_OK;
}

static HRESULT WINAPI BitmapImpl_GetResolution(IWICBitmap *iface,
    double *pDpiX, double *pDpiY)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);

    if (!pDpiX || !pDpiY)
        return E_INVALIDARG;

    EnterCriticalSection(&This->cs);
    *pDpiX = This->dpix;
    *pDpiY = This->dpiy;
    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static HRESULT WINAPI BitmapImpl_CopyPalette(IWICBitmap *iface,
    IWICPalette *pIPalette)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%p)\n", iface, pIPalette);

    if (!This->palette_set)
        return WINCODEC_ERR_PALETTEUNAVAILABLE;

    return IWICPalette_InitializeFromPalette(pIPalette, This->palette);
}

static HRESULT WINAPI BitmapImpl_CopyPixels(IWICBitmap *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    return copy_pixels(This->bpp, This->data, This->width, This->height,
        This->stride, prc, cbStride, cbBufferSize, pbBuffer);
}

static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock,
    DWORD flags, IWICBitmapLock **ppILock)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    BitmapLockImpl *result;
    WICRect rc;

    TRACE("(%p,%p,%x,%p)\n", iface, prcLock, flags, ppILock);

    if (!(flags & (WICBitmapLockRead|WICBitmapLockWrite)) || !ppILock)
        return E_INVALIDARG;

    if (!prcLock)
    {
        rc.X = rc.Y = 0;
        rc.Width = This->width;
        rc.Height = This->height;
        prcLock = &rc;
    }
    else if (prcLock->X >= This->width || prcLock->Y >= This->height ||
             prcLock->X + prcLock->Width > This->width ||
             prcLock->Y + prcLock->Height > This->height ||
             prcLock->Width <= 0 || prcLock->Height <= 0)
        return E_INVALIDARG;
    else if (((prcLock->X * This->bpp) % 8) != 0)
    {
        FIXME("Cannot lock at an X coordinate not at a full byte\n");
        return E_FAIL;
    }

    result = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl));
    if (!result)
        return E_OUTOFMEMORY;

    if (!BitmapImpl_AcquireLock(This, flags & WICBitmapLockWrite))
    {
        HeapFree(GetProcessHeap(), 0, result);
        return WINCODEC_ERR_ALREADYLOCKED;
    }

    result->IWICBitmapLock_iface.lpVtbl = &BitmapLockImpl_Vtbl;
    result->ref = 1;
    result->parent = This;
    result->width = prcLock->Width;
    result->height = prcLock->Height;
    result->data = This->data + This->stride * prcLock->Y +
        (This->bpp * prcLock->X)/8;

    IWICBitmap_AddRef(&This->IWICBitmap_iface);
    *ppILock = &result->IWICBitmapLock_iface;

    return S_OK;
}

static HRESULT WINAPI BitmapImpl_SetPalette(IWICBitmap *iface, IWICPalette *pIPalette)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    HRESULT hr;

    TRACE("(%p,%p)\n", iface, pIPalette);

    if (!This->palette)
    {
        IWICPalette *new_palette;
        hr = PaletteImpl_Create(&new_palette);

        if (FAILED(hr)) return hr;

        if (InterlockedCompareExchangePointer((void**)&This->palette, new_palette, NULL))
        {
            /* someone beat us to it */
            IWICPalette_Release(new_palette);
        }
    }

    hr = IWICPalette_InitializeFromPalette(This->palette, pIPalette);

    if (SUCCEEDED(hr))
        This->palette_set = 1;

    return S_OK;
}

static HRESULT WINAPI BitmapImpl_SetResolution(IWICBitmap *iface,
    double dpiX, double dpiY)
{
    BitmapImpl *This = impl_from_IWICBitmap(iface);
    TRACE("(%p,%f,%f)\n", iface, dpiX, dpiY);

    EnterCriticalSection(&This->cs);
    This->dpix = dpiX;
    This->dpiy = dpiY;
    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static const IWICBitmapVtbl BitmapImpl_Vtbl = {
    BitmapImpl_QueryInterface,
    BitmapImpl_AddRef,
    BitmapImpl_Release,
    BitmapImpl_GetSize,
    BitmapImpl_GetPixelFormat,
    BitmapImpl_GetResolution,
    BitmapImpl_CopyPalette,
    BitmapImpl_CopyPixels,
    BitmapImpl_Lock,
    BitmapImpl_SetPalette,
    BitmapImpl_SetResolution
};

static HRESULT WINAPI IMILBitmapImpl_QueryInterface(IMILBitmapSource *iface, REFIID iid,
    void **ppv)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IMILBitmapSource, iid))
    {
        IUnknown_AddRef(&This->IMILBitmapSource_iface);
        *ppv = &This->IMILBitmapSource_iface;
        return S_OK;
    }

    *ppv = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI IMILBitmapImpl_AddRef(IMILBitmapSource *iface)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_AddRef(&This->IWICBitmap_iface);
}

static ULONG WINAPI IMILBitmapImpl_Release(IMILBitmapSource *iface)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_Release(&This->IWICBitmap_iface);
}

static HRESULT WINAPI IMILBitmapImpl_GetSize(IMILBitmapSource *iface,
    UINT *width, UINT *height)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_GetSize(&This->IWICBitmap_iface, width, height);
}

static const struct
{
    const GUID *WIC_format;
    int enum_format;
} pixel_fmt_map[] =
{
    { &GUID_WICPixelFormatDontCare, 0 },
    { &GUID_WICPixelFormat1bppIndexed, 1 },
    { &GUID_WICPixelFormat2bppIndexed, 2 },
    { &GUID_WICPixelFormat4bppIndexed, 3 },
    { &GUID_WICPixelFormat8bppIndexed, 4 },
    { &GUID_WICPixelFormatBlackWhite, 5 },
    { &GUID_WICPixelFormat2bppGray, 6 },
    { &GUID_WICPixelFormat4bppGray, 7 },
    { &GUID_WICPixelFormat8bppGray, 8 },
    { &GUID_WICPixelFormat16bppBGR555, 9 },
    { &GUID_WICPixelFormat16bppBGR565, 0x0a },
    { &GUID_WICPixelFormat16bppGray, 0x0b },
    { &GUID_WICPixelFormat24bppBGR, 0x0c },
    { &GUID_WICPixelFormat24bppRGB, 0x0d },
    { &GUID_WICPixelFormat32bppBGR, 0x0e },
    { &GUID_WICPixelFormat32bppBGRA, 0x0f },
    { &GUID_WICPixelFormat32bppPBGRA, 0x10 },
    { &GUID_WICPixelFormat48bppRGB, 0x15 },
    { &GUID_WICPixelFormat64bppRGBA, 0x16 },
    { &GUID_WICPixelFormat64bppPRGBA, 0x17 },
    { &GUID_WICPixelFormat32bppCMYK, 0x1c }
};

static HRESULT WINAPI IMILBitmapImpl_GetPixelFormat(IMILBitmapSource *iface,
    int *format)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    int i;

    TRACE("(%p,%p)\n", iface, format);

    if (!format) return E_INVALIDARG;

    *format = 0;

    for (i = 0; i < sizeof(pixel_fmt_map)/sizeof(pixel_fmt_map[0]); i++)
    {
        if (IsEqualGUID(pixel_fmt_map[i].WIC_format, &This->pixelformat))
        {
            *format = pixel_fmt_map[i].enum_format;
            break;
        }
    }

    return S_OK;
}

static HRESULT WINAPI IMILBitmapImpl_GetResolution(IMILBitmapSource *iface,
    double *dpix, double *dpiy)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_GetResolution(&This->IWICBitmap_iface, dpix, dpiy);
}

static HRESULT WINAPI IMILBitmapImpl_CopyPalette(IMILBitmapSource *iface,
    IWICPalette *palette)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_CopyPalette(&This->IWICBitmap_iface, palette);
}

static HRESULT WINAPI IMILBitmapImpl_CopyPixels(IMILBitmapSource *iface,
    const WICRect *rc, UINT stride, UINT size, BYTE *buffer)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);
    return IWICBitmap_CopyPixels(&This->IWICBitmap_iface, rc, stride, size, buffer);
}

static HRESULT WINAPI IMILBitmapImpl_UnknownMethod1(IMILBitmapSource *iface, void **ppv)
{
    BitmapImpl *This = impl_from_IMILBitmapSource(iface);

    TRACE("(%p,%p)\n", iface, ppv);

    if (!ppv) return E_INVALIDARG;

    IUnknown_AddRef(&This->IMILUnknown1_iface);
    *ppv = &This->IMILUnknown1_iface;

    return S_OK;
}

static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl =
{
    IMILBitmapImpl_QueryInterface,
    IMILBitmapImpl_AddRef,
    IMILBitmapImpl_Release,
    IMILBitmapImpl_GetSize,
    IMILBitmapImpl_GetPixelFormat,
    IMILBitmapImpl_GetResolution,
    IMILBitmapImpl_CopyPalette,
    IMILBitmapImpl_CopyPixels,
    IMILBitmapImpl_UnknownMethod1,
};

static HRESULT WINAPI IMILUnknown1Impl_QueryInterface(IMILUnknown1 *iface, REFIID iid,
    void **ppv)
{
    BitmapImpl *This = impl_from_IMILUnknown1(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid))
    {
        IUnknown_AddRef(&This->IMILUnknown1_iface);
        *ppv = iface;
        return S_OK;
    }

    return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv);
}

static ULONG WINAPI IMILUnknown1Impl_AddRef(IMILUnknown1 *iface)
{
    BitmapImpl *This = impl_from_IMILUnknown1(iface);
    return IWICBitmap_AddRef(&This->IWICBitmap_iface);
}

static ULONG WINAPI IMILUnknown1Impl_Release(IMILUnknown1 *iface)
{
    BitmapImpl *This = impl_from_IMILUnknown1(iface);
    return IWICBitmap_Release(&This->IWICBitmap_iface);
}

static const IMILUnknown1Vtbl IMILUnknown1Impl_Vtbl =
{
    IMILUnknown1Impl_QueryInterface,
    IMILUnknown1Impl_AddRef,
    IMILUnknown1Impl_Release,
};

static HRESULT WINAPI IMILUnknown2Impl_QueryInterface(IMILUnknown2 *iface, REFIID iid,
    void **ppv)
{
    BitmapImpl *This = impl_from_IMILUnknown2(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid))
    {
        IUnknown_AddRef(&This->IMILUnknown2_iface);
        *ppv = iface;
        return S_OK;
    }

    return IWICBitmap_QueryInterface(&This->IWICBitmap_iface, iid, ppv);
}

static ULONG WINAPI IMILUnknown2Impl_AddRef(IMILUnknown2 *iface)
{
    BitmapImpl *This = impl_from_IMILUnknown2(iface);
    return IWICBitmap_AddRef(&This->IWICBitmap_iface);
}

static ULONG WINAPI IMILUnknown2Impl_Release(IMILUnknown2 *iface)
{
    BitmapImpl *This = impl_from_IMILUnknown2(iface);
    return IWICBitmap_Release(&This->IWICBitmap_iface);
}

static HRESULT WINAPI IMILUnknown2Impl_UnknownMethod1(IMILUnknown2 *iface, void *arg1, void *arg2)
{
    FIXME("(%p,%p,%p): stub\n", iface, arg1, arg2);
    return E_NOTIMPL;
}

static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl =
{
    IMILUnknown2Impl_QueryInterface,
    IMILUnknown2Impl_AddRef,
    IMILUnknown2Impl_Release,
    IMILUnknown2Impl_UnknownMethod1,
};

HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
    UINT stride, UINT datasize, BYTE *bits,
    REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
    IWICBitmap **ppIBitmap)
{
    HRESULT hr;
    BitmapImpl *This;
    BYTE *data;
    UINT bpp;

    hr = get_pixelformat_bpp(pixelFormat, &bpp);
    if (FAILED(hr)) return hr;

    if (!stride) stride = (((bpp*uiWidth)+31)/32)*4;
    if (!datasize) datasize = stride * uiHeight;

    if (datasize < stride * uiHeight) return WINCODEC_ERR_INSUFFICIENTBUFFER;
    if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
    data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
    if (!This || !data)
    {
        HeapFree(GetProcessHeap(), 0, This);
        HeapFree(GetProcessHeap(), 0, data);
        return E_OUTOFMEMORY;
    }
    if (bits) memcpy(data, bits, datasize);

    This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
    This->IMILBitmapSource_iface.lpVtbl = &IMILBitmapImpl_Vtbl;
    This->IMILUnknown1_iface.lpVtbl = &IMILUnknown1Impl_Vtbl;
    This->IMILUnknown2_iface.lpVtbl = &IMILUnknown2Impl_Vtbl;
    This->ref = 1;
    This->palette = NULL;
    This->palette_set = 0;
    This->lock = 0;
    This->data = data;
    This->width = uiWidth;
    This->height = uiHeight;
    This->stride = stride;
    This->bpp = bpp;
    memcpy(&This->pixelformat, pixelFormat, sizeof(GUID));
    This->dpix = This->dpiy = 0.0;
    InitializeCriticalSection(&This->cs);
    This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapImpl.lock");

    *ppIBitmap = &This->IWICBitmap_iface;

    return S_OK;
}
