/*
 * Copyright 2009 Tony Wasserka
 * Copyright 2010 Christian Costa
 * Copyright 2010 Owen Rudge for CodeWeavers
 * Copyright 2010 Matteo Bruni 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 "wine/unicode.h"
#include "wine/debug.h"
#include "d3dx9_36_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3dx);

/* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
static BOOL is_pow2(UINT num)
{
    return !(num & (num - 1));
}

/* Returns the smallest power of 2 which is greater than or equal to num */
static UINT make_pow2(UINT num)
{
    UINT result = 1;

    /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
    if (num >= 0x80000000)
        return 0x80000000;

    while (result < num)
        result <<= 1;

    return result;
}

static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex,
        int face, UINT level, struct IDirect3DSurface9 **surf)
{
    switch (type)
    {
        case D3DRTYPE_TEXTURE:
            return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf);
        case D3DRTYPE_CUBETEXTURE:
            return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf);
        default:
            ERR("Unexpected texture type\n");
            return E_NOTIMPL;
    }
}

HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9 *texture,
                                 const PALETTEENTRY *palette,
                                 UINT srclevel,
                                 DWORD filter)
{
    UINT level;
    HRESULT hr;
    D3DRESOURCETYPE type;

    TRACE("(%p, %p, %u, %#x)\n", texture, palette, srclevel, filter);

    if (!texture)
        return D3DERR_INVALIDCALL;

    if ((filter & 0xFFFF) > D3DX_FILTER_BOX && filter != D3DX_DEFAULT)
        return D3DERR_INVALIDCALL;

    if (srclevel == D3DX_DEFAULT)
        srclevel = 0;
    else if (srclevel >= IDirect3DBaseTexture9_GetLevelCount(texture))
        return D3DERR_INVALIDCALL;

    switch (type = IDirect3DBaseTexture9_GetType(texture))
    {
        case D3DRTYPE_TEXTURE:
        case D3DRTYPE_CUBETEXTURE:
        {
            IDirect3DSurface9 *topsurf, *mipsurf;
            D3DSURFACE_DESC desc;
            int i, numfaces;

            if (type == D3DRTYPE_TEXTURE)
            {
                numfaces = 1;
                IDirect3DTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
            }
            else
            {
                numfaces = 6;
                IDirect3DCubeTexture9_GetLevelDesc((IDirect3DTexture9*) texture, srclevel, &desc);
            }

            if (filter == D3DX_DEFAULT)
            {
                if (is_pow2(desc.Width) && is_pow2(desc.Height))
                    filter = D3DX_FILTER_BOX;
                else
                    filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
            }

            for (i = 0; i < numfaces; i++)
            {
                level = srclevel + 1;
                hr = get_surface(type, texture, i, srclevel, &topsurf);

                if (FAILED(hr))
                    return D3DERR_INVALIDCALL;

                while (get_surface(type, texture, i, level, &mipsurf) == D3D_OK)
                {
                    hr = D3DXLoadSurfaceFromSurface(mipsurf, palette, NULL, topsurf, palette, NULL, filter, 0);
                    IDirect3DSurface9_Release(topsurf);
                    topsurf = mipsurf;

                    if (FAILED(hr))
                        break;

                    level++;
                }

                IDirect3DSurface9_Release(topsurf);
                if (FAILED(hr))
                    return hr;
            }

            return D3D_OK;
        }

        case D3DRTYPE_VOLUMETEXTURE:
        {
            D3DVOLUME_DESC desc;
            int level, level_count;
            IDirect3DVolume9 *top_volume, *mip_volume;
            IDirect3DVolumeTexture9 *volume_texture = (IDirect3DVolumeTexture9*) texture;

            IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, srclevel, &desc);

            if (filter == D3DX_DEFAULT)
            {
                if (is_pow2(desc.Width) && is_pow2(desc.Height) && is_pow2(desc.Depth))
                    filter = D3DX_FILTER_BOX;
                else
                    filter = D3DX_FILTER_BOX | D3DX_FILTER_DITHER;
            }

            hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, srclevel, &top_volume);
            if (FAILED(hr))
                return hr;

            level_count = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
            for (level = srclevel + 1; level < level_count; level++)
            {
                IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, level, &mip_volume);
                hr = D3DXLoadVolumeFromVolume(mip_volume, palette, NULL, top_volume, palette, NULL, filter, 0);
                IDirect3DVolume9_Release(top_volume);
                top_volume = mip_volume;

                if (FAILED(hr))
                    break;
            }

            IDirect3DVolume9_Release(top_volume);
            if (FAILED(hr))
                return hr;

            return D3D_OK;
        }

        default:
            return D3DERR_INVALIDCALL;
    }
}

HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UINT *width, UINT *height,
        UINT *miplevels, DWORD usage, D3DFORMAT *format, D3DPOOL pool)
{
    UINT w = (width && *width) ? *width : 1;
    UINT h = (height && *height) ? *height : 1;
    D3DCAPS9 caps;
    D3DDEVICE_CREATION_PARAMETERS params;
    IDirect3D9 *d3d = NULL;
    D3DDISPLAYMODE mode;
    HRESULT hr;
    D3DFORMAT usedformat = D3DFMT_UNKNOWN;
    const struct pixel_format_desc *fmt;

    TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);

    if (!device)
        return D3DERR_INVALIDCALL;

    /* usage */
    if (usage == D3DX_DEFAULT)
        usage = 0;
    if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
        return D3DERR_INVALIDCALL;

    /* pool */
    if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
        return D3DERR_INVALIDCALL;

    /* format */
    if (format)
    {
        TRACE("Requested format %x\n", *format);
        usedformat = *format;
    }

    hr = IDirect3DDevice9_GetDirect3D(device, &d3d);

    if (FAILED(hr))
        goto cleanup;

    hr = IDirect3DDevice9_GetCreationParameters(device, &params);

    if (FAILED(hr))
        goto cleanup;

    hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);

    if (FAILED(hr))
        goto cleanup;

    if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
        usedformat = D3DFMT_A8R8G8B8;

    fmt = get_format_info(usedformat);

    hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
        usage, D3DRTYPE_TEXTURE, usedformat);
    if (FAILED(hr))
    {
        BOOL allow_24bits;
        int bestscore = INT_MIN, i = 0, j;
        unsigned int channels;
        const struct pixel_format_desc *curfmt, *bestfmt = NULL;

        TRACE("Requested format not supported, looking for a fallback.\n");

        if (!fmt)
        {
            FIXME("Pixel format %x not handled\n", usedformat);
            goto cleanup;
        }

        allow_24bits = fmt->bytes_per_pixel == 3;
        channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
            + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
        usedformat = D3DFMT_UNKNOWN;

        while ((curfmt = get_format_info_idx(i)))
        {
            unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
                + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
            int score;

            i++;

            if (curchannels < channels)
                continue;
            if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
                continue;

            hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
                mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
            if (FAILED(hr))
                continue;

            /* This format can be used, let's evaluate it.
               Weights chosen quite arbitrarily... */
            score = 16 - 4 * (curchannels - channels);

            for (j = 0; j < 4; j++)
            {
                int diff = curfmt->bits[j] - fmt->bits[j];
                score += 16 - (diff < 0 ? -diff * 4 : diff);
            }

            if (score > bestscore)
            {
                bestscore = score;
                usedformat = curfmt->format;
                bestfmt = curfmt;
            }
        }
        fmt = bestfmt;
        hr = D3D_OK;
    }

    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
        w = h = 256;
    else if (w == D3DX_DEFAULT)
        w = (height ? h : 256);
    else if (h == D3DX_DEFAULT)
        h = (width ? w : 256);

    if (fmt->block_width != 1 || fmt->block_height != 1)
    {
        if (w < fmt->block_width)
            w = fmt->block_width;
        if (h < fmt->block_height)
            h = fmt->block_height;
    }

    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
        w = make_pow2(w);

    if (w > caps.MaxTextureWidth)
        w = caps.MaxTextureWidth;

    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
        h = make_pow2(h);

    if (h > caps.MaxTextureHeight)
        h = caps.MaxTextureHeight;

    if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
    {
        if (w > h)
            h = w;
        else
            w = h;
    }

    if (width)
        *width = w;

    if (height)
        *height = h;

    if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
    {
        if (*miplevels > 1)
            *miplevels = 0;
    }
    else if (miplevels)
    {
        UINT max_mipmaps = 1;

        if (!width && !height)
            max_mipmaps = 9;    /* number of mipmaps in a 256x256 texture */
        else
        {
            UINT max_dimen = max(w, h);

            while (max_dimen > 1)
            {
                max_dimen >>= 1;
                max_mipmaps++;
            }
        }

        if (*miplevels == 0 || *miplevels > max_mipmaps)
            *miplevels = max_mipmaps;
    }

cleanup:

    if (d3d)
        IDirect3D9_Release(d3d);

    if (FAILED(hr))
        return hr;

    if (usedformat == D3DFMT_UNKNOWN)
    {
        WARN("Couldn't find a suitable pixel format\n");
        return D3DERR_NOTAVAILABLE;
    }

    TRACE("Format chosen: %x\n", usedformat);
    if (format)
        *format = usedformat;

    return D3D_OK;
}

HRESULT WINAPI D3DXCheckCubeTextureRequirements(struct IDirect3DDevice9 *device, UINT *size,
        UINT *miplevels, DWORD usage, D3DFORMAT *format, D3DPOOL pool)
{
    D3DCAPS9 caps;
    UINT s = (size && *size) ? *size : 256;
    HRESULT hr;

    TRACE("(%p, %p, %p, %u, %p, %u)\n", device, size, miplevels, usage, format, pool);

    if (s == D3DX_DEFAULT)
        s = 256;

    if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
        return D3DERR_NOTAVAILABLE;

    /* ensure width/height is power of 2 */
    if ((caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && (!is_pow2(s)))
        s = make_pow2(s);

    hr = D3DXCheckTextureRequirements(device, &s, &s, miplevels, usage, format, pool);

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
    {
        if(miplevels)
            *miplevels = 1;
    }

    if (size)
        *size = s;

    return hr;
}

HRESULT WINAPI D3DXCheckVolumeTextureRequirements(struct IDirect3DDevice9 *device, UINT *width, UINT *height,
        UINT *depth, UINT *miplevels, DWORD usage, D3DFORMAT *format, D3DPOOL pool)
{
    D3DCAPS9 caps;
    UINT w = width ? *width : D3DX_DEFAULT;
    UINT h = height ? *height : D3DX_DEFAULT;
    UINT d = (depth && *depth) ? *depth : 1;
    HRESULT hr;

    TRACE("(%p, %p, %p, %p, %p, %u, %p, %u)\n", device, width, height, depth, miplevels,
          usage, format, pool);

    if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
        return D3DERR_NOTAVAILABLE;

    hr = D3DXCheckTextureRequirements(device, &w, &h, NULL, usage, format, pool);
    if (d == D3DX_DEFAULT)
        d = 1;

    /* ensure width/height is power of 2 */
    if ((caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) &&
        (!is_pow2(w) || !is_pow2(h) || !is_pow2(d)))
    {
        w = make_pow2(w);
        h = make_pow2(h);
        d = make_pow2(d);
    }

    if (w > caps.MaxVolumeExtent)
        w = caps.MaxVolumeExtent;
    if (h > caps.MaxVolumeExtent)
        h = caps.MaxVolumeExtent;
    if (d > caps.MaxVolumeExtent)
        d = caps.MaxVolumeExtent;

    if (miplevels)
    {
        if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
            *miplevels = 1;
        else if ((usage & D3DUSAGE_AUTOGENMIPMAP))
        {
            if (*miplevels > 1)
                *miplevels = 0;
        }
        else
        {
            UINT max_mipmaps = 1;
            UINT max_dimen = max(max(w, h), d);

            while (max_dimen > 1)
            {
                max_dimen >>= 1;
                max_mipmaps++;
            }

            if (*miplevels == 0 || *miplevels > max_mipmaps)
                *miplevels = max_mipmaps;
        }
    }

    if (width)
        *width = w;
    if (height)
        *height = h;
    if (depth)
        *depth = d;

    return hr;
}

HRESULT WINAPI D3DXCreateTexture(struct IDirect3DDevice9 *device, UINT width, UINT height,
        UINT miplevels, DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DTexture9 **texture)
{
    HRESULT hr;

    TRACE("device %p, width %u, height %u, miplevels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
            device, width, height, miplevels, usage, format, pool, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    if (FAILED(hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool)))
        return hr;

    return IDirect3DDevice9_CreateTexture(device, width, height, miplevels, usage, format, pool, texture, NULL);
}

HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *device, const void *srcdata,
        UINT srcdatasize, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
        PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
{
    IDirect3DTexture9 **texptr;
    IDirect3DTexture9 *buftex;
    IDirect3DSurface9 *surface;
    BOOL file_width = FALSE, file_height = FALSE;
    BOOL file_format = FALSE, file_miplevels = FALSE;
    BOOL dynamic_texture;
    D3DXIMAGE_INFO imginfo;
    UINT loaded_miplevels, skip_levels;
    D3DCAPS9 caps;
    HRESULT hr;

    TRACE("device %p, srcdata %p, srcdatasize %u, width %u, height %u, miplevels %u,"
            " usage %#x, format %#x, pool %#x, filter %#x, mipfilter %#x, colorkey %#x,"
            " srcinfo %p, palette %p, texture %p.\n",
            device, srcdata, srcdatasize, width, height, miplevels, usage, format, pool,
            filter, mipfilter, colorkey, srcinfo, palette, texture);

    /* check for invalid parameters */
    if (!device || !texture || !srcdata || !srcdatasize)
        return D3DERR_INVALIDCALL;

    hr = D3DXGetImageInfoFromFileInMemory(srcdata, srcdatasize, &imginfo);
    if (FAILED(hr))
    {
        FIXME("Unrecognized file format, returning failure.\n");
        *texture = NULL;
        return hr;
    }

    /* handle default values */
    if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
        width = imginfo.Width;

    if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
        height = imginfo.Height;

    if (width == D3DX_DEFAULT)
        width = make_pow2(imginfo.Width);

    if (height == D3DX_DEFAULT)
        height = make_pow2(imginfo.Height);

    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
        format = imginfo.Format;

    if (width == D3DX_FROM_FILE)
    {
        file_width = TRUE;
        width = imginfo.Width;
    }

    if (height == D3DX_FROM_FILE)
    {
        file_height = TRUE;
        height = imginfo.Height;
    }

    if (format == D3DFMT_FROM_FILE)
    {
        file_format = TRUE;
        format = imginfo.Format;
    }

    if (miplevels == D3DX_FROM_FILE)
    {
        file_miplevels = TRUE;
        miplevels = imginfo.MipLevels;
    }

    skip_levels = mipfilter != D3DX_DEFAULT ? mipfilter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0;
    if (skip_levels && imginfo.MipLevels > skip_levels)
    {
        TRACE("Skipping the first %u (of %u) levels of a DDS mipmapped texture.\n",
                skip_levels, imginfo.MipLevels);
        TRACE("Texture level 0 dimensions are %ux%u.\n", imginfo.Width, imginfo.Height);
        width >>= skip_levels;
        height >>= skip_levels;
        miplevels -= skip_levels;
    }
    else
    {
        skip_levels = 0;
    }

    /* fix texture creation parameters */
    hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);
    if (FAILED(hr))
    {
        FIXME("Couldn't find suitable texture parameters.\n");
        *texture = NULL;
        return hr;
    }

    if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
    {
        FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
        miplevels = imginfo.MipLevels;
    }
    if (imginfo.ResourceType == D3DRTYPE_VOLUMETEXTURE
            && D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5 && miplevels > 1)
    {
        FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet.\n");
        miplevels = 1;
    }

    if (((file_width) && (width != imginfo.Width))    ||
        ((file_height) && (height != imginfo.Height)) ||
        ((file_format) && (format != imginfo.Format)) ||
        ((file_miplevels) && (miplevels != imginfo.MipLevels)))
    {
        return D3DERR_NOTAVAILABLE;
    }

    if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
        return D3DERR_INVALIDCALL;

    /* Create the to-be-filled texture */
    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
        texptr = &buftex;
    }
    else
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);
        texptr = texture;
    }

    if (FAILED(hr))
    {
        FIXME("Texture creation failed.\n");
        *texture = NULL;
        return hr;
    }

    TRACE("Texture created correctly. Now loading the texture data into it.\n");
    if (imginfo.ImageFileFormat != D3DXIFF_DDS)
    {
        IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
        hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
        IDirect3DSurface9_Release(surface);
        loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
    }
    else
    {
        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo, skip_levels,
                &loaded_miplevels);
    }

    if (FAILED(hr))
    {
        FIXME("Texture loading failed.\n");
        IDirect3DTexture9_Release(*texptr);
        *texture = NULL;
        return hr;
    }

    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
    if (FAILED(hr))
    {
        FIXME("Texture filtering failed.\n");
        IDirect3DTexture9_Release(*texptr);
        *texture = NULL;
        return hr;
    }

    /* Move the data to the actual texture if necessary */
    if (texptr == &buftex)
    {
        hr = D3DXCreateTexture(device, width, height, miplevels, usage, format, pool, texture);

        if (FAILED(hr))
        {
            IDirect3DTexture9_Release(buftex);
            *texture = NULL;
            return hr;
        }

        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)buftex, (IDirect3DBaseTexture9*)(*texture));
        IDirect3DTexture9_Release(buftex);
    }

    if (srcinfo)
        *srcinfo = imginfo;

    return D3D_OK;
}

HRESULT WINAPI D3DXCreateTextureFromFileInMemory(struct IDirect3DDevice9 *device,
        const void *srcdata, UINT srcdatasize, struct IDirect3DTexture9 **texture)
{
    TRACE("(%p, %p, %d, %p)\n", device, srcdata, srcdatasize, texture);

    return D3DXCreateTextureFromFileInMemoryEx(device, srcdata, srcdatasize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                               D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromFileExW(struct IDirect3DDevice9 *device, const WCHAR *srcfile,
        UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
        PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
{
    void *buffer;
    HRESULT hr;
    DWORD size;

    TRACE("device %p, srcfile %s, width %u, height %u, miplevels %u, usage %#x, format %#x, "
            "pool %#x, filter %#x, mipfilter %#x, colorkey 0x%08x, srcinfo %p, palette %p, texture %p.\n",
            device, debugstr_w(srcfile), width, height, miplevels, usage, format,
            pool, filter, mipfilter, colorkey, srcinfo, palette, texture);

    if (!srcfile)
        return D3DERR_INVALIDCALL;

    hr = map_view_of_file(srcfile, &buffer, &size);
    if (FAILED(hr))
        return D3DXERR_INVALIDDATA;

    hr = D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels, usage, format, pool,
        filter, mipfilter, colorkey, srcinfo, palette, texture);

    UnmapViewOfFile(buffer);

    return hr;
}

HRESULT WINAPI D3DXCreateTextureFromFileExA(struct IDirect3DDevice9 *device, const char *srcfile,
        UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
        PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
{
    WCHAR *widename;
    HRESULT hr;
    DWORD len;

    TRACE("device %p, srcfile %s, width %u, height %u, miplevels %u, usage %#x, format %#x, "
            "pool %#x, filter %#x, mipfilter %#x, colorkey 0x%08x, srcinfo %p, palette %p, texture %p.\n",
            device, debugstr_a(srcfile), width, height, miplevels, usage, format,
            pool, filter, mipfilter, colorkey, srcinfo, palette, texture);

    if (!device || !srcfile || !texture)
        return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
    widename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*widename));
    MultiByteToWideChar(CP_ACP, 0, srcfile, -1, widename, len);

    hr = D3DXCreateTextureFromFileExW(device, widename, width, height, miplevels,
                                      usage, format, pool, filter, mipfilter,
                                      colorkey, srcinfo, palette, texture);

    HeapFree(GetProcessHeap(), 0, widename);
    return hr;
}

HRESULT WINAPI D3DXCreateTextureFromFileA(struct IDirect3DDevice9 *device,
        const char *srcfile, struct IDirect3DTexture9 **texture)
{
    TRACE("(%p, %s, %p)\n", device, debugstr_a(srcfile), texture);

    return D3DXCreateTextureFromFileExA(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                        D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromFileW(struct IDirect3DDevice9 *device,
        const WCHAR *srcfile, struct IDirect3DTexture9 **texture)
{
    TRACE("(%p, %s, %p)\n", device, debugstr_w(srcfile), texture);

    return D3DXCreateTextureFromFileExW(device, srcfile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                        D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}


HRESULT WINAPI D3DXCreateTextureFromResourceA(struct IDirect3DDevice9 *device,
        HMODULE srcmodule, const char *resource, struct IDirect3DTexture9 **texture)
{
    TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(resource));

    return D3DXCreateTextureFromResourceExA(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                            D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromResourceW(struct IDirect3DDevice9 *device,
        HMODULE srcmodule, const WCHAR *resource, struct IDirect3DTexture9 **texture)
{
    TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(resource));

    return D3DXCreateTextureFromResourceExW(device, srcmodule, resource, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
                                            D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateTextureFromResourceExA(struct IDirect3DDevice9 *device, HMODULE srcmodule,
        const char *resource, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
        PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
{
    HRSRC resinfo;
    void *buffer;
    DWORD size;

    TRACE("device %p, srcmodule %p, resource %s, width %u, height %u, miplevels %u, usage %#x, format %#x, "
            "pool %#x, filter %#x, mipfilter %#x, colorkey 0x%08x, srcinfo %p, palette %p, texture %p.\n",
            device, srcmodule, debugstr_a(resource), width, height, miplevels, usage, format,
            pool, filter, mipfilter, colorkey, srcinfo, palette, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    if (!(resinfo = FindResourceA(srcmodule, resource, (const char *)RT_RCDATA))
            /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
            && !(resinfo = FindResourceA(srcmodule, resource, (const char *)RT_BITMAP)))
        return D3DXERR_INVALIDDATA;

    if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
        return D3DXERR_INVALIDDATA;

    return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels,
            usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
}

HRESULT WINAPI D3DXCreateTextureFromResourceExW(struct IDirect3DDevice9 *device, HMODULE srcmodule,
        const WCHAR *resource, UINT width, UINT height, UINT miplevels, DWORD usage, D3DFORMAT format,
        D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
        PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
{
    HRSRC resinfo;
    void *buffer;
    DWORD size;

    TRACE("device %p, srcmodule %p, resource %s, width %u, height %u, miplevels %u, usage %#x, format %#x, "
            "pool %#x, filter %#x, mipfilter %#x, colorkey 0x%08x, srcinfo %p, palette %p, texture %p.\n",
            device, srcmodule, debugstr_w(resource), width, height, miplevels, usage, format,
            pool, filter, mipfilter, colorkey, srcinfo, palette, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    if (!(resinfo = FindResourceW(srcmodule, resource, (const WCHAR *)RT_RCDATA))
            /* Try loading the resource as bitmap data (which is in DIB format D3DXIFF_DIB) */
            && !(resinfo = FindResourceW(srcmodule, resource, (const WCHAR *)RT_BITMAP)))
        return D3DXERR_INVALIDDATA;

    if (FAILED(load_resource_into_memory(srcmodule, resinfo, &buffer, &size)))
        return D3DXERR_INVALIDDATA;

    return D3DXCreateTextureFromFileInMemoryEx(device, buffer, size, width, height, miplevels,
            usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
}

HRESULT WINAPI D3DXCreateCubeTexture(struct IDirect3DDevice9 *device, UINT size, UINT miplevels,
        DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DCubeTexture9 **texture)
{
    HRESULT hr;

    TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
        pool, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);

    if (FAILED(hr))
    {
        TRACE("D3DXCheckCubeTextureRequirements failed\n");
        return hr;
    }

    return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemory(struct IDirect3DDevice9 *device,
        const void *data, UINT datasize, struct IDirect3DCubeTexture9 **texture)
{
    TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);

    return D3DXCreateCubeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, texture);
}

HRESULT WINAPI D3DXCreateVolumeTexture(struct IDirect3DDevice9 *device, UINT width, UINT height, UINT depth,
        UINT miplevels, DWORD usage, D3DFORMAT format, D3DPOOL pool, struct IDirect3DVolumeTexture9 **texture)
{
    HRESULT hr;

    TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
          miplevels, usage, format, pool, texture);

    if (!device || !texture)
        return D3DERR_INVALIDCALL;

    hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
                                            &miplevels, usage, &format, pool);

    if (FAILED(hr))
    {
        TRACE("D3DXCheckVolumeTextureRequirements failed\n");
        return hr;
    }

    return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
                                                usage, format, pool, texture, NULL);
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileA(IDirect3DDevice9 *device,
                                                const char *filename,
                                                IDirect3DVolumeTexture9 **volume_texture)
{
    int len;
    HRESULT hr;
    void *data;
    DWORD data_size;
    WCHAR *filenameW;

    TRACE("(%p, %s, %p): relay\n",
            device, debugstr_a(filename), volume_texture);

    if (!filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
    filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filenameW) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);

    hr = map_view_of_file(filenameW, &data, &data_size);
    HeapFree(GetProcessHeap(), 0, filenameW);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
            D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileW(IDirect3DDevice9 *device,
                                                const WCHAR *filename,
                                                IDirect3DVolumeTexture9 **volume_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %p): relay\n",
            device, debugstr_w(filename), volume_texture);

    if (!filename) return D3DERR_INVALIDCALL;

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
            D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, volume_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileExA(IDirect3DDevice9 *device,
                                                  const char *filename,
                                                  UINT width,
                                                  UINT height,
                                                  UINT depth,
                                                  UINT mip_levels,
                                                  DWORD usage,
                                                  D3DFORMAT format,
                                                  D3DPOOL pool,
                                                  DWORD filter,
                                                  DWORD mip_filter,
                                                  D3DCOLOR color_key,
                                                  D3DXIMAGE_INFO *src_info,
                                                  PALETTEENTRY *palette,
                                                  IDirect3DVolumeTexture9 **volume_texture)
{
    int len;
    HRESULT hr;
    WCHAR *filenameW;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, debugstr_a(filename), width, height, depth, mip_levels,
            usage, format, pool, filter, mip_filter, color_key, src_info,
            palette, volume_texture);

    if (!filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
    filenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filenameW) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, len);

    hr = map_view_of_file(filenameW, &data, &data_size);
    HeapFree(GetProcessHeap(), 0, filenameW);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, width, height, depth,
            mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
            volume_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileExW(IDirect3DDevice9 *device,
                                                  const WCHAR *filename,
                                                  UINT width,
                                                  UINT height,
                                                  UINT depth,
                                                  UINT mip_levels,
                                                  DWORD usage,
                                                  D3DFORMAT format,
                                                  D3DPOOL pool,
                                                  DWORD filter,
                                                  DWORD mip_filter,
                                                  D3DCOLOR color_key,
                                                  D3DXIMAGE_INFO *src_info,
                                                  PALETTEENTRY *palette,
                                                  IDirect3DVolumeTexture9 **volume_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, debugstr_w(filename), width, height, depth, mip_levels,
            usage, format, pool, filter, mip_filter, color_key, src_info,
            palette, volume_texture);

    if (!filename) return D3DERR_INVALIDCALL;

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, width, height, depth,
            mip_levels, usage, format, pool, filter, mip_filter, color_key, src_info, palette,
            volume_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device,
                                                       const void *data,
                                                       UINT data_size,
                                                       IDirect3DVolumeTexture9 **volume_texture)
{
    TRACE("(%p, %p, %u, %p): relay\n", device, data, data_size, volume_texture);

    return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
        D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
        0, NULL, NULL, volume_texture);
}

HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
                                                         const void *data,
                                                         UINT data_size,
                                                         UINT width,
                                                         UINT height,
                                                         UINT depth,
                                                         UINT mip_levels,
                                                         DWORD usage,
                                                         D3DFORMAT format,
                                                         D3DPOOL pool,
                                                         DWORD filter,
                                                         DWORD mip_filter,
                                                         D3DCOLOR color_key,
                                                         D3DXIMAGE_INFO *info,
                                                         PALETTEENTRY *palette,
                                                         IDirect3DVolumeTexture9 **volume_texture)
{
    HRESULT hr;
    D3DCAPS9 caps;
    D3DXIMAGE_INFO image_info;
    BOOL dynamic_texture;
    BOOL file_width = FALSE;
    BOOL file_height = FALSE;
    BOOL file_depth = FALSE;
    BOOL file_format = FALSE;
    BOOL file_mip_levels = FALSE;
    IDirect3DVolumeTexture9 *tex, *buftex;

    TRACE("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n",
            device, data, data_size, width, height, depth, mip_levels, usage, format, pool,
            filter, mip_filter, color_key, info, palette, volume_texture);

    if (!device || !data || !data_size || !volume_texture)
        return D3DERR_INVALIDCALL;

    hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info);
    if (FAILED(hr)) return hr;

    if (image_info.ImageFileFormat != D3DXIFF_DDS)
        return D3DXERR_INVALIDDATA;

    if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
        width = image_info.Width;
    if (width == D3DX_DEFAULT)
        width = make_pow2(image_info.Width);

    if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
        height = image_info.Height;
    if (height == D3DX_DEFAULT)
        height = make_pow2(image_info.Height);

    if (depth == 0 || depth == D3DX_DEFAULT_NONPOW2)
        depth = image_info.Depth;
    if (depth == D3DX_DEFAULT)
        depth = make_pow2(image_info.Depth);

    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
        format = image_info.Format;

    if (width == D3DX_FROM_FILE)
    {
        file_width = TRUE;
        width = image_info.Width;
    }

    if (height == D3DX_FROM_FILE)
    {
        file_height = TRUE;
        height = image_info.Height;
    }

    if (depth == D3DX_FROM_FILE)
    {
        file_depth = TRUE;
        depth = image_info.Depth;
    }

    if (format == D3DFMT_FROM_FILE)
    {
        file_format = TRUE;
        format = image_info.Format;
    }

    if (mip_levels == D3DX_FROM_FILE)
    {
        file_mip_levels = TRUE;
        mip_levels = image_info.MipLevels;
    }

    hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mip_levels, usage, &format, pool);
    if (FAILED(hr)) return hr;

    if ((file_width && width != image_info.Width)
            || (file_height && height != image_info.Height)
            || (file_depth && depth != image_info.Depth)
            || (file_format && format != image_info.Format)
            || (file_mip_levels && mip_levels != image_info.MipLevels))
        return D3DERR_NOTAVAILABLE;

    hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
    if (FAILED(hr))
        return D3DERR_INVALIDCALL;

    if (mip_levels > image_info.MipLevels)
    {
        FIXME("Generation of mipmaps for volume textures is not implemented yet\n");
        mip_levels = image_info.MipLevels;
    }

    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
    {
        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
        tex = buftex;
    }
    else
    {
        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
        buftex = NULL;
    }

    if (FAILED(hr)) return hr;

    hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info);
    if (FAILED(hr))
    {
        IDirect3DVolumeTexture9_Release(tex);
        return hr;
    }

    if (buftex)
    {
        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
        if (FAILED(hr))
        {
            IDirect3DVolumeTexture9_Release(buftex);
            return hr;
        }

        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
        IDirect3DVolumeTexture9_Release(buftex);
    }

    if (info)
        *info = image_info;

    *volume_texture = tex;
    return D3D_OK;
}

static inline void fill_texture(const struct pixel_format_desc *format, BYTE *pos, const D3DXVECTOR4 *value)
{
    DWORD c;

    for (c = 0; c < format->bytes_per_pixel; c++)
        pos[c] = 0;

    for (c = 0; c < 4; c++)
    {
        float comp_value;
        DWORD i, v = 0, mask32 = format->bits[c] == 32 ? ~0U : ((1 << format->bits[c]) - 1);

        switch (c)
        {
            case 0: /* Alpha */
                comp_value = value->w;
                break;
            case 1: /* Red */
                comp_value = value->x;
                break;
            case 2: /* Green */
                comp_value = value->y;
                break;
            case 3: /* Blue */
                comp_value = value->z;
                break;
        }

        if (format->type == FORMAT_ARGBF16)
            v = float_32_to_16(comp_value);
        else if (format->type == FORMAT_ARGBF)
            v = *(DWORD *)&comp_value;
        else if (format->type == FORMAT_ARGB)
            v = comp_value * ((1 << format->bits[c]) - 1) + 0.5f;
        else
            FIXME("Unhandled format type %#x\n", format->type);

        for (i = 0; i < format->bits[c] + format->shift[c]; i += 8)
        {
            BYTE byte, mask;

            if (format->shift[c] > i)
            {
                mask = mask32 << (format->shift[c] - i);
                byte = (v << (format->shift[c] - i)) & mask;
            }
            else
            {
                mask = mask32 >> (i - format->shift[c]);
                byte = (v >> (i - format->shift[c])) & mask;
            }
            pos[i / 8] |= byte;
        }
    }
}

HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 *texture, LPD3DXFILL2D function, void *funcdata)
{
    DWORD miplevels;
    DWORD m, x, y;
    D3DSURFACE_DESC desc;
    D3DLOCKED_RECT lock_rect;
    D3DXVECTOR4 value;
    D3DXVECTOR2 coord, size;
    const struct pixel_format_desc *format;
    BYTE *data;

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->type != FORMAT_ARGB && format->type != FORMAT_ARGBF16 && format->type != FORMAT_ARGBF)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
            return D3DERR_INVALIDCALL;

        size.x = 1.0f / desc.Width;
        size.y = 1.0f / desc.Height;

        data = lock_rect.pBits;

        for (y = 0; y < desc.Height; y++)
        {
            /* The callback function expects the coordinates of the center
               of the texel */
            coord.y = (y + 0.5f) / desc.Height;

            for (x = 0; x < desc.Width; x++)
            {
                coord.x = (x + 0.5f) / desc.Width;

                function(&value, &coord, &size, funcdata);

                fill_texture(format, data + y * lock_rect.Pitch + x * format->bytes_per_pixel, &value);
            }
        }
        IDirect3DTexture9_UnlockRect(texture, m);
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
                                                       const void *src_data,
                                                       UINT src_data_size,
                                                       UINT size,
                                                       UINT mip_levels,
                                                       DWORD usage,
                                                       D3DFORMAT format,
                                                       D3DPOOL pool,
                                                       DWORD filter,
                                                       DWORD mip_filter,
                                                       D3DCOLOR color_key,
                                                       D3DXIMAGE_INFO *src_info,
                                                       PALETTEENTRY *palette,
                                                       IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    D3DCAPS9 caps;
    UINT loaded_miplevels;
    D3DXIMAGE_INFO img_info;
    BOOL dynamic_texture;
    BOOL file_size = FALSE;
    BOOL file_format = FALSE;
    BOOL file_mip_levels = FALSE;
    IDirect3DCubeTexture9 *tex, *buftex;

    TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
        src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
        color_key, src_info, palette, cube_texture);

    if (!device || !cube_texture || !src_data || !src_data_size)
        return D3DERR_INVALIDCALL;

    hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
    if (FAILED(hr))
        return hr;

    if (img_info.ImageFileFormat != D3DXIFF_DDS)
        return D3DXERR_INVALIDDATA;

    if (img_info.Width != img_info.Height)
        return D3DXERR_INVALIDDATA;

    if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
        size = img_info.Width;
    if (size == D3DX_DEFAULT)
        size = make_pow2(img_info.Width);

    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
        format = img_info.Format;

    if (size == D3DX_FROM_FILE)
    {
        file_size = TRUE;
        size = img_info.Width;
    }

    if (format == D3DFMT_FROM_FILE)
    {
        file_format = TRUE;
        format = img_info.Format;
    }

    if (mip_levels == D3DX_FROM_FILE)
    {
        file_mip_levels = TRUE;
        mip_levels = img_info.MipLevels;
    }

    hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
    if (FAILED(hr))
        return hr;

    if ((file_size && size != img_info.Width)
            || (file_format && format != img_info.Format)
            || (file_mip_levels && mip_levels != img_info.MipLevels))
        return D3DERR_NOTAVAILABLE;

    hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
    if (FAILED(hr))
        return D3DERR_INVALIDCALL;

    if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
    {
        FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
        mip_levels = img_info.MipLevels;
    }

    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
        tex = buftex;
    }
    else
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
        buftex = NULL;
    }
    if (FAILED(hr))
        return hr;

    hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
    if (FAILED(hr))
    {
        IDirect3DCubeTexture9_Release(tex);
        return hr;
    }

    loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels);
    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
    if (FAILED(hr))
    {
        IDirect3DCubeTexture9_Release(tex);
        return hr;
    }

    if (buftex)
    {
        hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
        if (FAILED(hr))
        {
            IDirect3DCubeTexture9_Release(buftex);
            return hr;
        }

        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
        IDirect3DCubeTexture9_Release(buftex);
    }

    if (src_info)
        *src_info = img_info;

    *cube_texture = tex;
    return D3D_OK;
}


HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
                                              const char *src_filename,
                                              IDirect3DCubeTexture9 **cube_texture)
{
    int len;
    HRESULT hr;
    WCHAR *filename;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_a(src_filename), cube_texture);

    if (!src_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, filename);
        return D3DXERR_INVALIDDATA;
    }

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);

    UnmapViewOfFile(data);
    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileW(IDirect3DDevice9 *device,
                                              const WCHAR *src_filename,
                                              IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %p): relay\n", device, wine_dbgstr_w(src_filename), cube_texture);

    hr = map_view_of_file(src_filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
        0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, cube_texture);

    UnmapViewOfFile(data);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileExA(IDirect3DDevice9 *device,
                                                const char *src_filename,
                                                UINT size,
                                                UINT mip_levels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mip_filter,
                                                D3DCOLOR color_key,
                                                D3DXIMAGE_INFO *image_info,
                                                PALETTEENTRY *palette,
                                                IDirect3DCubeTexture9 **cube_texture)
{
    int len;
    HRESULT hr;
    WCHAR *filename;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, wine_dbgstr_a(src_filename), size, mip_levels, usage, format,
            pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    if (!src_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, src_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, src_filename, -1, filename, len);

    hr = map_view_of_file(filename, &data, &data_size);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, filename);
        return D3DXERR_INVALIDDATA;
    }

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
        usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    UnmapViewOfFile(data);
    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXCreateCubeTextureFromFileExW(IDirect3DDevice9 *device,
                                                const WCHAR *src_filename,
                                                UINT size,
                                                UINT mip_levels,
                                                DWORD usage,
                                                D3DFORMAT format,
                                                D3DPOOL pool,
                                                DWORD filter,
                                                DWORD mip_filter,
                                                D3DCOLOR color_key,
                                                D3DXIMAGE_INFO *image_info,
                                                PALETTEENTRY *palette,
                                                IDirect3DCubeTexture9 **cube_texture)
{
    HRESULT hr;
    void *data;
    DWORD data_size;

    TRACE("(%p, %s, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): relay\n",
            device, wine_dbgstr_w(src_filename), size, mip_levels, usage, format,
            pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    hr = map_view_of_file(src_filename, &data, &data_size);
    if (FAILED(hr)) return D3DXERR_INVALIDDATA;

    hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, data, data_size, size, mip_levels,
        usage, format, pool, filter, mip_filter, color_key, image_info, palette, cube_texture);

    UnmapViewOfFile(data);
    return hr;
}

enum cube_coord
{
    XCOORD = 0,
    XCOORDINV = 1,
    YCOORD = 2,
    YCOORDINV = 3,
    ZERO = 4,
    ONE = 5
};

static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
{
    switch (coord)
    {
        case XCOORD:
            return x + 0.5f;
        case XCOORDINV:
            return size - x - 0.5f;
        case YCOORD:
            return y + 0.5f;
        case YCOORDINV:
            return size - y - 0.5f;
        case ZERO:
            return 0.0f;
        case ONE:
            return size;
       default:
           ERR("Unexpected coordinate value\n");
           return 0.0f;
    }
}

HRESULT WINAPI D3DXFillCubeTexture(struct IDirect3DCubeTexture9 *texture, LPD3DXFILL3D function, void *funcdata)
{
    DWORD miplevels;
    DWORD m, x, y, f;
    D3DSURFACE_DESC desc;
    D3DLOCKED_RECT lock_rect;
    D3DXVECTOR4 value;
    D3DXVECTOR3 coord, size;
    const struct pixel_format_desc *format;
    BYTE *data;
    static const enum cube_coord coordmap[6][3] =
        {
            {ONE, YCOORDINV, XCOORDINV},
            {ZERO, YCOORDINV, XCOORD},
            {XCOORD, ONE, YCOORD},
            {XCOORD, ZERO, YCOORDINV},
            {XCOORD, YCOORDINV, ONE},
            {XCOORDINV, YCOORDINV, ZERO}
        };

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DCubeTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->type != FORMAT_ARGB && format->type != FORMAT_ARGBF16 && format->type != FORMAT_ARGBF)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        for (f = 0; f < 6; f++)
        {
            if (FAILED(IDirect3DCubeTexture9_LockRect(texture, f, m, &lock_rect, NULL, D3DLOCK_DISCARD)))
                return D3DERR_INVALIDCALL;

            size.x = (f == 0) || (f == 1) ? 0.0f : 2.0f / desc.Width;
            size.y = (f == 2) || (f == 3) ? 0.0f : 2.0f / desc.Width;
            size.z = (f == 4) || (f == 5) ? 0.0f : 2.0f / desc.Width;

            data = lock_rect.pBits;

            for (y = 0; y < desc.Height; y++)
            {
                for (x = 0; x < desc.Width; x++)
                {
                    coord.x = get_cube_coord(coordmap[f][0], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
                    coord.y = get_cube_coord(coordmap[f][1], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;
                    coord.z = get_cube_coord(coordmap[f][2], x, y, desc.Width) / desc.Width * 2.0f - 1.0f;

                    function(&value, &coord, &size, funcdata);

                    fill_texture(format, data + y * lock_rect.Pitch + x * format->bytes_per_pixel, &value);
                }
            }
            IDirect3DCubeTexture9_UnlockRect(texture, f, m);
        }
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXFillVolumeTexture(struct IDirect3DVolumeTexture9 *texture, LPD3DXFILL3D function, void *funcdata)
{
    DWORD miplevels;
    DWORD m, x, y, z;
    D3DVOLUME_DESC desc;
    D3DLOCKED_BOX lock_box;
    D3DXVECTOR4 value;
    D3DXVECTOR3 coord, size;
    const struct pixel_format_desc *format;
    BYTE *data;

    if (texture == NULL || function == NULL)
        return D3DERR_INVALIDCALL;

    miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);

    for (m = 0; m < miplevels; m++)
    {
        if (FAILED(IDirect3DVolumeTexture9_GetLevelDesc(texture, m, &desc)))
            return D3DERR_INVALIDCALL;

        format = get_format_info(desc.Format);
        if (format->type != FORMAT_ARGB && format->type != FORMAT_ARGBF16 && format->type != FORMAT_ARGBF)
        {
            FIXME("Unsupported texture format %#x\n", desc.Format);
            return D3DERR_INVALIDCALL;
        }

        if (FAILED(IDirect3DVolumeTexture9_LockBox(texture, m, &lock_box, NULL, D3DLOCK_DISCARD)))
            return D3DERR_INVALIDCALL;

        size.x = 1.0f / desc.Width;
        size.y = 1.0f / desc.Height;
        size.z = 1.0f / desc.Depth;

        data = lock_box.pBits;

        for (z = 0; z < desc.Depth; z++)
        {
            /* The callback function expects the coordinates of the center
               of the texel */
            coord.z = (z + 0.5f) / desc.Depth;

            for (y = 0; y < desc.Height; y++)
            {
                coord.y = (y + 0.5f) / desc.Height;

                for (x = 0; x < desc.Width; x++)
                {
                    coord.x = (x + 0.5f) / desc.Width;

                    function(&value, &coord, &size, funcdata);

                    fill_texture(format, data + z * lock_box.SlicePitch + y * lock_box.RowPitch
                            + x * format->bytes_per_pixel, &value);
                }
            }
        }
        IDirect3DVolumeTexture9_UnlockBox(texture, m);
    }

    return D3D_OK;
}

HRESULT WINAPI D3DXSaveTextureToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    int len;
    WCHAR *filename;
    HRESULT hr;
    ID3DXBuffer *buffer;

    TRACE("(%s, %#x, %p, %p): relay\n",
            wine_dbgstr_a(dst_filename), file_format, src_texture, src_palette);

    if (!dst_filename) return D3DERR_INVALIDCALL;

    len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0);
    filename = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!filename) return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len);

    hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
    if (SUCCEEDED(hr))
    {
        hr = write_buffer_to_file(filename, buffer);
        ID3DXBuffer_Release(buffer);
    }

    HeapFree(GetProcessHeap(), 0, filename);
    return hr;
}

HRESULT WINAPI D3DXSaveTextureToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    HRESULT hr;
    ID3DXBuffer *buffer;

    TRACE("(%s, %#x, %p, %p): relay\n",
        wine_dbgstr_w(dst_filename), file_format, src_texture, src_palette);

    if (!dst_filename) return D3DERR_INVALIDCALL;

    hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, src_texture, src_palette);
    if (SUCCEEDED(hr))
    {
        hr = write_buffer_to_file(dst_filename, buffer);
        ID3DXBuffer_Release(buffer);
    }

    return hr;
}

HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format,
        IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette)
{
    HRESULT hr;
    D3DRESOURCETYPE type;
    IDirect3DSurface9 *surface;

    TRACE("(%p, %#x, %p, %p)\n",
        dst_buffer, file_format, src_texture, src_palette);

    if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;

    if (file_format == D3DXIFF_DDS)
    {
        FIXME("DDS file format isn't supported yet\n");
        return E_NOTIMPL;
    }

    type = IDirect3DBaseTexture9_GetType(src_texture);
    switch (type)
    {
        case D3DRTYPE_TEXTURE:
        case D3DRTYPE_CUBETEXTURE:
            hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface);
            break;
        case D3DRTYPE_VOLUMETEXTURE:
            FIXME("Volume textures aren't supported yet\n");
            return E_NOTIMPL;
        default:
            return D3DERR_INVALIDCALL;
    }

    if (SUCCEEDED(hr))
    {
        hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL);
        IDirect3DSurface9_Release(surface);
    }

    return hr;
}
