mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
98 lines
2.2 KiB
C++
98 lines
2.2 KiB
C++
#include <DirectXPackedVector.h>
|
|
#include <DirectXTex.h>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
static std::wstring UTF8ToUTF16(std::string_view str) noexcept {
|
|
int convertResult = MultiByteToWideChar(CP_ACP, 0, str.data(), (int)str.size(), nullptr, 0);
|
|
if (convertResult <= 0) {
|
|
assert(false);
|
|
return {};
|
|
}
|
|
|
|
std::wstring r(convertResult + 10, L'\0');
|
|
convertResult = MultiByteToWideChar(CP_ACP, 0, str.data(), (int)str.size(), &r[0], (int)r.size());
|
|
if (convertResult <= 0) {
|
|
assert(false);
|
|
return {};
|
|
}
|
|
|
|
return std::wstring(r.begin(), r.begin() + convertResult);
|
|
}
|
|
|
|
static BYTE ResolveHex(char c) noexcept {
|
|
if (c >= '0' && c <= '9') {
|
|
return c - '0';
|
|
} else if (c >= 'a' && c <= 'f') {
|
|
return c - 'a' + 10;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
SetConsoleOutputCP(CP_UTF8);
|
|
|
|
if (argc != 3) {
|
|
std::wcout << "非法参数" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
const char* inFile = argv[1];
|
|
const char* outFile = argv[2];
|
|
|
|
std::ifstream ifs(inFile);
|
|
if (!ifs) {
|
|
std::wcout << L"打开" << inFile << L"失败" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
size_t width, height;
|
|
ifs >> width >> height;
|
|
ifs.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
|
|
|
std::vector<DirectX::PackedVector::HALF> data(width * height * 4);
|
|
|
|
for (size_t i = 0; i < data.size(); ++i) {
|
|
// 解析 32 位浮点数
|
|
union {
|
|
UINT i;
|
|
FLOAT f;
|
|
} binary{};
|
|
|
|
for (int j = 0; j < 4; ++j) {
|
|
char c1 = (char)ifs.get();
|
|
char c2 = (char)ifs.get();
|
|
|
|
if (!ifs) {
|
|
std::cout << "非法的文件格式" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
binary.i |= ((ResolveHex(c1) << 4) + ResolveHex(c2)) << (j * 8);
|
|
}
|
|
|
|
// 转换为半精度浮点数
|
|
data[i] = DirectX::PackedVector::XMConvertFloatToHalf(binary.f);
|
|
}
|
|
|
|
// 保存 DDS
|
|
DirectX::Image img{};
|
|
img.width = width;
|
|
img.height = height;
|
|
img.format = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
|
img.pixels = (uint8_t*)data.data();
|
|
img.rowPitch = width * 8;
|
|
img.slicePitch = img.rowPitch * height;
|
|
|
|
HRESULT hr = DirectX::SaveToDDSFile(img, DirectX::DDS_FLAGS_NONE, UTF8ToUTF16(outFile).c_str());
|
|
if (FAILED(hr)) {
|
|
std::cout << "保存 DDS 失败";
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "已生成 " << outFile << std::endl;
|
|
return 0;
|
|
}
|