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

typedef struct {
    DWORD bc2Size;
    DWORD bc2Width;
    DWORD bc2Height;
    WORD  bc2Planes;
    WORD  bc2BitCount;
    DWORD bc2Compression;
    DWORD bc2SizeImage;
    DWORD bc2XRes;
    DWORD bc2YRes;
    DWORD bc2ClrUsed;
    DWORD bc2ClrImportant;
    /* same as BITMAPINFOHEADER until this point */
    WORD  bc2ResUnit;
    WORD  bc2Reserved;
    WORD  bc2Orientation;
    WORD  bc2Halftoning;
    DWORD bc2HalftoneSize1;
    DWORD bc2HalftoneSize2;
    DWORD bc2ColorSpace;
    DWORD bc2AppData;
} BITMAPCOREHEADER2;

struct BmpFrameDecode;
typedef HRESULT (*ReadDataFunc)(struct BmpFrameDecode* This);

typedef struct BmpFrameDecode {
    const IWICBitmapFrameDecodeVtbl *lpVtbl;
    LONG ref;
    IStream *stream;
    BITMAPFILEHEADER bfh;
    BITMAPV5HEADER bih;
    const WICPixelFormatGUID *pixelformat;
    int bitsperpixel;
    ReadDataFunc read_data_func;
    INT stride;
    BYTE *imagedata;
    BYTE *imagedatastart;
} BmpFrameDecode;

static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
    void **ppv)
{
    BmpFrameDecode *This = (BmpFrameDecode*)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 BmpFrameDecode_AddRef(IWICBitmapFrameDecode *iface)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI BmpFrameDecode_Release(IWICBitmapFrameDecode *iface)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        IStream_Release(This->stream);
        HeapFree(GetProcessHeap(), 0, This->imagedata);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
    UINT *puiWidth, UINT *puiHeight)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);

    if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
    {
        BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
        *puiWidth = bch->bcWidth;
        *puiHeight = bch->bcHeight;
    }
    else
    {
        *puiWidth = This->bih.bV5Width;
        *puiHeight = abs(This->bih.bV5Height);
    }
    return S_OK;
}

static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
    WICPixelFormatGUID *pPixelFormat)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    TRACE("(%p,%p)\n", iface, pPixelFormat);

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

    return S_OK;
}

static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, double *pDpiY)
{
    switch (bih->bV5Size)
    {
    case sizeof(BITMAPCOREHEADER):
        *pDpiX = 96.0;
        *pDpiY = 96.0;
        return S_OK;
    case sizeof(BITMAPCOREHEADER2):
    case sizeof(BITMAPINFOHEADER):
    case sizeof(BITMAPV4HEADER):
    case sizeof(BITMAPV5HEADER):
        *pDpiX = bih->bV5XPelsPerMeter * 0.0254;
        *pDpiY = bih->bV5YPelsPerMeter * 0.0254;
        return S_OK;
    default:
        return E_FAIL;
    }
}

static HRESULT WINAPI BmpFrameDecode_GetResolution(IWICBitmapFrameDecode *iface,
    double *pDpiX, double *pDpiY)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    TRACE("(%p,%p,%p)\n", iface, pDpiX, pDpiY);

    return BmpHeader_GetResolution(&This->bih, pDpiX, pDpiY);
}

static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
    IWICPalette *pIPalette)
{
    HRESULT hr;
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    int count;
    WICColor *wiccolors=NULL;
    RGBTRIPLE *bgrcolors=NULL;

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

    if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
    {
        BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
        if (bch->bcBitCount <= 8)
        {
            /* 2**n colors in BGR format after the header */
            ULONG tablesize, bytesread;
            LARGE_INTEGER offset;
            int i;

            count = 1 << bch->bcBitCount;
            wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count);
            tablesize = sizeof(RGBTRIPLE) * count;
            bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
            if (!wiccolors || !bgrcolors)
            {
                hr = E_OUTOFMEMORY;
                goto end;
            }

            offset.QuadPart = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER);
            hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
            if (FAILED(hr)) goto end;

            hr = IStream_Read(This->stream, bgrcolors, tablesize, &bytesread);
            if (FAILED(hr)) goto end;
            if (bytesread != tablesize) {
                hr = E_FAIL;
                goto end;
            }

            for (i=0; i<count; i++)
            {
                wiccolors[i] = 0xff000000|
                               (bgrcolors[i].rgbtRed<<16)|
                               (bgrcolors[i].rgbtGreen<<8)|
                               bgrcolors[i].rgbtBlue;
            }
        }
        else
        {
            return WINCODEC_ERR_PALETTEUNAVAILABLE;
        }
    }
    else
    {
        if (This->bih.bV5BitCount <= 8)
        {
            ULONG tablesize, bytesread;
            LARGE_INTEGER offset;
            int i;

            if (This->bih.bV5ClrUsed == 0)
                count = 1 << This->bih.bV5BitCount;
            else
                count = This->bih.bV5ClrUsed;

            tablesize = sizeof(WICColor) * count;
            wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize);
            if (!wiccolors) return E_OUTOFMEMORY;

            offset.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
            hr = IStream_Seek(This->stream, offset, STREAM_SEEK_SET, NULL);
            if (FAILED(hr)) goto end;

            hr = IStream_Read(This->stream, wiccolors, tablesize, &bytesread);
            if (FAILED(hr)) goto end;
            if (bytesread != tablesize) {
                hr = E_FAIL;
                goto end;
            }

            /* convert from BGR to BGRA by setting alpha to 100% */
            for (i=0; i<count; i++)
                wiccolors[i] |= 0xff000000;
        }
        else
        {
            return WINCODEC_ERR_PALETTEUNAVAILABLE;
        }
    }

    hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count);

end:
    HeapFree(GetProcessHeap(), 0, wiccolors);
    HeapFree(GetProcessHeap(), 0, bgrcolors);
    return hr;
}

static HRESULT WINAPI BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    BmpFrameDecode *This = (BmpFrameDecode*)iface;
    HRESULT hr;
    UINT width, height;
    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    if (!This->imagedata)
    {
        hr = This->read_data_func(This);
        if (FAILED(hr)) return hr;
    }

    hr = BmpFrameDecode_GetSize(iface, &width, &height);
    if (FAILED(hr)) return hr;

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

static HRESULT WINAPI BmpFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
    IWICMetadataQueryReader **ppIMetadataQueryReader)
{
    TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpFrameDecode_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 BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface,
    IWICBitmapSource **ppIThumbnail)
{
    TRACE("(%p,%p)\n", iface, ppIThumbnail);
    return WINCODEC_ERR_CODECNOTHUMBNAIL;
}

static HRESULT BmpFrameDecode_ReadUncompressed(BmpFrameDecode* This)
{
    UINT bytesperrow;
    UINT width, height;
    UINT datasize;
    int bottomup;
    HRESULT hr;
    LARGE_INTEGER offbits;
    ULONG bytesread;

    if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
    {
        BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
        width = bch->bcWidth;
        height = bch->bcHeight;
        bottomup = 1;
    }
    else
    {
        width = This->bih.bV5Width;
        height = abs(This->bih.bV5Height);
        bottomup = (This->bih.bV5Height > 0);
    }

    /* row sizes in BMP files must be divisible by 4 bytes */
    bytesperrow = (((width * This->bitsperpixel)+31)/32)*4;
    datasize = bytesperrow * height;

    This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
    if (!This->imagedata) return E_OUTOFMEMORY;

    offbits.QuadPart = This->bfh.bfOffBits;
    hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto fail;

    hr = IStream_Read(This->stream, This->imagedata, datasize, &bytesread);
    if (FAILED(hr) || bytesread != datasize) goto fail;

    if (bottomup)
    {
        This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
        This->stride = -bytesperrow;
    }
    else
    {
        This->imagedatastart = This->imagedata;
        This->stride = bytesperrow;
    }
    return S_OK;

fail:
    HeapFree(GetProcessHeap(), 0, This->imagedata);
    This->imagedata = NULL;
    if (SUCCEEDED(hr)) hr = E_FAIL;
    return hr;
}

static HRESULT BmpFrameDecode_ReadRLE8(BmpFrameDecode* This)
{
    UINT bytesperrow;
    UINT width, height;
    BYTE *rledata, *cursor, *rledataend;
    UINT rlesize, datasize, palettesize;
    DWORD palette[256];
    UINT x, y;
    DWORD *bgrdata;
    HRESULT hr;
    LARGE_INTEGER offbits;
    ULONG bytesread;

    width = This->bih.bV5Width;
    height = abs(This->bih.bV5Height);
    bytesperrow = width * 4;
    datasize = bytesperrow * height;
    rlesize = This->bih.bV5SizeImage;
    if (This->bih.bV5ClrUsed && This->bih.bV5ClrUsed < 256)
        palettesize = 4 * This->bih.bV5ClrUsed;
    else
        palettesize = 4 * 256;

    rledata = HeapAlloc(GetProcessHeap(), 0, rlesize);
    This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
    if (!This->imagedata || !rledata)
    {
        hr = E_OUTOFMEMORY;
        goto fail;
    }

    /* read palette */
    offbits.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
    hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto fail;

    hr = IStream_Read(This->stream, palette, palettesize, &bytesread);
    if (FAILED(hr) || bytesread != palettesize) goto fail;

    /* read RLE data */
    offbits.QuadPart = This->bfh.bfOffBits;
    hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto fail;

    hr = IStream_Read(This->stream, rledata, rlesize, &bytesread);
    if (FAILED(hr) || bytesread != rlesize) goto fail;

    /* decode RLE */
    bgrdata = (DWORD*)This->imagedata;
    x = 0;
    y = 0;
    rledataend = rledata + rlesize;
    cursor = rledata;
    while (cursor < rledataend && y < height)
    {
        BYTE length = *cursor++;
        if (length == 0)
        {
            /* escape code */
            BYTE escape = *cursor++;
            switch(escape)
            {
            case 0: /* end of line */
                x = 0;
                y++;
                break;
            case 1: /* end of bitmap */
                goto end;
            case 2: /* delta */
                if (cursor < rledataend)
                {
                    x += *cursor++;
                    y += *cursor++;
                }
                break;
            default: /* absolute mode */
                length = escape;
                while (cursor < rledataend && length-- && x < width)
                    bgrdata[y*width + x++] = palette[*cursor++];
                if (escape & 1) cursor++; /* skip pad byte */
            }
        }
        else
        {
            DWORD color = palette[*cursor++];
            while (length-- && x < width)
                bgrdata[y*width + x++] = color;
        }
    }

end:
    HeapFree(GetProcessHeap(), 0, rledata);

    This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
    This->stride = -bytesperrow;

    return S_OK;

fail:
    HeapFree(GetProcessHeap(), 0, rledata);
    HeapFree(GetProcessHeap(), 0, This->imagedata);
    This->imagedata = NULL;
    if (SUCCEEDED(hr)) hr = E_FAIL;
    return hr;
}

static HRESULT BmpFrameDecode_ReadRLE4(BmpFrameDecode* This)
{
    UINT bytesperrow;
    UINT width, height;
    BYTE *rledata, *cursor, *rledataend;
    UINT rlesize, datasize, palettesize;
    DWORD palette[16];
    UINT x, y;
    DWORD *bgrdata;
    HRESULT hr;
    LARGE_INTEGER offbits;
    ULONG bytesread;

    width = This->bih.bV5Width;
    height = abs(This->bih.bV5Height);
    bytesperrow = width * 4;
    datasize = bytesperrow * height;
    rlesize = This->bih.bV5SizeImage;
    if (This->bih.bV5ClrUsed && This->bih.bV5ClrUsed < 16)
        palettesize = 4 * This->bih.bV5ClrUsed;
    else
        palettesize = 4 * 16;

    rledata = HeapAlloc(GetProcessHeap(), 0, rlesize);
    This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize);
    if (!This->imagedata || !rledata)
    {
        hr = E_OUTOFMEMORY;
        goto fail;
    }

    /* read palette */
    offbits.QuadPart = sizeof(BITMAPFILEHEADER) + This->bih.bV5Size;
    hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto fail;

    hr = IStream_Read(This->stream, palette, palettesize, &bytesread);
    if (FAILED(hr) || bytesread != palettesize) goto fail;

    /* read RLE data */
    offbits.QuadPart = This->bfh.bfOffBits;
    hr = IStream_Seek(This->stream, offbits, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto fail;

    hr = IStream_Read(This->stream, rledata, rlesize, &bytesread);
    if (FAILED(hr) || bytesread != rlesize) goto fail;

    /* decode RLE */
    bgrdata = (DWORD*)This->imagedata;
    x = 0;
    y = 0;
    rledataend = rledata + rlesize;
    cursor = rledata;
    while (cursor < rledataend && y < height)
    {
        BYTE length = *cursor++;
        if (length == 0)
        {
            /* escape code */
            BYTE escape = *cursor++;
            switch(escape)
            {
            case 0: /* end of line */
                x = 0;
                y++;
                break;
            case 1: /* end of bitmap */
                goto end;
            case 2: /* delta */
                if (cursor < rledataend)
                {
                    x += *cursor++;
                    y += *cursor++;
                }
                break;
            default: /* absolute mode */
                length = escape;
                while (cursor < rledataend && length-- && x < width)
                {
                    BYTE colors = *cursor++;
                    bgrdata[y*width + x++] = palette[colors>>4];
                    if (length-- && x < width)
                        bgrdata[y*width + x++] = palette[colors&0xf];
                    else
                        break;
                }
                if ((cursor - rledata) & 1) cursor++; /* skip pad byte */
            }
        }
        else
        {
            BYTE colors = *cursor++;
            DWORD color1 = palette[colors>>4];
            DWORD color2 = palette[colors&0xf];
            while (length-- && x < width)
            {
                bgrdata[y*width + x++] = color1;
                if (length-- && x < width)
                    bgrdata[y*width + x++] = color2;
                else
                    break;
            }
        }
    }

end:
    HeapFree(GetProcessHeap(), 0, rledata);

    This->imagedatastart = This->imagedata + (height-1) * bytesperrow;
    This->stride = -bytesperrow;

    return S_OK;

fail:
    HeapFree(GetProcessHeap(), 0, rledata);
    HeapFree(GetProcessHeap(), 0, This->imagedata);
    This->imagedata = NULL;
    if (SUCCEEDED(hr)) hr = E_FAIL;
    return hr;
}

static HRESULT BmpFrameDecode_ReadUnsupported(BmpFrameDecode* This)
{
    return E_FAIL;
}

struct bitfields_format {
    WORD bitcount; /* 0 for end of list */
    DWORD redmask;
    DWORD greenmask;
    DWORD bluemask;
    DWORD alphamask;
    const WICPixelFormatGUID *pixelformat;
    ReadDataFunc read_data_func;
};

static const struct bitfields_format bitfields_formats[] = {
    {16,0x7c00,0x3e0,0x1f,0,&GUID_WICPixelFormat16bppBGR555,BmpFrameDecode_ReadUncompressed},
    {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed},
    {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed},
    {32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed},
    {0}
};

static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl = {
    BmpFrameDecode_QueryInterface,
    BmpFrameDecode_AddRef,
    BmpFrameDecode_Release,
    BmpFrameDecode_GetSize,
    BmpFrameDecode_GetPixelFormat,
    BmpFrameDecode_GetResolution,
    BmpFrameDecode_CopyPalette,
    BmpFrameDecode_CopyPixels,
    BmpFrameDecode_GetMetadataQueryReader,
    BmpFrameDecode_GetColorContexts,
    BmpFrameDecode_GetThumbnail
};

typedef struct {
    const IWICBitmapDecoderVtbl *lpVtbl;
    LONG ref;
    BOOL initialized;
    IStream *stream;
    BITMAPFILEHEADER bfh;
    BITMAPV5HEADER bih;
    BmpFrameDecode *framedecode;
    const WICPixelFormatGUID *pixelformat;
    int bitsperpixel;
    ReadDataFunc read_data_func;
} BmpDecoder;

static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
{
    HRESULT hr;
    ULONG bytestoread, bytesread;
    LARGE_INTEGER seek;

    if (This->initialized) return WINCODEC_ERR_WRONGSTATE;

    seek.QuadPart = 0;
    hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) return hr;

    hr = IStream_Read(stream, &This->bfh, sizeof(BITMAPFILEHEADER), &bytesread);
    if (FAILED(hr)) return hr;
    if (bytesread != sizeof(BITMAPFILEHEADER) ||
        This->bfh.bfType != 0x4d42 /* "BM" */) return E_FAIL;

    hr = IStream_Read(stream, &This->bih.bV5Size, sizeof(DWORD), &bytesread);
    if (FAILED(hr)) return hr;
    if (bytesread != sizeof(DWORD) ||
        (This->bih.bV5Size != sizeof(BITMAPCOREHEADER) &&
         This->bih.bV5Size != sizeof(BITMAPCOREHEADER2) &&
         This->bih.bV5Size != sizeof(BITMAPINFOHEADER) &&
         This->bih.bV5Size != sizeof(BITMAPV4HEADER) &&
         This->bih.bV5Size != sizeof(BITMAPV5HEADER))) return E_FAIL;

    bytestoread = This->bih.bV5Size-sizeof(DWORD);
    hr = IStream_Read(stream, &This->bih.bV5Width, bytestoread, &bytesread);
    if (FAILED(hr)) return hr;
    if (bytestoread != bytesread) return E_FAIL;

    /* if this is a BITMAPINFOHEADER with BI_BITFIELDS compression, we need to
        read the extra fields */
    if (This->bih.bV5Size == sizeof(BITMAPINFOHEADER) &&
        This->bih.bV5Compression == BI_BITFIELDS)
    {
        hr = IStream_Read(stream, &This->bih.bV5RedMask, 12, &bytesread);
        if (FAILED(hr)) return hr;
        if (bytesread != 12) return E_FAIL;
        This->bih.bV5AlphaMask = 0;
    }

    /* decide what kind of bitmap this is and how/if we can read it */
    if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
    {
        BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
        TRACE("BITMAPCOREHEADER with depth=%i\n", bch->bcBitCount);
        This->bitsperpixel = bch->bcBitCount;
        This->read_data_func = BmpFrameDecode_ReadUncompressed;
        switch(bch->bcBitCount)
        {
        case 1:
            This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
            break;
        case 2:
            This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
            break;
        case 4:
            This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
            break;
        case 8:
            This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
            break;
        case 24:
            This->pixelformat = &GUID_WICPixelFormat24bppBGR;
            break;
        default:
            This->pixelformat = &GUID_WICPixelFormatUndefined;
            WARN("unsupported bit depth %i for BITMAPCOREHEADER\n", bch->bcBitCount);
            break;
        }
    }
    else /* struct is compatible with BITMAPINFOHEADER */
    {
        TRACE("bitmap header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
        switch(This->bih.bV5Compression)
        {
        case BI_RGB:
            This->bitsperpixel = This->bih.bV5BitCount;
            This->read_data_func = BmpFrameDecode_ReadUncompressed;
            switch(This->bih.bV5BitCount)
            {
            case 1:
                This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
                break;
            case 2:
                This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
                break;
            case 4:
                This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
                break;
            case 8:
                This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
                break;
            case 16:
                This->pixelformat = &GUID_WICPixelFormat16bppBGR555;
                break;
            case 24:
                This->pixelformat = &GUID_WICPixelFormat24bppBGR;
                break;
            case 32:
                This->pixelformat = &GUID_WICPixelFormat32bppBGR;
                break;
            default:
                This->pixelformat = &GUID_WICPixelFormatUndefined;
                FIXME("unsupported bit depth %i for uncompressed RGB\n", This->bih.bV5BitCount);
            }
            break;
        case BI_RLE8:
            This->bitsperpixel = 32;
            This->read_data_func = BmpFrameDecode_ReadRLE8;
            This->pixelformat = &GUID_WICPixelFormat32bppBGR;
            break;
        case BI_RLE4:
            This->bitsperpixel = 32;
            This->read_data_func = BmpFrameDecode_ReadRLE4;
            This->pixelformat = &GUID_WICPixelFormat32bppBGR;
            break;
        case BI_BITFIELDS:
        {
            const struct bitfields_format *format;
            if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER2))
            {
                /* BCH2 doesn't support bitfields; this is Huffman 1D compression */
                This->bitsperpixel = 0;
                This->read_data_func = BmpFrameDecode_ReadUnsupported;
                This->pixelformat = &GUID_WICPixelFormatUndefined;
                FIXME("Huffman 1D compression is unsupported\n");
                break;
            }
            This->bitsperpixel = This->bih.bV5BitCount;
            for (format = bitfields_formats; format->bitcount; format++)
            {
                if ((format->bitcount == This->bih.bV5BitCount) &&
                    (format->redmask == This->bih.bV5RedMask) &&
                    (format->greenmask == This->bih.bV5GreenMask) &&
                    (format->bluemask == This->bih.bV5BlueMask) &&
                    (format->alphamask == This->bih.bV5AlphaMask))
                {
                    This->read_data_func = format->read_data_func;
                    This->pixelformat = format->pixelformat;
                    break;
                }
            }
            if (!format->bitcount)
            {
                This->read_data_func = BmpFrameDecode_ReadUncompressed;
                This->pixelformat = &GUID_WICPixelFormatUndefined;
                FIXME("unsupported bitfields type depth=%i red=%x green=%x blue=%x alpha=%x\n",
                    This->bih.bV5BitCount, This->bih.bV5RedMask, This->bih.bV5GreenMask, This->bih.bV5BlueMask, This->bih.bV5AlphaMask);
            }
            break;
        }
        default:
            This->bitsperpixel = 0;
            This->read_data_func = BmpFrameDecode_ReadUnsupported;
            This->pixelformat = &GUID_WICPixelFormatUndefined;
            FIXME("unsupported bitmap type header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
            break;
        }
    }

    This->initialized = TRUE;

    return S_OK;
}

static HRESULT WINAPI BmpDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
    void **ppv)
{
    BmpDecoder *This = (BmpDecoder*)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 BmpDecoder_AddRef(IWICBitmapDecoder *iface)
{
    BmpDecoder *This = (BmpDecoder*)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface)
{
    BmpDecoder *This = (BmpDecoder*)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->framedecode) IUnknown_Release((IUnknown*)This->framedecode);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BmpDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
    DWORD *pdwCapability)
{
    HRESULT hr;
    BmpDecoder *This = (BmpDecoder*)iface;

    hr = BmpDecoder_ReadHeaders(This, pIStream);
    if (FAILED(hr)) return hr;

    if (This->read_data_func == BmpFrameDecode_ReadUnsupported)
        *pdwCapability = 0;
    else
        *pdwCapability = WICBitmapDecoderCapabilityCanDecodeAllImages;

    return S_OK;
}

static HRESULT WINAPI BmpDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
    WICDecodeOptions cacheOptions)
{
    HRESULT hr;
    BmpDecoder *This = (BmpDecoder*)iface;

    hr = BmpDecoder_ReadHeaders(This, pIStream);

    if (SUCCEEDED(hr))
    {
        This->stream = pIStream;
        IStream_AddRef(pIStream);
    }

    return hr;
}

static HRESULT WINAPI BmpDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
    GUID *pguidContainerFormat)
{
    memcpy(pguidContainerFormat, &GUID_ContainerFormatBmp, sizeof(GUID));
    return S_OK;
}

static HRESULT WINAPI BmpDecoder_GetDecoderInfo(IWICBitmapDecoder *iface,
    IWICBitmapDecoderInfo **ppIDecoderInfo)
{
    HRESULT hr;
    IWICComponentInfo *compinfo;

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

    hr = CreateComponentInfo(&CLSID_WICBmpDecoder, &compinfo);
    if (FAILED(hr)) return hr;

    hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo,
        (void**)ppIDecoderInfo);

    IWICComponentInfo_Release(compinfo);

    return hr;
}

static HRESULT WINAPI BmpDecoder_CopyPalette(IWICBitmapDecoder *iface,
    IWICPalette *pIPalette)
{
    TRACE("(%p,%p)\n", iface, pIPalette);

    return WINCODEC_ERR_PALETTEUNAVAILABLE;
}

static HRESULT WINAPI BmpDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
    IWICMetadataQueryReader **ppIMetadataQueryReader)
{
    TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpDecoder_GetPreview(IWICBitmapDecoder *iface,
    IWICBitmapSource **ppIBitmapSource)
{
    TRACE("(%p,%p)\n", iface, ppIBitmapSource);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpDecoder_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 BmpDecoder_GetThumbnail(IWICBitmapDecoder *iface,
    IWICBitmapSource **ppIThumbnail)
{
    TRACE("(%p,%p)\n", iface, ppIThumbnail);
    return WINCODEC_ERR_CODECNOTHUMBNAIL;
}

static HRESULT WINAPI BmpDecoder_GetFrameCount(IWICBitmapDecoder *iface,
    UINT *pCount)
{
    *pCount = 1;
    return S_OK;
}

static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface,
    UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
    BmpDecoder *This = (BmpDecoder*)iface;

    if (index != 0) return E_INVALIDARG;

    if (!This->stream) return WINCODEC_ERR_WRONGSTATE;

    if (!This->framedecode)
    {
        This->framedecode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameDecode));
        if (!This->framedecode) return E_OUTOFMEMORY;

        This->framedecode->lpVtbl = &BmpFrameDecode_Vtbl;
        This->framedecode->ref = 1;
        This->framedecode->stream = This->stream;
        IStream_AddRef(This->stream);
        This->framedecode->bfh = This->bfh;
        This->framedecode->bih = This->bih;
        This->framedecode->pixelformat = This->pixelformat;
        This->framedecode->bitsperpixel = This->bitsperpixel;
        This->framedecode->read_data_func = This->read_data_func;
        This->framedecode->imagedata = NULL;
    }

    *ppIBitmapFrame = (IWICBitmapFrameDecode*)This->framedecode;
    IWICBitmapFrameDecode_AddRef((IWICBitmapFrameDecode*)This->framedecode);

    return S_OK;
}

static const IWICBitmapDecoderVtbl BmpDecoder_Vtbl = {
    BmpDecoder_QueryInterface,
    BmpDecoder_AddRef,
    BmpDecoder_Release,
    BmpDecoder_QueryCapability,
    BmpDecoder_Initialize,
    BmpDecoder_GetContainerFormat,
    BmpDecoder_GetDecoderInfo,
    BmpDecoder_CopyPalette,
    BmpDecoder_GetMetadataQueryReader,
    BmpDecoder_GetPreview,
    BmpDecoder_GetColorContexts,
    BmpDecoder_GetThumbnail,
    BmpDecoder_GetFrameCount,
    BmpDecoder_GetFrame
};

HRESULT BmpDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    BmpDecoder *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(BmpDecoder));
    if (!This) return E_OUTOFMEMORY;

    This->lpVtbl = &BmpDecoder_Vtbl;
    This->ref = 1;
    This->initialized = FALSE;
    This->stream = NULL;
    This->framedecode = NULL;

    ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
    IUnknown_Release((IUnknown*)This);

    return ret;
}
