diff options
-rw-r--r-- | sys/net/ppp_deflate.c | 11 | ||||
-rw-r--r-- | sys/net/zlib.c | 2172 | ||||
-rw-r--r-- | sys/net/zlib.h | 628 |
3 files changed, 1959 insertions, 852 deletions
diff --git a/sys/net/ppp_deflate.c b/sys/net/ppp_deflate.c index a3f8423..08d1f22 100644 --- a/sys/net/ppp_deflate.c +++ b/sys/net/ppp_deflate.c @@ -1,4 +1,4 @@ -/* $Id: ppp_deflate.c,v 1.5 1997/09/21 22:31:20 dyson Exp $ */ +/* $Id: ppp_deflate.c,v 1.6 1997/10/28 15:58:32 bde Exp $ */ /* * ppp_deflate.c - interface the zlib procedures for Deflate compression @@ -60,7 +60,7 @@ struct deflate_state { #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ static void *z_alloc __P((void *, u_int items, u_int size)); -static void z_free __P((void *, void *ptr, u_int nb)); +static void z_free __P((void *, void *ptr)); static void *z_comp_alloc __P((u_char *options, int opt_len)); static void *z_decomp_alloc __P((u_char *options, int opt_len)); static void z_comp_free __P((void *state)); @@ -113,10 +113,9 @@ z_alloc(notused, items, size) } void -z_free(notused, ptr, nbytes) +z_free(notused, ptr) void *notused; void *ptr; - u_int nbytes; { FREE(ptr, M_DEVBUF); } @@ -148,10 +147,9 @@ z_comp_alloc(options, opt_len) state->strm.next_in = NULL; state->strm.zalloc = z_alloc; - state->strm.zalloc_init = z_alloc; state->strm.zfree = z_free; if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL, - -w_size, 8, Z_DEFAULT_STRATEGY, DEFLATE_OVHD+2) != Z_OK) { + -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) { FREE(state, M_DEVBUF); return NULL; } @@ -380,7 +378,6 @@ z_decomp_alloc(options, opt_len) state->strm.next_out = NULL; state->strm.zalloc = z_alloc; - state->strm.zalloc_init = z_alloc; state->strm.zfree = z_free; if (inflateInit2(&state->strm, -w_size) != Z_OK) { FREE(state, M_DEVBUF); diff --git a/sys/net/zlib.c b/sys/net/zlib.c index 7681c2a..1016253 100644 --- a/sys/net/zlib.c +++ b/sys/net/zlib.c @@ -1,29 +1,37 @@ /* - * This file is derived from various .h and .c files from the zlib-0.95 + * This file is derived from various .h and .c files from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. See zlib.h for conditions of * distribution and use. * * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp + * - added inflateIncomp and deflateOutputPending + * - allow strm->next_out to be NULL, meaning discard the output * - * $Id: zlib.c,v 1.4 1997/09/01 02:18:13 bde Exp $ + * $Id: zlib.c,v 1.5 1998/02/09 06:10:02 eivind Exp $ */ /* - * ==FILEVERSION 970501== + * ==FILEVERSION 971210== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. */ -/*+++++*/ +#define NO_DUMMY_DECL +#define NO_ZCFUNCS +#define MY_ZCALLOC + +#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) +#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ +#endif + + +/* +++ zutil.h */ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. + * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -32,8 +40,9 @@ subject to change. Applications should only use zlib.h. */ -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ +/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */ +#ifndef _Z_UTIL_H #define _Z_UTIL_H #ifdef KERNEL @@ -42,32 +51,59 @@ #include "zlib.h" #endif +#if defined(KERNEL) || defined(_KERNEL) +/* Assume this is a *BSD or SVR4 kernel */ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/systm.h> +# define HAVE_MEMCPY +# define memcpy(d, s, n) bcopy((s), (d), (n)) +# define memset(d, v, n) bzero((d), (n)) +# define memcmp bcmp + +#else +#if defined(__KERNEL__) +/* Assume this is a Linux kernel */ +#include <linux/string.h> +#define HAVE_MEMCPY + +#else /* not kernel */ + +#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) +# include <stddef.h> +# include <errno.h> +#else + extern int errno; +#endif +#ifdef STDC +# include <string.h> +# include <stdlib.h> +#endif +#endif /* __KERNEL__ */ +#endif /* _KERNEL || KERNEL */ + #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ -#define FAR - typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] -#ifndef NULL -#define NULL ((void *) 0) -#endif +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ /* common constants */ -#define DEFLATED 8 - #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif @@ -89,34 +125,103 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ #define MAX_MATCH 258 /* The minimum and maximum match lengths */ - /* functions */ +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ -#if defined(KERNEL) || defined(_KERNEL) -#include <sys/types.h> -#include <sys/systm.h> -# define zmemcpy(d, s, n) bcopy((s), (d), (n)) -# define zmemzero bzero + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# ifdef __TURBOC__ +# include <alloc.h> +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define FOPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef MACOS +# define OS_CODE 0x07 +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + + /* Common defaults */ +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef FOPEN +# define FOPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) #else -#if defined(__KERNEL__) -/* Assume this is Linux */ -#include <linux/string.h> -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) +# define zstrerror(errnum) "" +#endif -#else /* not kernel */ +#if defined(pyr) +# define NO_MEMCPY +#endif +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + */ +# define NO_MEMCPY +#endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else # define zmemcpy memcpy +# define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) +# endif #else extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); + extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len)); #endif -#endif /* __KERNEL__ */ -#endif /* KERNEL */ /* Diagnostic functions */ #ifdef DEBUG_ZLIB @@ -124,6 +229,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ # ifndef verbose # define verbose 0 # endif + extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) fprintf x # define Tracev(x) {if (verbose) fprintf x ;} @@ -140,21 +246,22 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ #endif -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); +typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZALLOC_INIT(strm, items, size) \ - (*((strm)->zalloc_init))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ +/* --- zutil.h */ +/* +++ deflate.h */ /* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly + * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -163,19 +270,17 @@ typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); subject to change. Applications should only use zlib.h. */ +/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */ -/*+++++*/ -/* From: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp */ +#ifndef _DEFLATE_H +#define _DEFLATE_H + +/* #include "zutil.h" */ /* =========================================================================== * Internal compression state. */ -/* Data type */ -#define Z_BINARY 0 -#define ASCII 1 -#define UNKNOWN 2 - #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ @@ -199,7 +304,6 @@ typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); #define INIT_STATE 42 #define BUSY_STATE 113 -#define FLUSH_STATE 124 #define FINISH_STATE 666 /* Stream status */ @@ -238,16 +342,16 @@ typedef unsigned IPos; */ typedef struct deflate_state { - z_stream *strm; /* pointer back to this zlib stream */ + z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ int pending; /* nb of bytes in the pending buffer */ - uLong adler; /* adler32 of uncompressed data */ int noheader; /* suppress zlib header and adler32 */ - Byte data_type; /* UNKNOWN, Z_BINARY or ASCII */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte method; /* STORED (for zip only) or DEFLATED */ - int minCompr; /* min size decrease for Z_FLUSH_NOSTORE */ + int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ @@ -330,7 +434,7 @@ typedef struct deflate_state { uInt good_match; /* Use a faster search when the previous match is longer than this */ - int nice_match; /* Stop searching when current match exceeds this */ + int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ @@ -405,11 +509,6 @@ typedef struct deflate_state { * are always zero. */ - uInt blocks_in_packet; - /* Number of blocks produced since the last time Z_PACKET_FLUSH - * was used. - */ - } FAR deflate_state; /* Output a byte on the stream. @@ -429,19 +528,21 @@ typedef struct deflate_state { */ /* in trees.c */ -local void ct_init OF((deflate_state *s)); -local int ct_tally OF((deflate_state *s, int dist, int lc)); -local ulg ct_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int flush)); -local void ct_align OF((deflate_state *s)); -local void ct_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); -local void ct_stored_type_only OF((deflate_state *s)); +void _tr_stored_type_only OF((deflate_state *)); +#endif +/* --- deflate.h */ -/*+++++*/ +/* +++ deflate.c */ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995 Jean-loup Gailly. + * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -478,8 +579,8 @@ local void ct_stored_type_only OF((deflate_state *s)); * * REFERENCES * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. @@ -489,9 +590,11 @@ local void ct_stored_type_only OF((deflate_state *s)); * */ -/* From: deflate.c,v 1.8 1995/05/03 17:27:08 jloup Exp */ +/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */ + +/* #include "deflate.h" */ -local char zlib_copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; +char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -499,6 +602,43 @@ local char zlib_copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; copyright string in the executable of your product. */ +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG_ZLIB +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + #define NIL 0 /* Tail of hash chains */ @@ -517,27 +657,27 @@ local char zlib_copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; * exclude worst case performance for pathological files. Better values may be * found for specific files. */ - typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; + compress_func func; } config; local config configuration_table[10] = { /* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0}, /* store only */ -/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8}, -/* 3 */ {4, 6, 32, 32}, - -/* 4 */ {4, 4, 16, 16}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32}, -/* 6 */ {8, 16, 128, 128}, -/* 7 */ {8, 32, 128, 256}, -/* 8 */ {32, 128, 258, 1024}, -/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different @@ -547,28 +687,10 @@ local config configuration_table[10] = { #define EQUAL 0 /* result of memcmp for equal strings */ -/* =========================================================================== - * Prototypes for local functions. - */ - -local void fill_window OF((deflate_state *s)); -local int deflate_fast OF((deflate_state *s, int flush)); -local int deflate_slow OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local int longest_match OF((deflate_state *s, IPos cur_match)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_stream *strm)); -local int read_buf OF((z_stream *strm, charf *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ -#endif - -#ifdef DEBUG_ZLIB -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif - /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive @@ -589,7 +711,7 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (str)) + s->head[s->ins_h] = (Pos)(str)) /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). @@ -600,34 +722,52 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ -int deflateInit (strm, level) - z_stream *strm; +int deflateInit_(strm, level, version, stream_size) + z_streamp strm; int level; + const char *version; + int stream_size; { - return deflateInit2 (strm, level, DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - 0, 0); + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ -int deflateInit2 (strm, level, method, windowBits, memLevel, - strategy, minCompression) - z_stream *strm; +int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; - int minCompression; + const char *version; + int stream_size; { deflate_state *s; int noheader = 0; + static char* my_version = ZLIB_VERSION; + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; -/* if (strm->zalloc == Z_NULL) strm->zalloc = zcalloc; */ -/* if (strm->zfree == Z_NULL) strm->zfree = zcfree; */ +#ifndef NO_ZCFUNCS + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; +#endif if (level == Z_DEFAULT_COMPRESSION) level = 6; @@ -635,11 +775,12 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, noheader = 1; windowBits = -windowBits; } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || - windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } - s = (deflate_state *) ZALLOC_INIT(strm, 1, sizeof(deflate_state)); + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; @@ -654,45 +795,83 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - s->window = (Bytef *) ZALLOC_INIT(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC_INIT(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC_INIT(strm, s->hash_size, sizeof(Pos)); + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - s->pending_buf = (uchf *) ZALLOC_INIT(strm, s->lit_bufsize, 2*sizeof(ush)); + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { - strm->msg = z_errmsg[1-Z_MEM_ERROR]; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } - s->d_buf = (ushf *) &(s->pending_buf[s->lit_bufsize]); - s->l_buf = (uchf *) &(s->pending_buf[3*s->lit_bufsize]); - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 32 bits (worst case - * is 15+15+13=33). - */ + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; - s->minCompr = minCompression; - s->blocks_in_packet = 0; return deflateReset(strm); } /* ========================================================================= */ +int deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + + s = (deflate_state *) strm->state; + if (s->status != INIT_STATE) return Z_STREAM_ERROR; + + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy((charf *)s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ int deflateReset (strm) - z_stream *strm; + z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == Z_NULL || strm->zfree == Z_NULL || - strm->zalloc_init == Z_NULL) return Z_STREAM_ERROR; + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ @@ -706,14 +885,51 @@ int deflateReset (strm) s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ } s->status = s->noheader ? BUSY_STATE : INIT_STATE; - s->adler = 1; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; - ct_init(s); + _tr_init(s); lm_init(s); return Z_OK; } +/* ========================================================================= */ +int deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = (deflate_state *) strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in @@ -728,191 +944,282 @@ local void putShortMSB (s, b) } /* ========================================================================= - * Flush as much pending output as possible. + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). */ local void flush_pending(strm) - z_stream *strm; + z_streamp strm; { - deflate_state *state = (deflate_state *) strm->state; - unsigned len = state->pending; + deflate_state *s = (deflate_state *) strm->state; + unsigned len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; - if (strm->next_out != NULL) { - zmemcpy(strm->next_out, state->pending_out, len); + if (strm->next_out != Z_NULL) { + zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; } - state->pending_out += len; + s->pending_out += len; strm->total_out += len; - strm->avail_out -= len; - state->pending -= len; - if (state->pending == 0) { - state->pending_out = state->pending_buf; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; } } /* ========================================================================= */ int deflate (strm, flush) - z_stream *strm; + z_streamp strm; int flush; { - deflate_state *state = (deflate_state *) strm->state; + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; - if (strm == Z_NULL || state == Z_NULL) return Z_STREAM_ERROR; - - if (strm->next_in == Z_NULL && strm->avail_in != 0) { + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) strm->state; + + if ((strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - state->strm = strm; /* just in case */ + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; /* Write the zlib header */ - if (state->status == INIT_STATE) { + if (s->status == INIT_STATE) { - uInt header = (DEFLATED + ((state->w_bits-8)<<4)) << 8; - uInt level_flags = (state->level-1) >> 1; + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); - state->status = BUSY_STATE; - putShortMSB(state, header); + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; } /* Flush as much pending output as possible */ - if (state->pending != 0) { + if (s->pending != 0) { flush_pending(strm); - if (strm->avail_out == 0) return Z_OK; - } + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } - /* If we came back in here to get the last output from - * a previous flush, we're done for now. + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. */ - if (state->status == FLUSH_STATE) { - state->status = BUSY_STATE; - if (flush != Z_NO_FLUSH && flush != Z_FINISH) - return Z_OK; + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ - if (state->status == FINISH_STATE && strm->avail_in != 0) { + if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ - if (strm->avail_in != 0 || state->lookahead != 0 || - (flush == Z_FINISH && state->status != FINISH_STATE)) { - int quit; + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; - if (flush == Z_FINISH) { - state->status = FINISH_STATE; - } - if (state->level <= 3) { - quit = deflate_fast(state, flush); - } else { - quit = deflate_slow(state, flush); - } - if (quit || strm->avail_out == 0) - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } + bstate = (*(configuration_table[s->level].func))(s, flush); - /* If a flush was requested, we have a little more to output now. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH - && state->status != FINISH_STATE) { - switch (flush) { - case Z_PARTIAL_FLUSH: - ct_align(state); - break; - case Z_PACKET_FLUSH: - /* Output just the 3-bit `stored' block type value, - but not a zero length. */ - ct_stored_type_only(state); - break; - default: - ct_stored_block(state, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(state); /* forget history */ + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } - } - flush_pending(strm); - if (strm->avail_out == 0) { - /* We'll have to come back to get the rest of the output; - * this ensures we don't output a second zero-length stored - * block (or whatever). - */ - state->status = FLUSH_STATE; return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush == Z_PACKET_FLUSH) { + /* Output just the 3-bit `stored' block type value, + but not a zero length. */ + _tr_stored_type_only(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } } - Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; - if (state->noheader) return Z_STREAM_END; + if (s->noheader) return Z_STREAM_END; /* Write the zlib trailer (adler32) */ - putShortMSB(state, (uInt)(state->adler >> 16)); - putShortMSB(state, (uInt)(state->adler & 0xffff)); + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ - state->noheader = -1; /* write the trailer only once! */ - return state->pending != 0 ? Z_OK : Z_STREAM_END; + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int deflateEnd (strm) - z_stream *strm; + z_streamp strm; { - deflate_state *state = (deflate_state *) strm->state; + int status; + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = (deflate_state *) strm->state; - if (strm == Z_NULL || state == Z_NULL) return Z_STREAM_ERROR; + status = s->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } - TRY_FREE(strm, state->window, state->w_size * 2 * sizeof(Byte)); - TRY_FREE(strm, state->prev, state->w_size * sizeof(Pos)); - TRY_FREE(strm, state->head, state->hash_size * sizeof(Pos)); - TRY_FREE(strm, state->pending_buf, state->lit_bufsize * 2 * sizeof(ush)); + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, s->pending_buf); + TRY_FREE(strm, s->head); + TRY_FREE(strm, s->prev); + TRY_FREE(strm, s->window); - ZFREE(strm, state, sizeof(deflate_state)); + ZFREE(strm, s); strm->state = Z_NULL; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + */ +int deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) + return Z_STREAM_ERROR; + ss = (deflate_state *) source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* ??? following zmemcpy doesn't work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + return Z_OK; } /* =========================================================================== + * Return the number of bytes of output which are immediately available + * for output from the decompressor. + */ +int deflateOutputPending (strm) + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return 0; + + return ((deflate_state *)(strm->state))->pending; +} + +/* =========================================================================== * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). */ local int read_buf(strm, buf, size) - z_stream *strm; + z_streamp strm; charf *buf; unsigned size; { unsigned len = strm->avail_in; - deflate_state *state = (deflate_state *) strm->state; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; - if (!state->noheader) { - state->adler = adler32(state->adler, strm->next_in, len); + if (!((deflate_state *)(strm->state))->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); } zmemcpy(buf, strm->next_in, len); strm->next_in += len; @@ -941,7 +1248,7 @@ local void lm_init (s) s->strstart = 0; s->block_start = 0L; s->lookahead = 0; - s->match_length = MIN_MATCH-1; + s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifdef ASMV @@ -956,12 +1263,13 @@ local void lm_init (s) * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ -local int longest_match(s, cur_match) +local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { @@ -970,6 +1278,7 @@ local int longest_match(s, cur_match) register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, @@ -1000,6 +1309,11 @@ local int longest_match(s, cur_match) if (s->prev_length >= s->good_match) { chain_length >>= 2; } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { @@ -1078,7 +1392,7 @@ local int longest_match(s, cur_match) if (len > best_len) { s->match_start = cur_match; best_len = len; - if (len >= s->nice_match) break; + if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else @@ -1089,7 +1403,8 @@ local int longest_match(s, cur_match) } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); - return best_len; + if ((uInt)best_len <= s->lookahead) return best_len; + return s->lookahead; } #endif /* ASMV */ @@ -1103,16 +1418,16 @@ local void check_match(s, start, match, length) int length; { /* check that the match is indeed a match */ - if (memcmp((charf *)s->window + match, + if (zmemcmp((charf *)s->window + match, (charf *)s->window + start, length) != EQUAL) { - fprintf(stderr, - " start %u, match %u, length %d\n", - start, match, length); - do { fprintf(stderr, "%c%c", s->window[match++], - s->window[start++]); } while (--length != 0); + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); z_error("invalid match"); } - if (verbose > 1) { + if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } @@ -1145,6 +1460,7 @@ local void fill_window(s) /* Deal with !@#$% 64K limit: */ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; + } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) @@ -1156,18 +1472,17 @@ local void fill_window(s) */ } else if (s->strstart >= wsize+MAX_DIST(s)) { - /* By the IN assertion, the window is not empty so we can't confuse - * more == 0 with more == 64K on a 16 bit machine. - */ zmemcpy((charf *)s->window, (charf *)s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage): + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; @@ -1185,7 +1500,6 @@ local void fill_window(s) * its value will never be used. */ } while (--n); - more += wsize; } if (s->strm->avail_in == 0) return; @@ -1226,36 +1540,96 @@ local void fill_window(s) * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ -#define FLUSH_BLOCK_ONLY(s, flush) { \ - ct_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), (long)s->strstart - s->block_start, (flush)); \ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, flush) { \ - FLUSH_BLOCK_ONLY(s, flush); \ - if (s->strm->avail_out == 0) return 1; \ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== - * Compress as much as possible from the input stream, return true if - * processing was terminated prematurely (no more input or output space). - * This function does not perform lazy evaluationof matches and inserts + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ -local int deflate_fast(s, flush) +local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - s->prev_length = MIN_MATCH-1; + int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except @@ -1265,8 +1639,9 @@ local int deflate_fast(s, flush) */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; - + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } if (s->lookahead == 0) break; /* flush the current block */ } @@ -1289,14 +1664,12 @@ local int deflate_fast(s, flush) s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ - - if (s->match_length > s->lookahead) s->match_length = s->lookahead; } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); - bflush = ct_tally(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH); + bflush = _tr_tally(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH); s->lookahead -= s->match_length; @@ -1329,14 +1702,14 @@ local int deflate_fast(s, flush) } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); - bflush = ct_tally (s, 0, s->window[s->strstart]); + bflush = _tr_tally (s, 0, s->window[s->strstart]); s->lookahead--; s->strstart++; } - if (bflush) FLUSH_BLOCK(s, Z_NO_FLUSH); + if (bflush) FLUSH_BLOCK(s, 0); } - FLUSH_BLOCK(s, flush); - return 0; /* normal exit */ + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== @@ -1344,7 +1717,7 @@ local int deflate_fast(s, flush) * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ -local int deflate_slow(s, flush) +local block_state deflate_slow(s, flush) deflate_state *s; int flush; { @@ -1360,8 +1733,9 @@ local int deflate_slow(s, flush) */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; - + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } if (s->lookahead == 0) break; /* flush the current block */ } @@ -1387,7 +1761,6 @@ local int deflate_slow(s, flush) s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ - if (s->match_length > s->lookahead) s->match_length = s->lookahead; if (s->match_length <= 5 && (s->strategy == Z_FILTERED || (s->match_length == MIN_MATCH && @@ -1408,8 +1781,8 @@ local int deflate_slow(s, flush) check_match(s, s->strstart-1, s->prev_match, s->prev_length); - bflush = ct_tally(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH); + bflush = _tr_tally(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not @@ -1427,7 +1800,7 @@ local int deflate_slow(s, flush) s->match_length = MIN_MATCH-1; s->strstart++; - if (bflush) FLUSH_BLOCK(s, Z_NO_FLUSH); + if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a @@ -1435,12 +1808,12 @@ local int deflate_slow(s, flush) * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); - if (ct_tally (s, 0, s->window[s->strstart-1])) { - FLUSH_BLOCK_ONLY(s, Z_NO_FLUSH); + if (_tr_tally (s, 0, s->window[s->strstart-1])) { + FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; - if (s->strm->avail_out == 0) return 1; + if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. @@ -1453,17 +1826,17 @@ local int deflate_slow(s, flush) Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); - ct_tally (s, 0, s->window[s->strstart-1]); + _tr_tally (s, 0, s->window[s->strstart-1]); s->match_available = 0; } - FLUSH_BLOCK(s, flush); - return 0; + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; } +/* --- deflate.c */ - -/*+++++*/ +/* +++ trees.c */ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995 Jean-loup Gailly + * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -1493,7 +1866,9 @@ local int deflate_slow(s, flush) * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ -/* From: trees.c,v 1.5 1995/05/03 17:27:12 jloup Exp */ +/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ + +/* #include "deflate.h" */ #ifdef DEBUG_ZLIB # include <ctype.h> @@ -1540,13 +1915,12 @@ local uch bl_order[BL_CODES] /* =========================================================================== * Local data. These are initialized only once. - * To do: initialize at compile time to be completely reentrant. ??? */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see ct_init + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ @@ -1591,7 +1965,7 @@ local static_tree_desc static_bl_desc = * Local (static) routines in this file. */ -local void ct_static_init OF((void)); +local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); @@ -1617,7 +1991,7 @@ local void copy_block OF((deflate_state *s, charf *buf, unsigned len, #else /* DEBUG_ZLIB */ # define send_code(s, c, tree) \ - { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ + { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif @@ -1649,7 +2023,7 @@ local void send_bits(s, value, length) int value; /* value to send */ int length; /* number of bits */ { - Tracev((stderr," l %2d v %4x ", length, value)); + Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; @@ -1689,11 +2063,13 @@ local void send_bits(s, value, length) /* the arguments must not have side effects */ /* =========================================================================== - * Initialize the various 'constant' tables. - * To do: do this at compile time. + * Initialize the various 'constant' tables. In a multi-threaded environment, + * this function may be called by two threads concurrently, but this is + * harmless since both invocations do exactly the same thing. */ -local void ct_static_init() +local void tr_static_init() { + static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ @@ -1702,6 +2078,8 @@ local void ct_static_init() ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ + if (static_init_done) return; + /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { @@ -1710,7 +2088,7 @@ local void ct_static_init() length_code[length++] = (uch)code; } } - Assert (length == 256, "ct_static_init: length != 256"); + Assert (length == 256, "tr_static_init: length != 256"); /* Note that the length 255 (match length 258) can be represented * in two different ways: code 284 + 5 bits or code 285, so we * overwrite length_code[255] to use the best encoding: @@ -1725,7 +2103,7 @@ local void ct_static_init() dist_code[dist++] = (uch)code; } } - Assert (dist == 256, "ct_static_init: dist != 256"); + Assert (dist == 256, "tr_static_init: dist != 256"); dist >>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; @@ -1733,7 +2111,7 @@ local void ct_static_init() dist_code[256 + dist++] = (uch)code; } } - Assert (dist == 256, "ct_static_init: 256+dist != 512"); + Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; @@ -1751,19 +2129,18 @@ local void ct_static_init() /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse(n, 5); + static_dtree[n].Code = bi_reverse((unsigned)n, 5); } + static_init_done = 1; } /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ -local void ct_init(s) +void _tr_init(s) deflate_state *s; { - if (static_dtree[0].Len == 0) { - ct_static_init(); /* To do: at compile time */ - } + tr_static_init(); s->compressed_len = 0L; @@ -1782,7 +2159,6 @@ local void ct_init(s) #ifdef DEBUG_ZLIB s->bits_sent = 0L; #endif - s->blocks_in_packet = 0; /* Initialize the first block of the first file: */ init_block(s); @@ -1986,7 +2362,7 @@ local void gen_codes (tree, max_code, bl_count) /* Now reverse the bits */ tree[n].Code = bi_reverse(next_code[len]++, len); - Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); } } @@ -2246,14 +2622,14 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -local void ct_stored_block(s, buf, stored_len, eof) +void _tr_stored_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ - s->compressed_len = (s->compressed_len + 3 + 7) & ~7L; + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ @@ -2261,7 +2637,7 @@ local void ct_stored_block(s, buf, stored_len, eof) /* Send just the `stored block' type code without any length bytes or data. */ -local void ct_stored_type_only(s) +void _tr_stored_type_only(s) deflate_state *s; { send_bits(s, (STORED_BLOCK << 1), 3); @@ -2273,12 +2649,15 @@ local void ct_stored_type_only(s) /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the EOB - * code for the previous block was coded on 5 bits or less, inflate - * may have only 5+3 bits of lookahead to decode this EOB. - * (There are no problems if the previous block is stored or fixed.) + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. */ -local void ct_align(s) +void _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); @@ -2286,10 +2665,11 @@ local void ct_align(s) s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ bi_flush(s); /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the EOB of the previous - * block was thus its length plus what we have just sent. + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. */ - if (s->last_eob_len + 10 - s->bi_valid < 9) { + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; @@ -2303,47 +2683,52 @@ local void ct_align(s) * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ -local ulg ct_flush_block(s, buf, stored_len, flush) +ulg _tr_flush_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ - int flush; /* Z_FINISH if this is the last block for a file */ + int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex; /* index of last bit length code of non zero freq */ - int eof = flush == Z_FINISH; + int max_blindex = 0; /* index of last bit length code of non zero freq */ - ++s->blocks_in_packet; + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { - /* Check if the file is ascii or binary */ - if (s->data_type == UNKNOWN) set_data_type(s); + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; - /* Determine the best encoding. Compute first the block length in bytes */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } /* If compression failed and this is the first and last block, * and if the .zip file can be seeked (to rewrite the local header), @@ -2351,53 +2736,38 @@ local ulg ct_flush_block(s, buf, stored_len, flush) */ #ifdef STORED_FILE_OK # ifdef FORCE_STORED_FILE - if (eof && compressed_len == 0L) /* force stored file */ + if (eof && s->compressed_len == 0L) { /* force stored file */ # else - if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) + if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { # endif - { /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (charf*)0) error ("block vanished"); - copy_block(buf, (unsigned)stored_len, 0); /* without header */ + copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ s->compressed_len = stored_len << 3; s->method = STORED; } else #endif /* STORED_FILE_OK */ - /* For Z_PACKET_FLUSH, if we don't achieve the required minimum - * compression, and this block contains all the data since the last - * time we used Z_PACKET_FLUSH, then just omit this block completely - * from the output. - */ - if (flush == Z_PACKET_FLUSH && s->blocks_in_packet == 1 - && opt_lenb > stored_len - s->minCompr) { - s->blocks_in_packet = 0; - /* output nothing */ - } else - #ifdef FORCE_STORED - if (buf != (char*)0) /* force stored block */ + if (buf != (char*)0) { /* force stored block */ #else - if (stored_len+4 <= opt_lenb && buf != (char*)0) + if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif - { /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ - ct_stored_block(s, buf, stored_len, eof); - } else + _tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC - if (static_lenb >= 0) /* force static trees */ + } else if (static_lenb >= 0) { /* force static trees */ #else - if (static_lenb == opt_lenb) + } else if (static_lenb == opt_lenb) { #endif - { send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); s->compressed_len += 3 + s->static_len; @@ -2425,10 +2795,10 @@ local ulg ct_flush_block(s, buf, stored_len, flush) * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -local int ct_tally (s, dist, lc) +int _tr_tally (s, dist, lc) deflate_state *s; - int dist; /* distance of matched string */ - int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; @@ -2441,7 +2811,7 @@ local int ct_tally (s, dist, lc) dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; @@ -2451,7 +2821,7 @@ local int ct_tally (s, dist, lc) if (s->level > 2 && (s->last_lit & 0xfff) == 0) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)s->strstart - s->block_start; + ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * @@ -2521,7 +2891,7 @@ local void compress_block(s, ltree, dtree) } /* =========================================================================== - * Set the data type to ASCII or Z_BINARY, using a crude approximation: + * Set the data type to ASCII or BINARY, using a crude approximation: * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * IN assertion: the fields freq of dyn_ltree are set and the total of all * frequencies does not exceed 64K (to fit in an int on 16 bit machines). @@ -2535,7 +2905,7 @@ local void set_data_type(s) while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : ASCII); + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); } /* =========================================================================== @@ -2613,15 +2983,23 @@ local void copy_block(s, buf, len, header) #ifdef DEBUG_ZLIB s->bits_sent += (ulg)len<<3; #endif - while (len--) { - put_byte(s, *buf++); - } + /* bundle up the put_byte(s, *buf++) calls */ + zmemcpy(&s->pending_buf[s->pending], buf, len); + s->pending += len; } +/* --- trees.c */ + +/* +++ inflate.c */ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ +/* #include "zutil.h" */ -/*+++++*/ +/* +++ infblock.h */ /* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -2633,130 +3011,43 @@ local void copy_block(s, buf, len, header) struct inflate_blocks_state; typedef struct inflate_blocks_state FAR inflate_blocks_statef; -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, check_func c, /* check function */ uInt w)); /* window size */ -local int inflate_blocks OF(( +extern int inflate_blocks OF(( inflate_blocks_statef *, - z_stream *, + z_streamp , int)); /* initial return code */ -local void inflate_blocks_reset OF(( +extern void inflate_blocks_reset OF(( inflate_blocks_statef *, - z_stream *, + z_streamp , uLongf *)); /* check value on output */ -local int inflate_blocks_free OF(( +extern int inflate_blocks_free OF(( inflate_blocks_statef *, - z_stream *, + z_streamp , uLongf *)); /* check value on output */ -local int inflate_addhistory OF(( +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_addhistory OF(( inflate_blocks_statef *, - z_stream *)); + z_streamp)); -local int inflate_packet_flush OF(( +extern int inflate_packet_flush OF(( inflate_blocks_statef *)); +/* --- infblock.h */ -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; +#ifndef NO_DUMMY_DECL +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ #endif -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - /* inflate private state */ struct internal_state { @@ -2764,6 +3055,11 @@ struct internal_state { enum { METHOD, /* waiting for method byte */ FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ BLOCKS, /* decompressing blocks */ CHECK4, /* four check bytes to go */ CHECK3, /* three check bytes to go */ @@ -2793,7 +3089,7 @@ struct internal_state { int inflateReset(z) -z_stream *z; +z_streamp z; { uLong c; @@ -2809,7 +3105,7 @@ z_stream *z; int inflateEnd(z) -z_stream *z; +z_streamp z; { uLong c; @@ -2817,24 +3113,37 @@ z_stream *z; return Z_STREAM_ERROR; if (z->state->blocks != Z_NULL) inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); + ZFREE(z, z->state); z->state = Z_NULL; Trace((stderr, "inflate: end\n")); return Z_OK; } -int inflateInit2(z, w) -z_stream *z; +int inflateInit2_(z, w, version, stream_size) +z_streamp z; int w; +const char *version; +int stream_size; { + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + /* initialize state */ if (z == Z_NULL) return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ + z->msg = Z_NULL; +#ifndef NO_ZCFUNCS + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; +#endif if ((z->state = (struct internal_state FAR *) - ZALLOC_INIT(z,1,sizeof(struct internal_state))) == Z_NULL) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) return Z_MEM_ERROR; z->state->blocks = Z_NULL; @@ -2856,7 +3165,7 @@ int w; /* create inflate_blocks state */ if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) == Z_NULL) { inflateEnd(z); @@ -2870,10 +3179,12 @@ int w; } -int inflateInit(z) -z_stream *z; +int inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; { - return inflateInit2(z, DEF_WBITS); + return inflateInit2_(z, DEF_WBITS, version, stream_size); } @@ -2881,52 +3192,74 @@ z_stream *z; #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) int inflate(z, f) -z_stream *z; +z_streamp z; int f; { int r; uInt b; - if (z == Z_NULL || z->next_in == Z_NULL) + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) return Z_STREAM_ERROR; r = Z_BUF_ERROR; while (1) switch (z->state->mode) { case METHOD: NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) { z->state->mode = BAD; - z->msg = "unknown compression method"; + z->msg = (char*)"unknown compression method"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } if ((z->state->sub.method >> 4) + 8 > z->state->wbits) { z->state->mode = BAD; - z->msg = "invalid window size"; + z->msg = (char*)"invalid window size"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } z->state->mode = FLAG; case FLAG: NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } + b = NEXTBYTE; if (((z->state->sub.method << 8) + b) % 31) { z->state->mode = BAD; - z->msg = "incorrect header check"; + z->msg = (char*)"incorrect header check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; case BLOCKS: r = inflate_blocks(z->state->blocks, z, r); if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) @@ -2966,7 +3299,7 @@ int f; if (z->state->sub.check.was != z->state->sub.check.need) { z->state->mode = BAD; - z->msg = "incorrect data check"; + z->msg = (char*)"incorrect data check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } @@ -2984,10 +3317,35 @@ int f; if (f != Z_PACKET_FLUSH) return r; z->state->mode = BAD; + z->msg = (char *)"need more for packet flush"; z->state->sub.marker = 0; /* can try inflateSync */ return Z_DATA_ERROR; } + +int inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<<z->state->wbits)) + { + length = (1<<z->state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; @@ -3007,7 +3365,7 @@ z_stream *z; int inflateSync(z) -z_stream *z; +z_streamp z; { uInt n; /* number of bytes to look at */ Bytef *p; /* pointer to bytes */ @@ -3057,10 +3415,112 @@ z_stream *z; #undef NEEDBYTE #undef NEXTBYTE +/* --- inflate.c */ + +/* +++ infblock.c */ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* #include "zutil.h" */ +/* #include "infblock.h" */ + +/* +++ inftrees.h */ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG_ZLIB + extern uInt inflate_hufts; +#endif + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *)); /* distance tree result */ + +extern int inflate_trees_free OF(( + inflate_huft *, /* tables to free */ + z_streamp )); /* for zfree function */ + +/* --- inftrees.h */ + +/* +++ infcodes.h */ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ -/*+++++*/ +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +/* --- infcodes.h */ + +/* +++ infutil.h */ /* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -3069,11 +3529,10 @@ z_stream *z; subject to change. Applications should only use zlib.h. */ -/* inflate blocks semi-private state */ -struct inflate_blocks_state { +#ifndef _INFUTIL_H +#define _INFUTIL_H - /* mode */ - enum { +typedef enum { TYPE, /* get type bits (3, including end bit) */ LENS, /* get lengths for stored */ STORED, /* processing stored block */ @@ -3082,9 +3541,15 @@ struct inflate_blocks_state { DTREE, /* get length, distance trees for a dynamic block */ CODES, /* processing fixed or dynamic block */ DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ + DONEB, /* finished last block, done */ + BADB} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ /* mode dependent information */ union { @@ -3095,10 +3560,10 @@ struct inflate_blocks_state { uIntf *blens; /* bit lengths of codes */ uInt bb; /* bit length tree depth */ inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ } trees; /* if DTREE, decoding info for trees */ struct { - inflate_huft *tl, *td; /* trees to free */ + inflate_huft *tl; + inflate_huft *td; /* trees to free */ inflate_codes_statef *codes; } decode; /* if CODES, current state */ @@ -3132,56 +3597,37 @@ struct inflate_blocks_state { #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} #define DUMPBITS(j) {b>>=(j);k-=(j);} /* output bytes */ -#define WAVAIL (q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;} /* load local pointers */ #define LOAD {LOADIN LOADOUT} -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; /* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( +extern int inflate_flush OF(( inflate_blocks_statef *, - z_stream *, + z_streamp , int)); -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif +#endif +/* --- infutil.h */ -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ +#ifndef NO_DUMMY_DECL +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#endif /* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ +local const uInt border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* @@ -3230,15 +3676,15 @@ local uInt border[] = { /* Order of the bit length code lengths */ */ -local void inflate_blocks_reset(s, z, c) +void inflate_blocks_reset(s, z, c) inflate_blocks_statef *s; -z_stream *z; +z_streamp z; uLongf *c; { if (s->checkfn != Z_NULL) *c = s->check; if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); + ZFREE(z, s->sub.trees.blens); if (s->mode == CODES) { inflate_codes_free(s->sub.decode.codes, z); @@ -3250,24 +3696,24 @@ uLongf *c; s->bitb = 0; s->read = s->write = s->window; if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); + z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); Trace((stderr, "inflate: blocks reset\n")); } -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; check_func c; uInt w; { inflate_blocks_statef *s; - if ((s = (inflate_blocks_statef *)ZALLOC_INIT + if ((s = (inflate_blocks_statef *)ZALLOC (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) return s; - if ((s->window = (Bytef *)ZALLOC_INIT(z, 1, w)) == Z_NULL) + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); + ZFREE(z, s); return Z_NULL; } s->end = s->window + w; @@ -3279,9 +3725,12 @@ uInt w; } -local int inflate_blocks(s, z, r) +#ifdef DEBUG_ZLIB + extern uInt inflate_hufts; +#endif +int inflate_blocks(s, z, r) inflate_blocks_statef *s; -z_stream *z; +z_streamp z; int r; { uInt t; /* temporary storage */ @@ -3341,24 +3790,24 @@ int r; case 3: /* illegal */ DUMPBITS(3) s->mode = BADB; - z->msg = "invalid block type"; + z->msg = (char*)"invalid block type"; r = Z_DATA_ERROR; LEAVE } break; case LENS: NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) { s->mode = BADB; - z->msg = "invalid stored block lengths"; + z->msg = (char*)"invalid stored block lengths"; r = Z_DATA_ERROR; LEAVE } s->sub.left = (uInt)b & 0xffff; b = k = 0; /* dump bits */ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); break; case STORED: if (n == 0) @@ -3384,7 +3833,7 @@ int r; if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { s->mode = BADB; - z->msg = "too many length or distance symbols"; + z->msg = (char*)"too many length or distance symbols"; r = Z_DATA_ERROR; LEAVE } @@ -3397,7 +3846,6 @@ int r; r = Z_MEM_ERROR; LEAVE } - s->sub.trees.nblens = t; DUMPBITS(14) s->sub.trees.index = 0; Tracev((stderr, "inflate: table sizes ok\n")); @@ -3416,6 +3864,7 @@ int r; &s->sub.trees.tb, z); if (t != Z_OK) { + ZFREE(z, s->sub.trees.blens); r = t; if (r == Z_DATA_ERROR) s->mode = BADB; @@ -3454,8 +3903,10 @@ int r; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { + inflate_trees_free(s->sub.trees.tb, z); + ZFREE(z, s->sub.trees.blens); s->mode = BADB; - z->msg = "invalid bit length repeat"; + z->msg = (char*)"invalid bit length repeat"; r = Z_DATA_ERROR; LEAVE } @@ -3476,8 +3927,12 @@ int r; bl = 9; /* must be <= 9 for lookahead assumptions */ bd = 6; /* must be <= 9 for lookahead assumptions */ t = s->sub.trees.table; +#ifdef DEBUG_ZLIB + inflate_hufts = 0; +#endif t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), s->sub.trees.blens, &bl, &bd, &tl, &td, z); + ZFREE(z, s->sub.trees.blens); if (t != Z_OK) { if (t == (uInt)Z_DATA_ERROR) @@ -3485,7 +3940,8 @@ int r; r = t; LEAVE } - Tracev((stderr, "inflate: trees ok\n")); + Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", + inflate_hufts, sizeof(inflate_huft))); if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) { inflate_trees_free(td, z); @@ -3493,7 +3949,6 @@ int r; r = Z_MEM_ERROR; LEAVE } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); s->sub.decode.codes = c; s->sub.decode.tl = tl; s->sub.decode.td = td; @@ -3542,18 +3997,28 @@ int r; } -local int inflate_blocks_free(s, z, c) +int inflate_blocks_free(s, z, c) inflate_blocks_statef *s; -z_stream *z; +z_streamp z; uLongf *c; { inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); + ZFREE(z, s->window); + ZFREE(z, s); Trace((stderr, "inflate: blocks freed\n")); return Z_OK; } + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy((charf *)s->window, d, n); + s->read = s->write = s->window + n; +} + /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; @@ -3562,7 +4027,7 @@ uLongf *c; * BLOCKS). On exit, the output will also be caught up, and the checksum * will have been updated if need be. */ -local int inflate_addhistory(s, z) +int inflate_addhistory(s, z) inflate_blocks_statef *s; z_stream *z; { @@ -3597,7 +4062,7 @@ z_stream *z; n -= t; z->total_out += t; s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ +/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ if (q == s->end) { s->read = q = s->window; m = WAVAIL; @@ -3612,7 +4077,7 @@ z_stream *z; * At the end of a Deflate-compressed PPP packet, we expect to have seen * a `stored' block type value but not the (zero) length bytes. */ -local int inflate_packet_flush(s) +int inflate_packet_flush(s) inflate_blocks_statef *s; { if (s->mode != LENS) @@ -3620,14 +4085,29 @@ local int inflate_packet_flush(s) s->mode = TYPE; return Z_OK; } +/* --- infblock.c */ - -/*+++++*/ +/* +++ inftrees.c */ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ +/* #include "zutil.h" */ +/* #include "inftrees.h" */ + +char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next @@ -3639,35 +4119,30 @@ local int huft_build OF(( uIntf *, /* code lengths in bits */ uInt, /* number of codes */ uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ inflate_huft * FAR*,/* result: starting table */ uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ + z_streamp )); /* for zalloc function */ local voidpf falloc OF(( voidpf, /* opaque pointer (not used) */ uInt, /* number of items */ uInt)); /* size of item */ -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - /* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ +local const uInt cpdext[30] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; @@ -3717,16 +4192,16 @@ local int huft_build(b, n, s, d, e, t, m, zs) uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ uInt n; /* number of codes (assumed <= N_MAX) */ uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ inflate_huft * FAR *t; /* result: starting table */ uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ +z_streamp zs; /* for zalloc function */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ + case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + lengths), or Z_MEM_ERROR if not enough memory. */ { uInt a; /* counter for codes of length k */ @@ -3808,6 +4283,7 @@ z_stream *zs; /* for zalloc function */ if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); + n = x[g]; /* set n to length of v */ /* Generate the Huffman codes and for each, make the table entries */ @@ -3833,7 +4309,8 @@ z_stream *zs; /* for zalloc function */ w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ @@ -3856,7 +4333,6 @@ z_stream *zs; /* for zalloc function */ inflate_trees_free(u[0], zs); return Z_MEM_ERROR; /* not enough memory */ } - q->word.Nalloc = z + 1; #ifdef DEBUG_ZLIB inflate_hufts += z + 1; #endif @@ -3887,7 +4363,7 @@ z_stream *zs; /* for zalloc function */ } else { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ r.base = d[*p++ - s]; } @@ -3916,28 +4392,28 @@ z_stream *zs; /* for zalloc function */ } -local int inflate_trees_bits(c, bb, tb, z) +int inflate_trees_bits(c, bb, tb, z) uIntf *c; /* 19 code lengths */ uIntf *bb; /* bits tree desired/actual depth */ inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ +z_streamp z; /* for zfree function */ { int r; r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) { inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; + z->msg = (char*)"incomplete dynamic bit lengths tree"; r = Z_DATA_ERROR; } return r; } -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) uInt nl; /* number of literal/length codes */ uInt nd; /* number of distance codes */ uIntf *c; /* that many (total) code lengths */ @@ -3945,36 +4421,43 @@ uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ +z_streamp z; /* for zfree function */ { int r; /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z); + if (r != Z_OK || *bl == 0) { if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) { inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; + z->msg = (char*)"incomplete literal/length tree"; r = Z_DATA_ERROR; } return r; } /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z); + if (r != Z_OK || (*bd == 0 && nl > 257)) { if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; + z->msg = (char*)"oversubscribed distance tree"; else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } #else inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; r = Z_DATA_ERROR; } inflate_trees_free(*tl, z); @@ -3988,10 +4471,8 @@ z_stream *z; /* for zfree function */ /* build fixed tables only once--keep them here */ -local int fixed_lock = 0; local int fixed_built = 0; #define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; local inflate_huft fixed_mem[FIXEDH]; local uInt fixed_bl; local uInt fixed_bd; @@ -4000,47 +4481,35 @@ local inflate_huft *fixed_td; local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ +voidpf q; /* opaque pointer */ uInt n; /* number of items */ uInt s; /* size of item */ { - Assert(s == sizeof(inflate_huft) && n <= fixed_left, + Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ + *(intf *)q -= n+s-s; /* s-s to avoid warning */ + return (voidpf)(fixed_mem + *(intf *)q); } -local int inflate_trees_fixed(bl, bd, tl, td) +int inflate_trees_fixed(bl, bd, tl, td) uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ { - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; + /* build fixed tables if not already (multiple overlapped executions ok) */ if (!fixed_built) { int k; /* temporary variable */ unsigned c[288]; /* length list for huft_build */ z_stream z; /* for falloc function */ + int f = FIXEDH; /* number of hufts left in fixed_mem */ /* set up fake z_stream for memory routines */ z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; + z.zfree = Z_NULL; + z.opaque = (voidpf)&f; /* literal table */ for (k = 0; k < 144; k++) @@ -4061,9 +4530,9 @@ inflate_huft * FAR *td; /* distance tree result */ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); /* done */ + Assert(f == 0, "invalid build of fixed tables"); fixed_built = 1; } - fixed_lock--; *bl = fixed_bl; *bd = fixed_bd; *tl = fixed_tl; @@ -4072,32 +4541,68 @@ inflate_huft * FAR *td; /* distance tree result */ } -local int inflate_trees_free(t, z) +int inflate_trees_free(t, z) inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ +z_streamp z; /* for zfree function */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { - register inflate_huft *p, *q; + register inflate_huft *p, *q, *r; + /* Reverse linked list */ + p = Z_NULL; + q = t; + while (q != Z_NULL) + { + r = (q - 1)->next; + (q - 1)->next = p; + p = q; + q = r; + } /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; while (p != Z_NULL) { q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); + ZFREE(z,p); p = q; } return Z_OK; } +/* --- inftrees.c */ -/*+++++*/ +/* +++ infcodes.c */ /* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ +/* #include "zutil.h" */ +/* #include "inftrees.h" */ +/* #include "infblock.h" */ +/* #include "infcodes.h" */ +/* #include "infutil.h" */ + +/* +++ inffast.h */ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); +/* --- inffast.h */ + /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next @@ -4144,10 +4649,11 @@ struct inflate_codes_state { }; -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; { inflate_codes_statef *c; @@ -4165,9 +4671,9 @@ z_stream *z; } -local int inflate_codes(s, z, r) +int inflate_codes(s, z, r) inflate_blocks_statef *s; -z_stream *z; +z_streamp z; int r; { uInt j; /* temporary storage */ @@ -4240,7 +4746,7 @@ int r; break; } c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; + z->msg = (char*)"invalid literal/length code"; r = Z_DATA_ERROR; LEAVE case LENEXT: /* i: getting length extra (have base) */ @@ -4272,7 +4778,7 @@ int r; break; } c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; + z->msg = (char*)"invalid distance code"; r = Z_DATA_ERROR; LEAVE case DISTEXT: /* i: getting distance extra */ @@ -4290,7 +4796,7 @@ int r; #else f = q - c->sub.copy.dist; if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); #endif while (c->len) { @@ -4325,28 +4831,48 @@ int r; } -local void inflate_codes_free(c, z) +void inflate_codes_free(c, z) inflate_codes_statef *c; -z_stream *z; +z_streamp z; { - ZFREE(z, c, sizeof(struct inflate_codes_state)); + ZFREE(z, c); Tracev((stderr, "inflate: codes free\n")); } +/* --- infcodes.c */ -/*+++++*/ +/* +++ infutil.c */ /* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ +/* #include "zutil.h" */ +/* #include "infblock.h" */ +/* #include "inftrees.h" */ +/* #include "infcodes.h" */ +/* #include "infutil.h" */ + +#ifndef NO_DUMMY_DECL +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#endif + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + /* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) +int inflate_flush(s, z, r) inflate_blocks_statef *s; -z_stream *z; +z_streamp z; int r; { uInt n; - Bytef *p, *q; + Bytef *p; + Bytef *q; /* local copies of source and destination pointers */ p = z->next_out; @@ -4363,10 +4889,10 @@ int r; /* update check information */ if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); + z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy as far as end of window */ - if (p != NULL) { + if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } @@ -4391,10 +4917,10 @@ int r; /* update check information */ if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); + z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy */ - if (p != NULL) { + if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } @@ -4408,14 +4934,25 @@ int r; /* done */ return r; } +/* --- infutil.c */ - -/*+++++*/ +/* +++ inffast.c */ /* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ +/* #include "zutil.h" */ +/* #include "inftrees.h" */ +/* #include "infblock.h" */ +/* #include "infcodes.h" */ +/* #include "infutil.h" */ +/* #include "inffast.h" */ + +#ifndef NO_DUMMY_DECL +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#endif + /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next @@ -4431,11 +4968,12 @@ int r; at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer. */ -local int inflate_fast(bl, bd, tl, td, s, z) +int inflate_fast(bl, bd, tl, td, s, z) uInt bl, bd; -inflate_huft *tl, *td; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ inflate_blocks_statef *s; -z_stream *z; +z_streamp z; { inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ @@ -4506,7 +5044,7 @@ z_stream *z; } else /* else offset after destination */ { - e = d - (q - s->window); /* bytes from offset to end */ + e = d - (uInt)(q - s->window); /* bytes from offset to end */ r = s->end - e; /* pointer to offset */ if (c > e) /* if source crosses, */ { @@ -4526,7 +5064,7 @@ z_stream *z; e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; else { - z->msg = "invalid distance code"; + z->msg = (char*)"invalid distance code"; UNGRAB UPDATE return Z_DATA_ERROR; @@ -4556,7 +5094,7 @@ z_stream *z; } else { - z->msg = "invalid literal/length code"; + z->msg = (char*)"invalid literal/length code"; UNGRAB UPDATE return Z_DATA_ERROR; @@ -4569,51 +5107,250 @@ z_stream *z; UPDATE return Z_OK; } +/* --- inffast.c */ - -/*+++++*/ +/* +++ zutil.c */ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. + * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ +/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */ + +#ifdef DEBUG_ZLIB +#include <stdio.h> +#endif + +/* #include "zutil.h" */ -char *zlib_version = ZLIB_VERSION; +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif -static char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ +#ifndef STDC +extern void exit OF((int)); +#endif + +static const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; -/*+++++*/ +const char *zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG_ZLIB +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + Bytef* s1; + Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER < 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ +/* --- zutil.c */ + +/* +++ adler32.c */ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler + * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ +/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ + +/* #include "zlib.h" */ #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ uLong adler32(adler, buf, len) uLong adler; - Bytef *buf; + const Bytef *buf; uInt len; { unsigned long s1 = adler & 0xffff; @@ -4627,13 +5364,16 @@ uLong adler32(adler, buf, len) len -= k; while (k >= 16) { DO16(buf); + buf += 16; k -= 16; } if (k != 0) do { - DO1(buf); + s1 += *buf++; + s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } +/* --- adler32.c */ diff --git a/sys/net/zlib.h b/sys/net/zlib.h index 8624b73..13fe524 100644 --- a/sys/net/zlib.h +++ b/sys/net/zlib.h @@ -1,23 +1,25 @@ -/* $Id: zlib.h,v 1.1.2.1 1997/07/01 20:44:10 peter Exp $ */ +/* $Id: zlib.h,v 1.3 1997/08/19 14:10:50 peter Exp $ */ /* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 + * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. */ /* - * ==FILEVERSION 970501== + * ==FILEVERSION 971127== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. */ + +/* +++ zlib.h */ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. + version 1.0.4, Jul 24th, 1996. - Copyright (C) 1995 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,43 +39,109 @@ Jean-loup Gailly Mark Adler gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ #ifndef _ZLIB_H #define _ZLIB_H -/* #include "zconf.h" */ /* included directly here */ +#ifdef __cplusplus +extern "C" { +#endif + +/* +++ zconf.h */ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. + * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ +/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H /* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateReset z_inflateReset +# define compress z_compress +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) +# define STDC +#endif #ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const # endif #endif -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include <unix.h> +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ @@ -85,10 +153,6 @@ # endif #endif -#ifndef FAR -# define FAR -#endif - /* Maximum value for windowBits in deflateInit2 and inflateInit2 */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ @@ -117,14 +181,44 @@ # endif #endif +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR __far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR __far +# endif +#endif +#ifndef FAR +# define FAR +#endif + typedef unsigned char Byte; /* 8 bits */ typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; +#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) + /* Borland C/C++ ignores FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC @@ -135,9 +229,19 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif -/* end of original zconf.h */ -#define ZLIB_VERSION "0.95P" +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) +# include <windows.h> +# define EXPORT WINAPI +#else +# define EXPORT +#endif + +#endif /* _ZCONF_H */ +/* --- zconf.h */ + +#define ZLIB_VERSION "1.0.4P" /* The 'zlib' compression library provides in-memory compression and @@ -156,10 +260,15 @@ typedef uLong FAR uLongf; repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. + + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; @@ -176,14 +285,16 @@ typedef struct z_stream_s { struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ - alloc_func zalloc_init; /* used to allocate the internal state during initialization */ free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ } z_stream; +typedef z_stream FAR *z_streamp; + /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out @@ -217,21 +328,26 @@ typedef struct z_stream_s { #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ +#define Z_PACKET_FLUSH 2 +#define Z_SYNC_FLUSH 3 +#define Z_FULL_FLUSH 4 +#define Z_FINISH 5 +/* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 +#define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ +#define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) @@ -240,42 +356,54 @@ typedef struct z_stream_s { #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 -/* Used to set the data_type field */ +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +extern const char * EXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. */ - /* basic functions */ - -extern int deflateInit OF((z_stream *strm, int level)); /* +extern int EXPORT deflateInit OF((z_streamp strm, int level)); + Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. - The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9: - 1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests - a default compromise between speed and compression (currently equivalent - to level 6). + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level. + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ -extern int deflate OF((z_stream *strm, int flush)); +extern int EXPORT deflate OF((z_streamp strm, int flush)); /* Performs one or both of the following actions: @@ -295,13 +423,20 @@ extern int deflate OF((z_stream *strm, int flush)); more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression block is terminated and flushed to the output buffer so that the decompressor can get all input data available so far. For method 9, a future variant on method 8, the current block will be flushed but not terminated. - If flush is set to Z_FULL_FLUSH, the compression block is terminated, a + Z_SYNC_FLUSH has the same effect as partial flush except that the compressed + output is byte aligned (the compressor can clear its internal bit buffer) + and the current block is always terminated; this can be useful if the + compressor has to be restarted from scratch after an interruption (in which + case the internal state of the compressor may be lost). + If flush is set to Z_FULL_FLUSH, the compression block is terminated, a special marker is output and the compression dictionary is discarded; this is useful to allow the decompressor to synchronize if one compressed block has been damaged (see inflateSync below). Flushing degrades compression and @@ -316,18 +451,9 @@ extern int deflate OF((z_stream *strm, int flush)); omitting the length bytes (the effect of this is that the 3-bit type code 000 for a stored block is output, and the output is then byte-aligned). This is designed for use at the end of a PPP packet. - In addition, if the current compression block contains all the data - since the last Z_PACKET_FLUSH, it is never output as a stored block. - If the current compression block output as a static or dynamic block - would not be at least `minCompression' bytes smaller than the - original data, then nothing is output for that block. (The type - code for the zero-length stored block is still output, resulting in - a single zero byte being output for the whole packet.) - `MinCompression' is a parameter to deflateInit2, or 0 if deflateInit - is used. - - If the parameter flush is set to Z_FINISH, all pending input is processed, - all pending output is flushed and deflate returns with Z_STREAM_END if there + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After @@ -352,37 +478,40 @@ extern int deflate OF((z_stream *strm, int flush)); */ -extern int deflateEnd OF((z_stream *strm)); +extern int EXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent. In the error case, msg may be set - but then points to a static string (which must not be deallocated). + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). */ -extern int inflateInit OF((z_stream *strm)); /* +extern int EXPORT inflateInit OF((z_streamp strm)); + Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, inflateInit updates them to use default + allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). + enough memory, Z_VERSION_ERROR if the zlib library version is incompatible + with the version assumed by the caller. msg is set to null if there is no + error message. inflateInit does not perform any decompression: this will be + done by inflate(). */ - #if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) -#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ +#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ #endif -extern int inflate OF((z_stream *strm, int flush)); +extern int EXPORT inflate OF((z_streamp strm, int flush)); /* Performs one or both of the following actions: @@ -392,15 +521,18 @@ extern int inflate OF((z_stream *strm, int flush)); will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each - call of inflate(). + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, inflate flushes as much output as possible to the output buffer. The @@ -425,15 +557,19 @@ extern int inflate OF((z_stream *strm, int flush)); inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ + produced, Z_NEED_DICT if a preset dictionary is needed at this point (see + inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, + Z_STREAM_ERROR if the stream structure was inconsistent (for example if + next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in + the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the + application may then call inflateSync to look for a good compression block. + In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the + dictionary chosen by the compressor. +*/ -extern int inflateEnd OF((z_stream *strm)); +extern int EXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any @@ -444,25 +580,26 @@ extern int inflateEnd OF((z_stream *strm)); static string (which must not be deallocated). */ - /* advanced functions */ + /* Advanced functions */ /* The following functions are needed only in some special applications. */ -extern int deflateInit2 OF((z_stream *strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy, - int minCompression)); /* +extern int EXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + This is another version of deflateInit with more compression options. The - fields next_in, zalloc and zfree must be initialized before by the caller. + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. - The method parameter is the compression method. It must be 8 in this - version of the library. (Method 9 will allow a 64K history buffer and + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. (Method 9 will allow a 64K history buffer and partial block flushes.) The windowBits parameter is the base two logarithm of the window size @@ -471,24 +608,22 @@ extern int deflateInit2 OF((z_stream *strm, values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. - The memLevel parameter specifies how much memory should be allocated + The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. - The strategy parameter is used to tune the compression algorithm. Use - the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data - produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman - encoding only (no string match). Filtered data consists mostly of small - values with a somewhat random distribution. In this case, the - compression algorithm is tuned to compress them better. The strategy - parameter only affects the compression ratio but not the correctness of - the compressed output even if it is not set appropriately. - - The minCompression parameter specifies the minimum reduction in size - required for a compressed block to be output when Z_PACKET_FLUSH is - used (see the description of deflate above). + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. If next_in is not null, the library will use this buffer to hold also some history information; the buffer must either hold the entire input @@ -507,11 +642,40 @@ extern int deflateInit2 OF((z_stream *strm, not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by - deflate(). + deflate(). */ -extern int deflateCopy OF((z_stream *dest, - z_stream *source)); +extern int EXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary (history buffer) from the given + byte sequence without producing any compressed output. This function must + be called immediately after deflateInit or deflateInit2, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and + can be predicted with good accuracy; the data can then be compressed better + than with the default empty dictionary. In this version of the library, + only the last 32K bytes of the dictionary are used. + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state + is inconsistent (for example if deflate has already been called for this + stream). deflateSetDictionary does not perform any compression: this will + be done by deflate(). +*/ + +extern int EXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. If the source stream is using an application-supplied history buffer, a new @@ -520,20 +684,20 @@ extern int deflateCopy OF((z_stream *dest, application to provide the correct values of next_out and avail_out for the next call of deflate. - This function is useful when several compression strategies will be + This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ -extern int deflateReset OF((z_stream *strm)); +extern int EXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. @@ -544,11 +708,38 @@ extern int deflateReset OF((z_stream *strm)); stream state was inconsistent (such as zalloc or state being NULL). */ -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); +extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); +/* + Dynamically update the compression level and compression strategy. + This can be used to switch between compression and straight copy of + the input data, or to switch to a different kind of input data requiring + a different strategy. If the compression level is changed, the input + available so far is compressed with the old level (and may be flushed); + the new level will take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +extern int EXPORT deflateOutputPending OF((z_streamp strm)); +/* + Returns the number of bytes of output which are immediately + available from the compressor (i.e. without any further input + or flush). +*/ + /* +extern int EXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. + fields next_out, zalloc, zfree and opaque must be initialized before by + the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for @@ -577,7 +768,26 @@ extern int inflateInit2 OF((z_stream *strm, inflate(). */ -extern int inflateSync OF((z_stream *strm)); +extern int EXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary (history buffer) from the given + uncompressed byte sequence. This function must be called immediately after + a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen + by the compressor can be determined from the Adler32 value returned by this + call of inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +extern int EXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until the special marker (see deflate() above) can be found, or until all available input is skipped. No output @@ -592,7 +802,7 @@ extern int inflateSync OF((z_stream *strm)); until success or end of the input data. */ -extern int inflateReset OF((z_stream *strm)); +extern int EXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. @@ -611,15 +821,127 @@ extern int inflateIncomp OF((z_stream *strm)); containing the data at next_in (except that the data is not output). */ + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level, window size, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +extern int EXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +extern gzFile EXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9"). gzopen can be used to read a file which is not in gzip format; + in this case gzread will directly read from the file without decompression. + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ + +extern gzFile EXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +extern int EXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +extern int EXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +extern const char * EXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + /* checksum functions */ /* - This function is not related to compression but is exported - anyway because it might be useful in applications using the + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression library. */ -extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); +extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and @@ -636,8 +958,56 @@ extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -#ifndef _Z_UTIL_H +extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +extern int EXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +extern int EXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size)); +extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif +uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */ + +#ifdef __cplusplus +} +#endif + #endif /* _ZLIB_H */ +/* --- zlib.h */ |