void Compress_SPARSE(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { // Keep compilers happy STORMLIB_UNUSED(pCmpType); STORMLIB_UNUSED(nCmpLevel); CompressSparse(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); }
void Compress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { z_stream z; // Stream information for zlib int windowBits; int nResult; // Keep compilers happy STORMLIB_UNUSED(pCmpType); STORMLIB_UNUSED(nCmpLevel); // Fill the stream structure for zlib z.next_in = (Bytef *)pvInBuffer; z.avail_in = (uInt)cbInBuffer; z.total_in = cbInBuffer; z.next_out = (Bytef *)pvOutBuffer; z.avail_out = *pcbOutBuffer; z.total_out = 0; z.zalloc = NULL; z.zfree = NULL; // Determine the proper window bits (WoW.exe build 12694) if(cbInBuffer <= 0x100) windowBits = 8; else if(cbInBuffer <= 0x200) windowBits = 9; else if(cbInBuffer <= 0x400) windowBits = 10; else if(cbInBuffer <= 0x800) windowBits = 11; else if(cbInBuffer <= 0x1000) windowBits = 12; else if(cbInBuffer <= 0x2000) windowBits = 13; else if(cbInBuffer <= 0x4000) windowBits = 14; else windowBits = 15; // Initialize the compression. // Storm.dll uses zlib version 1.1.3 // Wow.exe uses zlib version 1.2.3 nResult = deflateInit2(&z, 6, // Compression level used by WoW MPQs Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY); if(nResult == Z_OK) { // Call zlib to compress the data nResult = deflate(&z, Z_FINISH); if(nResult == Z_OK || nResult == Z_STREAM_END) *pcbOutBuffer = z.total_out; deflateEnd(&z); } }
void Compress_huff(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { THuffmannTree ht(true); TOutputStream os(pvOutBuffer, *pcbOutBuffer); STORMLIB_UNUSED(nCmpLevel); *pcbOutBuffer = ht.Compress(&os, pvInBuffer, cbInBuffer, *pCmpType); }
static void Compress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { TDataInfo Info; // Data information char * work_buf = STORM_ALLOC(char, CMP_BUFFER_SIZE);// Pklib's work buffer unsigned int dict_size; // Dictionary size unsigned int ctype = CMP_BINARY; // Compression type // Keep compilers happy STORMLIB_UNUSED(pCmpType); STORMLIB_UNUSED(nCmpLevel); // Handle no-memory condition if(work_buf != NULL) { // Fill data information structure memset(work_buf, 0, CMP_BUFFER_SIZE); Info.pbInBuff = (unsigned char *)pvInBuffer; Info.pbInBuffEnd = (unsigned char *)pvInBuffer + cbInBuffer; Info.pbOutBuff = (unsigned char *)pvOutBuffer; Info.pbOutBuffEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer; // // Set the dictionary size // // Diablo I uses fixed dictionary size of CMP_IMPLODE_DICT_SIZE3 // Starcraft I uses the variable dictionary size based on algorithm below // if (cbInBuffer < 0x600) dict_size = CMP_IMPLODE_DICT_SIZE1; else if(0x600 <= cbInBuffer && cbInBuffer < 0xC00) dict_size = CMP_IMPLODE_DICT_SIZE2; else dict_size = CMP_IMPLODE_DICT_SIZE3; // Do the compression if(implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size) == CMP_NO_ERROR) *pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer); STORM_FREE(work_buf); } }
static void Compress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { bz_stream strm; int blockSize100k = 9; int workFactor = 30; int bzError; // Keep compilers happy STORMLIB_UNUSED(pCmpType); STORMLIB_UNUSED(nCmpLevel); // Initialize the BZIP2 compression strm.bzalloc = NULL; strm.bzfree = NULL; // Blizzard uses 9 as blockSize100k, (0x30 as workFactor) // Last checked on Starcraft II if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == BZ_OK) { strm.next_in = (char *)pvInBuffer; strm.avail_in = cbInBuffer; strm.next_out = (char *)pvOutBuffer; strm.avail_out = *pcbOutBuffer; // Perform the compression for(;;) { bzError = BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH); if(bzError == BZ_STREAM_END || bzError < 0) break; } // Put the stream into idle state BZ2_bzCompressEnd(&strm); if(bzError > 0) *pcbOutBuffer = strm.total_out_lo32; } }
/*static */ void Compress_LZMA(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) { ICompressProgress Progress; CLzmaEncProps props; ISzAlloc SzAlloc; Byte * pbOutBuffer = (Byte *)pvOutBuffer; Byte * destBuffer; SizeT destLen = *pcbOutBuffer; SizeT srcLen = cbInBuffer; Byte encodedProps[LZMA_PROPS_SIZE]; size_t encodedPropsSize = LZMA_PROPS_SIZE; SRes nResult; // Keep compilers happy STORMLIB_UNUSED(pCmpType); STORMLIB_UNUSED(nCmpLevel); // Fill the callbacks in structures Progress.Progress = LZMA_Callback_Progress; SzAlloc.Alloc = LZMA_Callback_Alloc; SzAlloc.Free = LZMA_Callback_Free; // Initialize properties LzmaEncProps_Init(&props); // Perform compression destBuffer = (Byte *)pvOutBuffer + LZMA_HEADER_SIZE; destLen = *pcbOutBuffer - LZMA_HEADER_SIZE; nResult = LzmaEncode(destBuffer, &destLen, (Byte *)pvInBuffer, srcLen, &props, encodedProps, &encodedPropsSize, 0, &Progress, &SzAlloc, &SzAlloc); if(nResult != SZ_OK) return; // If we failed to compress the data if(destLen >= (SizeT)(*pcbOutBuffer - LZMA_HEADER_SIZE)) return; // Write "useFilter" variable. Blizzard MPQ must not use filter. *pbOutBuffer++ = 0; // Copy the encoded properties to the output buffer memcpy(pvOutBuffer, encodedProps, encodedPropsSize); pbOutBuffer += encodedPropsSize; // Copy the size of the data *pbOutBuffer++ = (unsigned char)(srcLen >> 0x00); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x08); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x10); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x18); *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; // Give the size of the data to the caller *pcbOutBuffer = (unsigned int)(destLen + LZMA_HEADER_SIZE); }