General code cleanuP

This commit is contained in:
Chuck Walbourn 2016-09-08 19:09:46 -07:00
parent 53e66ba1e9
commit 51bc3d5b16
28 changed files with 13052 additions and 12638 deletions

View File

@ -165,21 +165,11 @@ namespace
} }
// open the file // open the file
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( fileName, ScopedHandle hFile( safe_handle( CreateFile2( fileName,
GENERIC_READ, GENERIC_READ,
FILE_SHARE_READ, FILE_SHARE_READ,
OPEN_EXISTING, OPEN_EXISTING,
nullptr ) ) ); nullptr ) ) );
#else
ScopedHandle hFile( safe_handle( CreateFileW( fileName,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr ) ) );
#endif
if ( !hFile ) if ( !hFile )
{ {

View File

@ -21,23 +21,23 @@
#include "BC.h" #include "BC.h"
using namespace DirectX;
using namespace DirectX::PackedVector; using namespace DirectX::PackedVector;
namespace DirectX namespace
{ {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Constants // Constants
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Perceptual weightings for the importance of each channel. // Perceptual weightings for the importance of each channel.
static const HDRColorA g_Luminance (0.2125f / 0.7154f, 1.0f, 0.0721f / 0.7154f, 1.0f); const HDRColorA g_Luminance(0.2125f / 0.7154f, 1.0f, 0.0721f / 0.7154f, 1.0f);
static const HDRColorA g_LuminanceInv(0.7154f / 0.2125f, 1.0f, 0.7154f / 0.0721f, 1.0f); const HDRColorA g_LuminanceInv(0.7154f / 0.2125f, 1.0f, 0.7154f / 0.0721f, 1.0f);
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decode/Encode RGB 5/6/5 colors // Decode/Encode RGB 5/6/5 colors
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
inline static void Decode565(_Out_ HDRColorA *pColor, _In_ const uint16_t w565) inline void Decode565(_Out_ HDRColorA *pColor, _In_ const uint16_t w565)
{ {
pColor->r = (float)((w565 >> 11) & 31) * (1.0f / 31.0f); pColor->r = (float)((w565 >> 11) & 31) * (1.0f / 31.0f);
pColor->g = (float)((w565 >> 5) & 63) * (1.0f / 63.0f); pColor->g = (float)((w565 >> 5) & 63) * (1.0f / 63.0f);
@ -45,7 +45,7 @@ inline static void Decode565(_Out_ HDRColorA *pColor, _In_ const uint16_t w565)
pColor->a = 1.0f; pColor->a = 1.0f;
} }
inline static uint16_t Encode565(_In_ const HDRColorA *pColor) inline uint16_t Encode565(_In_ const HDRColorA *pColor)
{ {
HDRColorA Color; HDRColorA Color;
@ -64,8 +64,12 @@ inline static uint16_t Encode565(_In_ const HDRColorA *pColor)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static void OptimizeRGB(_Out_ HDRColorA *pX, _Out_ HDRColorA *pY, void OptimizeRGB(
_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pPoints, _In_ size_t cSteps, _In_ DWORD flags) _Out_ HDRColorA *pX,
_Out_ HDRColorA *pY,
_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pPoints,
size_t cSteps,
DWORD flags)
{ {
static const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f); static const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f);
static const float pC3[] = { 2.0f / 2.0f, 1.0f / 2.0f, 0.0f / 2.0f }; static const float pC3[] = { 2.0f / 2.0f, 1.0f / 2.0f, 0.0f / 2.0f };
@ -207,7 +211,6 @@ static void OptimizeRGB(_Out_ HDRColorA *pX, _Out_ HDRColorA *pY,
return; return;
} }
// Use Newton's Method to find local minima of sum-of-squares error. // Use Newton's Method to find local minima of sum-of-squares error.
float fSteps = (float)(cSteps - 1); float fSteps = (float)(cSteps - 1);
@ -286,7 +289,6 @@ static void OptimizeRGB(_Out_ HDRColorA *pX, _Out_ HDRColorA *pY,
dY.b += fD * Diff.b; dY.b += fD * Diff.b;
} }
// Move endpoints // Move endpoints
if (d2X > 0.0f) if (d2X > 0.0f)
{ {
@ -319,7 +321,10 @@ static void OptimizeRGB(_Out_ HDRColorA *pX, _Out_ HDRColorA *pY,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
inline static void DecodeBC1( _Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_ const D3DX_BC1 *pBC, _In_ bool isbc1 ) inline void DecodeBC1(
_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor,
_In_ const D3DX_BC1 *pBC,
bool isbc1)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes"); static_assert(sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes");
@ -368,9 +373,12 @@ inline static void DecodeBC1( _Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColo
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
void EncodeBC1(
static void EncodeBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor, _Out_ D3DX_BC1 *pBC,
_In_ bool bColorKey, _In_ float alphaRef, _In_ DWORD flags) _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor,
bool bColorKey,
float alphaRef,
DWORD flags)
{ {
assert(pBC && pColor); assert(pBC && pColor);
static_assert(sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes"); static_assert(sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes");
@ -678,7 +686,7 @@ static void EncodeBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) cons
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#ifdef COLOR_WEIGHTS #ifdef COLOR_WEIGHTS
static void EncodeSolidBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor) void EncodeSolidBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor)
{ {
#ifdef COLOR_AVG_0WEIGHTS #ifdef COLOR_AVG_0WEIGHTS
// Compute avg color // Compute avg color
@ -709,6 +717,7 @@ static void EncodeSolidBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK)
pBC->bitmap = 0x00000000; pBC->bitmap = 0x00000000;
} }
#endif // COLOR_WEIGHTS #endif // COLOR_WEIGHTS
}
//===================================================================================== //=====================================================================================
@ -719,14 +728,14 @@ static void EncodeSolidBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK)
// BC1 Compression // BC1 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC1(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC1(XMVECTOR *pColor, const uint8_t *pBC)
{ {
auto pBC1 = reinterpret_cast<const D3DX_BC1 *>(pBC); auto pBC1 = reinterpret_cast<const D3DX_BC1 *>(pBC);
DecodeBC1(pColor, pBC1, true); DecodeBC1(pColor, pBC1, true);
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC1(uint8_t *pBC, const XMVECTOR *pColor, float alphaRef, DWORD flags) void DirectX::D3DXEncodeBC1(uint8_t *pBC, const XMVECTOR *pColor, float alphaRef, DWORD flags)
{ {
assert(pBC && pColor); assert(pBC && pColor);
@ -791,7 +800,7 @@ void D3DXEncodeBC1(uint8_t *pBC, const XMVECTOR *pColor, float alphaRef, DWORD f
// BC2 Compression // BC2 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC2(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC2(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes"); static_assert(sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes");
@ -817,7 +826,7 @@ void D3DXDecodeBC2(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC2(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) void DirectX::D3DXEncodeBC2(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
assert(pBC && pColor); assert(pBC && pColor);
static_assert(sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes"); static_assert(sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes");
@ -894,7 +903,7 @@ void D3DXEncodeBC2(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
// BC3 Compression // BC3 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC3(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC3(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes"); static_assert(sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes");
@ -936,7 +945,7 @@ void D3DXDecodeBC3(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC3(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) void DirectX::D3DXEncodeBC3(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
assert(pBC && pColor); assert(pBC && pColor);
static_assert(sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes"); static_assert(sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes");
@ -1137,5 +1146,3 @@ void D3DXEncodeBC3(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
pBC3->bitmap[2 + iSet * 3] = ((uint8_t *)&dw)[2]; pBC3->bitmap[2 + iSet * 3] = ((uint8_t *)&dw)[2];
} }
} }
} // namespace

View File

@ -17,8 +17,7 @@
#include "BC.h" #include "BC.h"
namespace DirectX using namespace DirectX;
{
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Constants // Constants
@ -31,6 +30,8 @@ namespace DirectX
#define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN) #define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN)
// total texels in a 4x4 block. // total texels in a 4x4 block.
namespace
{
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Structures // Structures
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -158,7 +159,7 @@ struct BC4_SNORM
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert a floating point value to an 8-bit SNORM // Convert a floating point value to an 8-bit SNORM
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static void inline FloatToSNorm( _In_ float fVal, _Out_ int8_t *piSNorm ) void inline FloatToSNorm(_In_ float fVal, _Out_ int8_t *piSNorm)
{ {
const uint32_t dwMostNeg = (1 << (8 * sizeof(int8_t) - 1)); const uint32_t dwMostNeg = (1 << (8 * sizeof(int8_t) - 1));
@ -183,7 +184,10 @@ static void inline FloatToSNorm( _In_ float fVal, _Out_ int8_t *piSNorm )
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void FindEndPointsBC4U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1) void FindEndPointsBC4U(
_In_reads_(BLOCK_SIZE) const float theTexelsU[],
_Out_ uint8_t &endpointU_0,
_Out_ uint8_t &endpointU_1)
{ {
// The boundary of codec for signed/unsigned format // The boundary of codec for signed/unsigned format
float MIN_NORM; float MIN_NORM;
@ -237,7 +241,10 @@ static void FindEndPointsBC4U( _In_reads_(BLOCK_SIZE) const float theTexelsU[],
} }
} }
static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1) void FindEndPointsBC4S(
_In_reads_(BLOCK_SIZE) const float theTexelsU[],
_Out_ int8_t &endpointU_0,
_Out_ int8_t &endpointU_1)
{ {
// The boundary of codec for signed/unsigned format // The boundary of codec for signed/unsigned format
float MIN_NORM; float MIN_NORM;
@ -293,16 +300,26 @@ static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static inline void FindEndPointsBC5U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], inline void FindEndPointsBC5U(
_Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1, _Out_ uint8_t &endpointV_0, _Out_ uint8_t &endpointV_1) _In_reads_(BLOCK_SIZE) const float theTexelsU[],
_In_reads_(BLOCK_SIZE) const float theTexelsV[],
_Out_ uint8_t &endpointU_0,
_Out_ uint8_t &endpointU_1,
_Out_ uint8_t &endpointV_0,
_Out_ uint8_t &endpointV_1)
{ {
//Encoding the U and V channel by BC4 codec separately. //Encoding the U and V channel by BC4 codec separately.
FindEndPointsBC4U(theTexelsU, endpointU_0, endpointU_1); FindEndPointsBC4U(theTexelsU, endpointU_0, endpointU_1);
FindEndPointsBC4U(theTexelsV, endpointV_0, endpointV_1); FindEndPointsBC4U(theTexelsV, endpointV_0, endpointV_1);
} }
static inline void FindEndPointsBC5S( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], inline void FindEndPointsBC5S(
_Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1) _In_reads_(BLOCK_SIZE) const float theTexelsU[],
_In_reads_(BLOCK_SIZE) const float theTexelsV[],
_Out_ int8_t &endpointU_0,
_Out_ int8_t &endpointU_1,
_Out_ int8_t &endpointV_0,
_Out_ int8_t &endpointV_1)
{ {
//Encoding the U and V channel by BC4 codec separately. //Encoding the U and V channel by BC4 codec separately.
FindEndPointsBC4S(theTexelsU, endpointU_0, endpointU_1); FindEndPointsBC4S(theTexelsU, endpointU_0, endpointU_1);
@ -311,7 +328,9 @@ static inline void FindEndPointsBC5S( _In_reads_(BLOCK_SIZE) const float theTexe
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void FindClosestUNORM(_Inout_ BC4_UNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[]) void FindClosestUNORM(
_Inout_ BC4_UNORM* pBC,
_In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
{ {
float rGradient[8]; float rGradient[8];
int i; int i;
@ -336,7 +355,9 @@ static void FindClosestUNORM(_Inout_ BC4_UNORM* pBC, _In_reads_(NUM_PIXELS_PER_B
} }
} }
static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[]) void FindClosestSNORM(
_Inout_ BC4_SNORM* pBC,
_In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
{ {
float rGradient[8]; float rGradient[8];
int i; int i;
@ -360,6 +381,7 @@ static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_B
pBC->SetIndex(i, uBestIndex); pBC->SetIndex(i, uBestIndex);
} }
} }
}
//===================================================================================== //=====================================================================================
@ -370,7 +392,7 @@ static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_B
// BC4 Compression // BC4 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC4U( XMVECTOR *pColor, const uint8_t *pBC ) void DirectX::D3DXDecodeBC4U(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes"); static_assert(sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes");
@ -385,7 +407,7 @@ void D3DXDecodeBC4U( XMVECTOR *pColor, const uint8_t *pBC )
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes"); static_assert(sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes");
@ -400,7 +422,7 @@ void D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC4U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) void DirectX::D3DXEncodeBC4U(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
@ -421,7 +443,7 @@ void D3DXEncodeBC4U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC4S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) void DirectX::D3DXEncodeBC4S(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
@ -446,7 +468,7 @@ void D3DXEncodeBC4S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
// BC5 Compression // BC5 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes"); static_assert(sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes");
@ -462,7 +484,7 @@ void D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes"); static_assert(sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes");
@ -478,7 +500,7 @@ void D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC5U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) void DirectX::D3DXEncodeBC5U(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
@ -512,7 +534,7 @@ void D3DXEncodeBC5U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC5S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) void DirectX::D3DXEncodeBC5S(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
@ -544,5 +566,3 @@ void D3DXEncodeBC5S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
FindClosestSNORM(pBCR, theTexelsU); FindClosestSNORM(pBCR, theTexelsU);
FindClosestSNORM(pBCG, theTexelsV); FindClosestSNORM(pBCG, theTexelsV);
} }
} // namespace

View File

@ -17,27 +17,23 @@
#include "BC.h" #include "BC.h"
using namespace DirectX;
using namespace DirectX::PackedVector; using namespace DirectX::PackedVector;
namespace DirectX namespace
{ {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Constants // Constants
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f); const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f);
static const float pC3[] = { 2.0f/2.0f, 1.0f/2.0f, 0.0f/2.0f }; const float pC3[] = { 2.0f / 2.0f, 1.0f / 2.0f, 0.0f / 2.0f };
static const float pD3[] = { 0.0f/2.0f, 1.0f/2.0f, 2.0f/2.0f }; const float pD3[] = { 0.0f / 2.0f, 1.0f / 2.0f, 2.0f / 2.0f };
static const float pC4[] = { 3.0f/3.0f, 2.0f/3.0f, 1.0f/3.0f, 0.0f/3.0f }; const float pC4[] = { 3.0f / 3.0f, 2.0f / 3.0f, 1.0f / 3.0f, 0.0f / 3.0f };
static const float pD4[] = { 0.0f/3.0f, 1.0f/3.0f, 2.0f/3.0f, 3.0f/3.0f }; const float pD4[] = { 0.0f / 3.0f, 1.0f / 3.0f, 2.0f / 3.0f, 3.0f / 3.0f };
const int g_aWeights2[] = {0, 21, 43, 64};
const int g_aWeights3[] = {0, 9, 18, 27, 37, 46, 55, 64};
const int g_aWeights4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
// Partition, Shape, Pixel (index into 4x4 block) // Partition, Shape, Pixel (index into 4x4 block)
static const uint8_t g_aPartitionTable[3][64][16] = const uint8_t g_aPartitionTable[3][64][16] =
{ {
{ // 1 Region case has no subsets (all 0) { // 1 Region case has no subsets (all 0)
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@ -244,7 +240,7 @@ static const uint8_t g_aPartitionTable[3][64][16] =
}; };
// Partition, Shape, Fixup // Partition, Shape, Fixup
static const uint8_t g_aFixUp[3][64][3] = const uint8_t g_aFixUp[3][64][3] =
{ {
{ // No fix-ups for 1st subset for BC6H or BC7 { // No fix-ups for 1st subset for BC6H or BC7
{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0},
@ -305,6 +301,14 @@ static const uint8_t g_aFixUp[3][64][3] =
{ 0,15, 3}, { 0,12,15}, { 0, 3,15}, { 0, 3, 8} { 0,15, 3}, { 0,12,15}, { 0, 3,15}, { 0, 3, 8}
} }
}; };
}
namespace DirectX
{
const int g_aWeights2[] = { 0, 21, 43, 64 };
const int g_aWeights3[] = { 0, 9, 18, 27, 37, 46, 55, 64 };
const int g_aWeights4[] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 };
}
// BC6H Compression // BC6H Compression
const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[14][82] = const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[14][82] =
@ -555,10 +559,12 @@ const D3DX_BC7::ModeInfo D3DX_BC7::ms_aInfo[] =
}; };
namespace
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Helper functions // Helper functions
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
inline static bool IsFixUpOffset(_In_range_(0,2) size_t uPartitions, _In_range_(0,63) size_t uShape, _In_range_(0,15) size_t uOffset) inline bool IsFixUpOffset(_In_range_(0, 2) size_t uPartitions, _In_range_(0, 63) size_t uShape, _In_range_(0, 15) size_t uOffset)
{ {
assert(uPartitions < 3 && uShape < 64 && uOffset < 16); assert(uPartitions < 3 && uShape < 64 && uOffset < 16);
_Analysis_assume_(uPartitions < 3 && uShape < 64 && uOffset < 16); _Analysis_assume_(uPartitions < 3 && uShape < 64 && uOffset < 16);
@ -572,14 +578,14 @@ inline static bool IsFixUpOffset(_In_range_(0,2) size_t uPartitions, _In_range_(
return false; return false;
} }
inline static void TransformForward(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[]) inline void TransformForward(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[])
{ {
aEndPts[0].B -= aEndPts[0].A; aEndPts[0].B -= aEndPts[0].A;
aEndPts[1].A -= aEndPts[0].A; aEndPts[1].A -= aEndPts[0].A;
aEndPts[1].B -= aEndPts[0].A; aEndPts[1].B -= aEndPts[0].A;
} }
inline static void TransformInverse(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[], _In_ const LDRColorA& Prec, _In_ bool bSigned) inline void TransformInverse(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[], _In_ const LDRColorA& Prec, _In_ bool bSigned)
{ {
INTColor WrapMask((1 << Prec.r) - 1, (1 << Prec.g) - 1, (1 << Prec.b) - 1); INTColor WrapMask((1 << Prec.r) - 1, (1 << Prec.g) - 1, (1 << Prec.b) - 1);
aEndPts[0].B += aEndPts[0].A; aEndPts[0].B &= WrapMask; aEndPts[0].B += aEndPts[0].A; aEndPts[0].B &= WrapMask;
@ -593,7 +599,7 @@ inline static void TransformInverse(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEnd
} }
} }
inline static float Norm(_In_ const INTColor& a, _In_ const INTColor& b) inline float Norm(_In_ const INTColor& a, _In_ const INTColor& b)
{ {
float dr = float(a.r) - float(b.r); float dr = float(a.r) - float(b.r);
float dg = float(a.g) - float(b.g); float dg = float(a.g) - float(b.g);
@ -602,7 +608,7 @@ inline static float Norm(_In_ const INTColor& a, _In_ const INTColor& b)
} }
// return # of bits needed to store n. handle signed or unsigned cases properly // return # of bits needed to store n. handle signed or unsigned cases properly
inline static int NBits(_In_ int n, _In_ bool bIsSigned) inline int NBits(_In_ int n, _In_ bool bIsSigned)
{ {
int nb; int nb;
if (n == 0) if (n == 0)
@ -624,9 +630,13 @@ inline static int NBits(_In_ int n, _In_ bool bIsSigned)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static float OptimizeRGB(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints, float OptimizeRGB(
_Out_ HDRColorA* pX, _Out_ HDRColorA* pY, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints,
_In_ size_t cSteps, _In_ size_t cPixels, _In_reads_(cPixels) const size_t* pIndex) _Out_ HDRColorA* pX,
_Out_ HDRColorA* pY,
size_t cSteps,
size_t cPixels,
_In_reads_(cPixels) const size_t* pIndex)
{ {
float fError = FLT_MAX; float fError = FLT_MAX;
const float *pC = (3 == cSteps) ? pC3 : pC4; const float *pC = (3 == cSteps) ? pC3 : pC4;
@ -816,9 +826,13 @@ static float OptimizeRGB(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static float OptimizeRGBA(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints, float OptimizeRGBA(
_Out_ HDRColorA* pX, _Out_ HDRColorA* pY, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints,
_In_ size_t cSteps, _In_ size_t cPixels, _In_reads_(cPixels) const size_t* pIndex) _Out_ HDRColorA* pX,
_Out_ HDRColorA* pY,
size_t cSteps,
size_t cPixels,
_In_reads_(cPixels) const size_t* pIndex)
{ {
float fError = FLT_MAX; float fError = FLT_MAX;
const float *pC = (3 == cSteps) ? pC3 : pC4; const float *pC = (3 == cSteps) ? pC3 : pC4;
@ -980,9 +994,13 @@ static float OptimizeRGBA(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* cons
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
float ComputeError(
static float ComputeError(_Inout_ const LDRColorA& pixel, _In_reads_(1 << uIndexPrec) const LDRColorA aPalette[], _Inout_ const LDRColorA& pixel,
_In_ uint8_t uIndexPrec, _In_ uint8_t uIndexPrec2, _Out_opt_ size_t* pBestIndex = nullptr, _Out_opt_ size_t* pBestIndex2 = nullptr) _In_reads_(1 << uIndexPrec) const LDRColorA aPalette[],
uint8_t uIndexPrec,
uint8_t uIndexPrec2,
_Out_opt_ size_t* pBestIndex = nullptr,
_Out_opt_ size_t* pBestIndex2 = nullptr)
{ {
const size_t uNumIndices = size_t(1) << uIndexPrec; const size_t uNumIndices = size_t(1) << uIndexPrec;
const size_t uNumIndices2 = size_t(1) << uIndexPrec2; const size_t uNumIndices2 = size_t(1) << uIndexPrec2;
@ -1055,7 +1073,7 @@ static float ComputeError(_Inout_ const LDRColorA& pixel, _In_reads_(1 << uIndex
} }
inline static void FillWithErrorColors( _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut ) void FillWithErrorColors(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut)
{ {
for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
{ {
@ -1068,6 +1086,7 @@ inline static void FillWithErrorColors( _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRCo
#endif #endif
} }
} }
}
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -1234,6 +1253,7 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::Encode(bool bSigned, const HDRColorA* const pIn) void D3DX_BC6H::Encode(bool bSigned, const HDRColorA* const pIn)
{ {
@ -1309,6 +1329,7 @@ int D3DX_BC6H::Quantize(int iValue, int prec, bool bSigned)
return q; return q;
} }
_Use_decl_annotations_ _Use_decl_annotations_
int D3DX_BC6H::Unquantize(int comp, uint8_t uBitsPerComp, bool bSigned) int D3DX_BC6H::Unquantize(int comp, uint8_t uBitsPerComp, bool bSigned)
{ {
@ -1345,6 +1366,7 @@ int D3DX_BC6H::Unquantize(int comp, uint8_t uBitsPerComp, bool bSigned)
return unq; return unq;
} }
_Use_decl_annotations_ _Use_decl_annotations_
int D3DX_BC6H::FinishUnquantize(int comp, bool bSigned) int D3DX_BC6H::FinishUnquantize(int comp, bool bSigned)
{ {
@ -1401,6 +1423,7 @@ bool D3DX_BC6H::EndPointsFit(const EncodeParams* pEP, const INTEndPntPair aEndPt
return true; return true;
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::GeneratePaletteQuantized(const EncodeParams* pEP, const INTEndPntPair& endPts, INTColor aPalette[]) const void D3DX_BC6H::GeneratePaletteQuantized(const EncodeParams* pEP, const INTEndPntPair& endPts, INTColor aPalette[]) const
{ {
@ -1450,6 +1473,7 @@ void D3DX_BC6H::GeneratePaletteQuantized(const EncodeParams* pEP, const INTEndPn
} }
} }
// given a collection of colors and quantized endpoints, generate a palette, choose best entries, and return a single toterr // given a collection of colors and quantized endpoints, generate a palette, choose best entries, and return a single toterr
_Use_decl_annotations_ _Use_decl_annotations_
float D3DX_BC6H::MapColorsQuantized(const EncodeParams* pEP, const INTColor aColors[], size_t np, const INTEndPntPair &endPts) const float D3DX_BC6H::MapColorsQuantized(const EncodeParams* pEP, const INTColor aColors[], size_t np, const INTEndPntPair &endPts) const
@ -1485,6 +1509,7 @@ float D3DX_BC6H::MapColorsQuantized(const EncodeParams* pEP, const INTColor aCol
return fTotErr; return fTotErr;
} }
_Use_decl_annotations_ _Use_decl_annotations_
float D3DX_BC6H::PerturbOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, uint8_t ch, float D3DX_BC6H::PerturbOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, uint8_t ch,
const INTEndPntPair& oldEndPts, INTEndPntPair& newEndPts, float fOldErr, int do_b) const const INTEndPntPair& oldEndPts, INTEndPntPair& newEndPts, float fOldErr, int do_b) const
@ -1545,6 +1570,7 @@ float D3DX_BC6H::PerturbOne(const EncodeParams* pEP, const INTColor aColors[], s
return fMinErr; return fMinErr;
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::OptimizeOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, float aOrgErr, void D3DX_BC6H::OptimizeOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, float aOrgErr,
const INTEndPntPair &aOrgEndPts, INTEndPntPair &aOptEndPts) const const INTEndPntPair &aOrgEndPts, INTEndPntPair &aOptEndPts) const
@ -1597,6 +1623,7 @@ void D3DX_BC6H::OptimizeOne(const EncodeParams* pEP, const INTColor aColors[], s
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::OptimizeEndPoints(const EncodeParams* pEP, const float aOrgErr[], const INTEndPntPair aOrgEndPts[], INTEndPntPair aOptEndPts[]) const void D3DX_BC6H::OptimizeEndPoints(const EncodeParams* pEP, const float aOrgErr[], const INTEndPntPair aOrgEndPts[], INTEndPntPair aOptEndPts[]) const
{ {
@ -1622,6 +1649,7 @@ void D3DX_BC6H::OptimizeEndPoints(const EncodeParams* pEP, const float aOrgErr[]
} }
} }
// Swap endpoints as needed to ensure that the indices at fix up have a 0 high-order bit // Swap endpoints as needed to ensure that the indices at fix up have a 0 high-order bit
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::SwapIndices(const EncodeParams* pEP, INTEndPntPair aEndPts[], size_t aIndices[]) void D3DX_BC6H::SwapIndices(const EncodeParams* pEP, INTEndPntPair aEndPts[], size_t aIndices[])
@ -1650,6 +1678,7 @@ void D3DX_BC6H::SwapIndices(const EncodeParams* pEP, INTEndPntPair aEndPts[], si
} }
} }
// assign indices given a tile, shape, and quantized endpoints, return toterr for each region // assign indices given a tile, shape, and quantized endpoints, return toterr for each region
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::AssignIndices(const EncodeParams* pEP, const INTEndPntPair aEndPts[], size_t aIndices[], float aTotErr[]) const void D3DX_BC6H::AssignIndices(const EncodeParams* pEP, const INTEndPntPair aEndPts[], size_t aIndices[], float aTotErr[]) const
@ -1692,6 +1721,7 @@ void D3DX_BC6H::AssignIndices(const EncodeParams* pEP, const INTEndPntPair aEndP
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::QuantizeEndPts(const EncodeParams* pEP, INTEndPntPair* aQntEndPts) const void D3DX_BC6H::QuantizeEndPts(const EncodeParams* pEP, INTEndPntPair* aQntEndPts) const
{ {
@ -1713,6 +1743,7 @@ void D3DX_BC6H::QuantizeEndPts(const EncodeParams* pEP, INTEndPntPair* aQntEndPt
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::EmitBlock(const EncodeParams* pEP, const INTEndPntPair aEndPts[], const size_t aIndices[]) void D3DX_BC6H::EmitBlock(const EncodeParams* pEP, const INTEndPntPair aEndPts[], const size_t aIndices[])
{ {
@ -1756,6 +1787,7 @@ void D3DX_BC6H::EmitBlock(const EncodeParams* pEP, const INTEndPntPair aEndPts[]
assert(uStartBit == 128); assert(uStartBit == 128);
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::Refine(EncodeParams* pEP) void D3DX_BC6H::Refine(EncodeParams* pEP)
{ {
@ -1805,6 +1837,7 @@ void D3DX_BC6H::Refine(EncodeParams* pEP)
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DX_BC6H::GeneratePaletteUnquantized(const EncodeParams* pEP, size_t uRegion, INTColor aPalette[]) void D3DX_BC6H::GeneratePaletteUnquantized(const EncodeParams* pEP, size_t uRegion, INTColor aPalette[])
{ {
@ -1840,6 +1873,7 @@ void D3DX_BC6H::GeneratePaletteUnquantized(const EncodeParams* pEP, size_t uRegi
} }
} }
_Use_decl_annotations_ _Use_decl_annotations_
float D3DX_BC6H::MapColors(const EncodeParams* pEP, size_t uRegion, size_t np, const size_t* auIndex) const float D3DX_BC6H::MapColors(const EncodeParams* pEP, size_t uRegion, size_t np, const size_t* auIndex) const
{ {
@ -1929,7 +1963,6 @@ float D3DX_BC6H::RoughMSE(EncodeParams* pEP) const
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// BC7 Compression // BC7 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -2810,6 +2843,7 @@ float D3DX_BC7::RoughMSE(EncodeParams* pEP, size_t uShape, size_t uIndexMode)
return fTotalErr; return fTotalErr;
} }
//===================================================================================== //=====================================================================================
// Entry points // Entry points
//===================================================================================== //=====================================================================================
@ -2818,7 +2852,7 @@ float D3DX_BC7::RoughMSE(EncodeParams* pEP, size_t uShape, size_t uIndexMode)
// BC6H Compression // BC6H Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC6HU(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC6HU(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes"); static_assert(sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes");
@ -2826,7 +2860,7 @@ void D3DXDecodeBC6HU(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC6HS(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC6HS(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes"); static_assert(sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes");
@ -2834,7 +2868,7 @@ void D3DXDecodeBC6HS(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC6HU(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) void DirectX::D3DXEncodeBC6HU(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
assert(pBC && pColor); assert(pBC && pColor);
@ -2843,7 +2877,7 @@ void D3DXEncodeBC6HU(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC6HS(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) void DirectX::D3DXEncodeBC6HS(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
UNREFERENCED_PARAMETER(flags); UNREFERENCED_PARAMETER(flags);
assert(pBC && pColor); assert(pBC && pColor);
@ -2856,7 +2890,7 @@ void D3DXEncodeBC6HS(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
// BC7 Compression // BC7 Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXDecodeBC7(XMVECTOR *pColor, const uint8_t *pBC) void DirectX::D3DXDecodeBC7(XMVECTOR *pColor, const uint8_t *pBC)
{ {
assert(pColor && pBC); assert(pColor && pBC);
static_assert(sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes"); static_assert(sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes");
@ -2864,11 +2898,9 @@ void D3DXDecodeBC7(XMVECTOR *pColor, const uint8_t *pBC)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void D3DXEncodeBC7(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) void DirectX::D3DXEncodeBC7(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
{ {
assert(pBC && pColor); assert(pBC && pColor);
static_assert(sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes"); static_assert(sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes");
reinterpret_cast<D3DX_BC7*>(pBC)->Encode(!(flags& BC_FLAGS_USE_3SUBSETS), reinterpret_cast<const HDRColorA*>(pColor)); reinterpret_cast<D3DX_BC7*>(pBC)->Encode(!(flags& BC_FLAGS_USE_3SUBSETS), reinterpret_cast<const HDRColorA*>(pColor));
} }
} // namespace

View File

@ -19,6 +19,7 @@
#pragma comment(lib,"dxguid.lib") #pragma comment(lib,"dxguid.lib")
#endif #endif
using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace namespace
@ -82,9 +83,6 @@ namespace
} }
}; };
namespace DirectX
{
GPUCompressBC::GPUCompressBC() : GPUCompressBC::GPUCompressBC() :
m_bcformat(DXGI_FORMAT_UNKNOWN), m_bcformat(DXGI_FORMAT_UNKNOWN),
m_srcformat(DXGI_FORMAT_UNKNOWN), m_srcformat(DXGI_FORMAT_UNKNOWN),
@ -603,5 +601,3 @@ HRESULT GPUCompressBC::Compress( const Image& srcImage, const Image& destImage )
return hr; return hr;
} }
}; // namespace

View File

@ -33,7 +33,7 @@
#include <ocidl.h> #include <ocidl.h>
#define DIRECTX_TEX_VERSION 134 #define DIRECTX_TEX_VERSION 140
struct IWICImagingFactory; struct IWICImagingFactory;
struct IWICMetadataQueryReader; struct IWICMetadataQueryReader;
@ -204,21 +204,21 @@ namespace DirectX
// Filtering mode to use for any required image resizing (only needed when loading arrays of differently sized images; defaults to Fant) // Filtering mode to use for any required image resizing (only needed when loading arrays of differently sized images; defaults to Fant)
}; };
HRESULT __cdecl GetMetadataFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, HRESULT __cdecl GetMetadataFromDDSMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DWORD flags,
_Out_ TexMetadata& metadata ); _Out_ TexMetadata& metadata );
HRESULT __cdecl GetMetadataFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, HRESULT __cdecl GetMetadataFromDDSFile( _In_z_ const wchar_t* szFile, _In_ DWORD flags,
_Out_ TexMetadata& metadata ); _Out_ TexMetadata& metadata );
HRESULT __cdecl GetMetadataFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, HRESULT __cdecl GetMetadataFromTGAMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_ TexMetadata& metadata ); _Out_ TexMetadata& metadata );
HRESULT __cdecl GetMetadataFromTGAFile( _In_z_ LPCWSTR szFile, HRESULT __cdecl GetMetadataFromTGAFile( _In_z_ const wchar_t* szFile,
_Out_ TexMetadata& metadata ); _Out_ TexMetadata& metadata );
HRESULT __cdecl GetMetadataFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, HRESULT __cdecl GetMetadataFromWICMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DWORD flags,
_Out_ TexMetadata& metadata, _Out_ TexMetadata& metadata,
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr); _In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
HRESULT __cdecl GetMetadataFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, HRESULT __cdecl GetMetadataFromWICFile( _In_z_ const wchar_t* szFile, _In_ DWORD flags,
_Out_ TexMetadata& metadata, _Out_ TexMetadata& metadata,
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr); _In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
@ -238,13 +238,16 @@ namespace DirectX
{ {
public: public:
ScratchImage() ScratchImage()
: _nimages(0), _size(0), _image(nullptr), _memory(nullptr) {} : m_nimages(0), m_size(0), m_image(nullptr), m_memory(nullptr) {}
ScratchImage(ScratchImage&& moveFrom) ScratchImage(ScratchImage&& moveFrom)
: _nimages(0), _size(0), _image(nullptr), _memory(nullptr) { *this = std::move(moveFrom); } : m_nimages(0), m_size(0), m_image(nullptr), m_memory(nullptr) { *this = std::move(moveFrom); }
~ScratchImage() { Release(); } ~ScratchImage() { Release(); }
ScratchImage& __cdecl operator= (ScratchImage&& moveFrom); ScratchImage& __cdecl operator= (ScratchImage&& moveFrom);
ScratchImage(const ScratchImage&) = delete;
ScratchImage& operator=(const ScratchImage&) = delete;
HRESULT __cdecl Initialize( _In_ const TexMetadata& mdata, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize( _In_ const TexMetadata& mdata, _In_ DWORD flags = CP_FLAGS_NONE );
HRESULT __cdecl Initialize1D( _In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize1D( _In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
@ -261,27 +264,23 @@ namespace DirectX
bool __cdecl OverrideFormat( _In_ DXGI_FORMAT f ); bool __cdecl OverrideFormat( _In_ DXGI_FORMAT f );
const TexMetadata& __cdecl GetMetadata() const { return _metadata; } const TexMetadata& __cdecl GetMetadata() const { return m_metadata; }
const Image* __cdecl GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const; const Image* __cdecl GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const;
const Image* __cdecl GetImages() const { return _image; } const Image* __cdecl GetImages() const { return m_image; }
size_t __cdecl GetImageCount() const { return _nimages; } size_t __cdecl GetImageCount() const { return m_nimages; }
uint8_t* __cdecl GetPixels() const { return _memory; } uint8_t* __cdecl GetPixels() const { return m_memory; }
size_t __cdecl GetPixelsSize() const { return _size; } size_t __cdecl GetPixelsSize() const { return m_size; }
bool __cdecl IsAlphaAllOpaque() const; bool __cdecl IsAlphaAllOpaque() const;
private: private:
size_t _nimages; size_t m_nimages;
size_t _size; size_t m_size;
TexMetadata _metadata; TexMetadata m_metadata;
Image* _image; Image* m_image;
uint8_t* _memory; uint8_t* m_memory;
// Hide copy constructor and assignment operator
ScratchImage( const ScratchImage& );
ScratchImage& operator=( const ScratchImage& );
}; };
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
@ -289,35 +288,34 @@ namespace DirectX
class Blob class Blob
{ {
public: public:
Blob() : _buffer(nullptr), _size(0) {} Blob() : m_buffer(nullptr), m_size(0) {}
Blob(Blob&& moveFrom) : _buffer(nullptr), _size(0) { *this = std::move(moveFrom); } Blob(Blob&& moveFrom) : m_buffer(nullptr), m_size(0) { *this = std::move(moveFrom); }
~Blob() { Release(); } ~Blob() { Release(); }
Blob& __cdecl operator= (Blob&& moveFrom); Blob& __cdecl operator= (Blob&& moveFrom);
Blob(const Blob&) = delete;
Blob& operator=(const Blob&) = delete;
HRESULT __cdecl Initialize( _In_ size_t size ); HRESULT __cdecl Initialize( _In_ size_t size );
void __cdecl Release(); void __cdecl Release();
void *__cdecl GetBufferPointer() const { return _buffer; } void *__cdecl GetBufferPointer() const { return m_buffer; }
size_t __cdecl GetBufferSize() const { return _size; } size_t __cdecl GetBufferSize() const { return m_size; }
private: private:
void* _buffer; void* m_buffer;
size_t _size; size_t m_size;
// Hide copy constructor and assignment operator
Blob( const Blob& );
Blob& operator=( const Blob& );
}; };
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Image I/O // Image I/O
// DDS operations // DDS operations
HRESULT __cdecl LoadFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, HRESULT __cdecl LoadFromDDSMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DWORD flags,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
HRESULT __cdecl LoadFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, HRESULT __cdecl LoadFromDDSFile( _In_z_ const wchar_t* szFile, _In_ DWORD flags,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
HRESULT __cdecl SaveToDDSMemory( _In_ const Image& image, _In_ DWORD flags, HRESULT __cdecl SaveToDDSMemory( _In_ const Image& image, _In_ DWORD flags,
@ -325,23 +323,23 @@ namespace DirectX
HRESULT __cdecl SaveToDDSMemory( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, HRESULT __cdecl SaveToDDSMemory( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags,
_Out_ Blob& blob ); _Out_ Blob& blob );
HRESULT __cdecl SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ LPCWSTR szFile ); HRESULT __cdecl SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ const wchar_t* szFile );
HRESULT __cdecl SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ LPCWSTR szFile ); HRESULT __cdecl SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ const wchar_t* szFile );
// TGA operations // TGA operations
HRESULT __cdecl LoadFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, HRESULT __cdecl LoadFromTGAMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
HRESULT __cdecl LoadFromTGAFile( _In_z_ LPCWSTR szFile, HRESULT __cdecl LoadFromTGAFile( _In_z_ const wchar_t* szFile,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
HRESULT __cdecl SaveToTGAMemory( _In_ const Image& image, _Out_ Blob& blob ); HRESULT __cdecl SaveToTGAMemory( _In_ const Image& image, _Out_ Blob& blob );
HRESULT __cdecl SaveToTGAFile( _In_ const Image& image, _In_z_ LPCWSTR szFile ); HRESULT __cdecl SaveToTGAFile( _In_ const Image& image, _In_z_ const wchar_t* szFile );
// WIC operations // WIC operations
HRESULT __cdecl LoadFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, HRESULT __cdecl LoadFromWICMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DWORD flags,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image,
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr); _In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
HRESULT __cdecl LoadFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, HRESULT __cdecl LoadFromWICFile( _In_z_ const wchar_t* szFile, _In_ DWORD flags,
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image,
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr); _In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
@ -353,10 +351,10 @@ namespace DirectX
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr ); _In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr );
HRESULT __cdecl SaveToWICFile( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, HRESULT __cdecl SaveToWICFile( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
_In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr ); _In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr );
HRESULT __cdecl SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, HRESULT __cdecl SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
_In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr ); _In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr );
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------

View File

@ -113,7 +113,7 @@ inline HRESULT __cdecl SaveToDDSMemory(const Image& image, DWORD flags, Blob& bl
} }
_Use_decl_annotations_ _Use_decl_annotations_
inline HRESULT __cdecl SaveToDDSFile(const Image& image, DWORD flags, LPCWSTR szFile) inline HRESULT __cdecl SaveToDDSFile(const Image& image, DWORD flags, const wchar_t* szFile)
{ {
TexMetadata mdata = {}; TexMetadata mdata = {};
mdata.width = image.width; mdata.width = image.width;

View File

@ -22,11 +22,11 @@
#include "bc.h" #include "bc.h"
using namespace DirectX;
namespace DirectX namespace
{ {
inline DWORD GetBCFlags(_In_ DWORD compress)
inline static DWORD _GetBCFlags( _In_ DWORD compress )
{ {
static_assert(TEX_COMPRESS_RGB_DITHER == BC_FLAGS_DITHER_RGB, "TEX_COMPRESS_* flags should match BC_FLAGS_*"); static_assert(TEX_COMPRESS_RGB_DITHER == BC_FLAGS_DITHER_RGB, "TEX_COMPRESS_* flags should match BC_FLAGS_*");
static_assert(TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*"); static_assert(TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*");
@ -36,7 +36,7 @@ inline static DWORD _GetBCFlags( _In_ DWORD compress )
return (compress & (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A | BC_FLAGS_UNIFORM | BC_FLAGS_USE_3SUBSETS)); return (compress & (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A | BC_FLAGS_UNIFORM | BC_FLAGS_USE_3SUBSETS));
} }
inline static DWORD _GetSRGBFlags( _In_ DWORD compress ) inline 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_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_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*");
@ -44,7 +44,7 @@ inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
return (compress & TEX_COMPRESS_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 ) inline bool DetermineEncoderSettings(_In_ DXGI_FORMAT format, _Out_ BC_ENCODE& pfEncode, _Out_ size_t& blocksize, _Out_ DWORD& cflags)
{ {
switch (format) switch (format)
{ {
@ -70,8 +70,12 @@ inline static bool _DetermineEncoderSettings( _In_ DXGI_FORMAT format, _Out_ BC_
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags, HRESULT CompressBC(
_In_ DWORD srgb, _In_ float alphaRef ) const Image& image,
const Image& result,
DWORD bcflags,
DWORD srgb,
float alphaRef)
{ {
if (!image.pixels || !result.pixels) if (!image.pixels || !result.pixels)
return E_POINTER; return E_POINTER;
@ -99,7 +103,7 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
BC_ENCODE pfEncode; BC_ENCODE pfEncode;
size_t blocksize; size_t blocksize;
DWORD cflags; DWORD cflags;
if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) ) if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
__declspec(align(16)) XMVECTOR temp[16]; __declspec(align(16)) XMVECTOR temp[16];
@ -195,8 +199,12 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#ifdef _OPENMP #ifdef _OPENMP
static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags, HRESULT CompressBC_Parallel(
_In_ DWORD srgb, _In_ float alphaRef ) const Image& image,
const Image& result,
DWORD bcflags,
DWORD srgb,
float alphaRef)
{ {
if (!image.pixels || !result.pixels) if (!image.pixels || !result.pixels)
return E_POINTER; return E_POINTER;
@ -224,7 +232,7 @@ static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image&
BC_ENCODE pfEncode; BC_ENCODE pfEncode;
size_t blocksize; size_t blocksize;
DWORD cflags; DWORD cflags;
if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) ) if (!DetermineEncoderSettings(result.format, pfEncode, blocksize, cflags))
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
// Refactored version of loop to support parallel independance // Refactored version of loop to support parallel independance
@ -320,12 +328,11 @@ static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image&
return (fail) ? E_FAIL : S_OK; return (fail) ? E_FAIL : S_OK;
} }
#endif // _OPENMP #endif // _OPENMP
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static DXGI_FORMAT _DefaultDecompress( _In_ DXGI_FORMAT format ) DXGI_FORMAT DefaultDecompress(_In_ DXGI_FORMAT format)
{ {
switch (format) switch (format)
{ {
@ -373,7 +380,7 @@ static DXGI_FORMAT _DefaultDecompress( _In_ DXGI_FORMAT format )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result ) HRESULT DecompressBC(_In_ const Image& cImage, _In_ const Image& result)
{ {
if (!cImage.pixels || !result.pixels) if (!cImage.pixels || !result.pixels)
return E_POINTER; return E_POINTER;
@ -484,9 +491,11 @@ static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result
return S_OK; return S_OK;
} }
}
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
namespace DirectX
{
bool _IsAlphaAllOpaqueBC(_In_ const Image& cImage) bool _IsAlphaAllOpaqueBC(_In_ const Image& cImage)
{ {
if (!cImage.pixels) if (!cImage.pixels)
@ -570,6 +579,7 @@ bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
return true; return true;
} }
};
//===================================================================================== //=====================================================================================
@ -580,7 +590,12 @@ bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
// Compression // Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image ) HRESULT DirectX::Compress(
const Image& srcImage,
DXGI_FORMAT format,
DWORD compress,
float alphaRef,
ScratchImage& image)
{ {
if (IsCompressed(srcImage.format) || !IsCompressed(format)) if (IsCompressed(srcImage.format) || !IsCompressed(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -607,12 +622,12 @@ HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, flo
#ifndef _OPENMP #ifndef _OPENMP
return E_NOTIMPL; return E_NOTIMPL;
#else #else
hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); hr = CompressBC_Parallel(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), alphaRef);
#endif // _OPENMP #endif // _OPENMP
} }
else else
{ {
hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); hr = CompressBC(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), alphaRef);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -622,8 +637,14 @@ HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, flo
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::Compress(
DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DXGI_FORMAT format,
DWORD compress,
float alphaRef,
ScratchImage& cImages)
{ {
if (!srcImages || !nimages) if (!srcImages || !nimages)
return E_INVALIDARG; return E_INVALIDARG;
@ -675,7 +696,7 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
#else #else
if (compress & TEX_COMPRESS_PARALLEL) if (compress & TEX_COMPRESS_PARALLEL)
{ {
hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); hr = CompressBC_Parallel(src, dest[index], GetBCFlags(compress), GetSRGBFlags(compress), alphaRef);
if (FAILED(hr)) if (FAILED(hr))
{ {
cImages.Release(); cImages.Release();
@ -686,7 +707,7 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
} }
else else
{ {
hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); hr = CompressBC(src, dest[index], GetBCFlags(compress), GetSRGBFlags(compress), alphaRef);
if (FAILED(hr)) if (FAILED(hr))
{ {
cImages.Release(); cImages.Release();
@ -703,7 +724,10 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
// Decompression // Decompression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image ) HRESULT DirectX::Decompress(
const Image& cImage,
DXGI_FORMAT format,
ScratchImage& image)
{ {
if (!IsCompressed(cImage.format) || IsCompressed(format)) if (!IsCompressed(cImage.format) || IsCompressed(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -711,7 +735,7 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {
// Pick a default decompressed format based on BC input format // Pick a default decompressed format based on BC input format
format = _DefaultDecompress( cImage.format ); format = DefaultDecompress(cImage.format);
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {
// Input is not a compressed format // Input is not a compressed format
@ -740,7 +764,7 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
} }
// Decompress single image // Decompress single image
hr = _DecompressBC( cImage, *img ); hr = DecompressBC(cImage, *img);
if (FAILED(hr)) if (FAILED(hr))
image.Release(); image.Release();
@ -748,8 +772,12 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::Decompress(
DXGI_FORMAT format, ScratchImage& images ) const Image* cImages,
size_t nimages,
const TexMetadata& metadata,
DXGI_FORMAT format,
ScratchImage& images)
{ {
if (!cImages || !nimages) if (!cImages || !nimages)
return E_INVALIDARG; return E_INVALIDARG;
@ -760,7 +788,7 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {
// Pick a default decompressed format based on BC input format // Pick a default decompressed format based on BC input format
format = _DefaultDecompress( cImages[0].format ); format = DefaultDecompress(cImages[0].format);
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {
// Input is not a compressed format // Input is not a compressed format
@ -814,7 +842,7 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
return E_FAIL; return E_FAIL;
} }
hr = _DecompressBC( src, dest[ index ] ); hr = DecompressBC(src, dest[index]);
if (FAILED(hr)) if (FAILED(hr))
{ {
images.Release(); images.Release();
@ -824,5 +852,3 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -17,10 +17,11 @@
#include "bcdirectcompute.h" #include "bcdirectcompute.h"
namespace DirectX using namespace DirectX;
{
inline static DWORD _GetSRGBFlags( _In_ DWORD compress ) namespace
{
inline 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_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_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*");
@ -32,7 +33,11 @@ inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Converts to R8G8B8A8_UNORM or R8G8B8A8_UNORM_SRGB doing any conversion logic needed // Converts to R8G8B8A8_UNORM or R8G8B8A8_UNORM_SRGB doing any conversion logic needed
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _ConvertToRGBA32( _In_ const Image& srcImage, _In_ ScratchImage& image, bool srgb, _In_ DWORD filter ) HRESULT ConvertToRGBA32(
const Image& srcImage,
ScratchImage& image,
bool srgb,
DWORD filter)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -92,7 +97,10 @@ static HRESULT _ConvertToRGBA32( _In_ const Image& srcImage, _In_ ScratchImage&
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Converts to DXGI_FORMAT_R32G32B32A32_FLOAT doing any conversion logic needed // Converts to DXGI_FORMAT_R32G32B32A32_FLOAT doing any conversion logic needed
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _ConvertToRGBAF32( const Image& srcImage, ScratchImage& image, _In_ DWORD filter ) HRESULT ConvertToRGBAF32(
const Image& srcImage,
ScratchImage& image,
DWORD filter)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -137,7 +145,11 @@ static HRESULT _ConvertToRGBAF32( const Image& srcImage, ScratchImage& image, _I
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Compress using GPU, converting to the proper input format for the shader if needed // Compress using GPU, converting to the proper input format for the shader if needed
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image& srcImage, _In_ const Image& destImage, _In_ DWORD compress ) inline HRESULT GPUCompress(
_In_ GPUCompressBC* gpubc,
const Image& srcImage,
const Image& destImage,
DWORD compress)
{ {
if (!gpubc) if (!gpubc)
return E_POINTER; return E_POINTER;
@ -157,20 +169,20 @@ inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image&
ScratchImage image; ScratchImage image;
HRESULT hr; HRESULT hr;
DWORD srgb = _GetSRGBFlags( compress ); DWORD srgb = GetSRGBFlags(compress);
switch (format) switch (format)
{ {
case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM:
hr = _ConvertToRGBA32( srcImage, image, false, srgb ); hr = ConvertToRGBA32(srcImage, image, false, srgb);
break; break;
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
hr = _ConvertToRGBA32( srcImage, image, true, srgb ); hr = ConvertToRGBA32(srcImage, image, true, srgb);
break; break;
case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_FLOAT:
hr = _ConvertToRGBAF32( srcImage, image, srgb ); hr = ConvertToRGBAF32(srcImage, image, srgb);
break; break;
default: default:
@ -188,7 +200,7 @@ inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image&
return gpubc->Compress(*img, destImage); return gpubc->Compress(*img, destImage);
} }
} }
};
//===================================================================================== //=====================================================================================
// Entry-points // Entry-points
@ -198,7 +210,13 @@ inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image&
// Compression // Compression
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& image ) HRESULT DirectX::Compress(
ID3D11Device* pDevice,
const Image& srcImage,
DXGI_FORMAT format,
DWORD compress,
float alphaWeight,
ScratchImage& image)
{ {
if (!pDevice || IsCompressed(srcImage.format) || !IsCompressed(format)) if (!pDevice || IsCompressed(srcImage.format) || !IsCompressed(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -232,7 +250,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT form
return E_POINTER; return E_POINTER;
} }
hr = _GPUCompress( gpubc.get(), srcImage, *img, compress ); hr = GPUCompress(gpubc.get(), srcImage, *img, compress);
if (FAILED(hr)) if (FAILED(hr))
image.Release(); image.Release();
@ -240,8 +258,15 @@ HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT form
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::Compress(
DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& cImages ) ID3D11Device* pDevice,
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DXGI_FORMAT format,
DWORD compress,
float alphaWeight,
ScratchImage& cImages)
{ {
if (!pDevice || !srcImages || !nimages) if (!pDevice || !srcImages || !nimages)
return E_INVALIDARG; return E_INVALIDARG;
@ -321,7 +346,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
return E_FAIL; return E_FAIL;
} }
hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress ); hr = GPUCompress(gpubc.get(), src, dest[index], compress);
if (FAILED(hr)) if (FAILED(hr))
{ {
cImages.Release(); cImages.Release();
@ -372,7 +397,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
return E_FAIL; return E_FAIL;
} }
hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress ); hr = GPUCompress(gpubc.get(), src, dest[index], compress);
if (FAILED(hr)) if (FAILED(hr))
{ {
cImages.Release(); cImages.Release();
@ -398,5 +423,3 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// DirectXTexConvert.cpp // DirectXTexConvert.cpp
// //
// DirectX Texture Library - Image conversion // DirectX Texture Library - Image pixel format conversion
// //
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
@ -15,6 +15,7 @@
#include "directxtexp.h" #include "directxtexp.h"
using namespace DirectX;
using namespace DirectX::PackedVector; using namespace DirectX::PackedVector;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
@ -190,24 +191,25 @@ namespace
pDestination->zm = static_cast<uint32_t>(lroundf(z * ScaleR)); pDestination->zm = static_cast<uint32_t>(lroundf(z * ScaleR));
} }
#endif #endif
};
namespace DirectX const XMVECTORF32 g_Grayscale = { 0.2125f, 0.7154f, 0.0721f, 0.0f };
{ const XMVECTORF32 g_HalfMin = { -65504.f, -65504.f, -65504.f, -65504.f };
static const XMVECTORF32 g_Grayscale = { 0.2125f, 0.7154f, 0.0721f, 0.0f }; const XMVECTORF32 g_HalfMax = { 65504.f, 65504.f, 65504.f, 65504.f };
static const XMVECTORF32 g_HalfMin = { -65504.f, -65504.f, -65504.f, -65504.f }; const XMVECTORF32 g_8BitBias = { 0.5f / 255.f, 0.5f / 255.f, 0.5f / 255.f, 0.5f / 255.f };
static const XMVECTORF32 g_HalfMax = { 65504.f, 65504.f, 65504.f, 65504.f }; }
static const XMVECTORF32 g_8BitBias = { 0.5f/255.f, 0.5f/255.f, 0.5f/255.f, 0.5f/255.f };
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Copies an image row with optional clearing of alpha value to 1.0 // Copies an image row with optional clearing of alpha value to 1.0
// (can be used in place as well) otherwise copies the image row unmodified. // (can be used in place as well) otherwise copies the image row unmodified.
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize)) _Use_decl_annotations_
_When_(pDestination != pSource, _Out_writes_bytes_(outSize)) void DirectX::_CopyScanline(
LPVOID pDestination, _In_ size_t outSize, void* pDestination,
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, size_t outSize,
_In_ DXGI_FORMAT format, _In_ DWORD flags) const void* pSource,
size_t inSize,
DXGI_FORMAT format,
DWORD flags)
{ {
assert(pDestination && outSize > 0); assert(pDestination && outSize > 0);
assert(pSource && inSize > 0); assert(pSource && inSize > 0);
@ -446,7 +448,13 @@ void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize
// (can be used in place as well) otherwise copies the image row unmodified. // (can be used in place as well) otherwise copies the image row unmodified.
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void _SwizzleScanline( LPVOID pDestination, size_t outSize, LPCVOID pSource, size_t inSize, DXGI_FORMAT format, DWORD flags ) void DirectX::_SwizzleScanline(
void* pDestination,
size_t outSize,
const void* pSource,
size_t inSize,
DXGI_FORMAT format,
DWORD flags)
{ {
assert(pDestination && outSize > 0); assert(pDestination && outSize > 0);
assert(pSource && inSize > 0); assert(pSource && inSize > 0);
@ -610,8 +618,14 @@ void _SwizzleScanline( LPVOID pDestination, size_t outSize, LPCVOID pSource, siz
// Returns true if supported, false if expansion case not supported // Returns true if supported, false if expansion case not supported
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool _ExpandScanline( LPVOID pDestination, size_t outSize, DXGI_FORMAT outFormat, bool DirectX::_ExpandScanline(
LPCVOID pSource, size_t inSize, DXGI_FORMAT inFormat, DWORD flags ) void* pDestination,
size_t outSize,
DXGI_FORMAT outFormat,
const void* pSource,
size_t inSize,
DXGI_FORMAT inFormat,
DWORD flags)
{ {
assert(pDestination && outSize > 0); assert(pDestination && outSize > 0);
assert(pSource && inSize > 0); assert(pSource && inSize > 0);
@ -744,8 +758,12 @@ bool _ExpandScanline( LPVOID pDestination, size_t outSize, DXGI_FORMAT outFormat
return false; return false;
#pragma warning(suppress: 6101) #pragma warning(suppress: 6101)
_Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count, _Use_decl_annotations_ bool DirectX::_LoadScanline(
LPCVOID pSource, size_t size, DXGI_FORMAT format ) XMVECTOR* pDestination,
size_t count,
const void* pSource,
size_t size,
DXGI_FORMAT format)
{ {
assert(pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0)); assert(pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0));
assert(pSource && size > 0); assert(pSource && size > 0);
@ -1588,8 +1606,13 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
return false; return false;
_Use_decl_annotations_ _Use_decl_annotations_
bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, bool DirectX::_StoreScanline(
const XMVECTOR* pSource, size_t count, float threshold ) void* pDestination,
size_t size,
DXGI_FORMAT format,
const XMVECTOR* pSource,
size_t count,
float threshold)
{ {
assert(pDestination && size > 0); assert(pDestination && size > 0);
assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0)); assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0));
@ -2442,7 +2465,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
// Convert DXGI image to/from GUID_WICPixelFormat128bppRGBAFloat (no range conversions) // Convert DXGI image to/from GUID_WICPixelFormat128bppRGBAFloat (no range conversions)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _ConvertToR32G32B32A32( const Image& srcImage, ScratchImage& image ) HRESULT DirectX::_ConvertToR32G32B32A32(const Image& srcImage, ScratchImage& image)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -2482,7 +2505,7 @@ HRESULT _ConvertToR32G32B32A32( const Image& srcImage, ScratchImage& image )
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, const Image& destImage ) HRESULT DirectX::_ConvertFromR32G32B32A32(const Image& srcImage, const Image& destImage)
{ {
assert(srcImage.format == DXGI_FORMAT_R32G32B32A32_FLOAT); assert(srcImage.format == DXGI_FORMAT_R32G32B32A32_FLOAT);
@ -2508,7 +2531,7 @@ HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, const Image& destImage
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, DXGI_FORMAT format, ScratchImage& image ) HRESULT DirectX::_ConvertFromR32G32B32A32(const Image& srcImage, DXGI_FORMAT format, ScratchImage& image)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -2535,7 +2558,12 @@ HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, DXGI_FORMAT format, Scr
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _ConvertFromR32G32B32A32( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, ScratchImage& result ) HRESULT DirectX::_ConvertFromR32G32B32A32(
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DXGI_FORMAT format,
ScratchImage& result)
{ {
if (!srcImages) if (!srcImages)
return E_POINTER; return E_POINTER;
@ -2610,8 +2638,14 @@ HRESULT _ConvertFromR32G32B32A32( const Image* srcImages, size_t nimages, const
// where a = 0.055 // where a = 0.055
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format, bool DirectX::_StoreScanlineLinear(
XMVECTOR* pSource, size_t count, DWORD flags, float threshold ) void* pDestination,
size_t size,
DXGI_FORMAT format,
XMVECTOR* pSource,
size_t count,
DWORD flags,
float threshold)
{ {
assert(pDestination && size > 0); assert(pDestination && size > 0);
assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0)); assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0));
@ -2680,8 +2714,13 @@ bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format,
// where a = 0.055 // where a = 0.055
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool _LoadScanlineLinear( XMVECTOR* pDestination, size_t count, bool DirectX::_LoadScanlineLinear(
LPCVOID pSource, size_t size, DXGI_FORMAT format, DWORD flags ) XMVECTOR* pDestination,
size_t count,
const void* pSource,
size_t size,
DXGI_FORMAT format,
DWORD flags)
{ {
assert(pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0)); assert(pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0));
assert(pSource && size > 0); assert(pSource && size > 0);
@ -2748,6 +2787,8 @@ bool _LoadScanlineLinear( XMVECTOR* pDestination, size_t count,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert scanline based on source/target formats // Convert scanline based on source/target formats
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
namespace
{
struct ConvertData struct ConvertData
{ {
DXGI_FORMAT format; DXGI_FORMAT format;
@ -2755,7 +2796,8 @@ struct ConvertData
DWORD flags; DWORD flags;
}; };
static const ConvertData g_ConvertTable[] = { const ConvertData g_ConvertTable[] =
{
{ DXGI_FORMAT_R32G32B32A32_FLOAT, 32, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32A32_FLOAT, 32, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R32G32B32A32_UINT, 32, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32A32_UINT, 32, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R32G32B32A32_SINT, 32, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32A32_SINT, 32, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
@ -2843,7 +2885,7 @@ static const ConvertData g_ConvertTable[] = {
}; };
#pragma prefast( suppress : 25004, "Signature must match bsearch_s" ); #pragma prefast( suppress : 25004, "Signature must match bsearch_s" );
static int __cdecl _ConvertCompare( void *context, const void* ptr1, const void *ptr2 ) int __cdecl _ConvertCompare(void *context, const void* ptr1, const void *ptr2)
{ {
UNREFERENCED_PARAMETER(context); UNREFERENCED_PARAMETER(context);
const ConvertData *p1 = reinterpret_cast<const ConvertData*>(ptr1); const ConvertData *p1 = reinterpret_cast<const ConvertData*>(ptr1);
@ -2851,9 +2893,10 @@ static int __cdecl _ConvertCompare( void *context, const void* ptr1, const void
if (p1->format == p2->format) return 0; if (p1->format == p2->format) return 0;
else return (p1->format < p2->format) ? -1 : 1; else return (p1->format < p2->format) ? -1 : 1;
} }
}
_Use_decl_annotations_ _Use_decl_annotations_
DWORD _GetConvertFlags( DXGI_FORMAT format ) DWORD DirectX::_GetConvertFlags(DXGI_FORMAT format)
{ {
#ifdef _DEBUG #ifdef _DEBUG
// Ensure conversion table is in ascending order // Ensure conversion table is in ascending order
@ -2873,7 +2916,7 @@ DWORD _GetConvertFlags( DXGI_FORMAT format )
} }
_Use_decl_annotations_ _Use_decl_annotations_
void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, DXGI_FORMAT inFormat, DWORD flags ) void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, DXGI_FORMAT inFormat, DWORD flags)
{ {
assert(pBuffer && count > 0 && (((uintptr_t)pBuffer & 0xF) == 0)); assert(pBuffer && count > 0 && (((uintptr_t)pBuffer & 0xF) == 0));
assert(IsValid(outFormat) && !IsTypeless(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat)); assert(IsValid(outFormat) && !IsTypeless(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat));
@ -3481,9 +3524,10 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Dithering // Dithering
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
namespace
{
// 4X4X4 ordered dithering matrix // 4X4X4 ordered dithering matrix
static const float g_Dither[] = const float g_Dither[] =
{ {
// (z & 3) + ( (y & 3) * 8) + (x & 3) // (z & 3) + ( (y & 3) * 8) + (x & 3)
0.468750f, -0.031250f, 0.343750f, -0.156250f, 0.468750f, -0.031250f, 0.343750f, -0.156250f, 0.468750f, -0.031250f, 0.343750f, -0.156250f, 0.468750f, -0.031250f, 0.343750f, -0.156250f,
@ -3492,20 +3536,20 @@ static const float g_Dither[] =
-0.468750f, 0.031250f, -0.343750f, 0.156250f, -0.468750f, 0.031250f, -0.343750f, 0.156250f, -0.468750f, 0.031250f, -0.343750f, 0.156250f, -0.468750f, 0.031250f, -0.343750f, 0.156250f,
}; };
static const XMVECTORF32 g_Scale16pc = { 65535.f, 65535.f, 65535.f, 65535.f }; const XMVECTORF32 g_Scale16pc = { 65535.f, 65535.f, 65535.f, 65535.f };
static const XMVECTORF32 g_Scale15pc = { 32767.f, 32767.f, 32767.f, 32767.f }; const XMVECTORF32 g_Scale15pc = { 32767.f, 32767.f, 32767.f, 32767.f };
static const XMVECTORF32 g_Scale10pc = { 1023.f, 1023.f, 1023.f, 3.f }; const XMVECTORF32 g_Scale10pc = { 1023.f, 1023.f, 1023.f, 3.f };
static const XMVECTORF32 g_Scale9pc = { 511.f, 511.f, 511.f, 3.f }; const XMVECTORF32 g_Scale9pc = { 511.f, 511.f, 511.f, 3.f };
static const XMVECTORF32 g_Scale8pc = { 255.f, 255.f, 255.f, 255.f }; const XMVECTORF32 g_Scale8pc = { 255.f, 255.f, 255.f, 255.f };
static const XMVECTORF32 g_Scale7pc = { 127.f, 127.f, 127.f, 127.f }; const XMVECTORF32 g_Scale7pc = { 127.f, 127.f, 127.f, 127.f };
static const XMVECTORF32 g_Scale565pc = { 31.f, 63.f, 31.f, 1.f }; const XMVECTORF32 g_Scale565pc = { 31.f, 63.f, 31.f, 1.f };
static const XMVECTORF32 g_Scale5551pc = { 31.f, 31.f, 31.f, 1.f }; const XMVECTORF32 g_Scale5551pc = { 31.f, 31.f, 31.f, 1.f };
static const XMVECTORF32 g_Scale4pc = { 15.f, 15.f, 15.f, 15.f }; const XMVECTORF32 g_Scale4pc = { 15.f, 15.f, 15.f, 15.f };
static const XMVECTORF32 g_ErrorWeight3 = { 3.f/16.f, 3.f/16.f, 3.f/16.f, 3.f/16.f }; const XMVECTORF32 g_ErrorWeight3 = { 3.f / 16.f, 3.f / 16.f, 3.f / 16.f, 3.f / 16.f };
static const XMVECTORF32 g_ErrorWeight5 = { 5.f/16.f, 5.f/16.f, 5.f/16.f, 5.f/16.f }; const XMVECTORF32 g_ErrorWeight5 = { 5.f / 16.f, 5.f / 16.f, 5.f / 16.f, 5.f / 16.f };
static const XMVECTORF32 g_ErrorWeight1 = { 1.f/16.f, 1.f/16.f, 1.f/16.f, 1.f/16.f }; const XMVECTORF32 g_ErrorWeight1 = { 1.f / 16.f, 1.f / 16.f, 1.f / 16.f, 1.f / 16.f };
static const XMVECTORF32 g_ErrorWeight7 = { 7.f/16.f, 7.f/16.f, 7.f/16.f, 7.f/16.f }; const XMVECTORF32 g_ErrorWeight7 = { 7.f / 16.f, 7.f / 16.f, 7.f / 16.f, 7.f / 16.f };
#define STORE_SCANLINE( type, scalev, clampzero, norm, itype, mask, row, bgr ) \ #define STORE_SCANLINE( type, scalev, clampzero, norm, itype, mask, row, bgr ) \
if ( size >= sizeof(type) ) \ if ( size >= sizeof(type) ) \
@ -3659,13 +3703,22 @@ static const XMVECTORF32 g_ErrorWeight7 = { 7.f/16.f, 7.f/16.f, 7.f/16.f, 7.f/16
return true; \ return true; \
} \ } \
return false; return false;
}
#pragma warning(push) #pragma warning(push)
#pragma warning( disable : 4127 ) #pragma warning( disable : 4127 )
_Use_decl_annotations_ _Use_decl_annotations_
bool _StoreScanlineDither( LPVOID pDestination, size_t size, DXGI_FORMAT format, bool DirectX::_StoreScanlineDither(
XMVECTOR* pSource, size_t count, float threshold, size_t y, size_t z, XMVECTOR* pDiffusionErrors ) void* pDestination,
size_t size,
DXGI_FORMAT format,
XMVECTOR* pSource,
size_t count,
float threshold,
size_t y,
size_t z,
XMVECTOR* pDiffusionErrors)
{ {
assert(pDestination && size > 0); assert(pDestination && size > 0);
assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0)); assert(pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0));
@ -4110,12 +4163,17 @@ bool _StoreScanlineDither( LPVOID pDestination, size_t size, DXGI_FORMAT format,
#undef STORE_SCANLINE2 #undef STORE_SCANLINE2
#undef STORE_SCANLINE1 #undef STORE_SCANLINE1
namespace
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Selection logic for using WIC vs. our own routines // Selection logic for using WIC vs. our own routines
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static inline bool _UseWICConversion( _In_ DWORD filter, _In_ DXGI_FORMAT sformat, _In_ DXGI_FORMAT tformat, inline bool UseWICConversion(
_Out_ WICPixelFormatGUID& pfGUID, _Out_ WICPixelFormatGUID& targetGUID ) _In_ DWORD filter,
_In_ DXGI_FORMAT sformat,
_In_ DXGI_FORMAT tformat,
_Out_ WICPixelFormatGUID& pfGUID,
_Out_ WICPixelFormatGUID& targetGUID)
{ {
memcpy(&pfGUID, &GUID_NULL, sizeof(GUID)); memcpy(&pfGUID, &GUID_NULL, sizeof(GUID));
memcpy(&targetGUID, &GUID_NULL, sizeof(GUID)); memcpy(&targetGUID, &GUID_NULL, sizeof(GUID));
@ -4221,13 +4279,16 @@ static inline bool _UseWICConversion( _In_ DWORD filter, _In_ DXGI_FORMAT sforma
return true; return true;
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert the source image using WIC // Convert the source image using WIC
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixelFormatGUID& pfGUID, HRESULT ConvertUsingWIC(
_In_ const Image& srcImage,
_In_ const WICPixelFormatGUID& pfGUID,
_In_ const WICPixelFormatGUID& targetGUID, _In_ const WICPixelFormatGUID& targetGUID,
_In_ DWORD filter, _In_ float threshold, _In_ const Image& destImage ) _In_ DWORD filter,
_In_ float threshold,
_In_ const Image& destImage)
{ {
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -4275,7 +4336,12 @@ static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixel
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert the source image (not using WIC) // Convert the source image (not using WIC)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage, _In_ float threshold, _In_ size_t z ) HRESULT ConvertCustom(
_In_ const Image& srcImage,
_In_ DWORD filter,
_In_ const Image& destImage,
_In_ float threshold,
size_t z)
{ {
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -4356,9 +4422,8 @@ static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ con
return S_OK; return S_OK;
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static DXGI_FORMAT _PlanarToSingle( _In_ DXGI_FORMAT format ) DXGI_FORMAT _PlanarToSingle(_In_ DXGI_FORMAT format)
{ {
switch (format) switch (format)
{ {
@ -4383,7 +4448,6 @@ static DXGI_FORMAT _PlanarToSingle( _In_ DXGI_FORMAT format )
} }
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert the image from a planar to non-planar image // Convert the image from a planar to non-planar image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -4430,7 +4494,7 @@ static DXGI_FORMAT _PlanarToSingle( _In_ DXGI_FORMAT format )
}\ }\
} }
static HRESULT _ConvertToSinglePlane( _In_ const Image& srcImage, _In_ const Image& destImage ) HRESULT ConvertToSinglePlane_(_In_ const Image& srcImage, _In_ const Image& destImage)
{ {
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -4507,6 +4571,7 @@ static HRESULT _ConvertToSinglePlane( _In_ const Image& srcImage, _In_ const Ima
} }
#undef CONVERT_420_TO_422 #undef CONVERT_420_TO_422
}
//===================================================================================== //=====================================================================================
@ -4517,7 +4582,12 @@ static HRESULT _ConvertToSinglePlane( _In_ const Image& srcImage, _In_ const Ima
// Convert image // Convert image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Convert( const Image& srcImage, DXGI_FORMAT format, DWORD filter, float threshold, ScratchImage& image ) HRESULT DirectX::Convert(
const Image& srcImage,
DXGI_FORMAT format,
DWORD filter,
float threshold,
ScratchImage& image)
{ {
if ((srcImage.format == format) || !IsValid(format)) if ((srcImage.format == format) || !IsValid(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -4546,13 +4616,13 @@ HRESULT Convert( const Image& srcImage, DXGI_FORMAT format, DWORD filter, float
} }
WICPixelFormatGUID pfGUID, targetGUID; WICPixelFormatGUID pfGUID, targetGUID;
if ( _UseWICConversion( filter, srcImage.format, format, pfGUID, targetGUID ) ) if (UseWICConversion(filter, srcImage.format, format, pfGUID, targetGUID))
{ {
hr = _ConvertUsingWIC( srcImage, pfGUID, targetGUID, filter, threshold, *rimage ); hr = ConvertUsingWIC(srcImage, pfGUID, targetGUID, filter, threshold, *rimage);
} }
else else
{ {
hr = _Convert( srcImage, filter, *rimage, threshold, 0 ); hr = ConvertCustom(srcImage, filter, *rimage, threshold, 0);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -4569,8 +4639,14 @@ HRESULT Convert( const Image& srcImage, DXGI_FORMAT format, DWORD filter, float
// Convert image (complex) // Convert image (complex)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::Convert(
DXGI_FORMAT format, DWORD filter, float threshold, ScratchImage& result ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DXGI_FORMAT format,
DWORD filter,
float threshold,
ScratchImage& result)
{ {
if (!srcImages || !nimages || (metadata.format == format) || !IsValid(format)) if (!srcImages || !nimages || (metadata.format == format) || !IsValid(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -4604,7 +4680,7 @@ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& meta
} }
WICPixelFormatGUID pfGUID, targetGUID; WICPixelFormatGUID pfGUID, targetGUID;
bool usewic = _UseWICConversion( filter, metadata.format, format, pfGUID, targetGUID ); bool usewic = UseWICConversion(filter, metadata.format, format, pfGUID, targetGUID);
switch (metadata.dimension) switch (metadata.dimension)
{ {
@ -4633,11 +4709,11 @@ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& meta
if (usewic) if (usewic)
{ {
hr = _ConvertUsingWIC( src, pfGUID, targetGUID, filter, threshold, dst ); hr = ConvertUsingWIC(src, pfGUID, targetGUID, filter, threshold, dst);
} }
else else
{ {
hr = _Convert( src, filter, dst, threshold, 0 ); hr = ConvertCustom(src, filter, dst, threshold, 0);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -4680,11 +4756,11 @@ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& meta
if (usewic) if (usewic)
{ {
hr = _ConvertUsingWIC( src, pfGUID, targetGUID, filter, threshold, dst ); hr = ConvertUsingWIC(src, pfGUID, targetGUID, filter, threshold, dst);
} }
else else
{ {
hr = _Convert( src, filter, dst, threshold, slice ); hr = ConvertCustom(src, filter, dst, threshold, slice);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -4712,7 +4788,7 @@ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& meta
// Convert image from planar to single plane (image) // Convert image from planar to single plane (image)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT ConvertToSinglePlane( const Image& srcImage, ScratchImage& image ) HRESULT DirectX::ConvertToSinglePlane(const Image& srcImage, ScratchImage& image)
{ {
if (!IsPlanar(srcImage.format)) if (!IsPlanar(srcImage.format))
return E_INVALIDARG; return E_INVALIDARG;
@ -4738,7 +4814,7 @@ HRESULT ConvertToSinglePlane( const Image& srcImage, ScratchImage& image )
return E_POINTER; return E_POINTER;
} }
hr = _ConvertToSinglePlane( srcImage, *rimage ); hr = ConvertToSinglePlane_(srcImage, *rimage);
if (FAILED(hr)) if (FAILED(hr))
{ {
image.Release(); image.Release();
@ -4753,7 +4829,10 @@ HRESULT ConvertToSinglePlane( const Image& srcImage, ScratchImage& image )
// Convert image from planar to single plane (complex) // Convert image from planar to single plane (complex)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT ConvertToSinglePlane( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::ConvertToSinglePlane(
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
ScratchImage& result) ScratchImage& result)
{ {
if (!srcImages || !nimages) if (!srcImages || !nimages)
@ -4812,7 +4891,7 @@ HRESULT ConvertToSinglePlane( const Image* srcImages, size_t nimages, const TexM
return E_FAIL; return E_FAIL;
} }
hr = _ConvertToSinglePlane( src, dst ); hr = ConvertToSinglePlane_(src, dst);
if (FAILED(hr)) if (FAILED(hr))
{ {
result.Release(); result.Release();
@ -4822,5 +4901,3 @@ HRESULT ConvertToSinglePlane( const Image* srcImages, size_t nimages, const TexM
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -23,13 +23,16 @@
#define IID_GRAPHICS_PPV_ARGS(x) IID_PPV_ARGS(x) #define IID_GRAPHICS_PPV_ARGS(x) IID_PPV_ARGS(x)
#endif #endif
using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace DirectX namespace
{ {
HRESULT Capture(
static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ const TexMetadata& metadata, _In_ ID3D11DeviceContext* pContext,
_In_ const ScratchImage& result ) _In_ ID3D11Resource* pSource,
const TexMetadata& metadata,
const ScratchImage& result)
{ {
if (!pContext || !pSource || !result.GetPixels()) if (!pContext || !pSource || !result.GetPixels())
return E_POINTER; return E_POINTER;
@ -186,6 +189,7 @@ static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -196,7 +200,9 @@ static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource
// Determine if given texture metadata is supported on the given device // Determine if given texture metadata is supported on the given device
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsSupportedTexture( ID3D11Device* pDevice, const TexMetadata& metadata ) bool DirectX::IsSupportedTexture(
ID3D11Device* pDevice,
const TexMetadata& metadata)
{ {
if (!pDevice) if (!pDevice)
return false; return false;
@ -384,17 +390,30 @@ bool IsSupportedTexture( ID3D11Device* pDevice, const TexMetadata& metadata )
// Create a texture resource // Create a texture resource
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CreateTexture( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::CreateTexture(
ID3D11Device* pDevice,
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
ID3D11Resource** ppResource) ID3D11Resource** ppResource)
{ {
return CreateTextureEx( pDevice, srcImages, nimages, metadata, return CreateTextureEx(
pDevice, srcImages, nimages, metadata,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
ppResource); ppResource);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CreateTextureEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::CreateTextureEx(
D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Device* pDevice,
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11Resource** ppResource) ID3D11Resource** ppResource)
{ {
if (!pDevice || !srcImages || !nimages || !ppResource) if (!pDevice || !srcImages || !nimages || !ppResource)
@ -580,17 +599,30 @@ HRESULT CreateTextureEx( ID3D11Device* pDevice, const Image* srcImages, size_t n
// Create a shader resource view and associated texture // Create a shader resource view and associated texture
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CreateShaderResourceView( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::CreateShaderResourceView(
ID3D11Device* pDevice,
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
ID3D11ShaderResourceView** ppSRV) ID3D11ShaderResourceView** ppSRV)
{ {
return CreateShaderResourceViewEx( pDevice, srcImages, nimages, metadata, return CreateShaderResourceViewEx(
pDevice, srcImages, nimages, metadata,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
ppSRV); ppSRV);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CreateShaderResourceViewEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::CreateShaderResourceViewEx(
D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Device* pDevice,
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11ShaderResourceView** ppSRV) ID3D11ShaderResourceView** ppSRV)
{ {
if (!ppSRV) if (!ppSRV)
@ -682,7 +714,11 @@ HRESULT CreateShaderResourceViewEx( ID3D11Device* pDevice, const Image* srcImage
// Save a texture resource to a DDS file in memory/on disk // Save a texture resource to a DDS file in memory/on disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11Resource* pSource, ScratchImage& result ) HRESULT DirectX::CaptureTexture(
ID3D11Device* pDevice,
ID3D11DeviceContext* pContext,
ID3D11Resource* pSource,
ScratchImage& result)
{ {
if (!pDevice || !pContext || !pSource) if (!pDevice || !pContext || !pSource)
return E_INVALIDARG; return E_INVALIDARG;
@ -734,7 +770,7 @@ HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID
if (FAILED(hr)) if (FAILED(hr))
break; break;
hr = _Capture( pContext, pStaging.Get(), mdata, result ); hr = Capture(pContext, pStaging.Get(), mdata, result);
} }
break; break;
@ -835,7 +871,7 @@ HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID
if (FAILED(hr)) if (FAILED(hr))
break; break;
hr = _Capture( pContext, pStaging.Get(), mdata, result ); hr = Capture(pContext, pStaging.Get(), mdata, result);
} }
break; break;
@ -880,7 +916,7 @@ HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID
if (FAILED(hr)) if (FAILED(hr))
break; break;
hr = _Capture( pContext, pStaging.Get(), mdata, result ); hr = Capture(pContext, pStaging.Get(), mdata, result);
} }
break; break;
@ -897,5 +933,3 @@ HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -17,6 +17,8 @@
#include "dds.h" #include "dds.h"
using namespace DirectX;
namespace namespace
{ {
class auto_delete_file class auto_delete_file
@ -42,10 +44,6 @@ namespace
private: private:
HANDLE m_handle; HANDLE m_handle;
}; };
}
namespace DirectX
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Legacy format mapping table (used for DDS files without 'DX10' extended header) // Legacy format mapping table (used for DDS files without 'DX10' extended header)
@ -172,7 +170,7 @@ const LegacyDDS g_LegacyDDSMap[] =
// ZBuffer D3DFMT_D16_LOCKABLE // ZBuffer D3DFMT_D16_LOCKABLE
// FourCC 82 D3DFMT_D32F_LOCKABLE // FourCC 82 D3DFMT_D32F_LOCKABLE
static DXGI_FORMAT _GetDXGIFormat( const DDS_PIXELFORMAT& ddpf, DWORD flags, _Inout_ DWORD& convFlags ) DXGI_FORMAT GetDXGIFormat(const DDS_PIXELFORMAT& ddpf, DWORD flags, _Inout_ DWORD& convFlags)
{ {
const size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS); const size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS);
size_t index = 0; size_t index = 0;
@ -227,7 +225,11 @@ static DXGI_FORMAT _GetDXGIFormat( const DDS_PIXELFORMAT& ddpf, DWORD flags, _In
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes DDS header including optional DX10 extended header // Decodes DDS header including optional DX10 extended header
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecodeDDSHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t size, DWORD flags, _Out_ TexMetadata& metadata, HRESULT DecodeDDSHeader(
_In_reads_bytes_(size) const void* pSource,
size_t size,
DWORD flags,
_Out_ TexMetadata& metadata,
_Inout_ DWORD& convFlags) _Inout_ DWORD& convFlags)
{ {
if (!pSource) if (!pSource)
@ -378,7 +380,7 @@ static HRESULT _DecodeDDSHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t
// Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
} }
metadata.format = _GetDXGIFormat( pHeader->ddspf, flags, convFlags ); metadata.format = GetDXGIFormat(pHeader->ddspf, flags, convFlags);
if (metadata.format == DXGI_FORMAT_UNKNOWN) if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
@ -463,14 +465,19 @@ static HRESULT _DecodeDDSHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t
return S_OK; return S_OK;
} }
}
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes DDS file header (magic value, header, optional DX10 extended header) // Encodes DDS file header (magic value, header, optional DX10 extended header)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT _EncodeDDSHeader( const TexMetadata& metadata, DWORD flags, HRESULT DirectX::_EncodeDDSHeader(
LPVOID pDestination, size_t maxsize, size_t& required ) const TexMetadata& metadata,
DWORD flags,
void* pDestination,
size_t maxsize,
size_t& required)
{ {
if (!IsValid(metadata.format)) if (!IsValid(metadata.format))
return E_INVALIDARG; return E_INVALIDARG;
@ -697,6 +704,8 @@ HRESULT _EncodeDDSHeader( const TexMetadata& metadata, DWORD flags,
} }
namespace
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Converts an image row with optional clearing of alpha value to 1.0 // Converts an image row with optional clearing of alpha value to 1.0
// Returns true if supported, false if expansion case not supported // Returns true if supported, false if expansion case not supported
@ -716,7 +725,7 @@ enum TEXP_LEGACY_FORMAT
TEXP_LEGACY_A8L8 TEXP_LEGACY_A8L8
}; };
inline static TEXP_LEGACY_FORMAT _FindLegacyFormat( DWORD flags ) inline TEXP_LEGACY_FORMAT _FindLegacyFormat(DWORD flags)
{ {
TEXP_LEGACY_FORMAT lformat = TEXP_LEGACY_UNKNOWN; TEXP_LEGACY_FORMAT lformat = TEXP_LEGACY_UNKNOWN;
@ -745,9 +754,15 @@ inline static TEXP_LEGACY_FORMAT _FindLegacyFormat( DWORD flags )
} }
_Success_(return != false) _Success_(return != false)
static bool _LegacyExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, size_t outSize, _In_ DXGI_FORMAT outFormat, bool LegacyExpandScanline(
_In_reads_bytes_(inSize) LPCVOID pSource, size_t inSize, _In_ TEXP_LEGACY_FORMAT inFormat, _Out_writes_bytes_(outSize) void* pDestination,
_In_reads_opt_(256) const uint32_t* pal8, _In_ DWORD flags ) size_t outSize,
_In_ DXGI_FORMAT outFormat,
_In_reads_bytes_(inSize) const void* pSource,
size_t inSize,
_In_ TEXP_LEGACY_FORMAT inFormat,
_In_reads_opt_(256) const uint32_t* pal8,
_In_ DWORD flags)
{ {
assert(pDestination && outSize > 0); assert(pDestination && outSize > 0);
assert(pSource && inSize > 0); assert(pSource && inSize > 0);
@ -1043,8 +1058,14 @@ static bool _LegacyExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestinati
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Converts or copies image data from pPixels into scratch image data // Converts or copies image data from pPixels into scratch image data
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size_t size, HRESULT CopyImage(
_In_ const TexMetadata& metadata, _In_ DWORD cpFlags, _In_ DWORD convFlags, _In_reads_opt_(256) const uint32_t *pal8, _In_ const ScratchImage& image ) _In_reads_bytes_(size) const void* pPixels,
_In_ size_t size,
_In_ const TexMetadata& metadata,
_In_ DWORD cpFlags,
_In_ DWORD convFlags,
_In_reads_opt_(256) const uint32_t *pal8,
_In_ const ScratchImage& image)
{ {
assert(pPixels); assert(pPixels);
assert(image.GetPixels()); assert(image.GetPixels());
@ -1163,7 +1184,7 @@ static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size
else else
{ {
TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat(convFlags); TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat(convFlags);
if ( !_LegacyExpandScanline( pDest, dpitch, metadata.format, if (!LegacyExpandScanline(pDest, dpitch, metadata.format,
pSrc, spitch, lformat, pal8, pSrc, spitch, lformat, pal8,
tflags)) tflags))
return E_FAIL; return E_FAIL;
@ -1242,7 +1263,7 @@ static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size
else else
{ {
TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat(convFlags); TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat(convFlags);
if ( !_LegacyExpandScanline( pDest, dpitch, metadata.format, if (!LegacyExpandScanline(pDest, dpitch, metadata.format,
pSrc, spitch, lformat, pal8, pSrc, spitch, lformat, pal8,
tflags)) tflags))
return E_FAIL; return E_FAIL;
@ -1276,7 +1297,7 @@ static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size
return S_OK; return S_OK;
} }
static HRESULT _CopyImageInPlace( DWORD convFlags, _In_ const ScratchImage& image ) HRESULT CopyImageInPlace(DWORD convFlags, _In_ const ScratchImage& image)
{ {
if (!image.GetPixels()) if (!image.GetPixels())
return E_FAIL; return E_FAIL;
@ -1320,6 +1341,7 @@ static HRESULT _CopyImageInPlace( DWORD convFlags, _In_ const ScratchImage& imag
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -1331,26 +1353,33 @@ static HRESULT _CopyImageInPlace( DWORD convFlags, _In_ const ScratchImage& imag
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata& metadata ) HRESULT DirectX::GetMetadataFromDDSMemory(
const void* pSource,
size_t size,
DWORD flags,
TexMetadata& metadata)
{ {
if (!pSource || size == 0) if (!pSource || size == 0)
return E_INVALIDARG; return E_INVALIDARG;
DWORD convFlags = 0; DWORD convFlags = 0;
return _DecodeDDSHeader( pSource, size, flags, metadata, convFlags ); return DecodeDDSHeader(pSource, size, flags, metadata, convFlags);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata& metadata ) HRESULT DirectX::GetMetadataFromDDSFile(
const wchar_t* szFile,
DWORD flags,
TexMetadata& metadata)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
@ -1358,30 +1387,20 @@ HRESULT GetMetadataFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
} }
// Get the file size // Get the file size
LARGE_INTEGER fileSize = {0};
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
FILE_STANDARD_INFO fileInfo; FILE_STANDARD_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
fileSize = fileInfo.EndOfFile;
#else
if ( !GetFileSizeEx( hFile.get(), &fileSize ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
#endif
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file)
if ( fileSize.HighPart > 0 ) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
} }
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if ( fileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -1391,13 +1410,13 @@ HRESULT GetMetadataFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
uint8_t header[MAX_HEADER_SIZE]; uint8_t header[MAX_HEADER_SIZE];
DWORD bytesRead = 0; DWORD bytesRead = 0;
if ( !ReadFile( hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
DWORD convFlags = 0; DWORD convFlags = 0;
return _DecodeDDSHeader( header, bytesRead, flags, metadata, convFlags ); return DecodeDDSHeader(header, bytesRead, flags, metadata, convFlags);
} }
@ -1405,7 +1424,12 @@ HRESULT GetMetadataFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
// Load a DDS file in memory // Load a DDS file in memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata* metadata, ScratchImage& image ) HRESULT DirectX::LoadFromDDSMemory(
const void* pSource,
size_t size,
DWORD flags,
TexMetadata* metadata,
ScratchImage& image)
{ {
if (!pSource || size == 0) if (!pSource || size == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -1414,7 +1438,7 @@ HRESULT LoadFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
DWORD convFlags = 0; DWORD convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = _DecodeDDSHeader( pSource, size, flags, mdata, convFlags ); HRESULT hr = DecodeDDSHeader(pSource, size, flags, mdata, convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1438,9 +1462,9 @@ HRESULT LoadFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
auto pPixels = reinterpret_cast<LPCVOID>( reinterpret_cast<const uint8_t*>(pSource) + offset ); auto pPixels = reinterpret_cast<const void*>(reinterpret_cast<const uint8_t*>(pSource) + offset);
assert(pPixels); assert(pPixels);
hr = _CopyImage( pPixels, size - offset, mdata, hr = CopyImage(pPixels, size - offset, mdata,
(flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE, convFlags, pal8, image); (flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE, convFlags, pal8, image);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -1458,7 +1482,11 @@ HRESULT LoadFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
// Load a DDS file from disk // Load a DDS file from disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, ScratchImage& image ) HRESULT DirectX::LoadFromDDSFile(
const wchar_t* szFile,
DWORD flags,
TexMetadata* metadata,
ScratchImage& image)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -1466,10 +1494,10 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
image.Release(); image.Release();
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle ( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
ScopedHandle hFile( safe_handle ( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
@ -1478,30 +1506,20 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
} }
// Get the file size // Get the file size
LARGE_INTEGER fileSize = {0};
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
FILE_STANDARD_INFO fileInfo; FILE_STANDARD_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
fileSize = fileInfo.EndOfFile;
#else
if ( !GetFileSizeEx( hFile.get(), &fileSize ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
#endif
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file)
if ( fileSize.HighPart > 0 ) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
} }
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if ( fileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -1511,14 +1529,14 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
uint8_t header[MAX_HEADER_SIZE]; uint8_t header[MAX_HEADER_SIZE];
DWORD bytesRead = 0; DWORD bytesRead = 0;
if ( !ReadFile( hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
DWORD convFlags = 0; DWORD convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = _DecodeDDSHeader( header, bytesRead, flags, mdata, convFlags ); HRESULT hr = DecodeDDSHeader(header, bytesRead, flags, mdata, convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1545,7 +1563,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if ( !ReadFile( hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1558,7 +1576,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
offset += (256 * sizeof(uint32_t)); offset += (256 * sizeof(uint32_t));
} }
DWORD remaining = fileSize.LowPart - offset; DWORD remaining = fileInfo.EndOfFile.LowPart - offset;
if (remaining == 0) if (remaining == 0)
return E_FAIL; return E_FAIL;
@ -1575,7 +1593,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if ( !ReadFile( hFile.get(), temp.get(), remaining, &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1587,7 +1605,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
return E_FAIL; return E_FAIL;
} }
hr = _CopyImage( temp.get(), remaining, mdata, hr = CopyImage(temp.get(), remaining, mdata,
(flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE, (flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE,
convFlags, pal8.get(), image); convFlags, pal8.get(), image);
if (FAILED(hr)) if (FAILED(hr))
@ -1604,7 +1622,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
return E_FAIL; return E_FAIL;
} }
if ( !ReadFile( hFile.get(), image.GetPixels(), static_cast<DWORD>( image.GetPixelsSize() ), &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1613,7 +1631,7 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA)) if (convFlags & (CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA))
{ {
// Swizzle/copy image in place // Swizzle/copy image in place
hr = _CopyImageInPlace( convFlags, image ); hr = CopyImageInPlace(convFlags, image);
if (FAILED(hr)) if (FAILED(hr))
{ {
image.Release(); image.Release();
@ -1633,7 +1651,12 @@ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
// Save a DDS file to memory // Save a DDS file to memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToDDSMemory( const Image* images, size_t nimages, const TexMetadata& metadata, DWORD flags, Blob& blob ) HRESULT DirectX::SaveToDDSMemory(
const Image* images,
size_t nimages,
const TexMetadata& metadata,
DWORD flags,
Blob& blob)
{ {
if (!images || (nimages == 0)) if (!images || (nimages == 0))
return E_INVALIDARG; return E_INVALIDARG;
@ -1844,7 +1867,12 @@ HRESULT SaveToDDSMemory( const Image* images, size_t nimages, const TexMetadata&
// Save a DDS file to disk // Save a DDS file to disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& metadata, DWORD flags, LPCWSTR szFile ) HRESULT DirectX::SaveToDDSFile(
const Image* images,
size_t nimages,
const TexMetadata& metadata,
DWORD flags,
const wchar_t* szFile)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -1859,9 +1887,9 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
// Create file and write header // Create file and write header
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_WRITE | DELETE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_WRITE | DELETE, 0, nullptr, CREATE_ALWAYS, 0, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
@ -1871,7 +1899,7 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
auto_delete_file delonfail(hFile.get()); auto_delete_file delonfail(hFile.get());
DWORD bytesWritten; DWORD bytesWritten;
if ( !WriteFile( hFile.get(), header, static_cast<DWORD>( required ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), header, static_cast<DWORD>(required), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1906,7 +1934,7 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
if (images[index].slicePitch == ddsSlicePitch) if (images[index].slicePitch == ddsSlicePitch)
{ {
if ( !WriteFile( hFile.get(), images[ index ].pixels, static_cast<DWORD>( ddsSlicePitch ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1930,7 +1958,7 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
size_t lines = ComputeScanlines(metadata.format, images[index].height); size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
if ( !WriteFile( hFile.get(), sPtr, static_cast<DWORD>( ddsRowPitch ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1974,7 +2002,7 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
if (images[index].slicePitch == ddsSlicePitch) if (images[index].slicePitch == ddsSlicePitch)
{ {
if ( !WriteFile( hFile.get(), images[ index ].pixels, static_cast<DWORD>( ddsSlicePitch ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1998,7 +2026,7 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
size_t lines = ComputeScanlines(metadata.format, images[index].height); size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j) for (size_t j = 0; j < lines; ++j)
{ {
if ( !WriteFile( hFile.get(), sPtr, static_cast<DWORD>( ddsRowPitch ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -2027,5 +2055,3 @@ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& m
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -15,16 +15,19 @@
#include "directxtexp.h" #include "directxtexp.h"
using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace DirectX namespace
{ {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Do flip/rotate operation using WIC // Do flip/rotate operation using WIC
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWORD flags, HRESULT PerformFlipRotateUsingWIC(
_In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage ) const Image& srcImage,
DWORD flags,
const WICPixelFormatGUID& pfGUID,
const Image& destImage)
{ {
if (!srcImage.pixels || !destImage.pixels) if (!srcImage.pixels || !destImage.pixels)
return E_POINTER; return E_POINTER;
@ -82,7 +85,10 @@ static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWOR
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Do conversion, flip/rotate using WIC, conversion cycle // Do conversion, flip/rotate using WIC, conversion cycle
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage ) HRESULT PerformFlipRotateViaF32(
const Image& srcImage,
DWORD flags,
const Image& destImage)
{ {
if (!srcImage.pixels || !destImage.pixels) if (!srcImage.pixels || !destImage.pixels)
return E_POINTER; return E_POINTER;
@ -108,7 +114,7 @@ static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD
if (!tdest) if (!tdest)
return E_POINTER; return E_POINTER;
hr = _PerformFlipRotateUsingWIC( *tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest ); hr = PerformFlipRotateUsingWIC(*tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -120,6 +126,7 @@ static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -130,7 +137,10 @@ static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD
// Flip/rotate image // Flip/rotate image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image ) HRESULT DirectX::FlipRotate(
const Image& srcImage,
DWORD flags,
ScratchImage& image)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -188,12 +198,12 @@ HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image )
if (_DXGIToWIC(srcImage.format, pfGUID)) if (_DXGIToWIC(srcImage.format, pfGUID))
{ {
// Case 1: Source format is supported by Windows Imaging Component // Case 1: Source format is supported by Windows Imaging Component
hr = _PerformFlipRotateUsingWIC( srcImage, flags, pfGUID, *rimage ); hr = PerformFlipRotateUsingWIC(srcImage, flags, pfGUID, *rimage);
} }
else else
{ {
// Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
hr = _PerformFlipRotateViaF32( srcImage, flags, *rimage ); hr = PerformFlipRotateViaF32(srcImage, flags, *rimage);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -210,8 +220,12 @@ HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image )
// Flip/rotate image (complex) // Flip/rotate image (complex)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::FlipRotate(
DWORD flags, ScratchImage& result ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DWORD flags,
ScratchImage& result)
{ {
if (!srcImages || !nimages) if (!srcImages || !nimages)
return E_INVALIDARG; return E_INVALIDARG;
@ -307,12 +321,12 @@ HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& m
if (wicpf) if (wicpf)
{ {
// Case 1: Source format is supported by Windows Imaging Component // Case 1: Source format is supported by Windows Imaging Component
hr = _PerformFlipRotateUsingWIC( src, flags, pfGUID, dst ); hr = PerformFlipRotateUsingWIC(src, flags, pfGUID, dst);
} }
else else
{ {
// Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
hr = _PerformFlipRotateViaF32( src, flags, dst ); hr = PerformFlipRotateViaF32(src, flags, dst);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -324,5 +338,3 @@ HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& m
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -17,17 +17,22 @@
namespace DirectX namespace DirectX
{ {
extern bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels); extern bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels);
extern bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels); extern bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels);
extern bool _IsAlphaAllOpaqueBC(_In_ const Image& cImage); extern bool _IsAlphaAllOpaqueBC(_In_ const Image& cImage);
}
using namespace DirectX;
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Determines number of image array entries and pixel size // Determines number of image array entries and pixel size
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void _DetermineImageArray( const TexMetadata& metadata, DWORD cpFlags, void DirectX::_DetermineImageArray(
size_t& nImages, size_t& pixelSize ) const TexMetadata& metadata,
DWORD cpFlags,
size_t& nImages,
size_t& pixelSize)
{ {
assert(metadata.width > 0 && metadata.height > 0 && metadata.depth > 0); assert(metadata.width > 0 && metadata.height > 0 && metadata.depth > 0);
assert(metadata.arraySize > 0); assert(metadata.arraySize > 0);
@ -105,9 +110,13 @@ void _DetermineImageArray( const TexMetadata& metadata, DWORD cpFlags,
// Fills in the image array entries // Fills in the image array entries
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool _SetupImageArray( uint8_t *pMemory, size_t pixelSize, bool DirectX::_SetupImageArray(
const TexMetadata& metadata, DWORD cpFlags, uint8_t *pMemory,
Image* images, size_t nImages ) size_t pixelSize,
const TexMetadata& metadata,
DWORD cpFlags,
Image* images,
size_t nImages)
{ {
assert(pMemory); assert(pMemory);
assert(pixelSize > 0); assert(pixelSize > 0);
@ -235,16 +244,16 @@ ScratchImage& ScratchImage::operator= (ScratchImage&& moveFrom)
{ {
Release(); Release();
_nimages = moveFrom._nimages; m_nimages = moveFrom.m_nimages;
_size = moveFrom._size; m_size = moveFrom.m_size;
_metadata = moveFrom._metadata; m_metadata = moveFrom.m_metadata;
_image = moveFrom._image; m_image = moveFrom.m_image;
_memory = moveFrom._memory; m_memory = moveFrom.m_memory;
moveFrom._nimages = 0; moveFrom.m_nimages = 0;
moveFrom._size = 0; moveFrom.m_size = 0;
moveFrom._image = nullptr; moveFrom.m_image = nullptr;
moveFrom._memory = nullptr; moveFrom.m_memory = nullptr;
} }
return *this; return *this;
} }
@ -302,34 +311,34 @@ HRESULT ScratchImage::Initialize( const TexMetadata& mdata, DWORD flags )
Release(); Release();
_metadata.width = mdata.width; m_metadata.width = mdata.width;
_metadata.height = mdata.height; m_metadata.height = mdata.height;
_metadata.depth = mdata.depth; m_metadata.depth = mdata.depth;
_metadata.arraySize = mdata.arraySize; m_metadata.arraySize = mdata.arraySize;
_metadata.mipLevels = mipLevels; m_metadata.mipLevels = mipLevels;
_metadata.miscFlags = mdata.miscFlags; m_metadata.miscFlags = mdata.miscFlags;
_metadata.miscFlags2 = mdata.miscFlags2; m_metadata.miscFlags2 = mdata.miscFlags2;
_metadata.format = mdata.format; m_metadata.format = mdata.format;
_metadata.dimension = mdata.dimension; m_metadata.dimension = mdata.dimension;
size_t pixelSize, nimages; size_t pixelSize, nimages;
_DetermineImageArray( _metadata, flags, nimages, pixelSize ); _DetermineImageArray(m_metadata, flags, nimages, pixelSize);
_image = new (std::nothrow) Image[ nimages ]; m_image = new (std::nothrow) Image[nimages];
if ( !_image ) if (!m_image)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
_nimages = nimages; m_nimages = nimages;
memset( _image, 0, sizeof(Image) * nimages ); memset(m_image, 0, sizeof(Image) * nimages);
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) ); m_memory = reinterpret_cast<uint8_t*>(_aligned_malloc(pixelSize, 16));
if ( !_memory ) if (!m_memory)
{ {
Release(); Release();
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
_size = pixelSize; m_size = pixelSize;
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) if (!_SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))
{ {
Release(); Release();
return E_FAIL; return E_FAIL;
@ -349,7 +358,7 @@ HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t array
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
_metadata.dimension = TEX_DIMENSION_TEXTURE1D; m_metadata.dimension = TEX_DIMENSION_TEXTURE1D;
return S_OK; return S_OK;
} }
@ -368,34 +377,34 @@ HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height
Release(); Release();
_metadata.width = width; m_metadata.width = width;
_metadata.height = height; m_metadata.height = height;
_metadata.depth = 1; m_metadata.depth = 1;
_metadata.arraySize = arraySize; m_metadata.arraySize = arraySize;
_metadata.mipLevels = mipLevels; m_metadata.mipLevels = mipLevels;
_metadata.miscFlags = 0; m_metadata.miscFlags = 0;
_metadata.miscFlags2 = 0; m_metadata.miscFlags2 = 0;
_metadata.format = fmt; m_metadata.format = fmt;
_metadata.dimension = TEX_DIMENSION_TEXTURE2D; m_metadata.dimension = TEX_DIMENSION_TEXTURE2D;
size_t pixelSize, nimages; size_t pixelSize, nimages;
_DetermineImageArray( _metadata, flags, nimages, pixelSize ); _DetermineImageArray(m_metadata, flags, nimages, pixelSize);
_image = new (std::nothrow) Image[ nimages ]; m_image = new (std::nothrow) Image[nimages];
if ( !_image ) if (!m_image)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
_nimages = nimages; m_nimages = nimages;
memset( _image, 0, sizeof(Image) * nimages ); memset(m_image, 0, sizeof(Image) * nimages);
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) ); m_memory = reinterpret_cast<uint8_t*>(_aligned_malloc(pixelSize, 16));
if ( !_memory ) if (!m_memory)
{ {
Release(); Release();
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
_size = pixelSize; m_size = pixelSize;
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) if (!_SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))
{ {
Release(); Release();
return E_FAIL; return E_FAIL;
@ -418,37 +427,37 @@ HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height
Release(); Release();
_metadata.width = width; m_metadata.width = width;
_metadata.height = height; m_metadata.height = height;
_metadata.depth = depth; m_metadata.depth = depth;
_metadata.arraySize = 1; // Direct3D 10.x/11 does not support arrays of 3D textures m_metadata.arraySize = 1; // Direct3D 10.x/11 does not support arrays of 3D textures
_metadata.mipLevels = mipLevels; m_metadata.mipLevels = mipLevels;
_metadata.miscFlags = 0; m_metadata.miscFlags = 0;
_metadata.miscFlags2 = 0; m_metadata.miscFlags2 = 0;
_metadata.format = fmt; m_metadata.format = fmt;
_metadata.dimension = TEX_DIMENSION_TEXTURE3D; m_metadata.dimension = TEX_DIMENSION_TEXTURE3D;
size_t pixelSize, nimages; size_t pixelSize, nimages;
_DetermineImageArray( _metadata, flags, nimages, pixelSize ); _DetermineImageArray(m_metadata, flags, nimages, pixelSize);
_image = new (std::nothrow) Image[ nimages ]; m_image = new (std::nothrow) Image[nimages];
if ( !_image ) if (!m_image)
{ {
Release(); Release();
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
_nimages = nimages; m_nimages = nimages;
memset( _image, 0, sizeof(Image) * nimages ); memset(m_image, 0, sizeof(Image) * nimages);
_memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) ); m_memory = reinterpret_cast<uint8_t*>(_aligned_malloc(pixelSize, 16));
if ( !_memory ) if (!m_memory)
{ {
Release(); Release();
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
_size = pixelSize; m_size = pixelSize;
if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) if (!_SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))
{ {
Release(); Release();
return E_FAIL; return E_FAIL;
@ -468,7 +477,7 @@ HRESULT ScratchImage::InitializeCube( DXGI_FORMAT fmt, size_t width, size_t heig
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
_metadata.miscFlags |= TEX_MISC_TEXTURECUBE; m_metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
return S_OK; return S_OK;
} }
@ -491,12 +500,12 @@ HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D,
if (!sptr) if (!sptr)
return E_POINTER; return E_POINTER;
auto dptr = reinterpret_cast<uint8_t*>( _image[0].pixels ); auto dptr = reinterpret_cast<uint8_t*>(m_image[0].pixels);
if (!dptr) if (!dptr)
return E_POINTER; return E_POINTER;
size_t spitch = srcImage.rowPitch; size_t spitch = srcImage.rowPitch;
size_t dpitch = _image[0].rowPitch; size_t dpitch = m_image[0].rowPitch;
size_t size = std::min<size_t>(dpitch, spitch); size_t size = std::min<size_t>(dpitch, spitch);
@ -549,13 +558,13 @@ HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nIm
if (!sptr) if (!sptr)
return E_POINTER; return E_POINTER;
assert( index < _nimages ); assert(index < m_nimages);
auto dptr = reinterpret_cast<uint8_t*>( _image[index].pixels ); auto dptr = reinterpret_cast<uint8_t*>(m_image[index].pixels);
if (!dptr) if (!dptr)
return E_POINTER; return E_POINTER;
size_t spitch = images[index].rowPitch; size_t spitch = images[index].rowPitch;
size_t dpitch = _image[index].rowPitch; size_t dpitch = m_image[index].rowPitch;
size_t size = std::min<size_t>(dpitch, spitch); size_t size = std::min<size_t>(dpitch, spitch);
@ -584,7 +593,7 @@ HRESULT ScratchImage::InitializeCubeFromImages( const Image* images, size_t nIma
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
_metadata.miscFlags |= TEX_MISC_TEXTURECUBE; m_metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
return S_OK; return S_OK;
} }
@ -625,13 +634,13 @@ HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth,
if (!sptr) if (!sptr)
return E_POINTER; return E_POINTER;
assert( slice < _nimages ); assert(slice < m_nimages);
auto dptr = reinterpret_cast<uint8_t*>( _image[slice].pixels ); auto dptr = reinterpret_cast<uint8_t*>(m_image[slice].pixels);
if (!dptr) if (!dptr)
return E_POINTER; return E_POINTER;
size_t spitch = images[slice].rowPitch; size_t spitch = images[slice].rowPitch;
size_t dpitch = _image[slice].rowPitch; size_t dpitch = m_image[slice].rowPitch;
size_t size = std::min<size_t>(dpitch, spitch); size_t size = std::min<size_t>(dpitch, spitch);
@ -648,39 +657,39 @@ HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth,
void ScratchImage::Release() void ScratchImage::Release()
{ {
_nimages = 0; m_nimages = 0;
_size = 0; m_size = 0;
if ( _image ) if (m_image)
{ {
delete [] _image; delete[] m_image;
_image = 0; m_image = nullptr;
} }
if ( _memory ) if (m_memory)
{ {
_aligned_free( _memory ); _aligned_free(m_memory);
_memory = 0; m_memory = nullptr;
} }
memset(&_metadata, 0, sizeof(_metadata)); memset(&m_metadata, 0, sizeof(m_metadata));
} }
_Use_decl_annotations_ _Use_decl_annotations_
bool ScratchImage::OverrideFormat(DXGI_FORMAT f) bool ScratchImage::OverrideFormat(DXGI_FORMAT f)
{ {
if ( !_image ) if (!m_image)
return false; return false;
if (!IsValid(f) || IsPlanar(f) || IsPalettized(f)) if (!IsValid(f) || IsPlanar(f) || IsPalettized(f))
return false; return false;
for( size_t index = 0; index < _nimages; ++index ) for (size_t index = 0; index < m_nimages; ++index)
{ {
_image[ index ].format = f; m_image[index].format = f;
} }
_metadata.format = f; m_metadata.format = f;
return true; return true;
} }
@ -688,22 +697,22 @@ bool ScratchImage::OverrideFormat( DXGI_FORMAT f )
_Use_decl_annotations_ _Use_decl_annotations_
const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const
{ {
if ( mip >= _metadata.mipLevels ) if (mip >= m_metadata.mipLevels)
return nullptr; return nullptr;
size_t index = 0; size_t index = 0;
switch( _metadata.dimension ) switch (m_metadata.dimension)
{ {
case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE1D:
case TEX_DIMENSION_TEXTURE2D: case TEX_DIMENSION_TEXTURE2D:
if (slice > 0) if (slice > 0)
return nullptr; return nullptr;
if ( item >= _metadata.arraySize ) if (item >= m_metadata.arraySize)
return nullptr; return nullptr;
index = item*( _metadata.mipLevels ) + mip; index = item*(m_metadata.mipLevels) + mip;
break; break;
case TEX_DIMENSION_TEXTURE3D: case TEX_DIMENSION_TEXTURE3D:
@ -714,7 +723,7 @@ const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const
} }
else else
{ {
size_t d = _metadata.depth; size_t d = m_metadata.depth;
for (size_t level = 0; level < mip; ++level) for (size_t level = 0; level < mip; ++level)
{ {
@ -734,37 +743,37 @@ const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const
return nullptr; return nullptr;
} }
return &_image[index]; return &m_image[index];
} }
bool ScratchImage::IsAlphaAllOpaque() const bool ScratchImage::IsAlphaAllOpaque() const
{ {
if ( !_image ) if (!m_image)
return false; return false;
if ( !HasAlpha( _metadata.format ) ) if (!HasAlpha(m_metadata.format))
return true; return true;
if ( IsCompressed( _metadata.format ) ) if (IsCompressed(m_metadata.format))
{ {
for( size_t index = 0; index < _nimages; ++index ) for (size_t index = 0; index < m_nimages; ++index)
{ {
if ( !_IsAlphaAllOpaqueBC( _image[ index ] ) ) if (!_IsAlphaAllOpaqueBC(m_image[index]))
return false; return false;
} }
} }
else else
{ {
ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*_metadata.width), 16 ) ) ); ScopedAlignedArrayXMVECTOR scanline(reinterpret_cast<XMVECTOR*>(_aligned_malloc((sizeof(XMVECTOR)*m_metadata.width), 16)));
if (!scanline) if (!scanline)
return false; return false;
static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f }; static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
for( size_t index = 0; index < _nimages; ++index ) for (size_t index = 0; index < m_nimages; ++index)
{ {
#pragma warning( suppress : 6011 ) #pragma warning( suppress : 6011 )
const Image& img = _image[ index ]; const Image& img = m_image[index];
const uint8_t *pPixels = img.pixels; const uint8_t *pPixels = img.pixels;
assert(pPixels); assert(pPixels);
@ -790,5 +799,3 @@ bool ScratchImage::IsAlphaAllOpaque() const
return true; return true;
} }
}; // namespace

View File

@ -17,22 +17,18 @@
#include "filters.h" #include "filters.h"
using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace DirectX namespace
{ {
inline bool ispow2(_In_ size_t x)
//-------------------------------------------------------------------------------------
// Mipmap helper functions
//-------------------------------------------------------------------------------------
inline static bool ispow2( _In_ size_t x )
{ {
return ((x != 0) && !(x & (x - 1))); return ((x != 0) && !(x & (x - 1)));
} }
//--- mipmap (1D/2D) levels computation --- size_t _CountMips(_In_ size_t width, _In_ size_t height)
static size_t _CountMips( _In_ size_t width, _In_ size_t height )
{ {
size_t mipLevels = 1; size_t mipLevels = 1;
@ -50,28 +46,8 @@ static size_t _CountMips( _In_ size_t width, _In_ size_t height )
return mipLevels; return mipLevels;
} }
bool _CalculateMipLevels( _In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels )
{
if ( mipLevels > 1 )
{
size_t maxMips = _CountMips(width,height);
if ( mipLevels > maxMips )
return false;
}
else if ( mipLevels == 0 )
{
mipLevels = _CountMips(width,height);
}
else
{
mipLevels = 1;
}
return true;
}
size_t _CountMips3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth)
//--- volume mipmap (3D) levels computation ---
static size_t _CountMips3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth )
{ {
size_t mipLevels = 1; size_t mipLevels = 1;
@ -92,30 +68,11 @@ static size_t _CountMips3D( _In_ size_t width, _In_ size_t height, _In_ size_t d
return mipLevels; return mipLevels;
} }
bool _CalculateMipLevels3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels )
{
if ( mipLevels > 1 )
{
size_t maxMips = _CountMips3D(width,height,depth);
if ( mipLevels > maxMips )
return false;
}
else if ( mipLevels == 0 )
{
mipLevels = _CountMips3D(width,height,depth);
}
else
{
mipLevels = 1;
}
return true;
}
HRESULT EnsureWicBitmapPixelFormat(
//------------------------------------------------------------------------------------- _In_ IWICImagingFactory* pWIC,
// WIC related helper functions _In_ IWICBitmap* src,
//------------------------------------------------------------------------------------- _In_ DWORD filter,
static HRESULT _EnsureWicBitmapPixelFormat( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* src, _In_ DWORD filter,
_In_ const WICPixelFormatGUID& desiredPixelFormat, _In_ const WICPixelFormatGUID& desiredPixelFormat,
_Deref_out_ IWICBitmap** dest) _Deref_out_ IWICBitmap** dest)
{ {
@ -163,11 +120,58 @@ static HRESULT _EnsureWicBitmapPixelFormat( _In_ IWICImagingFactory* pWIC, _In_
return hr; return hr;
} }
}
namespace DirectX
{
bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels)
{
if (mipLevels > 1)
{
size_t maxMips = _CountMips(width, height);
if (mipLevels > maxMips)
return false;
}
else if (mipLevels == 0)
{
mipLevels = _CountMips(width, height);
}
else
{
mipLevels = 1;
}
return true;
}
bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels)
{
if (mipLevels > 1)
{
size_t maxMips = _CountMips3D(width, height, depth);
if (mipLevels > maxMips)
return false;
}
else if (mipLevels == 0)
{
mipLevels = _CountMips3D(width, height, depth);
}
else
{
mipLevels = 1;
}
return true;
}
//--- Resizing color and alpha channels separately using WIC --- //--- Resizing color and alpha channels separately using WIC ---
HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original, HRESULT _ResizeSeparateColorAndAlpha(
_In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img ) _In_ IWICImagingFactory* pWIC,
_In_ bool iswic2,
_In_ IWICBitmap* original,
_In_ size_t newWidth,
_In_ size_t newHeight,
_In_ DWORD filter,
_Inout_ const Image* img)
{ {
if (!pWIC || !original || !img) if (!pWIC || !original || !img)
return E_POINTER; return E_POINTER;
@ -243,7 +247,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmap> converted; ComPtr<IWICBitmap> converted;
hr = _EnsureWicBitmapPixelFormat( pWIC, original, filter, colorPixelFormat, converted.GetAddressOf() ); hr = EnsureWicBitmapPixelFormat(pWIC, original, filter, colorPixelFormat, converted.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = colorScaler->Initialize(converted.Get(), static_cast<UINT>(newWidth), static_cast<UINT>(newHeight), interpolationMode); hr = colorScaler->Initialize(converted.Get(), static_cast<UINT>(newWidth), static_cast<UINT>(newHeight), interpolationMode);
@ -256,7 +260,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
hr = pWIC->CreateBitmapFromSource(colorScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf()); hr = pWIC->CreateBitmapFromSource(colorScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = _EnsureWicBitmapPixelFormat( pWIC, resized.Get(), filter, colorPixelFormat, resizedColor.GetAddressOf() ); hr = EnsureWicBitmapPixelFormat(pWIC, resized.Get(), filter, colorPixelFormat, resizedColor.GetAddressOf());
} }
} }
} }
@ -270,7 +274,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmap> converted; ComPtr<IWICBitmap> converted;
hr = _EnsureWicBitmapPixelFormat( pWIC, original, filter, colorWithAlphaPixelFormat, converted.GetAddressOf() ); hr = EnsureWicBitmapPixelFormat(pWIC, original, filter, colorWithAlphaPixelFormat, converted.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = colorWithAlphaScaler->Initialize(converted.Get(), static_cast<UINT>(newWidth), static_cast<UINT>(newHeight), interpolationMode); hr = colorWithAlphaScaler->Initialize(converted.Get(), static_cast<UINT>(newWidth), static_cast<UINT>(newHeight), interpolationMode);
@ -283,7 +287,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
hr = pWIC->CreateBitmapFromSource(colorWithAlphaScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf()); hr = pWIC->CreateBitmapFromSource(colorWithAlphaScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = _EnsureWicBitmapPixelFormat( pWIC, resized.Get(), filter, colorWithAlphaPixelFormat, resizedColorWithAlpha.GetAddressOf() ); hr = EnsureWicBitmapPixelFormat(pWIC, resized.Get(), filter, colorWithAlphaPixelFormat, resizedColorWithAlpha.GetAddressOf());
} }
} }
} }
@ -362,7 +366,7 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmap> wicBitmap; ComPtr<IWICBitmap> wicBitmap;
hr = _EnsureWicBitmapPixelFormat( pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf() ); hr = EnsureWicBitmapPixelFormat(pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = wicBitmap->CopyPixels(nullptr, static_cast<UINT>(img->rowPitch), static_cast<UINT>(img->slicePitch), img->pixels); hr = wicBitmap->CopyPixels(nullptr, static_cast<UINT>(img->rowPitch), static_cast<UINT>(img->slicePitch), img->pixels);
@ -371,10 +375,12 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ bool i
return hr; return hr;
} }
}
namespace
{
//--- determine when to use WIC vs. non-WIC paths --- //--- determine when to use WIC vs. non-WIC paths ---
static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter ) bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ DWORD filter)
{ {
if (filter & TEX_FILTER_FORCE_NON_WIC) if (filter & TEX_FILTER_FORCE_NON_WIC)
{ {
@ -445,8 +451,13 @@ static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
//--- mipmap (1D/2D) generation using WIC image scalar --- //--- mipmap (1D/2D) generation using WIC image scalar ---
static HRESULT _GenerateMipMapsUsingWIC( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels, HRESULT GenerateMipMapsUsingWIC(
_In_ const WICPixelFormatGUID& pfGUID, _In_ const ScratchImage& mipChain, _In_ size_t item ) _In_ const Image& baseImage,
_In_ DWORD filter,
_In_ size_t levels,
_In_ const WICPixelFormatGUID& pfGUID,
_In_ const ScratchImage& mipChain,
_In_ size_t item)
{ {
assert(levels > 1); assert(levels > 1);
@ -578,7 +589,10 @@ static HRESULT _GenerateMipMapsUsingWIC( _In_ const Image& baseImage, _In_ DWORD
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Generate (1D/2D) mip-map helpers (custom filtering) // Generate (1D/2D) mip-map helpers (custom filtering)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _Setup2DMips( _In_reads_(nimages) const Image* baseImages, _In_ size_t nimages, _In_ const TexMetadata& mdata, HRESULT Setup2DMips(
_In_reads_(nimages) const Image* baseImages,
_In_ size_t nimages,
_In_ const TexMetadata& mdata,
_Out_ ScratchImage& mipChain) _Out_ ScratchImage& mipChain)
{ {
if (!baseImages || !nimages) if (!baseImages || !nimages)
@ -631,7 +645,7 @@ static HRESULT _Setup2DMips( _In_reads_(nimages) const Image* baseImages, _In_ s
} }
//--- 2D Point Filter --- //--- 2D Point Filter ---
static HRESULT _Generate2DMipsPointFilter( _In_ size_t levels, _In_ const ScratchImage& mipChain, _In_ size_t item ) HRESULT Generate2DMipsPointFilter(size_t levels, const ScratchImage& mipChain, size_t item)
{ {
if (!mipChain.GetImages()) if (!mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -715,7 +729,7 @@ static HRESULT _Generate2DMipsPointFilter( _In_ size_t levels, _In_ const Scratc
//--- 2D Box Filter --- //--- 2D Box Filter ---
static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) HRESULT Generate2DMipsBoxFilter(size_t levels, DWORD filter, const ScratchImage& mipChain, size_t item)
{ {
if (!mipChain.GetImages()) if (!mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -809,7 +823,7 @@ static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ DWORD filter,
//--- 2D Linear Filter --- //--- 2D Linear Filter ---
static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) HRESULT Generate2DMipsLinearFilter(size_t levels, DWORD filter, const ScratchImage& mipChain, size_t item)
{ {
if (!mipChain.GetImages()) if (!mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -919,9 +933,8 @@ static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filte
return S_OK; return S_OK;
} }
//--- 2D Cubic Filter --- //--- 2D Cubic Filter ---
static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) HRESULT Generate2DMipsCubicFilter(size_t levels, DWORD filter, const ScratchImage& mipChain, size_t item)
{ {
if (!mipChain.GetImages()) if (!mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -1107,7 +1120,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
//--- 2D Triangle Filter --- //--- 2D Triangle Filter ---
static HRESULT _Generate2DMipsTriangleFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) HRESULT Generate2DMipsTriangleFilter(size_t levels, DWORD filter, const ScratchImage& mipChain, size_t item)
{ {
if (!mipChain.GetImages()) if (!mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -1319,7 +1332,10 @@ static HRESULT _Generate2DMipsTriangleFilter( _In_ size_t levels, _In_ DWORD fil
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Generate volume mip-map helpers // Generate volume mip-map helpers
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _Setup3DMips( _In_reads_(depth) const Image* baseImages, _In_ size_t depth, size_t levels, HRESULT Setup3DMips(
_In_reads_(depth) const Image* baseImages,
size_t depth,
size_t levels,
_Out_ ScratchImage& mipChain) _Out_ ScratchImage& mipChain)
{ {
if (!baseImages || !depth) if (!baseImages || !depth)
@ -1371,7 +1387,7 @@ static HRESULT _Setup3DMips( _In_reads_(depth) const Image* baseImages, _In_ siz
//--- 3D Point Filter --- //--- 3D Point Filter ---
static HRESULT _Generate3DMipsPointFilter( _In_ size_t depth, _In_ size_t levels, _In_ const ScratchImage& mipChain ) HRESULT Generate3DMipsPointFilter(size_t depth, size_t levels, const ScratchImage& mipChain)
{ {
if (!depth || !mipChain.GetImages()) if (!depth || !mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -1517,7 +1533,7 @@ static HRESULT _Generate3DMipsPointFilter( _In_ size_t depth, _In_ size_t levels
//--- 3D Box Filter --- //--- 3D Box Filter ---
static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) HRESULT Generate3DMipsBoxFilter(size_t depth, size_t levels, DWORD filter, const ScratchImage& mipChain)
{ {
if (!depth || !mipChain.GetImages()) if (!depth || !mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -1689,7 +1705,7 @@ static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels,
//--- 3D Linear Filter --- //--- 3D Linear Filter ---
static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) HRESULT Generate3DMipsLinearFilter(size_t depth, size_t levels, DWORD filter, const ScratchImage& mipChain)
{ {
if (!depth || !mipChain.GetImages()) if (!depth || !mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -1882,7 +1898,7 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
//--- 3D Cubic Filter --- //--- 3D Cubic Filter ---
static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) HRESULT Generate3DMipsCubicFilter(size_t depth, size_t levels, DWORD filter, const ScratchImage& mipChain)
{ {
if (!depth || !mipChain.GetImages()) if (!depth || !mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -2261,7 +2277,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
//--- 3D Triangle Filter --- //--- 3D Triangle Filter ---
static HRESULT _Generate3DMipsTriangleFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) HRESULT Generate3DMipsTriangleFilter(size_t depth, size_t levels, DWORD filter, const ScratchImage& mipChain)
{ {
if (!depth || !mipChain.GetImages()) if (!depth || !mipChain.GetImages())
return E_INVALIDARG; return E_INVALIDARG;
@ -2498,6 +2514,7 @@ static HRESULT _Generate3DMipsTriangleFilter( _In_ size_t depth, _In_ size_t lev
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -2508,7 +2525,12 @@ static HRESULT _Generate3DMipsTriangleFilter( _In_ size_t depth, _In_ size_t lev
// Generate mipmap chain // Generate mipmap chain
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, ScratchImage& mipChain, bool allow1D ) HRESULT DirectX::GenerateMipMaps(
const Image& baseImage,
DWORD filter,
size_t levels,
ScratchImage& mipChain,
bool allow1D)
{ {
if (!IsValid(baseImage.format)) if (!IsValid(baseImage.format))
return E_INVALIDARG; return E_INVALIDARG;
@ -2531,7 +2553,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK"); static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK");
if ( _UseWICFiltering( baseImage.format, filter ) ) if (UseWICFiltering(baseImage.format, filter))
{ {
//--- Use WIC filtering to generate mipmaps ----------------------------------- //--- Use WIC filtering to generate mipmaps -----------------------------------
switch (filter & TEX_FILTER_MASK) switch (filter & TEX_FILTER_MASK)
@ -2554,7 +2576,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
return _GenerateMipMapsUsingWIC( baseImage, filter, levels, pfGUID, mipChain, 0 ); return GenerateMipMapsUsingWIC(baseImage, filter, levels, pfGUID, mipChain, 0);
} }
else else
{ {
@ -2576,7 +2598,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, 0 ); hr = GenerateMipMapsUsingWIC(*timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -2620,51 +2642,51 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
switch (filter_select) switch (filter_select)
{ {
case TEX_FILTER_BOX: case TEX_FILTER_BOX:
hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); hr = Setup2DMips(&baseImage, 1, mdata, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, 0 ); hr = Generate2DMipsBoxFilter(levels, filter, mipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_POINT: case TEX_FILTER_POINT:
hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); hr = Setup2DMips(&baseImage, 1, mdata, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate2DMipsPointFilter( levels, mipChain, 0 ); hr = Generate2DMipsPointFilter(levels, mipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_LINEAR: case TEX_FILTER_LINEAR:
hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); hr = Setup2DMips(&baseImage, 1, mdata, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, 0 ); hr = Generate2DMipsLinearFilter(levels, filter, mipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_CUBIC: case TEX_FILTER_CUBIC:
hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); hr = Setup2DMips(&baseImage, 1, mdata, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, 0 ); hr = Generate2DMipsCubicFilter(levels, filter, mipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_TRIANGLE: case TEX_FILTER_TRIANGLE:
hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); hr = Setup2DMips(&baseImage, 1, mdata, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate2DMipsTriangleFilter( levels, filter, mipChain, 0 ); hr = Generate2DMipsTriangleFilter(levels, filter, mipChain, 0);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
@ -2676,8 +2698,13 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::GenerateMipMaps(
DWORD filter, size_t levels, ScratchImage& mipChain ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DWORD filter,
size_t levels,
ScratchImage& mipChain)
{ {
if (!srcImages || !nimages || !IsValid(metadata.format)) if (!srcImages || !nimages || !IsValid(metadata.format))
return E_INVALIDARG; return E_INVALIDARG;
@ -2719,7 +2746,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK"); static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK");
if ( _UseWICFiltering( metadata.format, filter ) ) if (UseWICFiltering(metadata.format, filter))
{ {
//--- Use WIC filtering to generate mipmaps ----------------------------------- //--- Use WIC filtering to generate mipmaps -----------------------------------
switch (filter & TEX_FILTER_MASK) switch (filter & TEX_FILTER_MASK)
@ -2744,7 +2771,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _GenerateMipMapsUsingWIC( baseImages[item], filter, levels, pfGUID, mipChain, item ); hr = GenerateMipMapsUsingWIC(baseImages[item], filter, levels, pfGUID, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
{ {
mipChain.Release(); mipChain.Release();
@ -2778,7 +2805,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
if (!timg) if (!timg)
return E_POINTER; return E_POINTER;
hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, item ); hr = GenerateMipMapsUsingWIC(*timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, item);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -2808,65 +2835,65 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
switch (filter_select) switch (filter_select)
{ {
case TEX_FILTER_BOX: case TEX_FILTER_BOX:
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); hr = Setup2DMips(&baseImages[0], metadata.arraySize, mdata2, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, item ); hr = Generate2DMipsBoxFilter(levels, filter, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
} }
return hr; return hr;
case TEX_FILTER_POINT: case TEX_FILTER_POINT:
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); hr = Setup2DMips(&baseImages[0], metadata.arraySize, mdata2, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _Generate2DMipsPointFilter( levels, mipChain, item ); hr = Generate2DMipsPointFilter(levels, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
} }
return hr; return hr;
case TEX_FILTER_LINEAR: case TEX_FILTER_LINEAR:
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); hr = Setup2DMips(&baseImages[0], metadata.arraySize, mdata2, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, item ); hr = Generate2DMipsLinearFilter(levels, filter, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
} }
return hr; return hr;
case TEX_FILTER_CUBIC: case TEX_FILTER_CUBIC:
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); hr = Setup2DMips(&baseImages[0], metadata.arraySize, mdata2, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, item ); hr = Generate2DMipsCubicFilter(levels, filter, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
} }
return hr; return hr;
case TEX_FILTER_TRIANGLE: case TEX_FILTER_TRIANGLE:
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); hr = Setup2DMips(&baseImages[0], metadata.arraySize, mdata2, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
for (size_t item = 0; item < metadata.arraySize; ++item) for (size_t item = 0; item < metadata.arraySize; ++item)
{ {
hr = _Generate2DMipsTriangleFilter( levels, filter, mipChain, item ); hr = Generate2DMipsTriangleFilter(levels, filter, mipChain, item);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
} }
@ -2883,7 +2910,12 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
// Generate mipmap chain for volume texture // Generate mipmap chain for volume texture
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter, size_t levels, ScratchImage& mipChain ) HRESULT DirectX::GenerateMipMaps3D(
const Image* baseImages,
size_t depth,
DWORD filter,
size_t levels,
ScratchImage& mipChain)
{ {
if (!baseImages || !depth) if (!baseImages || !depth)
return E_INVALIDARG; return E_INVALIDARG;
@ -2930,51 +2962,51 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter,
switch (filter_select) switch (filter_select)
{ {
case TEX_FILTER_BOX: case TEX_FILTER_BOX:
hr = _Setup3DMips( baseImages, depth, levels, mipChain ); hr = Setup3DMips(baseImages, depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsBoxFilter( depth, levels, filter, mipChain ); hr = Generate3DMipsBoxFilter(depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_POINT: case TEX_FILTER_POINT:
hr = _Setup3DMips( baseImages, depth, levels, mipChain ); hr = Setup3DMips(baseImages, depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsPointFilter( depth, levels, mipChain ); hr = Generate3DMipsPointFilter(depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_LINEAR: case TEX_FILTER_LINEAR:
hr = _Setup3DMips( baseImages, depth, levels, mipChain ); hr = Setup3DMips(baseImages, depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsLinearFilter( depth, levels, filter, mipChain ); hr = Generate3DMipsLinearFilter(depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_CUBIC: case TEX_FILTER_CUBIC:
hr = _Setup3DMips( baseImages, depth, levels, mipChain ); hr = Setup3DMips(baseImages, depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsCubicFilter( depth, levels, filter, mipChain ); hr = Generate3DMipsCubicFilter(depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_TRIANGLE: case TEX_FILTER_TRIANGLE:
hr = _Setup3DMips( baseImages, depth, levels, mipChain ); hr = Setup3DMips(baseImages, depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsTriangleFilter( depth, levels, filter, mipChain ); hr = Generate3DMipsTriangleFilter(depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
@ -2985,8 +3017,13 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter,
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::GenerateMipMaps3D(
DWORD filter, size_t levels, ScratchImage& mipChain ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DWORD filter,
size_t levels,
ScratchImage& mipChain)
{ {
if (!srcImages || !nimages || !IsValid(metadata.format)) if (!srcImages || !nimages || !IsValid(metadata.format))
return E_INVALIDARG; return E_INVALIDARG;
@ -3041,51 +3078,51 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta
switch (filter_select) switch (filter_select)
{ {
case TEX_FILTER_BOX: case TEX_FILTER_BOX:
hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); hr = Setup3DMips(&baseImages[0], metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsBoxFilter( metadata.depth, levels, filter, mipChain ); hr = Generate3DMipsBoxFilter(metadata.depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_POINT: case TEX_FILTER_POINT:
hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); hr = Setup3DMips(&baseImages[0], metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsPointFilter( metadata.depth, levels, mipChain ); hr = Generate3DMipsPointFilter(metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_LINEAR: case TEX_FILTER_LINEAR:
hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); hr = Setup3DMips(&baseImages[0], metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsLinearFilter( metadata.depth, levels, filter, mipChain ); hr = Generate3DMipsLinearFilter(metadata.depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_CUBIC: case TEX_FILTER_CUBIC:
hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); hr = Setup3DMips(&baseImages[0], metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsCubicFilter( metadata.depth, levels, filter, mipChain ); hr = Generate3DMipsCubicFilter(metadata.depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
case TEX_FILTER_TRIANGLE: case TEX_FILTER_TRIANGLE:
hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); hr = Setup3DMips(&baseImages[0], metadata.depth, levels, mipChain);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _Generate3DMipsTriangleFilter( metadata.depth, levels, filter, mipChain ); hr = Generate3DMipsTriangleFilter(metadata.depth, levels, filter, mipChain);
if (FAILED(hr)) if (FAILED(hr))
mipChain.Release(); mipChain.Release();
return hr; return hr;
@ -3094,5 +3131,3 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
} }
} }
}; // namespace

View File

@ -15,14 +15,19 @@
#include "directxtexp.h" #include "directxtexp.h"
namespace DirectX using namespace DirectX;
namespace
{ {
static const XMVECTORF32 g_Gamma22 = { 2.2f, 2.2f, 2.2f, 1.f }; const XMVECTORF32 g_Gamma22 = { 2.2f, 2.2f, 2.2f, 1.f };
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, HRESULT ComputeMSE_(
_Out_ float& mse, _Out_writes_opt_(4) float* mseV, const Image& image1,
_In_ DWORD flags ) const Image& image2,
float& mse,
_Out_writes_opt_(4) float* mseV,
DWORD flags)
{ {
if (!image1.pixels || !image2.pixels) if (!image1.pixels || !image2.pixels)
return E_POINTER; return E_POINTER;
@ -161,6 +166,7 @@ static HRESULT _ComputeMSE( _In_ const Image& image1, _In_ const Image& image2,
return S_OK; return S_OK;
} }
};
//===================================================================================== //=====================================================================================
@ -171,7 +177,13 @@ static HRESULT _ComputeMSE( _In_ const Image& image1, _In_ const Image& image2,
// Copies a rectangle from one image into another // Copies a rectangle from one image into another
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT CopyRectangle( const Image& srcImage, const Rect& srcRect, const Image& dstImage, DWORD filter, size_t xOffset, size_t yOffset ) HRESULT DirectX::CopyRectangle(
const Image& srcImage,
const Rect& srcRect,
const Image& dstImage,
DWORD filter,
size_t xOffset,
size_t yOffset)
{ {
if (!srcImage.pixels || !dstImage.pixels) if (!srcImage.pixels || !dstImage.pixels)
return E_POINTER; return E_POINTER;
@ -278,7 +290,12 @@ HRESULT CopyRectangle( const Image& srcImage, const Rect& srcRect, const Image&
// Computes the Mean-Squared-Error (MSE) between two images // Computes the Mean-Squared-Error (MSE) between two images
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float* mseV, DWORD flags ) HRESULT DirectX::ComputeMSE(
const Image& image1,
const Image& image2,
float& mse,
float* mseV,
DWORD flags)
{ {
if (!image1.pixels || !image2.pixels) if (!image1.pixels || !image2.pixels)
return E_POINTER; return E_POINTER;
@ -310,7 +327,7 @@ HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float*
if (!img1 || !img2) if (!img1 || !img2)
return E_POINTER; return E_POINTER;
return _ComputeMSE( *img1, *img2, mse, mseV, flags ); return ComputeMSE_(*img1, *img2, mse, mseV, flags);
} }
else else
{ {
@ -324,7 +341,7 @@ HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float*
if (!img) if (!img)
return E_POINTER; return E_POINTER;
return _ComputeMSE( *img, image2, mse, mseV, flags ); return ComputeMSE_(*img, image2, mse, mseV, flags);
} }
} }
else else
@ -341,14 +358,12 @@ HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float*
if (!img) if (!img)
return E_POINTER; return E_POINTER;
return _ComputeMSE( image1, *img, mse, mseV, flags ); return ComputeMSE_(image1, *img, mse, mseV, flags);
} }
else else
{ {
// Case 4: neither image is compressed // Case 4: neither image is compressed
return _ComputeMSE( image1, image2, mse, mseV, flags ); return ComputeMSE_(image1, image2, mse, mseV, flags);
} }
} }
} }
}; // namespace

View File

@ -15,11 +15,13 @@
#include "directxtexp.h" #include "directxtexp.h"
namespace DirectX using namespace DirectX;
namespace
{ {
#pragma prefast(suppress : 25000, "FXMVECTOR is 16 bytes") #pragma prefast(suppress : 25000, "FXMVECTOR is 16 bytes")
static inline float _EvaluateColor( _In_ FXMVECTOR val, _In_ DWORD flags ) inline float EvaluateColor(_In_ FXMVECTOR val, _In_ DWORD flags)
{ {
XMFLOAT4A f; XMFLOAT4A f;
@ -48,32 +50,35 @@ static inline float _EvaluateColor( _In_ FXMVECTOR val, _In_ DWORD flags )
} }
} }
static void _EvaluateRow( _In_reads_(width) const XMVECTOR* pSource, _Out_writes_(width+2) float* pDest, void EvaluateRow(
_In_ size_t width, _In_ DWORD flags ) _In_reads_(width) const XMVECTOR* pSource,
_Out_writes_(width + 2) float* pDest,
size_t width,
DWORD flags)
{ {
assert(pSource && pDest); assert(pSource && pDest);
assert(width > 0); assert(width > 0);
for (size_t x = 0; x < width; ++x) for (size_t x = 0; x < width; ++x)
{ {
pDest[x+1] = _EvaluateColor( pSource[x], flags ); pDest[x + 1] = EvaluateColor(pSource[x], flags);
} }
if (flags & CNMAP_MIRROR_U) if (flags & CNMAP_MIRROR_U)
{ {
// Mirror in U // Mirror in U
pDest[0] = _EvaluateColor( pSource[0], flags ); pDest[0] = EvaluateColor(pSource[0], flags);
pDest[width+1] = _EvaluateColor( pSource[width-1], flags ); pDest[width + 1] = EvaluateColor(pSource[width - 1], flags);
} }
else else
{ {
// Wrap in U // Wrap in U
pDest[0] = _EvaluateColor( pSource[width-1], flags ); pDest[0] = EvaluateColor(pSource[width - 1], flags);
pDest[width+1] = _EvaluateColor( pSource[0], flags ); pDest[width + 1] = EvaluateColor(pSource[0], flags);
} }
} }
static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude, HRESULT ComputeNMap(_In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude,
_In_ DXGI_FORMAT format, _In_ const Image& normalMap) _In_ DXGI_FORMAT format, _In_ const Image& normalMap)
{ {
if (!srcImage.pixels || !normalMap.pixels) if (!srcImage.pixels || !normalMap.pixels)
@ -134,8 +139,8 @@ static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_
} }
// Evaluate the initial rows // Evaluate the initial rows
_EvaluateRow( row0, val0, width, flags ); EvaluateRow(row0, val0, width, flags);
_EvaluateRow( row1, val1, width, flags ); EvaluateRow(row1, val1, width, flags);
pSrc += rowPitch; pSrc += rowPitch;
@ -164,7 +169,7 @@ static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_
} }
// Evaluate row // Evaluate row
_EvaluateRow( row2, val2, width, flags ); EvaluateRow(row2, val2, width, flags);
// Generate target scanline // Generate target scanline
XMVECTOR *dptr = target; XMVECTOR *dptr = target;
@ -242,6 +247,7 @@ static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -252,8 +258,12 @@ static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_
// Generates a normal map from a height-map // Generates a normal map from a height-map
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude, HRESULT DirectX::ComputeNormalMap(
DXGI_FORMAT format, ScratchImage& normalMap ) const Image& srcImage,
DWORD flags,
float amplitude,
DXGI_FORMAT format,
ScratchImage& normalMap)
{ {
if (!srcImage.pixels || !IsValid(format)) if (!srcImage.pixels || !IsValid(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -293,7 +303,7 @@ HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude,
return E_POINTER; return E_POINTER;
} }
hr = _ComputeNMap( srcImage, flags, amplitude, format, *img ); hr = ComputeNMap(srcImage, flags, amplitude, format, *img);
if (FAILED(hr)) if (FAILED(hr))
{ {
normalMap.Release(); normalMap.Release();
@ -304,8 +314,14 @@ HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude,
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::ComputeNormalMap(
DWORD flags, float amplitude, DXGI_FORMAT format, ScratchImage& normalMaps ) const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DWORD flags,
float amplitude,
DXGI_FORMAT format,
ScratchImage& normalMaps)
{ {
if (!srcImages || !nimages || !IsValid(format)) if (!srcImages || !nimages || !IsValid(format))
return E_INVALIDARG; return E_INVALIDARG;
@ -369,7 +385,7 @@ HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetad
return E_FAIL; return E_FAIL;
} }
hr = _ComputeNMap( src, flags, amplitude, format, dest[ index ] ); hr = ComputeNMap(src, flags, amplitude, format, dest[index]);
if (FAILED(hr)) if (FAILED(hr))
{ {
normalMaps.Release(); normalMaps.Release();
@ -379,5 +395,3 @@ HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetad
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -175,40 +175,40 @@ namespace DirectX
void __cdecl _CopyScanline( _When_(pDestination == pSource, _Inout_updates_bytes_(outSize)) void __cdecl _CopyScanline( _When_(pDestination == pSource, _Inout_updates_bytes_(outSize))
_When_(pDestination != pSource, _Out_writes_bytes_(outSize)) _When_(pDestination != pSource, _Out_writes_bytes_(outSize))
LPVOID pDestination, _In_ size_t outSize, void* pDestination, _In_ size_t outSize,
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_reads_bytes_(inSize) const void* pSource, _In_ size_t inSize,
_In_ DXGI_FORMAT format, _In_ DWORD flags ); _In_ DXGI_FORMAT format, _In_ DWORD flags );
void __cdecl _SwizzleScanline( _When_(pDestination == pSource, _In_) void __cdecl _SwizzleScanline( _When_(pDestination == pSource, _In_)
_When_(pDestination != pSource, _Out_writes_bytes_(outSize)) _When_(pDestination != pSource, _Out_writes_bytes_(outSize))
LPVOID pDestination, _In_ size_t outSize, void* pDestination, _In_ size_t outSize,
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_reads_bytes_(inSize) const void* pSource, _In_ size_t inSize,
_In_ DXGI_FORMAT format, _In_ DWORD flags ); _In_ DXGI_FORMAT format, _In_ DWORD flags );
_Success_(return != false) _Success_(return != false)
bool __cdecl _ExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize, bool __cdecl _ExpandScanline( _Out_writes_bytes_(outSize) void* pDestination, _In_ size_t outSize,
_In_ DXGI_FORMAT outFormat, _In_ DXGI_FORMAT outFormat,
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_reads_bytes_(inSize) const void* pSource, _In_ size_t inSize,
_In_ DXGI_FORMAT inFormat, _In_ DWORD flags ); _In_ DXGI_FORMAT inFormat, _In_ DWORD flags );
_Success_(return != false) _Success_(return != false)
bool __cdecl _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count, bool __cdecl _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format ); _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DXGI_FORMAT format );
_Success_(return != false) _Success_(return != false)
bool __cdecl _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count, bool __cdecl _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags ); _In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags );
_Success_(return != false) _Success_(return != false)
bool __cdecl _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, bool __cdecl _StoreScanline( void* pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
_In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 ); _In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 );
_Success_(return != false) _Success_(return != false)
bool __cdecl _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, bool __cdecl _StoreScanlineLinear( void* pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags, _In_ float threshold = 0 ); _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags, _In_ float threshold = 0 );
_Success_(return != false) _Success_(return != false)
bool __cdecl _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, bool __cdecl _StoreScanlineDither( void* pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ float threshold, size_t y, size_t z, _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ float threshold, size_t y, size_t z,
_Inout_updates_all_opt_(count+2) XMVECTOR* pDiffusionErrors ); _Inout_updates_all_opt_(count+2) XMVECTOR* pDiffusionErrors );
@ -225,6 +225,6 @@ namespace DirectX
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// DDS helper functions // DDS helper functions
HRESULT __cdecl _EncodeDDSHeader( _In_ const TexMetadata& metadata, DWORD flags, HRESULT __cdecl _EncodeDDSHeader( _In_ const TexMetadata& metadata, DWORD flags,
_Out_writes_bytes_to_opt_(maxsize, required) LPVOID pDestination, _In_ size_t maxsize, _Out_ size_t& required ); _Out_writes_bytes_to_opt_(maxsize, required) void* pDestination, _In_ size_t maxsize, _Out_ size_t& required );
}; // namespace }; // namespace

View File

@ -15,10 +15,12 @@
#include "directxtexp.h" #include "directxtexp.h"
namespace DirectX using namespace DirectX;
namespace
{ {
static HRESULT _PremultiplyAlpha( _In_ const Image& srcImage, _In_ const Image& destImage ) HRESULT PremultiplyAlpha_(const Image& srcImage, const Image& destImage)
{ {
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -56,7 +58,7 @@ static HRESULT _PremultiplyAlpha( _In_ const Image& srcImage, _In_ const Image&
return S_OK; return S_OK;
} }
static HRESULT _PremultiplyAlphaLinear( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage ) HRESULT PremultiplyAlphaLinear(const Image& srcImage, DWORD flags, const Image& destImage)
{ {
assert(srcImage.width == destImage.width); assert(srcImage.width == destImage.width);
assert(srcImage.height == destImage.height); assert(srcImage.height == destImage.height);
@ -98,6 +100,7 @@ static HRESULT _PremultiplyAlphaLinear( _In_ const Image& srcImage, _In_ DWORD f
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -108,7 +111,10 @@ static HRESULT _PremultiplyAlphaLinear( _In_ const Image& srcImage, _In_ DWORD f
// Converts to a premultiplied alpha version of the texture // Converts to a premultiplied alpha version of the texture
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& image ) HRESULT DirectX::PremultiplyAlpha(
const Image& srcImage,
DWORD flags,
ScratchImage& image)
{ {
if (!srcImage.pixels) if (!srcImage.pixels)
return E_POINTER; return E_POINTER;
@ -134,7 +140,7 @@ HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& imag
return E_POINTER; return E_POINTER;
} }
hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( srcImage, *rimage ) : _PremultiplyAlphaLinear( srcImage, flags, *rimage ); hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(srcImage, *rimage) : PremultiplyAlphaLinear(srcImage, flags, *rimage);
if (FAILED(hr)) if (FAILED(hr))
{ {
image.Release(); image.Release();
@ -149,7 +155,12 @@ HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& imag
// Converts to a premultiplied alpha version of the texture (complex) // Converts to a premultiplied alpha version of the texture (complex)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD flags, ScratchImage& result ) HRESULT DirectX::PremultiplyAlpha(
const Image* srcImages,
size_t nimages,
const TexMetadata& metadata,
DWORD flags,
ScratchImage& result)
{ {
if (!srcImages || !nimages) if (!srcImages || !nimages)
return E_INVALIDARG; return E_INVALIDARG;
@ -210,7 +221,7 @@ HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetad
return E_FAIL; return E_FAIL;
} }
hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( src, dst ) : _PremultiplyAlphaLinear( src, flags, dst ); hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(src, dst) : PremultiplyAlphaLinear(src, flags, dst);
if (FAILED(hr)) if (FAILED(hr))
{ {
result.Release(); result.Release();
@ -220,5 +231,3 @@ HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetad
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -17,21 +17,23 @@
#include "filters.h" #include "filters.h"
using namespace DirectX;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
namespace DirectX namespace DirectX
{ {
//-------------------------------------------------------------------------------------
// WIC related helper functions
//-------------------------------------------------------------------------------------
extern HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original, extern HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, _In_ bool iswic2, _In_ IWICBitmap* original,
_In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img); _In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img);
}
namespace
{
//--- Do image resize using WIC --- //--- Do image resize using WIC ---
static HRESULT _PerformResizeUsingWIC( _In_ const Image& srcImage, _In_ DWORD filter, HRESULT PerformResizeUsingWIC(
_In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage ) const Image& srcImage,
DWORD filter,
const WICPixelFormatGUID& pfGUID,
const Image& destImage)
{ {
if (!srcImage.pixels || !destImage.pixels) if (!srcImage.pixels || !destImage.pixels)
return E_POINTER; return E_POINTER;
@ -124,7 +126,10 @@ static HRESULT _PerformResizeUsingWIC( _In_ const Image& srcImage, _In_ DWORD fi
//--- Do conversion, resize using WIC, conversion cycle --- //--- Do conversion, resize using WIC, conversion cycle ---
static HRESULT _PerformResizeViaF32( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT PerformResizeViaF32(
const Image& srcImage,
DWORD filter,
const Image& destImage)
{ {
if (!srcImage.pixels || !destImage.pixels) if (!srcImage.pixels || !destImage.pixels)
return E_POINTER; return E_POINTER;
@ -150,7 +155,7 @@ static HRESULT _PerformResizeViaF32( _In_ const Image& srcImage, _In_ DWORD filt
if (!tdest) if (!tdest)
return E_POINTER; return E_POINTER;
hr = _PerformResizeUsingWIC( *tsrc, filter, GUID_WICPixelFormat128bppRGBAFloat, *tdest ); hr = PerformResizeUsingWIC(*tsrc, filter, GUID_WICPixelFormat128bppRGBAFloat, *tdest);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -165,7 +170,7 @@ static HRESULT _PerformResizeViaF32( _In_ const Image& srcImage, _In_ DWORD filt
//--- determine when to use WIC vs. non-WIC paths --- //--- determine when to use WIC vs. non-WIC paths ---
static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter ) bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ DWORD filter)
{ {
if (filter & TEX_FILTER_FORCE_NON_WIC) if (filter & TEX_FILTER_FORCE_NON_WIC)
{ {
@ -240,7 +245,7 @@ static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
//--- Point Filter --- //--- Point Filter ---
static HRESULT _ResizePointFilter( _In_ const Image& srcImage, _In_ const Image& destImage ) HRESULT ResizePointFilter(const Image& srcImage, const Image& destImage)
{ {
assert(srcImage.pixels && destImage.pixels); assert(srcImage.pixels && destImage.pixels);
assert(srcImage.format == destImage.format); assert(srcImage.format == destImage.format);
@ -298,7 +303,7 @@ static HRESULT _ResizePointFilter( _In_ const Image& srcImage, _In_ const Image&
//--- Box Filter --- //--- Box Filter ---
static HRESULT _ResizeBoxFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT ResizeBoxFilter(const Image& srcImage, DWORD filter, const Image& destImage)
{ {
assert(srcImage.pixels && destImage.pixels); assert(srcImage.pixels && destImage.pixels);
assert(srcImage.format == destImage.format); assert(srcImage.format == destImage.format);
@ -360,7 +365,7 @@ static HRESULT _ResizeBoxFilter( _In_ const Image& srcImage, _In_ DWORD filter,
//--- Linear Filter --- //--- Linear Filter ---
static HRESULT _ResizeLinearFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT ResizeLinearFilter(const Image& srcImage, DWORD filter, const Image& destImage)
{ {
assert(srcImage.pixels && destImage.pixels); assert(srcImage.pixels && destImage.pixels);
assert(srcImage.format == destImage.format); assert(srcImage.format == destImage.format);
@ -446,7 +451,7 @@ static HRESULT _ResizeLinearFilter( _In_ const Image& srcImage, _In_ DWORD filte
//--- Cubic Filter --- //--- Cubic Filter ---
static HRESULT _ResizeCubicFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT ResizeCubicFilter(const Image& srcImage, DWORD filter, const Image& destImage)
{ {
assert(srcImage.pixels && destImage.pixels); assert(srcImage.pixels && destImage.pixels);
assert(srcImage.format == destImage.format); assert(srcImage.format == destImage.format);
@ -606,7 +611,7 @@ static HRESULT _ResizeCubicFilter( _In_ const Image& srcImage, _In_ DWORD filter
//--- Triangle Filter --- //--- Triangle Filter ---
static HRESULT _ResizeTriangleFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT ResizeTriangleFilter(const Image& srcImage, DWORD filter, const Image& destImage)
{ {
assert(srcImage.pixels && destImage.pixels); assert(srcImage.pixels && destImage.pixels);
assert(srcImage.format == destImage.format); assert(srcImage.format == destImage.format);
@ -782,7 +787,7 @@ static HRESULT _ResizeTriangleFilter( _In_ const Image& srcImage, _In_ DWORD fil
//--- Custom filter resize --- //--- Custom filter resize ---
static HRESULT _PerformResizeUsingCustomFilters( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) HRESULT PerformResizeUsingCustomFilters(const Image& srcImage, DWORD filter, const Image& destImage)
{ {
if (!srcImage.pixels || !destImage.pixels) if (!srcImage.pixels || !destImage.pixels)
return E_POINTER; return E_POINTER;
@ -800,24 +805,25 @@ static HRESULT _PerformResizeUsingCustomFilters( _In_ const Image& srcImage, _In
switch (filter_select) switch (filter_select)
{ {
case TEX_FILTER_POINT: case TEX_FILTER_POINT:
return _ResizePointFilter( srcImage, destImage ); return ResizePointFilter(srcImage, destImage);
case TEX_FILTER_BOX: case TEX_FILTER_BOX:
return _ResizeBoxFilter( srcImage, filter, destImage ); return ResizeBoxFilter(srcImage, filter, destImage);
case TEX_FILTER_LINEAR: case TEX_FILTER_LINEAR:
return _ResizeLinearFilter( srcImage, filter, destImage ); return ResizeLinearFilter(srcImage, filter, destImage);
case TEX_FILTER_CUBIC: case TEX_FILTER_CUBIC:
return _ResizeCubicFilter( srcImage, filter, destImage ); return ResizeCubicFilter(srcImage, filter, destImage);
case TEX_FILTER_TRIANGLE: case TEX_FILTER_TRIANGLE:
return _ResizeTriangleFilter( srcImage, filter, destImage ); return ResizeTriangleFilter(srcImage, filter, destImage);
default: default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
} }
} }
}
//===================================================================================== //=====================================================================================
@ -828,7 +834,12 @@ static HRESULT _PerformResizeUsingCustomFilters( _In_ const Image& srcImage, _In
// Resize image // Resize image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter, ScratchImage& image ) HRESULT DirectX::Resize(
const Image& srcImage,
size_t width,
size_t height,
DWORD filter,
ScratchImage& image)
{ {
if (width == 0 || height == 0) if (width == 0 || height == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -856,23 +867,23 @@ HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter
if (!rimage) if (!rimage)
return E_POINTER; return E_POINTER;
if ( _UseWICFiltering( srcImage.format, filter ) ) if (UseWICFiltering(srcImage.format, filter))
{ {
WICPixelFormatGUID pfGUID; WICPixelFormatGUID pfGUID;
if (_DXGIToWIC(srcImage.format, pfGUID, true)) if (_DXGIToWIC(srcImage.format, pfGUID, true))
{ {
// Case 1: Source format is supported by Windows Imaging Component // Case 1: Source format is supported by Windows Imaging Component
hr = _PerformResizeUsingWIC( srcImage, filter, pfGUID, *rimage ); hr = PerformResizeUsingWIC(srcImage, filter, pfGUID, *rimage);
} }
else else
{ {
// Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
hr = _PerformResizeViaF32( srcImage, filter, *rimage ); hr = PerformResizeViaF32(srcImage, filter, *rimage);
} }
} }
else else
{ {
hr = _PerformResizeUsingCustomFilters( srcImage, filter, *rimage ); hr = PerformResizeUsingCustomFilters(srcImage, filter, *rimage);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -889,8 +900,14 @@ HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter
// Resize image (complex) // Resize image (complex)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metadata, HRESULT DirectX::Resize(
size_t width, size_t height, DWORD filter, ScratchImage& result ) 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) if (!srcImages || !nimages || width == 0 || height == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -906,7 +923,7 @@ HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metad
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
bool usewic = _UseWICFiltering( metadata.format, filter ); bool usewic = UseWICFiltering(metadata.format, filter);
WICPixelFormatGUID pfGUID = { 0 }; WICPixelFormatGUID pfGUID = { 0 };
bool wicpf = (usewic) ? _DXGIToWIC(metadata.format, pfGUID, true) : false; bool wicpf = (usewic) ? _DXGIToWIC(metadata.format, pfGUID, true) : false;
@ -951,18 +968,18 @@ HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metad
if (wicpf) if (wicpf)
{ {
// Case 1: Source format is supported by Windows Imaging Component // Case 1: Source format is supported by Windows Imaging Component
hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg ); hr = PerformResizeUsingWIC(*srcimg, filter, pfGUID, *destimg);
} }
else else
{ {
// Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
hr = _PerformResizeViaF32( *srcimg, filter, *destimg ); hr = PerformResizeViaF32(*srcimg, filter, *destimg);
} }
} }
else else
{ {
// Case 3: not using WIC resizing // Case 3: not using WIC resizing
hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg ); hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -1010,18 +1027,18 @@ HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metad
if (wicpf) if (wicpf)
{ {
// Case 1: Source format is supported by Windows Imaging Component // Case 1: Source format is supported by Windows Imaging Component
hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg ); hr = PerformResizeUsingWIC(*srcimg, filter, pfGUID, *destimg);
} }
else else
{ {
// Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
hr = _PerformResizeViaF32( *srcimg, filter, *destimg ); hr = PerformResizeViaF32(*srcimg, filter, *destimg);
} }
} }
else else
{ {
// Case 3: not using WIC resizing // Case 3: not using WIC resizing
hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg ); hr = PerformResizeUsingCustomFilters(*srcimg, filter, *destimg);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -1039,5 +1056,3 @@ HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metad
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -23,6 +23,10 @@
// * Always writes uncompressed files (i.e. can read RLE compression, but does not write it) // * Always writes uncompressed files (i.e. can read RLE compression, but does not write it)
// //
using namespace DirectX;
namespace
{
enum TGAImageType enum TGAImageType
{ {
TGA_NO_IMAGE = 0, TGA_NO_IMAGE = 0,
@ -110,13 +114,15 @@ enum CONVERSION_FLAGS
CONV_FLAGS_888 = 0x20000, // 24bpp format CONV_FLAGS_888 = 0x20000, // 24bpp format
}; };
namespace DirectX
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes TGA header // Decodes TGA header
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecodeTGAHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _Out_ TexMetadata& metadata, size_t& offset, HRESULT DecodeTGAHeader(
_In_reads_bytes_(size) const void* pSource,
size_t size,
_Out_ TexMetadata& metadata,
size_t& offset,
_Inout_opt_ DWORD* convFlags) _Inout_opt_ DWORD* convFlags)
{ {
if (!pSource) if (!pSource)
@ -231,7 +237,7 @@ static HRESULT _DecodeTGAHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Set alpha for images with all 0 alpha channel // Set alpha for images with all 0 alpha channel
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _SetAlphaChannelToOpaque( _In_ const Image* image ) HRESULT SetAlphaChannelToOpaque(_In_ const Image* image)
{ {
assert(image); assert(image);
@ -252,7 +258,11 @@ static HRESULT _SetAlphaChannelToOpaque( _In_ const Image* image )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Uncompress pixel data from a TGA into the target image // Uncompress pixel data from a TGA into the target image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _UncompressPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _In_ const Image* image, _In_ DWORD convFlags ) HRESULT UncompressPixels(
_In_reads_bytes_(size) const void* pSource,
size_t size,
_In_ const Image* image,
_In_ DWORD convFlags)
{ {
assert(pSource && size > 0); assert(pSource && size > 0);
@ -417,7 +427,7 @@ static HRESULT _UncompressPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa) if (!nonzeroa)
{ {
HRESULT hr = _SetAlphaChannelToOpaque( image ); HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -553,7 +563,7 @@ static HRESULT _UncompressPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa) if (!nonzeroa)
{ {
HRESULT hr = _SetAlphaChannelToOpaque( image ); HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -572,7 +582,11 @@ static HRESULT _UncompressPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Copies pixel data from a TGA into the target image // Copies pixel data from a TGA into the target image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _In_ const Image* image, _In_ DWORD convFlags ) HRESULT CopyPixels(
_In_reads_bytes_(size) const void* pSource,
size_t size,
_In_ const Image* image,
_In_ DWORD convFlags)
{ {
assert(pSource && size > 0); assert(pSource && size > 0);
@ -657,7 +671,7 @@ static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size,
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa) if (!nonzeroa)
{ {
HRESULT hr = _SetAlphaChannelToOpaque( image ); HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -717,7 +731,7 @@ static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size,
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa) if (!nonzeroa)
{ {
HRESULT hr = _SetAlphaChannelToOpaque( image ); HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -736,7 +750,7 @@ static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes TGA file header // Encodes TGA file header
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _EncodeTGAHeader( _In_ const Image& image, _Out_ TGA_HEADER& header, _Inout_ DWORD& convFlags ) HRESULT EncodeTGAHeader(_In_ const Image& image, _Out_ TGA_HEADER& header, _Inout_ DWORD& convFlags)
{ {
memset(&header, 0, sizeof(TGA_HEADER)); memset(&header, 0, sizeof(TGA_HEADER));
@ -799,8 +813,11 @@ static HRESULT _EncodeTGAHeader( _In_ const Image& image, _Out_ TGA_HEADER& head
// Copies BGRX data to form BGR 24bpp data // Copies BGRX data to form BGR 24bpp data
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
#pragma warning(suppress: 6001 6101) // In the case where outSize is insufficient we do not write to pDestination #pragma warning(suppress: 6001 6101) // In the case where outSize is insufficient we do not write to pDestination
static void _Copy24bppScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize, void Copy24bppScanline(
_In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize ) _Out_writes_bytes_(outSize) void* pDestination,
_In_ size_t outSize,
_In_reads_bytes_(inSize) const void* pSource,
_In_ size_t inSize)
{ {
assert(pDestination && outSize > 0); assert(pDestination && outSize > 0);
assert(pSource && inSize > 0); assert(pSource && inSize > 0);
@ -827,6 +844,7 @@ static void _Copy24bppScanline( _Out_writes_bytes_(outSize) LPVOID pDestination,
} }
} }
} }
}
//===================================================================================== //=====================================================================================
@ -837,26 +855,29 @@ static void _Copy24bppScanline( _Out_writes_bytes_(outSize) LPVOID pDestination,
// Obtain metadata from TGA file in memory/on disk // Obtain metadata from TGA file in memory/on disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata& metadata ) HRESULT DirectX::GetMetadataFromTGAMemory(
const void* pSource,
size_t size,
TexMetadata& metadata )
{ {
if ( !pSource || size == 0 ) if ( !pSource || size == 0 )
return E_INVALIDARG; return E_INVALIDARG;
size_t offset; size_t offset;
return _DecodeTGAHeader( pSource, size, metadata, offset, 0 ); return DecodeTGAHeader( pSource, size, metadata, offset, 0 );
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromTGAFile( LPCWSTR szFile, TexMetadata& metadata ) HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TexMetadata& metadata)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
@ -864,30 +885,20 @@ HRESULT GetMetadataFromTGAFile( LPCWSTR szFile, TexMetadata& metadata )
} }
// Get the file size // Get the file size
LARGE_INTEGER fileSize = {0};
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
FILE_STANDARD_INFO fileInfo; FILE_STANDARD_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
fileSize = fileInfo.EndOfFile;
#else
if ( !GetFileSizeEx( hFile.get(), &fileSize ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
#endif
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file)
if ( fileSize.HighPart > 0 ) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
} }
// Need at least enough data to fill the standard header to be a valid TGA // Need at least enough data to fill the standard header to be a valid TGA
if ( fileSize.LowPart < ( sizeof(TGA_HEADER) ) ) if (fileInfo.EndOfFile.LowPart < (sizeof(TGA_HEADER)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -895,13 +906,13 @@ HRESULT GetMetadataFromTGAFile( LPCWSTR szFile, TexMetadata& metadata )
// Read the standard header (we don't need the file footer to parse the file) // Read the standard header (we don't need the file footer to parse the file)
uint8_t header[sizeof(TGA_HEADER)]; uint8_t header[sizeof(TGA_HEADER)];
DWORD bytesRead = 0; DWORD bytesRead = 0;
if ( !ReadFile( hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
size_t offset; size_t offset;
return _DecodeTGAHeader( header, bytesRead, metadata, offset, 0 ); return DecodeTGAHeader(header, bytesRead, metadata, offset, 0);
} }
@ -909,7 +920,11 @@ HRESULT GetMetadataFromTGAFile( LPCWSTR szFile, TexMetadata& metadata )
// Load a TGA file in memory // Load a TGA file in memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata* metadata, ScratchImage& image ) HRESULT DirectX::LoadFromTGAMemory(
const void* pSource,
size_t size,
TexMetadata* metadata,
ScratchImage& image)
{ {
if (!pSource || size == 0) if (!pSource || size == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -919,14 +934,14 @@ HRESULT LoadFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata* metadata,
size_t offset; size_t offset;
DWORD convFlags = 0; DWORD convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = _DecodeTGAHeader( pSource, size, mdata, offset, &convFlags ); HRESULT hr = DecodeTGAHeader(pSource, size, mdata, offset, &convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
if (offset > size) if (offset > size)
return E_FAIL; return E_FAIL;
auto pPixels = reinterpret_cast<LPCVOID>( reinterpret_cast<const uint8_t*>(pSource) + offset ); auto pPixels = reinterpret_cast<const void*>(reinterpret_cast<const uint8_t*>(pSource) + offset);
size_t remaining = size - offset; size_t remaining = size - offset;
if (remaining == 0) if (remaining == 0)
@ -938,11 +953,11 @@ HRESULT LoadFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata* metadata,
if (convFlags & CONV_FLAGS_RLE) if (convFlags & CONV_FLAGS_RLE)
{ {
hr = _UncompressPixels( pPixels, remaining, image.GetImage(0,0,0), convFlags ); hr = UncompressPixels(pPixels, remaining, image.GetImage(0, 0, 0), convFlags);
} }
else else
{ {
hr = _CopyPixels( pPixels, remaining, image.GetImage(0,0,0), convFlags ); hr = CopyPixels(pPixels, remaining, image.GetImage(0, 0, 0), convFlags);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -962,7 +977,10 @@ HRESULT LoadFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata* metadata,
// Load a TGA file from disk // Load a TGA file from disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& image ) HRESULT DirectX::LoadFromTGAFile(
const wchar_t* szFile,
TexMetadata* metadata,
ScratchImage& image)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -970,10 +988,10 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
image.Release(); image.Release();
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
@ -981,30 +999,20 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
} }
// Get the file size // Get the file size
LARGE_INTEGER fileSize = {0};
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
FILE_STANDARD_INFO fileInfo; FILE_STANDARD_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
fileSize = fileInfo.EndOfFile;
#else
if ( !GetFileSizeEx( hFile.get(), &fileSize ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
#endif
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file)
if ( fileSize.HighPart > 0 ) if (fileInfo.EndOfFile.HighPart > 0)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
} }
// Need at least enough data to fill the header to be a valid TGA // Need at least enough data to fill the header to be a valid TGA
if ( fileSize.LowPart < sizeof(TGA_HEADER) ) if (fileInfo.EndOfFile.LowPart < sizeof(TGA_HEADER))
{ {
return E_FAIL; return E_FAIL;
} }
@ -1012,7 +1020,7 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
// Read the header // Read the header
uint8_t header[sizeof(TGA_HEADER)]; uint8_t header[sizeof(TGA_HEADER)];
DWORD bytesRead = 0; DWORD bytesRead = 0;
if ( !ReadFile( hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1020,12 +1028,12 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
size_t offset; size_t offset;
DWORD convFlags = 0; DWORD convFlags = 0;
TexMetadata mdata; TexMetadata mdata;
HRESULT hr = _DecodeTGAHeader( header, bytesRead, mdata, offset, &convFlags ); HRESULT hr = DecodeTGAHeader(header, bytesRead, mdata, offset, &convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
// Read the pixels // Read the pixels
DWORD remaining = static_cast<DWORD>( fileSize.LowPart - offset ); DWORD remaining = static_cast<DWORD>(fileInfo.EndOfFile.LowPart - offset);
if (remaining == 0) if (remaining == 0)
return E_FAIL; return E_FAIL;
@ -1048,7 +1056,7 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
if (!(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY)) if (!(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY))
{ {
// This case we can read directly into the image buffer in place // This case we can read directly into the image buffer in place
if ( !ReadFile( hFile.get(), image.GetPixels(), static_cast<DWORD>( image.GetPixelsSize() ), &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1155,7 +1163,7 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa) if (!nonzeroa)
{ {
hr = _SetAlphaChannelToOpaque( img ); hr = SetAlphaChannelToOpaque(img);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -1172,7 +1180,7 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if ( !ReadFile( hFile.get(), temp.get(), remaining, &bytesRead, 0 ) ) if (!ReadFile(hFile.get(), temp.get(), remaining, &bytesRead, nullptr))
{ {
image.Release(); image.Release();
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
@ -1186,11 +1194,11 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
if (convFlags & CONV_FLAGS_RLE) if (convFlags & CONV_FLAGS_RLE)
{ {
hr = _UncompressPixels( temp.get(), remaining, image.GetImage(0,0,0), convFlags ); hr = UncompressPixels(temp.get(), remaining, image.GetImage(0, 0, 0), convFlags);
} }
else else
{ {
hr = _CopyPixels( temp.get(), remaining, image.GetImage(0,0,0), convFlags ); hr = CopyPixels(temp.get(), remaining, image.GetImage(0, 0, 0), convFlags);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -1211,14 +1219,14 @@ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& im
// Save a TGA file to memory // Save a TGA file to memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToTGAMemory( const Image& image, Blob& blob ) HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob)
{ {
if (!image.pixels) if (!image.pixels)
return E_POINTER; return E_POINTER;
TGA_HEADER tga_header; TGA_HEADER tga_header;
DWORD convFlags = 0; DWORD convFlags = 0;
HRESULT hr = _EncodeTGAHeader( image, tga_header, convFlags ); HRESULT hr = EncodeTGAHeader(image, tga_header, convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1254,7 +1262,7 @@ HRESULT SaveToTGAMemory( const Image& image, Blob& blob )
// Copy pixels // Copy pixels
if (convFlags & CONV_FLAGS_888) if (convFlags & CONV_FLAGS_888)
{ {
_Copy24bppScanline( dPtr, rowPitch, pPixels, image.rowPitch ); Copy24bppScanline(dPtr, rowPitch, pPixels, image.rowPitch);
} }
else if (convFlags & CONV_FLAGS_SWIZZLE) else if (convFlags & CONV_FLAGS_SWIZZLE)
{ {
@ -1277,7 +1285,7 @@ HRESULT SaveToTGAMemory( const Image& image, Blob& blob )
// Save a TGA file to disk // Save a TGA file to disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile ) HRESULT DirectX::SaveToTGAFile(const Image& image, const wchar_t* szFile)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -1287,15 +1295,15 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
TGA_HEADER tga_header; TGA_HEADER tga_header;
DWORD convFlags = 0; DWORD convFlags = 0;
HRESULT hr = _EncodeTGAHeader( image, tga_header, convFlags ); HRESULT hr = EncodeTGAHeader(image, tga_header, convFlags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
// Create file and write header // Create file and write header
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr)));
#endif #endif
if (!hFile) if (!hFile)
{ {
@ -1326,8 +1334,7 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
// Write blob // Write blob
const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize()); const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize());
DWORD bytesWritten; DWORD bytesWritten;
if ( !WriteFile( hFile.get(), blob.GetBufferPointer(), bytesToWrite, if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
&bytesWritten, 0 ) )
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1346,7 +1353,7 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
// Write header // Write header
DWORD bytesWritten; DWORD bytesWritten;
if ( !WriteFile( hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1362,7 +1369,7 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
// Copy pixels // Copy pixels
if (convFlags & CONV_FLAGS_888) if (convFlags & CONV_FLAGS_888)
{ {
_Copy24bppScanline( temp.get(), rowPitch, pPixels, image.rowPitch ); Copy24bppScanline(temp.get(), rowPitch, pPixels, image.rowPitch);
} }
else if (convFlags & CONV_FLAGS_SWIZZLE) else if (convFlags & CONV_FLAGS_SWIZZLE)
{ {
@ -1375,7 +1382,7 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
pPixels += image.rowPitch; pPixels += image.rowPitch;
if ( !WriteFile( hFile.get(), temp.get(), static_cast<DWORD>( rowPitch ), &bytesWritten, 0 ) ) if (!WriteFile(hFile.get(), temp.get(), static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -1387,5 +1394,3 @@ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile )
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -15,8 +15,6 @@
#include "directxtexp.h" #include "directxtexp.h"
using Microsoft::WRL::ComPtr;
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
static_assert(XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT == DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, "Xbox One XDK mismatch detected"); static_assert(XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT == DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, "Xbox One XDK mismatch detected");
static_assert(XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT == DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, "Xbox One XDK mismatch detected"); static_assert(XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT == DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, "Xbox One XDK mismatch detected");
@ -33,7 +31,11 @@ static_assert(WIN10_DXGI_FORMAT_V208 == DXGI_FORMAT_V208, "Windows SDK mismatch
static_assert(WIN10_DXGI_FORMAT_V408 == DXGI_FORMAT_V408, "Windows SDK mismatch detected"); static_assert(WIN10_DXGI_FORMAT_V408 == DXGI_FORMAT_V408, "Windows SDK mismatch detected");
#endif #endif
using namespace DirectX;
using Microsoft::WRL::ComPtr;
namespace
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// WIC Pixel Format Translation Data // WIC Pixel Format Translation Data
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -44,7 +46,7 @@ struct WICTranslate
bool srgb; bool srgb;
}; };
static const WICTranslate g_WICFormats[] = const WICTranslate g_WICFormats[] =
{ {
{ GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT, false }, { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT, false },
@ -71,19 +73,17 @@ static const WICTranslate g_WICFormats[] =
{ GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM, false }, { GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM, false },
}; };
static bool g_WIC2 = false; bool g_WIC2 = false;
static IWICImagingFactory* g_Factory = nullptr; IWICImagingFactory* g_Factory = nullptr;
}
namespace DirectX
{
//===================================================================================== //=====================================================================================
// WIC Utilities // WIC Utilities
//===================================================================================== //=====================================================================================
_Use_decl_annotations_ _Use_decl_annotations_
DXGI_FORMAT _WICToDXGI( const GUID& guid ) DXGI_FORMAT DirectX::_WICToDXGI(const GUID& guid)
{ {
for (size_t i = 0; i < _countof(g_WICFormats); ++i) for (size_t i = 0; i < _countof(g_WICFormats); ++i)
{ {
@ -103,7 +103,7 @@ DXGI_FORMAT _WICToDXGI( const GUID& guid )
} }
_Use_decl_annotations_ _Use_decl_annotations_
bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR ) bool DirectX::_DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR )
{ {
switch( format ) switch( format )
{ {
@ -163,7 +163,7 @@ bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR )
return false; return false;
} }
DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID ) DWORD DirectX::_CheckWICColorSpace(_In_ const GUID& sourceGUID, _In_ const GUID& targetGUID)
{ {
DWORD srgb = 0; DWORD srgb = 0;
@ -195,7 +195,7 @@ DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetG
// Public helper function to get common WIC codec GUIDs // Public helper function to get common WIC codec GUIDs
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
REFGUID GetWICCodec( WICCodecs codec ) REFGUID DirectX::GetWICCodec(WICCodecs codec)
{ {
switch (codec) switch (codec)
{ {
@ -229,7 +229,7 @@ REFGUID GetWICCodec( WICCodecs codec )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Singleton function for WIC factory // Singleton function for WIC factory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
IWICImagingFactory* GetWICFactory( bool& iswic2 ) IWICImagingFactory* DirectX::GetWICFactory(bool& iswic2)
{ {
if (g_Factory) if (g_Factory)
{ {
@ -240,7 +240,7 @@ IWICImagingFactory* GetWICFactory( bool& iswic2 )
static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT; static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;
InitOnceExecuteOnce(&s_initOnce, InitOnceExecuteOnce(&s_initOnce,
[](PINIT_ONCE, PVOID, PVOID *factory) -> BOOL [](PINIT_ONCE, PVOID, LPVOID *factory) -> BOOL
{ {
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance( HRESULT hr = CoCreateInstance(
@ -290,7 +290,7 @@ IWICImagingFactory* GetWICFactory( bool& iswic2 )
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Optional initializer for WIC factory // Optional initializer for WIC factory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
void SetWICFactory(_In_opt_ IWICImagingFactory* pWIC) void DirectX::SetWICFactory(_In_opt_ IWICImagingFactory* pWIC)
{ {
if (pWIC == g_Factory) if (pWIC == g_Factory)
return; return;
@ -323,7 +323,7 @@ void SetWICFactory(_In_opt_ IWICImagingFactory* pWIC)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsPacked(DXGI_FORMAT fmt) bool DirectX::IsPacked(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -342,7 +342,7 @@ bool IsPacked(DXGI_FORMAT fmt)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsVideo(DXGI_FORMAT fmt) bool DirectX::IsVideo(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -379,7 +379,7 @@ bool IsVideo(DXGI_FORMAT fmt)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsPlanar(DXGI_FORMAT fmt) bool DirectX::IsPlanar(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -403,13 +403,12 @@ bool IsPlanar(DXGI_FORMAT fmt)
default: default:
return false; return false;
} }
} }
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsDepthStencil(DXGI_FORMAT fmt) bool DirectX::IsDepthStencil(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -434,7 +433,7 @@ bool IsDepthStencil(DXGI_FORMAT fmt)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool IsTypeless(DXGI_FORMAT fmt, bool partialTypeless) bool DirectX::IsTypeless(DXGI_FORMAT fmt, bool partialTypeless)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -478,7 +477,7 @@ bool IsTypeless(DXGI_FORMAT fmt, bool partialTypeless)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
bool HasAlpha(DXGI_FORMAT fmt) bool DirectX::HasAlpha(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -541,7 +540,7 @@ bool HasAlpha(DXGI_FORMAT fmt)
// Returns bits-per-pixel for a given DXGI format, or 0 on failure // Returns bits-per-pixel for a given DXGI format, or 0 on failure
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
size_t BitsPerPixel( DXGI_FORMAT fmt ) size_t DirectX::BitsPerPixel(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -703,7 +702,7 @@ size_t BitsPerPixel( DXGI_FORMAT fmt )
// For mixed formats, it returns the largest color-depth in the format // For mixed formats, it returns the largest color-depth in the format
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
size_t BitsPerColor( DXGI_FORMAT fmt ) size_t DirectX::BitsPerColor(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -869,7 +868,7 @@ size_t BitsPerColor( DXGI_FORMAT fmt )
// based on DXGI format, width, and height // based on DXGI format, width, and height
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height, void DirectX::ComputePitch(DXGI_FORMAT fmt, size_t width, size_t height,
size_t& rowPitch, size_t& slicePitch, DWORD flags) size_t& rowPitch, size_t& slicePitch, DWORD flags)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
@ -1031,7 +1030,7 @@ void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
size_t ComputeScanlines(DXGI_FORMAT fmt, size_t height) size_t DirectX::ComputeScanlines(DXGI_FORMAT fmt, size_t height)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -1094,7 +1093,7 @@ size_t ComputeScanlines(DXGI_FORMAT fmt, size_t height)
// Converts to an SRGB equivalent type if available // Converts to an SRGB equivalent type if available
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt ) DXGI_FORMAT DirectX::MakeSRGB(DXGI_FORMAT fmt)
{ {
switch (fmt) switch (fmt)
{ {
@ -1129,7 +1128,7 @@ DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt )
// Converts to a format to an equivalent TYPELESS format if available // Converts to a format to an equivalent TYPELESS format if available
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt ) DXGI_FORMAT DirectX::MakeTypeless(DXGI_FORMAT fmt)
{ {
switch (static_cast<int>(fmt)) switch (static_cast<int>(fmt))
{ {
@ -1249,7 +1248,7 @@ DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt )
// Converts to a TYPELESS format to an equivalent UNORM format if available // Converts to a TYPELESS format to an equivalent UNORM format if available
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
DXGI_FORMAT MakeTypelessUNORM( DXGI_FORMAT fmt ) DXGI_FORMAT DirectX::MakeTypelessUNORM(DXGI_FORMAT fmt)
{ {
switch (fmt) switch (fmt)
{ {
@ -1308,7 +1307,7 @@ DXGI_FORMAT MakeTypelessUNORM( DXGI_FORMAT fmt )
// Converts to a TYPELESS format to an equivalent FLOAT format if available // Converts to a TYPELESS format to an equivalent FLOAT format if available
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
DXGI_FORMAT MakeTypelessFLOAT( DXGI_FORMAT fmt ) DXGI_FORMAT DirectX::MakeTypelessFLOAT(DXGI_FORMAT fmt)
{ {
switch (fmt) switch (fmt)
{ {
@ -1404,24 +1403,24 @@ Blob& Blob::operator= (Blob&& moveFrom)
{ {
Release(); Release();
_buffer = moveFrom._buffer; m_buffer = moveFrom.m_buffer;
_size = moveFrom._size; m_size = moveFrom.m_size;
moveFrom._buffer = nullptr; moveFrom.m_buffer = nullptr;
moveFrom._size = 0; moveFrom.m_size = 0;
} }
return *this; return *this;
} }
void Blob::Release() void Blob::Release()
{ {
if ( _buffer ) if (m_buffer)
{ {
_aligned_free( _buffer ); _aligned_free(m_buffer);
_buffer = nullptr; m_buffer = nullptr;
} }
_size = 0; m_size = 0;
} }
_Use_decl_annotations_ _Use_decl_annotations_
@ -1432,16 +1431,14 @@ HRESULT Blob::Initialize( size_t size )
Release(); Release();
_buffer = _aligned_malloc( size, 16 ); m_buffer = _aligned_malloc(size, 16);
if ( !_buffer ) if (!m_buffer)
{ {
Release(); Release();
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
_size = size; m_size = size;
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -15,8 +15,6 @@
#include "directxtexp.h" #include "directxtexp.h"
using Microsoft::WRL::ComPtr;
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// IStream support for WIC Memory routines // IStream support for WIC Memory routines
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -66,6 +64,11 @@ using Microsoft::WRL::ComPtr;
#endif #endif
using namespace DirectX;
using Microsoft::WRL::ComPtr;
namespace
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// WIC Pixel Format nearest conversion table // WIC Pixel Format nearest conversion table
@ -77,7 +80,7 @@ struct WICConvert
GUID target; GUID target;
}; };
static const WICConvert g_WICConvert[] = const WICConvert g_WICConvert[] =
{ {
// Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required // Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required
// Note target GUID in this conversion table must be one of those directly supported formats. // Note target GUID in this conversion table must be one of those directly supported formats.
@ -135,13 +138,13 @@ static const WICConvert g_WICConvert[] =
// We don't support n-channel formats // We don't support n-channel formats
}; };
namespace DirectX
{
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Returns the DXGI format and optionally the WIC pixel GUID to convert to // Returns the DXGI format and optionally the WIC pixel GUID to convert to
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat, _In_ DWORD flags, _In_ bool iswic2, DXGI_FORMAT DetermineFormat(
_In_ const WICPixelFormatGUID& pixelFormat,
DWORD flags,
bool iswic2,
_Out_opt_ WICPixelFormatGUID* pConvert) _Out_opt_ WICPixelFormatGUID* pConvert)
{ {
if (pConvert) if (pConvert)
@ -236,9 +239,13 @@ static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Determines metadata for image // Determines metadata for image
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecodeMetadata( _In_ DWORD flags, _In_ bool iswic2, HRESULT DecodeMetadata(
_In_ IWICBitmapDecoder *decoder, _In_ IWICBitmapFrameDecode *frame, DWORD flags,
_Out_ TexMetadata& metadata, _Out_opt_ WICPixelFormatGUID* pConvert, bool iswic2,
_In_ IWICBitmapDecoder *decoder,
_In_ IWICBitmapFrameDecode *frame,
_Out_ TexMetadata& metadata,
_Out_opt_ WICPixelFormatGUID* pConvert,
_In_opt_ std::function<void(IWICMetadataQueryReader*)> getMQR) _In_opt_ std::function<void(IWICMetadataQueryReader*)> getMQR)
{ {
if (!decoder || !frame) if (!decoder || !frame)
@ -274,7 +281,7 @@ static HRESULT _DecodeMetadata( _In_ DWORD flags, _In_ bool iswic2,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
metadata.format = _DetermineFormat( pixelFormat, flags, iswic2, pConvert ); metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert);
if (metadata.format == DXGI_FORMAT_UNKNOWN) if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
@ -353,8 +360,12 @@ static HRESULT _DecodeMetadata( _In_ DWORD flags, _In_ bool iswic2,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes a single frame // Decodes a single frame
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecodeSingleFrame( _In_ DWORD flags, _In_ const TexMetadata& metadata, _In_ const WICPixelFormatGUID& convertGUID, HRESULT DecodeSingleFrame(
_In_ IWICBitmapFrameDecode *frame, _Inout_ ScratchImage& image ) DWORD flags,
const TexMetadata& metadata,
const WICPixelFormatGUID& convertGUID,
_In_ IWICBitmapFrameDecode *frame,
_Inout_ ScratchImage& image)
{ {
if (!frame) if (!frame)
return E_POINTER; return E_POINTER;
@ -413,8 +424,11 @@ static HRESULT _DecodeSingleFrame( _In_ DWORD flags, _In_ const TexMetadata& met
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes an image array, resizing/format converting as needed // Decodes an image array, resizing/format converting as needed
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _DecodeMultiframe( _In_ DWORD flags, _In_ const TexMetadata& metadata, HRESULT DecodeMultiframe(
_In_ IWICBitmapDecoder *decoder, _Inout_ ScratchImage& image ) DWORD flags,
const TexMetadata& metadata,
_In_ IWICBitmapDecoder *decoder,
_Inout_ ScratchImage& image)
{ {
if (!decoder) if (!decoder)
return E_POINTER; return E_POINTER;
@ -542,7 +556,10 @@ static HRESULT _DecodeMultiframe( _In_ DWORD flags, _In_ const TexMetadata& meta
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes image metadata // Encodes image metadata
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _EncodeMetadata( _In_ IWICBitmapFrameEncode* frame, _In_ const GUID& containerFormat, _In_ DXGI_FORMAT format ) HRESULT EncodeMetadata(
_In_ IWICBitmapFrameEncode* frame,
const GUID& containerFormat,
DXGI_FORMAT format)
{ {
if (!frame) if (!frame)
return E_POINTER; return E_POINTER;
@ -628,8 +645,13 @@ static HRESULT _EncodeMetadata( _In_ IWICBitmapFrameEncode* frame, _In_ const GU
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes a single frame // Encodes a single frame
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID containerFormat, HRESULT EncodeImage(
_In_ IWICBitmapFrameEncode* frame, _In_opt_ IPropertyBag2* props, _In_opt_ const GUID* targetFormat ) const Image& image,
DWORD flags,
_In_ REFGUID containerFormat,
_In_ IWICBitmapFrameEncode* frame,
_In_opt_ IPropertyBag2* props,
_In_opt_ const GUID* targetFormat)
{ {
if (!frame) if (!frame)
return E_INVALIDARG; return E_INVALIDARG;
@ -667,7 +689,7 @@ static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REF
return E_FAIL; return E_FAIL;
} }
hr = _EncodeMetadata( frame, containerFormat, image.format ); hr = EncodeMetadata(frame, containerFormat, image.format);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -723,9 +745,13 @@ static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REF
return S_OK; return S_OK;
} }
static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags, HRESULT EncodeSingleFrame(
_In_ REFGUID containerFormat, _Inout_ IStream* stream, const Image& image,
_In_opt_ const GUID* targetFormat, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps ) DWORD flags,
_In_ REFGUID containerFormat,
_Inout_ IStream* stream,
_In_opt_ const GUID* targetFormat,
_In_opt_ std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!stream) if (!stream)
return E_INVALIDARG; return E_INVALIDARG;
@ -768,7 +794,7 @@ static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags,
setCustomProps(props.Get()); setCustomProps(props.Get());
} }
hr = _EncodeImage( image, flags, containerFormat, frame.Get(), props.Get(), targetFormat ); hr = EncodeImage(image, flags, containerFormat, frame.Get(), props.Get(), targetFormat);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -783,9 +809,14 @@ static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags,
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes an image array // Encodes an image array
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, HRESULT EncodeMultiframe(
_In_ REFGUID containerFormat, _Inout_ IStream* stream, _In_reads_(nimages) const Image* images,
_In_opt_ const GUID* targetFormat, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps ) size_t nimages,
DWORD flags,
_In_ REFGUID containerFormat,
_Inout_ IStream* stream,
_In_opt_ const GUID* targetFormat,
_In_opt_ std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!stream || nimages < 2) if (!stream || nimages < 2)
return E_INVALIDARG; return E_INVALIDARG;
@ -834,7 +865,7 @@ static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_
setCustomProps(props.Get()); setCustomProps(props.Get());
} }
hr = _EncodeImage( images[index], flags, containerFormat, frame.Get(), props.Get(), targetFormat ); hr = EncodeImage(images[index], flags, containerFormat, frame.Get(), props.Get(), targetFormat);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
@ -845,6 +876,7 @@ static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_
return S_OK; return S_OK;
} }
}
//===================================================================================== //=====================================================================================
@ -855,7 +887,12 @@ static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_
// Obtain metadata from WIC-supported file in memory // Obtain metadata from WIC-supported file in memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata& metadata, std::function<void(IWICMetadataQueryReader*)> getMQR ) HRESULT DirectX::GetMetadataFromWICMemory(
const void* pSource,
size_t size,
DWORD flags,
TexMetadata& metadata,
std::function<void(IWICMetadataQueryReader*)> getMQR)
{ {
if (!pSource || size == 0) if (!pSource || size == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -891,7 +928,7 @@ HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, Tex
return hr; return hr;
// Get metadata // Get metadata
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), metadata, nullptr, getMQR ); hr = DecodeMetadata(flags, iswic2, decoder.Get(), frame.Get(), metadata, nullptr, getMQR);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -903,7 +940,11 @@ HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, Tex
// Obtain metadata from WIC-supported file on disk // Obtain metadata from WIC-supported file on disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metadata, std::function<void(IWICMetadataQueryReader*)> getMQR ) HRESULT DirectX::GetMetadataFromWICFile(
const wchar_t* szFile,
DWORD flags,
TexMetadata& metadata,
std::function<void(IWICMetadataQueryReader*)> getMQR)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -925,7 +966,7 @@ HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
return hr; return hr;
// Get metadata // Get metadata
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), metadata, nullptr, getMQR ); hr = DecodeMetadata(flags, iswic2, decoder.Get(), frame.Get(), metadata, nullptr, getMQR);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -937,7 +978,13 @@ HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metada
// Load a WIC-supported file in memory // Load a WIC-supported file in memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata* metadata, ScratchImage& image, std::function<void(IWICMetadataQueryReader*)> getMQR ) HRESULT DirectX::LoadFromWICMemory(
const void* pSource,
size_t size,
DWORD flags,
TexMetadata* metadata,
ScratchImage& image,
std::function<void(IWICMetadataQueryReader*)> getMQR)
{ {
if (!pSource || size == 0) if (!pSource || size == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -976,17 +1023,17 @@ HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
// Get metadata // Get metadata
TexMetadata mdata; TexMetadata mdata;
WICPixelFormatGUID convertGUID = { 0 }; WICPixelFormatGUID convertGUID = { 0 };
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID, getMQR ); hr = DecodeMetadata(flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID, getMQR);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
if ((mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES)) if ((mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES))
{ {
hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image ); hr = DecodeMultiframe(flags, mdata, decoder.Get(), image);
} }
else else
{ {
hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image ); hr = DecodeSingleFrame(flags, mdata, convertGUID, frame.Get(), image);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -1006,7 +1053,12 @@ HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadat
// Load a WIC-supported file from disk // Load a WIC-supported file from disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, ScratchImage& image, std::function<void(IWICMetadataQueryReader*)> getMQR ) HRESULT DirectX::LoadFromWICFile(
const wchar_t* szFile,
DWORD flags,
TexMetadata* metadata,
ScratchImage& image,
std::function<void(IWICMetadataQueryReader*)> getMQR)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -1032,17 +1084,17 @@ HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
// Get metadata // Get metadata
TexMetadata mdata; TexMetadata mdata;
WICPixelFormatGUID convertGUID = { 0 }; WICPixelFormatGUID convertGUID = { 0 };
hr = _DecodeMetadata( flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID, getMQR ); hr = DecodeMetadata(flags, iswic2, decoder.Get(), frame.Get(), mdata, &convertGUID, getMQR);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
if ((mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES)) if ((mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES))
{ {
hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image ); hr = DecodeMultiframe(flags, mdata, decoder.Get(), image);
} }
else else
{ {
hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image ); hr = DecodeSingleFrame(flags, mdata, convertGUID, frame.Get(), image);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -1062,8 +1114,13 @@ HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, Scr
// Save a WIC-supported file to memory // Save a WIC-supported file to memory
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToWICMemory( const Image& image, DWORD flags, REFGUID containerFormat, Blob& blob, HRESULT DirectX::SaveToWICMemory(
const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps ) const Image& image,
DWORD flags,
REFGUID containerFormat,
Blob& blob,
const GUID* targetFormat,
std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!image.pixels) if (!image.pixels)
return E_POINTER; return E_POINTER;
@ -1075,7 +1132,7 @@ HRESULT SaveToWICMemory( const Image& image, DWORD flags, REFGUID containerForma
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeSingleFrame(image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1109,8 +1166,14 @@ HRESULT SaveToWICMemory( const Image& image, DWORD flags, REFGUID containerForma
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToWICMemory( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, Blob& blob, HRESULT DirectX::SaveToWICMemory(
const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps ) const Image* images,
size_t nimages,
DWORD flags,
REFGUID containerFormat,
Blob& blob,
const GUID* targetFormat,
std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!images || nimages == 0) if (!images || nimages == 0)
return E_INVALIDARG; return E_INVALIDARG;
@ -1123,9 +1186,9 @@ HRESULT SaveToWICMemory( const Image* images, size_t nimages, DWORD flags, REFGU
return hr; return hr;
if (nimages > 1) if (nimages > 1)
hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeMultiframe(images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
else else
hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeSingleFrame(images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1164,8 +1227,13 @@ HRESULT SaveToWICMemory( const Image* images, size_t nimages, DWORD flags, REFGU
// Save a WIC-supported file to disk // Save a WIC-supported file to disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat, LPCWSTR szFile, HRESULT DirectX::SaveToWICFile(
const GUID* targetFormat, std::function<void(IPropertyBag2*)> setCustomProps ) const Image& image,
DWORD flags,
REFGUID containerFormat,
const wchar_t* szFile,
const GUID* targetFormat,
std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!szFile) if (!szFile)
return E_INVALIDARG; return E_INVALIDARG;
@ -1187,7 +1255,7 @@ HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeSingleFrame(image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
if (FAILED(hr)) if (FAILED(hr))
{ {
stream.Reset(); stream.Reset();
@ -1199,7 +1267,13 @@ HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat,
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, LPCWSTR szFile, const GUID* targetFormat, HRESULT DirectX::SaveToWICFile(
const Image* images,
size_t nimages,
DWORD flags,
REFGUID containerFormat,
const wchar_t* szFile,
const GUID* targetFormat,
std::function<void(IPropertyBag2*)> setCustomProps) std::function<void(IPropertyBag2*)> setCustomProps)
{ {
if (!szFile || !images || nimages == 0) if (!szFile || !images || nimages == 0)
@ -1220,9 +1294,9 @@ HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID
return hr; return hr;
if (nimages > 1) if (nimages > 1)
hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeMultiframe(images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
else else
hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); hr = EncodeSingleFrame(images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -1233,5 +1307,3 @@ HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID
return S_OK; return S_OK;
} }
}; // namespace

View File

@ -417,6 +417,6 @@ namespace TriangleFilter
return S_OK; return S_OK;
} }
}; // namespace }; // namespace TriangleFilter
}; // namespace }; // namespace DirectX

View File

@ -229,7 +229,7 @@ namespace
class auto_delete_file_wic class auto_delete_file_wic
{ {
public: public:
auto_delete_file_wic(ComPtr<IWICStream>& hFile, LPCWSTR szFile) : m_handle(hFile), m_filename(szFile) {} auto_delete_file_wic(ComPtr<IWICStream>& hFile, const wchar_t* szFile) : m_handle(hFile), m_filename(szFile) {}
~auto_delete_file_wic() ~auto_delete_file_wic()
{ {
if (m_filename) if (m_filename)
@ -242,7 +242,7 @@ namespace
void clear() { m_filename = 0; } void clear() { m_filename = 0; }
private: private:
LPCWSTR m_filename; const wchar_t* m_filename;
ComPtr<IWICStream>& m_handle; ComPtr<IWICStream>& m_handle;
auto_delete_file_wic(const auto_delete_file_wic&) = delete; auto_delete_file_wic(const auto_delete_file_wic&) = delete;
@ -705,7 +705,7 @@ namespace
IWICImagingFactory* factory = nullptr; IWICImagingFactory* factory = nullptr;
InitOnceExecuteOnce(&s_initOnce, InitOnceExecuteOnce(&s_initOnce,
[](PINIT_ONCE, PVOID, PVOID *factory) -> BOOL [](PINIT_ONCE, PVOID, LPVOID *factory) -> BOOL
{ {
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance( HRESULT hr = CoCreateInstance(
@ -751,7 +751,7 @@ namespace
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_z_ LPCWSTR fileName ) _In_z_ const wchar_t* fileName )
{ {
if ( !fileName ) if ( !fileName )
return E_INVALIDARG; return E_INVALIDARG;
@ -764,9 +764,9 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
// Create file // Create file
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, 0 ) ) ); ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr ) ) );
#else #else
ScopedHandle hFile( safe_handle( CreateFileW( fileName, GENERIC_WRITE | DELETE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); ScopedHandle hFile( safe_handle( CreateFileW( fileName, GENERIC_WRITE | DELETE, 0, nullptr, CREATE_ALWAYS, 0, nullptr ) ) );
#endif #endif
if ( !hFile ) if ( !hFile )
return HRESULT_FROM_WIN32( GetLastError() ); return HRESULT_FROM_WIN32( GetLastError() );
@ -912,7 +912,7 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_ REFGUID guidContainerFormat, _In_ REFGUID guidContainerFormat,
_In_z_ LPCWSTR fileName, _In_z_ const wchar_t* fileName,
_In_opt_ const GUID* targetFormat, _In_opt_ const GUID* targetFormat,
_In_opt_ std::function<void(IPropertyBag2*)> setCustomProps ) _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps )
{ {

View File

@ -32,12 +32,12 @@ namespace DirectX
{ {
HRESULT SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_z_ LPCWSTR fileName ); _In_z_ const wchar_t* fileName );
HRESULT SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_ REFGUID guidContainerFormat, _In_ REFGUID guidContainerFormat,
_In_z_ LPCWSTR fileName, _In_z_ const wchar_t* fileName,
_In_opt_ const GUID* targetFormat = nullptr, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr ); _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
} }

View File

@ -839,11 +839,7 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
return hr; return hr;
// Create file // Create file
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr ) ) );
ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, 0 ) ) );
#else
ScopedHandle hFile( safe_handle( CreateFileW( fileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) );
#endif
if ( !hFile ) if ( !hFile )
return HRESULT_FROM_WIN32( GetLastError() ); return HRESULT_FROM_WIN32( GetLastError() );
@ -972,13 +968,13 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
// Write header & pixels // Write header & pixels
DWORD bytesWritten; DWORD bytesWritten;
if ( !WriteFile( hFile.get(), fileHeader, static_cast<DWORD>( headerSize ), &bytesWritten, 0 ) ) if ( !WriteFile( hFile.get(), fileHeader, static_cast<DWORD>( headerSize ), &bytesWritten, nullptr ) )
return HRESULT_FROM_WIN32( GetLastError() ); return HRESULT_FROM_WIN32( GetLastError() );
if ( bytesWritten != headerSize ) if ( bytesWritten != headerSize )
return E_FAIL; return E_FAIL;
if ( !WriteFile( hFile.get(), pixels.get(), static_cast<DWORD>( slicePitch ), &bytesWritten, 0 ) ) if ( !WriteFile( hFile.get(), pixels.get(), static_cast<DWORD>( slicePitch ), &bytesWritten, nullptr ) )
return HRESULT_FROM_WIN32( GetLastError() ); return HRESULT_FROM_WIN32( GetLastError() );
if ( bytesWritten != slicePitch ) if ( bytesWritten != slicePitch )

View File

@ -34,7 +34,8 @@
namespace DirectX namespace DirectX
{ {
// Standard version // Standard version
HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromMemory(
_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
@ -42,7 +43,8 @@ namespace DirectX
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
HRESULT CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromFile(
_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ ID3D11ShaderResourceView** textureView,
@ -50,7 +52,8 @@ namespace DirectX
); );
// Standard version with optional auto-gen mipmap support // Standard version with optional auto-gen mipmap support
HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromMemory(
_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
@ -59,7 +62,8 @@ namespace DirectX
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
HRESULT CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromFile(
_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
@ -68,11 +72,12 @@ namespace DirectX
); );
// Extended version // Extended version
HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromMemoryEx(
_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
@ -81,7 +86,8 @@ namespace DirectX
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
HRESULT CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromFileEx(
_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
@ -94,7 +100,8 @@ namespace DirectX
); );
// Extended version with optional auto-gen mipmap support // Extended version with optional auto-gen mipmap support
HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromMemoryEx(
_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
@ -108,7 +115,8 @@ namespace DirectX
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
HRESULT CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT CreateWICTextureFromFileEx(
_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,