#include "RLib_Compress.h"
#include
using namespace System;
using namespace System::IO;
//-------------------------------------------------------------------------
#pragma warning(disable: 4127)// 条件表达式是常量
#pragma warning(disable:4035)
#pragma warning(disable:4146)//一元负运算符应用于无符号类型,结果仍为无符号类型
#pragma warning(disable:4244)//从“int”转换到“U8”,可能丢失数据
///
// PAQD2 0.284 (2004.8.15) [Head File] Author:Dwing
///
typedef unsigned char U8;
typedef unsigned short U16;
typedef unsigned long U32;
#define ISLETTER(a) ((a)>='a'&&(a)<='z'||(a)>='A'&&(a)<='Z')
#define PSCALE 4096
#define Top_value U32(0XFFFFFFFF)
#define First_qtr U32(0X40000000)
#define Half U32(0X80000000)
#define Third_qtr U32(0XC0000000)
rnd //
class Random //1025
{
U32 table[256];
U8 i;
public:
void init();
U32 operator()();
};
hash /
class Hash //4096
{
U32 table[4][256];
public:
void init();
U32 operator()(U8 i0)const
{
return table[0][i0];
}
U32 operator()(U8 i0, U8 i1)const
{
return table[0][i0] + table[1][i1];
}
U32 operator()(U8 i0, U8 i1, U8 i2)const
{
return table[0][i0] + table[1][i1] + table[2][i2];
}
U32 operator()(U8 i0, U8 i1, U8 i2, U8 i3)const
{
return table[0][i0] + table[1][i1] + table[2][i2] + table[3][i3];
}
};
Counter //
class Counter //1
{
struct E
{
U16 n0, n1;
U8 s00, s01, s10, s11;
U32 p0, p1;
};
const static E table[];
public:
U8 state;
Counter(): state(0){}
int get0()const
{
return table[state].n0;
}
int get1()const
{
return table[state].n1;
}
void add(int y);
};
ch ///
class Ch //4396
{
public:
U8 *buf, lidx[256];
U32 lpos[256][8];
U32 N, p, bp, lo, hi, b1, b2, b3, b4, bt;
void init();
void free()
{
AppBase::Collect(buf);
}
U8 operator()(int i)const
{
return buf[(p - i) &N];
}
U8 operator()()const
{
return buf[p];
}
U32 pos(int i)const
{
return lpos[b1][(lidx[b1] - i) &7];
}
U32 operator[](int i)const
{
return buf[i &N];
}
void update(int y);
};
Hashtable
class Hashtable //16
{
struct HashElement //16
{
U8 checksum;
Counter c[15];
HashElement(): checksum(0){}
}
*table;
Counter *Tcxt;
char *p;
/*const */U32 N;
public:
Hashtable(U32 n);
~Hashtable()
{
System::AppBase::Collect(p);
}
void set(U32 h);
Counter &operator()(U32 c)
{
return Tcxt[c];
}
};
mixer
class Mixer //8720
{
protected:
enum
{
C = 32, N = 64
};
U32 bc0[N], bc1[N], wt[C][N];
int n, c, b0, b1;
public:
void init();
void write(int n0, int n1)
{
bc0[++n] = n0;
bc1[n] = n1;
}
void add(int n0, int n1)
{
bc0[n] += n0;
bc1[n] += n1;
}
int predict(int vc);
};
class Mixer1: public Mixer
{
public:
void update(int y);
};
class Mixer2: public Mixer
{
public:
void update(int y);
};
class MultiMixer //8720*2
{
Mixer1 m1;
Mixer2 m2;
public:
void init()
{
m1.init();
m2.init();
}
void write(int n0, int n1);
void add(int n0, int n1);
int predict();
void update(int y);
};
CounterMap ///
class CounterMap1 //12
{
struct S
{
U8 c, n;
}
*t, *cxt;
/*const */int N;
public:
CounterMap1(int n);
~CounterMap1()
{
AppBase::Collect(t);
}
void update(U32 h);
void add();
};
class CounterMap2 //52
{
Counter *cp[8];
U32 cxt;
Hashtable ht2;
public:
CounterMap2(int n);
void add();
void update(U32 h);
void write();
};
class CounterMap //64
{
CounterMap1 cm1;
CounterMap2 cm2;
public:
CounterMap(int n);
void update(U32 h);
void write();
void add();
};
charModel
class CharModel
{
enum
{
N = 10
};
/*const */int SIZE;
Counter *cp0, *cp1, t0[256], t1[65536];
U32 cxt[N];
CounterMap t2, t3;
CounterMap2 t4, t5, t6, t7, t8, t9;
public:
CharModel();
void model();
};
matchModel ///
class MatchModel
{
/*const */int N;
U32 *ptr, hash0, hash1, begin, end;
public:
MatchModel();
~MatchModel()
{
AppBase::Collect(ptr);
}
void model();
};
recordModel //
class RecordModel
{
/*const */int SIZE;
CounterMap t0, t3, t4;
int rp1, rp2;
public:
RecordModel();
void model();
};
sparseModel //
class SparseModel
{
/*const */int SIZE;
CounterMap t2, t3, t4, t5, t6;
public:
SparseModel();
void model();
};
analogModel //
class AnalogModel //0.5K
{
/*const */int SIZE;
CounterMap t0, t1, t2, t5;
public:
AnalogModel();
void model();
};
wordModel
class WordModel //1K
{
CounterMap t3;
U32 word;
public:
WordModel();
void model();
};
exeModel /
class ExeModel //2K
{
struct S
{
U32 a;
U8 n;
S(): a(0), n(0){}
}
t[256];
public:
void model();
};
Predictor
class Predictor
{
CharModel charModel;
MatchModel matchModel;
RecordModel recordModel;
SparseModel sparseModel;
AnalogModel analogModel;
WordModel wordModel;
ExeModel exeModel;
enum
{
SSE1 = 256 * 4, SSE2 = 32, SSESCALE = 1024 / SSE2
};
class SSEMap
{
U16 table[PSCALE];
public:
int operator()(int p)const
{
return table[p];
}
SSEMap();
} ssemap;
struct SSEContext
{
U8 c1, n;
SSEContext(): c1(0), n(0){}
int p()const
{
return PSCALE *(c1 *64+1) / (n *64+2);
}
void update(int y)
{
c1 += y;
if (++n == 255)
{
c1 >>= 1;
n = 127;
}
}
};
SSEContext sse[SSE1][SSE2 + 1];
U32 nextp, ssep, context;
public:
Predictor();
int p()const
{
return nextp;
}
void update(int y);
};
//-------------------------------------------------------------------------
typedef enum
{
COMPRESS, DECOMPRESS
} Mode;
class Encoder
{
Predictor predictor;
/*const */Mode mode;
Stream *output;
U32 x1, x2, x, bits_to_follow;
U8 bptr, bout, bptrin;
int bin;
public:
Encoder(Mode m, Stream *s);
~Encoder();
RLIB_ClassNewDel;
public:
void encode(U32 y);
U32 decode();
void flush();
void bit_plus_follow(int bit);
int input_bit();
};
//-------------------------------------------------------------------------
class zUDA
{
private:
Encoder e;
public:
zUDA(Mode mode, Stream *s):e(mode, s){};
RLIB_ClassNewDel;
public:
void zUDA::enc(char *s, int n)
{
int i;
U8 c;
for (; n; n--)
for (c = *s++, i = 7; i >= 0; i--, c <<= 1)
{
e.encode((U32)c >> 7);
}
}
void zUDA::dec(char *d, int n)
{
int i;
U32 c;
for (; n; n--, *d++ = (U8)c)
for (c = 0, i = 7; i >= 0; i--)
{
c += c + e.decode();
}
}
void zUDA::flush()
{
e.flush();
}
};
///
#define MEM 3 // for experimental version
//unsigned MEM=3; // for released version
Random rnd;
Hash hash;
Ch ch;
MultiMixer mixer;
///
void handler()
{
printf("FINAL ERROR: Not Enough Memory!\n");
exit(0);
}
///
inline void Random::init()
{
memset(this, 0, sizeof(Random));
table[0] = 123456789;
table[1] = 987654321;
for (int j = 2; j < 256; j++)
{
table[j] = table[j - 1] *11+table[j - 2] *19 / 16;
}
}
//-------------------------------------------------------------------------
inline U32 Random::operator()()
{
__asm // i=U8(i+1);
{
// return table[i]^=table[U8(i+143)];
xor eax, eax
mov al, rnd.i
inc al
mov rnd.i, al
lea edx, [offset rnd.table + eax * 4]
add al, 143
mov eax, [offset rnd.table + eax * 4]
xor eax, [edx]
mov[edx], eax
}
}
///
inline void Hash::init()
{
memset(this, 0, sizeof(Hash));
int i, j;
for (i = 3; i >= 0; i--)
for (j = 0; j < 256; j++)
{
table[i][j] = rnd();
}
}
///
inline void Ch::init()
{
memset(this, 0, sizeof(Ch));
N = 1 << (21+MEM);
buf = (U8*)AppBase::Allocate(N);
if (!buf)
{
handler();
}
lo = buf[0] = 1;
N--;
}
//-------------------------------------------------------------------------
inline void Ch::update(int y)
{
bp++;
bt = y;
buf[p] += buf[p] + y;
lo += lo + y;
if (lo >= 16)
{
lo = 1;
if (!(bp &= 7))
优秀压缩算法UDA-PAQD2 0.284
最新推荐文章于 2024-05-19 01:47:05 发布