20 using Microsoft::WRL::ComPtr;
28 inline static bool ispow2( _In_
size_t x )
30 return ((x != 0) && !(x & (x - 1)));
35 static size_t _CountMips( _In_
size_t width, _In_
size_t height )
39 while ( height > 1 || width > 1 )
58 if ( mipLevels > maxMips )
61 else if ( mipLevels == 0 )
74 static size_t _CountMips3D( _In_
size_t width, _In_
size_t height, _In_
size_t depth )
78 while ( height > 1 || width > 1 || depth > 1 )
95 bool _CalculateMipLevels3D( _In_
size_t width, _In_
size_t height, _In_
size_t depth, _Inout_
size_t& mipLevels )
100 if ( mipLevels > maxMips )
103 else if ( mipLevels == 0 )
119 _In_
const WICPixelFormatGUID& desiredPixelFormat,
120 _Deref_out_ IWICBitmap**
dest )
122 if ( !pWIC || !src || !dest )
127 WICPixelFormatGUID actualPixelFormat;
128 HRESULT hr = src->GetPixelFormat( &actualPixelFormat );
132 if ( memcmp( &actualPixelFormat, &desiredPixelFormat,
sizeof(WICPixelFormatGUID) ) == 0 )
139 ComPtr<IWICFormatConverter> converter;
140 hr = pWIC->CreateFormatConverter( converter.GetAddressOf() );
143 hr = converter->Initialize( src, desiredPixelFormat,
_GetWICDither(filter), 0, 0, WICBitmapPaletteTypeCustom );
148 hr = pWIC->CreateBitmapFromSource( converter.Get(), WICBitmapCacheOnDemand,
dest );
159 _In_
size_t newWidth, _In_
size_t newHeight, _In_ DWORD filter, _Inout_
const Image* img )
161 if ( !pWIC || !original || !img )
164 const WICBitmapInterpolationMode interpolationMode =
_GetWICInterp(filter);
166 WICPixelFormatGUID desiredPixelFormat = GUID_WICPixelFormatUndefined;
167 HRESULT hr = original->GetPixelFormat( &desiredPixelFormat );
169 size_t colorBytesInPixel = 0;
170 size_t colorBytesPerPixel = 0;
171 size_t colorWithAlphaBytesPerPixel = 0;
172 WICPixelFormatGUID colorPixelFormat = GUID_WICPixelFormatUndefined;
173 WICPixelFormatGUID colorWithAlphaPixelFormat = GUID_WICPixelFormatUndefined;
177 ComPtr<IWICComponentInfo> componentInfo;
178 hr = pWIC->CreateComponentInfo( desiredPixelFormat, componentInfo.GetAddressOf() );
180 ComPtr<IWICPixelFormatInfo> pixelFormatInfo;
183 hr = componentInfo.As( &pixelFormatInfo );
186 UINT bitsPerPixel = 0;
189 hr = pixelFormatInfo->GetBitsPerPixel( &bitsPerPixel );
194 if ( bitsPerPixel <= 32 )
196 colorBytesInPixel = colorBytesPerPixel = 3;
197 colorPixelFormat = GUID_WICPixelFormat24bppBGR;
199 colorWithAlphaBytesPerPixel = 4;
200 colorWithAlphaPixelFormat = GUID_WICPixelFormat32bppBGRA;
204 #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
207 colorBytesInPixel = colorBytesPerPixel = 12;
208 colorPixelFormat = GUID_WICPixelFormat96bppRGBFloat;
213 colorBytesInPixel = 12;
214 colorBytesPerPixel = 16;
215 colorPixelFormat = GUID_WICPixelFormat128bppRGBFloat;
218 colorWithAlphaBytesPerPixel = 16;
219 colorWithAlphaPixelFormat = GUID_WICPixelFormat128bppRGBAFloat;
225 ComPtr<IWICBitmap> resizedColor;
228 ComPtr<IWICBitmapScaler> colorScaler;
229 hr = pWIC->CreateBitmapScaler( colorScaler.GetAddressOf() );
232 ComPtr<IWICBitmap> converted;
236 hr = colorScaler->Initialize( converted.Get(),
static_cast<UINT
>(newWidth), static_cast<UINT>(newHeight), interpolationMode );
242 ComPtr<IWICBitmap> resized;
243 hr = pWIC->CreateBitmapFromSource( colorScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf() );
252 ComPtr<IWICBitmap> resizedColorWithAlpha;
255 ComPtr<IWICBitmapScaler> colorWithAlphaScaler;
256 hr = pWIC->CreateBitmapScaler( colorWithAlphaScaler.GetAddressOf() );
259 ComPtr<IWICBitmap> converted;
263 hr = colorWithAlphaScaler->Initialize( converted.Get(),
static_cast<UINT
>(newWidth), static_cast<UINT>(newHeight), interpolationMode );
269 ComPtr<IWICBitmap> resized;
270 hr = pWIC->CreateBitmapFromSource( colorWithAlphaScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf() );
281 ComPtr<IWICBitmapLock> colorLock;
282 ComPtr<IWICBitmapLock> colorWithAlphaLock;
283 hr = resizedColor->Lock(
nullptr, WICBitmapLockRead, colorLock.GetAddressOf() );
286 hr = resizedColorWithAlpha->Lock(
nullptr, WICBitmapLockWrite, colorWithAlphaLock.GetAddressOf() );
291 WICInProcPointer colorWithAlphaData =
nullptr;
292 UINT colorWithAlphaSizeInBytes = 0;
293 UINT colorWithAlphaStride = 0;
295 hr = colorWithAlphaLock->GetDataPointer( &colorWithAlphaSizeInBytes, &colorWithAlphaData );
298 if ( !colorWithAlphaData )
304 hr = colorWithAlphaLock->GetStride( &colorWithAlphaStride );
308 WICInProcPointer colorData =
nullptr;
309 UINT colorSizeInBytes = 0;
310 UINT colorStride = 0;
313 hr = colorLock->GetDataPointer( &colorSizeInBytes, &colorData );
322 hr = colorLock->GetStride( &colorStride );
327 for (
size_t j = 0; SUCCEEDED(hr) && j < newHeight; j++ )
329 for (
size_t i = 0; SUCCEEDED(hr) && i < newWidth; i++ )
331 size_t colorWithAlphaIndex = (j * colorWithAlphaStride) + (i * colorWithAlphaBytesPerPixel);
332 size_t colorIndex = (j * colorStride) + (i * colorBytesPerPixel);
334 if ( ((colorWithAlphaIndex + colorBytesInPixel) > colorWithAlphaSizeInBytes)
335 || ( (colorIndex + colorBytesPerPixel) > colorSizeInBytes) )
341 #pragma warning( suppress : 26014 6386 ) // No overflow possible here
342 memcpy_s( colorWithAlphaData + colorWithAlphaIndex, colorWithAlphaBytesPerPixel, colorData + colorIndex, colorBytesInPixel );
351 ComPtr<IWICBitmap> wicBitmap;
355 hr = wicBitmap->CopyPixels(
nullptr, static_cast<UINT>(img->rowPitch), static_cast<UINT>(img->slicePitch), img->pixels );
384 static_assert(
TEX_FILTER_POINT == 0x100000,
"TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
427 _In_
const WICPixelFormatGUID& pfGUID, _In_
const ScratchImage& mipChain, _In_
size_t item )
431 if ( !baseImage.pixels || !mipChain.GetPixels() )
434 IWICImagingFactory* pWIC =
_GetWIC();
436 return E_NOINTERFACE;
438 size_t width = baseImage.width;
439 size_t height = baseImage.height;
441 ComPtr<IWICBitmap> source;
442 HRESULT hr = pWIC->CreateBitmapFromMemory( static_cast<UINT>( width ), static_cast<UINT>( height ), pfGUID,
443 static_cast<UINT>( baseImage.rowPitch ), static_cast<UINT>( baseImage.slicePitch ),
444 baseImage.pixels, source.GetAddressOf() );
449 const Image *img0 = mipChain.GetImage( 0, item, 0 );
457 const uint8_t *pSrc = baseImage.pixels;
458 for(
size_t h=0; h < height; ++h )
460 size_t msize = std::min<size_t>( img0->
rowPitch, baseImage.rowPitch );
461 memcpy_s( pDest, img0->
rowPitch, pSrc, msize );
462 pSrc += baseImage.rowPitch;
466 ComPtr<IWICComponentInfo> componentInfo;
467 hr = pWIC->CreateComponentInfo( pfGUID, componentInfo.GetAddressOf() );
471 ComPtr<IWICPixelFormatInfo2> pixelFormatInfo;
472 hr = componentInfo.As( &pixelFormatInfo );
476 BOOL supportsTransparency = FALSE;
477 hr = pixelFormatInfo->SupportsTransparency( &supportsTransparency );
482 for(
size_t level = 1; level < levels; ++level )
484 const Image *img = mipChain.GetImage( level, item, 0 );
504 ComPtr<IWICBitmapScaler> scaler;
505 hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() );
509 hr = scaler->Initialize( source.Get(),
static_cast<UINT
>( width ), static_cast<UINT>( height ),
_GetWICInterp( filter ) );
513 WICPixelFormatGUID pfScaler;
514 hr = scaler->GetPixelFormat( &pfScaler );
518 if ( memcmp( &pfScaler, &pfGUID,
sizeof(WICPixelFormatGUID) ) == 0 )
520 hr = scaler->CopyPixels( 0, static_cast<UINT>( img->
rowPitch ), static_cast<UINT>( img->
slicePitch ), img->
pixels );
528 ComPtr<IWICFormatConverter> FC;
529 hr = pWIC->CreateFormatConverter( FC.GetAddressOf() );
533 hr = FC->Initialize( scaler.Get(), pfGUID,
_GetWICDither( filter ), 0, 0, WICBitmapPaletteTypeCustom );
554 if ( !baseImages || !nimages )
557 assert( mdata.mipLevels > 1 );
558 assert( mdata.arraySize == nimages );
560 assert( mdata.width == baseImages[0].width );
561 assert( mdata.height == baseImages[0].height );
562 assert( mdata.format == baseImages[0].format );
564 HRESULT hr = mipChain.Initialize( mdata );
569 for(
size_t item=0; item < nimages; ++item )
571 const Image& src = baseImages[item];
573 const Image *
dest = mipChain.GetImage( 0, item, 0 );
591 for(
size_t h=0; h < mdata.height; ++h )
593 size_t msize = std::min<size_t>( dest->
rowPitch, rowPitch );
594 memcpy_s( pDest, dest->
rowPitch, pSrc, msize );
606 if ( !mipChain.GetImages() )
613 size_t width = mipChain.GetMetadata().width;
614 size_t height = mipChain.GetMetadata().height;
619 return E_OUTOFMEMORY;
621 XMVECTOR* target = scanline.get();
623 XMVECTOR* row = target + width;
626 for(
size_t level=1; level < levels; ++level )
629 memset( row, 0xCD,
sizeof(XMVECTOR)*width );
633 const Image* src = mipChain.GetImage( level-1, item, 0 );
634 const Image*
dest = mipChain.GetImage( level, item, 0 );
644 size_t nwidth = (width > 1) ? (width >> 1) : 1;
645 size_t nheight = (height > 1) ? (height >> 1) : 1;
647 size_t xinc = ( width << 16 ) / nwidth;
648 size_t yinc = ( height << 16 ) / nheight;
650 size_t lasty = size_t(-1);
653 for(
size_t y = 0;
y < nheight; ++
y )
655 if ( (lasty ^ sy) >> 16 )
657 if ( !
_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->
format ) )
663 for(
size_t x = 0; x < nwidth; ++x )
665 target[ x ] = row[ sx >> 16 ];
690 if ( !mipChain.GetImages() )
697 size_t width = mipChain.GetMetadata().width;
698 size_t height = mipChain.GetMetadata().height;
706 return E_OUTOFMEMORY;
708 XMVECTOR* target = scanline.get();
710 XMVECTOR* urow0 = target + width;
711 XMVECTOR* urow1 = target + width*2;
713 const XMVECTOR* urow2 = urow0 + 1;
714 const XMVECTOR* urow3 = urow1 + 1;
717 for(
size_t level=1; level < levels; ++level )
731 const Image* src = mipChain.GetImage( level-1, item, 0 );
732 const Image*
dest = mipChain.GetImage( level, item, 0 );
742 size_t nwidth = (width > 1) ? (width >> 1) : 1;
743 size_t nheight = (height > 1) ? (height >> 1) : 1;
745 for(
size_t y = 0;
y < nheight; ++
y )
751 if ( urow0 != urow1 )
758 for(
size_t x = 0; x < nwidth; ++x )
762 AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] );
784 if ( !mipChain.GetImages() )
791 size_t width = mipChain.GetMetadata().width;
792 size_t height = mipChain.GetMetadata().height;
797 return E_OUTOFMEMORY;
799 std::unique_ptr<LinearFilter[]> lf(
new (std::nothrow)
LinearFilter[ width+height ] );
801 return E_OUTOFMEMORY;
806 XMVECTOR* target = scanline.get();
808 XMVECTOR* row0 = target + width;
809 XMVECTOR* row1 = target + width*2;
812 for(
size_t level=1; level < levels; ++level )
815 const Image* src = mipChain.GetImage( level-1, item, 0 );
816 const Image*
dest = mipChain.GetImage( level, item, 0 );
826 size_t nwidth = (width > 1) ? (width >> 1) : 1;
829 size_t nheight = (height > 1) ? (height >> 1) : 1;
833 memset( row0, 0xCD,
sizeof(XMVECTOR)*width );
834 memset( row1, 0xDD,
sizeof(XMVECTOR)*width );
837 size_t u0 = size_t(-1);
838 size_t u1 = size_t(-1);
840 for(
size_t y = 0;
y < nheight; ++
y )
842 auto& toY = lfY[
y ];
858 std::swap( row0, row1 );
870 for(
size_t x = 0; x < nwidth; ++x )
872 auto& toX = lfX[ x ];
896 if ( !mipChain.GetImages() )
903 size_t width = mipChain.GetMetadata().width;
904 size_t height = mipChain.GetMetadata().height;
909 return E_OUTOFMEMORY;
911 std::unique_ptr<CubicFilter[]> cf(
new (std::nothrow)
CubicFilter[ width+height ] );
913 return E_OUTOFMEMORY;
918 XMVECTOR* target = scanline.get();
920 XMVECTOR* row0 = target + width;
921 XMVECTOR* row1 = target + width*2;
922 XMVECTOR* row2 = target + width*3;
923 XMVECTOR* row3 = target + width*4;
926 for(
size_t level=1; level < levels; ++level )
929 const Image* src = mipChain.GetImage( level-1, item, 0 );
930 const Image*
dest = mipChain.GetImage( level, item, 0 );
940 size_t nwidth = (width > 1) ? (width >> 1) : 1;
943 size_t nheight = (height > 1) ? (height >> 1) : 1;
947 memset( row0, 0xCD,
sizeof(XMVECTOR)*width );
948 memset( row1, 0xDD,
sizeof(XMVECTOR)*width );
949 memset( row2, 0xED,
sizeof(XMVECTOR)*width );
950 memset( row3, 0xFD,
sizeof(XMVECTOR)*width );
953 size_t u0 = size_t(-1);
954 size_t u1 = size_t(-1);
955 size_t u2 = size_t(-1);
956 size_t u3 = size_t(-1);
958 for(
size_t y = 0;
y < nheight; ++
y )
960 auto& toY = cfY[
y ];
965 if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 )
972 else if ( toY.u0 == u1 )
977 std::swap( row0, row1 );
979 else if ( toY.u0 == u2 )
984 std::swap( row0, row2 );
986 else if ( toY.u0 == u3 )
991 std::swap( row0, row3 );
998 if ( toY.u1 != u2 && toY.u1 != u3 )
1005 else if ( toY.u1 == u2 )
1010 std::swap( row1, row2 );
1012 else if ( toY.u1 == u3 )
1017 std::swap( row1, row3 );
1036 std::swap( row2, row3 );
1049 for(
size_t x = 0; x < nwidth; ++x )
1051 auto& toX = cfX[ x ];
1053 XMVECTOR C0, C1, C2, C3;
1055 CUBIC_INTERPOLATE( C0, toX.x, row0[ toX.u0 ], row0[ toX.u1 ], row0[ toX.u2 ], row0[ toX.u3 ] );
1056 CUBIC_INTERPOLATE( C1, toX.x, row1[ toX.u0 ], row1[ toX.u1 ], row1[ toX.u2 ], row1[ toX.u3 ] );
1057 CUBIC_INTERPOLATE( C2, toX.x, row2[ toX.u0 ], row2[ toX.u1 ], row2[ toX.u2 ], row2[ toX.u3 ] );
1058 CUBIC_INTERPOLATE( C3, toX.x, row3[ toX.u0 ], row3[ toX.u1 ], row3[ toX.u2 ], row3[ toX.u3 ] );
1082 if ( !mipChain.GetImages() )
1083 return E_INVALIDARG;
1085 using namespace TriangleFilter;
1091 size_t width = mipChain.GetMetadata().width;
1092 size_t height = mipChain.GetMetadata().height;
1097 return E_OUTOFMEMORY;
1099 std::unique_ptr<TriangleRow[]> rowActive(
new (std::nothrow) TriangleRow[ height ] );
1101 return E_OUTOFMEMORY;
1103 TriangleRow * rowFree =
nullptr;
1105 std::unique_ptr<Filter> tfX, tfY;
1107 XMVECTOR* row = scanline.get();
1110 for(
size_t level=1; level < levels; ++level )
1113 const Image* src = mipChain.GetImage( level-1, item, 0 );
1114 const Image*
dest = mipChain.GetImage( level, item, 0 );
1116 if ( !src || !dest )
1121 const uint8_t* pEndSrc = pSrc + rowPitch * height;
1125 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1130 size_t nheight = (height > 1) ? (height >> 1) : 1;
1136 memset( row, 0xCD,
sizeof(XMVECTOR)*width );
1139 auto xFromEnd =
reinterpret_cast<const FilterFrom*
>(
reinterpret_cast<const uint8_t*
>( tfX.get() ) + tfX->sizeInBytes );
1140 auto yFromEnd =
reinterpret_cast<const FilterFrom*
>(
reinterpret_cast<const uint8_t*
>( tfY.get() ) + tfY->sizeInBytes );
1143 for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; )
1145 for (
size_t j = 0; j < yFrom->count; ++j )
1147 size_t v = yFrom->to[ j ].u;
1149 TriangleRow* rowAcc = &rowActive.get()[ v ];
1151 ++rowAcc->remaining;
1153 if ( rowAcc->scanline )
1155 memset( rowAcc->scanline.get(), 0,
sizeof(XMVECTOR) * nwidth );
1159 yFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( yFrom ) + yFrom->sizeInBytes );
1163 for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; )
1166 for (
size_t j = 0; j < yFrom->count; ++j )
1168 size_t v = yFrom->to[ j ].u;
1170 TriangleRow* rowAcc = &rowActive.get()[ v ];
1172 if ( !rowAcc->scanline )
1178 assert( rowFree->scanline != 0 );
1179 rowAcc->scanline.reset( rowFree->scanline.release() );
1180 rowFree = rowFree->next;
1184 rowAcc->scanline.reset( reinterpret_cast<XMVECTOR*>( _aligned_malloc(
sizeof(XMVECTOR) * nwidth, 16 ) ) );
1185 if ( !rowAcc->scanline )
1186 return E_OUTOFMEMORY;
1189 memset( rowAcc->scanline.get(), 0,
sizeof(XMVECTOR) * nwidth );
1194 if ( (pSrc + rowPitch) > pEndSrc )
1204 for( FilterFrom* xFrom = tfX->from; xFrom < xFromEnd; ++x )
1206 for (
size_t j = 0; j < yFrom->count; ++j )
1208 size_t v = yFrom->to[ j ].u;
1210 float yweight = yFrom->to[ j ].weight;
1212 XMVECTOR* accPtr = rowActive[ v ].scanline.get();
1216 for (
size_t k = 0; k < xFrom->count; ++k )
1218 size_t u = xFrom->to[ k ].u;
1221 XMVECTOR weight = XMVectorReplicate( yweight * xFrom->to[ k ].weight );
1224 accPtr[ u ] = XMVectorMultiplyAdd( row[ x ], weight, accPtr[ u ] );
1228 xFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( xFrom ) + xFrom->sizeInBytes );
1232 for (
size_t j = 0; j < yFrom->count; ++j )
1234 size_t v = yFrom->to[ j ].u;
1236 TriangleRow* rowAcc = &rowActive.get()[ v ];
1238 assert( rowAcc->remaining > 0 );
1239 --rowAcc->remaining;
1241 if ( !rowAcc->remaining )
1243 XMVECTOR* pAccSrc = rowAcc->scanline.get();
1249 case DXGI_FORMAT_R10G10B10A2_UNORM:
1250 case DXGI_FORMAT_R10G10B10A2_UINT:
1254 static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f };
1256 XMVECTOR* ptr = pAccSrc;
1257 for(
size_t i=0; i < dest->
width; ++i, ++ptr )
1259 *ptr = XMVectorAdd( *ptr, Bias );
1270 rowAcc->next = rowFree;
1275 yFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( yFrom ) + yFrom->sizeInBytes );
1295 if ( !baseImages || !depth )
1296 return E_INVALIDARG;
1300 size_t width = baseImages[0].width;
1301 size_t height = baseImages[0].height;
1303 HRESULT hr = mipChain.Initialize3D( baseImages[0].
format, width, height, depth, levels );
1308 for(
size_t slice=0; slice < depth; ++slice )
1310 const Image& src = baseImages[slice];
1312 const Image *
dest = mipChain.GetImage( 0, 0, slice );
1330 for(
size_t h=0; h < height; ++h )
1332 size_t msize = std::min<size_t>( dest->
rowPitch, rowPitch );
1333 memcpy_s( pDest, dest->
rowPitch, pSrc, msize );
1346 if ( !depth || !mipChain.GetImages() )
1347 return E_INVALIDARG;
1353 size_t width = mipChain.GetMetadata().width;
1354 size_t height = mipChain.GetMetadata().height;
1359 return E_OUTOFMEMORY;
1361 XMVECTOR* target = scanline.get();
1363 XMVECTOR* row = target + width;
1366 for(
size_t level=1; level < levels; ++level )
1369 memset( row, 0xCD,
sizeof(XMVECTOR)*width );
1375 size_t ndepth = depth >> 1;
1377 size_t zinc = ( depth << 16 ) / ndepth;
1380 for(
size_t slice=0; slice < ndepth; ++slice )
1382 const Image* src = mipChain.GetImage( level-1, 0, (sz >> 16) );
1383 const Image*
dest = mipChain.GetImage( level, 0, slice );
1385 if ( !src || !dest )
1393 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1394 size_t nheight = (height > 1) ? (height >> 1) : 1;
1396 size_t xinc = ( width << 16 ) / nwidth;
1397 size_t yinc = ( height << 16 ) / nheight;
1399 size_t lasty = size_t(-1);
1402 for(
size_t y = 0;
y < nheight; ++
y )
1404 if ( (lasty ^ sy) >> 16 )
1406 if ( !
_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->
format ) )
1412 for(
size_t x = 0; x < nwidth; ++x )
1414 target[ x ] = row[ sx >> 16 ];
1431 const Image* src = mipChain.GetImage( level-1, 0, 0 );
1432 const Image*
dest = mipChain.GetImage( level, 0, 0 );
1434 if ( !src || !dest )
1442 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1443 size_t nheight = (height > 1) ? (height >> 1) : 1;
1445 size_t xinc = ( width << 16 ) / nwidth;
1446 size_t yinc = ( height << 16 ) / nheight;
1448 size_t lasty = size_t(-1);
1451 for(
size_t y = 0;
y < nheight; ++
y )
1453 if ( (lasty ^ sy) >> 16 )
1455 if ( !
_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->
format ) )
1461 for(
size_t x = 0; x < nwidth; ++x )
1463 target[ x ] = row[ sx >> 16 ];
1492 if ( !depth || !mipChain.GetImages() )
1493 return E_INVALIDARG;
1499 size_t width = mipChain.GetMetadata().width;
1500 size_t height = mipChain.GetMetadata().height;
1508 return E_OUTOFMEMORY;
1510 XMVECTOR* target = scanline.get();
1512 XMVECTOR* urow0 = target + width;
1513 XMVECTOR* urow1 = target + width*2;
1514 XMVECTOR* vrow0 = target + width*3;
1515 XMVECTOR* vrow1 = target + width*4;
1517 const XMVECTOR* urow2 = urow0 + 1;
1518 const XMVECTOR* urow3 = urow1 + 1;
1519 const XMVECTOR* vrow2 = vrow0 + 1;
1520 const XMVECTOR* vrow3 = vrow1 + 1;
1523 for(
size_t level=1; level < levels; ++level )
1542 size_t ndepth = depth >> 1;
1544 for(
size_t slice=0; slice < ndepth; ++slice )
1546 size_t slicea = std::min<size_t>( slice * 2, depth-1 );
1547 size_t sliceb = std::min<size_t>( slicea + 1, depth-1 );
1549 const Image* srca = mipChain.GetImage( level-1, 0, slicea );
1550 const Image* srcb = mipChain.GetImage( level-1, 0, sliceb );
1551 const Image*
dest = mipChain.GetImage( level, 0, slice );
1553 if ( !srca || !srcb || !dest )
1556 const uint8_t* pSrc1 = srca->pixels;
1560 size_t aRowPitch = srca->rowPitch;
1563 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1564 size_t nheight = (height > 1) ? (height >> 1) : 1;
1566 for(
size_t y = 0;
y < nheight; ++
y )
1572 if ( urow0 != urow1 )
1583 if ( vrow0 != vrow1 )
1590 for(
size_t x = 0; x < nwidth; ++x )
1594 AVERAGE8( target[x], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ],
1595 vrow0[ x2 ], vrow1[ x2 ], vrow2[ x2 ], vrow3[ x2 ] );
1607 const Image* src = mipChain.GetImage( level-1, 0, 0 );
1608 const Image*
dest = mipChain.GetImage( level, 0, 0 );
1610 if ( !src || !dest )
1618 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1619 size_t nheight = (height > 1) ? (height >> 1) : 1;
1621 for(
size_t y = 0;
y < nheight; ++
y )
1627 if ( urow0 != urow1 )
1634 for(
size_t x = 0; x < nwidth; ++x )
1638 AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] );
1664 if ( !depth || !mipChain.GetImages() )
1665 return E_INVALIDARG;
1671 size_t width = mipChain.GetMetadata().width;
1672 size_t height = mipChain.GetMetadata().height;
1677 return E_OUTOFMEMORY;
1679 std::unique_ptr<LinearFilter[]> lf(
new (std::nothrow)
LinearFilter[ width+height+depth ] );
1681 return E_OUTOFMEMORY;
1687 XMVECTOR* target = scanline.get();
1689 XMVECTOR* urow0 = target + width;
1690 XMVECTOR* urow1 = target + width*2;
1691 XMVECTOR* vrow0 = target + width*3;
1692 XMVECTOR* vrow1 = target + width*4;
1695 for(
size_t level=1; level < levels; ++level )
1697 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1700 size_t nheight = (height > 1) ? (height >> 1) : 1;
1704 memset( urow0, 0xCD,
sizeof(XMVECTOR)*width );
1705 memset( urow1, 0xDD,
sizeof(XMVECTOR)*width );
1706 memset( vrow0, 0xED,
sizeof(XMVECTOR)*width );
1707 memset( vrow1, 0xFD,
sizeof(XMVECTOR)*width );
1713 size_t ndepth = depth >> 1;
1716 for(
size_t slice=0; slice < ndepth; ++slice )
1718 auto& toZ = lfZ[ slice ];
1720 const Image* srca = mipChain.GetImage( level-1, 0, toZ.u0 );
1721 const Image* srcb = mipChain.GetImage( level-1, 0, toZ.u1 );
1722 if ( !srca || !srcb )
1725 size_t u0 = size_t(-1);
1726 size_t u1 = size_t(-1);
1728 const Image*
dest = mipChain.GetImage( level, 0, slice );
1734 for(
size_t y = 0;
y < nheight; ++
y )
1736 auto& toY = lfY[
y ];
1753 std::swap( urow0, urow1 );
1754 std::swap( vrow0, vrow1 );
1767 for(
size_t x = 0; x < nwidth; ++x )
1769 auto& toX = lfX[ x ];
1783 const Image* src = mipChain.GetImage( level-1, 0, 0 );
1784 const Image*
dest = mipChain.GetImage( level, 0, 0 );
1786 if ( !src || !dest )
1794 size_t u0 = size_t(-1);
1795 size_t u1 = size_t(-1);
1797 for(
size_t y = 0;
y < nheight; ++
y )
1799 auto& toY = lfY[
y ];
1815 std::swap( urow0, urow1 );
1827 for(
size_t x = 0; x < nwidth; ++x )
1829 auto& toX = lfX[ x ];
1857 if ( !depth || !mipChain.GetImages() )
1858 return E_INVALIDARG;
1864 size_t width = mipChain.GetMetadata().width;
1865 size_t height = mipChain.GetMetadata().height;
1870 return E_OUTOFMEMORY;
1872 std::unique_ptr<CubicFilter[]> cf(
new (std::nothrow)
CubicFilter[ width+height+depth ] );
1874 return E_OUTOFMEMORY;
1880 XMVECTOR* target = scanline.get();
1887 XMVECTOR *ptr = scanline.get() + width;
1888 for(
size_t j = 0; j < 4; ++j )
1890 urow[j] = ptr; ptr += width;
1891 vrow[j] = ptr; ptr += width;
1892 srow[j] = ptr; ptr += width;
1893 trow[j] = ptr; ptr += width;
1897 for(
size_t level=1; level < levels; ++level )
1899 size_t nwidth = (width > 1) ? (width >> 1) : 1;
1902 size_t nheight = (height > 1) ? (height >> 1) : 1;
1906 for(
size_t j = 0; j < 4; ++j )
1908 memset( urow[j], 0xCD,
sizeof(XMVECTOR)*width );
1909 memset( vrow[j], 0xDD,
sizeof(XMVECTOR)*width );
1910 memset( srow[j], 0xED,
sizeof(XMVECTOR)*width );
1911 memset( trow[j], 0xFD,
sizeof(XMVECTOR)*width );
1918 size_t ndepth = depth >> 1;
1921 for(
size_t slice=0; slice < ndepth; ++slice )
1923 auto& toZ = cfZ[ slice ];
1925 const Image* srca = mipChain.GetImage( level-1, 0, toZ.u0 );
1926 const Image* srcb = mipChain.GetImage( level-1, 0, toZ.u1 );
1927 const Image* srcc = mipChain.GetImage( level-1, 0, toZ.u2 );
1928 const Image* srcd = mipChain.GetImage( level-1, 0, toZ.u3 );
1929 if ( !srca || !srcb || !srcc || !srcd )
1932 size_t u0 = size_t(-1);
1933 size_t u1 = size_t(-1);
1934 size_t u2 = size_t(-1);
1935 size_t u3 = size_t(-1);
1937 const Image*
dest = mipChain.GetImage( level, 0, slice );
1943 for(
size_t y = 0;
y < nheight; ++
y )
1945 auto& toY = cfY[
y ];
1950 if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 )
1960 else if ( toY.u0 == u1 )
1965 std::swap( urow[0], vrow[0] );
1966 std::swap( urow[1], vrow[1] );
1967 std::swap( urow[2], vrow[2] );
1968 std::swap( urow[3], vrow[3] );
1970 else if ( toY.u0 == u2 )
1975 std::swap( urow[0], srow[0] );
1976 std::swap( urow[1], srow[1] );
1977 std::swap( urow[2], srow[2] );
1978 std::swap( urow[3], srow[3] );
1980 else if ( toY.u0 == u3 )
1985 std::swap( urow[0], trow[0] );
1986 std::swap( urow[1], trow[1] );
1987 std::swap( urow[2], trow[2] );
1988 std::swap( urow[3], trow[3] );
1995 if ( toY.u1 != u2 && toY.u1 != u3 )
2005 else if ( toY.u1 == u2 )
2010 std::swap( vrow[0], srow[0] );
2011 std::swap( vrow[1], srow[1] );
2012 std::swap( vrow[2], srow[2] );
2013 std::swap( vrow[3], srow[3] );
2015 else if ( toY.u1 == u3 )
2020 std::swap( vrow[0], trow[0] );
2021 std::swap( vrow[1], trow[1] );
2022 std::swap( vrow[2], trow[2] );
2023 std::swap( vrow[3], trow[3] );
2045 std::swap( srow[0], trow[0] );
2046 std::swap( srow[1], trow[1] );
2047 std::swap( srow[2], trow[2] );
2048 std::swap( srow[3], trow[3] );
2064 for(
size_t x = 0; x < nwidth; ++x )
2066 auto& toX = cfX[ x ];
2070 for(
size_t j=0; j < 4; ++j )
2072 XMVECTOR C0, C1, C2, C3;
2073 CUBIC_INTERPOLATE( C0, toX.x, urow[j][ toX.u0 ], urow[j][ toX.u1 ], urow[j][ toX.u2 ], urow[j][ toX.u3 ] );
2074 CUBIC_INTERPOLATE( C1, toX.x, vrow[j][ toX.u0 ], vrow[j][ toX.u1 ], vrow[j][ toX.u2 ], vrow[j][ toX.u3 ] );
2075 CUBIC_INTERPOLATE( C2, toX.x, srow[j][ toX.u0 ], srow[j][ toX.u1 ], srow[j][ toX.u2 ], srow[j][ toX.u3 ] );
2076 CUBIC_INTERPOLATE( C3, toX.x, trow[j][ toX.u0 ], trow[j][ toX.u1 ], trow[j][ toX.u2 ], trow[j][ toX.u3 ] );
2093 const Image* src = mipChain.GetImage( level-1, 0, 0 );
2094 const Image*
dest = mipChain.GetImage( level, 0, 0 );
2096 if ( !src || !dest )
2104 size_t u0 = size_t(-1);
2105 size_t u1 = size_t(-1);
2106 size_t u2 = size_t(-1);
2107 size_t u3 = size_t(-1);
2109 for(
size_t y = 0;
y < nheight; ++
y )
2111 auto& toY = cfY[
y ];
2116 if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 )
2123 else if ( toY.u0 == u1 )
2128 std::swap( urow[0], vrow[0] );
2130 else if ( toY.u0 == u2 )
2135 std::swap( urow[0], srow[0] );
2137 else if ( toY.u0 == u3 )
2142 std::swap( urow[0], trow[0] );
2149 if ( toY.u1 != u2 && toY.u1 != u3 )
2156 else if ( toY.u1 == u2 )
2161 std::swap( vrow[0], srow[0] );
2163 else if ( toY.u1 == u3 )
2168 std::swap( vrow[0], trow[0] );
2187 std::swap( srow[0], trow[0] );
2200 for(
size_t x = 0; x < nwidth; ++x )
2202 auto& toX = cfX[ x ];
2204 XMVECTOR C0, C1, C2, C3;
2205 CUBIC_INTERPOLATE( C0, toX.x, urow[0][ toX.u0 ], urow[0][ toX.u1 ], urow[0][ toX.u2 ], urow[0][ toX.u3 ] );
2206 CUBIC_INTERPOLATE( C1, toX.x, vrow[0][ toX.u0 ], vrow[0][ toX.u1 ], vrow[0][ toX.u2 ], vrow[0][ toX.u3 ] );
2207 CUBIC_INTERPOLATE( C2, toX.x, srow[0][ toX.u0 ], srow[0][ toX.u1 ], srow[0][ toX.u2 ], srow[0][ toX.u3 ] );
2208 CUBIC_INTERPOLATE( C3, toX.x, trow[0][ toX.u0 ], trow[0][ toX.u1 ], trow[0][ toX.u2 ], trow[0][ toX.u3 ] );
2236 if ( !depth || !mipChain.GetImages() )
2237 return E_INVALIDARG;
2239 using namespace TriangleFilter;
2245 size_t width = mipChain.GetMetadata().width;
2246 size_t height = mipChain.GetMetadata().height;
2251 return E_OUTOFMEMORY;
2253 std::unique_ptr<TriangleRow[]> sliceActive(
new (std::nothrow) TriangleRow[ depth ] );
2255 return E_OUTOFMEMORY;
2257 TriangleRow * sliceFree =
nullptr;
2259 std::unique_ptr<Filter> tfX, tfY, tfZ;
2261 XMVECTOR* row = scanline.get();
2264 for(
size_t level=1; level < levels; ++level )
2266 size_t nwidth = (width > 1) ? (width >> 1) : 1;
2271 size_t nheight = (height > 1) ? (height >> 1) : 1;
2276 size_t ndepth = (depth > 1 ) ? (depth >> 1) : 1;
2282 memset( row, 0xCD,
sizeof(XMVECTOR)*width );
2285 auto xFromEnd =
reinterpret_cast<const FilterFrom*
>(
reinterpret_cast<const uint8_t*
>( tfX.get() ) + tfX->sizeInBytes );
2286 auto yFromEnd =
reinterpret_cast<const FilterFrom*
>(
reinterpret_cast<const uint8_t*
>( tfY.get() ) + tfY->sizeInBytes );
2287 auto zFromEnd =
reinterpret_cast<const FilterFrom*
>(
reinterpret_cast<const uint8_t*
>( tfZ.get() ) + tfZ->sizeInBytes );
2290 for( FilterFrom* zFrom = tfZ->from; zFrom < zFromEnd; )
2292 for (
size_t j = 0; j < zFrom->count; ++j )
2294 size_t w = zFrom->to[ j ].u;
2296 TriangleRow* sliceAcc = &sliceActive.get()[ w ];
2298 ++sliceAcc->remaining;
2300 if ( sliceAcc->scanline )
2302 memset( sliceAcc->scanline.get(), 0,
sizeof(XMVECTOR) * nwidth * nheight );
2306 zFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( zFrom ) + zFrom->sizeInBytes );
2311 for( FilterFrom* zFrom = tfZ->from; zFrom < zFromEnd; ++z )
2314 for (
size_t j = 0; j < zFrom->count; ++j )
2316 size_t w = zFrom->to[ j ].u;
2318 TriangleRow* sliceAcc = &sliceActive.get()[ w ];
2320 if ( !sliceAcc->scanline )
2326 assert( sliceFree->scanline != 0 );
2327 sliceAcc->scanline.reset( sliceFree->scanline.release() );
2328 sliceFree = sliceFree->next;
2332 size_t bytes =
sizeof(XMVECTOR) * nwidth * nheight;
2333 sliceAcc->scanline.reset( reinterpret_cast<XMVECTOR*>( _aligned_malloc( bytes, 16 ) ) );
2334 if ( !sliceAcc->scanline )
2335 return E_OUTOFMEMORY;
2338 memset( sliceAcc->scanline.get(), 0,
sizeof(XMVECTOR) * nwidth * nheight );
2343 const Image* src = mipChain.GetImage( level-1, 0, z );
2349 const uint8_t* pEndSrc = pSrc + rowPitch * height;
2351 for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; )
2354 if ( (pSrc + rowPitch) > pEndSrc )
2364 for( FilterFrom* xFrom = tfX->from; xFrom < xFromEnd; ++x )
2366 for (
size_t j = 0; j < zFrom->count; ++j )
2368 size_t w = zFrom->to[ j ].u;
2370 float zweight = zFrom->to[ j ].weight;
2372 XMVECTOR* accSlice = sliceActive[ w ].scanline.get();
2376 for (
size_t k = 0; k < yFrom->count; ++k )
2378 size_t v = yFrom->to[ k ].u;
2380 float yweight = yFrom->to[ k ].weight;
2382 XMVECTOR * accPtr = accSlice + v * nwidth;
2384 for (
size_t l = 0; l < xFrom->count; ++l )
2386 size_t u = xFrom->to[ l ].u;
2389 XMVECTOR weight = XMVectorReplicate( zweight * yweight * xFrom->to[ l ].weight );
2392 accPtr[ u ] = XMVectorMultiplyAdd( row[ x ], weight, accPtr[ u ] );
2397 xFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( xFrom ) + xFrom->sizeInBytes );
2400 yFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( yFrom ) + yFrom->sizeInBytes );
2404 for (
size_t j = 0; j < zFrom->count; ++j )
2406 size_t w = zFrom->to[ j ].u;
2408 TriangleRow* sliceAcc = &sliceActive.get()[ w ];
2410 assert( sliceAcc->remaining > 0 );
2411 --sliceAcc->remaining;
2413 if ( !sliceAcc->remaining )
2415 const Image*
dest = mipChain.GetImage( level, 0, w );
2416 XMVECTOR* pAccSrc = sliceAcc->scanline.get();
2417 if ( !dest || !pAccSrc )
2422 for(
size_t h = 0; h < nheight; ++h )
2426 case DXGI_FORMAT_R10G10B10A2_UNORM:
2427 case DXGI_FORMAT_R10G10B10A2_UINT:
2431 static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f };
2433 XMVECTOR* ptr = pAccSrc;
2434 for(
size_t i=0; i < dest->
width; ++i, ++ptr )
2436 *ptr = XMVectorAdd( *ptr, Bias );
2451 sliceAcc->next = sliceFree;
2452 sliceFree = sliceAcc;
2456 zFrom =
reinterpret_cast<FilterFrom*
>(
reinterpret_cast<uint8_t*
>( zFrom ) + zFrom->sizeInBytes );
2480 _Use_decl_annotations_
2484 return E_INVALIDARG;
2490 return E_INVALIDARG;
2494 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2499 static_assert(
TEX_FILTER_POINT == 0x100000,
"TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
2514 WICPixelFormatGUID pfGUID;
2518 hr = (baseImage.
height > 1 || !allow1D)
2529 assert( baseImage.
format != DXGI_FORMAT_R32G32B32A32_FLOAT );
2552 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2559 memset( &mdata, 0,
sizeof(mdata) );
2561 if ( baseImage.
height > 1 || !allow1D )
2576 if ( !filter_select )
2582 switch( filter_select )
2635 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2640 _Use_decl_annotations_
2645 return E_INVALIDARG;
2649 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2652 return E_INVALIDARG;
2654 std::vector<const Image> baseImages;
2655 baseImages.reserve( metadata.
arraySize );
2656 for(
size_t item=0; item < metadata.
arraySize; ++item )
2659 if ( index >= nimages )
2662 const Image& src = srcImages[ index ];
2672 baseImages.push_back( src );
2679 static_assert(
TEX_FILTER_POINT == 0x100000,
"TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
2694 WICPixelFormatGUID pfGUID;
2704 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2719 assert( metadata.
format != DXGI_FORMAT_R32G32B32A32_FLOAT );
2723 mdata2.
format = DXGI_FORMAT_R32G32B32A32_FLOAT;
2729 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2751 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2761 if ( !filter_select )
2767 switch( filter_select )
2774 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2787 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2800 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2813 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2826 for(
size_t item = 0; item < metadata.
arraySize; ++item )
2835 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2844 _Use_decl_annotations_
2847 if ( !baseImages || !depth )
2848 return E_INVALIDARG;
2851 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2854 size_t width = baseImages[0].
width;
2855 size_t height = baseImages[0].
height;
2858 return E_INVALIDARG;
2860 for(
size_t slice=0; slice < depth; ++slice )
2862 if ( !baseImages[slice].pixels )
2865 if ( baseImages[slice].format != format || baseImages[slice].width != width || baseImages[slice].height != height )
2873 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2875 static_assert(
TEX_FILTER_POINT == 0x100000,
"TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
2880 if ( !filter_select )
2886 switch( filter_select )
2889 hr =
_Setup3DMips( baseImages, depth, levels, mipChain );
2899 hr =
_Setup3DMips( baseImages, depth, levels, mipChain );
2909 hr =
_Setup3DMips( baseImages, depth, levels, mipChain );
2919 hr =
_Setup3DMips( baseImages, depth, levels, mipChain );
2929 hr =
_Setup3DMips( baseImages, depth, levels, mipChain );
2939 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2943 _Use_decl_annotations_
2948 return E_INVALIDARG;
2951 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2955 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
2958 return E_INVALIDARG;
2960 std::vector<const Image> baseImages;
2961 baseImages.reserve( metadata.
depth );
2962 for(
size_t slice=0; slice < metadata.
depth; ++slice )
2965 if ( index >= nimages )
2968 const Image& src = srcImages[ index ];
2978 baseImages.push_back( src );
2985 static_assert(
TEX_FILTER_POINT == 0x100000,
"TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
2988 if ( !filter_select )
2994 switch( filter_select )
3047 return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
bool _CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t &mipLevels)
static HRESULT _Generate3DMipsCubicFilter(_In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain)
std::unique_ptr< DirectX::XMVECTOR, aligned_deleter > ScopedAlignedArrayXMVECTOR
const Image * GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const
static HRESULT _EnsureWicBitmapPixelFormat(_In_ IWICImagingFactory *pWIC, _In_ IWICBitmap *src, _In_ DWORD filter, _In_ const WICPixelFormatGUID &desiredPixelFormat, _Deref_out_ IWICBitmap **dest)
size_t BitsPerColor(_In_ DXGI_FORMAT fmt)
bool IsPlanar(_In_ DXGI_FORMAT fmt)
static HRESULT _Generate3DMipsBoxFilter(_In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain)
_Use_decl_annotations_ HRESULT _ConvertFromR32G32B32A32(const Image &srcImage, const Image &destImage)
_Use_decl_annotations_ HRESULT _ConvertToR32G32B32A32(const Image &srcImage, ScratchImage &image)
size_t _In_ DXGI_FORMAT size_t _In_ TEXP_LEGACY_FORMAT _In_ DWORD flags assert(pDestination &&outSize > 0)
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
HRESULT Initialize(_In_ const TexMetadata &mdata, _In_ DWORD flags=CP_FLAGS_NONE)
static HRESULT _Generate3DMipsPointFilter(_In_ size_t depth, _In_ size_t levels, _In_ const ScratchImage &mipChain)
static HRESULT _Generate2DMipsTriangleFilter(_In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain, _In_ size_t item)
HRESULT Initialize2D(_In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags=CP_FLAGS_NONE)
_Use_decl_annotations_ bool _LoadScanline(XMVECTOR *pDestination, size_t count, LPCVOID pSource, size_t size, DXGI_FORMAT format)
#define CUBIC_INTERPOLATE(res, dx, p0, p1, p2, p3)
void _CreateCubicFilter(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _In_ bool mirror, _Out_writes_(dest) CubicFilter *cf)
IWICImagingFactory * _GetWIC()
bool IsCompressed(_In_ DXGI_FORMAT fmt)
size_t GetImageCount() const
HRESULT GenerateMipMaps(_In_ const Image &baseImage, _In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage &mipChain, _In_ bool allow1D=false)
static HRESULT _Setup2DMips(_In_reads_(nimages) const Image *baseImages, _In_ size_t nimages, _In_ const TexMetadata &mdata, _Out_ ScratchImage &mipChain)
_In_ size_t _In_ const TexMetadata & metadata
HRESULT _Create(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Inout_ std::unique_ptr< Filter > &tf)
bool IsValid(_In_ DXGI_FORMAT fmt)
static HRESULT _GenerateMipMapsUsingWIC(_In_ const Image &baseImage, _In_ DWORD filter, _In_ size_t levels, _In_ const WICPixelFormatGUID &pfGUID, _In_ const ScratchImage &mipChain, _In_ size_t item)
bool IsPalettized(_In_ DXGI_FORMAT fmt)
HRESULT GenerateMipMaps3D(_In_reads_(depth) const Image *baseImages, _In_ size_t depth, _In_ DWORD filter, _In_ size_t levels, _Out_ ScratchImage &mipChain)
static HRESULT _Generate2DMipsLinearFilter(_In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain, _In_ size_t item)
static size_t _CountMips(_In_ size_t width, _In_ size_t height)
HRESULT Initialize1D(_In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags=CP_FLAGS_NONE)
static HRESULT _Generate2DMipsBoxFilter(_In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain, _In_ size_t item)
WICBitmapDitherType _GetWICDither(_In_ DWORD flags)
_In_ size_t _In_ DXGI_FORMAT _In_reads_(count) const XMVECTOR *pSource
_Use_decl_annotations_ bool _LoadScanlineLinear(XMVECTOR *pDestination, size_t count, LPCVOID pSource, size_t size, DXGI_FORMAT format, DWORD flags)
_Use_decl_annotations_ bool _StoreScanlineLinear(LPVOID pDestination, size_t size, DXGI_FORMAT format, XMVECTOR *pSource, size_t count, DWORD flags)
bool IsTypeless(_In_ DXGI_FORMAT fmt, _In_ bool partialTypeless=true)
#define AVERAGE8(res, p0, p1, p2, p3, p4, p5, p6, p7)
#define TRILINEAR_INTERPOLATE(res, x, y, z, r0, r1, r2, r3)
static size_t _CountMips3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth)
bool IsSRGB(_In_ DXGI_FORMAT fmt)
#define BILINEAR_INTERPOLATE(res, x, y, r0, r1)
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
static HRESULT _Generate3DMipsTriangleFilter(_In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain)
static HRESULT _Generate2DMipsCubicFilter(_In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain, _In_ size_t item)
static bool _UseWICFiltering(_In_ DXGI_FORMAT format, _In_ DWORD filter)
const Image * GetImages() const
bool _DXGIToWIC(_In_ DXGI_FORMAT format, _Out_ GUID &guid, _In_ bool ignoreRGBvsBGR=false)
HRESULT _ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory *pWIC, _In_ IWICBitmap *original, _In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image *img)
const TexMetadata & GetMetadata() const
bool _CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t &mipLevels)
static bool ispow2(_In_ size_t x)
static HRESULT _Generate2DMipsPointFilter(_In_ size_t levels, _In_ const ScratchImage &mipChain, _In_ size_t item)
#define AVERAGE4(res, p0, p1, p2, p3)
_Use_decl_annotations_ bool _StoreScanline(LPVOID pDestination, size_t size, DXGI_FORMAT format, const XMVECTOR *pSource, size_t count, float threshold)
void _CreateLinearFilter(_In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter *lf)
static HRESULT _Generate3DMipsLinearFilter(_In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage &mipChain)
WICBitmapInterpolationMode _GetWICInterp(_In_ DWORD flags)
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t size_t z
static HRESULT _Setup3DMips(_In_reads_(depth) const Image *baseImages, _In_ size_t depth, size_t levels, _Out_ ScratchImage &mipChain)