summaryrefslogtreecommitdiffstats
path: root/sys/net/zlib.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-03-21 20:56:16 +0000
committerpeter <peter@FreeBSD.org>1998-03-21 20:56:16 +0000
commitde12df2a1c38956044434fd895d4c16b88dfff01 (patch)
tree1feb18efb9d0ded7818ad41a2cdd44d9e126a93b /sys/net/zlib.c
parent166f281a882b31fa49758ec1f3b4071fa0cba3b8 (diff)
downloadFreeBSD-src-de12df2a1c38956044434fd895d4c16b88dfff01.zip
FreeBSD-src-de12df2a1c38956044434fd895d4c16b88dfff01.tar.gz
Update kernel parts of ppp to ppp-2.3.3. Not much has changed except
that the deflate components use zlib 1.0.4 instead of zlib 0.95.
Diffstat (limited to 'sys/net/zlib.c')
-rw-r--r--sys/net/zlib.c2172
1 files changed, 1456 insertions, 716 deletions
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 */
OpenPOWER on IntegriCloud