#include #include #include #include #define LZW_MAX_CODES 4096 typedef struct double_s { short group,chr,first,next; }DOUBLE_S; typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES]; DOUBLE_S *compress_dic; int clear_code; int end_code; int free_code; int nextgroup; int bitsize,init_bitsize; char old_value=0; void do_clear_code() { int i; old_value=0; nextgroup=free_code; bitsize=init_bitsize; for(i=0;igroup=i;p->chr=-1;p->next=-1;p->first=-1; } } void reinit_lzw() { do_clear_code(); } void init_lzw_compressor(int dic_size) { compress_dic=(CODE_TABLE *)getmem(sizeof(CODE_TABLE)); clear_code=1<group; ps=compress_dic[ps].first; while (ps!=-1) { if (compress_dic[ps].chr==p->chr) return ps; ps=compress_dic[ps].next; } return -1; } void add_code(DOUBLE_S *p) { p->first=-1;p->next=compress_dic[p->group].first; memcpy(&compress_dic[nextgroup],p,sizeof(DOUBLE_S)); compress_dic[p->group].first=nextgroup; nextgroup++; } long lzw_encode(char *source,void *target,int size) { long bitpos=0; DOUBLE_S p; int f; clear: old_value=p.group=*source++;size--; while (size-->0) { p.chr=(int)((char)(*source++-old_value));old_value+=p.chr; f=find_code(&p); if (f<0) { bitpos=output_code(target,bitpos,bitsize,p.group); add_code(&p); if (nextgroup==(1<=LZW_MAX_CODES) { bitpos=output_code(target,bitpos,bitsize,p.group); bitpos=output_code(target,bitpos,bitsize,clear_code); do_clear_code(); goto clear; } } else p.group=f; } bitpos=output_code(target,bitpos,bitsize,p.group); bitpos=output_code(target,bitpos,bitsize,end_code); return (bitpos+8)>>3; } void de_add_code(DOUBLE_S *p,int *mask) { DOUBLE_S *q; q=&compress_dic[nextgroup];q->group=p->group;q->chr=p->chr;q->first=compress_dic[p->group].first+1; nextgroup++; if (nextgroup==*mask) { *mask=(*mask<<1)+1; bitsize++; } } int expand_code(int code,char **target) { static int first; if (code>end_code) { expand_code(compress_dic[code].group,target); **target=old_value=compress_dic[code].chr+old_value; (*target)++; } else { **target=old_value=code+old_value; (*target)++; first=code; } return first; } char fast_expand_code(int code,char **target); #pragma aux fast_expand_code parm[eax][edi] modify [esi ecx] value [bl] void lzw_decode(void *source,char *target) { long bitpos=0; int code,old,i; DOUBLE_S p; int old_first; int mask=0xff; for(i=0;i