Пример #1
0
//-------------------------------------------------------------------------------------
// Resize image
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter, ScratchImage& image )
{
    if ( width == 0 || height == 0 )
        return E_INVALIDARG;

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

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

    if ( !srcImage.pixels )
        return E_POINTER;

    if ( IsCompressed( srcImage.format ) )
    {
        // We don't support resizing compressed images
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    HRESULT hr = image.Initialize2D( srcImage.format, width, height, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
        return E_POINTER;

    if ( _UseWICFiltering( srcImage.format, filter ) )
    {
        WICPixelFormatGUID pfGUID;
        if ( _DXGIToWIC( srcImage.format, pfGUID, true ) )
        {
            // Case 1: Source format is supported by Windows Imaging Component
            hr = _PerformResizeUsingWIC( srcImage, filter, pfGUID, *rimage );
        }
        else
        {
            // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
            hr = _PerformResizeViaF32( srcImage, filter, *rimage );
        }
    }
    else
    {
        hr = _PerformResizeUsingCustomFilters( srcImage, filter, *rimage );
    }

    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
Пример #2
0
//-------------------------------------------------------------------------------------
// Compression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
{
    if ( IsCompressed(srcImage.format) || !IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    // Image size must be a multiple of 4 (degenerate cases for mipmaps are allowed)
    bool degenerate = false;

    size_t width = srcImage.width;
    if ( (width % 4) != 0 )
    {
        if ( width != 1 && width != 2 )
            return E_INVALIDARG;

        degenerate = true;
    }

    size_t height = srcImage.height;
    if ( (height % 4) != 0 )
    {
        if ( height != 1 && height != 2 )
            return E_INVALIDARG;

        degenerate = true;
    }

    // Create compressed image
    HRESULT hr = image.Initialize2D( format, width, height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Compress single image
    if ( (compress & TEX_COMPRESS_PARALLEL) && !degenerate )
    {
#ifndef _OPENMP
        return E_NOTIMPL;
#else
        hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), alphaRef );
#endif // _OPENMP
    }
    else
    {
        hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), alphaRef, degenerate );
    }

    if ( FAILED(hr) )
        image.Release();

    return hr;
}
Пример #3
0
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::Decompress(
    const Image& cImage,
    DXGI_FORMAT format,
    ScratchImage& image)
{
    if (!IsCompressed(cImage.format) || IsCompressed(format))
        return E_INVALIDARG;

    if (format == DXGI_FORMAT_UNKNOWN)
    {
        // Pick a default decompressed format based on BC input format
        format = DefaultDecompress(cImage.format);
        if (format == DXGI_FORMAT_UNKNOWN)
        {
            // Input is not a compressed format
            return E_INVALIDARG;
        }
    }
    else
    {
        if (!IsValid(format))
            return E_INVALIDARG;

        if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format))
            return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
    }

    // Create decompressed image
    HRESULT hr = image.Initialize2D(format, cImage.width, cImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *img = image.GetImage(0, 0, 0);
    if (!img)
    {
        image.Release();
        return E_POINTER;
    }

    // Decompress single image
    hr = DecompressBC(cImage, *img);
    if (FAILED(hr))
        image.Release();

    return hr;
}
Пример #4
0
//-------------------------------------------------------------------------------------
// Converts to/from a premultiplied alpha version of the texture
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::PremultiplyAlpha(
    const Image& srcImage,
    DWORD flags,
    ScratchImage& image)
{
    if (!srcImage.pixels)
        return E_POINTER;

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

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

    HRESULT hr = image.Initialize2D(srcImage.format, srcImage.width, srcImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *rimage = image.GetImage(0, 0, 0);
    if (!rimage)
    {
        image.Release();
        return E_POINTER;
    }

    if (flags & TEX_PMALPHA_REVERSE)
    {
        hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? DemultiplyAlpha(srcImage, *rimage) : DemultiplyAlphaLinear(srcImage, flags, *rimage);
    }
    else
    {
        hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(srcImage, *rimage) : PremultiplyAlphaLinear(srcImage, flags, *rimage);
    }
    if (FAILED(hr))
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
Пример #5
0
//-------------------------------------------------------------------------------------
// Compression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::Compress(
    const Image& srcImage,
    DXGI_FORMAT format,
    DWORD compress,
    float threshold,
    ScratchImage& image)
{
    if (IsCompressed(srcImage.format) || !IsCompressed(format))
        return E_INVALIDARG;

    if (IsTypeless(format)
        || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format))
        return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);

    // Create compressed image
    HRESULT hr = image.Initialize2D(format, srcImage.width, srcImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *img = image.GetImage(0, 0, 0);
    if (!img)
    {
        image.Release();
        return E_POINTER;
    }

    // Compress single image
    if (compress & TEX_COMPRESS_PARALLEL)
    {
#ifndef _OPENMP
        return E_NOTIMPL;
#else
        hr = CompressBC_Parallel(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), threshold);
#endif // _OPENMP
    }
    else
    {
        hr = CompressBC(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), threshold);
    }

    if (FAILED(hr))
        image.Release();

    return hr;
}
Пример #6
0
//-------------------------------------------------------------------------------------
// Do conversion, flip/rotate using WIC, conversion cycle
//-------------------------------------------------------------------------------------
static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage )
{
    if ( !srcImage.pixels || !destImage.pixels )
        return E_POINTER;

    assert( srcImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
    assert( srcImage.format == destImage.format );

    ScratchImage temp;
    HRESULT hr = _ConvertToR32G32B32A32( srcImage, temp );
    if ( FAILED(hr) )
        return hr;

    const Image *tsrc = temp.GetImage( 0, 0, 0 );
    if ( !tsrc )
        return E_POINTER;

    ScratchImage rtemp;
    hr = rtemp.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, destImage.width, destImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *tdest = rtemp.GetImage( 0, 0, 0 );
    if ( !tdest )
        return E_POINTER;

    hr = _PerformFlipRotateUsingWIC( *tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest );
    if ( FAILED(hr) )
        return hr;

    temp.Release();

    hr = _ConvertFromR32G32B32A32( *tdest, destImage );
    if ( FAILED(hr) )
        return hr;

    return S_OK;
}
Пример #7
0
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
{
    if ( IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        // Pick a default decompressed format based on BC input format
        format = _DefaultDecompress( cImage.format );
        if ( format == DXGI_FORMAT_UNKNOWN )
        {
            // Input is not a compressed format
            return E_INVALIDARG;
        }
    }
    else if ( !IsCompressed(cImage.format) || !IsValid(format) )
        return E_INVALIDARG;

    // Create decompressed image
    HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Decompress single image
    hr = _DecompressBC( cImage, *img );
    if ( FAILED(hr) )
        image.Release();

    return hr;
}
Пример #8
0
//-------------------------------------------------------------------------------------
// Converts to a premultiplied alpha version of the texture
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image& srcImage, ScratchImage& image )
{
    if ( !srcImage.pixels )
        return E_POINTER;

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

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

    HRESULT hr = image.Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
    {
        image.Release();
        return E_POINTER;
    }

    hr = _PremultiplyAlpha( srcImage, *rimage );
    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
Пример #9
0
//-------------------------------------------------------------------------------------
// Flip/rotate image
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image )
{
    if ( !srcImage.pixels )
        return E_POINTER;

    if ( !flags )
        return E_INVALIDARG;

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

    if ( IsCompressed( srcImage.format ) )
    {
        // We don't support flip/rotate operations on compressed images
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" );
    static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" );
    static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" );

    // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags
    switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) )
    {
    case 0:
    case TEX_FR_ROTATE90:
    case TEX_FR_ROTATE180:
    case TEX_FR_ROTATE270:
        break;

    default:
        return E_INVALIDARG;
    }

    size_t nwidth = srcImage.width;
    size_t nheight = srcImage.height;

    if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270))
    {
        nwidth = srcImage.height;
        nheight = srcImage.width;
    }

    HRESULT hr = image.Initialize2D( srcImage.format, nwidth, nheight, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
        return E_POINTER;

    WICPixelFormatGUID pfGUID;
    if ( _DXGIToWIC( srcImage.format, pfGUID ) )
    {
        // Case 1: Source format is supported by Windows Imaging Component
        hr = _PerformFlipRotateUsingWIC( srcImage, flags, pfGUID, *rimage );
    }
    else
    {
        // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
        hr = _PerformFlipRotateViaF32( srcImage, flags, *rimage );
    }

    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}