From 0c53148a96413eec254a6b3ba49d52fb7f48e24f Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Wed, 7 Jun 2023 12:39:59 +0200 Subject: Decompression refactoring --- src/SCompression.cpp | 23 ++++++++++++++++++----- src/SFileReadFile.cpp | 21 +++++++++------------ src/StormLib.h | 2 -- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/SCompression.cpp b/src/SCompression.cpp index b689063..d6d2e27 100644 --- a/src/SCompression.cpp +++ b/src/SCompression.cpp @@ -1038,11 +1038,6 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu return SCompDecompressInternal(dcmp_table, _countof(dcmp_table), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); } -int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) -{ - return SCompDecompressInternal(dcmp_table_sc_beta, _countof(dcmp_table_sc_beta), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); -} - int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) { DECOMPRESS pfnDecompress1 = NULL; @@ -1157,6 +1152,24 @@ int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB return nResult; } +int WINAPI SCompDecompressX(TMPQArchive * ha, void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + // MPQs version 2 use their own fixed list of compression flags. + if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + { + return SCompDecompress2(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); + } + + // Starcraft BETA has specific decompression table. + if(ha->dwFlags & MPQ_FLAG_STARCRAFT_BETA) + { + return SCompDecompressInternal(dcmp_table_sc_beta, _countof(dcmp_table_sc_beta), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); + } + + // Default: Use the common MPQ v1 decompression routine + return SCompDecompressInternal(dcmp_table, _countof(dcmp_table), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + /*****************************************************************************/ /* */ /* File decompression for MPK archives */ diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 39f794e..b0698c1 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -13,6 +13,11 @@ #include "StormLib.h" #include "StormCommon.h" +//----------------------------------------------------------------------------- +// External references (not public functions) + +int WINAPI SCompDecompressX(TMPQArchive * ha, void * pvOutBuffer, int * pcbOutBuffer, void * pbInBuffer, int cbInBuffer); + //----------------------------------------------------------------------------- // Local functions @@ -171,18 +176,10 @@ static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, // Remember the last used compression hf->dwCompression0 = pbInSector[0]; - // Decompress the data - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) - { - nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); - } - else - { - if(ha->dwFlags & MPQ_FLAG_STARCRAFT_BETA) - nResult = SCompDecompress_SC1B(pbOutSector, &cbOutSector, pbInSector, cbInSector); - else - nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); - } + // Decompress the data. We need to perform MPQ-specific decompression, + // as multiple Blizzard games may have their own decompression tables + // and even decompression methods. + nResult = SCompDecompressX(ha, pbOutSector, &cbOutSector, pbInSector, cbInSector); } // Is the file compressed by PKWARE Data Compression Library ? diff --git a/src/StormLib.h b/src/StormLib.h index 5142868..94e9813 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -1122,8 +1122,6 @@ int WINAPI SCompExplode (void * pvOutBuffer, int * pcbOutBuffer, void * pv int WINAPI SCompCompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel); int WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); -int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); -//int WINAPI SCompDecompress_SCBW(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); //----------------------------------------------------------------------------- // Non-Windows support for SetLastError/GetLastError -- cgit v1.2.3