Integrate libmspack's LZX decompressor for Xbox 360 and UE-style compressed data. This replaces the need for external xcompress64.dll which was hanging/crashing on certain files. - Add mspack/ library (lzxd.c decompressor with Gildor's fixes) - Implement memory-based mspack_system for in-memory decompression - Support multiple LZX formats: raw streams, Xbox 360 block format, and Dead Rising 2's per-block format with 4-byte size headers - Add DecompressDeadRisingLZX() with per-block independent contexts to handle the block-based compression correctly Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
118 lines
4.3 KiB
C++
118 lines
4.3 KiB
C++
#ifndef COMPRESSION_H
|
|
#define COMPRESSION_H
|
|
|
|
#include "QtZlib/zlib.h"
|
|
|
|
//#include <windows.h>
|
|
#include <QtGlobal>
|
|
#include <stddef.h>
|
|
#include <QByteArray>
|
|
#include <QVector>
|
|
#include <QCryptographicHash>
|
|
|
|
enum OodleFormat {
|
|
LZH = 0,
|
|
LZHLW = 1,
|
|
LZNIB = 2,
|
|
FormatNone = 3,
|
|
LZB16 = 4,
|
|
LZBLW = 5,
|
|
LZA = 6,
|
|
LZNA = 7,
|
|
Kraken = 8,
|
|
Mermaid = 9,
|
|
BitKnit = 10,
|
|
Selkie = 11,
|
|
Hydra = 12,
|
|
Leviathan = 13
|
|
};
|
|
|
|
enum OodleCompressionLevel {
|
|
LevelNone = 0,
|
|
SuperFast = 1,
|
|
VeryFast = 2,
|
|
Fast = 3,
|
|
Normal = 4,
|
|
Optimal1 = 5,
|
|
Optimal2 = 6,
|
|
Optimal3 = 7,
|
|
Optimal4 = 8,
|
|
Optimal5 = 9
|
|
};
|
|
|
|
typedef int (*OodleLZ_CompressFunc)(OodleFormat Format, std::byte *Buffer, long BufferSize, std::byte *OutputBuffer, OodleCompressionLevel Level, uint a, uint b, uint c);
|
|
typedef int (__stdcall *OodleLZ_DecompressFunc)(
|
|
const void *compBuf,
|
|
int64_t compBufSize,
|
|
void *rawBuf,
|
|
int64_t rawLen,
|
|
uint32_t fuzzSafe,
|
|
uint32_t checkCRC,
|
|
uint32_t verbosity,
|
|
void *decBufBase,
|
|
size_t decBufSize,
|
|
void *fpCallback,
|
|
void *callbackUserData,
|
|
void *decoderMemory,
|
|
size_t decoderMemorySize,
|
|
int threadPhase
|
|
);
|
|
|
|
class Compression {
|
|
public:
|
|
// QuickBMS path configuration
|
|
static void setQuickBmsPath(const QString &path);
|
|
static QString quickBmsPath();
|
|
|
|
static quint32 CalculateAdler32Checksum(const QByteArray &data);
|
|
static QByteArray DecompressZLIB(const QByteArray &aCompressedData);
|
|
static QByteArray DecompressZlibAuto(const QByteArray &aCompressedData);
|
|
static qint64 FindZlibOffset(const QByteArray &bytes);
|
|
static QByteArray StripHashBlocks(const QByteArray &raw,
|
|
int dataChunkSize = 0x200000,
|
|
int hashChunkSize = 0x2000);
|
|
static QByteArray CompressZLIB(const QByteArray &aData);
|
|
static QByteArray CompressZLIBWithSettings(const QByteArray &aData,
|
|
int aCompressionLevel = Z_BEST_COMPRESSION,
|
|
int aWindowBits = MAX_WBITS,
|
|
int aMemLevel = 8,
|
|
int aStrategy = Z_DEFAULT_STRATEGY,
|
|
const QByteArray &aDictionary = {});
|
|
|
|
static QByteArray DecompressDeflate(const QByteArray &aCompressedData);
|
|
static QByteArray CompressDeflate(const QByteArray &aData);
|
|
static QByteArray CompressDeflateWithSettings(const QByteArray &aData,
|
|
int aCompressionLevel = Z_BEST_COMPRESSION,
|
|
int aWindowBits = MAX_WBITS,
|
|
int aMemLevel = 8,
|
|
int aStrategy = Z_DEFAULT_STRATEGY,
|
|
const QByteArray &aDictionary = {});
|
|
|
|
static QByteArray DecompressLZO(const QByteArray &aCompressedData, quint32 aDestSize);
|
|
|
|
static QByteArray DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize);
|
|
static QByteArray CompressOodle(const QByteArray &aData);
|
|
|
|
|
|
static QByteArray CompressXMem(const QByteArray &data);
|
|
static QByteArray DecompressXMem(const QByteArray &data, int flags = 0, int windowSize = 0x20000, int partSize = 0x80000);
|
|
|
|
// Dead Rising LZX: 8-byte header (u32 uncompressed_size BE + u32 block_size BE) + raw LZX payload
|
|
static QByteArray DecompressDeadRisingLZX(const QByteArray &data);
|
|
private:
|
|
static quint32 pGetOodleCompressedBounds(quint32 aBufferSize);
|
|
static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize,
|
|
OodleFormat aformat, OodleCompressionLevel alevel);
|
|
static QByteArray pDecompressOodle(const QByteArray &aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize);
|
|
|
|
// XMem format-specific decompression helpers
|
|
static QByteArray DecompressXMemNative(const QByteArray &data);
|
|
static QByteArray DecompressXMemTDecode(const QByteArray &data, int flags, int windowSize, int partSize);
|
|
static QByteArray DecompressXMemRaw(const QByteArray &data, int flags, int windowSize, int partSize);
|
|
|
|
static QString s_quickBmsPath;
|
|
};
|
|
|
|
|
|
#endif // COMPRESSION_H
|