/*
 * Copyright 2009 Vincent Povirk for CodeWeavers
 * Copyright 2012 Dmitry Timoshkov
 *
 * 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 "shellapi.h"

#include "wincodecs_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

typedef struct {
    IWICComponentFactory IWICComponentFactory_iface;
    LONG ref;
} ComponentFactory;

static inline ComponentFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
{
    return CONTAINING_RECORD(iface, ComponentFactory, IWICComponentFactory_iface);
}

static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid,
    void **ppv)
{
    ComponentFactory *This = impl_from_IWICComponentFactory(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) ||
        IsEqualIID(&IID_IWICComponentFactory, iid))
    {
        *ppv = &This->IWICComponentFactory_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface)
{
    ComponentFactory *This = impl_from_IWICComponentFactory(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface)
{
    ComponentFactory *This = impl_from_IWICComponentFactory(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 ComponentFactory_CreateDecoderFromFilename(
    IWICComponentFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
    DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
    IWICBitmapDecoder **ppIDecoder)
{
    IWICStream *stream;
    HRESULT hr;

    TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename),
        debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);

    hr = StreamImpl_Create(&stream);
    if (SUCCEEDED(hr))
    {
        hr = IWICStream_InitializeFromFilename(stream, wzFilename, dwDesiredAccess);

        if (SUCCEEDED(hr))
        {
            hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream,
                pguidVendor, metadataOptions, ppIDecoder);
        }

        IWICStream_Release(stream);
    }

    return hr;
}

static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
                                       WICDecodeOptions metadataOptions)
{
    IEnumUnknown *enumdecoders;
    IUnknown *unkdecoderinfo;
    IWICBitmapDecoderInfo *decoderinfo;
    IWICBitmapDecoder *decoder = NULL;
    GUID vendor;
    HRESULT res;
    ULONG num_fetched;
    BOOL matches;

    res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
    if (FAILED(res)) return NULL;

    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))
            {
                if (pguidVendor)
                {
                    res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
                    if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor))
                    {
                        IWICBitmapDecoderInfo_Release(decoderinfo);
                        IUnknown_Release(unkdecoderinfo);
                        continue;
                    }
                }

                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);

    return decoder;
}

static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
    IWICComponentFactory *iface, IStream *pIStream, const GUID *pguidVendor,
    WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
    HRESULT res;
    IWICBitmapDecoder *decoder = NULL;

    TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
        metadataOptions, ppIDecoder);

    if (pguidVendor)
        decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
    if (!decoder)
        decoder = find_decoder(pIStream, NULL, metadataOptions);

    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 ComponentFactory_CreateDecoderFromFileHandle(
    IWICComponentFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor,
    WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
    IWICStream *stream;
    HRESULT hr;

    TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor),
        metadataOptions, ppIDecoder);

    hr = StreamImpl_Create(&stream);
    if (SUCCEEDED(hr))
    {
        hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile);
        if (SUCCEEDED(hr))
        {
            hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream,
                pguidVendor, metadataOptions, ppIDecoder);
        }
        IWICStream_Release(stream);
    }
    return hr;
}

static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface,
    REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
{
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
    return CreateComponentInfo(clsidComponent, ppIInfo);
}

static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface,
    REFGUID guidContainerFormat, const GUID *pguidVendor,
    IWICBitmapDecoder **ppIDecoder)
{
    IEnumUnknown *enumdecoders;
    IUnknown *unkdecoderinfo;
    IWICBitmapDecoderInfo *decoderinfo;
    IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL;
    GUID vendor;
    HRESULT res;
    ULONG num_fetched;

    TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
        debugstr_guid(pguidVendor), ppIDecoder);

    if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG;

    res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
    if (FAILED(res)) return res;

    while (!preferred_decoder)
    {
        res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
        if (res != S_OK) break;

        res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo);
        if (SUCCEEDED(res))
        {
            GUID container_guid;

            res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid);
            if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat))
            {
                IWICBitmapDecoder *new_decoder;

                res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder);
                if (SUCCEEDED(res))
                {
                    if (pguidVendor)
                    {
                        res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
                        if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor))
                        {
                            preferred_decoder = new_decoder;
                            new_decoder = NULL;
                        }
                    }

                    if (new_decoder && !decoder)
                    {
                        decoder = new_decoder;
                        new_decoder = NULL;
                    }

                    if (new_decoder) IWICBitmapDecoder_Release(new_decoder);
                }
            }

            IWICBitmapDecoderInfo_Release(decoderinfo);
        }

        IUnknown_Release(unkdecoderinfo);
    }

    IEnumUnknown_Release(enumdecoders);

    if (preferred_decoder)
    {
        *ppIDecoder = preferred_decoder;
        if (decoder) IWICBitmapDecoder_Release(decoder);
        return S_OK;
    }

    if (decoder)
    {
        *ppIDecoder = decoder;
        return S_OK;
    }

    *ppIDecoder = NULL;
    return WINCODEC_ERR_COMPONENTNOTFOUND;
}

static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface,
    REFGUID guidContainerFormat, const GUID *pguidVendor,
    IWICBitmapEncoder **ppIEncoder)
{
    static int fixme=0;
    IEnumUnknown *enumencoders;
    IUnknown *unkencoderinfo;
    IWICBitmapEncoderInfo *encoderinfo;
    IWICBitmapEncoder *encoder=NULL;
    HRESULT res=S_OK;
    ULONG num_fetched;
    GUID actual_containerformat;

    TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
        debugstr_guid(pguidVendor), ppIEncoder);

    if (pguidVendor && !fixme++)
        FIXME("ignoring vendor GUID\n");

    res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders);
    if (FAILED(res)) return res;

    while (!encoder)
    {
        res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched);

        if (res == S_OK)
        {
            res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo);

            if (SUCCEEDED(res))
            {
                res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat);

                if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat))
                {
                    res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder);
                    if (FAILED(res))
                        encoder = NULL;
                }

                IWICBitmapEncoderInfo_Release(encoderinfo);
            }

            IUnknown_Release(unkencoderinfo);
        }
        else
            break;
    }

    IEnumUnknown_Release(enumencoders);

    if (encoder)
    {
        *ppIEncoder = encoder;
        return S_OK;
    }
    else
    {
        WARN("failed to create encoder\n");
        *ppIEncoder = NULL;
        return WINCODEC_ERR_COMPONENTNOTFOUND;
    }
}

static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface,
    IWICPalette **ppIPalette)
{
    TRACE("(%p,%p)\n", iface, ppIPalette);
    return PaletteImpl_Create(ppIPalette);
}

static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface,
    IWICFormatConverter **ppIFormatConverter)
{
    return FormatConverter_CreateInstance(&IID_IWICFormatConverter, (void**)ppIFormatConverter);
}

static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface,
    IWICBitmapScaler **ppIBitmapScaler)
{
    TRACE("(%p,%p)\n", iface, ppIBitmapScaler);

    return BitmapScaler_Create(ppIBitmapScaler);
}

static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface,
    IWICBitmapClipper **ppIBitmapClipper)
{
    TRACE("(%p,%p)\n", iface, ppIBitmapClipper);
    return BitmapClipper_Create(ppIBitmapClipper);
}

static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface,
    IWICBitmapFlipRotator **ppIBitmapFlipRotator)
{
    TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator);
    return FlipRotator_Create(ppIBitmapFlipRotator);
}

static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface,
    IWICStream **ppIWICStream)
{
    TRACE("(%p,%p)\n", iface, ppIWICStream);
    return StreamImpl_Create(ppIWICStream);
}

static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface,
    IWICColorContext **ppIColorContext)
{
    TRACE("(%p,%p)\n", iface, ppIColorContext);
    return ColorContext_Create(ppIColorContext);
}

static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface,
    IWICColorTransform **ppIColorTransform)
{
    TRACE("(%p,%p)\n", iface, ppIColorTransform);
    return ColorTransform_Create(ppIColorTransform);
}

static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface,
    UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
    WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
    TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
        debugstr_guid(pixelFormat), option, ppIBitmap);
    return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, pixelFormat, option, ppIBitmap);
}

static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
    IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
    IWICBitmap **ppIBitmap)
{
    IWICBitmap *result;
    IWICBitmapLock *lock;
    IWICPalette *palette;
    UINT width, height;
    WICPixelFormatGUID pixelformat = {0};
    HRESULT hr;
    WICRect rc;
    double dpix, dpiy;
    IWICComponentInfo *info;
    IWICPixelFormatInfo2 *formatinfo;
    WICPixelFormatNumericRepresentation format_type;

    TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);

    if (!piBitmapSource || !ppIBitmap)
        return E_INVALIDARG;

    hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);

    if (SUCCEEDED(hr))
        hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);

    if (SUCCEEDED(hr))
        hr = CreateComponentInfo(&pixelformat, &info);

    if (SUCCEEDED(hr))
    {
        hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);

        if (SUCCEEDED(hr))
        {
            hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);

            IWICPixelFormatInfo2_Release(formatinfo);
        }

        IWICComponentInfo_Release(info);
    }

    if (SUCCEEDED(hr))
        hr = BitmapImpl_Create(width, height, 0, 0, NULL, &pixelformat, option, &result);

    if (SUCCEEDED(hr))
    {
        hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
        if (SUCCEEDED(hr))
        {
            UINT stride, buffersize;
            BYTE *buffer;
            rc.X = rc.Y = 0;
            rc.Width = width;
            rc.Height = height;

            hr = IWICBitmapLock_GetStride(lock, &stride);

            if (SUCCEEDED(hr))
                hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);

            if (SUCCEEDED(hr))
                hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
                    buffersize, buffer);

            IWICBitmapLock_Release(lock);
        }

        if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
                              format_type == WICPixelFormatNumericRepresentationIndexed))
        {
            hr = PaletteImpl_Create(&palette);

            if (SUCCEEDED(hr))
            {
                hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);

                if (SUCCEEDED(hr))
                    hr = IWICBitmap_SetPalette(result, palette);
                else
                    hr = S_OK;

                IWICPalette_Release(palette);
            }
        }

        if (SUCCEEDED(hr))
        {
            hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);

            if (SUCCEEDED(hr))
                hr = IWICBitmap_SetResolution(result, dpix, dpiy);
            else
                hr = S_OK;
        }

        if (SUCCEEDED(hr))
            *ppIBitmap = result;
        else
            IWICBitmap_Release(result);
    }

    return hr;
}

static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *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 ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface,
    UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
    UINT size, BYTE *buffer, IWICBitmap **bitmap)
{
    TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
        debugstr_guid(format), stride, size, buffer, bitmap);

    if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;

    return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);
}

static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)
{
    BOOL ret = TRUE;
    BITMAPV4HEADER bmh;
    HDC hdc;

    hdc = CreateCompatibleDC(0);

    memset(&bmh, 0, sizeof(bmh));
    bmh.bV4Size = sizeof(bmh);
    bmh.bV4Width = 1;
    bmh.bV4Height = 1;
    bmh.bV4V4Compression = BI_BITFIELDS;
    bmh.bV4BitCount = 16;

    GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO *)&bmh, DIB_RGB_COLORS);

    if (bmh.bV4RedMask == 0x7c00 &&
        bmh.bV4GreenMask == 0x3e0 &&
        bmh.bV4BlueMask == 0x1f)
    {
        *format = GUID_WICPixelFormat16bppBGR555;
    }
    else if (bmh.bV4RedMask == 0xf800 &&
        bmh.bV4GreenMask == 0x7e0 &&
        bmh.bV4BlueMask == 0x1f)
    {
        *format = GUID_WICPixelFormat16bppBGR565;
    }
    else
    {
        FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask,
            bmh.bV4GreenMask, bmh.bV4BlueMask);
        ret = FALSE;
    }

    DeleteDC(hdc);
    return ret;
}

static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
    HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
{
    BITMAP bm;
    HRESULT hr;
    WICPixelFormatGUID format;
    IWICBitmapLock *lock;
    UINT size, num_palette_entries = 0;
    PALETTEENTRY entry[256];

    TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap);

    if (!bitmap) return E_INVALIDARG;

    if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm))
        return WINCODEC_ERR_WIN32ERROR;

    if (hpal)
    {
        num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry);
        if (!num_palette_entries)
            return WINCODEC_ERR_WIN32ERROR;
    }

    /* TODO: Figure out the correct format for 16, 32, 64 bpp */
    switch(bm.bmBitsPixel)
    {
    case 1:
        format = GUID_WICPixelFormat1bppIndexed;
        break;
    case 4:
        format = GUID_WICPixelFormat4bppIndexed;
        break;
    case 8:
        format = GUID_WICPixelFormat8bppIndexed;
        break;
    case 16:
        if (!get_16bpp_format(hbm, &format))
            return E_INVALIDARG;
        break;
    case 24:
        format = GUID_WICPixelFormat24bppBGR;
        break;
    case 32:
        switch (option)
        {
        case WICBitmapUseAlpha:
            format = GUID_WICPixelFormat32bppBGRA;
            break;
        case WICBitmapUsePremultipliedAlpha:
            format = GUID_WICPixelFormat32bppPBGRA;
            break;
        case WICBitmapIgnoreAlpha:
            format = GUID_WICPixelFormat32bppBGR;
            break;
        default:
            return E_INVALIDARG;
        }
        break;
    case 48:
        format = GUID_WICPixelFormat48bppRGB;
        break;
    default:
        FIXME("unsupported %d bpp\n", bm.bmBitsPixel);
        return E_INVALIDARG;
    }

    hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, WICBitmapCacheOnLoad, bitmap);
    if (hr != S_OK) return hr;

    hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
    if (hr == S_OK)
    {
        BYTE *buffer;
        HDC hdc;
        char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
        BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;

        IWICBitmapLock_GetDataPointer(lock, &size, &buffer);

        hdc = CreateCompatibleDC(0);

        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi->bmiHeader.biBitCount = 0;
        GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS);
        bmi->bmiHeader.biHeight = -bm.bmHeight;
        GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS);

        DeleteDC(hdc);
        IWICBitmapLock_Release(lock);

        if (num_palette_entries)
        {
            IWICPalette *palette;
            WICColor colors[256];
            UINT i;

            hr = PaletteImpl_Create(&palette);
            if (hr == S_OK)
            {
                for (i = 0; i < num_palette_entries; i++)
                    colors[i] = 0xff000000 | entry[i].peRed << 16 |
                                entry[i].peGreen << 8 | entry[i].peBlue;

                hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries);
                if (hr == S_OK)
                    hr = IWICBitmap_SetPalette(*bitmap, palette);

                IWICPalette_Release(palette);
            }
        }
    }

    if (hr != S_OK)
    {
        IWICBitmap_Release(*bitmap);
        *bitmap = NULL;
    }

    return hr;
}

static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface,
    HICON hicon, IWICBitmap **bitmap)
{
    IWICBitmapLock *lock;
    ICONINFO info;
    BITMAP bm;
    int width, height, x, y;
    UINT stride, size;
    BYTE *buffer;
    DWORD *bits;
    BITMAPINFO bi;
    HDC hdc;
    BOOL has_alpha;
    HRESULT hr;

    TRACE("(%p,%p,%p)\n", iface, hicon, bitmap);

    if (!bitmap) return E_INVALIDARG;

    if (!GetIconInfo(hicon, &info))
        return HRESULT_FROM_WIN32(GetLastError());

    GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm);

    width = bm.bmWidth;
    height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
    stride = width * 4;
    size = stride * height;

    hr = BitmapImpl_Create(width, height, stride, size, NULL,
                           &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap);
    if (hr != S_OK) goto failed;

    hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
    if (hr != S_OK)
    {
        IWICBitmap_Release(*bitmap);
        goto failed;
    }
    IWICBitmapLock_GetDataPointer(lock, &size, &buffer);

    hdc = CreateCompatibleDC(0);

    memset(&bi, 0, sizeof(bi));
    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    bi.bmiHeader.biWidth = width;
    bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;

    has_alpha = FALSE;

    if (info.hbmColor)
    {
        GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS);

        if (bm.bmBitsPixel == 32)
        {
            /* If any pixel has a non-zero alpha, ignore hbmMask */
            bits = (DWORD *)buffer;
            for (x = 0; x < width && !has_alpha; x++, bits++)
            {
                for (y = 0; y < height; y++)
                {
                    if (*bits & 0xff000000)
                    {
                        has_alpha = TRUE;
                        break;
                    }
                }
            }
        }
    }
    else
        GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS);

    if (!has_alpha)
    {
        DWORD *rgba;

        if (info.hbmMask)
        {
            BYTE *mask;

            mask = HeapAlloc(GetProcessHeap(), 0, size);
            if (!mask)
            {
                IWICBitmapLock_Release(lock);
                IWICBitmap_Release(*bitmap);
                DeleteDC(hdc);
                hr = E_OUTOFMEMORY;
                goto failed;
            }

            /* read alpha data from the mask */
            GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS);

            for (y = 0; y < height; y++)
            {
                rgba = (DWORD *)(buffer + y * stride);
                bits = (DWORD *)(mask + y * stride);

                for (x = 0; x < width; x++, rgba++, bits++)
                {
                    if (*bits)
                        *rgba = 0;
                    else
                        *rgba |= 0xff000000;
                }
            }

            HeapFree(GetProcessHeap(), 0, mask);
        }
        else
        {
            /* set constant alpha of 255 */
            for (y = 0; y < height; y++)
            {
                rgba = (DWORD *)(buffer + y * stride);
                for (x = 0; x < width; x++, rgba++)
                    *rgba |= 0xff000000;
            }
        }

    }

    IWICBitmapLock_Release(lock);
    DeleteDC(hdc);

failed:
    DeleteObject(info.hbmColor);
    DeleteObject(info.hbmMask);

    return hr;
}

static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *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 ComponentFactory_CreateFastMetadataEncoderFromDecoder(
    IWICComponentFactory *iface, IWICBitmapDecoder *pIDecoder,
    IWICFastMetadataEncoder **ppIFastEncoder)
{
    FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
    IWICComponentFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
    IWICFastMetadataEncoder **ppIFastEncoder)
{
    FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *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 ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *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 HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
        REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
{
    FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
        options, stream, reader);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
        REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
{
    HRESULT hr;
    IEnumUnknown *enumreaders;
    IUnknown *unkreaderinfo;
    IWICMetadataReaderInfo *readerinfo;
    IWICPersistStream *wicpersiststream;
    ULONG num_fetched;
    GUID decoder_vendor;
    BOOL matches;
    LARGE_INTEGER zero;

    TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
        options, stream, reader);

    if (!format || !stream || !reader)
        return E_INVALIDARG;

    zero.QuadPart = 0;

    hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders);
    if (FAILED(hr)) return hr;

    *reader = NULL;

start:
    while (!*reader)
    {
        hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched);

        if (hr == S_OK)
        {
            hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo);

            if (SUCCEEDED(hr))
            {
                if (vendor)
                {
                    hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor);

                    if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor))
                    {
                        IWICMetadataReaderInfo_Release(readerinfo);
                        IUnknown_Release(unkreaderinfo);
                        continue;
                    }
                }

                hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches);

                if (SUCCEEDED(hr) && matches)
                {
                    hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);

                    if (SUCCEEDED(hr))
                        hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader);

                    if (SUCCEEDED(hr))
                    {
                        hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);

                        if (SUCCEEDED(hr))
                        {
                            hr = IWICPersistStream_LoadEx(wicpersiststream,
                                stream, vendor, options & WICPersistOptionMask);

                            IWICPersistStream_Release(wicpersiststream);
                        }

                        if (FAILED(hr))
                        {
                            IWICMetadataReader_Release(*reader);
                            *reader = NULL;
                        }
                    }
                }

                IUnknown_Release(readerinfo);
            }

            IUnknown_Release(unkreaderinfo);
        }
        else
            break;
    }

    if (!*reader && vendor)
    {
        vendor = NULL;
        IEnumUnknown_Reset(enumreaders);
        goto start;
    }

    IEnumUnknown_Release(enumreaders);

    if (!*reader && !(options & WICMetadataCreationFailUnknown))
    {
        hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);

        if (SUCCEEDED(hr))
            hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader);

        if (SUCCEEDED(hr))
        {
            hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);

            if (SUCCEEDED(hr))
            {
                hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask);

                IWICPersistStream_Release(wicpersiststream);
            }

            if (FAILED(hr))
            {
                IWICMetadataReader_Release(*reader);
                *reader = NULL;
            }
        }
    }

    if (*reader)
        return S_OK;
    else
        return WINCODEC_ERR_COMPONENTNOTFOUND;
}

static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
        REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer)
{
    FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface,
        IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer)
{
    FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface,
        IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader)
{
    TRACE("%p,%p,%p\n", iface, block_reader, query_reader);

    if (!block_reader || !query_reader)
        return E_INVALIDARG;

    return MetadataQueryReader_CreateInstance(block_reader, NULL, query_reader);
}

static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface,
        IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer)
{
    FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer);
    return E_NOTIMPL;
}

static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface,
        PROPBAG2 *options, UINT count, IPropertyBag2 **property)
{
    TRACE("(%p,%p,%u,%p)\n", iface, options, count, property);
    return CreatePropertyBag2(options, count, property);
}

static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = {
    ComponentFactory_QueryInterface,
    ComponentFactory_AddRef,
    ComponentFactory_Release,
    ComponentFactory_CreateDecoderFromFilename,
    ComponentFactory_CreateDecoderFromStream,
    ComponentFactory_CreateDecoderFromFileHandle,
    ComponentFactory_CreateComponentInfo,
    ComponentFactory_CreateDecoder,
    ComponentFactory_CreateEncoder,
    ComponentFactory_CreatePalette,
    ComponentFactory_CreateFormatConverter,
    ComponentFactory_CreateBitmapScaler,
    ComponentFactory_CreateBitmapClipper,
    ComponentFactory_CreateBitmapFlipRotator,
    ComponentFactory_CreateStream,
    ComponentFactory_CreateColorContext,
    ComponentFactory_CreateColorTransformer,
    ComponentFactory_CreateBitmap,
    ComponentFactory_CreateBitmapFromSource,
    ComponentFactory_CreateBitmapFromSourceRect,
    ComponentFactory_CreateBitmapFromMemory,
    ComponentFactory_CreateBitmapFromHBITMAP,
    ComponentFactory_CreateBitmapFromHICON,
    ComponentFactory_CreateComponentEnumerator,
    ComponentFactory_CreateFastMetadataEncoderFromDecoder,
    ComponentFactory_CreateFastMetadataEncoderFromFrameDecode,
    ComponentFactory_CreateQueryWriter,
    ComponentFactory_CreateQueryWriterFromReader,
    ComponentFactory_CreateMetadataReader,
    ComponentFactory_CreateMetadataReaderFromContainer,
    ComponentFactory_CreateMetadataWriter,
    ComponentFactory_CreateMetadataWriterFromReader,
    ComponentFactory_CreateQueryReaderFromBlockReader,
    ComponentFactory_CreateQueryWriterFromBlockWriter,
    ComponentFactory_CreateEncoderPropertyBag
};

HRESULT ComponentFactory_CreateInstance(REFIID iid, void** ppv)
{
    ComponentFactory *This;
    HRESULT ret;

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

    *ppv = NULL;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory));
    if (!This) return E_OUTOFMEMORY;

    This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl;
    This->ref = 1;

    ret = IWICComponentFactory_QueryInterface(&This->IWICComponentFactory_iface, iid, ppv);
    IWICComponentFactory_Release(&This->IWICComponentFactory_iface);

    return ret;
}
