/*
 * Copyright 2010 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 "wine/port.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"
#include "wine/library.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

#include "pshpack1.h"

typedef struct {
    BYTE id_length;
    BYTE colormap_type;
    BYTE image_type;
    /* Colormap Specification */
    WORD colormap_firstentry;
    WORD colormap_length;
    BYTE colormap_entrysize;
    /* Image Specification */
    WORD xorigin;
    WORD yorigin;
    WORD width;
    WORD height;
    BYTE depth;
    BYTE image_descriptor;
} tga_header;

#define IMAGETYPE_COLORMAPPED 1
#define IMAGETYPE_TRUECOLOR 2
#define IMAGETYPE_GRAYSCALE 3
#define IMAGETYPE_RLE 8

#define IMAGE_ATTRIBUTE_BITCOUNT_MASK 0xf
#define IMAGE_RIGHTTOLEFT 0x10
#define IMAGE_TOPTOBOTTOM 0x20

typedef struct {
    DWORD extension_area_offset;
    DWORD developer_directory_offset;
    char magic[18];
} tga_footer;

static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";

typedef struct {
    WORD size;
    char author_name[41];
    char author_comments[324];
    WORD timestamp[6];
    char job_name[41];
    WORD job_timestamp[6];
    char software_id[41];
    WORD software_version;
    char software_version_letter;
    DWORD key_color;
    WORD pixel_width;
    WORD pixel_height;
    WORD gamma_numerator;
    WORD gamma_denominator;
    DWORD color_correction_offset;
    DWORD thumbnail_offset;
    DWORD scanline_offset;
    BYTE attributes_type;
} tga_extension_area;

#define ATTRIBUTE_NO_ALPHA 0
#define ATTRIBUTE_UNDEFINED 1
#define ATTRIBUTE_UNDEFINED_PRESERVE 2
#define ATTRIBUTE_ALPHA 3
#define ATTRIBUTE_PALPHA 4

#include "poppack.h"

typedef struct {
    IWICBitmapDecoder IWICBitmapDecoder_iface;
    IWICBitmapFrameDecode IWICBitmapFrameDecode_iface;
    LONG ref;
    BOOL initialized;
    IStream *stream;
    tga_header header;
    tga_extension_area extension_area;
    BYTE *imagebits;
    BYTE *origin;
    int stride;
    ULONG id_offset;
    ULONG colormap_length;
    ULONG colormap_offset;
    ULONG image_offset;
    ULONG extension_area_offset;
    ULONG developer_directory_offset;
    CRITICAL_SECTION lock;
} TgaDecoder;

static inline TgaDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
{
    return CONTAINING_RECORD(iface, TgaDecoder, IWICBitmapDecoder_iface);
}

static inline TgaDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface)
{
    return CONTAINING_RECORD(iface, TgaDecoder, IWICBitmapFrameDecode_iface);
}

static HRESULT WINAPI TgaDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid,
    void **ppv)
{
    TgaDecoder *This = impl_from_IWICBitmapDecoder(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->IWICBitmapDecoder_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI TgaDecoder_AddRef(IWICBitmapDecoder *iface)
{
    TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface)
{
    TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        if (This->stream)
            IStream_Release(This->stream);
        HeapFree(GetProcessHeap(), 0, This->imagebits);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI TgaDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *pIStream,
    DWORD *pdwCapability)
{
    FIXME("(%p,%p,%p): stub\n", iface, pIStream, pdwCapability);
    return E_NOTIMPL;
}

static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
    WICDecodeOptions cacheOptions)
{
    TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
    HRESULT hr=S_OK;
    DWORD bytesread;
    LARGE_INTEGER seek;
    tga_footer footer;
    int attribute_bitcount;
    int mapped_depth=0;

    TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);

    EnterCriticalSection(&This->lock);

    if (This->initialized)
    {
        hr = WINCODEC_ERR_WRONGSTATE;
        goto end;
    }

    seek.QuadPart = 0;
    hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) goto end;

    hr = IStream_Read(pIStream, &This->header, sizeof(tga_header), &bytesread);
    if (SUCCEEDED(hr) && bytesread != sizeof(tga_header))
    {
        TRACE("got only %u bytes\n", bytesread);
        hr = E_FAIL;
    }
    if (FAILED(hr)) goto end;

    TRACE("imagetype=%u, colormap type=%u, depth=%u, image descriptor=0x%x\n",
        This->header.image_type, This->header.colormap_type,
        This->header.depth, This->header.image_descriptor);

    /* Sanity checking. Since TGA has no clear identifying markers, we need
     * to be careful to not load a non-TGA image. */
    switch (This->header.image_type)
    {
    case IMAGETYPE_COLORMAPPED:
    case IMAGETYPE_COLORMAPPED|IMAGETYPE_RLE:
        if (This->header.colormap_type != 1)
            hr = E_FAIL;
        mapped_depth = This->header.colormap_entrysize;
        break;
    case IMAGETYPE_TRUECOLOR:
    case IMAGETYPE_TRUECOLOR|IMAGETYPE_RLE:
        if (This->header.colormap_type != 0 && This->header.colormap_type != 1)
            hr = E_FAIL;
        mapped_depth = This->header.depth;
        break;
    case IMAGETYPE_GRAYSCALE:
    case IMAGETYPE_GRAYSCALE|IMAGETYPE_RLE:
        if (This->header.colormap_type != 0)
            hr = E_FAIL;
        mapped_depth = 0;
        break;
    default:
        hr = E_FAIL;
    }

    if (This->header.depth != 8 && This->header.depth != 16 &&
        This->header.depth != 24 && This->header.depth != 32)
        hr = E_FAIL;

    if ((This->header.image_descriptor & 0xc0) != 0)
        hr = E_FAIL;

    attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;

    if (attribute_bitcount &&
        !((mapped_depth == 32 && attribute_bitcount == 8) ||
          (mapped_depth == 16 && attribute_bitcount == 1)))
        hr = E_FAIL;

    if (FAILED(hr))
    {
        WARN("bad tga header\n");
        goto end;
    }

    /* Locate data in the file based on the header. */
    This->id_offset = sizeof(tga_header);
    This->colormap_offset = This->id_offset + This->header.id_length;
    if (This->header.colormap_type == 1)
        This->colormap_length = ((This->header.colormap_entrysize+7)/8) * This->header.colormap_length;
    else
        This->colormap_length = 0;
    This->image_offset = This->colormap_offset + This->colormap_length;

    /* Read footer if there is one */
    seek.QuadPart = -sizeof(tga_footer);
    hr = IStream_Seek(pIStream, seek, STREAM_SEEK_END, NULL);

    if (SUCCEEDED(hr)) {
        hr = IStream_Read(pIStream, &footer, sizeof(tga_footer), &bytesread);
        if (SUCCEEDED(hr) && bytesread != sizeof(tga_footer))
        {
            TRACE("got only %u footer bytes\n", bytesread);
            hr = E_FAIL;
        }

        if (memcmp(footer.magic, tga_footer_magic, sizeof(tga_footer_magic)) == 0)
        {
            This->extension_area_offset = footer.extension_area_offset;
            This->developer_directory_offset = footer.developer_directory_offset;
        }
        else
        {
            This->extension_area_offset = 0;
            This->developer_directory_offset = 0;
        }
    }
    else
    {
        /* File is too small to have a footer. */
        This->extension_area_offset = 0;
        This->developer_directory_offset = 0;
        hr = S_OK;
    }

    if (This->extension_area_offset)
    {
        seek.QuadPart = This->extension_area_offset;
        hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
        if (FAILED(hr)) goto end;

        hr = IStream_Read(pIStream, &This->extension_area, sizeof(tga_extension_area), &bytesread);
        if (SUCCEEDED(hr) && bytesread != sizeof(tga_extension_area))
        {
            TRACE("got only %u extension area bytes\n", bytesread);
            hr = E_FAIL;
        }
        if (SUCCEEDED(hr) && This->extension_area.size < 495)
        {
            TRACE("extension area is only %u bytes long\n", This->extension_area.size);
            hr = E_FAIL;
        }
        if (FAILED(hr)) goto end;
    }

    IStream_AddRef(pIStream);
    This->stream = pIStream;
    This->initialized = TRUE;

end:
    LeaveCriticalSection(&This->lock);
    return hr;
}

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

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

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

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

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

    IWICComponentInfo_Release(compinfo);

    return hr;
}

static HRESULT WINAPI TgaDecoder_CopyPalette(IWICBitmapDecoder *iface,
    IWICPalette *pIPalette)
{
    FIXME("(%p,%p): stub\n", iface, pIPalette);
    return E_NOTIMPL;
}

static HRESULT WINAPI TgaDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface,
    IWICMetadataQueryReader **ppIMetadataQueryReader)
{
    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
    return E_NOTIMPL;
}

static HRESULT WINAPI TgaDecoder_GetPreview(IWICBitmapDecoder *iface,
    IWICBitmapSource **ppIBitmapSource)
{
    FIXME("(%p,%p): stub\n", iface, ppIBitmapSource);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI TgaDecoder_GetColorContexts(IWICBitmapDecoder *iface,
    UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI TgaDecoder_GetThumbnail(IWICBitmapDecoder *iface,
    IWICBitmapSource **ppIThumbnail)
{
    FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
    return WINCODEC_ERR_CODECNOTHUMBNAIL;
}

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

static HRESULT WINAPI TgaDecoder_GetFrame(IWICBitmapDecoder *iface,
    UINT index, IWICBitmapFrameDecode **ppIBitmapFrame)
{
    TgaDecoder *This = impl_from_IWICBitmapDecoder(iface);
    TRACE("(%p,%p)\n", iface, ppIBitmapFrame);

    if (!This->initialized) return WINCODEC_ERR_NOTINITIALIZED;

    if (index != 0) return E_INVALIDARG;

    IWICBitmapDecoder_AddRef(iface);
    *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface;

    return S_OK;
}

static const IWICBitmapDecoderVtbl TgaDecoder_Vtbl = {
    TgaDecoder_QueryInterface,
    TgaDecoder_AddRef,
    TgaDecoder_Release,
    TgaDecoder_QueryCapability,
    TgaDecoder_Initialize,
    TgaDecoder_GetContainerFormat,
    TgaDecoder_GetDecoderInfo,
    TgaDecoder_CopyPalette,
    TgaDecoder_GetMetadataQueryReader,
    TgaDecoder_GetPreview,
    TgaDecoder_GetColorContexts,
    TgaDecoder_GetThumbnail,
    TgaDecoder_GetFrameCount,
    TgaDecoder_GetFrame
};

static HRESULT WINAPI TgaDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
    void **ppv)
{
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICBitmapSource, iid) ||
        IsEqualIID(&IID_IWICBitmapFrameDecode, iid))
    {
        *ppv = iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI TgaDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
    return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface);
}

static ULONG WINAPI TgaDecoder_Frame_Release(IWICBitmapFrameDecode *iface)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
    return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);
}

static HRESULT WINAPI TgaDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface,
    UINT *puiWidth, UINT *puiHeight)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);

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

    TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight);

    return S_OK;
}

static HRESULT WINAPI TgaDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface,
    WICPixelFormatGUID *pPixelFormat)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
    int attribute_bitcount;
    byte attribute_type;

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

    attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;

    if (attribute_bitcount && This->extension_area_offset)
        attribute_type = This->extension_area.attributes_type;
    else if (attribute_bitcount)
        attribute_type = ATTRIBUTE_ALPHA;
    else
        attribute_type = ATTRIBUTE_NO_ALPHA;

    switch (This->header.image_type & ~IMAGETYPE_RLE)
    {
    case IMAGETYPE_COLORMAPPED:
        switch (This->header.depth)
        {
        case 8:
            memcpy(pPixelFormat, &GUID_WICPixelFormat8bppIndexed, sizeof(GUID));
            break;
        default:
            FIXME("Unhandled indexed color depth %u\n", This->header.depth);
            return E_NOTIMPL;
        }
        break;
    case IMAGETYPE_TRUECOLOR:
        switch (This->header.depth)
        {
        case 16:
            switch (attribute_type)
            {
            case ATTRIBUTE_NO_ALPHA:
            case ATTRIBUTE_UNDEFINED:
            case ATTRIBUTE_UNDEFINED_PRESERVE:
                memcpy(pPixelFormat, &GUID_WICPixelFormat16bppBGR555, sizeof(GUID));
                break;
            case ATTRIBUTE_ALPHA:
            case ATTRIBUTE_PALPHA:
                memcpy(pPixelFormat, &GUID_WICPixelFormat16bppBGRA5551, sizeof(GUID));
                break;
            default:
                FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
                return E_NOTIMPL;
            }
            break;
        case 24:
            memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID));
            break;
        case 32:
            switch (attribute_type)
            {
            case ATTRIBUTE_NO_ALPHA:
            case ATTRIBUTE_UNDEFINED:
            case ATTRIBUTE_UNDEFINED_PRESERVE:
                memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGR, sizeof(GUID));
                break;
            case ATTRIBUTE_ALPHA:
                memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
                break;
            case ATTRIBUTE_PALPHA:
                memcpy(pPixelFormat, &GUID_WICPixelFormat32bppPBGRA, sizeof(GUID));
                break;
            default:
                FIXME("Unhandled 32-bit attribute type %u\n", attribute_type);
                return E_NOTIMPL;
            }
            break;
        default:
            FIXME("Unhandled truecolor depth %u\n", This->header.depth);
            return E_NOTIMPL;
        }
        break;
    case IMAGETYPE_GRAYSCALE:
        switch (This->header.depth)
        {
        case 8:
            memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID));
            break;
        case 16:
            memcpy(pPixelFormat, &GUID_WICPixelFormat16bppGray, sizeof(GUID));
            break;
        default:
            FIXME("Unhandled grayscale depth %u\n", This->header.depth);
            return E_NOTIMPL;
        }
        break;
    default:
        ERR("Unknown image type %u\n", This->header.image_type);
        return E_FAIL;
    }

    return S_OK;
}

static HRESULT WINAPI TgaDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface,
    double *pDpiX, double *pDpiY)
{
    FIXME("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
    return E_NOTIMPL;
}

static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
    IWICPalette *pIPalette)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
    HRESULT hr=S_OK;
    WICColor colors[256], *color;
    BYTE *colormap_data;
    WORD *wcolormap_data;
    DWORD *dwcolormap_data;
    LARGE_INTEGER seek;
    ULONG bytesread;
    int depth, attribute_bitcount, attribute_type;
    int i;

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

    if (!This->colormap_length)
    {
        WARN("no colormap present in this file\n");
        return WINCODEC_ERR_PALETTEUNAVAILABLE;
    }

    if (This->header.colormap_firstentry + This->header.colormap_length > 256)
    {
        FIXME("cannot read colormap with %i entries starting at %i\n",
            This->header.colormap_firstentry + This->header.colormap_length,
            This->header.colormap_firstentry);
        return E_FAIL;
    }

    colormap_data = HeapAlloc(GetProcessHeap(), 0, This->colormap_length);
    if (!colormap_data) return E_OUTOFMEMORY;

    wcolormap_data = (WORD*)colormap_data;
    dwcolormap_data = (DWORD*)colormap_data;

    EnterCriticalSection(&This->lock);

    seek.QuadPart = This->colormap_offset;
    hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL);

    if (SUCCEEDED(hr))
    {
        hr = IStream_Read(This->stream, colormap_data, This->colormap_length, &bytesread);
        if (SUCCEEDED(hr) && bytesread != This->colormap_length)
        {
            WARN("expected %i bytes in colormap, got %i\n", This->colormap_length, bytesread);
            hr = E_FAIL;
        }
    }

    LeaveCriticalSection(&This->lock);

    if (SUCCEEDED(hr))
    {
        attribute_bitcount = This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK;

        if (attribute_bitcount && This->extension_area_offset)
            attribute_type = This->extension_area.attributes_type;
        else if (attribute_bitcount)
            attribute_type = ATTRIBUTE_ALPHA;
        else
            attribute_type = ATTRIBUTE_NO_ALPHA;

        depth = This->header.colormap_entrysize;
        if (depth == 15)
        {
            depth = 16;
            attribute_type = ATTRIBUTE_NO_ALPHA;
        }

        memset(colors, 0, sizeof(colors));

        color = &colors[This->header.colormap_firstentry];

        /* Colormap entries can be in any truecolor format, and we have to convert them. */
        switch (depth)
        {
        case 16:
            switch (attribute_type)
            {
            case ATTRIBUTE_NO_ALPHA:
            case ATTRIBUTE_UNDEFINED:
            case ATTRIBUTE_UNDEFINED_PRESERVE:
                for (i=0; i<This->header.colormap_length; i++)
                {
                    WORD srcval = wcolormap_data[i];
                    *color++=0xff000000 | /* constant 255 alpha */
                             ((srcval << 9) & 0xf80000) | /* r */
                             ((srcval << 4) & 0x070000) | /* r - 3 bits */
                             ((srcval << 6) & 0x00f800) | /* g */
                             ((srcval << 1) & 0x000700) | /* g - 3 bits */
                             ((srcval << 3) & 0x0000f8) | /* b */
                             ((srcval >> 2) & 0x000007);  /* b - 3 bits */
                }
                break;
            case ATTRIBUTE_ALPHA:
            case ATTRIBUTE_PALPHA:
                for (i=0; i<This->header.colormap_length; i++)
                {
                    WORD srcval = wcolormap_data[i];
                    *color++=((srcval & 0x8000) ? 0xff000000 : 0) | /* alpha */
                             ((srcval << 9) & 0xf80000) | /* r */
                             ((srcval << 4) & 0x070000) | /* r - 3 bits */
                             ((srcval << 6) & 0x00f800) | /* g */
                             ((srcval << 1) & 0x000700) | /* g - 3 bits */
                             ((srcval << 3) & 0x0000f8) | /* b */
                             ((srcval >> 2) & 0x000007);  /* b - 3 bits */
                }
                break;
            default:
                FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
                hr = E_NOTIMPL;
            }
            break;
        case 24:
            for (i=0; i<This->header.colormap_length; i++)
            {
                *color++=0xff000000 | /* alpha */
                         colormap_data[i*3+2] | /* red */
                         colormap_data[i*3+1] | /* green */
                         colormap_data[i*3]; /* blue */
            }
            break;
        case 32:
            switch (attribute_type)
            {
            case ATTRIBUTE_NO_ALPHA:
            case ATTRIBUTE_UNDEFINED:
            case ATTRIBUTE_UNDEFINED_PRESERVE:
                for (i=0; i<This->header.colormap_length; i++)
                    *color++=dwcolormap_data[i]|0xff000000;
                break;
            case ATTRIBUTE_ALPHA:
                for (i=0; i<This->header.colormap_length; i++)
                    *color++=dwcolormap_data[i];
                break;
            case ATTRIBUTE_PALPHA:
                /* FIXME: Unpremultiply alpha */
            default:
                FIXME("Unhandled 16-bit attribute type %u\n", attribute_type);
                hr = E_NOTIMPL;
            }
            break;
        default:
            FIXME("Unhandled truecolor depth %u\n", This->header.depth);
            hr = E_NOTIMPL;
        }
    }

    HeapFree(GetProcessHeap(), 0, colormap_data);

    if (SUCCEEDED(hr))
        hr = IWICPalette_InitializeCustom(pIPalette, colors, 256);

    return hr;
}

static HRESULT TgaDecoder_ReadRLE(TgaDecoder *This, BYTE *imagebits, int datasize)
{
    int i=0, j, bytesperpixel;
    ULONG bytesread;
    HRESULT hr=S_OK;

    bytesperpixel = This->header.depth / 8;

    while (i<datasize)
    {
        BYTE rc;
        int count, size;
        BYTE pixeldata[4];

        hr = IStream_Read(This->stream, &rc, 1, &bytesread);
        if (bytesread != 1) hr = E_FAIL;
        if (FAILED(hr)) break;

        count = (rc&0x7f)+1;
        size = count * bytesperpixel;

        if (size + i > datasize)
        {
            WARN("RLE packet too large\n");
            hr = E_FAIL;
            break;
        }

        if (rc&0x80)
        {
            /* Run-length packet */
            hr = IStream_Read(This->stream, pixeldata, bytesperpixel, &bytesread);
            if (bytesread != bytesperpixel) hr = E_FAIL;
            if (FAILED(hr)) break;

            if (bytesperpixel == 1)
                memset(&imagebits[i], pixeldata[0], count);
            else
            {
                for (j=0; j<count; j++)
                    memcpy(&imagebits[i+j*bytesperpixel], pixeldata, bytesperpixel);
            }
        }
        else
        {
            /* Raw packet */
            hr = IStream_Read(This->stream, &imagebits[i], size, &bytesread);
            if (bytesread != size) hr = E_FAIL;
            if (FAILED(hr)) break;
        }

        i += size;
    }

    return hr;
}

static HRESULT TgaDecoder_ReadImage(TgaDecoder *This)
{
    HRESULT hr=S_OK;
    int datasize;
    LARGE_INTEGER seek;
    ULONG bytesread;

    if (This->imagebits)
        return S_OK;

    EnterCriticalSection(&This->lock);

    if (!This->imagebits)
    {
        if (This->header.image_descriptor & IMAGE_RIGHTTOLEFT)
        {
            FIXME("Right to left image reading not implemented\n");
            hr = E_NOTIMPL;
        }

        if (SUCCEEDED(hr))
        {
            datasize = This->header.width * This->header.height * (This->header.depth / 8);
            This->imagebits = HeapAlloc(GetProcessHeap(), 0, datasize);
            if (!This->imagebits) hr = E_OUTOFMEMORY;
        }

        if (SUCCEEDED(hr))
        {
            seek.QuadPart = This->image_offset;
            hr = IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL);
        }

        if (SUCCEEDED(hr))
        {
            if (This->header.image_type & IMAGETYPE_RLE)
            {
                hr = TgaDecoder_ReadRLE(This, This->imagebits, datasize);
            }
            else
            {
                hr = IStream_Read(This->stream, This->imagebits, datasize, &bytesread);
                if (SUCCEEDED(hr) && bytesread != datasize)
                    hr = E_FAIL;
            }
        }

        if (SUCCEEDED(hr))
        {
            if (This->header.image_descriptor & IMAGE_TOPTOBOTTOM)
            {
                This->origin = This->imagebits;
                This->stride = This->header.width * (This->header.depth / 8);
            }
            else
            {
                This->stride = -This->header.width * (This->header.depth / 8);
                This->origin = This->imagebits + This->header.width * (This->header.height - 1) * (This->header.depth / 8);
            }
        }
        else
        {
            HeapFree(GetProcessHeap(), 0, This->imagebits);
            This->imagebits = NULL;
        }
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI TgaDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface,
    const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
{
    TgaDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
    HRESULT hr;

    TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);

    hr = TgaDecoder_ReadImage(This);

    if (SUCCEEDED(hr))
    {
        hr = copy_pixels(This->header.depth, This->origin,
            This->header.width, This->header.height, This->stride,
            prc, cbStride, cbBufferSize, pbBuffer);
    }

    return hr;
}

static HRESULT WINAPI TgaDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
    IWICMetadataQueryReader **ppIMetadataQueryReader)
{
    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryReader);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI TgaDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface,
    UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI TgaDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface,
    IWICBitmapSource **ppIThumbnail)
{
    FIXME("(%p,%p): stub\n", iface, ppIThumbnail);
    return WINCODEC_ERR_CODECNOTHUMBNAIL;
}

static const IWICBitmapFrameDecodeVtbl TgaDecoder_Frame_Vtbl = {
    TgaDecoder_Frame_QueryInterface,
    TgaDecoder_Frame_AddRef,
    TgaDecoder_Frame_Release,
    TgaDecoder_Frame_GetSize,
    TgaDecoder_Frame_GetPixelFormat,
    TgaDecoder_Frame_GetResolution,
    TgaDecoder_Frame_CopyPalette,
    TgaDecoder_Frame_CopyPixels,
    TgaDecoder_Frame_GetMetadataQueryReader,
    TgaDecoder_Frame_GetColorContexts,
    TgaDecoder_Frame_GetThumbnail
};

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

    This->IWICBitmapDecoder_iface.lpVtbl = &TgaDecoder_Vtbl;
    This->IWICBitmapFrameDecode_iface.lpVtbl = &TgaDecoder_Frame_Vtbl;
    This->ref = 1;
    This->initialized = FALSE;
    This->stream = NULL;
    This->imagebits = NULL;
    InitializeCriticalSection(&This->lock);
    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TgaDecoder.lock");

    ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv);
    IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface);

    return ret;
}
