/* * Decompress the input file. */ #include #include "lz1.h" extern int SWAPword(int); WORD fetch(void); WORD getcode( FILE *); #define swapword(x) SWAPword(x) /* problems with the decompression: works for about 600H bytes, then loses it. Get skipped text and nuls in the body of the decompressed file. */ WORD de_LZ_1(infile, outfile, bytes) FILE *infile, *outfile; long bytes; { WORD tag, finchar, ii, code, oldcode, incode, stack_top = MAXSTACK; UCHAR stack[MAXSTACK+1]; int many ; /* problem with byte order here */ many= fread(&tag,sizeof(tag),1,infile); if (many < 1 ) return(-2); tag = (WORD)swapword((WORD)tag); /* to correct byte order */ if ( tag != TAG ) return( -2); /* CWW, was if (fread(&tag, sizeof(tag), 1, infile) < 1 || tag != TAG) return (-2); */ lz1_init(); /* initializes maxcode, maxmaxcode */ lz_bytes = bytes - sizeof(tag); /* first 256 codes are themselves */ for (free_ent = 0; free_ent < 256 ; free_ent++) { Code[free_ent].next = Code[free_ent].chain = (WORD) NULL; Code[free_ent].prefix = (WORD)NULL; Code[free_ent].suffix = (WORD)free_ent; } /* starts with free_ent = 256 below */ oldcode = getcode(infile); finchar = oldcode; /* get first code, output it, and put it in the table */ fwrite(&finchar,1,1, outfile); /* first code must be 8 bits */ while ((code = getcode(infile)) != (WORD)(-1) ) { incode = code; if (code >= free_ent) /* Special case for KwKwK string. */ { stack[--stack_top] = (UCHAR)(finchar & 0x00ff); code = oldcode; } while (code >= (WORD) 256) /* Generate characters in reverse order */ { stack[--stack_top] = (UCHAR)(Code[code].suffix & 0x00ff); code = Code[code].prefix; } finchar = Code[code].suffix; stack[--stack_top] = (UCHAR)( finchar & 0x00ff); /* And put them out in forward order */ fwrite(&stack[stack_top], 1, MAXSTACK - stack_top, outfile); stack_top = MAXSTACK; if ((code = free_ent) < maxmaxcode) /* Generate new entry */ { Code[code].prefix = oldcode; Code[code].suffix = finchar; free_ent++; } oldcode = incode; /* Remember previous code. */ } return (code); } /*page*/ /* * Read one code from the input file. If EOF, return -1. file is viewed logically as a bitstream???? */ static WORD size = 0; WORD getcode(infile) FILE *infile; { WORD code; if ( ( offset >= size) || (free_ent > maxcode) ) /* need to refill buffer ?? */ { if (free_ent > maxcode) { n_bits++; /* new entry too big, increase size */ maxcode = (n_bits == maxbits) ? maxmaxcode : (1 << n_bits) - 1; } if (lz_bytes <= 0) return ((UWORD)(-1)); /* "eof" */ /* read n_bits bytes or what's left */ size = (lz_bytes > (long) n_bits) ? n_bits : (int) lz_bytes; size = fread(buf, 1, size, infile); /* read new buffer too */ /* reads in by bytes */ if (size <= 0) return ((UWORD)(-1)); lz_bytes -= size; /* adjust total */ offset = 0; /* set beginning of bits */ /* * Convert size to bits, and round down so that stray bits * at the end aren't treated as data */ size = BytesToBits(size) - (n_bits - 1); } code = fetch(); /* get the bits */ offset += n_bits; /* adjust position */ return(code); } /* try to solve byte order problem in buffer by making it only bytes?? */ WORD fetch() { UWORD w_offset, fetchword, size2; UWORD high,low; UWORD mask; mask = LowOrder(n_bits); fetchword = offset >> LOG2WSIZE; /* offset measured in bits, so convert */ w_offset = LowOrder(LOG2WSIZE) & offset; /* try to solve byte order */ high = buf[fetchword]; high = SWAPword(high); low = buf[fetchword + 1]; low = SWAPword(low); if (w_offset + n_bits <= WSIZE) { /* all in one word in bit buffer */ high = high >> ( (WSIZE -n_bits) -w_offset) ; high &= mask; return((WORD)high); } else { /* if n_bits > 8 this one will be use all the time */ size2 = n_bits - (WSIZE - w_offset); high = (high << size2) & mask; low = (low >> (WSIZE -size2) ) & mask; return((WORD) ( high | low ) ); } }