mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@553 385bec56-5757-e545-9c3a-d8741f4650f1
171 lines
4.4 KiB
C++
171 lines
4.4 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <cstring>
|
|
|
|
#include "testUtil.h"
|
|
|
|
namespace internal
|
|
{
|
|
inline u32 Read32Le(const u8* p)
|
|
{
|
|
return (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
|
}
|
|
|
|
}
|
|
|
|
// ################################################################################
|
|
|
|
u32 GetUncompressedSize(const void* pData)
|
|
{
|
|
const u8* p = static_cast<const u8*>(pData);
|
|
|
|
u32 size = internal::Read32Le(p) >> 8;
|
|
if (size == 0)
|
|
{
|
|
size = internal::Read32Le(p + 4);
|
|
}
|
|
return size;
|
|
}
|
|
|
|
void UncompressLZ( const void *srcp, void *destp )
|
|
{
|
|
const u8* pSrc = static_cast<const u8*>(srcp);
|
|
u8* pDst = static_cast<u8*>(destp);
|
|
u32 destCount = internal::Read32Le(pSrc) >> 8;
|
|
bool exFormat = (*pSrc & 0x0F)? true : false;
|
|
|
|
pSrc += 4;
|
|
|
|
if ( destCount == 0 )
|
|
{
|
|
destCount = internal::Read32Le(pSrc);
|
|
pSrc += 4;
|
|
}
|
|
|
|
while ( destCount > 0 )
|
|
{
|
|
u32 flags = *pSrc++;
|
|
for ( int i = 0; i < 8; ++i )
|
|
{
|
|
if ( !(flags & 0x80) )
|
|
{
|
|
*pDst++ = *pSrc++;
|
|
destCount--;
|
|
}
|
|
else
|
|
{
|
|
u32 length = (*pSrc >> 4);
|
|
s32 offset;
|
|
|
|
if ( ! exFormat )
|
|
{
|
|
length += 3;
|
|
}
|
|
else
|
|
{
|
|
// LZ77拡張フォーマット
|
|
if ( length == 1 )
|
|
{
|
|
length = (*pSrc++ & 0x0F) << 12;
|
|
length |= (*pSrc++) << 4;
|
|
length |= (*pSrc >> 4);
|
|
length += 0xFF + 0xF + 3;
|
|
}
|
|
else if ( length == 0 )
|
|
{
|
|
length = (*pSrc++ & 0x0F) << 4;
|
|
length |= (*pSrc >> 4);
|
|
length += 0xF + 2;
|
|
}
|
|
else
|
|
{
|
|
length += 1;
|
|
}
|
|
}
|
|
offset = (*pSrc++ & 0x0f) << 8;
|
|
offset = (offset | *pSrc++) + 1;
|
|
// 不正なデータを展開した際のバッファオーバーラン対策
|
|
length = std::min(length, destCount);
|
|
destCount -= length;
|
|
u8* pTmp = pDst - offset;
|
|
for (int j = 0; j < length; j++)
|
|
{
|
|
*pDst++ = *pTmp++;
|
|
}
|
|
}
|
|
if ( destCount <= 0 )
|
|
{
|
|
break;
|
|
}
|
|
flags <<= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DumpBuf(void* buf, size_t fileSize)
|
|
{
|
|
std::cout.setf(std::ios::hex, std::ios::basefield);
|
|
for(size_t i = 0; i < fileSize; i++)
|
|
{
|
|
std::cout << std::setw(2) << std::setfill('0') << static_cast<short>(reinterpret_cast<u8*>(buf)[i]);
|
|
if(i % 16 == 15)
|
|
{
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
std::cout << std::endl;
|
|
|
|
}
|
|
|
|
void ReadFile(const wchar_t* path, void** decode, size_t* size)
|
|
{
|
|
if(path == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
char filePath[256];
|
|
std::wcstombs(filePath, path, sizeof(filePath));
|
|
|
|
char prefix[] = "../../../common/romfiles/regionData/";
|
|
|
|
char fullPath[256];
|
|
std::memset(fullPath, 0, sizeof(fullPath));
|
|
strlcpy(fullPath, prefix, sizeof(fullPath));
|
|
strlcat(fullPath, filePath, 256 - strlen(fullPath));
|
|
//std::cout << fullPath << std::endl;
|
|
|
|
std::ifstream ifs(fullPath, std::ios::in | std::ios::binary);
|
|
|
|
ifs.seekg(0, std::fstream::end);
|
|
size_t eofPos = ifs.tellg();
|
|
ifs.clear();
|
|
ifs.seekg(0, std::fstream::beg);
|
|
size_t begPos = ifs.tellg();
|
|
size_t fileSize = eofPos - begPos;
|
|
//std::cout << "filesize = " << fileSize << std::endl;
|
|
|
|
u8* buf = new u8[fileSize];
|
|
ifs.read(reinterpret_cast<char*>(buf), fileSize);
|
|
|
|
ifs.close();
|
|
//DumpBuf(buf, fileSize);
|
|
|
|
size_t uncompressedSize = GetUncompressedSize(buf);
|
|
//std::cout.setf(std::ios::dec, std::ios::basefield);
|
|
//std::cout << "UncompressedSize = " << uncompressedSize << std::endl;
|
|
|
|
*decode = new u8[uncompressedSize];
|
|
*size = uncompressedSize;
|
|
|
|
UncompressLZ( buf, *decode);
|
|
//DumpBuf(decode, uncompressedSize);
|
|
|
|
delete[] buf;
|
|
|
|
|
|
}
|