1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-23 02:42:39 +01:00
openrw/rwlib/source/loaders/LoaderIMG.cpp
2018-06-30 04:03:20 +02:00

110 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;
}
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) {
char* raw_data = new char[assetInfo.size * 2048];
fseek(fp, assetInfo.offset * 2048, SEEK_SET);
if (fread(raw_data, 2048, assetInfo.size, fp) != assetInfo.size) {
RW_ERROR("Error reading asset " << assetInfo.name);
}
fclose(fp);
return raw_data;
} else
return 0;
}
/// Writes the contents of assetname to filename
bool LoaderIMG::saveAsset(const std::string& assetname,
const std::string& filename) {
char* 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, 2048, asset.size, dumpFile);
printf("=> IMG: Saved %s to disk with filename %s\n",
assetname.c_str(), filename.c_str());
}
fclose(dumpFile);
delete[] raw_data;
return true;
} else {
delete[] raw_data;
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;
}