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