Пример #1
0
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);
}
Пример #2
0
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);
    }
}
Пример #3
0
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);
}                 
Пример #4
0
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);
    }
}
Пример #5
0
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;
    }
}
Пример #6
0
/*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);
}