#include #include #include #include #define SIZE 255 int queue[SIZE]; int front, rear; typedef struct _jump { int index; struct _jump *next; }jump; jump jump_table[256]; #define ESCAPE 0xB4 #define IDENT1 0x33 #define IDENT2 0x44 #define FAIL 0xff void init_queue() { front = rear = 0; } int queue_full() { return (rear + 1) % SIZE == front; } int queue_empty() { return front == rear; } int put(int k) { queue[rear] = k; rear = ++ rear % SIZE; return k; } int get() { int i; i = queue[front]; front = ++front % SIZE; return i; } int qx(int k) { return (k + SIZE ) % SIZE; } void make_detname(char dstname[], char srcname[]) { Char temp[256]; fnsplit(srcname, temp, temp, dstname, temp); strcat(dstname, .lzw); } long file_length(char filename[]) { FILE *fp; long l; if( ( fp = fopen(filename, rb)) == NULL) return 0L; fseek(fp, 0, SEEK_END); l = ftell(fp); fclose(fp); return l; } void delete_all_jump() { int i; jump *j, *d; for(i = 0; i <256; i++) { j = jump_table[i].next; while( j != NULL) { d = j; j = j->next; free(d); } jump_table[i].next = NULL: } } void put_jump(int c, int ptr) { jump *j; if((j = (jump*)malloc(sizef(jump))) == NULL) { printf(\nError : Out of memory.); exit(1); } j->next = jump_table[c].next; jump_table[c].next = j; j->index = ptr; } void del_jump(int c, int ptr) { jump *j, *p; p = jump_table + c; j = ->next; while( j && j-> index != ptr) { p = j; j = j->next; } p->next = j-> next; free(j); } int qmatch(int length) { int i; jump *t, *p; int cp, sp; cp = qx(rear length); p = jump_table + queue[cp]; t = p->next; while(t != NULL) { sp = t->index; for(i = 1; i < 1 && queue[qx(sp+i)] == queue[qx(cp+i)]; i++); if(i == length) return sp; t = t->next; } return FAIL; } int putcl(int c, FILE *dst) { if(c == ESCAPE) { putc(ESCAPE, DST); putc(0x00, dst); } else putc(c, dst); return c; } void encode(int sp, int cp, int length, FILE *dst) { int I; for(i = 0; i < length; i++) put_jump(queue[qx(cp+i)], qx(cp+i)); putc(ESCAPE, dst); putc(qx(cp-sp), dst); putc(length, dst); } void lzwin_comp(FILE *src, char *srcname) { int length; char dstname[13]; FILE *dst; int sp, cp; int i, j; make_dstname(dstname, srcaname); if((dst = fopen(dstname, wb)) == NULL) { printf(\n Error : Cant create file); fcloseall(); exit(1); } putc(IDENT1, dst); putc(IDENT2, dst); puts(srcname, dst); putc(NULL, dst); for(i = 0; i <256; i++) jump_table[i].next = NULL; rewind(src); init_queue(); put(getc(src)); length = 0; while( ! feof(src)) { if(queue_full()) { if(sp == front) { if(length > 3) encode(sp, cp, length, dst); else for(i = 0; i 0) { j = qmatch(length + 1); if(j == FAIL) { if(length > 3) { encode(sp, cp, length, dst); length = 0; } else { for(i = 0; i < length; i++) { put_jump(queue[qx(cp+i)], qx(cp+i)); putc1(queue[qx(cp+i)], dst); } length = 0; } } else { sp = j; length++; put(getc(src)); } } } if(length > 3) encode(sp, cp, length, dst); else for(i = 0; i< length; i++) putc1(queue[qx(cp+i)], dst); delete_all_jump(); fclose(dst); } void put_byte(int c, FILE * dst) { if(queue_full()) putc(getc(), dst); putc(c); } void lzwin_decomp(FILE *src) { int c; char srcname[13]; FILE *dst; int length; int i = 0, j; int sp; rewind(src); c = getc(src); if(c != IDENT1 || getc(src) != IDENT2) { printf(\nError : That file is not LempelZiv Encoding file); fcloseall(); exit(1); } while((c = getc(src)) != NULL) srcname[i++] = c; srcname[i] = NULL; if((dst = fopen(srcname, wb)) == NULL) { printf(\n Error : Disk full); floseall(); exit(1); } init_queue(); c = getc(src); while(!feof(src)) { if(c == ESCAPE) { if((c == getc(src)) == 0) put_byte(ESCAPE, dst); else { length = getc(src); sp = qx(rear c); for( i= 0; i < length; i++) put_byte(queue[qx(sp+i)], dst); } } else put_byte(c, dst); c = getc(src); } while(! queue_empty()) putc(get(), dst); fclose(dst); } voidl main(int argc, char *argv[]) { FILE *src; long s, d; char dstname[13]; if(argc < 3) { printf(\n Usage : LZWIN < a or x> ); exit(1); } s = file_length(argv[2]); if((src = fopen(argv[2], rb)) == NULL) { printf(\n Error : that file does not exist.); exit(1); } if(srtcmp(argv[1], a) == 0) { lzwin_comp(src, argv[2]); make_dstname(dstname, argv[2]); d = file_length(dstname); printf(\nFile compressed to %d%%, (int)((double)d\s *100.)); } else if(strcmp(argv[1], x) == 0 ) { lzwin_decomp(src); printf(\nFiledecompressed & created); } fclose(src); }