mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-23 17:45:46 +00:00
203 lines
5.8 KiB
C++
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>();
|
|
}
|