14 #if defined(_MSC_VER) && (_MSC_VER > 1000)
18 #include <directxmath.h>
19 #include <directxpackedvector.h>
32 XMGLOBALCONST XMVECTORF32
g_boxScale = { 0.25f, 0.25f, 0.25f, 0.25f };
33 XMGLOBALCONST XMVECTORF32
g_boxScale3D = { 0.125f, 0.125f, 0.125f, 0.125f };
35 #define AVERAGE4( res, p0, p1, p2, p3 ) \
37 XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
38 v = XMVectorAdd( v, (p2) ); \
39 v = XMVectorAdd( v, (p3) ); \
40 res = XMVectorMultiply( v, g_boxScale ); \
43 #define AVERAGE8( res, p0, p1, p2, p3, p4, p5, p6, p7) \
45 XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
46 v = XMVectorAdd( v, (p2) ); \
47 v = XMVectorAdd( v, (p3) ); \
48 v = XMVectorAdd( v, (p4) ); \
49 v = XMVectorAdd( v, (p5) ); \
50 v = XMVectorAdd( v, (p6) ); \
51 v = XMVectorAdd( v, (p7) ); \
52 res = XMVectorMultiply( v, g_boxScale3D ); \
74 float scale = float(source) / float(dest);
78 for(
size_t u = 0; u <
dest; ++u )
80 float srcB = ( float(u) + 0.5f ) * scale + 0.5f;
82 ptrdiff_t isrcB = ptrdiff_t(srcB);
83 ptrdiff_t isrcA = isrcB - 1;
87 isrcA = ( wrap ) ? ( source - 1) : 0;
90 if (
size_t(isrcB) >= source )
92 isrcB = ( wrap ) ? 0 : ( source - 1);
95 float weight = 1.0f + float(isrcB) - srcB;
97 auto& entry = lf[ u ];
98 entry.u0 = size_t(isrcA);
99 entry.weight0 = weight;
101 entry.u1 = size_t(isrcB);
102 entry.weight1 = 1.0f - weight;
106 #define BILINEAR_INTERPOLATE( res, x, y, r0, r1 ) \
107 res = ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
108 + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) )
110 #define TRILINEAR_INTERPOLATE( res, x, y, z, r0, r1, r2, r3 ) \
111 res = ( z.weight0 * ( ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
112 + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) ) ) ) \
113 + ( z.weight1 * ( ( y.weight0 * ( (r2)[ x.u0 ] * x.weight0 + (r2)[ x.u1 ] * x.weight1 ) ) \
114 + ( y.weight1 * ( (r3)[ x.u0 ] * x.weight0 + (r3)[ x.u1 ] * x.weight1 ) ) ) )
121 XMGLOBALCONST XMVECTORF32
g_cubicThird = { 1.f/3.f, 1.f/3.f, 1.f/3.f, 1.f/3.f };
122 XMGLOBALCONST XMVECTORF32
g_cubicSixth = { 1.f/6.f, 1.f/6.f, 1.f/6.f, 1.f/6.f };
123 XMGLOBALCONST XMVECTORF32
g_cubicHalf = { 1.f/2.f, 1.f/2.f, 1.f/2.f, 1.f/2.f };
125 inline ptrdiff_t
bounduvw( ptrdiff_t u, ptrdiff_t maxu,
bool wrap,
bool mirror )
146 u = maxu - (u - maxu - 1);
151 u = std::min<ptrdiff_t>( u, maxu );
152 u = std::max<ptrdiff_t>( u, 0 );
172 float scale = float(source) / float(dest);
174 for(
size_t u = 0; u <
dest; ++u )
176 float srcB = ( float(u) + 0.5f ) * scale - 0.5f;
178 ptrdiff_t isrcB =
bounduvw( ptrdiff_t(srcB), source - 1, wrap, mirror );
179 ptrdiff_t isrcA =
bounduvw( isrcB - 1, source - 1, wrap, mirror );
180 ptrdiff_t isrcC =
bounduvw( isrcB + 1, source - 1, wrap, mirror );
181 ptrdiff_t isrcD =
bounduvw( isrcB + 2, source - 1, wrap, mirror );
183 auto& entry = cf[ u ];
184 entry.u0 = size_t(isrcA);
185 entry.u1 = size_t(isrcB);
186 entry.u2 = size_t(isrcC);
187 entry.u3 = size_t(isrcD);
189 float x = srcB - float(isrcB);
194 #define CUBIC_INTERPOLATE( res, dx, p0, p1, p2, p3 ) \
196 XMVECTOR a0 = (p1); \
197 XMVECTOR d0 = (p0) - a0; \
198 XMVECTOR d2 = (p2) - a0; \
199 XMVECTOR d3 = (p3) - a0; \
200 XMVECTOR a1 = d2 - g_cubicThird*d0 - g_cubicSixth*d3; \
201 XMVECTOR a2 = g_cubicHalf*d0 + g_cubicHalf*d2; \
202 XMVECTOR a3 = g_cubicSixth*d3 - g_cubicSixth*d0 - g_cubicHalf*d2; \
203 XMVECTOR vdx = XMVectorReplicate( dx ); \
204 XMVECTOR vdx2 = vdx * vdx; \
205 XMVECTOR vdx3 = vdx2 * vdx; \
206 res = a0 + a1*vdx + a2*vdx2 + a3*vdx3; \
214 namespace TriangleFilter
251 inline HRESULT
_Create( _In_
size_t source, _In_
size_t dest, _In_
bool wrap, _Inout_ std::unique_ptr<Filter>& tf )
256 float scale = float(dest) / float(source);
257 float scaleInv = 0.5f / scale;
261 float repeat = (wrap) ? 1.f : 0.f;
263 for(
size_t u = 0; u < source; ++u )
265 float src = float(u) - 0.5f;
266 float destMin = src * scale;
267 float destMax = destMin + scale;
269 totalSize +=
TF_FROM_SIZE + TF_TO_SIZE + size_t( destMax - destMin + repeat + 1.f ) * TF_TO_SIZE * 2;
277 if ( tf->totalSize >= totalSize )
279 pFilter =
reinterpret_cast<uint8_t*
>( tf.get() );
291 pFilter =
new (std::nothrow)
uint8_t[ totalSize ];
293 return E_OUTOFMEMORY;
295 tf.reset( reinterpret_cast<Filter*>( pFilter ) );
296 tf->totalSize = totalSize;
304 float accumWeight = 0.f;
306 for(
size_t u = 0; u < source; ++u )
309 size_t sizeFrom = sizeInBytes;
310 auto pFrom =
reinterpret_cast<FilterFrom*
>( pFilter + sizeInBytes );
313 if ( sizeInBytes > totalSize )
319 for(
size_t j = 0; j < 2; ++j )
321 float src = float( u + j ) - 0.5f;
323 float destMin = src * scale;
324 float destMax = destMin + scale;
331 if ( destMax >
float(dest) )
332 destMax = float(dest);
335 for(
auto k = static_cast<ptrdiff_t>( floorf( destMin ) ); float(k) < destMax; ++k )
344 u0 = size_t( k + ptrdiff_t(dest) );
346 else if ( k >= ptrdiff_t(dest) )
349 u0 = size_t( k - ptrdiff_t(dest) );
361 auto pTo =
reinterpret_cast<FilterTo*
>( pFilter + sizeInBytes );
365 if ( sizeInBytes > totalSize )
369 pTo->weight = accumWeight;
385 if ( !wrap && src < 0.f )
387 else if ( !wrap && ( ( src + 1.f ) >=
float(source) ) )
390 weight = (d0 + d1) * scaleInv - src;
392 accumWeight += (d1 - d0) * ( j ? (1.f - weight) : weight );
399 auto pTo =
reinterpret_cast<FilterTo*
>( pFilter + sizeInBytes );
403 if ( sizeInBytes > totalSize )
407 pTo->weight = accumWeight;
413 pFrom->count = toCount;
414 pFrom->sizeInBytes = sizeInBytes - sizeFrom;
417 tf->sizeInBytes = sizeInBytes;
std::unique_ptr< DirectX::XMVECTOR, aligned_deleter > ScopedAlignedArrayXMVECTOR
static const size_t TF_TO_SIZE
static const float TF_EPSILON
size_t _In_ DXGI_FORMAT size_t _In_ TEXP_LEGACY_FORMAT _In_ DWORD flags assert(pDestination &&outSize > 0)
static const size_t TF_FROM_SIZE
XMGLOBALCONST XMVECTORF32 g_cubicSixth
void _CreateCubicFilter(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _In_ bool mirror, _Out_writes_(dest) CubicFilter *cf)
XMGLOBALCONST XMVECTORF32 g_boxScale
XMGLOBALCONST XMVECTORF32 g_cubicThird
HRESULT _Create(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Inout_ std::unique_ptr< Filter > &tf)
XMGLOBALCONST XMVECTORF32 g_boxScale3D
_In_ size_t _In_ const TexMetadata _In_ DWORD _Out_writes_(nImages) Image *images
XMGLOBALCONST XMVECTORF32 g_cubicHalf
static const size_t TF_FILTER_SIZE
ScopedAlignedArrayXMVECTOR scanline
ptrdiff_t bounduvw(ptrdiff_t u, ptrdiff_t maxu, bool wrap, bool mirror)
void _CreateLinearFilter(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter *lf)