DirectXTex updated to January 2023 (#47)

This commit is contained in:
Chuck Walbourn 2023-01-31 21:57:52 -08:00 коммит произвёл GitHub
Родитель 95f3f7fe34
Коммит 9aabad0707
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
39 изменённых файлов: 4932 добавлений и 4397 удалений

Просмотреть файл

@ -30,11 +30,21 @@ namespace DirectX
enum BC_FLAGS : uint32_t
{
BC_FLAGS_NONE = 0x0,
BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3
BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3
BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
BC_FLAGS_USE_3SUBSETS = 0x80000, // By default, BC7 skips mode 0 & 2; this flag adds those modes back
BC_FLAGS_FORCE_BC7_MODE6 = 0x100000, // BC7 should only use mode 6; skip other modes
BC_FLAGS_DITHER_RGB = 0x10000,
// Enables dithering for RGB colors for BC1-3
BC_FLAGS_DITHER_A = 0x20000,
// Enables dithering for Alpha channel for BC1-3
BC_FLAGS_UNIFORM = 0x40000,
// By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
BC_FLAGS_USE_3SUBSETS = 0x80000,
// By default, BC7 skips mode 0 & 2; this flag adds those modes back
BC_FLAGS_FORCE_BC7_MODE6 = 0x100000,
// BC7 should only use mode 6; skip other modes
};
//-------------------------------------------------------------------------------------
@ -50,7 +60,6 @@ public:
public:
HDRColorA() = default;
HDRColorA(float _r, float _g, float _b, float _a) noexcept : r(_r), g(_g), b(_b), a(_a) {}
HDRColorA(const HDRColorA& c) noexcept : r(c.r), g(c.g), b(c.b), a(c.a) {}
// binary operators
HDRColorA operator + (const HDRColorA& c) const noexcept

Просмотреть файл

@ -452,7 +452,6 @@ namespace
public:
INTColor() = default;
INTColor(int nr, int ng, int nb) noexcept : r(nr), g(ng), b(nb), pad(0) {}
INTColor(const INTColor& c) noexcept : r(c.r), g(c.g), b(c.b), pad(0) {}
INTColor& operator += (_In_ const INTColor& c) noexcept
{
@ -751,9 +750,12 @@ namespace
float RoughMSE(_Inout_ EncodeParams* pEP) const noexcept;
private:
static const ModeDescriptor ms_aDesc[][82];
static const ModeInfo ms_aInfo[];
static const int ms_aModeToInfo[];
static constexpr uint8_t c_NumModes = 14;
static constexpr uint8_t c_NumModeInfo = 32;
static const ModeDescriptor ms_aDesc[c_NumModes][82];
static const ModeInfo ms_aInfo[c_NumModes];
static const int ms_aModeToInfo[c_NumModeInfo];
};
// BC67 compression (16b bits per texel)
@ -856,12 +858,14 @@ namespace
static float RoughMSE(_Inout_ EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode) noexcept;
private:
static const ModeInfo ms_aInfo[];
static constexpr uint8_t c_NumModes = 8;
static const ModeInfo ms_aInfo[c_NumModes];
};
}
// BC6H Compression
const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[14][82] =
const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[D3DX_BC6H::c_NumModes][82] =
{
{ // Mode 1 (0x00) - 10 5 5 5
{ M, 0}, { M, 1}, {GY, 4}, {BY, 4}, {BZ, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4},
@ -1033,7 +1037,7 @@ const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[14][82] =
};
// Mode, Partitions, Transformed, IndexPrec, RGBAPrec
const D3DX_BC6H::ModeInfo D3DX_BC6H::ms_aInfo[] =
const D3DX_BC6H::ModeInfo D3DX_BC6H::ms_aInfo[D3DX_BC6H::c_NumModes] =
{
{0x00, 1, true, 3, { { LDRColorA(10,10,10,0), LDRColorA(5, 5, 5,0) }, { LDRColorA(5,5,5,0), LDRColorA(5,5,5,0) } } }, // Mode 1
{0x01, 1, true, 3, { { LDRColorA(7, 7, 7,0), LDRColorA(6, 6, 6,0) }, { LDRColorA(6,6,6,0), LDRColorA(6,6,6,0) } } }, // Mode 2
@ -1051,7 +1055,7 @@ const D3DX_BC6H::ModeInfo D3DX_BC6H::ms_aInfo[] =
{0x0f, 0, true, 4, { { LDRColorA(16,16,16,0), LDRColorA(4, 4, 4,0) }, { LDRColorA(0,0,0,0), LDRColorA(0,0,0,0) } } }, // Mode 14
};
const int D3DX_BC6H::ms_aModeToInfo[] =
const int D3DX_BC6H::ms_aModeToInfo[D3DX_BC6H::c_NumModeInfo] =
{
0, // Mode 1 - 0x00
1, // Mode 2 - 0x01
@ -1088,7 +1092,7 @@ const int D3DX_BC6H::ms_aModeToInfo[] =
};
// BC7 compression: uPartitions, uPartitionBits, uPBits, uRotationBits, uIndexModeBits, uIndexPrec, uIndexPrec2, RGBAPrec, RGBAPrecWithP
const D3DX_BC7::ModeInfo D3DX_BC7::ms_aInfo[] =
const D3DX_BC7::ModeInfo D3DX_BC7::ms_aInfo[D3DX_BC7::c_NumModes] =
{
{2, 4, 6, 0, 0, 3, 0, LDRColorA(4,4,4,0), LDRColorA(5,5,5,0)},
// Mode 0: Color only, 3 Subsets, RGBP 4441 (unique P-bit), 3-bit indecies, 16 partitions
@ -1655,17 +1659,14 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const noexcept
uMode = static_cast<uint8_t>((unsigned(GetBits(uStartBit, 3)) << 2) | uMode);
}
assert(uMode < 32);
_Analysis_assume_(uMode < 32);
assert(uMode < c_NumModeInfo);
_Analysis_assume_(uMode < c_NumModeInfo);
if (ms_aModeToInfo[uMode] >= 0)
{
assert(static_cast<unsigned int>(ms_aModeToInfo[uMode]) < std::size(ms_aInfo));
_Analysis_assume_(ms_aModeToInfo[uMode] < std::size(ms_aInfo));
assert(static_cast<unsigned int>(ms_aModeToInfo[uMode]) < c_NumModes);
_Analysis_assume_(ms_aModeToInfo[uMode] < c_NumModes);
const ModeDescriptor* desc = ms_aDesc[ms_aModeToInfo[uMode]];
assert(static_cast<unsigned int>(ms_aModeToInfo[uMode]) < std::size(ms_aDesc));
_Analysis_assume_(ms_aModeToInfo[uMode] < std::size(ms_aDesc));
const ModeInfo& info = ms_aInfo[ms_aModeToInfo[uMode]];
INTEndPntPair aEndPts[BC6H_MAX_REGIONS] = {};
@ -1695,7 +1696,7 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const noexcept
case BZ: aEndPts[1].B.b |= 1 << uint32_t(desc[uCurBit].m_uBit); break;
default:
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC6H: Invalid header bits encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -1739,7 +1740,7 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const noexcept
const size_t uNumBits = IsFixUpOffset(info.uPartitions, uShape, i) ? info.uIndexPrec - 1u : info.uIndexPrec;
if (uStartBit + uNumBits > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC6H: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -1749,7 +1750,7 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const noexcept
if (uIndex >= ((info.uPartitions > 0) ? 8 : 16))
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC6H: Invalid index encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -1784,7 +1785,7 @@ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const noexcept
}
else
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
const char* warnstr = "BC6H: Invalid mode encountered during decoding\n";
switch (uMode)
{
@ -1811,7 +1812,7 @@ void D3DX_BC6H::Encode(bool bSigned, const HDRColorA* const pIn) noexcept
EncodeParams EP(pIn, bSigned);
for (EP.uMode = 0; EP.uMode < std::size(ms_aInfo) && EP.fBestErr > 0; ++EP.uMode)
for (EP.uMode = 0; EP.uMode < c_NumModes && EP.fBestErr > 0; ++EP.uMode)
{
const uint8_t uShapes = ms_aInfo[EP.uMode].uPartitions ? 32u : 1u;
// Number of rough cases to look at. reasonable values of this are 1, uShapes/4, and uShapes
@ -1936,6 +1937,9 @@ _Use_decl_annotations_
bool D3DX_BC6H::EndPointsFit(const EncodeParams* pEP, const INTEndPntPair aEndPts[]) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const bool bTransformed = ms_aInfo[pEP->uMode].bTransformed;
const bool bIsSigned = pEP->bSigned;
const LDRColorA& Prec0 = ms_aInfo[pEP->uMode].RGBAPrec[0][0];
@ -1978,6 +1982,9 @@ _Use_decl_annotations_
void D3DX_BC6H::GeneratePaletteQuantized(const EncodeParams* pEP, const INTEndPntPair& endPts, INTColor aPalette[]) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const size_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec;
const size_t uNumIndices = size_t(1) << uIndexPrec;
assert(uNumIndices > 0);
@ -2029,6 +2036,8 @@ _Use_decl_annotations_
float D3DX_BC6H::MapColorsQuantized(const EncodeParams* pEP, const INTColor aColors[], size_t np, const INTEndPntPair &endPts) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec;
auto const uNumIndices = static_cast<const uint8_t>(1u << uIndexPrec);
@ -2065,6 +2074,9 @@ float D3DX_BC6H::PerturbOne(const EncodeParams* pEP, const INTColor aColors[], s
const INTEndPntPair& oldEndPts, INTEndPntPair& newEndPts, float fOldErr, int do_b) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
uint8_t uPrec;
switch (ch)
{
@ -2178,6 +2190,9 @@ _Use_decl_annotations_
void D3DX_BC6H::OptimizeEndPoints(const EncodeParams* pEP, const float aOrgErr[], const INTEndPntPair aOrgEndPts[], INTEndPntPair aOptEndPts[]) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC6H_MAX_REGIONS);
_Analysis_assume_(uPartitions < BC6H_MAX_REGIONS);
@ -2205,6 +2220,9 @@ _Use_decl_annotations_
void D3DX_BC6H::SwapIndices(const EncodeParams* pEP, INTEndPntPair aEndPts[], size_t aIndices[]) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const size_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
const size_t uNumIndices = size_t(1) << ms_aInfo[pEP->uMode].uIndexPrec;
const size_t uHighIndexBit = uNumIndices >> 1;
@ -2234,6 +2252,9 @@ _Use_decl_annotations_
void D3DX_BC6H::AssignIndices(const EncodeParams* pEP, const INTEndPntPair aEndPts[], size_t aIndices[], float aTotErr[]) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
auto const uNumIndices = static_cast<const uint8_t>(1u << ms_aInfo[pEP->uMode].uIndexPrec);
@ -2276,6 +2297,9 @@ _Use_decl_annotations_
void D3DX_BC6H::QuantizeEndPts(const EncodeParams* pEP, INTEndPntPair* aQntEndPts) const noexcept
{
assert(pEP && aQntEndPts);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const INTEndPntPair* aUnqEndPts = pEP->aUnqEndPts[pEP->uShape];
const LDRColorA& Prec = ms_aInfo[pEP->uMode].RGBAPrec[0][0];
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
@ -2298,6 +2322,9 @@ _Use_decl_annotations_
void D3DX_BC6H::EmitBlock(const EncodeParams* pEP, const INTEndPntPair aEndPts[], const size_t aIndices[]) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uRealMode = ms_aInfo[pEP->uMode].uMode;
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec;
@ -2342,6 +2369,9 @@ _Use_decl_annotations_
void D3DX_BC6H::Refine(EncodeParams* pEP) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC6H_MAX_REGIONS);
_Analysis_assume_(uPartitions < BC6H_MAX_REGIONS);
@ -2394,6 +2424,9 @@ void D3DX_BC6H::GeneratePaletteUnquantized(const EncodeParams* pEP, size_t uRegi
assert(pEP);
assert(uRegion < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES);
_Analysis_assume_(uRegion < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const INTEndPntPair& endPts = pEP->aUnqEndPts[pEP->uShape][uRegion];
const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec;
auto const uNumIndices = static_cast<const uint8_t>(1u << uIndexPrec);
@ -2428,6 +2461,9 @@ _Use_decl_annotations_
float D3DX_BC6H::MapColors(const EncodeParams* pEP, size_t uRegion, size_t np, const size_t* auIndex) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec;
auto const uNumIndices = static_cast<const uint8_t>(1u << uIndexPrec);
INTColor aPalette[BC6H_MAX_INDICES];
@ -2455,6 +2491,8 @@ float D3DX_BC6H::RoughMSE(EncodeParams* pEP) const noexcept
assert(pEP);
assert(pEP->uShape < BC6H_MAX_SHAPES);
_Analysis_assume_(pEP->uShape < BC6H_MAX_SHAPES);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
INTEndPntPair* aEndPts = pEP->aUnqEndPts[pEP->uShape];
@ -2558,7 +2596,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
{
if (uStartBit + RGBAPrec.r > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2573,7 +2611,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
{
if (uStartBit + RGBAPrec.g > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2588,7 +2626,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
{
if (uStartBit + RGBAPrec.b > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2603,7 +2641,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
{
if (uStartBit + RGBAPrec.a > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2620,7 +2658,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
{
if (uStartBit > 127)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2658,7 +2696,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
const size_t uNumBits = IsFixUpOffset(ms_aInfo[uMode].uPartitions, uShape, i) ? uIndexPrec - 1u : uIndexPrec;
if (uStartBit + uNumBits > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2675,7 +2713,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
const size_t uNumBits = i ? uIndexPrec2 : uIndexPrec2 - 1u;
if (uStartBit + uNumBits > 128)
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Invalid block encountered during decoding\n");
#endif
FillWithErrorColors(pOut);
@ -2717,7 +2755,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const noexcept
}
else
{
#ifdef _DEBUG
#if defined(_WIN32) && defined(_DEBUG)
OutputDebugStringA("BC7: Reserved mode 8 encountered during decoding\n");
#endif
// Per the BC7 format spec, we must return transparent black
@ -2838,6 +2876,9 @@ _Use_decl_annotations_
void D3DX_BC7::GeneratePaletteQuantized(const EncodeParams* pEP, size_t uIndexMode, const LDREndPntPair& endPts, LDRColorA aPalette[]) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const size_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec;
const size_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2;
const size_t uNumIndices = size_t(1) << uIndexPrec;
@ -2868,6 +2909,9 @@ float D3DX_BC7::PerturbOne(const EncodeParams* pEP, const LDRColorA aColors[], s
const LDREndPntPair &oldEndPts, LDREndPntPair &newEndPts, float fOldErr, uint8_t do_b) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const int prec = ms_aInfo[pEP->uMode].RGBAPrecWithP[ch];
LDREndPntPair tmp_endPts = newEndPts = oldEndPts;
float fMinErr = fOldErr;
@ -2910,6 +2954,9 @@ void D3DX_BC7::Exhaustive(const EncodeParams* pEP, const LDRColorA aColors[], si
float& fOrgErr, LDREndPntPair& optEndPt) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPrec = ms_aInfo[pEP->uMode].RGBAPrecWithP[ch];
LDREndPntPair tmpEndPt;
if (fOrgErr == 0)
@ -2981,6 +3028,8 @@ void D3DX_BC7::OptimizeOne(const EncodeParams* pEP, const LDRColorA aColors[], s
float fOrgErr, const LDREndPntPair& org, LDREndPntPair& opt) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
float fOptErr = fOrgErr;
opt = org;
@ -3047,6 +3096,9 @@ void D3DX_BC7::OptimizeEndPoints(const EncodeParams* pEP, size_t uShape, size_t
const LDREndPntPair aOrgEndPts[], LDREndPntPair aOptEndPts[]) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC7_MAX_REGIONS && uShape < BC7_MAX_SHAPES);
_Analysis_assume_(uPartitions < BC7_MAX_REGIONS && uShape < BC7_MAX_SHAPES);
@ -3072,6 +3124,8 @@ void D3DX_BC7::AssignIndices(const EncodeParams* pEP, size_t uShape, size_t uInd
assert(pEP);
assert(uShape < BC7_MAX_SHAPES);
_Analysis_assume_(uShape < BC7_MAX_SHAPES);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC7_MAX_REGIONS);
@ -3149,6 +3203,9 @@ _Use_decl_annotations_
void D3DX_BC7::EmitBlock(const EncodeParams* pEP, size_t uShape, size_t uRotation, size_t uIndexMode, const LDREndPntPair aEndPts[], const size_t aIndex[], const size_t aIndex2[]) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC7_MAX_REGIONS);
_Analysis_assume_(uPartitions < BC7_MAX_REGIONS);
@ -3201,7 +3258,7 @@ void D3DX_BC7::EmitBlock(const EncodeParams* pEP, size_t uShape, size_t uRotatio
for (i = 0; i < uPBits; i++)
{
SetBits(uStartBit, 1, aPVote[i] > (aCount[i] >> 1) ? 1u : 0u);
SetBits(uStartBit, 1, (aPVote[i] >(aCount[i] >> 1)) ? 1u : 0u);
}
}
else
@ -3236,6 +3293,9 @@ _Use_decl_annotations_
void D3DX_BC7::FixEndpointPBits(const EncodeParams* pEP, const LDREndPntPair *pOrigEndpoints, LDREndPntPair *pFixedEndpoints) noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const size_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC7_MAX_REGIONS);
_Analysis_assume_(uPartitions < BC7_MAX_REGIONS);
@ -3323,6 +3383,8 @@ float D3DX_BC7::Refine(const EncodeParams* pEP, size_t uShape, size_t uRotation,
assert(pEP);
assert(uShape < BC7_MAX_SHAPES);
_Analysis_assume_(uShape < BC7_MAX_SHAPES);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const size_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;
assert(uPartitions < BC7_MAX_REGIONS);
@ -3379,6 +3441,9 @@ _Use_decl_annotations_
float D3DX_BC7::MapColors(const EncodeParams* pEP, const LDRColorA aColors[], size_t np, size_t uIndexMode, const LDREndPntPair& endPts, float fMinErr) const noexcept
{
assert(pEP);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
const uint8_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec;
const uint8_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2;
LDRColorA aPalette[BC7_MAX_INDICES];
@ -3404,6 +3469,9 @@ float D3DX_BC7::RoughMSE(EncodeParams* pEP, size_t uShape, size_t uIndexMode) no
assert(pEP);
assert(uShape < BC7_MAX_SHAPES);
_Analysis_assume_(uShape < BC7_MAX_SHAPES);
assert(pEP->uMode < c_NumModes);
_Analysis_assume_(pEP->uMode < c_NumModes);
LDREndPntPair* aEndPts = pEP->aEndPts[uShape];
const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions;

Просмотреть файл

@ -17,7 +17,7 @@
#include <utility>
#include <vector>
#if defined(WIN32) || defined(_WIN32)
#ifdef _WIN32
#if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__) && !defined(__XBOX_D3D12_X__)
#ifdef _GAMING_XBOX_SCARLETT
#include <d3d12_xs.h>
@ -36,8 +36,8 @@
#include <DirectXMath.h>
#ifdef WIN32
#ifdef NTDDI_WIN10_FE
#ifdef _WIN32
#if defined(NTDDI_WIN10_FE) || defined(__MINGW32__)
#include <ocidl.h>
#else
#include <OCIdl.h>
@ -47,7 +47,7 @@ struct IWICImagingFactory;
struct IWICMetadataQueryReader;
#endif
#define DIRECTX_TEX_VERSION 195
#define DIRECTX_TEX_VERSION 198
namespace DirectX
@ -63,6 +63,7 @@ namespace DirectX
bool __cdecl IsPalettized(_In_ DXGI_FORMAT fmt) noexcept;
bool __cdecl IsDepthStencil(_In_ DXGI_FORMAT fmt) noexcept;
bool __cdecl IsSRGB(_In_ DXGI_FORMAT fmt) noexcept;
bool __cdecl IsBGR(_In_ DXGI_FORMAT fmt) noexcept;
bool __cdecl IsTypeless(_In_ DXGI_FORMAT fmt, _In_ bool partialTypeless = true) noexcept;
bool __cdecl HasAlpha(_In_ DXGI_FORMAT fmt) noexcept;
@ -85,16 +86,35 @@ namespace DirectX
enum CP_FLAGS : unsigned long
{
CP_FLAGS_NONE = 0x0, // Normal operation
CP_FLAGS_LEGACY_DWORD = 0x1, // Assume pitch is DWORD aligned instead of BYTE aligned
CP_FLAGS_PARAGRAPH = 0x2, // Assume pitch is 16-byte aligned instead of BYTE aligned
CP_FLAGS_YMM = 0x4, // Assume pitch is 32-byte aligned instead of BYTE aligned
CP_FLAGS_ZMM = 0x8, // Assume pitch is 64-byte aligned instead of BYTE aligned
CP_FLAGS_PAGE4K = 0x200, // Assume pitch is 4096-byte aligned instead of BYTE aligned
CP_FLAGS_BAD_DXTN_TAILS = 0x1000, // BC formats with malformed mipchain blocks smaller than 4x4
CP_FLAGS_24BPP = 0x10000, // Override with a legacy 24 bits-per-pixel format size
CP_FLAGS_16BPP = 0x20000, // Override with a legacy 16 bits-per-pixel format size
CP_FLAGS_8BPP = 0x40000, // Override with a legacy 8 bits-per-pixel format size
CP_FLAGS_NONE = 0x0,
// Normal operation
CP_FLAGS_LEGACY_DWORD = 0x1,
// Assume pitch is DWORD aligned instead of BYTE aligned
CP_FLAGS_PARAGRAPH = 0x2,
// Assume pitch is 16-byte aligned instead of BYTE aligned
CP_FLAGS_YMM = 0x4,
// Assume pitch is 32-byte aligned instead of BYTE aligned
CP_FLAGS_ZMM = 0x8,
// Assume pitch is 64-byte aligned instead of BYTE aligned
CP_FLAGS_PAGE4K = 0x200,
// Assume pitch is 4096-byte aligned instead of BYTE aligned
CP_FLAGS_BAD_DXTN_TAILS = 0x1000,
// BC formats with malformed mipchain blocks smaller than 4x4
CP_FLAGS_24BPP = 0x10000,
// Override with a legacy 24 bits-per-pixel format size
CP_FLAGS_16BPP = 0x20000,
// Override with a legacy 16 bits-per-pixel format size
CP_FLAGS_8BPP = 0x40000,
// Override with a legacy 8 bits-per-pixel format size
};
HRESULT __cdecl ComputePitch(
@ -104,6 +124,7 @@ namespace DirectX
size_t __cdecl ComputeScanlines(_In_ DXGI_FORMAT fmt, _In_ size_t height) noexcept;
DXGI_FORMAT __cdecl MakeSRGB(_In_ DXGI_FORMAT fmt) noexcept;
DXGI_FORMAT __cdecl MakeLinear(_In_ DXGI_FORMAT fmt) noexcept;
DXGI_FORMAT __cdecl MakeTypeless(_In_ DXGI_FORMAT fmt) noexcept;
DXGI_FORMAT __cdecl MakeTypelessUNORM(_In_ DXGI_FORMAT fmt) noexcept;
DXGI_FORMAT __cdecl MakeTypelessFLOAT(_In_ DXGI_FORMAT fmt) noexcept;
@ -118,13 +139,13 @@ namespace DirectX
TEX_DIMENSION_TEXTURE3D = 4,
};
enum TEX_MISC_FLAG
enum TEX_MISC_FLAG : unsigned long
// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
{
TEX_MISC_TEXTURECUBE = 0x4L,
};
enum TEX_MISC_FLAG2
enum TEX_MISC_FLAG2 : unsigned long
{
TEX_MISC2_ALPHA_MODE_MASK = 0x7L,
};
@ -296,7 +317,7 @@ namespace DirectX
_In_ TGA_FLAGS flags,
_Out_ TexMetadata& metadata) noexcept;
#ifdef WIN32
#ifdef _WIN32
HRESULT __cdecl GetMetadataFromWICMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_In_ WIC_FLAGS flags,
@ -467,7 +488,7 @@ namespace DirectX
_In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
// WIC operations
#ifdef WIN32
#ifdef _WIN32
HRESULT __cdecl LoadFromWICMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_In_ WIC_FLAGS flags,
@ -523,7 +544,7 @@ namespace DirectX
TEX_FR_FLIP_VERTICAL = 0x10,
};
#ifdef WIN32
#ifdef _WIN32
HRESULT __cdecl FlipRotate(_In_ const Image& srcImage, _In_ TEX_FR_FLAGS flags, _Out_ ScratchImage& image) noexcept;
HRESULT __cdecl FlipRotate(
_In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
@ -809,7 +830,7 @@ namespace DirectX
//---------------------------------------------------------------------------------
// WIC utility code
#ifdef WIN32
#ifdef _WIN32
enum WICCodecs
{
WIC_CODEC_BMP = 1, // Windows Bitmap (.bmp)
@ -836,6 +857,15 @@ namespace DirectX
_Out_ size_t& required) noexcept;
//---------------------------------------------------------------------------------
// Direct3D interop
enum CREATETEX_FLAGS : uint32_t
{
CREATETEX_DEFAULT = 0,
CREATETEX_FORCE_SRGB = 0x1,
CREATETEX_IGNORE_SRGB = 0x2,
};
// Direct3D 11 functions
#if defined(__d3d11_h__) || defined(__d3d11_x_h__)
bool __cdecl IsSupportedTexture(_In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata) noexcept;
@ -850,18 +880,17 @@ namespace DirectX
HRESULT __cdecl CreateTextureEx(
_In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ CREATETEX_FLAGS flags,
_Outptr_ ID3D11Resource** ppResource) noexcept;
HRESULT __cdecl CreateShaderResourceViewEx(
_In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
_In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ CREATETEX_FLAGS flags,
_Outptr_ ID3D11ShaderResourceView** ppSRV) noexcept;
HRESULT __cdecl CaptureTexture(_In_ ID3D11Device* pDevice, _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Out_ ScratchImage& result) noexcept;
#endif
//---------------------------------------------------------------------------------
// Direct3D 12 functions
#if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)
bool __cdecl IsSupportedTexture(_In_ ID3D12Device* pDevice, _In_ const TexMetadata& metadata) noexcept;
@ -872,7 +901,7 @@ namespace DirectX
HRESULT __cdecl CreateTextureEx(
_In_ ID3D12Device* pDevice, _In_ const TexMetadata& metadata,
_In_ D3D12_RESOURCE_FLAGS resFlags, _In_ bool forceSRGB,
_In_ D3D12_RESOURCE_FLAGS resFlags, _In_ CREATETEX_FLAGS flags,
_Outptr_ ID3D12Resource** ppResource) noexcept;
HRESULT __cdecl PrepareUpload(

Просмотреть файл

@ -24,6 +24,7 @@ DEFINE_ENUM_FLAG_OPERATORS(TEX_PMALPHA_FLAGS);
DEFINE_ENUM_FLAG_OPERATORS(TEX_COMPRESS_FLAGS);
DEFINE_ENUM_FLAG_OPERATORS(CNMAP_FLAGS);
DEFINE_ENUM_FLAG_OPERATORS(CMSE_FLAGS);
DEFINE_ENUM_FLAG_OPERATORS(CREATETEX_FLAGS);
// WIC_FILTER modes match TEX_FILTER modes
constexpr WIC_FLAGS operator|(WIC_FLAGS a, TEX_FILTER_FLAGS b) { return static_cast<WIC_FLAGS>(static_cast<unsigned long>(a) | static_cast<unsigned long>(b & TEX_FILTER_MODE_MASK)); }
@ -116,6 +117,27 @@ inline bool __cdecl IsSRGB(DXGI_FORMAT fmt) noexcept
}
}
_Use_decl_annotations_
inline bool __cdecl IsBGR(DXGI_FORMAT fmt) noexcept
{
switch (fmt)
{
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8X8_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_B4G4R4A4_UNORM:
return true;
default:
return false;
}
}
//=====================================================================================
// Image I/O

Просмотреть файл

@ -69,7 +69,8 @@ namespace
{
Exponent--;
Mantissa <<= 1;
} while ((Mantissa & 0x80) == 0);
}
while ((Mantissa & 0x80) == 0);
Mantissa &= 0x7F;
}
@ -135,7 +136,8 @@ namespace
{
Exponent--;
Mantissa <<= 1;
} while ((Mantissa & 0x40) == 0);
}
while ((Mantissa & 0x40) == 0);
Mantissa &= 0x3F;
}
@ -2066,7 +2068,11 @@ bool DirectX::Internal::StoreScanline(
{
if (sPtr >= ePtr) break;
XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>(*sPtr++);
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
v = XMVectorMultiplyAdd(v, s_Scale, g_XMOneHalf);
#else
v = XMVectorMultiply(v, s_Scale);
#endif
XMStoreU565(dPtr++, v);
}
return true;
@ -2077,12 +2083,19 @@ bool DirectX::Internal::StoreScanline(
if (size >= sizeof(XMU555))
{
static const XMVECTORF32 s_Scale = { { { 31.f, 31.f, 31.f, 1.f } } };
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
static const XMVECTORF32 s_OneHalfXYZ = { { { 0.5f, 0.5f, 0.5f, 0.f } } };
#endif
XMU555 * __restrict dPtr = static_cast<XMU555*>(pDestination);
for (size_t icount = 0; icount < (size - sizeof(XMU555) + 1); icount += sizeof(XMU555))
{
if (sPtr >= ePtr) break;
XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>(*sPtr++);
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
v = XMVectorMultiplyAdd(v, s_Scale, s_OneHalfXYZ);
#else
v = XMVectorMultiply(v, s_Scale);
#endif
XMStoreU555(dPtr, v);
dPtr->w = (XMVectorGetW(v) > threshold) ? 1u : 0u;
++dPtr;
@ -2240,15 +2253,11 @@ bool DirectX::Internal::StoreScanline(
const int u0 = ((-38 * rgb1.x - 74 * rgb1.y + 112 * rgb1.z + 128) >> 8) + 128;
const int v0 = ((112 * rgb1.x - 94 * rgb1.y - 18 * rgb1.z + 128) >> 8) + 128;
XMUBYTEN4 rgb2;
XMUBYTEN4 rgb2 = {};
if (sPtr < ePtr)
{
XMStoreUByteN4(&rgb2, *sPtr++);
}
else
{
rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0;
}
const int y1 = ((66 * rgb2.x + 129 * rgb2.y + 25 * rgb2.z + 128) >> 8) + 16;
const int u1 = ((-38 * rgb2.x - 74 * rgb2.y + 112 * rgb2.z + 128) >> 8) + 128;
@ -2285,15 +2294,11 @@ bool DirectX::Internal::StoreScanline(
const int u0 = static_cast<int>((-9683 * r - 19017 * g + 28700 * b + 32768) >> 16) + 512;
const int v0 = static_cast<int>((28700 * r - 24033 * g - 4667 * b + 32768) >> 16) + 512;
XMUDECN4 rgb2;
XMUDECN4 rgb2 = {};
if (sPtr < ePtr)
{
XMStoreUDecN4(&rgb2, *sPtr++);
}
else
{
rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0;
}
r = rgb2.x;
g = rgb2.y;
@ -2333,15 +2338,11 @@ bool DirectX::Internal::StoreScanline(
const int u0 = static_cast<int>((-9674 * r - 18998 * g + 28672 * b + 32768) >> 16) + 32768;
const int v0 = static_cast<int>((28672 * r - 24010 * g - 4662 * b + 32768) >> 16) + 32768;
XMUSHORTN4 rgb2;
XMUSHORTN4 rgb2 = {};
if (sPtr < ePtr)
{
XMStoreUShortN4(&rgb2, *sPtr++);
}
else
{
rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0;
}
r = int64_t(rgb2.x);
g = int64_t(rgb2.y);
@ -2370,7 +2371,11 @@ bool DirectX::Internal::StoreScanline(
{
if (sPtr >= ePtr) break;
XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>(*sPtr++);
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
v = XMVectorMultiplyAdd(v, s_Scale, g_XMOneHalf);
#else
v = XMVectorMultiply(v, s_Scale);
#endif
XMStoreUNibble4(dPtr++, v);
}
return true;
@ -2446,8 +2451,11 @@ bool DirectX::Internal::StoreScanline(
for (size_t icount = 0; icount < (size - sizeof(uint8_t) + 1); icount += sizeof(uint8_t))
{
if (sPtr >= ePtr) break;
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
const XMVECTOR v = XMVectorMultiplyAdd(*sPtr++, s_Scale, g_XMOneHalf);
#else
const XMVECTOR v = XMVectorMultiply(*sPtr++, s_Scale);
#endif
XMUNIBBLE4 nibble;
XMStoreUNibble4(&nibble, v);
*dPtr = static_cast<uint8_t>(nibble.v);
@ -3670,7 +3678,7 @@ void DirectX::Internal::ConvertScanline(
// RGB format -> RG format
switch (static_cast<int>(flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE)))
{
case static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE):
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
@ -3682,7 +3690,7 @@ void DirectX::Internal::ConvertScanline(
}
break;
case static_cast<int>(TEX_FILTER_RGB_COPY_GREEN) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE):
case (static_cast<int>(TEX_FILTER_RGB_COPY_GREEN) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
@ -3694,7 +3702,7 @@ void DirectX::Internal::ConvertScanline(
}
break;
case static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_GREEN):
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_GREEN)):
default:
// Leave data unchanged and the store will handle this...
break;
@ -4392,7 +4400,7 @@ namespace
_Out_ WICPixelFormatGUID& pfGUID,
_Out_ WICPixelFormatGUID& targetGUID) noexcept
{
#ifndef WIN32
#ifndef _WIN32
UNREFERENCED_PARAMETER(filter);
UNREFERENCED_PARAMETER(sformat);
UNREFERENCED_PARAMETER(tformat);
@ -4555,7 +4563,7 @@ namespace
_In_ float threshold,
_In_ const Image& destImage)
{
#ifndef WIN32
#ifndef _WIN32
UNREFERENCED_PARAMETER(srcImage);
UNREFERENCED_PARAMETER(pfGUID);
UNREFERENCED_PARAMETER(targetGUID);
@ -4773,6 +4781,10 @@ namespace
}\
}
#ifdef __clang__
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#endif
HRESULT ConvertToSinglePlane_(_In_ const Image& srcImage, _In_ const Image& destImage) noexcept
{
assert(srcImage.width == destImage.width);
@ -4787,21 +4799,33 @@ namespace
{
case DXGI_FORMAT_NV12:
assert(destImage.format == DXGI_FORMAT_YUY2);
CONVERT_420_TO_422(uint8_t, XMUBYTEN4)
if ((srcImage.width % 2) != 0 || (srcImage.height % 2) != 0)
return E_INVALIDARG;
CONVERT_420_TO_422(uint8_t, XMUBYTEN4);
return S_OK;
case DXGI_FORMAT_P010:
assert(destImage.format == DXGI_FORMAT_Y210);
CONVERT_420_TO_422(uint16_t, XMUSHORTN4)
if ((srcImage.width % 2) != 0 || (srcImage.height % 2) != 0)
return E_INVALIDARG;
CONVERT_420_TO_422(uint16_t, XMUSHORTN4);
return S_OK;
case DXGI_FORMAT_P016:
assert(destImage.format == DXGI_FORMAT_Y216);
CONVERT_420_TO_422(uint16_t, XMUSHORTN4)
if ((srcImage.width % 2) != 0 || (srcImage.height % 2) != 0)
return E_INVALIDARG;
CONVERT_420_TO_422(uint16_t, XMUSHORTN4);
return S_OK;
case DXGI_FORMAT_NV11:
assert(destImage.format == DXGI_FORMAT_YUY2);
if ((srcImage.width % 4) != 0)
return E_INVALIDARG;
// Convert 4:1:1 to 4:2:2
{
const size_t rowPitch = srcImage.rowPitch;

Просмотреть файл

@ -171,11 +171,13 @@ namespace
return E_UNEXPECTED;
}
const size_t msize = (metadata.dimension == TEX_DIMENSION_TEXTURE2D)
? std::min<size_t>(img->rowPitch, mapped.RowPitch) : img->rowPitch;
auto sptr = static_cast<const uint8_t*>(mapped.pData);
uint8_t* dptr = img->pixels;
for (size_t h = 0; h < lines; ++h)
{
const size_t msize = std::min<size_t>(img->rowPitch, mapped.RowPitch);
memcpy(dptr, sptr, msize);
sptr += mapped.RowPitch;
dptr += img->rowPitch;
@ -217,6 +219,9 @@ bool DirectX::IsSupportedTexture(
if (!IsValid(fmt))
return false;
const size_t iWidth = metadata.width;
const size_t iHeight = metadata.height;
switch (fmt)
{
case DXGI_FORMAT_BC4_TYPELESS:
@ -239,6 +244,49 @@ bool DirectX::IsSupportedTexture(
return false;
break;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
case DXGI_FORMAT_420_OPAQUE:
if ((metadata.dimension != TEX_DIMENSION_TEXTURE2D)
|| (iWidth % 2) != 0 || (iHeight % 2) != 0)
{
return false;
}
break;
case DXGI_FORMAT_YUY2:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
case WIN10_DXGI_FORMAT_P208:
if ((iWidth % 2) != 0)
{
return false;
}
break;
case DXGI_FORMAT_NV11:
if ((iWidth % 4) != 0)
{
return false;
}
break;
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8:
// Legacy video stream formats are not supported by Direct3D.
return false;
case WIN10_DXGI_FORMAT_V208:
if ((metadata.dimension != TEX_DIMENSION_TEXTURE2D)
|| (iHeight % 2) != 0)
{
return false;
}
break;
default:
break;
}
@ -249,8 +297,6 @@ bool DirectX::IsSupportedTexture(
// Validate array size, dimension, and width/height
const size_t arraySize = metadata.arraySize;
const size_t iWidth = metadata.width;
const size_t iHeight = metadata.height;
const size_t iDepth = metadata.depth;
// Most cases are known apriori based on feature level, but we use this for robustness to handle the few optional cases
@ -409,7 +455,7 @@ HRESULT DirectX::CreateTexture(
{
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, CREATETEX_DEFAULT,
ppResource);
}
@ -423,7 +469,7 @@ HRESULT DirectX::CreateTextureEx(
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
CREATETEX_FLAGS flags,
ID3D11Resource** ppResource) noexcept
{
if (!pDevice || !srcImages || !nimages || !ppResource)
@ -541,7 +587,15 @@ HRESULT DirectX::CreateTextureEx(
// Create texture using static initialization data
HRESULT hr = E_UNEXPECTED;
const DXGI_FORMAT tformat = (forceSRGB) ? MakeSRGB(metadata.format) : metadata.format;
DXGI_FORMAT format = metadata.format;
if (flags & CREATETEX_FORCE_SRGB)
{
format = MakeSRGB(format);
}
else if (flags & CREATETEX_IGNORE_SRGB)
{
format = MakeLinear(format);
}
switch (metadata.dimension)
{
@ -551,7 +605,7 @@ HRESULT DirectX::CreateTextureEx(
desc.Width = static_cast<UINT>(metadata.width);
desc.MipLevels = static_cast<UINT>(metadata.mipLevels);
desc.ArraySize = static_cast<UINT>(metadata.arraySize);
desc.Format = tformat;
desc.Format = format;
desc.Usage = usage;
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = cpuAccessFlags;
@ -568,7 +622,7 @@ HRESULT DirectX::CreateTextureEx(
desc.Height = static_cast<UINT>(metadata.height);
desc.MipLevels = static_cast<UINT>(metadata.mipLevels);
desc.ArraySize = static_cast<UINT>(metadata.arraySize);
desc.Format = tformat;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = usage;
@ -590,7 +644,7 @@ HRESULT DirectX::CreateTextureEx(
desc.Height = static_cast<UINT>(metadata.height);
desc.Depth = static_cast<UINT>(metadata.depth);
desc.MipLevels = static_cast<UINT>(metadata.mipLevels);
desc.Format = tformat;
desc.Format = format;
desc.Usage = usage;
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = cpuAccessFlags;
@ -618,7 +672,7 @@ HRESULT DirectX::CreateShaderResourceView(
{
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, CREATETEX_DEFAULT,
ppSRV);
}
@ -632,7 +686,7 @@ HRESULT DirectX::CreateShaderResourceViewEx(
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
CREATETEX_FLAGS flags,
ID3D11ShaderResourceView** ppSRV) noexcept
{
if (!ppSRV)
@ -645,7 +699,7 @@ HRESULT DirectX::CreateShaderResourceViewEx(
ComPtr<ID3D11Resource> resource;
HRESULT hr = CreateTextureEx(pDevice, srcImages, nimages, metadata,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
usage, bindFlags, cpuAccessFlags, miscFlags, flags,
resource.GetAddressOf());
if (FAILED(hr))
return hr;
@ -653,10 +707,18 @@ HRESULT DirectX::CreateShaderResourceViewEx(
assert(resource);
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
if (forceSRGB)
if (flags & CREATETEX_FORCE_SRGB)
{
SRVDesc.Format = MakeSRGB(metadata.format);
}
else if (flags & CREATETEX_IGNORE_SRGB)
{
SRVDesc.Format = MakeLinear(metadata.format);
}
else
{
SRVDesc.Format = metadata.format;
}
switch (metadata.dimension)
{

Просмотреть файл

@ -1256,8 +1256,9 @@ namespace
}
size_t pixelSize, nimages;
if (!DetermineImageArray(metadata, cpFlags, nimages, pixelSize))
return HRESULT_E_ARITHMETIC_OVERFLOW;
HRESULT hr = DetermineImageArray(metadata, cpFlags, nimages, pixelSize);
if (FAILED(hr))
return hr;
if ((nimages == 0) || (nimages != image.GetImageCount()))
{
@ -1583,7 +1584,7 @@ HRESULT DirectX::GetMetadataFromDDSFile(
if (!szFile)
return E_INVALIDARG;
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -1637,7 +1638,7 @@ HRESULT DirectX::GetMetadataFromDDSFile(
// Read the header in (including extended header if present)
uint8_t header[MAX_HEADER_SIZE] = {};
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{
@ -1746,7 +1747,7 @@ HRESULT DirectX::LoadFromDDSFile(
image.Release();
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -1798,7 +1799,7 @@ HRESULT DirectX::LoadFromDDSFile(
// Read the header in (including extended header if present)
uint8_t header[MAX_HEADER_SIZE] = {};
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr))
{
@ -1824,7 +1825,7 @@ HRESULT DirectX::LoadFromDDSFile(
if (!(convFlags & CONV_FLAGS_DX10))
{
#ifdef WIN32
#ifdef _WIN32
// Must reset file position since we read more than the standard header above
const LARGE_INTEGER filePos = { { sizeof(uint32_t) + sizeof(DDS_HEADER), 0 } };
if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
@ -1849,7 +1850,7 @@ HRESULT DirectX::LoadFromDDSFile(
return E_OUTOFMEMORY;
}
#ifdef WIN32
#ifdef _WIN32
if (!ReadFile(hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -1885,7 +1886,7 @@ HRESULT DirectX::LoadFromDDSFile(
return E_OUTOFMEMORY;
}
#ifdef WIN32
#ifdef _WIN32
if (!ReadFile(hFile.get(), temp.get(), static_cast<DWORD>(remaining), &bytesRead, nullptr))
{
image.Release();
@ -1943,12 +1944,19 @@ HRESULT DirectX::LoadFromDDSFile(
return HRESULT_E_ARITHMETIC_OVERFLOW;
}
#ifdef WIN32
if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
#ifdef _WIN32
auto const pixelBytes = static_cast<DWORD>(image.GetPixelsSize());
if (!ReadFile(hFile.get(), image.GetPixels(), pixelBytes, &bytesRead, nullptr))
{
image.Release();
return HRESULT_FROM_WIN32(GetLastError());
}
if (bytesRead != pixelBytes)
{
image.Release();
return E_FAIL;
}
#else
inFile.read(reinterpret_cast<char*>(image.GetPixels()), image.GetPixelsSize());
if (!inFile)
@ -2223,7 +2231,7 @@ HRESULT DirectX::SaveToDDSFile(
return hr;
// Create file and write header
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile,
GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
@ -2285,7 +2293,7 @@ HRESULT DirectX::SaveToDDSFile(
if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX))
{
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2318,7 +2326,7 @@ HRESULT DirectX::SaveToDDSFile(
const size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j)
{
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2370,7 +2378,7 @@ HRESULT DirectX::SaveToDDSFile(
if ((images[index].slicePitch == ddsSlicePitch) && (ddsSlicePitch <= UINT32_MAX))
{
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), images[index].pixels, static_cast<DWORD>(ddsSlicePitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2403,7 +2411,7 @@ HRESULT DirectX::SaveToDDSFile(
const size_t lines = ComputeScanlines(metadata.format, images[index].height);
for (size_t j = 0; j < lines; ++j)
{
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), sPtr, static_cast<DWORD>(ddsRowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2433,7 +2441,7 @@ HRESULT DirectX::SaveToDDSFile(
return E_FAIL;
}
#ifdef WIN32
#ifdef _WIN32
delonfail.clear();
#endif

Просмотреть файл

@ -34,7 +34,7 @@
using namespace DirectX;
#ifndef WIN32
#ifndef _WIN32
#include <cstdarg>
#define strncpy_s strncpy
@ -77,7 +77,7 @@ namespace
return 0;
}
#ifndef WIN32
#ifndef _WIN32
template<size_t sizeOfBuffer>
inline int sprintf_s(char(&buffer)[sizeOfBuffer], const char* format, ...)
{
@ -598,7 +598,7 @@ HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& meta
if (!szFile)
return E_INVALIDARG;
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -652,7 +652,7 @@ HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& meta
// Read the first part of the file to find the header
uint8_t header[8192] = {};
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, std::min<DWORD>(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr))
{
@ -902,7 +902,7 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S
image.Release();
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -960,7 +960,7 @@ HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, S
return E_OUTOFMEMORY;
}
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), temp.get(), fileInfo.EndOfFile.LowPart, &bytesRead, nullptr))
{
@ -1125,7 +1125,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
}
// Create file and write header
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile,
GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
@ -1163,7 +1163,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
return hr;
// Write blob
#ifdef WIN32
#ifdef _WIN32
auto const bytesToWrite = static_cast<const DWORD>(blob.GetBufferSize());
DWORD bytesWritten;
if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
@ -1196,7 +1196,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
char header[256] = {};
sprintf_s(header, g_Header, image.height, image.width);
#ifdef WIN32
#ifdef _WIN32
auto const headerLen = static_cast<DWORD>(strlen(header));
DWORD bytesWritten;
@ -1221,7 +1221,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, fpp);
sPtr += image.rowPitch;
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -1258,7 +1258,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
if (encSize > UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), enc, static_cast<DWORD>(encSize), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -1274,7 +1274,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
}
else
{
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -1292,7 +1292,7 @@ HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile) noexce
#endif
}
#ifdef WIN32
#ifdef _WIN32
delonfail.clear();
#endif

Просмотреть файл

@ -14,7 +14,7 @@
using namespace DirectX;
using namespace DirectX::Internal;
#ifndef WIN32
#ifndef _WIN32
namespace
{
inline void * _aligned_malloc(size_t size, size_t alignment)
@ -31,7 +31,7 @@ namespace
// Determines number of image array entries and pixel size
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
bool DirectX::Internal::DetermineImageArray(
HRESULT DirectX::Internal::DetermineImageArray(
const TexMetadata& metadata,
CP_FLAGS cpFlags,
size_t& nImages,
@ -56,10 +56,11 @@ bool DirectX::Internal::DetermineImageArray(
for (size_t level = 0; level < metadata.mipLevels; ++level)
{
size_t rowPitch, slicePitch;
if (FAILED(ComputePitch(metadata.format, w, h, rowPitch, slicePitch, cpFlags)))
HRESULT hr = ComputePitch(metadata.format, w, h, rowPitch, slicePitch, cpFlags);
if (FAILED(hr))
{
nImages = pixelSize = 0;
return false;
return hr;
}
totalPixelSize += uint64_t(slicePitch);
@ -83,10 +84,11 @@ bool DirectX::Internal::DetermineImageArray(
for (size_t level = 0; level < metadata.mipLevels; ++level)
{
size_t rowPitch, slicePitch;
if (FAILED(ComputePitch(metadata.format, w, h, rowPitch, slicePitch, cpFlags)))
HRESULT hr = ComputePitch(metadata.format, w, h, rowPitch, slicePitch, cpFlags);
if (FAILED(hr))
{
nImages = pixelSize = 0;
return false;
return hr;
}
for (size_t slice = 0; slice < d; ++slice)
@ -109,7 +111,7 @@ bool DirectX::Internal::DetermineImageArray(
default:
nImages = pixelSize = 0;
return false;
return E_INVALIDARG;
}
#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
@ -117,7 +119,7 @@ bool DirectX::Internal::DetermineImageArray(
if (totalPixelSize > UINT32_MAX)
{
nImages = pixelSize = 0;
return false;
return HRESULT_E_ARITHMETIC_OVERFLOW;
}
#else
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
@ -126,7 +128,7 @@ bool DirectX::Internal::DetermineImageArray(
nImages = nimages;
pixelSize = static_cast<size_t>(totalPixelSize);
return true;
return S_OK;
}
@ -348,8 +350,9 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc
m_metadata.dimension = mdata.dimension;
size_t pixelSize, nimages;
if (!DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_E_ARITHMETIC_OVERFLOW;
HRESULT hr = DetermineImageArray(m_metadata, flags, nimages, pixelSize);
if (FAILED(hr))
return hr;
m_image = new (std::nothrow) Image[nimages];
if (!m_image)
@ -364,7 +367,9 @@ HRESULT ScratchImage::Initialize(const TexMetadata& mdata, CP_FLAGS flags) noexc
Release();
return E_OUTOFMEMORY;
}
memset(m_memory, 0, pixelSize);
m_size = pixelSize;
if (!SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))
{
Release();
@ -415,8 +420,9 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height,
m_metadata.dimension = TEX_DIMENSION_TEXTURE2D;
size_t pixelSize, nimages;
if (!DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_E_ARITHMETIC_OVERFLOW;
HRESULT hr = DetermineImageArray(m_metadata, flags, nimages, pixelSize);
if (FAILED(hr))
return hr;
m_image = new (std::nothrow) Image[nimages];
if (!m_image)
@ -431,7 +437,9 @@ HRESULT ScratchImage::Initialize2D(DXGI_FORMAT fmt, size_t width, size_t height,
Release();
return E_OUTOFMEMORY;
}
memset(m_memory, 0, pixelSize);
m_size = pixelSize;
if (!SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))
{
Release();
@ -466,8 +474,9 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height,
m_metadata.dimension = TEX_DIMENSION_TEXTURE3D;
size_t pixelSize, nimages;
if (!DetermineImageArray(m_metadata, flags, nimages, pixelSize))
return HRESULT_E_ARITHMETIC_OVERFLOW;
HRESULT hr = DetermineImageArray(m_metadata, flags, nimages, pixelSize);
if (FAILED(hr))
return hr;
m_image = new (std::nothrow) Image[nimages];
if (!m_image)
@ -484,6 +493,7 @@ HRESULT ScratchImage::Initialize3D(DXGI_FORMAT fmt, size_t width, size_t height,
Release();
return E_OUTOFMEMORY;
}
memset(m_memory, 0, pixelSize);
m_size = pixelSize;
if (!SetupImageArray(m_memory, pixelSize, m_metadata, flags, m_image, nimages))

Просмотреть файл

@ -65,7 +65,7 @@ namespace
return mipLevels;
}
#ifdef WIN32
#ifdef _WIN32
HRESULT EnsureWicBitmapPixelFormat(
_In_ IWICImagingFactory* pWIC,
_In_ IWICBitmap* src,
@ -264,13 +264,13 @@ namespace
XMVECTOR r1 = XMVectorSplatW(*pRow1);
XMVECTOR v1 = XMVectorSaturate(XMVectorMultiply(r0, scale));
XMVECTOR v2 = XMVectorSaturate(XMVectorMultiply(r1, scale));
const XMVECTOR v2 = XMVectorSaturate(XMVectorMultiply(r1, scale));
r0 = XMVectorSplatW(*(++pRow0));
r1 = XMVectorSplatW(*(++pRow1));
XMVECTOR v3 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(r0), scale));
XMVECTOR v4 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(r1), scale));
const XMVECTOR v4 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(r1), scale));
v1 = XMVectorMergeXY(v1, v2); // [v1.x v2.x --- ---]
v3 = XMVectorMergeXY(v3, v4); // [v3.x v4.x --- ---]
@ -399,7 +399,7 @@ bool DirectX::Internal::CalculateMipLevels3D(
return true;
}
#ifdef WIN32
#ifdef _WIN32
//--- Resizing color and alpha channels separately using WIC ---
_Use_decl_annotations_
HRESULT DirectX::Internal::ResizeSeparateColorAndAlpha(
@ -543,7 +543,7 @@ HRESULT DirectX::Internal::ResizeSeparateColorAndAlpha(
if (SUCCEEDED(hr))
{
WICInProcPointer colorWithAlphaData = nullptr;
BYTE* colorWithAlphaData = nullptr;
UINT colorWithAlphaSizeInBytes = 0;
UINT colorWithAlphaStride = 0;
@ -560,7 +560,7 @@ HRESULT DirectX::Internal::ResizeSeparateColorAndAlpha(
}
}
WICInProcPointer colorData = nullptr;
BYTE* colorData = nullptr;
UINT colorSizeInBytes = 0;
UINT colorStride = 0;
if (SUCCEEDED(hr))
@ -620,7 +620,7 @@ HRESULT DirectX::Internal::ResizeSeparateColorAndAlpha(
namespace
{
#ifdef WIN32
#ifdef _WIN32
//--- determine when to use WIC vs. non-WIC paths ---
bool UseWICFiltering(_In_ DXGI_FORMAT format, _In_ TEX_FILTER_FLAGS filter) noexcept
{
@ -686,6 +686,14 @@ namespace
case TEX_FILTER_TRIANGLE:
// WIC does not implement this filter
return false;
default:
if (BitsPerColor(format) > 8)
{
// Avoid the WIC bitmap scaler when doing filtering of XR/HDR formats
return false;
}
break;
}
return true;
@ -1190,6 +1198,10 @@ namespace
}
//--- 2D Cubic Filter ---
#ifdef __clang__
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#endif
HRESULT Generate2DMipsCubicFilter(size_t levels, TEX_FILTER_FLAGS filter, const ScratchImage& mipChain, size_t item) noexcept
{
using namespace DirectX::Filters;
@ -1353,12 +1365,12 @@ namespace
XMVECTOR C0, C1, C2, C3;
CUBIC_INTERPOLATE(C0, toX.x, row0[toX.u0], row0[toX.u1], row0[toX.u2], row0[toX.u3])
CUBIC_INTERPOLATE(C1, toX.x, row1[toX.u0], row1[toX.u1], row1[toX.u2], row1[toX.u3])
CUBIC_INTERPOLATE(C2, toX.x, row2[toX.u0], row2[toX.u1], row2[toX.u2], row2[toX.u3])
CUBIC_INTERPOLATE(C3, toX.x, row3[toX.u0], row3[toX.u1], row3[toX.u2], row3[toX.u3])
CUBIC_INTERPOLATE(C0, toX.x, row0[toX.u0], row0[toX.u1], row0[toX.u2], row0[toX.u3]);
CUBIC_INTERPOLATE(C1, toX.x, row1[toX.u0], row1[toX.u1], row1[toX.u2], row1[toX.u3]);
CUBIC_INTERPOLATE(C2, toX.x, row2[toX.u0], row2[toX.u1], row2[toX.u2], row2[toX.u3]);
CUBIC_INTERPOLATE(C3, toX.x, row3[toX.u0], row3[toX.u1], row3[toX.u2], row3[toX.u3]);
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3)
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3);
}
if (!StoreScanlineLinear(pDest, dest->rowPitch, dest->format, target, nwidth, filter))
@ -2384,15 +2396,15 @@ namespace
for (size_t j = 0; j < 4; ++j)
{
XMVECTOR C0, C1, C2, C3;
CUBIC_INTERPOLATE(C0, toX.x, urow[j][toX.u0], urow[j][toX.u1], urow[j][toX.u2], urow[j][toX.u3])
CUBIC_INTERPOLATE(C1, toX.x, vrow[j][toX.u0], vrow[j][toX.u1], vrow[j][toX.u2], vrow[j][toX.u3])
CUBIC_INTERPOLATE(C2, toX.x, srow[j][toX.u0], srow[j][toX.u1], srow[j][toX.u2], srow[j][toX.u3])
CUBIC_INTERPOLATE(C3, toX.x, trow[j][toX.u0], trow[j][toX.u1], trow[j][toX.u2], trow[j][toX.u3])
CUBIC_INTERPOLATE(C0, toX.x, urow[j][toX.u0], urow[j][toX.u1], urow[j][toX.u2], urow[j][toX.u3]);
CUBIC_INTERPOLATE(C1, toX.x, vrow[j][toX.u0], vrow[j][toX.u1], vrow[j][toX.u2], vrow[j][toX.u3]);
CUBIC_INTERPOLATE(C2, toX.x, srow[j][toX.u0], srow[j][toX.u1], srow[j][toX.u2], srow[j][toX.u3]);
CUBIC_INTERPOLATE(C3, toX.x, trow[j][toX.u0], trow[j][toX.u1], trow[j][toX.u2], trow[j][toX.u3]);
CUBIC_INTERPOLATE(D[j], toY.x, C0, C1, C2, C3)
CUBIC_INTERPOLATE(D[j], toY.x, C0, C1, C2, C3);
}
CUBIC_INTERPOLATE(target[x], toZ.x, D[0], D[1], D[2], D[3])
CUBIC_INTERPOLATE(target[x], toZ.x, D[0], D[1], D[2], D[3]);
}
if (!StoreScanlineLinear(pDest, dest->rowPitch, dest->format, target, nwidth, filter))
@ -2516,12 +2528,12 @@ namespace
auto const& toX = cfX[x];
XMVECTOR C0, C1, C2, C3;
CUBIC_INTERPOLATE(C0, toX.x, urow[0][toX.u0], urow[0][toX.u1], urow[0][toX.u2], urow[0][toX.u3])
CUBIC_INTERPOLATE(C1, toX.x, vrow[0][toX.u0], vrow[0][toX.u1], vrow[0][toX.u2], vrow[0][toX.u3])
CUBIC_INTERPOLATE(C2, toX.x, srow[0][toX.u0], srow[0][toX.u1], srow[0][toX.u2], srow[0][toX.u3])
CUBIC_INTERPOLATE(C3, toX.x, trow[0][toX.u0], trow[0][toX.u1], trow[0][toX.u2], trow[0][toX.u3])
CUBIC_INTERPOLATE(C0, toX.x, urow[0][toX.u0], urow[0][toX.u1], urow[0][toX.u2], urow[0][toX.u3]);
CUBIC_INTERPOLATE(C1, toX.x, vrow[0][toX.u0], vrow[0][toX.u1], vrow[0][toX.u2], vrow[0][toX.u3]);
CUBIC_INTERPOLATE(C2, toX.x, srow[0][toX.u0], srow[0][toX.u1], srow[0][toX.u2], srow[0][toX.u3]);
CUBIC_INTERPOLATE(C3, toX.x, trow[0][toX.u0], trow[0][toX.u1], trow[0][toX.u2], trow[0][toX.u3]);
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3)
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3);
}
if (!StoreScanlineLinear(pDest, dest->rowPitch, dest->format, target, nwidth, filter))
@ -2824,7 +2836,7 @@ HRESULT DirectX::GenerateMipMaps(
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK");
#ifdef WIN32
#ifdef _WIN32
bool usewic = UseWICFiltering(baseImage.format, filter);
WICPixelFormatGUID pfGUID = {};
@ -3039,7 +3051,7 @@ HRESULT DirectX::GenerateMipMaps(
static_assert(TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MODE_MASK");
#ifdef WIN32
#ifdef _WIN32
bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter);
WICPixelFormatGUID pfGUID = {};

Просмотреть файл

@ -19,7 +19,7 @@ using Microsoft::WRL::ComPtr;
namespace
{
#ifdef WIN32
#ifdef _WIN32
//--- Do image resize using WIC ---
HRESULT PerformResizeUsingWIC(
const Image& srcImage,
@ -233,6 +233,14 @@ namespace
case TEX_FILTER_TRIANGLE:
// WIC does not implement this filter
return false;
default:
if (BitsPerColor(format) > 8)
{
// Avoid the WIC bitmap scaler when doing filtering of XR/HDR formats
return false;
}
break;
}
return true;
@ -451,6 +459,10 @@ namespace
//--- Cubic Filter ---
#ifdef __clang__
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#endif
HRESULT ResizeCubicFilter(const Image& srcImage, TEX_FILTER_FLAGS filter, const Image& destImage) noexcept
{
using namespace DirectX::Filters;
@ -594,12 +606,12 @@ namespace
XMVECTOR C0, C1, C2, C3;
CUBIC_INTERPOLATE(C0, toX.x, row0[toX.u0], row0[toX.u1], row0[toX.u2], row0[toX.u3])
CUBIC_INTERPOLATE(C1, toX.x, row1[toX.u0], row1[toX.u1], row1[toX.u2], row1[toX.u3])
CUBIC_INTERPOLATE(C2, toX.x, row2[toX.u0], row2[toX.u1], row2[toX.u2], row2[toX.u3])
CUBIC_INTERPOLATE(C3, toX.x, row3[toX.u0], row3[toX.u1], row3[toX.u2], row3[toX.u3])
CUBIC_INTERPOLATE(C0, toX.x, row0[toX.u0], row0[toX.u1], row0[toX.u2], row0[toX.u3]);
CUBIC_INTERPOLATE(C1, toX.x, row1[toX.u0], row1[toX.u1], row1[toX.u2], row1[toX.u3]);
CUBIC_INTERPOLATE(C2, toX.x, row2[toX.u0], row2[toX.u1], row2[toX.u2], row2[toX.u3]);
CUBIC_INTERPOLATE(C3, toX.x, row3[toX.u0], row3[toX.u1], row3[toX.u2], row3[toX.u3]);
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3)
CUBIC_INTERPOLATE(target[x], toY.x, C0, C1, C2, C3);
}
if (!StoreScanlineLinear(pDest, destImage.rowPitch, destImage.format, target, destImage.width, filter))
@ -864,7 +876,7 @@ HRESULT DirectX::Resize(
return HRESULT_E_NOT_SUPPORTED;
}
#ifdef WIN32
#ifdef _WIN32
bool usewic = UseWICFiltering(srcImage.format, filter);
WICPixelFormatGUID pfGUID = {};
@ -893,7 +905,7 @@ HRESULT DirectX::Resize(
if (!rimage)
return E_POINTER;
#ifdef WIN32
#ifdef _WIN32
if (usewic)
{
if (wicpf)
@ -951,7 +963,7 @@ HRESULT DirectX::Resize(
if (FAILED(hr))
return hr;
#ifdef WIN32
#ifdef _WIN32
bool usewic = !metadata.IsPMAlpha() && UseWICFiltering(metadata.format, filter);
WICPixelFormatGUID pfGUID = {};
@ -1007,7 +1019,7 @@ HRESULT DirectX::Resize(
return E_FAIL;
}
#ifdef WIN32
#ifdef _WIN32
if (usewic)
{
if (wicpf)
@ -1068,7 +1080,7 @@ HRESULT DirectX::Resize(
return E_FAIL;
}
#ifdef WIN32
#ifdef _WIN32
if (usewic)
{
if (wicpf)

Просмотреть файл

@ -15,7 +15,8 @@
// The implementation here has the following limitations:
// * Does not support files that contain color maps (these are rare in practice)
// * Interleaved files are not supported (deprecated aspect of TGA format)
// * Only supports 8-bit grayscale; 16-, 24-, and 32-bit truecolor images
// * Only supports 8-bit grayscale; 16-, 24-, and 32-bit truecolor images RLE or uncompressed
// plus 24-bit color-mapped uncompressed images
// * Always writes uncompressed files (i.e. can read RLE compression, but does not write it)
//
@ -76,6 +77,8 @@ namespace
static_assert(sizeof(TGA_HEADER) == 18, "TGA 2.0 size mismatch");
constexpr size_t TGA_HEADER_LEN = 18;
struct TGA_FOOTER
{
uint32_t dwExtensionOffset;
@ -125,6 +128,7 @@ namespace
CONV_FLAGS_INVERTX = 0x2, // If set, scanlines are right-to-left
CONV_FLAGS_INVERTY = 0x4, // If set, scanlines are top-to-bottom
CONV_FLAGS_RLE = 0x8, // Source data is RLE compressed
CONV_FLAGS_PALETTED = 0x10, // Source data is paletted
CONV_FLAGS_SWIZZLE = 0x10000, // Swizzle BGR<->RGB data
CONV_FLAGS_888 = 0x20000, // 24bpp format
@ -147,19 +151,13 @@ namespace
memset(&metadata, 0, sizeof(TexMetadata));
if (size < sizeof(TGA_HEADER))
if (size < TGA_HEADER_LEN)
{
return HRESULT_E_INVALID_DATA;
}
auto pHeader = static_cast<const TGA_HEADER*>(pSource);
if (pHeader->bColorMapType != 0
|| pHeader->wColorMapLength != 0)
{
return HRESULT_E_NOT_SUPPORTED;
}
if (pHeader->bDescriptor & (TGA_FLAGS_INTERLEAVED_2WAY | TGA_FLAGS_INTERLEAVED_4WAY))
{
return HRESULT_E_NOT_SUPPORTED;
@ -167,13 +165,58 @@ namespace
if (!pHeader->wWidth || !pHeader->wHeight)
{
// These are uint16 values so are already bounded by UINT16_MAX.
return HRESULT_E_INVALID_DATA;
}
switch (pHeader->bImageType)
{
case TGA_NO_IMAGE:
case TGA_COLOR_MAPPED_RLE:
return HRESULT_E_NOT_SUPPORTED;
case TGA_COLOR_MAPPED:
if (pHeader->bColorMapType != 1
|| pHeader->wColorMapLength == 0
|| pHeader->bBitsPerPixel != 8)
{
return HRESULT_E_NOT_SUPPORTED;
}
switch (pHeader->bColorMapSize)
{
case 24:
if (flags & TGA_FLAGS_BGR)
{
metadata.format = DXGI_FORMAT_B8G8R8X8_UNORM;
}
else
{
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
}
break;
// Other possible values are 15, 16, and 32 which we do not support.
default:
return HRESULT_E_NOT_SUPPORTED;
}
if (convFlags)
{
*convFlags |= CONV_FLAGS_PALETTED;
}
break;
case TGA_TRUECOLOR:
case TGA_TRUECOLOR_RLE:
if (pHeader->bColorMapType != 0
|| pHeader->wColorMapLength != 0)
{
return HRESULT_E_NOT_SUPPORTED;
}
switch (pHeader->bBitsPerPixel)
{
case 16:
@ -198,6 +241,9 @@ namespace
case 32:
metadata.format = (flags & TGA_FLAGS_BGR) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
break;
default:
return HRESULT_E_NOT_SUPPORTED;
}
if (convFlags && (pHeader->bImageType == TGA_TRUECOLOR_RLE))
@ -208,6 +254,12 @@ namespace
case TGA_BLACK_AND_WHITE:
case TGA_BLACK_AND_WHITE_RLE:
if (pHeader->bColorMapType != 0
|| pHeader->wColorMapLength != 0)
{
return HRESULT_E_NOT_SUPPORTED;
}
switch (pHeader->bBitsPerPixel)
{
case 8:
@ -224,11 +276,6 @@ namespace
}
break;
case TGA_NO_IMAGE:
case TGA_COLOR_MAPPED:
case TGA_COLOR_MAPPED_RLE:
return HRESULT_E_NOT_SUPPORTED;
default:
return HRESULT_E_INVALID_DATA;
}
@ -247,7 +294,7 @@ namespace
*convFlags |= CONV_FLAGS_INVERTY;
}
offset = sizeof(TGA_HEADER);
offset = TGA_HEADER_LEN;
if (pHeader->bIDLength != 0)
{
@ -258,6 +305,64 @@ namespace
}
//-------------------------------------------------------------------------------------
// Reads palette for color-mapped TGA formats
//-------------------------------------------------------------------------------------
HRESULT ReadPalette(
_In_reads_(TGA_HEADER_LEN) const uint8_t* header,
_In_reads_bytes_(size) const void* pSource,
size_t size,
TGA_FLAGS flags,
uint8_t palette[256 * 4],
size_t& colorMapSize) noexcept
{
assert(header && pSource);
auto pHeader = reinterpret_cast<const TGA_HEADER*>(header);
if (pHeader->bColorMapType != 1
|| pHeader->wColorMapLength == 0
|| pHeader->wColorMapLength > 256
|| pHeader->bColorMapSize != 24)
{
return HRESULT_E_NOT_SUPPORTED;
}
const size_t maxColorMap = size_t(pHeader->wColorMapFirst) + size_t(pHeader->wColorMapLength);
if (maxColorMap > 256)
{
return HRESULT_E_NOT_SUPPORTED;
}
colorMapSize = size_t(pHeader->wColorMapLength) * ((size_t(pHeader->bColorMapSize) + 7) >> 3);
if (colorMapSize > size)
{
return HRESULT_E_INVALID_DATA;
}
auto bytes = reinterpret_cast<const uint8_t*>(pSource);
for (size_t i = pHeader->wColorMapFirst; i < maxColorMap; ++i)
{
if (flags & TGA_FLAGS_BGR)
{
palette[i * 4 + 0] = bytes[0];
palette[i * 4 + 2] = bytes[2];
}
else
{
palette[i * 4 + 0] = bytes[2];
palette[i * 4 + 2] = bytes[0];
}
palette[i * 4 + 1] = bytes[1];
palette[i * 4 + 3] = 255;
bytes += 3;
}
return S_OK;
}
//-------------------------------------------------------------------------------------
// Set alpha for images with all 0 alpha channel
//-------------------------------------------------------------------------------------
@ -814,7 +919,8 @@ namespace
size_t size,
TGA_FLAGS flags,
_In_ const Image* image,
_In_ uint32_t convFlags) noexcept
_In_ uint32_t convFlags,
_In_opt_ const uint8_t* palette) noexcept
{
assert(pSource && size > 0);
@ -823,7 +929,8 @@ namespace
// Compute TGA image data pitch
size_t rowPitch, slicePitch;
HRESULT hr = ComputePitch(image->format, image->width, image->height, rowPitch, slicePitch,
HRESULT hr = ComputePitch(image->format, image->width, image->height,
rowPitch, slicePitch,
(convFlags & CONV_FLAGS_EXPAND) ? CP_FLAGS_24BPP : CP_FLAGS_NONE);
if (FAILED(hr))
return hr;
@ -833,9 +940,41 @@ namespace
bool opaquealpha = false;
if ((convFlags & CONV_FLAGS_PALETTED) != 0)
{
if (!palette)
return E_UNEXPECTED;
const auto table = reinterpret_cast<const uint32_t*>(palette);
for (size_t y = 0; y < image->height; ++y)
{
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
assert(offset < rowPitch);
auto dPtr = reinterpret_cast<uint32_t*>(image->pixels
+ (image->rowPitch * ((convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1))))
+ offset;
for (size_t x = 0; x < image->width; ++x)
{
if (sPtr >= endPtr)
return E_FAIL;
*dPtr = table[*(sPtr++)];
if (convFlags & CONV_FLAGS_INVERTX)
--dPtr;
else
++dPtr;
}
}
}
else
{
switch (image->format)
{
//--------------------------------------------------------------------------- 8-bit
//----------------------------------------------------------------------- 8-bit
case DXGI_FORMAT_R8_UNORM:
for (size_t y = 0; y < image->height; ++y)
{
@ -861,7 +1000,7 @@ namespace
}
break;
//-------------------------------------------------------------------------- 16-bit
//---------------------------------------------------------------------- 16-bit
case DXGI_FORMAT_B5G5R5A1_UNORM:
{
uint32_t minalpha = 255;
@ -911,7 +1050,7 @@ namespace
}
break;
//------------------------------------------------------ 24/32-bit (with swizzling)
//-------------------------------------------------- 24/32-bit (with swizzling)
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
uint32_t minalpha = 255;
@ -979,7 +1118,7 @@ namespace
}
break;
//-------------------------------------------------------------------- 32-bit (BGR)
//---------------------------------------------------------------- 32-bit (BGR)
case DXGI_FORMAT_B8G8R8A8_UNORM:
{
assert((convFlags & CONV_FLAGS_EXPAND) == 0);
@ -1032,7 +1171,7 @@ namespace
}
break;
//-------------------------------------------------------------------- 24-bit (BGR)
//---------------------------------------------------------------- 24-bit (BGR)
case DXGI_FORMAT_B8G8R8X8_UNORM:
{
assert((convFlags & CONV_FLAGS_EXPAND) != 0);
@ -1064,10 +1203,11 @@ namespace
}
break;
//---------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
default:
return E_FAIL;
}
}
return opaquealpha ? S_FALSE : S_OK;
}
@ -1078,7 +1218,7 @@ namespace
//-------------------------------------------------------------------------------------
HRESULT EncodeTGAHeader(_In_ const Image& image, _Out_ TGA_HEADER& header, _Inout_ uint32_t& convFlags) noexcept
{
memset(&header, 0, sizeof(TGA_HEADER));
memset(&header, 0, TGA_HEADER_LEN);
if ((image.width > UINT16_MAX)
|| (image.height > UINT16_MAX))
@ -1224,7 +1364,7 @@ namespace
time_t now = {};
time(&now);
#ifdef WIN32
#ifdef _WIN32
tm info;
auto pinfo = &info;
if (!gmtime_s(pinfo, &now))
@ -1343,7 +1483,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
if (!szFile)
return E_INVALIDARG;
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -1389,28 +1529,28 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
#endif
// Need at least enough data to fill the standard header to be a valid TGA
if (len < (sizeof(TGA_HEADER)))
if (len < TGA_HEADER_LEN)
{
return E_FAIL;
}
// Read the standard header (we don't need the file footer to parse the file)
uint8_t header[sizeof(TGA_HEADER)] = {};
uint8_t header[TGA_HEADER_LEN] = {};
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
if (!ReadFile(hFile.get(), header, TGA_HEADER_LEN, &bytesRead, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
}
auto const headerLen = static_cast<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
inFile.read(reinterpret_cast<char*>(header), TGA_HEADER_LEN);
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
size_t headerLen = TGA_HEADER_LEN;
#endif
size_t offset;
@ -1424,7 +1564,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
{
TGA_FOOTER footer = {};
#ifdef WIN32
#ifdef _WIN32
if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) != INVALID_SET_FILE_POINTER)
{
if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr))
@ -1452,7 +1592,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags,
if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{
#ifdef WIN32
#ifdef _WIN32
const LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{
@ -1514,12 +1654,29 @@ HRESULT DirectX::LoadFromTGAMemory(
if (offset > size)
return E_FAIL;
const void* pPixels = static_cast<const uint8_t*>(pSource) + offset;
size_t paletteOffset = 0;
uint8_t palette[256 * 4] = {};
if (convFlags & CONV_FLAGS_PALETTED)
{
const size_t remaining = size - offset;
if (remaining == 0)
return E_FAIL;
auto pColorMap = static_cast<const uint8_t*>(pSource) + offset;
_Analysis_assume_(size > TGA_HEADER_LEN);
hr = ReadPalette(static_cast<const uint8_t*>(pSource), pColorMap, remaining, flags,
palette, paletteOffset);
if (FAILED(hr))
return hr;
}
const size_t remaining = size - offset - paletteOffset;
if (remaining == 0)
return E_FAIL;
const void* pPixels = static_cast<const uint8_t*>(pSource) + offset + paletteOffset;
hr = image.Initialize2D(mdata.format, mdata.width, mdata.height, 1, 1);
if (FAILED(hr))
return hr;
@ -1530,7 +1687,7 @@ HRESULT DirectX::LoadFromTGAMemory(
}
else
{
hr = CopyPixels(pPixels, remaining, flags, image.GetImage(0, 0, 0), convFlags);
hr = CopyPixels(pPixels, remaining, flags, image.GetImage(0, 0, 0), convFlags, palette);
}
if (FAILED(hr))
@ -1592,7 +1749,7 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release();
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
@ -1638,28 +1795,28 @@ HRESULT DirectX::LoadFromTGAFile(
#endif
// Need at least enough data to fill the header to be a valid TGA
if (len < sizeof(TGA_HEADER))
if (len < TGA_HEADER_LEN)
{
return E_FAIL;
}
// Read the header
uint8_t header[sizeof(TGA_HEADER)] = {};
uint8_t header[TGA_HEADER_LEN] = {};
#ifdef WIN32
#ifdef _WIN32
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, nullptr))
if (!ReadFile(hFile.get(), header, TGA_HEADER_LEN, &bytesRead, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
}
auto const headerLen = static_cast<size_t>(bytesRead);
#else
inFile.read(reinterpret_cast<char*>(header), sizeof(TGA_HEADER));
inFile.read(reinterpret_cast<char*>(header), TGA_HEADER_LEN);
if (!inFile)
return E_FAIL;
size_t headerLen = sizeof(TGA_HEADER);
size_t headerLen = TGA_HEADER_LEN;
#endif
size_t offset;
@ -1674,9 +1831,9 @@ HRESULT DirectX::LoadFromTGAFile(
if (remaining == 0)
return E_FAIL;
if (offset > sizeof(TGA_HEADER))
if (offset > TGA_HEADER_LEN)
{
#ifdef WIN32
#ifdef _WIN32
// Skip past the id string
const LARGE_INTEGER filePos = { { static_cast<DWORD>(offset), 0 } };
if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
@ -1698,7 +1855,7 @@ HRESULT DirectX::LoadFromTGAFile(
bool opaquealpha = false;
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 | CONV_FLAGS_PALETTED)) && (convFlags & CONV_FLAGS_INVERTY))
{
// This case we can read directly into the image buffer in place
if (remaining < image.GetPixelsSize())
@ -1713,7 +1870,7 @@ HRESULT DirectX::LoadFromTGAFile(
return HRESULT_E_ARITHMETIC_OVERFLOW;
}
#ifdef WIN32
#ifdef _WIN32
if (!ReadFile(hFile.get(), image.GetPixels(), static_cast<DWORD>(image.GetPixelsSize()), &bytesRead, nullptr))
{
image.Release();
@ -1923,7 +2080,7 @@ HRESULT DirectX::LoadFromTGAFile(
break;
}
}
else // RLE || EXPAND || INVERTX || !INVERTY
else // RLE || EXPAND || INVERTX || PALETTED || !INVERTY
{
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[remaining]);
if (!temp)
@ -1932,7 +2089,7 @@ HRESULT DirectX::LoadFromTGAFile(
return E_OUTOFMEMORY;
}
#ifdef WIN32
#ifdef _WIN32
if (!ReadFile(hFile.get(), temp.get(), static_cast<DWORD>(remaining), &bytesRead, nullptr))
{
image.Release();
@ -1953,13 +2110,27 @@ HRESULT DirectX::LoadFromTGAFile(
}
#endif
size_t paletteOffset = 0;
uint8_t palette[256 * 4] = {};
if (convFlags & CONV_FLAGS_PALETTED)
{
hr = ReadPalette(header, temp.get(), remaining, flags, palette, paletteOffset);
if (FAILED(hr))
{
image.Release();
return hr;
}
}
if (convFlags & CONV_FLAGS_RLE)
{
hr = UncompressPixels(temp.get(), remaining, flags, image.GetImage(0, 0, 0), convFlags);
hr = UncompressPixels(temp.get() + paletteOffset, remaining - paletteOffset,
flags, image.GetImage(0, 0, 0), convFlags);
}
else
{
hr = CopyPixels(temp.get(), remaining, flags, image.GetImage(0, 0, 0), convFlags);
hr = CopyPixels(temp.get() + paletteOffset, remaining - paletteOffset,
flags, image.GetImage(0, 0, 0), convFlags, palette);
}
if (FAILED(hr))
@ -1978,7 +2149,7 @@ HRESULT DirectX::LoadFromTGAFile(
{
TGA_FOOTER footer = {};
#ifdef WIN32
#ifdef _WIN32
if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), nullptr, FILE_END) != INVALID_SET_FILE_POINTER)
{
if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr))
@ -2011,7 +2182,7 @@ HRESULT DirectX::LoadFromTGAFile(
if (footer.dwExtensionOffset != 0
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= len))
{
#ifdef WIN32
#ifdef _WIN32
const LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{
@ -2089,7 +2260,7 @@ HRESULT DirectX::SaveToTGAMemory(
if (FAILED(hr))
return hr;
hr = blob.Initialize(sizeof(TGA_HEADER)
hr = blob.Initialize(TGA_HEADER_LEN
+ slicePitch
+ (metadata ? sizeof(TGA_EXTENSION) : 0)
+ sizeof(TGA_FOOTER));
@ -2101,8 +2272,8 @@ HRESULT DirectX::SaveToTGAMemory(
assert(destPtr != nullptr);
uint8_t* dPtr = destPtr;
memcpy(dPtr, &tga_header, sizeof(TGA_HEADER));
dPtr += sizeof(TGA_HEADER);
memcpy(dPtr, &tga_header, TGA_HEADER_LEN);
dPtr += TGA_HEADER_LEN;
const uint8_t* pPixels = image.pixels;
assert(pPixels);
@ -2174,7 +2345,7 @@ HRESULT DirectX::SaveToTGAFile(
return hr;
// Create file and write header
#ifdef WIN32
#ifdef _WIN32
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0,
CREATE_ALWAYS, nullptr)));
@ -2211,7 +2382,7 @@ HRESULT DirectX::SaveToTGAFile(
return hr;
// Write blob
#ifdef WIN32
#ifdef _WIN32
const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize());
DWORD bytesWritten;
if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
@ -2239,17 +2410,17 @@ HRESULT DirectX::SaveToTGAFile(
return E_OUTOFMEMORY;
// Write header
#ifdef WIN32
#ifdef _WIN32
DWORD bytesWritten;
if (!WriteFile(hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, nullptr))
if (!WriteFile(hFile.get(), &tga_header, TGA_HEADER_LEN, &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
}
if (bytesWritten != sizeof(TGA_HEADER))
if (bytesWritten != TGA_HEADER_LEN)
return E_FAIL;
#else
outFile.write(reinterpret_cast<char*>(&tga_header), sizeof(TGA_HEADER));
outFile.write(reinterpret_cast<char*>(&tga_header), TGA_HEADER_LEN);
if (!outFile)
return E_FAIL;
#endif
@ -2278,7 +2449,7 @@ HRESULT DirectX::SaveToTGAFile(
pPixels += image.rowPitch;
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), temp.get(), static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2300,7 +2471,7 @@ HRESULT DirectX::SaveToTGAFile(
TGA_EXTENSION ext = {};
SetExtension(&ext, flags, *metadata);
#ifdef WIN32
#ifdef _WIN32
extOffset = SetFilePointer(hFile.get(), 0, nullptr, FILE_CURRENT);
if (extOffset == INVALID_SET_FILE_POINTER)
{
@ -2330,7 +2501,7 @@ HRESULT DirectX::SaveToTGAFile(
footer.dwExtensionOffset = extOffset;
memcpy(footer.Signature, g_Signature, sizeof(g_Signature));
#ifdef WIN32
#ifdef _WIN32
if (!WriteFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesWritten, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
@ -2345,7 +2516,7 @@ HRESULT DirectX::SaveToTGAFile(
#endif
}
#ifdef WIN32
#ifdef _WIN32
delonfail.clear();
#endif

Просмотреть файл

@ -32,7 +32,7 @@ using Microsoft::WRL::ComPtr;
namespace
{
#ifdef WIN32
#ifdef _WIN32
//-------------------------------------------------------------------------------------
// WIC Pixel Format Translation Data
//-------------------------------------------------------------------------------------
@ -127,7 +127,7 @@ namespace
}
#ifdef WIN32
#ifdef _WIN32
//=====================================================================================
// WIC Utilities
//=====================================================================================
@ -973,6 +973,11 @@ HRESULT DirectX::ComputePitch(DXGI_FORMAT fmt, size_t width, size_t height,
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
if ((height % 2) != 0)
{
// Requires a height alignment of 2.
return E_INVALIDARG;
}
assert(IsPlanar(fmt));
pitch = ((uint64_t(width) + 1u) >> 1) * 2u;
slice = pitch * (uint64_t(height) + ((uint64_t(height) + 1u) >> 1));
@ -980,6 +985,20 @@ HRESULT DirectX::ComputePitch(DXGI_FORMAT fmt, size_t width, size_t height,
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
if ((height % 2) != 0)
{
// Requires a height alignment of 2.
return E_INVALIDARG;
}
#if (__cplusplus >= 201703L)
[[fallthrough]];
#elif defined(__clang__)
[[clang::fallthrough]];
#elif defined(_MSC_VER)
__fallthrough;
#endif
case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT:
case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT:
@ -1001,6 +1020,11 @@ HRESULT DirectX::ComputePitch(DXGI_FORMAT fmt, size_t width, size_t height,
break;
case WIN10_DXGI_FORMAT_V208:
if ((height % 2) != 0)
{
// Requires a height alignment of 2.
return E_INVALIDARG;
}
assert(IsPlanar(fmt));
pitch = uint64_t(width);
slice = pitch * (uint64_t(height) + (((uint64_t(height) + 1u) >> 1) * 2u));
@ -1183,6 +1207,41 @@ DXGI_FORMAT DirectX::MakeSRGB(DXGI_FORMAT fmt) noexcept
}
//-------------------------------------------------------------------------------------
// Converts to an non-SRGB equivalent type
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
DXGI_FORMAT DirectX::MakeLinear(DXGI_FORMAT fmt) noexcept
{
switch (fmt)
{
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_BC1_UNORM_SRGB:
return DXGI_FORMAT_BC1_UNORM;
case DXGI_FORMAT_BC2_UNORM_SRGB:
return DXGI_FORMAT_BC2_UNORM;
case DXGI_FORMAT_BC3_UNORM_SRGB:
return DXGI_FORMAT_BC3_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
return DXGI_FORMAT_B8G8R8X8_UNORM;
case DXGI_FORMAT_BC7_UNORM_SRGB:
return DXGI_FORMAT_BC7_UNORM;
default:
return fmt;
}
}
//-------------------------------------------------------------------------------------
// Converts to a format to an equivalent TYPELESS format if available
//-------------------------------------------------------------------------------------

Просмотреть файл

@ -19,7 +19,7 @@
<ProjectGuid>{9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}</ProjectGuid>
<RootNamespace>DirectXTex</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

Просмотреть файл

@ -12,7 +12,7 @@
#pragma once
// Off by default warnings
#pragma warning(disable : 4619 4616 4061 4265 4365 4571 4623 4625 4626 4628 4668 4710 4711 4746 4774 4820 4987 5026 5027 5031 5032 5039 5045 5219 26812)
#pragma warning(disable : 4619 4616 4061 4265 4365 4571 4623 4625 4626 4628 4668 4710 4711 4746 4774 4820 4987 5026 5027 5031 5032 5039 5045 5219 5246 5264 26812)
// C4619/4616 #pragma warning warnings
// C4061 enumerator 'X' in switch of enum 'X' is not explicitly handled by a case label
// C4265 class has virtual functions, but destructor is not virtual
@ -35,6 +35,8 @@
// C5039 pointer or reference to potentially throwing function passed to extern C function under - EHc
// C5045 Spectre mitigation warning
// C5219 implicit conversion from 'int' to 'float', possible loss of data
// C5246 the initialization of a subobject should be wrapped in braces
// C5264 'const' variable is not used
// 26812: The enum type 'x' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
// Windows 8.1 SDK related Off by default warnings
@ -68,16 +70,17 @@
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wtautological-type-limit-compare"
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wundef"
#endif
#if defined(WIN32) || defined(_WIN32)
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma warning(push)
#pragma warning(disable : 4005)
#define NOMINMAX
#define NOMINMAX 1
#define NODRAWTEXT
#define NOGDI
#define NOBITMAP
@ -88,6 +91,10 @@
#include <Windows.h>
#ifdef __MINGW32__
#include <unknwn.h>
#endif
#ifndef _WIN32_WINNT_WIN10
#define _WIN32_WINNT_WIN10 0x0A00
#endif
@ -132,7 +139,7 @@
#include <new>
#include <tuple>
#ifndef WIN32
#ifndef _WIN32
#include <fstream>
#include <filesystem>
#include <thread>
@ -148,10 +155,10 @@
#include "DirectXTex.h"
#ifdef _WIN32
#include <malloc.h>
#ifdef WIN32
#ifdef NTDDI_WIN10_FE
#if defined(NTDDI_WIN10_FE) || defined(__MINGW32__)
#include <ole2.h>
#else
#include <Ole2.h>
@ -180,6 +187,10 @@ using WICPixelFormatGUID = GUID;
#define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190)
#if defined(__MINGW32__) && !defined(E_BOUNDS)
#define E_BOUNDS static_cast<HRESULT>(0x8000000BL)
#endif
// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)
#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast<HRESULT>(0x80070216L)
@ -210,7 +221,7 @@ namespace DirectX
{
//-----------------------------------------------------------------------------
// WIC helper functions
#ifdef WIN32
#ifdef _WIN32
DXGI_FORMAT __cdecl WICToDXGI(_In_ const GUID& guid) noexcept;
bool __cdecl DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false) noexcept;
@ -299,7 +310,7 @@ namespace DirectX
//---------------------------------------------------------------------------------
// Image helper functions
_Success_(return) bool __cdecl DetermineImageArray(
HRESULT __cdecl DetermineImageArray(
_In_ const TexMetadata& metadata, _In_ CP_FLAGS cpFlags,
_Out_ size_t& nImages, _Out_ size_t& pixelSize) noexcept;
@ -314,8 +325,12 @@ namespace DirectX
enum TEXP_SCANLINE_FLAGS : uint32_t
{
TEXP_SCANLINE_NONE = 0,
TEXP_SCANLINE_SETALPHA = 0x1, // Set alpha channel to known opaque value
TEXP_SCANLINE_LEGACY = 0x2, // Enables specific legacy format conversion cases
TEXP_SCANLINE_SETALPHA = 0x1,
// Set alpha channel to known opaque value
TEXP_SCANLINE_LEGACY = 0x2,
// Enables specific legacy format conversion cases
};
enum CONVERT_FLAGS : uint32_t
@ -413,7 +428,7 @@ namespace DirectX
bool __cdecl CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth,
_Inout_ size_t& mipLevels) noexcept;
#ifdef WIN32
#ifdef _WIN32
HRESULT __cdecl ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC,
_In_ bool iswic2,
_In_ IWICBitmap* original,

Просмотреть файл

@ -6,11 +6,11 @@ http://go.microsoft.com/fwlink/?LinkId=248926
Copyright (c) Microsoft Corporation.
**March 24, 2022**
**January 31, 2023**
This package contains DirectXTex, a shared source library for reading and writing ``.DDS`` files, and performing various texture content processing operations including resizing, format conversion, mip-map generation, block compression for Direct3D runtime texture resources, and height-map to normal-map conversion. This library makes use of the Windows Image Component (WIC) APIs. It also includes ``.TGA`` and ``.HDR`` readers and writers since these image file formats are commonly used for texture content processing pipelines, but are not currently supported by a built-in WIC codec.
This code is designed to build with Visual Studio 2017 ([15.9](https://walbourn.github.io/vs-2017-15-9-update/)), Visual Studio 2019, Visual Studio 2022, or clang for Windows v11 or later. Use of the Windows 10 May 2020 Update SDK ([19041](https://walbourn.github.io/windows-10-may-2020-update-sdk/)) or later is required.
This code is designed to build with Visual Studio 2019 (16.11), Visual Studio 2022, clang for Windows v12 or later, or MinGW 12.2. Use of the Windows 10 May 2020 Update SDK ([19041](https://walbourn.github.io/windows-10-may-2020-update-sdk/)) or later is required for Visual Studio. It can also be built for Windows Subsystem for Linux using GCC 11 or later.
These components are designed to work without requiring any content from the legacy DirectX SDK. For details, see [Where is the DirectX SDK?](https://aka.ms/dxsdk).
@ -25,6 +25,10 @@ These components are designed to work without requiring any content from the leg
> The majority of the header files here are intended for internal implementation
of the library only (``BC.h``, ``BCDirectCompute.h``, ``DDS.h``, ``DirectXTexP.h``, etc.). Only ``DirectXTex.h`` and ``DirectXTex.inl`` are meant as the 'public' header for the library.
* ``Auxiliary\``
+ Contains optional source files for the DirectXTex library, such as adapter loading functions using the OpenEXR library.
* ``Texconv\``
+ This DirectXTex sample is an implementation of the [texconv](https://github.com/Microsoft/DirectXTex/wiki/Texconv) command-line texture utility from the DirectX SDK utilizing DirectXTex rather than D3DX.
@ -59,7 +63,11 @@ These components are designed to work without requiring any content from the leg
> DDSTextureLoader12, ScreenGrab12, and WICTextureLoader12 are 'stand-alone' versions of the same modules provided in the [DirectX Tool Kit for DX12](https://github.com/Microsoft/DirectXTK12).
# Documentation
* ``build\``
+ Contains YAML files for the build pipelines along with some miscellaneous build files and scripts.
## Documentation
Documentation is available on the [GitHub wiki](https://github.com/Microsoft/DirectXTex/wiki).
@ -71,6 +79,8 @@ For the latest version of DirectXTex, bug reports, etc. please visit the project
## Release Notes
* Starting with the July 2022 release, the ``bool forceSRGB`` parameter for the CreateTextureEx and CreateShaderResourceViewEx functions is now a ``CREATETEX_FLAGS`` typed enum bitmask flag parameter. This may have a *breaking change* impact to client code. Replace ``true`` with ``CREATETEX_FORCE_SRGB`` and ``false`` with ``CREATETEX_DEFAULT``.
* Starting with the June 2020 release, this library makes use of typed enum bitmask flags per the recommendation of the _C++ Standard_ section *17.5.2.1.3 Bitmask types*. This is consistent with Direct3D 12's use of the ``DEFINE_ENUM_FLAG_OPERATORS`` macro. This may have *breaking change* impacts to client code:
* You cannot pass the ``0`` literal as your flags value. Instead you must make use of the appropriate default enum value: ``CP_FLAGS_NONE``, ``DDS_FLAGS_NONE``, ``WIC_FLAGS_NONE``, ``TEX_FR_ROTATE0``, ``TEX_FILTER_DEFAULT``, ``TEX_FILTER_DEFAULT``, ``TEX_FILTER_DEFAULT``, ``CNMAP_DEFAULT``, or ``CNMAP_DEFAULT``.
@ -87,7 +97,9 @@ For the latest version of DirectXTex, bug reports, etc. please visit the project
* Loading of 96bpp floating-point TIFF files results in a corrupted image prior to Windows 8. This fix is available on Windows 7 SP1 with KB 2670838 installed.
* The UWP projects and the Win10 classic desktop project include configurations for the ARM64 platform. These require VS 2017 (15.9 update) or later to build, with the ARM64 toolset installed.
* The UWP projects and the Win10 classic desktop project include configurations for the ARM64 platform. Building these requires installing the ARM64 toolset.
* When using clang/LLVM for the ARM64 platform, the Windows 11 SDK ([22000](https://walbourn.github.io/windows-sdk-for-windows-11/)) is required.
* The ``CompileShaders.cmd`` script must have Windows-style (CRLF) line-endings. If it is changed to Linux-style (LF) line-endings, it can fail to build all the required shaders.

Просмотреть файл

@ -37,13 +37,14 @@ if %error% == 0 (
echo Shaders compiled ok
) else (
echo There were shader compilation errors!
exit /b 1
)
endlocal
exit /b
exit /b 0
:CompileShader
set fxc=%PCFXC% %1.hlsl %FXCOPTS% /Tcs_4_0 /E%2 "/Fh%CompileShadersOutput%\%1_%2.inc" "/Fd%CompileShadersOutput%\%1_%2.pdb" /Vn%1_%2
set fxc=%PCFXC% "%1.hlsl" %FXCOPTS% /Tcs_4_0 /E%2 "/Fh%CompileShadersOutput%\%1_%2.inc" "/Fd%CompileShadersOutput%\%1_%2.pdb" /Vn%1_%2
echo.
echo %fxc%
%fxc% || set error=1

Просмотреть файл

@ -15,7 +15,7 @@
#include <memory>
#include <tuple>
#ifndef WIN32
#ifndef _WIN32
#include <cstdlib>
struct aligned_deleter { void operator()(void* p) noexcept { free(p); } };

Просмотреть файл

@ -23,6 +23,7 @@
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <memory>
#include <new>
#include <tuple>

Просмотреть файл

@ -20,11 +20,14 @@
#define NOHELP
#pragma warning(pop)
#include <ShlObj.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cwchar>
#include <cwctype>
#include <fstream>
@ -46,7 +49,6 @@
#include <wincodec.h>
#pragma warning(disable : 4619 4616 4091 4838 26812)
#include <ShlObj.h>
#include "DirectXTex.h"
#include "DirectXTexXbox.h"
@ -788,16 +790,16 @@ namespace
switch (info.GetAlphaMode())
{
case TEX_ALPHA_MODE_OPAQUE:
wprintf(L" \x0e0:Opaque");
wprintf(L" \x03B1:Opaque");
break;
case TEX_ALPHA_MODE_PREMULTIPLIED:
wprintf(L" \x0e0:PM");
wprintf(L" \x03B1:PM");
break;
case TEX_ALPHA_MODE_STRAIGHT:
wprintf(L" \x0e0:NonPM");
wprintf(L" \x03B1:NonPM");
break;
case TEX_ALPHA_MODE_CUSTOM:
wprintf(L" \x0e0:Custom");
wprintf(L" \x03B1:Custom");
break;
case TEX_ALPHA_MODE_UNKNOWN:
break;
@ -871,81 +873,97 @@ namespace
{
PrintLogo();
wprintf(L"Usage: texconv <options> <files>\n\n");
wprintf(L" -r wildcard filename search is recursive\n");
wprintf(L" -r:flatten flatten the directory structure (default)\n");
wprintf(L" -r:keep keep the directory structure\n");
wprintf(L" -flist <filename> use text file with a list of input files (one per line)\n");
wprintf(L"\n -w <n> width\n");
wprintf(L" -h <n> height\n");
wprintf(L" -m <n> miplevels\n");
wprintf(L" -f <format> format\n");
wprintf(L"\n -if <filter> image filtering\n");
wprintf(L" -srgb{i|o} sRGB {input, output}\n");
wprintf(L"\n -px <string> name prefix\n");
wprintf(L" -sx <string> name suffix\n");
wprintf(L" -o <directory> output directory\n");
wprintf(L" -l force output filename to lower case\n");
wprintf(L" -y overwrite existing output file (if any)\n");
wprintf(L" -ft <filetype> output file type\n");
wprintf(L"\n -hflip horizonal flip of source image\n");
wprintf(L" -vflip vertical flip of source image\n");
wprintf(L"\n -sepalpha resize/generate mips alpha channel separately\n");
wprintf(L" from color channels\n");
wprintf(L" -keepcoverage <ref> Preserve alpha coverage in mips for alpha test ref\n");
wprintf(L"\n -nowic Force non-WIC filtering\n");
wprintf(L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n");
wprintf(L" -pmalpha convert final texture to use premultiplied alpha\n");
wprintf(L" -alpha convert premultiplied alpha to straight alpha\n");
wprintf(
static const wchar_t* const s_usage =
L"Usage: texconv <options> <files>\n"
L"\n"
L" -r wildcard filename search is recursive\n"
L" -r:flatten flatten the directory structure (default)\n"
L" -r:keep keep the directory structure\n"
L" -flist <filename> use text file with a list of input files (one per line)\n"
L"\n"
L" -w <n> width\n"
L" -h <n> height\n"
L" -m <n> miplevels\n"
L" -f <format> format\n"
L"\n"
L" -if <filter> image filtering\n"
L" -srgb{i|o} sRGB {input, output}\n"
L"\n"
L" -px <string> name prefix\n"
L" -sx <string> name suffix\n"
L" -o <directory> output directory\n"
L" -l force output filename to lower case\n"
L" -y overwrite existing output file (if any)\n"
L" -ft <filetype> output file type\n"
L"\n"
L" -hflip horizonal flip of source image\n"
L" -vflip vertical flip of source image\n"
L"\n"
L" -sepalpha resize/generate mips alpha channel separately\n"
L" from color channels\n"
L" -keepcoverage <ref> Preserve alpha coverage in mips for alpha test ref\n"
L"\n"
L" -nowic Force non-WIC filtering\n"
L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n"
L" -pmalpha convert final texture to use premultiplied alpha\n"
L" -alpha convert premultiplied alpha to straight alpha\n"
L" -at <threshold> Alpha threshold used for BC1, RGBA5551, and WIC\n"
L" (defaults to 0.5)\n");
wprintf(L"\n -fl <feature-level> Set maximum feature level target (defaults to 11.0)\n");
wprintf(L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n");
wprintf(
L"\n -nmap <options> converts height-map to normal-map\n"
L" (defaults to 0.5)\n"
L"\n"
L" -fl <feature-level> Set maximum feature level target (defaults to 11.0)\n"
L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n"
L"\n"
L" -nmap <options> converts height-map to normal-map\n"
L" options must be one or more of\n"
L" r, g, b, a, l, m, u, v, i, o\n");
wprintf(L" -nmapamp <weight> normal map amplitude (defaults to 1.0)\n");
wprintf(L"\n (DDS input only)\n");
wprintf(L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n");
wprintf(L" -dword Use DWORD instead of BYTE alignment\n");
wprintf(L" -badtails Fix for older DXTn with bad mipchain tails\n");
wprintf(L" -fixbc4x4 Fix for odd-sized BC files that Direct3D can't load\n");
wprintf(L" -xlum expand legacy L8, L16, and A8P8 formats\n");
wprintf(L"\n (DDS output only)\n");
wprintf(L" -dx10 Force use of 'DX10' extended header\n");
wprintf(L" -dx9 Force use of legacy DX9 header\n");
wprintf(L" -xbox Tile and use 'XBOX' variant of DDS\n");
wprintf(L" -xgmode <mode> Tile using provided memory layout mode\n");
wprintf(L"\n (TGA output only)\n");
wprintf(L" -tga20 Write file including TGA 2.0 extension area\n");
wprintf(L"\n (BMP, PNG, JPG, TIF, WDP output only)\n");
wprintf(L" -wicq <quality> When writing images with WIC use quality (0.0 to 1.0)\n");
wprintf(L" -wiclossless When writing images with WIC use lossless mode\n");
wprintf(L" -wicmulti When writing images with WIC encode multiframe images\n");
wprintf(L"\n -nologo suppress copyright message\n");
wprintf(L" -timing Display elapsed processing time\n\n");
L" r, g, b, a, l, m, u, v, i, o\n"
L" -nmapamp <weight> normal map amplitude (defaults to 1.0)\n"
L"\n"
L" (DDS input only)\n"
L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n"
L" -dword Use DWORD instead of BYTE alignment\n"
L" -badtails Fix for older DXTn with bad mipchain tails\n"
L" -fixbc4x4 Fix for odd-sized BC files that Direct3D can't load\n"
L" -xlum expand legacy L8, L16, and A8P8 formats\n"
L"\n"
L" (DDS output only)\n"
L" -dx10 Force use of 'DX10' extended header\n"
L" -dx9 Force use of legacy DX9 header\n"
L" -xbox Tile and use 'XBOX' variant of DDS\n"
L" -xgmode <mode> Tile using provided memory layout mode\n"
L"\n"
L" (TGA output only)\n"
L" -tga20 Write file including TGA 2.0 extension area\n"
L"\n"
L" (BMP, PNG, JPG, TIF, WDP output only)\n"
L" -wicq <quality> When writing images with WIC use quality (0.0 to 1.0)\n"
L" -wiclossless When writing images with WIC use lossless mode\n"
L" -wicmulti When writing images with WIC encode multiframe images\n"
L"\n"
L" -nologo suppress copyright message\n"
L" -timing Display elapsed processing time\n"
L"\n"
#ifdef _OPENMP
wprintf(L" -singleproc Do not use multi-threaded compression\n");
L" -singleproc Do not use multi-threaded compression\n"
#endif
wprintf(L" -gpu <adapter> Select GPU for DirectCompute-based codecs (0 is default)\n");
wprintf(L" -nogpu Do not use DirectCompute-based codecs\n");
wprintf(
L"\n -bc <options> Sets options for BC compression\n"
L" -gpu <adapter> Select GPU for DirectCompute-based codecs (0 is default)\n"
L" -nogpu Do not use DirectCompute-based codecs\n"
L"\n"
L" -bc <options> Sets options for BC compression\n"
L" options must be one or more of\n"
L" d, u, q, x\n");
wprintf(
L" d, u, q, x\n"
L" -aw <weight> BC7 GPU compressor weighting for alpha error metric\n"
L" (defaults to 1.0)\n");
wprintf(L"\n -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n");
wprintf(L" -rotatecolor <rot> rotates color primaries and/or applies a curve\n");
wprintf(L" -nits <value> paper-white value in nits to use for HDR10 (def: 200.0)\n");
wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n");
wprintf(L" -x2bias Enable *2 - 1 conversion cases for unorm/pos-only-float\n");
wprintf(L" -inverty Invert Y (i.e. green) channel values\n");
wprintf(L" -reconstructz Rebuild Z (blue) channel assuming X/Y are normals\n");
wprintf(L" -swizzle <rgba> Swizzle image channels using HLSL-style mask\n");
L" (defaults to 1.0)\n"
L"\n"
L" -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n"
L" -rotatecolor <rot> rotates color primaries and/or applies a curve\n"
L" -nits <value> paper-white value in nits to use for HDR10 (def: 200.0)\n"
L" -tonemap Apply a tonemap operator based on maximum luminance\n"
L" -x2bias Enable *2 - 1 conversion cases for unorm/pos-only-float\n"
L" -inverty Invert Y (i.e. green) channel values\n"
L" -reconstructz Rebuild Z (blue) channel assuming X/Y are normals\n"
L" -swizzle <rgba> Swizzle image channels using HLSL-style mask\n";
wprintf(L"%ls", s_usage);
wprintf(L"\n <format>: ");
PrintList(13, g_pFormats);
@ -2097,7 +2115,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
else if (_wcsicmp(ext, L".tga") == 0)
{
hr = LoadFromTGAFile(pConv->szSrc, TGA_FLAGS_NONE, &info, *image);
TGA_FLAGS tgaFlags = (IsBGR(format)) ? TGA_FLAGS_BGR : TGA_FLAGS_NONE;
hr = LoadFromTGAFile(pConv->szSrc, tgaFlags, &info, *image);
if (FAILED(hr))
{
wprintf(L" FAILED (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
@ -2909,7 +2929,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
{
case DXGI_FORMAT_BC4_SNORM:
case DXGI_FORMAT_BC5_SNORM:
nmfmt = DXGI_FORMAT_R8G8B8A8_SNORM;
nmfmt = (BitsPerColor(info.format) > 8) ? DXGI_FORMAT_R16G16B16A16_SNORM : DXGI_FORMAT_R8G8B8A8_SNORM;
break;
case DXGI_FORMAT_BC6H_SF16:
@ -2918,7 +2938,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
break;
default:
nmfmt = DXGI_FORMAT_R8G8B8A8_UNORM;
nmfmt = (BitsPerColor(info.format) > 8) ? DXGI_FORMAT_R16G16B16A16_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
break;
}
}