www.pudn.com > gzip.rar > gzip.c
/* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * Copyright (C) 1992-1993 Jean-loup Gailly * The unzip code was written and put in the public domain by Mark Adler. * Portions of the lzw code are 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. * * See the license_msg below and the file COPYING for the software license. * See the file algorithm.doc for the compression algorithms and file formats. */ /* Compress files with zip algorithm and 'compress' interface. * See usage() and help() functions below for all options. * Outputs: * file.gz: compressed file with same mode, owner, and utimes * or stdout with -c option or if stdin used as input. * If the output file name had to be truncated, the original name is kept * in the compressed file. * On MSDOS, file.tmp -> file.tmz. On VMS, file.tmp -> file.tmp-gz. * * Using gz on MSDOS would create too many file name conflicts. For * example, foo.txt -> foo.tgz (.tgz must be reserved as shorthand for * tar.gz). Similarly, foo.dir and foo.doc would both be mapped to foo.dgz. * I also considered 12345678.txt -> 12345txt.gz but this truncates the name * too heavily. There is no ideal solution given the MSDOS 8+3 limitation. * * For the meaning of all compilation flags, see comments in Makefile.in. */ #include#include "zipmem.h" #include "gzip.h" #include "lzw.h" /* global buffers */ DECLARE( uch, inbuf, INBUFSIZ + INBUF_EXTRA ); DECLARE( uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA ); DECLARE( ush, d_buf, DIST_BUFSIZE ); DECLARE( uch, window, 2L * WSIZE ); /* 声明 */ DECLARE( ush, tab_prefix, 1L << BITS ); /* local variables */ int quiet = 0; /* be very quiet (-q) */ int maxbits = BITS; /* max bits per code for LZW */ int method = DEFLATED;/* compression method */ int level = 6; /* compression level */ int exit_code = 0; /* program exit code */ int time_stamp; /* original time stamp (modification time) */ int bytes_in = 0; /* number of input bytes */ int bytes_out = 0; /* number of output bytes */ int total_in = 0; /* input bytes for all files */ int total_out = 0; /* output bytes for all files */ unsigned insize = 0; /* valid bytes in inbuf */ unsigned inptr = 0; /* index of next byte to be processed in inbuf */ unsigned outcnt = 0; /* bytes in output buffer */ local int get_method OF(()); int (* work ) OF(()) = zip; /* function to call */ /* ======================================================================== * Compress */ int zipmem( char * mem_inptr, int mem_insize, char * mem_outptr ) { time_stamp = 0; ALLOC( uch, inbuf, INBUFSIZ + INBUF_EXTRA ); ALLOC( uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA ); ALLOC( ush, d_buf, DIST_BUFSIZE ); ALLOC( uch, window, 2L * WSIZE ); /* 分配 */ ALLOC( ush, tab_prefix, 1L << BITS ); clear_bufs(); /* clear input and output buffers */ zip_mem_outptr = mem_outptr; /* 输出缓存 */ zip_mem_outlen = 0; /* 输出缓存大小 */ zip_mem_inptr = mem_inptr; /* 输入指针 */ zip_mem_insize = mem_insize; /* 输入缓存长度 */ zip_mem_inpos = 0; /* 输入缓存当前位置 */ zip(); FREE( inbuf ); FREE( outbuf ); FREE( d_buf ); FREE( window ); FREE( tab_prefix ); return zip_mem_outlen; } /* ======================================================================== * deCompress */ int unzipmem( char * mem_inptr, int mem_insize, char * mem_outptr ) { time_stamp = 0; ALLOC( uch, inbuf, INBUFSIZ + INBUF_EXTRA ); ALLOC( uch, outbuf, OUTBUFSIZ + OUTBUF_EXTRA ); ALLOC( ush, d_buf, DIST_BUFSIZE ); ALLOC( uch, window, 2L * WSIZE );/* 分配 */ ALLOC( ush, tab_prefix, 1L << BITS ); clear_bufs(); /* clear input and output buffers */ zip_mem_outptr = mem_outptr; /* 输出缓存 */ zip_mem_outlen = 0; /* 输出缓存大小 */ /* 解压缩 */ unzip_mem_inptr = mem_inptr; /* 输入指针 */ unzip_mem_insize = mem_insize; /* 输入缓存长度 */ unzip_mem_inpos = 0; /* 输入缓存当前位置 */ get_method(); unzip(); FREE( inbuf ); FREE( outbuf ); FREE( d_buf ); FREE( window ); FREE( tab_prefix ); return zip_mem_outlen; } /* ======================================================================== * Check the magic number of the input file and update ofname if an * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. * Updates time_stamp if there is one and --no-time is not used. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. * If the member is a zip file, it must be the only one. */ local int get_method() { /* If --force and --stdout, zcat == cat, so do not complain about * premature end of file: use try_byte instead of get_byte. */ ( char )get_byte(); ( char )get_byte(); method = - 1; /* unknown yet */ /* assume multiple members in gzip file except for record oriented I/O */ method = ( int )get_byte(); work = unzip; ( uch )get_byte(); ( ulg )get_byte(); (( ulg )get_byte()); (( ulg )get_byte()); (( ulg )get_byte()); ( void )get_byte(); /* Ignore extra flags for the moment */ ( void )get_byte(); /* Ignore OS type for the moment */ return method; }