diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index b3e4a7a4..586d21ff 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -143,6 +143,10 @@ namespace DirectX DIRECTX_TEX_API size_t __cdecl ComputeScanlines(_In_ DXGI_FORMAT fmt, _In_ size_t height) noexcept; + DIRECTX_TEX_API bool __cdecl CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels) noexcept; + DIRECTX_TEX_API bool __cdecl CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, + _Inout_ size_t& mipLevels) noexcept; + DIRECTX_TEX_API DXGI_FORMAT __cdecl MakeSRGB(_In_ DXGI_FORMAT fmt) noexcept; DIRECTX_TEX_API DXGI_FORMAT __cdecl MakeLinear(_In_ DXGI_FORMAT fmt) noexcept; DIRECTX_TEX_API DXGI_FORMAT __cdecl MakeTypeless(_In_ DXGI_FORMAT fmt) noexcept; diff --git a/DirectXTex/DirectXTexDDS.cpp b/DirectXTex/DirectXTexDDS.cpp index 48a2a6d0..a6827f5b 100644 --- a/DirectXTex/DirectXTexDDS.cpp +++ b/DirectXTex/DirectXTexDDS.cpp @@ -506,7 +506,7 @@ namespace { // Allow cases where mipCount was computed incorrectly size_t maxMips = 0; - std::ignore = Internal::CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, maxMips); + std::ignore = CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, maxMips); metadata.mipLevels = std::min(metadata.mipLevels, maxMips); } } @@ -533,7 +533,7 @@ namespace { // Allow cases where mipCount was computed incorrectly size_t maxMips = 0; - std::ignore = Internal::CalculateMipLevels(metadata.width, metadata.height, maxMips); + std::ignore = CalculateMipLevels(metadata.width, metadata.height, maxMips); metadata.mipLevels = std::min(metadata.mipLevels, maxMips); } } diff --git a/DirectXTex/DirectXTexMipmaps.cpp b/DirectXTex/DirectXTexMipmaps.cpp index cb09339c..0b0e9e1c 100644 --- a/DirectXTex/DirectXTexMipmaps.cpp +++ b/DirectXTex/DirectXTexMipmaps.cpp @@ -356,7 +356,7 @@ namespace } _Use_decl_annotations_ -bool DirectX::Internal::CalculateMipLevels( +bool DirectX::CalculateMipLevels( size_t width, size_t height, size_t& mipLevels) noexcept @@ -379,7 +379,7 @@ bool DirectX::Internal::CalculateMipLevels( } _Use_decl_annotations_ -bool DirectX::Internal::CalculateMipLevels3D( +bool DirectX::CalculateMipLevels3D( size_t width, size_t height, size_t depth, diff --git a/DirectXTex/DirectXTexP.h b/DirectXTex/DirectXTexP.h index 951a3a7b..be209291 100644 --- a/DirectXTex/DirectXTexP.h +++ b/DirectXTex/DirectXTexP.h @@ -442,9 +442,6 @@ namespace DirectX //--------------------------------------------------------------------------------- // Misc helper functions bool __cdecl IsAlphaAllOpaqueBC(_In_ const Image& cImage) noexcept; - bool __cdecl CalculateMipLevels(_In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels) noexcept; - bool __cdecl CalculateMipLevels3D(_In_ size_t width, _In_ size_t height, _In_ size_t depth, - _Inout_ size_t& mipLevels) noexcept; #ifdef _WIN32 HRESULT __cdecl ResizeSeparateColorAndAlpha(_In_ IWICImagingFactory* pWIC, diff --git a/Texassemble/texassemble.cpp b/Texassemble/texassemble.cpp index 70f2266d..6a7456e3 100644 --- a/Texassemble/texassemble.cpp +++ b/Texassemble/texassemble.cpp @@ -131,6 +131,7 @@ namespace OPT_FILELIST, OPT_WIDTH, OPT_HEIGHT, + OPT_MIPLEVELS, OPT_FORMAT, OPT_FILTER, OPT_SRGBI, @@ -180,6 +181,7 @@ namespace { L"flist", OPT_FILELIST }, { L"w", OPT_WIDTH }, { L"h", OPT_HEIGHT }, + { L"m", OPT_MIPLEVELS }, { L"f", OPT_FORMAT }, { L"if", OPT_FILTER }, { L"srgbi", OPT_SRGBI }, @@ -215,6 +217,7 @@ namespace { L"height", OPT_HEIGHT }, { L"help", OPT_HELP }, { L"image-filter", OPT_FILTER }, + { L"mip-levels", OPT_MIPLEVELS }, { L"overwrite", OPT_OVERWRITE }, { L"separate-alpha", OPT_SEPALPHA }, { L"srgb-in", OPT_SRGBI }, @@ -545,6 +548,7 @@ namespace L" cube-from-ht create cubemap from a h-tee image\n" L" cube-from-hs create cubemap from a h-strip image\n" L" cube-from-vs create cubemap from a v-strip image\n" + L" from-mips create texture with provided mipmap images\n" L"\nOPTIONS\n" L" -r wildcard filename search is recursive\n" L" -flist , --file-list \n" @@ -552,6 +556,7 @@ namespace L"\n" L" -w , --width width for output\n" L" -h , --height height for output\n" + L" -m , --mip-levels miplevels for output (*-from-mips only)\n" L" -f , --format pixel format for output\n" L"\n" L" -if , --image-filter image filtering\n" @@ -775,6 +780,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) // Parameters and defaults size_t width = 0; size_t height = 0; + size_t mipLevels = 0; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; TEX_FILTER_FLAGS dwFilter = TEX_FILTER_DEFAULT; @@ -920,6 +926,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case OPT_FILELIST: case OPT_WIDTH: case OPT_HEIGHT: + case OPT_MIPLEVELS: case OPT_FORMAT: case OPT_FILTER: case OPT_SRGBI: @@ -956,6 +963,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case OPT_FILELIST: case OPT_WIDTH: case OPT_HEIGHT: + case OPT_MIPLEVELS: case OPT_FORMAT: case OPT_FILTER: case OPT_OUTPUTFILE: @@ -996,6 +1004,19 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } break; + case OPT_MIPLEVELS: + if (dwCommand != CMD_FROM_MIPS) + { + wprintf(L"-m option only applies to *-from-mips command\n"); + return 1; + } + else if (swscanf_s(pValue, L"%zu", &mipLevels) != 1) + { + wprintf(L"Invalid value specified with -m (%ls)\n", pValue); + return 1; + } + break; + case OPT_FORMAT: format = static_cast(LookupByName(pValue, g_pFormats)); if (!format) @@ -1224,6 +1245,28 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } break; + case CMD_FROM_MIPS: + if (conversion.size() < 2) + { + wprintf(L"ERROR: *-from-mips command requires at least 2 input files\n"); + return 1; + } + else if (width != 0 && height != 0) + { + if (!CalculateMipLevels(width, height, mipLevels)) + { + wprintf(L"ERROR: mipLevels value invalid for given dimensions (%zu x %zu)\n", width, height); + return 1; + } + + if (conversion.size() != mipLevels) + { + wprintf(L"ERROR: number of input files doesn't match the specified mip levels for given dimensions (%zu x %zu, %zu mip levels)\n", width, height, mipLevels); + return 1; + } + } + break; + default: break; } @@ -1660,10 +1703,25 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { height = info.height; } + size_t targetWidth = width; size_t targetHeight = height; if (dwCommand == CMD_FROM_MIPS) { + if (!conversionIndex) + { + if (mipLevels == 0) + { + mipLevels = conversion.size(); + } + + if (!CalculateMipLevels(width, height, mipLevels)) + { + wprintf(L"\nERROR: Too many input mips provided for the given dimensions of %zu x %zu.\n", width, height); + return 1; + } + } + size_t mipdiv = 1; for (size_t i = 0; i < conversionIndex; ++i) {