一个lzw算法例子供参考

一个lzw算法例子供参考
class LZWCoder
{
private:
        struct TStr
        {
                char *string;
                unsigned int len;
        };
        TStr StrTable[4097];
        unsigned int ItemPt;
        unsigned int BytePt;
        unsigned char BitPt;
        unsigned char Bit[8];
        unsigned char Bits;
        unsigned int OutBytes;
        void InitStrTable();
        void CopyStr(TStr *d, TStr s);
        void StrJoinChar(TStr *s, char c);
        unsigned int InStrTable(TStr s);
        void AddTableEntry(TStr s);
        void WriteCode(char *dest, unsigned int b);
        unsigned int GetNextCode(char *src);
        void StrFromCode(TStr *s, unsigned int c);
        void WriteString(char *dest, TStr s);
public:
        unsigned int Encode(char *src, unsigned int len, char *dest);
        unsigned int Decode(char *src, unsigned int *len, char *dest);
        LZWCoder();
        ~LZWCoder();
};

void LZWCoder::InitStrTable()
{
        unsigned int i;
        for(i = 0; i < 256; i ++)
        {
                StrTable[i].string = (char *)realloc(StrTable[i].string, 1);
                StrTable[i].string[0] = i;
                StrTable[i].len = 1;
        }
        StrTable[256].string = NULL;
        StrTable[256].len = 0;
        StrTable[257].string = NULL;
        StrTable[257].len = 0;
        ItemPt = 257;
        Bits = 9;
}

void LZWCoder::CopyStr(TStr *d, TStr s)
{
        unsigned int i;
        d->string = (char *)realloc(d->string, s.len);
        for(i = 0; i < s.len; i ++)
                d->string[i] = s.string[i];
        d->len = s.len;
}

void LZWCoder::StrJoinChar(TStr *s, char c)
{
        s->string = (char *)realloc(s->string, s->len + 1);
        s->string[s->len ++] = c;
}

unsigned int LZWCoder::InStrTable(TStr s)
{
        unsigned int i,j;
        bool b;
        for(i = 0; i <= ItemPt; i ++)
        {
                if(StrTable[i].len == s.len)
                {
                        b = true;
                        for(j = 0; j < s.len; j ++)
                                if(StrTable[i].string[j] != s.string[j])
                                {
                                        b = false;
                                        break;
                                }
                        if(b) return i;
                }
        }
        return 65535;
}

void LZWCoder::AddTableEntry(TStr s)
{
        CopyStr(&StrTable[++ItemPt], s);
}

void LZWCoder::WriteCode(char *dest, unsigned int b)
{
        unsigned char i;
        for(i = 0; i < Bits; i++)
        {
                Bit[BitPt ++] = (b & (1 << (Bits - i - 1))) != 0;
                if(BitPt == 8)
                {
                        BitPt = 0;
                        dest[BytePt ++] = (Bit[0] << 7)
                                        + (Bit[1] << 6)
                                        + (Bit[2] << 5)
                                        + (Bit[3] << 4)
                                        + (Bit[4] << 3)
                                        + (Bit[5] << 2)
                                        + (Bit[6] << 1)
                                        + Bit[7];
                }
        }
}

unsigned int LZWCoder::GetNextCode(char *src)
{
        unsigned char i;
        unsigned int c = 0;
        for(i = 0; i < Bits; i ++)
        {
                c = (c << 1) + ((src[BytePt] & (1 << (8 - (BitPt ++) - 1))) != 0);
                if(BitPt == 8)
                {
                        BitPt = 0;
                        BytePt ++;
                }
        }
        return c;
}

void LZWCoder::StrFromCode(TStr *s, unsigned int c)
{
        CopyStr(s, StrTable[c]);
}

void LZWCoder::WriteString(char *dest, TStr s)
{
        unsigned int i;
        for(i = 0; i < s.len; i++)
                dest[OutBytes ++] = s.string[i];
}

unsigned int LZWCoder::Encode(char *src, unsigned int len, char *dest)
{
        TStr Omega, t;
        char k;
        unsigned int i;
        unsigned int p;
        BytePt = 0;
        BitPt = 0;
        InitStrTable();
        WriteCode(dest, 256);
        Omega.string = NULL;
        Omega.len = 0;
        t.string = NULL;
        t.len = 0;
        for(i = 0; i < len; i ++)
        {
                k = src[i];
                CopyStr(&t, Omega);
                StrJoinChar(&t, k);
                if(InStrTable(t) != 65535)
                        CopyStr(&Omega, t);
                else
                {
                        WriteCode(dest, InStrTable(Omega));
                        AddTableEntry(t);
                        switch(ItemPt)
                        {
                                case 512: Bits = 10; break;
                                case 1024: Bits = 11; break;
                                case 2048: Bits = 12; break;
                                case 4096: WriteCode(dest, 256); InitStrTable();
                        }
                        Omega.string = (char *)realloc(Omega.string, 1);
                        Omega.string[0] = k;
                        Omega.len = 1;
                }
        }
        WriteCode(dest, InStrTable(Omega));
        WriteCode(dest, 257);
        Bits = 7;
        WriteCode(dest, 0);
        free(Omega.string);
        free(t.string);
        return BytePt;
}

unsigned int LZWCoder::Decode(char *src, unsigned int *len, char *dest)
{
        unsigned int code, oldcode;
        TStr t, s;
        BytePt = 0;
        BitPt = 0;
        OutBytes = 0;
        t.string = NULL;
        t.len = 0;
        s.string = NULL;
        s.len = 0;
        InitStrTable();
        while((code = GetNextCode(src)) != 257)
        {
                if(code == 256)
                {
                        InitStrTable();
                        code = GetNextCode(src);
                        if(code == 257) break;
                        StrFromCode(&s, code);
                        WriteString(dest, s);
                        oldcode = code;
                }
                else
                {
                        if(code <= ItemPt)
                        {
                                StrFromCode(&s, code);
                                WriteString(dest, s);
                                StrFromCode(&t, oldcode);
                                StrJoinChar(&t, s.string[0]);
                                AddTableEntry(t);
                                switch(ItemPt)
                                {
                                        case 511: Bits = 10; break;
                                        case 1023: Bits = 11; break;
                                        case 2047: Bits = 12; break;
                                }
                                oldcode = code;
                        }
                        else
                        {
                                StrFromCode(&s, oldcode);
                                StrJoinChar(&s, s.string[0]);
                                WriteString(dest, s);
                                AddTableEntry(s);
                                switch(ItemPt)
                                {
                                        case 511: Bits = 10; break;
                                        case 1023: Bits = 11; break;
                                        case 2047: Bits = 12; break;
                                }
                                oldcode = code;
                        }
                }
        }
        free(t.string);
        free(s.string);
        *len = BytePt + (BitPt != 0);
        return OutBytes;
}

LZWCoder::LZWCoder()
{
        unsigned int i;
        for(i = 0; i < 4097; i ++)
        {
                StrTable[i].string = NULL;
                StrTable[i].len = 0;
        }
}

LZWCoder::~LZWCoder()
{
        unsigned int i;
        for(i = 0; i < 4097; i ++)
                free(StrTable[i].string);
}


/
LZWCoder *Coder;
Coder = new LZWCoder();
//然后用
//Coder->Encode(char *src, unsigned int len, char *dest);
//Coder->Decode(char *src, unsigned int *len, char *dest);
int idatasize = 1024*1024*10;
char *shsrc = new char[idatasize];
char *shdest = new char[idatasize];
char *shdecodedest = new char[idatasize];

for (int i=0;i<idatasize;i++)
{
 *(shsrc+i) = i%256;
}
memset(shdest,0,idatasize);
memset(shdecodedest,0,idatasize);

DWORD dbeg11111 = GetTickCount();
unsigned int iretval =  Coder->Encode(shsrc, idatasize, shdest);
DWORD dbeg22222 = GetTickCount();
iretval = Coder->Decode(shdest, (unsigned int*)&iretval, shdecodedest);
DWORD dbeg33333 = GetTickCount();

std::cout<<"en = " << dbeg22222-dbeg11111 <<";de = "  <<dbeg33333-dbeg22222 <<std::endl;
std::cin>>dbeg22222;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值