#include #include #include #include #include #define getmem(s) malloc(s) #define New(typ) (typ *)getmem(sizeof(typ)) #define NewArr(typ,pocet) (typ *)getmem(sizeof(typ)*pocet); #define ClrArr(p,typ,pocet) memset(p,0,sizeof(typ)*pocet); #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; unsigned char old_value=0; void do_clear_code() //funkce maze slovni (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(); } char init_lzw_compressor(int dic_size) //dic size je velikost slovniku(bitova) //pro 8 bitove hodnoty zde vloz 8. { compress_dic=(DOUBLE_S *)getmem(sizeof(CODE_TABLE)); if (compress_dic==NULL) return -1; clear_code=1<>3; data<<=bitepos & 7; c[0]|=data; c[1]=data>>8; c[2]=data>>16; return bitepos+bitesize; } /*int input_code(void *source,long *bitepos,int bitsize,int mask); #pragma aux input_code parm [esi][edi][ebx][edx]=\ "mov ecx,[edi]"\ "mov eax,ecx"\ "shr eax,3"\ "mov eax,[esi+eax]"\ "and cl,7"\ "shr eax,cl"\ "and eax,edx"\ "add [edi],ebx"\ value[eax] modify [ecx]; */ int input_code_c(unsigned char *source,long *bitepos,int bitsize,int mask) { unsigned char *c;int x; c=source; c+=*bitepos>>3; x=c[0]+(c[1]<<8)+(c[2]<<16); x>>=*bitepos & 7; x &= mask; *bitepos=*bitepos+bitsize; return x; } int find_code(DOUBLE_S *p) //hleda skupinu ve slovniku. Pokud neexistuje vraci -1; { int ps; ps=p->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) //vklada novou dvojici { 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(unsigned char *source,void *target,int size) //Encode LZW. zdroj, cil a velikost dat. Vraci velikost komprimovano. { long bitpos=0; long maxbpos=size*8; DOUBLE_S p; int f; clear: old_value=(unsigned char)(p.group=*source++);size--; while (size-->0) { if (bitpos>maxbpos) return -1; p.chr=(int)((unsigned char)(*source++));old_value+=p.chr; f=find_code(&p); if (f<0) { bitpos=output_code_c(target,bitpos,bitsize,p.group); add_code(&p); if (nextgroup==(1<=LZW_MAX_CODES) { bitpos=output_code_c(target,bitpos,bitsize,p.group); bitpos=output_code_c(target,bitpos,bitsize,clear_code); do_clear_code(); goto clear; } } else p.group=f; } bitpos=output_code_c(target,bitpos,bitsize,p.group); bitpos=output_code_c(target,bitpos,bitsize,end_code); if (bitpos>maxbpos) return -1; 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,unsigned char **target) { static int first; if (code>end_code) { assert(compress_dic[code].group