From 86cf9d542ffa1162aeeda2548810e6be8755d5f2 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Tue, 13 Jun 2023 15:40:45 -0700 Subject: [PATCH] tex tools updated with support for long file paths with Windows 10 (#364) --- Auxiliary/DirectXTexEXR.cpp | 46 ++-- CMakeLists.txt | 5 +- Texassemble/Texassemble_Desktop_2019.vcxproj | 3 + .../Texassemble_Desktop_2019.vcxproj.filters | 5 + .../Texassemble_Desktop_2019_Win10.vcxproj | 3 + ...ssemble_Desktop_2019_Win10.vcxproj.filters | 5 + Texassemble/Texassemble_Desktop_2022.vcxproj | 3 + .../Texassemble_Desktop_2022.vcxproj.filters | 5 + .../Texassemble_Desktop_2022_Win10.vcxproj | 3 + ...ssemble_Desktop_2022_Win10.vcxproj.filters | 5 + Texassemble/settings.manifest | 21 ++ Texassemble/texassemble.cpp | 178 +++++++-------- Texconv/Texconv_Desktop_2019.vcxproj | 3 + Texconv/Texconv_Desktop_2019.vcxproj.filters | 5 + Texconv/Texconv_Desktop_2019_Win10.vcxproj | 3 + ...Texconv_Desktop_2019_Win10.vcxproj.filters | 5 + Texconv/Texconv_Desktop_2022.vcxproj | 3 + Texconv/Texconv_Desktop_2022.vcxproj.filters | 5 + Texconv/Texconv_Desktop_2022_Win10.vcxproj | 3 + ...Texconv_Desktop_2022_Win10.vcxproj.filters | 5 + Texconv/settings.manifest | 21 ++ Texconv/texconv.cpp | 202 +++++++----------- Texdiag/settings.manifest | 21 ++ Texdiag/texdiag.cpp | 159 ++++++-------- Texdiag/texdiag_Desktop_2019.vcxproj | 3 + Texdiag/texdiag_Desktop_2019.vcxproj.filters | 5 + Texdiag/texdiag_Desktop_2019_Win10.vcxproj | 3 + ...texdiag_Desktop_2019_Win10.vcxproj.filters | 5 + Texdiag/texdiag_Desktop_2022.vcxproj | 3 + Texdiag/texdiag_Desktop_2022.vcxproj.filters | 5 + Texdiag/texdiag_Desktop_2022_Win10.vcxproj | 3 + ...texdiag_Desktop_2022_Win10.vcxproj.filters | 5 + 32 files changed, 422 insertions(+), 327 deletions(-) create mode 100644 Texassemble/settings.manifest create mode 100644 Texconv/settings.manifest create mode 100644 Texdiag/settings.manifest diff --git a/Auxiliary/DirectXTexEXR.cpp b/Auxiliary/DirectXTexEXR.cpp index 53cbdca..94fe63e 100644 --- a/Auxiliary/DirectXTexEXR.cpp +++ b/Auxiliary/DirectXTexEXR.cpp @@ -216,11 +216,16 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta return E_INVALIDARG; #ifdef _WIN32 - char fileName[MAX_PATH] = {}; - const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr); - if (result <= 0) + std::string fileName; + const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr); + if (nameLength > 0) { - *fileName = 0; + fileName.resize(nameLength); + const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName.data(), nameLength, nullptr, nullptr); + if (result <= 0) + { + fileName.clear(); + } } #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) @@ -241,7 +246,7 @@ HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& meta return HRESULT_FROM_WIN32(GetLastError()); } - InputStream stream(hFile.get(), fileName); + InputStream stream(hFile.get(), fileName.c_str()); #else std::wstring wFileName(szFile); std::string fileName(wFileName.cbegin(), wFileName.cend()); @@ -318,11 +323,16 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S } #ifdef _WIN32 - char fileName[MAX_PATH] = {}; - const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr); - if (result <= 0) + std::string fileName; + const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr); + if (nameLength > 0) { - *fileName = 0; + fileName.resize(nameLength); + const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName.data(), nameLength, nullptr, nullptr); + if (result <= 0) + { + fileName.clear(); + } } #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) @@ -343,7 +353,7 @@ HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, S return HRESULT_FROM_WIN32(GetLastError()); } - InputStream stream(hFile.get(), fileName); + InputStream stream(hFile.get(), fileName.c_str()); #else std::wstring wFileName(szFile); std::string fileName(wFileName.cbegin(), wFileName.cend()); @@ -450,12 +460,18 @@ HRESULT DirectX::SaveToEXRFile(const Image& image, const wchar_t* szFile) } #ifdef _WIN32 - char fileName[MAX_PATH] = {}; - const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr); - if (result <= 0) + std::string fileName; + const int nameLength = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, nullptr, 0, nullptr, nullptr); + if (nameLength > 0) { - *fileName = 0; + fileName.resize(nameLength); + const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName.data(), nameLength, nullptr, nullptr); + if (result <= 0) + { + fileName.clear(); + } } + // Create file and write header #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile(safe_handle(CreateFile2( @@ -477,7 +493,7 @@ HRESULT DirectX::SaveToEXRFile(const Image& image, const wchar_t* szFile) auto_delete_file delonfail(hFile.get()); - OutputStream stream(hFile.get(), fileName); + OutputStream stream(hFile.get(), fileName.c_str()); #else std::wstring wFileName(szFile); std::string fileName(wFileName.cbegin(), wFileName.cend()); diff --git a/CMakeLists.txt b/CMakeLists.txt index 038b72c..e3ac0a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,6 +285,7 @@ if(BUILD_TOOLS AND BUILD_DX11 AND WIN32) add_executable(texassemble Texassemble/texassemble.cpp Texassemble/texassemble.rc + Texassemble/settings.manifest Texassemble/AnimatedGif.cpp) target_link_libraries(texassemble ${PROJECT_NAME} ole32.lib version.lib) source_group(texassemble REGULAR_EXPRESSION Texassemble/*.*) @@ -292,6 +293,7 @@ if(BUILD_TOOLS AND BUILD_DX11 AND WIN32) add_executable(texconv Texconv/texconv.cpp Texconv/texconv.rc + Texconv/settings.manifest Texconv/ExtendedBMP.cpp Texconv/PortablePixMap.cpp) target_link_libraries(texconv ${PROJECT_NAME} ole32.lib shell32.lib version.lib) @@ -299,7 +301,8 @@ if(BUILD_TOOLS AND BUILD_DX11 AND WIN32) add_executable(texdiag Texdiag/texdiag.cpp - Texdiag/texdiag.rc) + Texdiag/texdiag.rc + Texdiag/settings.manifest) target_link_libraries(texdiag ${PROJECT_NAME} ole32.lib version.lib) source_group(texdiag REGULAR_EXPRESSION Texdiag/*.*) diff --git a/Texassemble/Texassemble_Desktop_2019.vcxproj b/Texassemble/Texassemble_Desktop_2019.vcxproj index efb171e..fd60085 100644 --- a/Texassemble/Texassemble_Desktop_2019.vcxproj +++ b/Texassemble/Texassemble_Desktop_2019.vcxproj @@ -291,6 +291,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2019.vcxproj.filters b/Texassemble/Texassemble_Desktop_2019.vcxproj.filters index e1687da..1dc8bda 100644 --- a/Texassemble/Texassemble_Desktop_2019.vcxproj.filters +++ b/Texassemble/Texassemble_Desktop_2019.vcxproj.filters @@ -15,4 +15,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj b/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj index d30449e..eaa982c 100644 --- a/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj +++ b/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj @@ -421,6 +421,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj.filters b/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj.filters index e1687da..1dc8bda 100644 --- a/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj.filters +++ b/Texassemble/Texassemble_Desktop_2019_Win10.vcxproj.filters @@ -15,4 +15,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2022.vcxproj b/Texassemble/Texassemble_Desktop_2022.vcxproj index 5905036..4f576ca 100644 --- a/Texassemble/Texassemble_Desktop_2022.vcxproj +++ b/Texassemble/Texassemble_Desktop_2022.vcxproj @@ -297,6 +297,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2022.vcxproj.filters b/Texassemble/Texassemble_Desktop_2022.vcxproj.filters index e1687da..1dc8bda 100644 --- a/Texassemble/Texassemble_Desktop_2022.vcxproj.filters +++ b/Texassemble/Texassemble_Desktop_2022.vcxproj.filters @@ -15,4 +15,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj b/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj index c44c5ea..ac95131 100644 --- a/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj +++ b/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj @@ -427,6 +427,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj.filters b/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj.filters index e1687da..1dc8bda 100644 --- a/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj.filters +++ b/Texassemble/Texassemble_Desktop_2022_Win10.vcxproj.filters @@ -15,4 +15,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texassemble/settings.manifest b/Texassemble/settings.manifest new file mode 100644 index 0000000..544e45d --- /dev/null +++ b/Texassemble/settings.manifest @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + true + + + diff --git a/Texassemble/texassemble.cpp b/Texassemble/texassemble.cpp index 06d70f8..28f2bce 100644 --- a/Texassemble/texassemble.cpp +++ b/Texassemble/texassemble.cpp @@ -126,7 +126,7 @@ namespace struct SConversion { - wchar_t szSrc[MAX_PATH]; + std::wstring szSrc; }; struct SValue @@ -432,11 +432,11 @@ namespace return 0; } - void SearchForFiles(const wchar_t* path, std::list& files, bool recursive) + void SearchForFiles(const std::filesystem::path& path, std::list& files, bool recursive) { // Process files WIN32_FIND_DATAW findData = {}; - ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path, + ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -446,12 +446,8 @@ namespace { if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY))) { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - SConversion conv = {}; - _wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr); + conv.szSrc = path.parent_path().append(findData.cFileName).native(); files.push_back(conv); } @@ -463,15 +459,9 @@ namespace // Process directories if (recursive) { - wchar_t searchDir[MAX_PATH] = {}; - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - _wmakepath_s(searchDir, drive, dir, L"*", nullptr); - } + auto searchDir = path.parent_path().append(L"*"); - hFile.reset(safe_handle(FindFirstFileExW(searchDir, + hFile.reset(safe_handle(FindFirstFileExW(searchDir.c_str(), FindExInfoBasic, &findData, FindExSearchLimitToDirectories, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -484,17 +474,7 @@ namespace { if (findData.cFileName[0] != L'.') { - wchar_t subdir[MAX_PATH] = {}; - - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - wchar_t fname[_MAX_FNAME] = {}; - wchar_t ext[_MAX_FNAME] = {}; - _wsplitpath_s(path, drive, dir, fname, ext); - wcscat_s(dir, findData.cFileName); - _wmakepath_s(subdir, drive, dir, fname, ext); - } + auto subdir = path.parent_path().append(findData.cFileName).append(path.filename().c_str()); SearchForFiles(subdir, files, recursive); } @@ -510,36 +490,38 @@ namespace { std::list flist; std::set excludes; - wchar_t fname[1024] = {}; + + auto fname = std::make_unique(32768); for (;;) { - inFile >> fname; + inFile >> fname.get(); if (!inFile) break; - if (*fname == L'#') + if (fname[0] == L'#') { // Comment } - else if (*fname == L'-') + else if (fname[0] == L'-') { if (flist.empty()) { - wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname); + wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname.get()); } else { - std::filesystem::path path(fname + 1); + std::filesystem::path path(fname.get() + 1); auto& npath = path.make_preferred(); - if (wcspbrk(fname, L"?*") != nullptr) + if (wcspbrk(fname.get(), L"?*") != nullptr) { std::list removeFiles; - SearchForFiles(npath.c_str(), removeFiles, false); + SearchForFiles(npath, removeFiles, false); for (auto& it : removeFiles) { - _wcslwr_s(it.szSrc); - excludes.insert(it.szSrc); + std::wstring name = it.szSrc; + std::transform(name.begin(), name.end(), name.begin(), towlower); + excludes.insert(name); } } else @@ -550,16 +532,16 @@ namespace } } } - else if (wcspbrk(fname, L"?*") != nullptr) + else if (wcspbrk(fname.get(), L"?*") != nullptr) { - std::filesystem::path path(fname); - SearchForFiles(path.make_preferred().c_str(), flist, false); + std::filesystem::path path(fname.get()); + SearchForFiles(path.make_preferred(), flist, false); } else { SConversion conv = {}; - std::filesystem::path path(fname); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + std::filesystem::path path(fname.get()); + conv.szSrc = path.make_preferred().native(); flist.push_back(conv); } @@ -690,7 +672,7 @@ namespace wchar_t version[32] = {}; wchar_t appName[_MAX_PATH] = {}; - if (GetModuleFileNameW(nullptr, appName, static_cast(std::size(appName)))) + if (GetModuleFileNameW(nullptr, appName, _MAX_PATH)) { const DWORD size = GetFileVersionInfoSizeW(appName, nullptr); if (size > 0) @@ -1018,7 +1000,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) uint32_t zeroElements[4] = {}; uint32_t oneElements[4] = {}; - wchar_t szOutputFile[MAX_PATH] = {}; + std::wstring outputFile; // Set locale for output since GetErrorDesc can get localized strings. std::locale::global(std::locale("")); @@ -1226,12 +1208,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case OPT_OUTPUTFILE: { std::filesystem::path path(pValue); - wcscpy_s(szOutputFile, path.make_preferred().c_str()); + outputFile = path.make_preferred().native(); - wchar_t ext[_MAX_EXT] = {}; - _wsplitpath_s(szOutputFile, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT); - - fileType = LookupByName(ext, g_pExtFileTypes); + fileType = LookupByName(path.extension().c_str(), g_pExtFileTypes); switch (dwCommand) { @@ -1356,7 +1335,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { const size_t count = conversion.size(); std::filesystem::path path(pArg); - SearchForFiles(path.make_preferred().c_str(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0); + SearchForFiles(path.make_preferred(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0); if (conversion.size() <= count) { wprintf(L"No matching files found for %ls\n", pArg); @@ -1367,7 +1346,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { SConversion conv = {}; std::filesystem::path path(pArg); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + conv.szSrc = path.make_preferred().native(); conversion.push_back(conv); } } @@ -1423,19 +1402,17 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (dwCommand == CMD_GIF) { - wchar_t ext[_MAX_EXT] = {}; - wchar_t fname[_MAX_FNAME] = {}; - _wsplitpath_s(conversion.front().szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT); + std::filesystem::path curpath(conversion.front().szSrc); - wprintf(L"reading %ls", conversion.front().szSrc); + wprintf(L"reading %ls", curpath.c_str()); fflush(stdout); - if (!*szOutputFile) + if (outputFile.empty()) { - _wmakepath_s(szOutputFile, nullptr, nullptr, fname, L".dds"); + outputFile = curpath.stem().concat(L".dds").native(); } - hr = LoadAnimatedGif(conversion.front().szSrc, loadedImages, (dwOptions & (1 << OPT_GIF_BGCOLOR)) != 0); + hr = LoadAnimatedGif(curpath.c_str(), loadedImages, (dwOptions & (1 << OPT_GIF_BGCOLOR)) != 0); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1446,14 +1423,13 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { for (auto pConv = conversion.begin(); pConv != conversion.end(); ++pConv) { - wchar_t ext[_MAX_EXT] = {}; - wchar_t fname[_MAX_FNAME] = {}; - _wsplitpath_s(pConv->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT); + std::filesystem::path curpath(pConv->szSrc); + auto const ext = curpath.extension(); // Load source image if (pConv != conversion.begin()) wprintf(L"\n"); - else if (!*szOutputFile) + else if (outputFile.empty()) { switch (dwCommand) { @@ -1464,22 +1440,22 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case CMD_H_STRIP: case CMD_V_STRIP: case CMD_ARRAY_STRIP: - _wmakepath_s(szOutputFile, nullptr, nullptr, fname, L".bmp"); + outputFile = curpath.stem().concat(L".bmp").native(); break; default: - if (_wcsicmp(ext, L".dds") == 0) + if (_wcsicmp(curpath.extension().c_str(), L".dds") == 0) { wprintf(L"ERROR: Need to specify output file via -o\n"); return 1; } - _wmakepath_s(szOutputFile, nullptr, nullptr, fname, L".dds"); + outputFile = curpath.stem().concat(L".dds").native(); break; } } - wprintf(L"reading %ls", pConv->szSrc); + wprintf(L"reading %ls", curpath.c_str()); fflush(stdout); TexMetadata info; @@ -1498,9 +1474,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case CMD_H_TEE: case CMD_H_STRIP: case CMD_V_STRIP: - if (_wcsicmp(ext, L".dds") == 0) + if (_wcsicmp(ext.c_str(), L".dds") == 0) { - hr = LoadFromDDSFile(pConv->szSrc, DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); + hr = LoadFromDDSFile(curpath.c_str(), DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1525,9 +1501,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) break; case CMD_ARRAY_STRIP: - if (_wcsicmp(ext, L".dds") == 0) + if (_wcsicmp(ext.c_str(), L".dds") == 0) { - hr = LoadFromDDSFile(pConv->szSrc, DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); + hr = LoadFromDDSFile(curpath.c_str(), DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1548,9 +1524,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) break; default: - if (_wcsicmp(ext, L".dds") == 0) + if (_wcsicmp(ext.c_str(), L".dds") == 0) { - hr = LoadFromDDSFile(pConv->szSrc, DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); + hr = LoadFromDDSFile(curpath.c_str(), DDS_FLAGS_ALLOW_LARGE_FILES, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1579,20 +1555,20 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } } } - else if (_wcsicmp(ext, L".tga") == 0) + else if (_wcsicmp(ext.c_str(), L".tga") == 0) { TGA_FLAGS tgaFlags = (IsBGR(format)) ? TGA_FLAGS_BGR : TGA_FLAGS_NONE; - hr = LoadFromTGAFile(pConv->szSrc, tgaFlags, &info, *image); + hr = LoadFromTGAFile(curpath.c_str(), tgaFlags, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); return 1; } } - else if (_wcsicmp(ext, L".hdr") == 0) + else if (_wcsicmp(ext.c_str(), L".hdr") == 0) { - hr = LoadFromHDRFile(pConv->szSrc, &info, *image); + hr = LoadFromHDRFile(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1600,9 +1576,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } } #ifdef USE_OPENEXR - else if (_wcsicmp(ext, L".exr") == 0) + else if (_wcsicmp(ext.c_str(), L".exr") == 0) { - hr = LoadFromEXRFile(pConv->szSrc, &info, *image); + hr = LoadFromEXRFile(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -1620,17 +1596,17 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) static_assert(static_cast(WIC_FLAGS_FILTER_CUBIC) == static_cast(TEX_FILTER_CUBIC), "WIC_FLAGS_* & TEX_FILTER_* should match"); static_assert(static_cast(WIC_FLAGS_FILTER_FANT) == static_cast(TEX_FILTER_FANT), "WIC_FLAGS_* & TEX_FILTER_* should match"); - hr = LoadFromWICFile(pConv->szSrc, WIC_FLAGS_ALL_FRAMES | dwFilter, &info, *image); + hr = LoadFromWICFile(curpath.c_str(), WIC_FLAGS_ALL_FRAMES | dwFilter, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); if (hr == static_cast(0xc00d5212) /* MF_E_TOPO_CODEC_NOT_FOUND */) { - if (_wcsicmp(ext, L".heic") == 0 || _wcsicmp(ext, L".heif") == 0) + if (_wcsicmp(ext.c_str(), L".heic") == 0 || _wcsicmp(ext.c_str(), L".heif") == 0) { wprintf(L"INFO: This format requires installing the HEIF Image Extensions - https://aka.ms/heif\n"); } - else if (_wcsicmp(ext, L".webp") == 0) + else if (_wcsicmp(ext.c_str(), L".webp") == 0) { wprintf(L"INFO: This format requires installing the WEBP Image Extensions - https://www.microsoft.com/p/webp-image-extensions/9pg2dk419drg\n"); } @@ -2192,26 +2168,26 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } // Write cross/strip - wprintf(L"\nWriting %ls ", szOutputFile); + wprintf(L"\nWriting %ls ", outputFile.c_str()); PrintInfo(result.GetMetadata()); wprintf(L"\n"); fflush(stdout); if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; } } - hr = SaveImageFile(*dest, fileType, szOutputFile); + hr = SaveImageFile(*dest, fileType, outputFile.c_str()); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2260,26 +2236,26 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } // Write merged texture - wprintf(L"\nWriting %ls ", szOutputFile); + wprintf(L"\nWriting %ls ", outputFile.c_str()); PrintInfo(result.GetMetadata()); wprintf(L"\n"); fflush(stdout); if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; } } - hr = SaveImageFile(*result.GetImage(0, 0, 0), fileType, szOutputFile); + hr = SaveImageFile(*result.GetImage(0, 0, 0), fileType, outputFile.c_str()); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2329,26 +2305,26 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } // Write array strip - wprintf(L"\nWriting %ls ", szOutputFile); + wprintf(L"\nWriting %ls ", outputFile.c_str()); PrintInfo(result.GetMetadata()); wprintf(L"\n"); fflush(stdout); if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; } } - hr = SaveImageFile(*dest, fileType, szOutputFile); + hr = SaveImageFile(*dest, fileType, outputFile.c_str()); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2528,19 +2504,19 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } // Write texture - wprintf(L"\nWriting %ls ", szOutputFile); + wprintf(L"\nWriting %ls ", outputFile.c_str()); PrintInfo(result.GetMetadata()); wprintf(L"\n"); fflush(stdout); if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; @@ -2549,7 +2525,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) hr = SaveToDDSFile(result.GetImages(), result.GetImageCount(), result.GetMetadata(), (dwOptions & (1 << OPT_USE_DX10)) ? (DDS_FLAGS_FORCE_DX10_EXT | DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE, - szOutputFile); + outputFile.c_str()); if (FAILED(hr)) { wprintf(L"\nFAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2641,19 +2617,19 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } // Write texture - wprintf(L"\nWriting %ls ", szOutputFile); + wprintf(L"\nWriting %ls ", outputFile.c_str()); PrintInfo(result.GetMetadata()); wprintf(L"\n"); fflush(stdout); if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; @@ -2662,7 +2638,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) hr = SaveToDDSFile(result.GetImages(), result.GetImageCount(), result.GetMetadata(), (dwOptions & (1 << OPT_USE_DX10)) ? (DDS_FLAGS_FORCE_DX10_EXT | DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE, - szOutputFile); + outputFile.c_str()); if (FAILED(hr)) { wprintf(L"\nFAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); diff --git a/Texconv/Texconv_Desktop_2019.vcxproj b/Texconv/Texconv_Desktop_2019.vcxproj index 16195b2..aa57838 100644 --- a/Texconv/Texconv_Desktop_2019.vcxproj +++ b/Texconv/Texconv_Desktop_2019.vcxproj @@ -298,6 +298,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2019.vcxproj.filters b/Texconv/Texconv_Desktop_2019.vcxproj.filters index 80e1359..b665e63 100644 --- a/Texconv/Texconv_Desktop_2019.vcxproj.filters +++ b/Texconv/Texconv_Desktop_2019.vcxproj.filters @@ -16,4 +16,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2019_Win10.vcxproj b/Texconv/Texconv_Desktop_2019_Win10.vcxproj index d573f61..c0c0008 100644 --- a/Texconv/Texconv_Desktop_2019_Win10.vcxproj +++ b/Texconv/Texconv_Desktop_2019_Win10.vcxproj @@ -431,6 +431,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2019_Win10.vcxproj.filters b/Texconv/Texconv_Desktop_2019_Win10.vcxproj.filters index 80e1359..b665e63 100644 --- a/Texconv/Texconv_Desktop_2019_Win10.vcxproj.filters +++ b/Texconv/Texconv_Desktop_2019_Win10.vcxproj.filters @@ -16,4 +16,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2022.vcxproj b/Texconv/Texconv_Desktop_2022.vcxproj index 6793125..a37a6d4 100644 --- a/Texconv/Texconv_Desktop_2022.vcxproj +++ b/Texconv/Texconv_Desktop_2022.vcxproj @@ -304,6 +304,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2022.vcxproj.filters b/Texconv/Texconv_Desktop_2022.vcxproj.filters index 80e1359..b665e63 100644 --- a/Texconv/Texconv_Desktop_2022.vcxproj.filters +++ b/Texconv/Texconv_Desktop_2022.vcxproj.filters @@ -16,4 +16,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2022_Win10.vcxproj b/Texconv/Texconv_Desktop_2022_Win10.vcxproj index 930b078..24e5c88 100644 --- a/Texconv/Texconv_Desktop_2022_Win10.vcxproj +++ b/Texconv/Texconv_Desktop_2022_Win10.vcxproj @@ -437,6 +437,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texconv/Texconv_Desktop_2022_Win10.vcxproj.filters b/Texconv/Texconv_Desktop_2022_Win10.vcxproj.filters index 80e1359..b665e63 100644 --- a/Texconv/Texconv_Desktop_2022_Win10.vcxproj.filters +++ b/Texconv/Texconv_Desktop_2022_Win10.vcxproj.filters @@ -16,4 +16,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texconv/settings.manifest b/Texconv/settings.manifest new file mode 100644 index 0000000..544e45d --- /dev/null +++ b/Texconv/settings.manifest @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + true + + + diff --git a/Texconv/texconv.cpp b/Texconv/texconv.cpp index d82a092..f7538b3 100644 --- a/Texconv/texconv.cpp +++ b/Texconv/texconv.cpp @@ -157,8 +157,8 @@ namespace struct SConversion { - wchar_t szSrc[MAX_PATH]; - wchar_t szFolder[MAX_PATH]; + std::wstring szSrc; + std::wstring szFolder; }; template @@ -570,11 +570,11 @@ namespace return L""; } - void SearchForFiles(const wchar_t* path, std::list& files, bool recursive, const wchar_t* folder) + void SearchForFiles(const std::filesystem::path& path, std::list& files, bool recursive, const wchar_t* folder) { // Process files WIN32_FIND_DATAW findData = {}; - ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path, + ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -584,15 +584,11 @@ namespace { if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY))) { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - SConversion conv = {}; - _wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr); + conv.szSrc = path.parent_path().append(findData.cFileName).native(); if (folder) { - wcscpy_s(conv.szFolder, folder); + conv.szFolder = folder; } files.push_back(conv); } @@ -605,15 +601,9 @@ namespace // Process directories if (recursive) { - wchar_t searchDir[MAX_PATH] = {}; - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - _wmakepath_s(searchDir, drive, dir, L"*", nullptr); - } + auto searchDir = path.parent_path().append(L"*"); - hFile.reset(safe_handle(FindFirstFileExW(searchDir, + hFile.reset(safe_handle(FindFirstFileExW(searchDir.c_str(), FindExInfoBasic, &findData, FindExSearchLimitToDirectories, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -626,19 +616,11 @@ namespace { if (findData.cFileName[0] != L'.') { - wchar_t subdir[MAX_PATH] = {}; auto subfolder = (folder) ? (std::wstring(folder) + std::wstring(findData.cFileName) + std::filesystem::path::preferred_separator) : (std::wstring(findData.cFileName) + std::filesystem::path::preferred_separator); - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - wchar_t fname[_MAX_FNAME] = {}; - wchar_t ext[_MAX_FNAME] = {}; - _wsplitpath_s(path, drive, dir, fname, ext); - wcscat_s(dir, findData.cFileName); - _wmakepath_s(subdir, drive, dir, fname, ext); - } + + auto subdir = path.parent_path().append(findData.cFileName).append(path.filename().c_str()); SearchForFiles(subdir, files, recursive, subfolder.c_str()); } @@ -654,36 +636,38 @@ namespace { std::list flist; std::set excludes; - wchar_t fname[1024] = {}; + + auto fname = std::make_unique(32768); for (;;) { - inFile >> fname; + inFile >> fname.get(); if (!inFile) break; - if (*fname == L'#') + if (fname[0] == L'#') { // Comment } - else if (*fname == L'-') + else if (fname[0] == L'-') { if (flist.empty()) { - wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname); + wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname.get()); } else { - std::filesystem::path path(fname + 1); + std::filesystem::path path(fname.get() + 1); auto& npath = path.make_preferred(); - if (wcspbrk(fname, L"?*") != nullptr) + if (wcspbrk(fname.get(), L"?*") != nullptr) { std::list removeFiles; - SearchForFiles(npath.c_str(), removeFiles, false, nullptr); + SearchForFiles(npath, removeFiles, false, nullptr); for (auto& it : removeFiles) { - _wcslwr_s(it.szSrc); - excludes.insert(it.szSrc); + std::wstring name = it.szSrc; + std::transform(name.begin(), name.end(), name.begin(), towlower); + excludes.insert(name); } } else @@ -694,16 +678,16 @@ namespace } } } - else if (wcspbrk(fname, L"?*") != nullptr) + else if (wcspbrk(fname.get(), L"?*") != nullptr) { - std::filesystem::path path(fname); - SearchForFiles(path.make_preferred().c_str(), flist, false, nullptr); + std::filesystem::path path(fname.get()); + SearchForFiles(path.make_preferred(), flist, false, nullptr); } else { SConversion conv = {}; - std::filesystem::path path(fname); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + std::filesystem::path path(fname.get()); + conv.szSrc = path.make_preferred().native(); flist.push_back(conv); } @@ -845,7 +829,7 @@ namespace wchar_t version[32] = {}; wchar_t appName[_MAX_PATH] = {}; - if (GetModuleFileNameW(nullptr, appName, static_cast(std::size(appName)))) + if (GetModuleFileNameW(nullptr, appName, _MAX_PATH)) { const DWORD size = GetFileVersionInfoSizeW(appName, nullptr); if (size > 0) @@ -1453,7 +1437,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) wchar_t szPrefix[MAX_PATH] = {}; wchar_t szSuffix[MAX_PATH] = {}; - wchar_t szOutputDir[MAX_PATH] = {}; + std::filesystem::path outputDir; // Set locale for output since GetErrorDesc can get localized strings. std::locale::global(std::locale("")); @@ -1675,7 +1659,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) case OPT_OUTPUTDIR: { std::filesystem::path path(pValue); - wcscpy_s(szOutputDir, path.make_preferred().c_str()); + outputDir = path.make_preferred(); } break; @@ -2033,7 +2017,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { const size_t count = conversion.size(); std::filesystem::path path(pArg); - SearchForFiles(path.make_preferred().c_str(), conversion, (dwOptions & (uint64_t(1) << OPT_RECURSIVE)) != 0, nullptr); + SearchForFiles(path.make_preferred(), conversion, (dwOptions & (uint64_t(1) << OPT_RECURSIVE)) != 0, nullptr); if (conversion.size() <= count) { wprintf(L"No matching files found for %ls\n", pArg); @@ -2044,7 +2028,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { SConversion conv = {}; std::filesystem::path path(pArg); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + conv.szSrc = path.make_preferred().native(); conversion.push_back(conv); } } @@ -2058,13 +2042,6 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (~dwOptions & (uint64_t(1) << OPT_NOLOGO)) PrintLogo(false); - // Work out out filename prefix and suffix - if (szOutputDir[0] && (std::filesystem::path::preferred_separator != szOutputDir[wcslen(szOutputDir) - 1])) - { - wchar_t pSeparator[2] = { std::filesystem::path::preferred_separator, 0 }; - wcscat_s(szOutputDir, MAX_PATH, pSeparator); - } - auto fileTypeName = LookupByValue(FileType, g_pSaveFileTypes); if (fileTypeName) @@ -2103,13 +2080,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) wprintf(L"\n"); // --- Load source image ------------------------------------------------------- - wprintf(L"reading %ls", pConv->szSrc); + wprintf(L"reading %ls", pConv->szSrc.c_str()); fflush(stdout); - wchar_t ext[_MAX_EXT] = {}; - wchar_t fname[_MAX_FNAME] = {}; - _wsplitpath_s(pConv->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT); - TexMetadata info; std::unique_ptr image(new (std::nothrow) ScratchImage); @@ -2119,7 +2092,10 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) return 1; } - if (_wcsicmp(ext, L".dds") == 0 || _wcsicmp(ext, L".ddx") == 0) + std::filesystem::path curpath(pConv->szSrc); + auto const ext = curpath.extension(); + + if (_wcsicmp(ext.c_str(), L".dds") == 0 || _wcsicmp(ext.c_str(), L".ddx") == 0) { DDS_FLAGS ddsFlags = DDS_FLAGS_ALLOW_LARGE_FILES; if (dwOptions & (uint64_t(1) << OPT_DDS_DWORD_ALIGN)) @@ -2129,7 +2105,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (dwOptions & (uint64_t(1) << OPT_DDS_BAD_DXTN_TAILS)) ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS; - hr = LoadFromDDSFile(pConv->szSrc, ddsFlags, &info, *image); + hr = LoadFromDDSFile(curpath.c_str(), ddsFlags, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2158,9 +2134,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) image->OverrideFormat(info.format); } } - else if (_wcsicmp(ext, L".bmp") == 0) + else if (_wcsicmp(ext.c_str(), L".bmp") == 0) { - hr = LoadFromBMPEx(pConv->szSrc, WIC_FLAGS_NONE | dwFilter, &info, *image); + hr = LoadFromBMPEx(curpath.c_str(), WIC_FLAGS_NONE | dwFilter, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2168,7 +2144,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) continue; } } - else if (_wcsicmp(ext, L".tga") == 0) + else if (_wcsicmp(ext.c_str(), L".tga") == 0) { TGA_FLAGS tgaFlags = (IsBGR(format)) ? TGA_FLAGS_BGR : TGA_FLAGS_NONE; if (dwOptions & (uint64_t(1) << OPT_TGAZEROALPHA)) @@ -2176,7 +2152,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) tgaFlags |= TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA; } - hr = LoadFromTGAFile(pConv->szSrc, tgaFlags, &info, *image); + hr = LoadFromTGAFile(curpath.c_str(), tgaFlags, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2184,9 +2160,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) continue; } } - else if (_wcsicmp(ext, L".hdr") == 0) + else if (_wcsicmp(ext.c_str(), L".hdr") == 0) { - hr = LoadFromHDRFile(pConv->szSrc, &info, *image); + hr = LoadFromHDRFile(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2194,9 +2170,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) continue; } } - else if (_wcsicmp(ext, L".ppm") == 0) + else if (_wcsicmp(ext.c_str(), L".ppm") == 0) { - hr = LoadFromPortablePixMap(pConv->szSrc, &info, *image); + hr = LoadFromPortablePixMap(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2204,9 +2180,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) continue; } } - else if (_wcsicmp(ext, L".pfm") == 0) + else if (_wcsicmp(ext.c_str(), L".pfm") == 0) { - hr = LoadFromPortablePixMapHDR(pConv->szSrc, &info, *image); + hr = LoadFromPortablePixMapHDR(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2215,9 +2191,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } } #ifdef USE_OPENEXR - else if (_wcsicmp(ext, L".exr") == 0) + else if (_wcsicmp(ext.c_str(), L".exr") == 0) { - hr = LoadFromEXRFile(pConv->szSrc, &info, *image); + hr = LoadFromEXRFile(curpath.c_str(), &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -2240,18 +2216,18 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (FileType == CODEC_DDS) wicFlags |= WIC_FLAGS_ALL_FRAMES; - hr = LoadFromWICFile(pConv->szSrc, wicFlags, &info, *image); + hr = LoadFromWICFile(curpath.c_str(), wicFlags, &info, *image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); retVal = 1; if (hr == static_cast(0xc00d5212) /* MF_E_TOPO_CODEC_NOT_FOUND */) { - if (_wcsicmp(ext, L".heic") == 0 || _wcsicmp(ext, L".heif") == 0) + if (_wcsicmp(ext.c_str(), L".heic") == 0 || _wcsicmp(ext.c_str(), L".heif") == 0) { wprintf(L"INFO: This format requires installing the HEIF Image Extensions - https://aka.ms/heif\n"); } - else if (_wcsicmp(ext, L".webp") == 0) + else if (_wcsicmp(ext.c_str(), L".webp") == 0) { wprintf(L"INFO: This format requires installing the WEBP Image Extensions - https://www.microsoft.com/p/webp-image-extensions/9pg2dk419drg\n"); } @@ -3714,25 +3690,23 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) wprintf(L"\n"); // Figure out dest filename - wchar_t *pchSlash, *pchDot; + std::filesystem::path dest(outputDir); - wchar_t szDest[1024] = {}; - wcscpy_s(szDest, szOutputDir); - - if (keepRecursiveDirs && *pConv->szFolder) + if (keepRecursiveDirs && !pConv->szFolder.empty()) { - wcscat_s(szDest, pConv->szFolder); + dest.append(pConv->szFolder.c_str()); - wchar_t szPath[MAX_PATH] = {}; - if (!GetFullPathNameW(szDest, MAX_PATH, szPath, nullptr)) + std::error_code ec; + auto apath = std::filesystem::absolute(dest, ec); + + if (ec) { - wprintf(L" get full path FAILED (%08X%ls)\n", - static_cast(HRESULT_FROM_WIN32(GetLastError())), GetErrorDesc(HRESULT_FROM_WIN32(GetLastError()))); + wprintf(L" get full path FAILED (%hs)\n", ec.message().c_str()); retVal = 1; continue; } - auto const err = static_cast(SHCreateDirectoryExW(nullptr, szPath, nullptr)); + auto const err = static_cast(SHCreateDirectoryExW(nullptr, apath.c_str(), nullptr)); if (err != ERROR_SUCCESS && err != ERROR_ALREADY_EXISTS) { wprintf(L" directory creation FAILED (%08X%ls)\n", @@ -3743,42 +3717,30 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } if (*szPrefix) - wcscat_s(szDest, szPrefix); - - pchSlash = wcsrchr(pConv->szSrc, std::filesystem::path::preferred_separator); - if (pchSlash) - wcscat_s(szDest, pchSlash + 1); - else - wcscat_s(szDest, pConv->szSrc); - - pchSlash = wcsrchr(szDest, std::filesystem::path::preferred_separator); - pchDot = wcsrchr(szDest, '.'); - - if (pchDot > pchSlash) - *pchDot = 0; - - if (*szSuffix) - wcscat_s(szDest, szSuffix); - - if (dwOptions & (uint64_t(1) << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szDest); + dest.append(szPrefix); + dest.concat(curpath.stem().c_str()); + dest.concat(szSuffix); + } + else + { + dest.append(curpath.stem().c_str()); + dest.concat(szSuffix); } - if (wcslen(szDest) > _MAX_PATH) + std::wstring destName = dest.c_str(); + if (dwOptions & (uint64_t(1) << OPT_TOLOWER)) { - wprintf(L"\nERROR: Output filename exceeds max-path, skipping!\n"); - retVal = 1; - continue; + std::transform(destName.begin(), destName.end(), destName.begin(), towlower); } // Write texture - wprintf(L"writing %ls", szDest); + wprintf(L"writing %ls", destName.c_str()); fflush(stdout); if (~dwOptions & (uint64_t(1) << OPT_OVERWRITE)) { - if (GetFileAttributesW(szDest) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(destName.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite:\n"); retVal = 1; @@ -3805,29 +3767,29 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) ddsFlags |= DDS_FLAGS_FORCE_DX9_LEGACY; } - hr = SaveToDDSFile(img, nimg, info, ddsFlags, szDest); + hr = SaveToDDSFile(img, nimg, info, ddsFlags, destName.c_str()); break; } case CODEC_TGA: - hr = SaveToTGAFile(img[0], TGA_FLAGS_NONE, szDest, (dwOptions & (uint64_t(1) << OPT_TGA20)) ? &info : nullptr); + hr = SaveToTGAFile(img[0], TGA_FLAGS_NONE, destName.c_str(), (dwOptions & (uint64_t(1) << OPT_TGA20)) ? &info : nullptr); break; case CODEC_HDR: - hr = SaveToHDRFile(img[0], szDest); + hr = SaveToHDRFile(img[0], destName.c_str()); break; case CODEC_PPM: - hr = SaveToPortablePixMap(img[0], szDest); + hr = SaveToPortablePixMap(img[0], destName.c_str()); break; case CODEC_PFM: - hr = SaveToPortablePixMapHDR(img[0], szDest); + hr = SaveToPortablePixMapHDR(img[0], destName.c_str()); break; #ifdef USE_OPENEXR case CODEC_EXR: - hr = SaveToEXRFile(img[0], szDest); + hr = SaveToEXRFile(img[0], destName.c_str()); break; #endif @@ -3835,7 +3797,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { const WICCodecs codec = (FileType == CODEC_HDP || FileType == CODEC_JXR) ? WIC_CODEC_WMP : static_cast(FileType); const size_t nimages = (dwOptions & (uint64_t(1) << OPT_WIC_MULTIFRAME)) ? nimg : 1; - hr = SaveToWICFile(img, nimages, WIC_FLAGS_NONE, GetWICCodec(codec), szDest, nullptr, + hr = SaveToWICFile(img, nimages, WIC_FLAGS_NONE, GetWICCodec(codec), destName.c_str(), nullptr, [&](IPropertyBag2* props) { const bool wicLossless = (dwOptions & (uint64_t(1) << OPT_WIC_LOSSLESS)) != 0; diff --git a/Texdiag/settings.manifest b/Texdiag/settings.manifest new file mode 100644 index 0000000..544e45d --- /dev/null +++ b/Texdiag/settings.manifest @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + true + + + diff --git a/Texdiag/texdiag.cpp b/Texdiag/texdiag.cpp index b2fde0c..324effb 100644 --- a/Texdiag/texdiag.cpp +++ b/Texdiag/texdiag.cpp @@ -100,7 +100,7 @@ static_assert(OPT_MAX <= 32, "dwOptions is a unsigned int bitfield"); struct SConversion { - wchar_t szSrc[MAX_PATH]; + std::wstring szSrc; }; struct SValue @@ -422,11 +422,11 @@ namespace return L""; } - void SearchForFiles(const wchar_t* path, std::list& files, bool recursive) + void SearchForFiles(const std::filesystem::path& path, std::list& files, bool recursive) { // Process files WIN32_FIND_DATAW findData = {}; - ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path, + ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -436,12 +436,8 @@ namespace { if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY))) { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - SConversion conv = {}; - _wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr); + conv.szSrc = path.parent_path().append(findData.cFileName).native(); files.push_back(conv); } @@ -453,15 +449,9 @@ namespace // Process directories if (recursive) { - wchar_t searchDir[MAX_PATH] = {}; - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); - _wmakepath_s(searchDir, drive, dir, L"*", nullptr); - } + auto searchDir = path.parent_path().append(L"*"); - hFile.reset(safe_handle(FindFirstFileExW(searchDir, + hFile.reset(safe_handle(FindFirstFileExW(searchDir.c_str(), FindExInfoBasic, &findData, FindExSearchLimitToDirectories, nullptr, FIND_FIRST_EX_LARGE_FETCH))); @@ -474,17 +464,7 @@ namespace { if (findData.cFileName[0] != L'.') { - wchar_t subdir[MAX_PATH] = {}; - - { - wchar_t drive[_MAX_DRIVE] = {}; - wchar_t dir[_MAX_DIR] = {}; - wchar_t fname[_MAX_FNAME] = {}; - wchar_t ext[_MAX_FNAME] = {}; - _wsplitpath_s(path, drive, dir, fname, ext); - wcscat_s(dir, findData.cFileName); - _wmakepath_s(subdir, drive, dir, fname, ext); - } + auto subdir = path.parent_path().append(findData.cFileName).append(path.filename().c_str()); SearchForFiles(subdir, files, recursive); } @@ -500,36 +480,38 @@ namespace { std::list flist; std::set excludes; - wchar_t fname[1024] = {}; + + auto fname = std::make_unique(32768); for (;;) { - inFile >> fname; + inFile >> fname.get(); if (!inFile) break; - if (*fname == L'#') + if (fname[0] == L'#') { // Comment } - else if (*fname == L'-') + else if (fname[0] == L'-') { if (flist.empty()) { - wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname); + wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname.get()); } else { - std::filesystem::path path(fname + 1); + std::filesystem::path path(fname.get() + 1); auto& npath = path.make_preferred(); - if (wcspbrk(fname, L"?*") != nullptr) + if (wcspbrk(fname.get(), L"?*") != nullptr) { std::list removeFiles; - SearchForFiles(npath.c_str(), removeFiles, false); + SearchForFiles(npath, removeFiles, false); for (auto& it : removeFiles) { - _wcslwr_s(it.szSrc); - excludes.insert(it.szSrc); + std::wstring name = it.szSrc; + std::transform(name.begin(), name.end(), name.begin(), towlower); + excludes.insert(name); } } else @@ -540,16 +522,16 @@ namespace } } } - else if (wcspbrk(fname, L"?*") != nullptr) + else if (wcspbrk(fname.get(), L"?*") != nullptr) { - std::filesystem::path path(fname); - SearchForFiles(path.make_preferred().c_str(), flist, false); + std::filesystem::path path(fname.get()); + SearchForFiles(path.make_preferred(), flist, false); } else { SConversion conv = {}; - std::filesystem::path path(fname); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + std::filesystem::path path(fname.get()); + conv.szSrc = path.make_preferred().native(); flist.push_back(conv); } @@ -632,7 +614,7 @@ namespace wchar_t version[32] = {}; wchar_t appName[_MAX_PATH] = {}; - if (GetModuleFileNameW(nullptr, appName, static_cast(std::size(appName)))) + if (GetModuleFileNameW(nullptr, appName, _MAX_PATH)) { const DWORD size = GetFileVersionInfoSizeW(appName, nullptr); if (size > 0) @@ -778,10 +760,10 @@ namespace if (!image) return E_OUTOFMEMORY; - wchar_t ext[_MAX_EXT] = {}; - _wsplitpath_s(fileName, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT); + std::filesystem::path fname(fileName); + auto const ext = fname.extension(); - if (_wcsicmp(ext, L".dds") == 0) + if (_wcsicmp(ext.c_str(), L".dds") == 0) { DDS_FLAGS ddsFlags = DDS_FLAGS_ALLOW_LARGE_FILES; if (dwOptions & (1 << OPT_DDS_DWORD_ALIGN)) @@ -814,16 +796,16 @@ namespace return S_OK; } - else if (_wcsicmp(ext, L".tga") == 0) + else if (_wcsicmp(ext.c_str(), L".tga") == 0) { return LoadFromTGAFile(fileName, TGA_FLAGS_NONE, &info, *image); } - else if (_wcsicmp(ext, L".hdr") == 0) + else if (_wcsicmp(ext.c_str(), L".hdr") == 0) { return LoadFromHDRFile(fileName, &info, *image); } #ifdef USE_OPENEXR - else if (_wcsicmp(ext, L".exr") == 0) + else if (_wcsicmp(ext.c_str(), L".exr") == 0) { return LoadFromEXRFile(fileName, &info, *image); } @@ -841,11 +823,11 @@ namespace HRESULT hr = LoadFromWICFile(fileName, dwFilter | WIC_FLAGS_ALL_FRAMES, &info, *image); if (hr == static_cast(0xc00d5212) /* MF_E_TOPO_CODEC_NOT_FOUND */) { - if (_wcsicmp(ext, L".heic") == 0 || _wcsicmp(ext, L".heif") == 0) + if (_wcsicmp(ext.c_str(), L".heic") == 0 || _wcsicmp(ext.c_str(), L".heif") == 0) { wprintf(L"\nINFO: This format requires installing the HEIF Image Extensions - https://aka.ms/heif\n"); } - else if (_wcsicmp(ext, L".webp") == 0) + else if (_wcsicmp(ext.c_str(), L".webp") == 0) { wprintf(L"\nINFO: This format requires installing the WEBP Image Extensions - https://www.microsoft.com/p/webp-image-extensions/9pg2dk419drg\n"); } @@ -3271,7 +3253,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) float threshold = 0.25f; DXGI_FORMAT diffFormat = DXGI_FORMAT_B8G8R8A8_UNORM; uint32_t fileType = WIC_CODEC_BMP; - wchar_t szOutputFile[MAX_PATH] = {}; + std::wstring outputFile; // Set locale for output since GetErrorDesc can get localized strings. std::locale::global(std::locale("")); @@ -3444,12 +3426,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) else { std::filesystem::path path(pValue); - wcscpy_s(szOutputFile, path.make_preferred().c_str()); + outputFile = path.make_preferred().native(); - wchar_t ext[_MAX_EXT] = {}; - _wsplitpath_s(szOutputFile, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT); - - fileType = LookupByName(ext, g_pExtFileTypes); + fileType = LookupByName(path.extension().c_str(), g_pExtFileTypes); } break; @@ -3543,7 +3522,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { const size_t count = conversion.size(); std::filesystem::path path(pArg); - SearchForFiles(path.make_preferred().c_str(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0); + SearchForFiles(path.make_preferred(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0); if (conversion.size() <= count) { wprintf(L"No matching files found for %ls\n", pArg); @@ -3554,7 +3533,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { SConversion conv = {}; std::filesystem::path path(pArg); - wcscpy_s(conv.szSrc, path.make_preferred().c_str()); + conv.szSrc = path.make_preferred().native(); conversion.push_back(conv); } } @@ -3582,12 +3561,12 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { auto pImage1 = conversion.cbegin(); - wprintf(L"1: %ls", pImage1->szSrc); + wprintf(L"1: %ls", pImage1->szSrc.c_str()); fflush(stdout); TexMetadata info1; std::unique_ptr image1; - hr = LoadImage(pImage1->szSrc, dwOptions, dwFilter, info1, image1); + hr = LoadImage(pImage1->szSrc.c_str(), dwOptions, dwFilter, info1, image1); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -3597,12 +3576,12 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) auto pImage2 = conversion.cbegin(); std::advance(pImage2, 1); - wprintf(L"\n2: %ls", pImage2->szSrc); + wprintf(L"\n2: %ls", pImage2->szSrc.c_str()); fflush(stdout); TexMetadata info2; std::unique_ptr image2; - hr = LoadImage(pImage2->szSrc, dwOptions, dwFilter, info2, image2); + hr = LoadImage(pImage2->szSrc.c_str(), dwOptions, dwFilter, info2, image2); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -3621,18 +3600,18 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (dwCommand == CMD_DIFF) { - if (!*szOutputFile) + if (outputFile.empty()) { - wchar_t ext[_MAX_EXT] = {}; - wchar_t fname[_MAX_FNAME] = {}; - _wsplitpath_s(pImage1->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT); - if (_wcsicmp(ext, L".bmp") == 0) + std::filesystem::path curpath(pImage1->szSrc); + auto const ext = curpath.extension(); + + if (_wcsicmp(ext.c_str(), L".bmp") == 0) { wprintf(L"ERROR: Need to specify output file via -o\n"); return 1; } - _wmakepath_s(szOutputFile, nullptr, nullptr, fname, L".bmp"); + outputFile = curpath.stem().concat(L".bmp").native(); } if (image1->GetImageCount() > 1 || image2->GetImageCount() > 1) @@ -3648,26 +3627,26 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) if (dwOptions & (1 << OPT_TOLOWER)) { - std::ignore = _wcslwr_s(szOutputFile); + std::transform(outputFile.begin(), outputFile.end(), outputFile.begin(), towlower); } if (~dwOptions & (1 << OPT_OVERWRITE)) { - if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(outputFile.c_str()) != INVALID_FILE_ATTRIBUTES) { wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n"); return 1; } } - hr = SaveImage(diffImage.GetImage(0, 0, 0), szOutputFile, fileType); + hr = SaveImage(diffImage.GetImage(0, 0, 0), outputFile.c_str(), fileType); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); return 1; } - wprintf(L"Difference %ls\n", szOutputFile); + wprintf(L"Difference %ls\n", outputFile.c_str()); } else if ((info1.depth == 1 && info1.arraySize == 1 @@ -3831,16 +3810,18 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) default: for (auto pConv = conversion.cbegin(); pConv != conversion.cend(); ++pConv) { + std::filesystem::path curpath(pConv->szSrc); + // Load source image if (pConv != conversion.begin()) wprintf(L"\n"); - wprintf(L"%ls", pConv->szSrc); + wprintf(L"%ls", curpath.c_str()); fflush(stdout); TexMetadata info; std::unique_ptr image; - hr = LoadImage(pConv->szSrc, dwOptions, dwFilter, info, image); + hr = LoadImage(curpath.c_str(), dwOptions, dwFilter, info, image); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -3918,11 +3899,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) return 1; } - wchar_t ext[_MAX_EXT] = {}; - wchar_t fname[_MAX_FNAME] = {}; - _wsplitpath_s(pConv->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, nullptr, 0); - - wcscpy_s(ext, LookupByValue(fileType, g_pDumpFileTypes)); + auto const ext = LookupByValue(fileType, g_pDumpFileTypes); if (info.depth > 1) { @@ -3942,19 +3919,20 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } else { - wchar_t subFname[_MAX_FNAME] = {}; + wchar_t subFname[_MAX_PATH] = {}; if (info.mipLevels > 1) { - swprintf_s(subFname, L"%ls_slice%03zu_mip%03zu", fname, slice, mip); + swprintf_s(subFname, L"%ls_slice%03zu_mip%03zu", curpath.stem().c_str(), slice, mip); } else { - swprintf_s(subFname, L"%ls_slice%03zu", fname, slice); + swprintf_s(subFname, L"%ls_slice%03zu", curpath.stem().c_str(), slice); } - _wmakepath_s(szOutputFile, nullptr, nullptr, subFname, ext); + outputFile.assign(subFname); + outputFile.append(ext); - hr = SaveImage(img, szOutputFile, fileType); + hr = SaveImage(img, outputFile.c_str(), fileType); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); @@ -3985,19 +3963,20 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) } else { - wchar_t subFname[_MAX_FNAME]; + wchar_t subFname[_MAX_PATH] = {}; if (info.mipLevels > 1) { - swprintf_s(subFname, L"%ls_item%03zu_mip%03zu", fname, item, mip); + swprintf_s(subFname, L"%ls_item%03zu_mip%03zu", curpath.stem().c_str(), item, mip); } else { - swprintf_s(subFname, L"%ls_item%03zu", fname, item); + swprintf_s(subFname, L"%ls_item%03zu", curpath.stem().c_str(), item); } - _wmakepath_s(szOutputFile, nullptr, nullptr, subFname, ext); + outputFile.assign(subFname); + outputFile.append(ext); - hr = SaveImage(img, szOutputFile, fileType); + hr = SaveImage(img, outputFile.c_str(), fileType); if (FAILED(hr)) { wprintf(L" FAILED (%08X%ls)\n", static_cast(hr), GetErrorDesc(hr)); diff --git a/Texdiag/texdiag_Desktop_2019.vcxproj b/Texdiag/texdiag_Desktop_2019.vcxproj index 2bae518..3e44877 100644 --- a/Texdiag/texdiag_Desktop_2019.vcxproj +++ b/Texdiag/texdiag_Desktop_2019.vcxproj @@ -290,6 +290,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2019.vcxproj.filters b/Texdiag/texdiag_Desktop_2019.vcxproj.filters index 3a2f907..b4b97ed 100644 --- a/Texdiag/texdiag_Desktop_2019.vcxproj.filters +++ b/Texdiag/texdiag_Desktop_2019.vcxproj.filters @@ -14,4 +14,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2019_Win10.vcxproj b/Texdiag/texdiag_Desktop_2019_Win10.vcxproj index a0e6c6a..b060e74 100644 --- a/Texdiag/texdiag_Desktop_2019_Win10.vcxproj +++ b/Texdiag/texdiag_Desktop_2019_Win10.vcxproj @@ -420,6 +420,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2019_Win10.vcxproj.filters b/Texdiag/texdiag_Desktop_2019_Win10.vcxproj.filters index 3a2f907..b4b97ed 100644 --- a/Texdiag/texdiag_Desktop_2019_Win10.vcxproj.filters +++ b/Texdiag/texdiag_Desktop_2019_Win10.vcxproj.filters @@ -14,4 +14,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2022.vcxproj b/Texdiag/texdiag_Desktop_2022.vcxproj index 0fe694a..8dd2198 100644 --- a/Texdiag/texdiag_Desktop_2022.vcxproj +++ b/Texdiag/texdiag_Desktop_2022.vcxproj @@ -296,6 +296,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2022.vcxproj.filters b/Texdiag/texdiag_Desktop_2022.vcxproj.filters index 3a2f907..b4b97ed 100644 --- a/Texdiag/texdiag_Desktop_2022.vcxproj.filters +++ b/Texdiag/texdiag_Desktop_2022.vcxproj.filters @@ -14,4 +14,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2022_Win10.vcxproj b/Texdiag/texdiag_Desktop_2022_Win10.vcxproj index a99a5ac..b986776 100644 --- a/Texdiag/texdiag_Desktop_2022_Win10.vcxproj +++ b/Texdiag/texdiag_Desktop_2022_Win10.vcxproj @@ -426,6 +426,9 @@ {371b9fa9-4c90-4ac6-a123-aced756d6c77} + + + \ No newline at end of file diff --git a/Texdiag/texdiag_Desktop_2022_Win10.vcxproj.filters b/Texdiag/texdiag_Desktop_2022_Win10.vcxproj.filters index 3a2f907..b4b97ed 100644 --- a/Texdiag/texdiag_Desktop_2022_Win10.vcxproj.filters +++ b/Texdiag/texdiag_Desktop_2022_Win10.vcxproj.filters @@ -14,4 +14,9 @@ Resource Files + + + Resource Files + + \ No newline at end of file