1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 11:22:45 +01:00
openrw/rwcore/loaders/LoaderIMG.cpp
Daniel Evans 4fd92a1549 Rename rwlib library to "core" to fit its new role
Also move up source files into the root directory, as there's nothing else in this directory
2018-08-09 20:28:24 +01:00

108 lines
2.9 KiB
C++

#include "loaders/LoaderIMG.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <cstdio>
#include "rw/debug.hpp"
LoaderIMG::LoaderIMG() : m_version(GTAIIIVC), m_assetCount(0) {
}
bool LoaderIMG::load(const rwfs::path& filepath) {
auto dirPath = filepath;
dirPath.replace_extension(".dir");
FILE* fp = fopen(dirPath.string().c_str(), "rb");
if (fp) {
fseek(fp, 0, SEEK_END);
unsigned long fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
m_assetCount = fileSize / 32;
m_assets.resize(m_assetCount);
if ((m_assetCount = fread(&m_assets[0], sizeof(LoaderIMGFile),
m_assetCount, fp)) != fileSize / 32) {
m_assets.resize(m_assetCount);
RW_ERROR("Error reading records in IMG archive");
}
fclose(fp);
auto imgPath = filepath;
imgPath.replace_extension(".img");
m_archive = imgPath;
return true;
} else {
return false;
}
}
/// Get the information of a asset in the examining archive
bool LoaderIMG::findAssetInfo(const std::string& assetname,
LoaderIMGFile& out) {
for (auto &asset : m_assets) {
if (boost::iequals(asset.name, assetname)) {
out = asset;
return true;
}
}
return false;
}
std::unique_ptr<char[]> LoaderIMG::loadToMemory(const std::string& assetname) {
LoaderIMGFile assetInfo;
bool found = findAssetInfo(assetname, assetInfo);
if (!found) {
RW_ERROR("Asset '" << assetname << "' not found!");
return nullptr;
}
auto imgName = m_archive;
FILE* fp = fopen(imgName.string().c_str(), "rb");
if (fp) {
auto raw_data = std::make_unique<char[]>(assetInfo.size * 2048);
fseek(fp, assetInfo.offset * 2048, SEEK_SET);
if (fread(raw_data.get(), 2048, assetInfo.size, fp) != assetInfo.size) {
RW_ERROR("Error reading asset " << assetInfo.name);
}
fclose(fp);
return raw_data;
} else
return nullptr;
}
/// Writes the contents of assetname to filename
bool LoaderIMG::saveAsset(const std::string& assetname,
const std::string& filename) {
auto raw_data = loadToMemory(assetname);
if (!raw_data) return false;
FILE* dumpFile = fopen(filename.c_str(), "wb");
if (dumpFile) {
LoaderIMGFile asset;
if (findAssetInfo(assetname, asset)) {
fwrite(raw_data.get(), 2048, asset.size, dumpFile);
printf("=> IMG: Saved %s to disk with filename %s\n",
assetname.c_str(), filename.c_str());
}
fclose(dumpFile);
return true;
} else {
return false;
}
}
/// Get the information of an asset by its index
const LoaderIMGFile& LoaderIMG::getAssetInfoByIndex(size_t index) const {
return m_assets[index];
}
uint32_t LoaderIMG::getAssetCount() const {
return m_assetCount;
}