OpenAssetTools/src/ImageConverter/ImageConverter.cpp
2024-09-27 20:31:33 +02:00

203 lines
5.8 KiB
C++

#include "ImageConverter.h"
#include "Image/DdsLoader.h"
#include "Image/DdsWriter.h"
#include "Image/IwiLoader.h"
#include "Image/IwiWriter13.h"
#include "Image/IwiWriter27.h"
#include "Image/IwiWriter6.h"
#include "Image/IwiWriter8.h"
#include "Image/Texture.h"
#include "ImageConverterArgs.h"
#include "Utils/StringUtils.h"
#include <assert.h>
#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
namespace image_converter
{
constexpr auto EXTENSION_IWI = ".iwi";
constexpr auto EXTENSION_DDS = ".dds";
class ImageConverterImpl final : public ImageConverter
{
public:
ImageConverterImpl()
: m_game_to_convert_to(image_converter::Game::UNKNOWN)
{
}
bool Start(const int argc, const char** argv) override
{
auto shouldContinue = true;
if (!m_args.ParseArgs(argc, argv, shouldContinue))
return false;
if (!shouldContinue)
return true;
m_game_to_convert_to = m_args.m_game_to_convert_to;
for (const auto& file : m_args.m_files_to_convert)
Convert(file);
return true;
}
private:
void Convert(const std::string& file)
{
const fs::path filePath(file);
auto extension = filePath.extension().string();
utils::MakeStringLowerCase(extension);
if (extension == EXTENSION_IWI)
ConvertIwi(filePath);
else if (extension == EXTENSION_DDS)
ConvertDds(filePath);
else
std::cerr << std::format("Unsupported extension {}\n", extension);
}
bool ConvertIwi(const fs::path& iwiPath)
{
std::ifstream file(iwiPath, std::ios::in | std::ios::binary);
if (!file.is_open())
{
std::cerr << std::format("Failed to open input file {}\n", iwiPath.string());
return false;
}
const auto texture = iwi::LoadIwi(file);
if (!texture)
return false;
auto outPath = iwiPath;
outPath.replace_extension(".dds");
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
if (!outFile.is_open())
{
std::cerr << std::format("Failed to open output file {}\n", outPath.string());
return false;
}
m_dds_writer.DumpImage(outFile, texture.get());
return true;
}
bool ConvertDds(const fs::path& ddsPath)
{
std::ifstream file(ddsPath, std::ios::in | std::ios::binary);
if (!file.is_open())
{
std::cerr << std::format("Failed to open input file {}\n", ddsPath.string());
return false;
}
const auto texture = dds::LoadDds(file);
if (!texture)
return false;
if (!EnsureIwiWriterIsPresent())
return false;
auto outPath = ddsPath;
outPath.replace_extension(".iwi");
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
if (!outFile.is_open())
{
std::cerr << std::format("Failed to open output file {}\n", outPath.string());
return false;
}
m_iwi_writer->DumpImage(outFile, texture.get());
return true;
}
bool EnsureIwiWriterIsPresent()
{
if (m_iwi_writer)
return true;
if (m_game_to_convert_to == Game::UNKNOWN && !ShowGameTui())
return false;
switch (m_game_to_convert_to)
{
case Game::IW3:
m_iwi_writer = std::make_unique<iwi6::IwiWriter>();
break;
case Game::IW4:
case Game::IW5:
m_iwi_writer = std::make_unique<iwi8::IwiWriter>();
break;
case Game::T5:
m_iwi_writer = std::make_unique<iwi13::IwiWriter>();
break;
case Game::T6:
m_iwi_writer = std::make_unique<iwi27::IwiWriter>();
break;
default:
assert(false);
return false;
}
return true;
}
bool ShowGameTui()
{
std::cout << "Select the game to convert to:\n";
std::cout << " 1 - Call Of Duty 4: Modern Warfare (IW3)\n";
std::cout << " 2 - Call Of Duty: Modern Warfare 2 (IW4)\n";
std::cout << " 3 - Call Of Duty: Modern Warfare 3 (IW5)\n";
std::cout << " 4 - Call Of Duty: Black Ops (T5)\n";
std::cout << " 5 - Call Of Duty: Black Ops 2 (T6)\n";
unsigned num;
std::cin >> num;
switch (num)
{
case 1:
m_game_to_convert_to = Game::IW3;
break;
case 2:
m_game_to_convert_to = Game::IW4;
break;
case 3:
m_game_to_convert_to = Game::IW5;
break;
case 4:
m_game_to_convert_to = Game::T5;
break;
case 5:
m_game_to_convert_to = Game::T6;
break;
default:
std::cerr << "Invalid input\n";
return false;
}
return true;
}
ImageConverterArgs m_args;
image_converter::Game m_game_to_convert_to;
DdsWriter m_dds_writer;
std::unique_ptr<IImageWriter> m_iwi_writer;
};
} // namespace image_converter
std::unique_ptr<ImageConverter> ImageConverter::Create()
{
return std::make_unique<image_converter::ImageConverterImpl>();
}