summaryrefslogtreecommitdiff
path: root/thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp')
-rw-r--r--thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp413
1 files changed, 263 insertions, 150 deletions
diff --git a/thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp b/thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp
index 9c1bfbd8..52fb3d45 100644
--- a/thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp
+++ b/thirdparty/directxtex/DirectXTex/DirectXTexCompress.cpp
@@ -17,11 +17,12 @@
#ifdef _OPENMP
#include <omp.h>
-#pragma warning(disable : 4616 6001 6993)
+#pragma warning(disable : 4616 6993)
#endif
#include "BC.h"
+
namespace DirectX
{
@@ -31,13 +32,46 @@ inline static DWORD _GetBCFlags( _In_ DWORD compress )
static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
- return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM) );
+ static_assert( TEX_COMPRESS_BC7_USE_3SUBSETS == BC_FLAGS_USE_3SUBSETS, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
+ return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM|BC_FLAGS_USE_3SUBSETS) );
+}
+
+inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
+{
+ static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+ static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+ static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+ return ( compress & TEX_COMPRESS_SRGB );
+}
+
+inline static bool _DetermineEncoderSettings( _In_ DXGI_FORMAT format, _Out_ BC_ENCODE& pfEncode, _Out_ size_t& blocksize, _Out_ DWORD& cflags )
+{
+ switch(format)
+ {
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB: pfEncode = nullptr; blocksize = 8; cflags = 0; break;
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB: pfEncode = D3DXEncodeBC2; blocksize = 16; cflags = 0; break;
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB: pfEncode = D3DXEncodeBC3; blocksize = 16; cflags = 0; break;
+ case DXGI_FORMAT_BC4_UNORM: pfEncode = D3DXEncodeBC4U; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break;
+ case DXGI_FORMAT_BC4_SNORM: pfEncode = D3DXEncodeBC4S; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break;
+ case DXGI_FORMAT_BC5_UNORM: pfEncode = D3DXEncodeBC5U; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
+ case DXGI_FORMAT_BC5_SNORM: pfEncode = D3DXEncodeBC5S; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
+ case DXGI_FORMAT_BC6H_UF16: pfEncode = D3DXEncodeBC6HU; blocksize = 16; cflags = 0; break;
+ case DXGI_FORMAT_BC6H_SF16: pfEncode = D3DXEncodeBC6HS; blocksize = 16; cflags = 0; break;
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB: pfEncode = D3DXEncodeBC7; blocksize = 16; cflags = 0; break;
+ default: pfEncode = nullptr; blocksize = 0; cflags = 0; return false;
+ }
+
+ return true;
}
//-------------------------------------------------------------------------------------
static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
- _In_ float alphaRef, _In_ bool degenerate )
+ _In_ DWORD srgb, _In_ float alphaRef )
{
if ( !image.pixels || !result.pixels )
return E_POINTER;
@@ -64,25 +98,9 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
// Determine BC format encoder
BC_ENCODE pfEncode;
size_t blocksize;
- switch(result.format)
- {
- case DXGI_FORMAT_BC1_UNORM:
- case DXGI_FORMAT_BC1_UNORM_SRGB: pfEncode = nullptr; blocksize = 8; break;
- case DXGI_FORMAT_BC2_UNORM:
- case DXGI_FORMAT_BC2_UNORM_SRGB: pfEncode = D3DXEncodeBC2; blocksize = 16; break;
- case DXGI_FORMAT_BC3_UNORM:
- case DXGI_FORMAT_BC3_UNORM_SRGB: pfEncode = D3DXEncodeBC3; blocksize = 16; break;
- case DXGI_FORMAT_BC4_UNORM: pfEncode = D3DXEncodeBC4U; blocksize = 8; break;
- case DXGI_FORMAT_BC4_SNORM: pfEncode = D3DXEncodeBC4S; blocksize = 8; break;
- case DXGI_FORMAT_BC5_UNORM: pfEncode = D3DXEncodeBC5U; blocksize = 16; break;
- case DXGI_FORMAT_BC5_SNORM: pfEncode = D3DXEncodeBC5S; blocksize = 16; break;
- case DXGI_FORMAT_BC6H_UF16: pfEncode = D3DXEncodeBC6HU; blocksize = 16; break;
- case DXGI_FORMAT_BC6H_SF16: pfEncode = D3DXEncodeBC6HS; blocksize = 16; break;
- case DXGI_FORMAT_BC7_UNORM:
- case DXGI_FORMAT_BC7_UNORM_SRGB: pfEncode = D3DXEncodeBC7; blocksize = 16; break;
- default:
+ DWORD cflags;
+ if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
- }
XMVECTOR temp[16];
const uint8_t *pSrc = image.pixels;
@@ -91,55 +109,65 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
{
const uint8_t *sptr = pSrc;
uint8_t* dptr = pDest;
- for( size_t count = 0; count < rowPitch; count += sbpp*4 )
+ size_t ph = std::min<size_t>( 4, image.height - h );
+ size_t w = 0;
+ for( size_t count = 0; (count < result.rowPitch) && (w < image.width); count += blocksize, w += 4 )
{
- if ( !_LoadScanline( &temp[0], 4, sptr, rowPitch, format ) )
+ size_t pw = std::min<size_t>( 4, image.width - w );
+ assert( pw > 0 && ph > 0 );
+
+ if ( !_LoadScanline( &temp[0], pw, sptr, rowPitch, format ) )
return E_FAIL;
- if ( image.height > 1 )
+ if ( ph > 1 )
{
- if ( !_LoadScanline( &temp[4], 4, sptr + rowPitch, rowPitch, format ) )
+ if ( !_LoadScanline( &temp[4], pw, sptr + rowPitch, rowPitch, format ) )
return E_FAIL;
- if ( image.height > 2 )
+ if ( ph > 2 )
{
- if ( !_LoadScanline( &temp[8], 4, sptr + rowPitch*2, rowPitch, format ) )
+ if ( !_LoadScanline( &temp[8], pw, sptr + rowPitch*2, rowPitch, format ) )
return E_FAIL;
- if ( !_LoadScanline( &temp[12], 4, sptr + rowPitch*3, rowPitch, format ) )
- return E_FAIL;
+ if ( ph > 3 )
+ {
+ if ( !_LoadScanline( &temp[12], pw, sptr + rowPitch*3, rowPitch, format ) )
+ return E_FAIL;
+ }
}
}
- if ( degenerate )
+ if ( pw != 4 || ph != 4 )
{
- assert( image.width < 4 || image.height < 4 );
- const size_t uSrc[] = { 0, 0, 0, 1 };
+ // Replicate pixels for partial block
+ static const size_t uSrc[] = { 0, 0, 0, 1 };
- if ( image.width < 4 )
+ if ( pw < 4 )
{
- for( size_t t=0; t < image.height && t < 4; ++t )
+ for( size_t t = 0; t < ph && t < 4; ++t )
{
- for( size_t s = image.width; s < 4; ++s )
+ for( size_t s = pw; s < 4; ++s )
{
- temp[ t*4 + s ] = temp[ t*4 + uSrc[s] ];
+#pragma prefast(suppress: 26000, "PREFAST false positive")
+ temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ];
}
}
}
- if ( image.height < 4 )
+ if ( ph < 4 )
{
- for( size_t t=image.height; t < 4; ++t )
+ for( size_t t = ph; t < 4; ++t )
{
- for( size_t s =0; s < 4; ++s )
+ for( size_t s = 0; s < 4; ++s )
{
- temp[ t*4 + s ] = temp[ uSrc[t]*4 + s ];
+#pragma prefast(suppress: 26000, "PREFAST false positive")
+ temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ];
}
}
}
}
- _ConvertScanline( temp, 16, result.format, format, 0 );
+ _ConvertScanline( temp, 16, result.format, format, cflags | srgb );
if ( pfEncode )
pfEncode( dptr, temp, bcflags );
@@ -161,14 +189,11 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
//-------------------------------------------------------------------------------------
#ifdef _OPENMP
static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
- _In_ float alphaRef )
+ _In_ DWORD srgb, _In_ float alphaRef )
{
if ( !image.pixels || !result.pixels )
return E_POINTER;
- // Parallel version doesn't support degenerate case
- assert( ((image.width % 4) == 0) && ((image.height % 4) == 0 ) );
-
assert( image.width == result.width );
assert( image.height == result.height );
@@ -189,35 +214,19 @@ static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image&
// Determine BC format encoder
BC_ENCODE pfEncode;
size_t blocksize;
- switch(result.format)
- {
- case DXGI_FORMAT_BC1_UNORM:
- case DXGI_FORMAT_BC1_UNORM_SRGB: pfEncode = nullptr; blocksize = 8; break;
- case DXGI_FORMAT_BC2_UNORM:
- case DXGI_FORMAT_BC2_UNORM_SRGB: pfEncode = D3DXEncodeBC2; blocksize = 16; break;
- case DXGI_FORMAT_BC3_UNORM:
- case DXGI_FORMAT_BC3_UNORM_SRGB: pfEncode = D3DXEncodeBC3; blocksize = 16; break;
- case DXGI_FORMAT_BC4_UNORM: pfEncode = D3DXEncodeBC4U; blocksize = 8; break;
- case DXGI_FORMAT_BC4_SNORM: pfEncode = D3DXEncodeBC4S; blocksize = 8; break;
- case DXGI_FORMAT_BC5_UNORM: pfEncode = D3DXEncodeBC5U; blocksize = 16; break;
- case DXGI_FORMAT_BC5_SNORM: pfEncode = D3DXEncodeBC5S; blocksize = 16; break;
- case DXGI_FORMAT_BC6H_UF16: pfEncode = D3DXEncodeBC6HU; blocksize = 16; break;
- case DXGI_FORMAT_BC6H_SF16: pfEncode = D3DXEncodeBC6HS; blocksize = 16; break;
- case DXGI_FORMAT_BC7_UNORM:
- case DXGI_FORMAT_BC7_UNORM_SRGB: pfEncode = D3DXEncodeBC7; blocksize = 16; break;
- default:
+ DWORD cflags;
+ if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
- }
// Refactored version of loop to support parallel independance
- const size_t nBlocks = std::max<size_t>(1, image.width / 4) * std::max<size_t>(1, image.height / 4);
+ const size_t nBlocks = std::max<size_t>(1, (image.width + 3) / 4 ) * std::max<size_t>(1, (image.height + 3) / 4 );
bool fail = false;
#pragma omp parallel for
for( int nb=0; nb < static_cast<int>( nBlocks ); ++nb )
{
- const size_t nbWidth = std::max<size_t>(1, image.width / 4);
+ const size_t nbWidth = std::max<size_t>(1, (image.width + 3) / 4 );
const size_t y = nb / nbWidth;
const size_t x = nb - (y*nbWidth);
@@ -229,20 +238,61 @@ static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image&
uint8_t *pDest = result.pixels + (nb*blocksize);
+ size_t ph = std::min<size_t>( 4, image.height - y );
+ size_t pw = std::min<size_t>( 4, image.width - x );
+ assert( pw > 0 && ph > 0 );
+
XMVECTOR temp[16];
- if ( !_LoadScanline( &temp[0], 4, pSrc, rowPitch, format ) )
+ if ( !_LoadScanline( &temp[0], pw, pSrc, rowPitch, format ) )
fail = true;
- if ( !_LoadScanline( &temp[4], 4, pSrc + rowPitch, rowPitch, format ) )
- fail = true;
+ if ( ph > 1 )
+ {
+ if ( !_LoadScanline( &temp[4], pw, pSrc + rowPitch, rowPitch, format ) )
+ fail = true;
- if ( !_LoadScanline( &temp[8], 4, pSrc + rowPitch*2, rowPitch, format ) )
- fail = true;
+ if ( ph > 2 )
+ {
+ if ( !_LoadScanline( &temp[8], pw, pSrc + rowPitch*2, rowPitch, format ) )
+ fail = true;
- if ( !_LoadScanline( &temp[12], 4, pSrc + rowPitch*3, rowPitch, format ) )
- fail = true;
+ if ( ph > 3 )
+ {
+ if ( !_LoadScanline( &temp[12], pw, pSrc + rowPitch*3, rowPitch, format ) )
+ fail = true;
+ }
+ }
+ }
+
+ if ( pw != 4 || ph != 4 )
+ {
+ // Replicate pixels for partial block
+ static const size_t uSrc[] = { 0, 0, 0, 1 };
+
+ if ( pw < 4 )
+ {
+ for( size_t t = 0; t < ph && t < 4; ++t )
+ {
+ for( size_t s = pw; s < 4; ++s )
+ {
+ temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ];
+ }
+ }
+ }
+
+ if ( ph < 4 )
+ {
+ for( size_t t = ph; t < 4; ++t )
+ {
+ for( size_t s = 0; s < 4; ++s )
+ {
+ temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ];
+ }
+ }
+ }
+ }
- _ConvertScanline( temp, 16, result.format, format, 0 );
+ _ConvertScanline( temp, 16, result.format, format, cflags | srgb );
if ( pfEncode )
pfEncode( pDest, temp, bcflags );
@@ -313,21 +363,6 @@ static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result
assert( cImage.width == result.width );
assert( cImage.height == result.height );
- // Image must be a multiple of 4 (degenerate cases of 1x1, 1x2, 2x1, and 2x2 are allowed)
- size_t width = cImage.width;
- if ( (width % 4) != 0 )
- {
- if ( width != 1 && width != 2 )
- return E_INVALIDARG;
- }
-
- size_t height = cImage.height;
- if ( (height % 4) != 0 )
- {
- if ( height != 1 && height != 2 )
- return E_INVALIDARG;
- }
-
const DXGI_FORMAT format = result.format;
size_t dbpp = BitsPerPixel( format );
if ( !dbpp )
@@ -390,26 +425,34 @@ static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result
{
const uint8_t *sptr = pSrc;
uint8_t* dptr = pDest;
- for( size_t count = 0; count < cImage.rowPitch; count += sbpp )
+ size_t ph = std::min<size_t>( 4, cImage.height - h );
+ size_t w = 0;
+ for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 )
{
pfDecode( temp, sptr );
_ConvertScanline( temp, 16, format, cformat, 0 );
- if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], 4 ) )
+ size_t pw = std::min<size_t>( 4, cImage.width - w );
+ assert( pw > 0 && ph > 0 );
+
+ if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], pw ) )
return E_FAIL;
- if ( result.height > 1 )
+ if ( ph > 1 )
{
- if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], 4 ) )
+ if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], pw ) )
return E_FAIL;
- if ( result.height > 2 )
+ if ( ph > 2 )
{
- if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], 4 ) )
+ if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], pw ) )
return E_FAIL;
- if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], 4 ) )
- return E_FAIL;
+ if ( ph > 3 )
+ {
+ if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], pw ) )
+ return E_FAIL;
+ }
}
}
@@ -425,6 +468,92 @@ static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result
}
+//-------------------------------------------------------------------------------------
+bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
+{
+ if ( !cImage.pixels )
+ return false;
+
+ // Promote "typeless" BC formats
+ DXGI_FORMAT cformat;
+ switch( cImage.format )
+ {
+ case DXGI_FORMAT_BC1_TYPELESS: cformat = DXGI_FORMAT_BC1_UNORM; break;
+ case DXGI_FORMAT_BC2_TYPELESS: cformat = DXGI_FORMAT_BC2_UNORM; break;
+ case DXGI_FORMAT_BC3_TYPELESS: cformat = DXGI_FORMAT_BC3_UNORM; break;
+ case DXGI_FORMAT_BC7_TYPELESS: cformat = DXGI_FORMAT_BC7_UNORM; break;
+ default: cformat = cImage.format; break;
+ }
+
+ // Determine BC format decoder
+ BC_DECODE pfDecode;
+ size_t sbpp;
+ switch(cformat)
+ {
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB: pfDecode = D3DXDecodeBC1; sbpp = 8; break;
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB: pfDecode = D3DXDecodeBC2; sbpp = 16; break;
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB: pfDecode = D3DXDecodeBC3; sbpp = 16; break;
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break;
+ default:
+ // BC4, BC5, and BC6 don't have alpha channels
+ return false;
+ }
+
+ // Scan blocks for non-opaque alpha
+ static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
+
+ XMVECTOR temp[16];
+ const uint8_t *pPixels = cImage.pixels;
+ for( size_t h = 0; h < cImage.height; h += 4 )
+ {
+ const uint8_t *ptr = pPixels;
+ size_t ph = std::min<size_t>( 4, cImage.height - h );
+ size_t w = 0;
+ for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 )
+ {
+ pfDecode( temp, ptr );
+
+ size_t pw = std::min<size_t>( 4, cImage.width - w );
+ assert( pw > 0 && ph > 0 );
+
+ if ( pw == 4 && ph == 4 )
+ {
+ // Full blocks
+ for( size_t j = 0; j < 16; ++j )
+ {
+ XMVECTOR alpha = XMVectorSplatW( temp[j] );
+ if ( XMVector4Less( alpha, threshold ) )
+ return false;
+ }
+ }
+ else
+ {
+ // Handle partial blocks
+ for( size_t y = 0; y < ph; ++y )
+ {
+ for( size_t x = 0; x < pw; ++x )
+ {
+ XMVECTOR alpha = XMVectorSplatW( temp[ y * 4 + x ] );
+ if ( XMVector4Less( alpha, threshold ) )
+ return false;
+ }
+ }
+ }
+
+ ptr += sbpp;
+ }
+
+ pPixels += cImage.rowPitch;
+ }
+
+ return true;
+}
+
+
//=====================================================================================
// Entry-points
//=====================================================================================
@@ -432,34 +561,18 @@ static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result
//-------------------------------------------------------------------------------------
// 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) )
+ if ( IsCompressed(srcImage.format) || !IsCompressed(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;
- }
+ 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, width, height, 1, 1 );
+ HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
if ( FAILED(hr) )
return hr;
@@ -471,17 +584,17 @@ HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, flo
}
// Compress single image
- if ( (compress & TEX_COMPRESS_PARALLEL) && !degenerate )
+ if (compress & TEX_COMPRESS_PARALLEL)
{
#ifndef _OPENMP
return E_NOTIMPL;
#else
- hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), alphaRef );
+ hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
#endif // _OPENMP
}
else
{
- hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), alphaRef, degenerate );
+ hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
}
if ( FAILED(hr) )
@@ -490,29 +603,19 @@ HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, flo
return hr;
}
+_Use_decl_annotations_
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
{
if ( !srcImages || !nimages )
return E_INVALIDARG;
- if ( !IsCompressed(format) || IsTypeless(format) )
+ if ( IsCompressed(metadata.format) || !IsCompressed(format) )
return E_INVALIDARG;
- // Image size must be a multiple of 4 (degenerate cases for mipmaps are allowed)
- size_t width = srcImages[0].width;
- if ( (width % 4) != 0 )
- {
- if ( width != 1 && width != 2 )
- return E_INVALIDARG;
- }
-
- size_t height = srcImages[0].height;
- if ( (height % 4) != 0 )
- {
- if ( height != 1 && height != 2 )
- return E_INVALIDARG;
- }
+ if ( IsTypeless(format)
+ || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
cImages.Release();
@@ -541,24 +644,20 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
const Image& src = srcImages[ index ];
- height = src.height;
- width = src.width;
- if ( width != dest[ index ].width || height != dest[ index ].height )
+ if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
{
cImages.Release();
return E_FAIL;
}
- bool degenerate = ((height < 4) || (width < 4)) != 0;
-
- if ( (compress & TEX_COMPRESS_PARALLEL) && !degenerate)
+ if ( (compress & TEX_COMPRESS_PARALLEL) )
{
#ifndef _OPENMP
return E_NOTIMPL;
#else
if ( compress & TEX_COMPRESS_PARALLEL )
{
- hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), alphaRef );
+ hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
if ( FAILED(hr) )
{
cImages.Release();
@@ -569,7 +668,7 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
}
else
{
- hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), alphaRef, degenerate );
+ hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
if ( FAILED(hr) )
{
cImages.Release();
@@ -585,9 +684,10 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
{
- if ( IsCompressed(format) || IsTypeless(format) )
+ if ( !IsCompressed(cImage.format) || IsCompressed(format) )
return E_INVALIDARG;
if ( format == DXGI_FORMAT_UNKNOWN )
@@ -600,8 +700,14 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
return E_INVALIDARG;
}
}
- else if ( !IsCompressed(cImage.format) || !IsValid(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 );
@@ -623,13 +729,14 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
return hr;
}
+_Use_decl_annotations_
HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata,
DXGI_FORMAT format, ScratchImage& images )
{
if ( !cImages || !nimages )
return E_INVALIDARG;
- if ( IsCompressed(format) || IsTypeless(format) )
+ if ( !IsCompressed(metadata.format) || IsCompressed(format) )
return E_INVALIDARG;
if ( format == DXGI_FORMAT_UNKNOWN )
@@ -642,8 +749,14 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
return E_FAIL;
}
}
- else if ( !IsValid(format) )
- return E_INVALIDARG;
+ else
+ {
+ if ( !IsValid(format) )
+ return E_INVALIDARG;
+
+ if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
+ HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ }
images.Release();