Beispiel #1
0
void PrintInfo( const TexMetadata& info )
{
    wprintf( L" (%Iux%Iu", info.width, info.height);

    if ( TEX_DIMENSION_TEXTURE3D == info.dimension )
        wprintf( L"x%Iu", info.depth);

    if ( info.mipLevels > 1 )
        wprintf( L",%Iu", info.mipLevels);

    if ( info.arraySize > 1 )
        wprintf( L",%Iu", info.arraySize);

    wprintf( L" ");
    PrintFormat( info.format );

    switch ( info.dimension )
    {
    case TEX_DIMENSION_TEXTURE1D:
        wprintf( (info.arraySize > 1) ? L" 1DArray" : L" 1D" );
        break;

    case TEX_DIMENSION_TEXTURE2D:
        if ( info.IsCubemap() )
        {
            wprintf( (info.arraySize > 6) ? L" CubeArray" : L" Cube" );
        }
        else
        {
            wprintf( (info.arraySize > 1) ? L" 2DArray" : L" 2D" );
        }
        break;

    case TEX_DIMENSION_TEXTURE3D:
        wprintf( L" 3D");
        break;
    }

    wprintf( L")");
}
Beispiel #2
0
//-------------------------------------------------------------------------------------
// Converts to/from a premultiplied alpha version of the texture (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::PremultiplyAlpha(
    const Image* srcImages,
    size_t nimages,
    const TexMetadata& metadata,
    DWORD flags,
    ScratchImage& result)
{
    if (!srcImages || !nimages)
        return E_INVALIDARG;

    if (IsCompressed(metadata.format)
        || IsPlanar(metadata.format)
        || IsPalettized(metadata.format)
        || IsTypeless(metadata.format)
        || !HasAlpha(metadata.format))
        return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);

    if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX))
        return E_INVALIDARG;

    if (metadata.IsPMAlpha() != ((flags & TEX_PMALPHA_REVERSE) != 0))
        return E_FAIL;

    TexMetadata mdata2 = metadata;
    mdata2.SetAlphaMode((flags & TEX_PMALPHA_REVERSE) ? TEX_ALPHA_MODE_STRAIGHT : TEX_ALPHA_MODE_PREMULTIPLIED);
    HRESULT hr = result.Initialize(mdata2);
    if (FAILED(hr))
        return hr;

    if (nimages != result.GetImageCount())
    {
        result.Release();
        return E_FAIL;
    }

    const Image* dest = result.GetImages();
    if (!dest)
    {
        result.Release();
        return E_POINTER;
    }

    for (size_t index = 0; index < nimages; ++index)
    {
        const Image& src = srcImages[index];
        if (src.format != metadata.format)
        {
            result.Release();
            return E_FAIL;
        }

        if ((src.width > UINT32_MAX) || (src.height > UINT32_MAX))
            return E_FAIL;

        const Image& dst = dest[index];
        assert(dst.format == metadata.format);

        if (src.width != dst.width || src.height != dst.height)
        {
            result.Release();
            return E_FAIL;
        }

        if (flags & TEX_PMALPHA_REVERSE)
        {
            hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? DemultiplyAlpha(src, dst) : DemultiplyAlphaLinear(src, flags, dst);
        }
        else
        {
            hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(src, dst) : PremultiplyAlphaLinear(src, flags, dst);
        }
        if (FAILED(hr))
        {
            result.Release();
            return hr;
        }
    }

    return S_OK;
}
Beispiel #3
0
//-------------------------------------------------------------------------------------
// Resize image (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                size_t width, size_t height, DWORD filter, ScratchImage& result )
{
    if ( !srcImages || !nimages || width == 0 || height == 0 )
        return E_INVALIDARG;

#ifdef _M_X64
    if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    TexMetadata mdata2 = metadata;
    mdata2.width = width;
    mdata2.height = height;
    mdata2.mipLevels = 1;
    HRESULT hr = result.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    bool usewic = _UseWICFiltering( metadata.format, filter );

    WICPixelFormatGUID pfGUID = {0};
    bool wicpf = ( usewic ) ? _DXGIToWIC( metadata.format, pfGUID, true ) : false;

    switch ( metadata.dimension )
    {
    case TEX_DIMENSION_TEXTURE1D:
    case TEX_DIMENSION_TEXTURE2D:
        assert( metadata.depth == 1 );

        for( size_t item = 0; item < metadata.arraySize; ++item )
        {
            size_t srcIndex = metadata.ComputeIndex( 0, item, 0 );
            if ( srcIndex >= nimages )
            {
                result.Release();
                return E_FAIL;
            }

            const Image* srcimg = &srcImages[ srcIndex ];
            const Image* destimg = result.GetImage( 0, item, 0 );
            if ( !srcimg || !destimg )
            {
                result.Release();
                return E_POINTER;
            }

            if ( srcimg->format != metadata.format )
            {
                result.Release();
                return E_FAIL;
            }

#ifdef _M_X64
            if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) )
            {
                result.Release();
                return E_FAIL;
            }
#endif

            if ( usewic )
            {
                if ( wicpf )
                {
                    // Case 1: Source format is supported by Windows Imaging Component
                    hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg );
                }
                else
                {
                    // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
                    hr = _PerformResizeViaF32( *srcimg, filter, *destimg );
                }
            }
            else
            {
                // Case 3: not using WIC resizing
                hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg );
            }

            if ( FAILED(hr) )
            {
                result.Release();
                return hr;
            }
        }
        break;

    case TEX_DIMENSION_TEXTURE3D:
        assert( metadata.arraySize == 1 );

        for( size_t slice = 0; slice < metadata.depth; ++slice )
        {
            size_t srcIndex = metadata.ComputeIndex( 0, 0, slice );
            if ( srcIndex >= nimages )
            {
                result.Release();
                return E_FAIL;
            }

            const Image* srcimg = &srcImages[ srcIndex ];
            const Image* destimg = result.GetImage( 0, 0, slice );
            if ( !srcimg || !destimg )
            {
                result.Release();
                return E_POINTER;
            }

            if ( srcimg->format != metadata.format )
            {
                result.Release();
                return E_FAIL;
            }

#ifdef _M_X64
            if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) )
            {
                result.Release();
                return E_FAIL;
            }
#endif

            if ( usewic )
            {
                if ( wicpf )
                {
                    // Case 1: Source format is supported by Windows Imaging Component
                    hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg );
                }
                else
                {
                    // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
                    hr = _PerformResizeViaF32( *srcimg, filter, *destimg );
                }
            }
            else
            {
                // Case 3: not using WIC resizing
                hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg );
            }

            if ( FAILED(hr) )
            {
                result.Release();
                return hr;
            }
        }
        break;

    default:
        result.Release();
        return E_FAIL;
    }

    return S_OK;
}
//-------------------------------------------------------------------------------------
// Converts to a premultiplied alpha version of the texture (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetadata& metadata, ScratchImage& result )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed(metadata.format)
         || IsVideo(metadata.format)
         || IsTypeless(metadata.format)
         || !HasAlpha(metadata.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

#ifdef _M_X64
    if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    if ( metadata.IsPMAlpha() )
    {
        // Already premultiplied
        return E_FAIL;
    }

    TexMetadata mdata2 = metadata;
    mdata2.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED);
    HRESULT hr = result.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != result.GetImageCount() )
    {
        result.Release();
        return E_FAIL;
    }

    const Image* dest = result.GetImages();
    if ( !dest )
    {
        result.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        const Image& src = srcImages[ index ];
        if ( src.format != metadata.format )
        {
            result.Release();
            return E_FAIL;
        }

#ifdef _M_X64
        if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) )
            return E_FAIL;
#endif
        const Image& dst = dest[ index ];
        assert( dst.format == metadata.format );

        if ( src.width != dst.width || src.height != dst.height )
        {
            result.Release();
            return E_FAIL;
        }

        hr = _PremultiplyAlpha( src, dst );
        if ( FAILED(hr) )
        {
            result.Release();
            return hr;
        }
    }

    return S_OK;
}