1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-18 16:32:32 +02:00
openrw/rwcore/loaders/LoaderIMG.cpp

108 lines
2.9 KiB
C++
Raw Normal View History

#include "loaders/LoaderIMG.hpp"
2016-08-09 14:03:38 +02:00
#include <boost/algorithm/string/predicate.hpp>
#include <cstdio>
2018-06-21 16:49:05 +02:00
#include "rw/debug.hpp"
2013-07-02 08:06:03 +02:00
LoaderIMG::LoaderIMG() : m_version(GTAIIIVC), m_assetCount(0) {
2013-07-02 08:06:03 +02:00
}
2017-11-02 05:01:00 +01:00
bool LoaderIMG::load(const rwfs::path& filepath) {
auto dirPath = filepath;
dirPath.replace_extension(".dir");
2017-11-02 05:01:00 +01:00
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);
2017-11-02 05:01:00 +01:00
auto imgPath = filepath;
imgPath.replace_extension(".img");
m_archive = imgPath;
return true;
} else {
return false;
}
2013-07-02 08:06:03 +02:00
}
/// Get the information of a asset in the examining archive
bool LoaderIMG::findAssetInfo(const std::string& assetname,
LoaderIMGFile& out) {
2018-01-26 16:47:07 +01:00
for (auto &asset : m_assets) {
if (boost::iequals(asset.name, assetname)) {
out = asset;
return true;
}
}
return false;
2013-07-02 08:06:03 +02:00
}
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;
}
2017-11-02 05:01:00 +01:00
auto imgName = m_archive;
2017-11-02 05:01:00 +01:00
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;
2013-07-02 08:06:03 +02:00
}
/// 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;
}
2013-07-02 08:06:03 +02:00
}
/// Get the information of an asset by its index
const LoaderIMGFile& LoaderIMG::getAssetInfoByIndex(size_t index) const {
return m_assets[index];
2013-07-02 08:06:03 +02:00
}
uint32_t LoaderIMG::getAssetCount() const {
return m_assetCount;
2013-07-02 08:06:03 +02:00
}