2010-12-10 04:50:08 +01:00
|
|
|
#ifndef LZ77_H
|
|
|
|
#define LZ77_H
|
|
|
|
|
|
|
|
#include "includes.h"
|
|
|
|
|
2012-01-11 06:29:59 +01:00
|
|
|
//class for dealing with LZ77 compression (version 0x10)
|
2010-12-10 04:50:08 +01:00
|
|
|
//! in most cases, you just want to use the static functions
|
|
|
|
// QByteArray stuff = LZ77::Decompress( someCompressedData );
|
|
|
|
// QByteArray compressedData = LZ77::Compress( someData );
|
|
|
|
class LZ77
|
|
|
|
{
|
|
|
|
public:
|
2012-01-11 06:29:59 +01:00
|
|
|
enum CompressionType
|
|
|
|
{
|
|
|
|
None, // not compressed
|
|
|
|
v10, // version 0x10
|
|
|
|
v11, // version 0x11
|
|
|
|
v10_w_magic // version 0x10 with "LZ77" magic bytes
|
|
|
|
};
|
|
|
|
|
2010-12-10 04:50:08 +01:00
|
|
|
LZ77();
|
|
|
|
void InsertNode( int r );
|
|
|
|
void DeleteNode( int p );
|
|
|
|
void InitTree();
|
|
|
|
|
2012-01-11 06:29:59 +01:00
|
|
|
//gets the offset in a bytearray of the lz77 magic word
|
2010-12-10 04:50:08 +01:00
|
|
|
static int GetLz77Offset( const QByteArray &data );
|
|
|
|
|
|
|
|
//gets the decompressed size of a lz77 compressed buffer
|
|
|
|
static quint32 GetDecompressedSize( const QByteArray &data );
|
|
|
|
|
2012-01-11 06:29:59 +01:00
|
|
|
//decompress a buffer that is compressed with the 0x10 variant
|
|
|
|
static QByteArray Decompress_v10( const QByteArray &compressed, int offset );
|
2010-12-10 04:50:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2012-01-11 06:29:59 +01:00
|
|
|
static QByteArray Compress( const QByteArray &ba, CompressionType type );
|
2010-12-10 04:50:08 +01:00
|
|
|
//compressed a qbytearray with the lz77 argorythm
|
|
|
|
//returns a qbytearray ncluding the lz77 header
|
2012-01-11 06:29:59 +01:00
|
|
|
static QByteArray Compress_v10( const QByteArray &ba, bool addMagic = true );
|
|
|
|
|
|
|
|
//check the type of archive, and get theoffset of the "LZ77" magic word in the case of v10_w_magic
|
|
|
|
static CompressionType GetCompressedType( const QByteArray &data, int *outOffset = NULL );
|
|
|
|
|
|
|
|
// decompress data and get whatever type of compression was used on the data
|
|
|
|
static QByteArray Decompress( const QByteArray &stuff, CompressionType *outType = NULL );
|
2010-12-10 04:50:08 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
int lson[ 4097 ];
|
|
|
|
int rson[ 4353 ];
|
|
|
|
int dad[ 4097 ];
|
|
|
|
quint16 text_buf[ 4113 ];
|
|
|
|
int match_position;
|
|
|
|
int match_length;
|
|
|
|
int textsize;
|
|
|
|
int codesize;
|
2012-01-11 06:29:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
//used internally by the static compression function
|
|
|
|
QByteArray Compr_v10( const QByteArray &ba, bool addMagic = true );
|
|
|
|
};
|
|
|
|
|
|
|
|
class LZ77_11
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
LZ77_11();
|
|
|
|
static QByteArray Compress( const QByteArray &stuff );
|
|
|
|
static QByteArray Decompress( const QByteArray stuff );
|
|
|
|
};
|
|
|
|
|
|
|
|
class LzWindowDictionary
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
LzWindowDictionary();
|
|
|
|
|
|
|
|
QList<int> Search( const QByteArray &DecompressedData, quint32 offset, quint32 length );
|
|
|
|
void SlideWindow( int Amount );
|
|
|
|
void SlideBlock();
|
|
|
|
void RemoveOldEntries( quint8 index );
|
|
|
|
void SetWindowSize( int size );
|
|
|
|
void SetMinMatchAmount( int amount );
|
|
|
|
void SetMaxMatchAmount( int amount );
|
|
|
|
void SetBlockSize( int size );
|
|
|
|
void AddEntry( const QByteArray &DecompressedData, int offset );
|
|
|
|
void AddEntryRange( const QByteArray &DecompressedData, int offset, int length );
|
|
|
|
|
|
|
|
private:
|
|
|
|
int WindowSize;
|
|
|
|
int WindowStart;
|
|
|
|
int WindowLength;
|
|
|
|
int MinMatchAmount;
|
|
|
|
int MaxMatchAmount;
|
|
|
|
int BlockSize;
|
|
|
|
QList<int> OffsetList[ 0x100 ];
|
2010-12-10 04:50:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // LZ77_H
|