#include #include #include #include #include #include #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(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(srcp); u8* pDst = static_cast(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(reinterpret_cast(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(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; }