?? unlzw.c
字號(hào):
/* unlzw.c -- decompress files in LZW format. * The code in this file is directly derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * This is a temporary version which will be rewritten in some future version * to accommodate in-memory decompression. */#ifdef RCSIDstatic char rcsid[] = "$Id: unlzw.c,v 0.15 1993/06/10 13:28:35 jloup Exp $";#endif#include <sys/types.h>#include "tailor.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifndef NO_FCNTL_H# include <fcntl.h>#endif#include "gzip.h"#include "lzw.h"typedef unsigned char char_type;typedef long code_int;typedef unsigned long count_int;typedef unsigned short count_short;typedef unsigned long cmp_code_int;#define MAXCODE(n) (1L << (n)) #ifndef REGISTERS# define REGISTERS 2#endif#define REG1 #define REG2 #define REG3 #define REG4 #define REG5 #define REG6 #define REG7 #define REG8 #define REG9 #define REG10#define REG11 #define REG12 #define REG13#define REG14#define REG15#define REG16#if REGISTERS >= 1# undef REG1# define REG1 register#endif#if REGISTERS >= 2# undef REG2# define REG2 register#endif#if REGISTERS >= 3# undef REG3# define REG3 register#endif#if REGISTERS >= 4# undef REG4# define REG4 register#endif#if REGISTERS >= 5# undef REG5# define REG5 register#endif#if REGISTERS >= 6# undef REG6# define REG6 register#endif#if REGISTERS >= 7# undef REG7# define REG7 register#endif#if REGISTERS >= 8# undef REG8# define REG8 register#endif#if REGISTERS >= 9# undef REG9# define REG9 register#endif#if REGISTERS >= 10# undef REG10# define REG10 register#endif#if REGISTERS >= 11# undef REG11# define REG11 register#endif#if REGISTERS >= 12# undef REG12# define REG12 register#endif#if REGISTERS >= 13# undef REG13# define REG13 register#endif#if REGISTERS >= 14# undef REG14# define REG14 register#endif#if REGISTERS >= 15# undef REG15# define REG15 register#endif#if REGISTERS >= 16# undef REG16# define REG16 register#endif #ifndef BYTEORDER# define BYTEORDER 0000#endif #ifndef NOALLIGN# define NOALLIGN 0#endifunion bytes { long word; struct {#if BYTEORDER == 4321 char_type b1; char_type b2; char_type b3; char_type b4;#else#if BYTEORDER == 1234 char_type b4; char_type b3; char_type b2; char_type b1;#else# undef BYTEORDER int dummy;#endif#endif } bytes;};#if BYTEORDER == 4321 && NOALLIGN == 1# define input(b,o,c,n,m){ \ (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ (o) += (n); \ }#else# define input(b,o,c,n,m){ \ REG1 char_type *p = &(b)[(o)>>3]; \ (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ ((long)(p[2])<<16))>>((o)&0x7))&(m); \ (o) += (n); \ }#endif#ifndef MAXSEG_64K /* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */# define tab_prefixof(i) tab_prefix[i]# define clear_tab_prefixof() memzero(tab_prefix, 256);#else /* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */ /* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd codes */ ush *tab_prefix[2];# define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]# define clear_tab_prefixof() \ memzero(tab_prefix0, 128), \ memzero(tab_prefix1, 128);#endif#define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1]))#define tab_suffixof(i) tab_suffix[i]int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 *//* ============================================================================ * Decompress in to out. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to * be stored in the compressed file. * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets iptr to insize-1 included. * The magic header has already been checked and skipped. * bytes_in and bytes_out have been initialized. */int unlzw(in, out) int in, out; /* input and output file descriptors */{ REG2 char_type *stackp; REG3 code_int code; REG4 int finchar; REG5 code_int oldcode; REG6 code_int incode; REG7 long inbits; REG8 long posbits; REG9 int outpos;/* REG10 int insize; (global) */ REG11 unsigned bitmask; REG12 code_int free_ent; REG13 code_int maxcode; REG14 code_int maxmaxcode; REG15 int n_bits; REG16 int rsize; #ifdef MAXSEG_64K tab_prefix[0] = tab_prefix0; tab_prefix[1] = tab_prefix1;#endif maxbits = get_byte(); block_mode = maxbits & BLOCK_MODE; if ((maxbits & LZW_RESERVED) != 0) { WARN((stderr, "\n%s: %s: warning, unknown flags 0x%x\n", progname, ifname, maxbits & LZW_RESERVED)); } maxbits &= BIT_MASK; maxmaxcode = MAXCODE(maxbits); if (maxbits > BITS) { fprintf(stderr, "\n%s: %s: compressed with %d bits, can only handle %d bits\n", progname, ifname, maxbits, BITS); exit_code = ERROR; return ERROR; } rsize = insize; maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<<n_bits)-1; oldcode = -1; finchar = 0; outpos = 0; posbits = inptr<<3; free_ent = ((block_mode) ? FIRST : 256); clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */ for (code = 255 ; code >= 0 ; --code) { tab_suffixof(code) = (char_type)code; } do { REG1 int i; int e; int o; resetbuf: e = insize-(o = (posbits>>3)); for (i = 0 ; i < e ; ++i) { inbuf[i] = inbuf[i+o]; } insize = e; posbits = 0; if (insize < INBUF_EXTRA) { if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) { read_error(); } insize += rsize; bytes_in += (ulg)rsize; } inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : ((long)insize<<3)-(n_bits-1)); while (inbits > posbits) { if (free_ent > maxcode) { posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ++n_bits; if (n_bits == maxbits) { maxcode = maxmaxcode; } else { maxcode = MAXCODE(n_bits)-1; } bitmask = (1<<n_bits)-1; goto resetbuf; } input(inbuf,posbits,code,n_bits,bitmask); Tracev((stderr, "%d ", code)); if (oldcode == -1) { if (code >= 256) error("corrupt input."); outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code)); continue; } if (code == CLEAR && block_mode) { clear_tab_prefixof(); free_ent = FIRST - 1; posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<<n_bits)-1; goto resetbuf; } incode = code; stackp = de_stack; if (code >= free_ent) { /* Special case for KwKwK string. */ if (code > free_ent) {#ifdef DEBUG char_type *p; posbits -= n_bits; p = &inbuf[posbits>>3]; fprintf(stderr, "code:%ld free_ent:%ld n_bits:%d insize:%u\n", code, free_ent, n_bits, insize); fprintf(stderr, "posbits:%ld inbuf:%02X %02X %02X %02X %02X\n", posbits, p[-1],p[0],p[1],p[2],p[3]);#endif if (!test && outpos > 0) { write_buf(out, (char*)outbuf, outpos); bytes_out += (ulg)outpos; } error(to_stdout ? "corrupt input." : "corrupt input. Use zcat to recover some data."); } *--stackp = (char_type)finchar; code = oldcode; } while ((cmp_code_int)code >= (cmp_code_int)256) { /* Generate output characters in reverse order */ *--stackp = tab_suffixof(code); code = tab_prefixof(code); } *--stackp = (char_type)(finchar = tab_suffixof(code)); /* And put them out in forward order */ { REG1 int i; if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) { do { if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos; if (i > 0) { memcpy(outbuf+outpos, stackp, i); outpos += i; } if (outpos >= OUTBUFSIZ) { if (!test) { write_buf(out, (char*)outbuf, outpos); bytes_out += (ulg)outpos; } outpos = 0; } stackp+= i; } while ((i = (de_stack-stackp)) > 0); } else { memcpy(outbuf+outpos, stackp, i); outpos += i; } } if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */ tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = (char_type)finchar; free_ent = code+1; } oldcode = incode; /* Remember previous code. */ } } while (rsize != 0); if (!test && outpos > 0) { write_buf(out, (char*)outbuf, outpos); bytes_out += (ulg)outpos; } return OK;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -