BOOL CLZSS::Decomp(CArcFile* pclArc, DWORD dwDicSize, DWORD dwDicPtr, DWORD dwLengthOffset) { SFileInfo* pstFileInfo = pclArc->GetOpenFileInfo(); // Read DWORD dwSrcSize = pstFileInfo->sizeCmp; YCMemory<BYTE> clmSrc(dwSrcSize); pclArc->Read(&clmSrc[0], dwSrcSize); // Buffer allocation for extraction DWORD dwDstSize = pstFileInfo->sizeOrg; YCMemory<BYTE> clmDst(dwDstSize); // Decompression Decomp(&clmDst[0], dwDstSize, &clmSrc[0], dwSrcSize, dwDicSize, dwDicPtr, dwLengthOffset); // Bitmap if (lstrcmp(PathFindExtension(pstFileInfo->name), _T(".bmp")) == 0) { CImage clImage; clImage.Init(pclArc, &clmDst[0]); clImage.Write(dwDstSize); clImage.Close(); } else // Other { pclArc->OpenFile(); pclArc->WriteFile(&clmDst[0], dwDstSize); pclArc->CloseFile(); } return TRUE; }
/// Decode 6 /// /// @param archive Archive /// @param src Compressed data /// @param src_size Compressed data size /// @param width Width /// @param height Height /// @param bpp Number of bits /// bool CPB2A::Decode6(CArcFile* archive, const u8* src, size_t src_size, s32 width, s32 height, u16 bpp) { // Ensure base image buffer const u32 base_size = static_cast<u32>(width * height * 4); std::vector<u8> base(base_size); // Decompress base image Decomp6(base.data(), base.size(), src, src_size, width, height, 32, nullptr, 0); // Output base image CImage image; image.Init(archive, width, height, 32); image.WriteReverse(base.data(), base.size()); image.Close(); // Get number of image files const u32 num_image_files = *reinterpret_cast<const u32*>(&src[8]); if (num_image_files == 1) { // Only the base image exists return true; } // Ensure difference image buffer const size_t dst_size = base.size(); std::vector<u8> dst(dst_size); // Output difference image for (u32 frame_number = 1; frame_number < num_image_files; frame_number++) { // Decompress difference image Decomp6(dst.data(), dst.size(), src, src_size, width, height, 32, base.data(), frame_number); // Output difference image TCHAR diff_name[256]; _stprintf(diff_name, _T("_%02u"), frame_number - 1); image.Init(archive, width, height, 32, nullptr, 0, diff_name); image.WriteReverse(dst.data(), dst.size(), false); image.Close(); } return true; }
BOOL CAOS::DecodeMask( CArcFile* pclArc // Archive ) { SFileInfo* pstFileInfo = pclArc->GetOpenFileInfo(); // Read Data DWORD dwSrcSize = pstFileInfo->sizeCmp; YCMemory<BYTE> clmSrc( dwSrcSize ); pclArc->Read( &clmSrc[0], dwSrcSize ); // Output CImage clImage; clImage.Init( pclArc, &clmSrc[0] ); clImage.Write( dwSrcSize ); clImage.Close(); return TRUE; }
BOOL CAOS::DecodeABM( CArcFile* pclArc // Archive ) { SFileInfo* pstFileInfo = pclArc->GetOpenFileInfo(); // Read data DWORD dwSrcSize = pstFileInfo->sizeCmp; YCMemory<BYTE> clmSrc( dwSrcSize ); pclArc->Read( &clmSrc[0], dwSrcSize ); // Get bitmap header BITMAPFILEHEADER* pstbfhSrc = (BITMAPFILEHEADER*) &clmSrc[0]; BITMAPINFOHEADER* pstbihSrc = (BITMAPINFOHEADER*) &clmSrc[14]; CImage clImage; YCMemory<BYTE> clmDst; YCString clsLastName; DWORD dwDstSize; DWORD dwFrames; DWORD dwOffsetToData; DWORD dwSrcPtr = 0; DWORD dwDstPtr = 0; switch( pstbihSrc->biBitCount ) { case 1: // Multi-frame dwFrames = *(DWORD*) &clmSrc[58]; dwOffsetToData = *(DWORD*) &clmSrc[66]; dwDstSize = (pstbihSrc->biWidth * pstbihSrc->biHeight * 4); clmDst.resize( dwDstSize ); // Multiple files if( dwFrames >= 2 ) { clsLastName.Format( _T("_000") ); } // Decompression dwSrcPtr = dwOffsetToData; for( DWORD i = 0 ; i < dwDstSize ; i += 4 ) { clmDst[i + 0] = clmSrc[dwSrcPtr++]; clmDst[i + 1] = clmSrc[dwSrcPtr++]; clmDst[i + 2] = clmSrc[dwSrcPtr++]; clmDst[i + 3] = 0xFF; } // Output clImage.Init( pclArc, pstbihSrc->biWidth, pstbihSrc->biHeight, 32, NULL, 0, clsLastName ); clImage.WriteReverse( &clmDst[0], dwDstSize ); clImage.Close(); // for( DWORD i = 1 ; i < dwFrames ; i++ ) { DWORD dwOffsetToFrame = *(DWORD*) &clmSrc[70 + (i - 1) * 4]; clsLastName.Format( _T("_%03d"), i ); // Decompression ZeroMemory( &clmDst[0], dwDstSize ); DecompABM( &clmDst[0], dwDstSize, &clmSrc[dwOffsetToFrame], (dwSrcSize - dwOffsetToFrame) ); // Output clImage.Init( pclArc, pstbihSrc->biWidth, pstbihSrc->biHeight, 32, NULL, 0, clsLastName ); clImage.WriteReverse( &clmDst[0], dwDstSize, FALSE ); clImage.Close(); } break; case 32: // 32bit dwDstSize = (pstbihSrc->biWidth * pstbihSrc->biHeight * 4); clmDst.resize( dwDstSize ); // Decompression DecompABM( &clmDst[0], dwDstSize, &clmSrc[54], (dwSrcSize - 54) ); // Output clImage.Init( pclArc, pstbihSrc->biWidth, pstbihSrc->biHeight, pstbihSrc->biBitCount ); clImage.WriteReverse( &clmDst[0], dwDstSize ); clImage.Close(); break; default: // Other pclArc->OpenFile(); pclArc->WriteFile( &clmSrc[0], dwSrcSize ); pclArc->CloseFile(); } return TRUE; }
bool CSusie::Decode(CArcFile* pclArc) { YCStringA clsPathToArc = pclArc->GetArcPath(); YCStringA clsFileName = pclArc->GetOpenFileInfo()->name; // Get header const u8* pbtHeader = pclArc->GetHeader(); // GetPicture() file input std::vector<YCLibrary*> vtSupportPlugin; for (auto& pstsiTarget : m_stsiMain) { if (pstsiTarget.bValidity == 0) { // Invalid Susie plugin continue; } // Get IsSupported() IsSupportedProc IsSupported = reinterpret_cast<IsSupportedProc>(pstsiTarget.cllPlugin.GetProcAddress(_T("IsSupported"))); if (IsSupported == nullptr) { // IsSupported() function is not implemented continue; } // Copy the archive's file path char szPathToArc[MAX_PATH]; strcpy(szPathToArc, clsPathToArc); BYTE abtHeader[2048]; memcpy(abtHeader, pbtHeader, sizeof(abtHeader)); if (!IsSupported(szPathToArc, (DWORD) abtHeader)) { // Archive file is not supported continue; } // Archive file is supported vtSupportPlugin.push_back(&pstsiTarget.cllPlugin); // Copy the archive file path strcpy(szPathToArc, clsPathToArc); // Get GetPicture() GetPictureProc GetPicture = reinterpret_cast<GetPictureProc>(pstsiTarget.cllPlugin.GetProcAddress(_T("GetPicture"))); if (GetPicture == nullptr) { // GetPicture() function is not implemented continue; } YCLocalMemory cllmBitmapInfo; YCLocalMemory cllmBitmapData; // Call GetPicture() if (GetPicture(szPathToArc, pclArc->GetOpenFileInfo()->start, 0x0000, &cllmBitmapInfo.GetHandle(), &cllmBitmapData.GetHandle(), nullptr, 0) != 0) { // GetPicture() has failed continue; } // Get image information LPBITMAPINFO pBMPInfo = (LPBITMAPINFO) cllmBitmapInfo.Lock(); LPBYTE pHBm = (LPBYTE) cllmBitmapData.Lock(); size_t HBmSize = cllmBitmapData.GetSize(); // Image output CImage image; image.Init(pclArc, pBMPInfo->bmiHeader.biWidth, pBMPInfo->bmiHeader.biHeight, pBMPInfo->bmiHeader.biBitCount, (LPBYTE) pBMPInfo->bmiColors); image.Write(pHBm, HBmSize); image.Close(); // Exit (Free resources) cllmBitmapInfo.Free(); cllmBitmapData.Free(); return true; } // File input - GetFile() YCLocalMemory cllmSrc; for (auto& supportPlugin : vtSupportPlugin) { // Copy archive file path char szPathToArc[MAX_PATH]; strcpy(szPathToArc, clsPathToArc); // Get GetFile() GetFileProc GetFile = reinterpret_cast<GetFileProc>(supportPlugin->GetProcAddress(_T("GetFile"))); if (GetFile == nullptr) { // GetFile() function is not supported continue; } // Call GetFile() if (GetFile(szPathToArc, pclArc->GetOpenFileInfo()->start, (LPSTR)&cllmSrc.GetHandle(), 0x0100, nullptr, 0) != 0) { // GetFile has failed cllmSrc.Free(); continue; } // Successful completion break; } // Lock the memory for reading bool bGetFileSuccess = true; LPBYTE pbtSrc = nullptr; DWORD dwSrcSize; if (cllmSrc.GetHandle() != nullptr) { // Successful GetFile() pbtSrc = (LPBYTE) cllmSrc.Lock(); dwSrcSize = cllmSrc.GetSize(); } else { // GetFile() has failed bGetFileSuccess = false; // Memory allocation dwSrcSize = pclArc->GetOpenFileInfo()->sizeCmp; cllmSrc.Alloc(LHND, dwSrcSize); pbtSrc = (LPBYTE) cllmSrc.Lock(); // Reading pclArc->Read(pbtSrc, dwSrcSize); pclArc->SeekCur(-(INT64)dwSrcSize); } // Memory Input - GetPicture() for (auto& pstsiTarget : m_stsiMain) { if (pstsiTarget.bValidity == 0) { // Invalid Susie plugin continue; } // Get IsSupported() IsSupportedProc IsSupported = reinterpret_cast<IsSupportedProc>(pstsiTarget.cllPlugin.GetProcAddress(_T("IsSupported"))); if (IsSupported == nullptr) { // IsSupported() function is not implemented continue; } // Copy file path // Plugin fails if the full path does not exist char szPathToFile[MAX_PATH]; strcpy(szPathToFile, clsPathToArc.GetDirPath()); PathAppendA(szPathToFile, clsFileName); // Needs 2KB BYTE abtSrcHeader[2048]; DWORD dwCopySize = (dwSrcSize <= sizeof(abtSrcHeader)) ? dwSrcSize : sizeof(abtSrcHeader); ZeroMemory(abtSrcHeader, sizeof(abtSrcHeader)); memcpy(abtSrcHeader, pbtSrc, dwCopySize); // Call IsSupported() if (!IsSupported(szPathToFile, (DWORD) abtSrcHeader)) { // File is not supported continue; } // Get GetPicture() GetPictureProc GetPicture = reinterpret_cast<GetPictureProc>(pstsiTarget.cllPlugin.GetProcAddress(_T("GetPicture"))); if (GetPicture == nullptr) { // GetPicture() function is not implemented continue; } YCLocalMemory cllmBitmapInfo; YCLocalMemory cllmBitmapData; // Call GetPicture() if (GetPicture((LPSTR)pbtSrc, dwSrcSize, 0x0001, &cllmBitmapInfo.GetHandle(), &cllmBitmapData.GetHandle(), nullptr, 0) != 0) { // GetPicture() has failed continue; } // Get image info LPBITMAPINFO pBMPInfo = (LPBITMAPINFO) cllmBitmapInfo.Lock(); LPBYTE pHBm = (LPBYTE) cllmBitmapData.Lock(); size_t HBmSize = cllmBitmapData.GetSize(); // Image output CImage image; image.Init(pclArc, pBMPInfo->bmiHeader.biWidth, pBMPInfo->bmiHeader.biHeight, pBMPInfo->bmiHeader.biBitCount, (BYTE*) pBMPInfo->bmiColors); image.Write(pHBm, HBmSize); image.Close(); // Exit cllmBitmapInfo.Free(); cllmBitmapData.Free(); cllmSrc.Free(); return true; } // Exit if the file could not be obtained in the function GetFile() if (!bGetFileSuccess) { cllmSrc.Free(); return false; } // Output file obtained from GetFile() pclArc->OpenFile(); pclArc->WriteFile(pbtSrc, dwSrcSize, pclArc->GetOpenFileInfo()->sizeCmp); pclArc->CloseFile(); // Exit (Free resources) cllmSrc.Free(); return true; }