Merge conflicts.

This commit is contained in:
Steve Price 1998-02-28 06:08:17 +00:00
parent 9521a6bb06
commit 25552e1d6d
13 changed files with 1074 additions and 253 deletions

View File

@ -1,5 +1,5 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-1996 Mark Adler
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -18,7 +18,7 @@
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
uLong adler32(adler, buf, len)
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;

View File

@ -1,5 +1,5 @@
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -8,22 +8,22 @@
#include "zlib.h"
/* ===========================================================================
Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be at least 0.1% larger than
sourceLen plus 8 bytes. Upon exit, destLen is the actual size of the
compressed buffer.
This function can be used to compress a whole file at once if the
input file is mmap'ed.
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int compress (dest, destLen, source, sourceLen)
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int level;
{
z_stream stream;
int err;
@ -42,7 +42,7 @@ int compress (dest, destLen, source, sourceLen)
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
@ -55,3 +55,14 @@ int compress (dest, destLen, source, sourceLen)
err = deflateEnd(&stream);
return err;
}
/* ===========================================================================
*/
int ZEXPORT compress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}

View File

@ -1,5 +1,5 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-1996 Mark Adler
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -45,7 +45,7 @@ local void make_crc_table()
int n, k;
uLong poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */
poly = 0L;
@ -65,7 +65,7 @@ local void make_crc_table()
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
local uLongf crc_table[256] = {
local const uLongf crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
@ -124,12 +124,12 @@ local uLongf crc_table[256] = {
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
uLongf *get_crc_table()
const uLongf * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table();
#endif
return (uLongf *)crc_table;
return (const uLongf *)crc_table;
}
/* ========================================================================= */
@ -139,7 +139,7 @@ uLongf *get_crc_table()
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uLong crc32(crc, buf, len)
uLong ZEXPORT crc32(crc, buf, len)
uLong crc;
const Bytef *buf;
uInt len;

View File

@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -36,8 +36,8 @@
*
* 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.
@ -51,7 +51,8 @@
#include "deflate.h"
char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly ";
const char deflate_copyright[] =
" deflate 1.1.1 Copyright 1995-1998 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
@ -77,12 +78,14 @@ 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 uInt longest_match OF((deflate_state *s, IPos cur_match));
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));
local int read_buf OF((z_streamp strm, Bytef *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
@ -120,7 +123,7 @@ typedef struct config_s {
compress_func func;
} config;
local config configuration_table[10] = {
local const config configuration_table[10] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
@ -157,14 +160,23 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
* Insert string str in the dictionary and set match_head to the previous head
* of the hash chain (the most recent string with same hash key). Return
* the previous length of the hash chain.
* If this file is compiled with -DFASTEST, the compression level is forced
* to 1, and no hash chains are maintained.
* IN assertion: all calls to to INSERT_STRING are made with consecutive
* input characters and the first MIN_MATCH bytes of str are valid
* (except for the last MIN_MATCH-1 bytes of the input file).
*/
#ifdef FASTEST
#define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
match_head = s->head[s->ins_h], \
s->head[s->ins_h] = (Pos)(str))
#else
#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] = (Pos)(str))
#endif
/* ===========================================================================
* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
@ -172,10 +184,10 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
*/
#define CLEAR_HASH(s) \
s->head[s->hash_size-1] = NIL; \
zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
/* ========================================================================= */
int deflateInit_(strm, level, version, stream_size)
int ZEXPORT deflateInit_(strm, level, version, stream_size)
z_streamp strm;
int level;
const char *version;
@ -187,7 +199,7 @@ int deflateInit_(strm, level, version, stream_size)
}
/* ========================================================================= */
int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
version, stream_size)
z_streamp strm;
int level;
@ -200,13 +212,14 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
{
deflate_state *s;
int noheader = 0;
static const 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] != ZLIB_VERSION[0] ||
if (version == Z_NULL || version[0] != my_version[0] ||
stream_size != sizeof(z_stream)) {
return Z_VERSION_ERROR;
}
@ -220,6 +233,9 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (strm->zfree == Z_NULL) strm->zfree = zcfree;
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#ifdef FASTEST
level = 1;
#endif
if (windowBits < 0) { /* undocumented feature: suppress zlib header */
noheader = 1;
@ -253,6 +269,7 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
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) {
@ -271,7 +288,7 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
}
/* ========================================================================= */
int deflateSetDictionary (strm, dictionary, dictLength)
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
@ -290,9 +307,11 @@ int deflateSetDictionary (strm, dictionary, dictLength)
if (length < MIN_MATCH) return Z_OK;
if (length > MAX_DIST(s)) {
length = MAX_DIST(s);
dictionary += dictLength - length;
#ifndef USE_DICT_HEAD
dictionary += dictLength - length; /* use the tail of the dictionary */
#endif
}
zmemcpy((charf *)s->window, dictionary, length);
zmemcpy(s->window, dictionary, length);
s->strstart = length;
s->block_start = (long)length;
@ -310,7 +329,7 @@ int deflateSetDictionary (strm, dictionary, dictLength)
}
/* ========================================================================= */
int deflateReset (strm)
int ZEXPORT deflateReset (strm)
z_streamp strm;
{
deflate_state *s;
@ -340,7 +359,7 @@ int deflateReset (strm)
}
/* ========================================================================= */
int deflateParams(strm, level, strategy)
int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
@ -414,7 +433,7 @@ local void flush_pending(strm)
}
/* ========================================================================= */
int deflate (strm, flush)
int ZEXPORT deflate (strm, flush)
z_streamp strm;
int flush;
{
@ -548,42 +567,85 @@ int deflate (strm, flush)
}
/* ========================================================================= */
int deflateEnd (strm)
int ZEXPORT deflateEnd (strm)
z_streamp strm;
{
int status;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
status = strm->state->status;
if (status != INIT_STATE && status != BUSY_STATE &&
status != FINISH_STATE) {
return Z_STREAM_ERROR;
}
/* Deallocate in reverse order of allocations: */
TRY_FREE(strm, strm->state->pending_buf);
TRY_FREE(strm, strm->state->head);
TRY_FREE(strm, strm->state->prev);
TRY_FREE(strm, strm->state->window);
status = strm->state->status;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
}
/* ========================================================================= */
int deflateCopy (dest, source)
/* =========================================================================
* Copy the source state to the destination state.
* To simplify the source, this is not supported for 16-bit MSDOS (which
* doesn't have enough memory anyway to duplicate compression states).
*/
int ZEXPORT deflateCopy (dest, source)
z_streamp dest;
z_streamp source;
{
if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
#ifdef MAXSEG_64K
return Z_STREAM_ERROR;
#else
deflate_state *ds;
deflate_state *ss;
ushf *overlay;
ss = source->state;
if (source == Z_NULL || dest == Z_NULL || ss == Z_NULL) {
return Z_STREAM_ERROR;
}
*dest = *source;
return Z_STREAM_ERROR; /* to be implemented */
#if 0
dest->state = (struct internal_state FAR *)
(*dest->zalloc)(1, sizeof(deflate_state));
if (dest->state == Z_NULL) return Z_MEM_ERROR;
*(dest->state) = *(source->state);
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 do not 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;
#endif
}
@ -597,7 +659,7 @@ int deflateCopy (dest, source)
*/
local int read_buf(strm, buf, size)
z_streamp strm;
charf *buf;
Bytef *buf;
unsigned size;
{
unsigned len = strm->avail_in;
@ -658,6 +720,7 @@ local void lm_init (s)
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent.
*/
#ifndef FASTEST
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
@ -792,9 +855,67 @@ local uInt longest_match(s, cur_match)
} while ((cur_match = prev[cur_match & wmask]) > limit
&& --chain_length != 0);
if ((uInt)best_len <= s->lookahead) return best_len;
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead;
}
#else /* FASTEST */
/* ---------------------------------------------------------------------------
* Optimized version for level == 1 only
*/
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
/* Return failure if the match length is less than 2:
*/
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match += 2;
Assert(*scan == *match, "match[2]?");
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
if (len < MIN_MATCH) return MIN_MATCH - 1;
s->match_start = cur_match;
return len <= s->lookahead ? len : s->lookahead;
}
#endif /* FASTEST */
#endif /* ASMV */
#ifdef DEBUG
@ -807,8 +928,8 @@ local void check_match(s, start, match, length)
int length;
{
/* check that the match is indeed a match */
if (zmemcmp((charf *)s->window + match,
(charf *)s->window + start, length) != EQUAL) {
if (zmemcmp(s->window + match,
s->window + start, length) != EQUAL) {
fprintf(stderr, " start %u, match %u, length %d\n",
start, match, length);
do {
@ -816,7 +937,7 @@ local void check_match(s, start, match, length)
} 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);
}
@ -861,33 +982,35 @@ local void fill_window(s)
*/
} else if (s->strstart >= wsize+MAX_DIST(s)) {
zmemcpy((charf *)s->window, (charf *)s->window+wsize,
(unsigned)wsize);
zmemcpy(s->window, 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];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL);
} while (--n);
n = wsize;
p = &s->prev[n];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL);
/* If n is not on any hash chain, prev[n] is garbage but
* its value will never be used.
*/
} while (--n);
n = s->hash_size;
p = &s->head[n];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL);
} while (--n);
n = wsize;
#ifndef FASTEST
p = &s->prev[n];
do {
m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL);
/* If n is not on any hash chain, prev[n] is garbage but
* its value will never be used.
*/
} while (--n);
#endif
more += wsize;
}
if (s->strm->avail_in == 0) return;
@ -905,8 +1028,7 @@ local void fill_window(s)
*/
Assert(more >= 2, "more < 2");
n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead,
more);
n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
s->lookahead += n;
/* Initialize the hash value now that we have some input: */
@ -951,12 +1073,24 @@ local void fill_window(s)
* 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.
* 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) {
@ -974,14 +1108,17 @@ local block_state deflate_stored(s, flush)
s->strstart += s->lookahead;
s->lookahead = 0;
/* Stored blocks are limited to 0xffff bytes: */
if (s->strstart == 0 || s->strstart > 0xfffe) {
/* 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 = s->strstart - 0xffff;
s->strstart = 0xffff;
s->lookahead = (uInt)(s->strstart - max_start);
s->strstart = (uInt)max_start;
FLUSH_BLOCK(s, 0);
}
/* Emit a stored block if it is large enough: */
/* 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);
}
@ -1041,14 +1178,15 @@ local block_state deflate_fast(s, flush)
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length);
bflush = _tr_tally(s, s->strstart - s->match_start,
s->match_length - MIN_MATCH);
_tr_tally_dist(s, s->strstart - s->match_start,
s->match_length - MIN_MATCH, bflush);
s->lookahead -= s->match_length;
/* Insert new strings in the hash table only if the match length
* is not too large. This saves time but degrades compression.
*/
#ifndef FASTEST
if (s->match_length <= s->max_insert_length &&
s->lookahead >= MIN_MATCH) {
s->match_length--; /* string at strstart already in hash table */
@ -1060,7 +1198,9 @@ local block_state deflate_fast(s, flush)
*/
} while (--s->match_length != 0);
s->strstart++;
} else {
} else
#endif
{
s->strstart += s->match_length;
s->match_length = 0;
s->ins_h = s->window[s->strstart];
@ -1075,7 +1215,7 @@ local block_state deflate_fast(s, flush)
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
bflush = _tr_tally (s, 0, s->window[s->strstart]);
_tr_tally_lit (s, s->window[s->strstart], bflush);
s->lookahead--;
s->strstart++;
}
@ -1154,8 +1294,8 @@ local block_state deflate_slow(s, flush)
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
s->prev_length - MIN_MATCH);
_tr_tally_dist(s, s->strstart -1 - s->prev_match,
s->prev_length - MIN_MATCH, bflush);
/* Insert in hash table all strings up to the end of the match.
* strstart-1 and strstart are already inserted. If there is not
@ -1181,7 +1321,8 @@ local block_state deflate_slow(s, flush)
* is longer, truncate the previous match to a single literal.
*/
Tracevv((stderr,"%c", s->window[s->strstart-1]));
if (_tr_tally (s, 0, s->window[s->strstart-1])) {
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
if (bflush) {
FLUSH_BLOCK_ONLY(s, 0);
}
s->strstart++;
@ -1199,7 +1340,7 @@ local block_state deflate_slow(s, flush)
Assert (flush != Z_NO_FLUSH, "no flush?");
if (s->match_available) {
Tracevv((stderr,"%c", s->window[s->strstart-1]));
_tr_tally (s, 0, s->window[s->strstart-1]);
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
s->match_available = 0;
}
FLUSH_BLOCK(s, flush == Z_FINISH);

View File

@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-1996 Jean-loup Gailly
* Copyright (C) 1995-1998 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -83,6 +83,7 @@ typedef struct internal_state {
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 */
int noheader; /* suppress zlib header and adler32 */
@ -272,4 +273,46 @@ ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch _length_code[];
extern uch _dist_code[];
#else
extern const uch _length_code[];
extern const uch _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->last_lit] = 0; \
s->l_buf[s->last_lit++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (length); \
ush dist = (distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif

View File

@ -1,5 +1,5 @@
/* example.c -- usage example of the zlib compression library
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -41,7 +41,7 @@ void test_large_deflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_large_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_flush OF((Byte *compr, uLong comprLen));
void test_flush OF((Byte *compr, uLong *comprLen));
void test_sync OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_dict_deflate OF((Byte *compr, uLong comprLen));
@ -69,6 +69,7 @@ void test_compress(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad uncompress\n");
exit(1);
} else {
printf("uncompress(): %s\n", uncompr);
}
@ -86,16 +87,23 @@ void test_gzio(out, in, uncompr, uncomprLen)
int err;
int len = strlen(hello)+1;
gzFile file;
z_off_t pos;
file = gzopen(out, "wb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) {
fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
gzputc(file, 'h');
if (gzputs(file, "ello") != 4) {
fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
exit(1);
}
if (gzprintf(file, ", %s!", "hello") != 8) {
fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
exit(1);
}
gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
gzclose(file);
file = gzopen(in, "rb");
@ -107,14 +115,41 @@ void test_gzio(out, in, uncompr, uncomprLen)
uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
if (uncomprLen != len) {
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
exit(1);
}
gzclose(file);
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad gzread\n");
fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
exit(1);
} else {
printf("gzread(): %s\n", uncompr);
}
pos = gzseek(file, -8L, SEEK_CUR);
if (pos != 6 || gztell(file) != pos) {
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
pos, gztell(file));
exit(1);
}
if (gzgetc(file) != ' ') {
fprintf(stderr, "gzgetc error\n");
exit(1);
}
gzgets(file, (char*)uncompr, uncomprLen);
uncomprLen = strlen((char*)uncompr);
if (uncomprLen != 6) { /* "hello!" */
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
exit(1);
}
if (strcmp((char*)uncompr, hello+7)) {
fprintf(stderr, "bad gzgets after gzseek\n");
exit(1);
} else {
printf("gzgets() after gzseek: %s\n", uncompr);
}
gzclose(file);
}
/* ===========================================================================
@ -171,12 +206,13 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen)
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.next_out = uncompr;
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH);
@ -189,6 +225,7 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate\n");
exit(1);
} else {
printf("inflate(): %s\n", uncompr);
}
@ -223,6 +260,7 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
CHECK_ERR(err, "deflate");
if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n");
exit(1);
}
/* Feed in already compressed data and switch to no compression: */
@ -242,6 +280,7 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1);
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
@ -263,12 +302,12 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (uInt)uncomprLen;
@ -282,6 +321,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
exit(1);
} else {
printf("large_inflate(): OK\n");
}
@ -292,7 +332,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
*/
void test_flush(compr, comprLen)
Byte *compr;
uLong comprLen;
uLong *comprLen;
{
z_stream c_stream; /* compression stream */
int err;
@ -308,7 +348,7 @@ void test_flush(compr, comprLen)
c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (uInt)comprLen;
c_stream.avail_out = (uInt)*comprLen;
err = deflate(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate");
@ -321,6 +361,8 @@ void test_flush(compr, comprLen)
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
*comprLen = c_stream.total_out;
}
/* ===========================================================================
@ -339,12 +381,13 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = 2; /* just read the zlib header */
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.next_out = uncompr;
d_stream.avail_in = 2; /* just read the zlib header */
d_stream.avail_out = (uInt)uncomprLen;
inflate(&d_stream, Z_NO_FLUSH);
@ -358,6 +401,7 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
if (err != Z_DATA_ERROR) {
fprintf(stderr, "inflate should report DATA_ERROR\n");
/* Because of incorrect adler32 */
exit(1);
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
@ -396,6 +440,7 @@ void test_dict_deflate(compr, comprLen)
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1);
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
@ -417,12 +462,12 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_out = uncompr;
d_stream.avail_out = (uInt)uncomprLen;
@ -445,6 +490,7 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate with dict\n");
exit(1);
} else {
printf("inflate with dictionary: %s\n", uncompr);
}
@ -461,8 +507,9 @@ int main(argc, argv)
Byte *compr, *uncompr;
uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
uLong uncomprLen = comprLen;
static const char* myVersion = ZLIB_VERSION;
if (zlibVersion()[0] != ZLIB_VERSION[0]) {
if (zlibVersion()[0] != myVersion[0]) {
fprintf(stderr, "incompatible zlib version\n");
exit(1);
@ -479,7 +526,6 @@ int main(argc, argv)
printf("out of memory\n");
exit(1);
}
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : "foo.gz"),
@ -492,8 +538,9 @@ int main(argc, argv)
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
test_flush(compr, comprLen);
test_flush(compr, &comprLen);
test_sync(compr, comprLen, uncompr, uncomprLen);
comprLen = uncomprLen;
test_dict_deflate(compr, comprLen);
test_dict_inflate(compr, comprLen, uncompr, uncomprLen);

View File

@ -1,6 +1,8 @@
/* gzio.c -- IO on .gz files
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Compile this file with -DNO_DEFLATE to avoid the compression code.
*/
/* $FreeBSD$ */
@ -11,7 +13,8 @@
struct internal_state {int dummy;}; /* for buggy compilers */
#define Z_BUFSIZE 4096
#define Z_BUFSIZE 16384
#define Z_PRINTF_BUFSIZE 4096
#define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);}
@ -38,10 +41,12 @@ typedef struct gz_stream {
char *path; /* path name for debugging only */
int transparent; /* 1 if input file is not a .gz file */
char mode; /* 'w' or 'r' */
long startpos; /* start of compressed data in file (header skipped) */
} gz_stream;
local gzFile gz_open OF((const char *path, const char *mode, int fd));
local int do_flush OF((gzFile file, int flush));
local int get_byte OF((gz_stream *s));
local void check_header OF((gz_stream *s));
local int destroy OF((gz_stream *s));
@ -64,6 +69,7 @@ local gzFile gz_open (path, mode, fd)
{
int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */
int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
char *p = (char*)mode;
gz_stream *s;
char fmode[80]; /* copy of mode, without the compression level */
@ -99,6 +105,10 @@ local gzFile gz_open (path, mode, fd)
if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '0' && *p <= '9') {
level = *p - '0';
} else if (*p == 'f') {
strategy = Z_FILTERED;
} else if (*p == 'h') {
strategy = Z_HUFFMAN_ONLY;
} else {
*m++ = *p; /* copy the mode */
}
@ -106,19 +116,24 @@ local gzFile gz_open (path, mode, fd)
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateInit2(&(s->stream), level,
Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
/* windowBits is passed < 0 to suppress zlib header */
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
#endif
if (err != Z_OK || s->outbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
} else {
err = inflateInit2(&(s->stream), -MAX_WBITS);
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
err = inflateInit2(&(s->stream), -MAX_WBITS);
/* windowBits is passed < 0 to tell that there is no zlib header */
if (err != Z_OK || s->inbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
@ -126,7 +141,7 @@ local gzFile gz_open (path, mode, fd)
s->stream.avail_out = Z_BUFSIZE;
errno = 0;
s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
if (s->file == NULL) {
return destroy(s), (gzFile)Z_NULL;
@ -136,16 +151,24 @@ local gzFile gz_open (path, mode, fd)
*/
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
s->startpos = 10L;
/* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use
* startpos anyway in write mode, so this initialization is not
* necessary.
*/
} else {
check_header(s); /* skip the .gz header */
s->startpos = (ftell(s->file) - s->stream.avail_in);
}
return (gzFile)s;
}
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing.
*/
gzFile gzopen (path, mode)
gzFile ZEXPORT gzopen (path, mode)
const char *path;
const char *mode;
{
@ -156,7 +179,7 @@ gzFile gzopen (path, mode)
Associate a gzFile with the file descriptor fd. fd is not dup'ed here
to mimic the behavio(u)r of fdopen.
*/
gzFile gzdopen (fd, mode)
gzFile ZEXPORT gzdopen (fd, mode)
int fd;
const char *mode;
{
@ -168,6 +191,31 @@ gzFile gzdopen (fd, mode)
return gz_open (name, mode, fd);
}
/* ===========================================================================
* Update the compression level and strategy
*/
int ZEXPORT gzsetparams (file, level, strategy)
gzFile file;
int level;
int strategy;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
/* Make room to allow flushing */
if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO;
}
s->stream.avail_out = Z_BUFSIZE;
}
return deflateParams (&(s->stream), level, strategy);
}
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
@ -212,8 +260,11 @@ local void check_header(s)
for (len = 0; len < 2; len++) {
c = get_byte(s);
if (c != gz_magic[len]) {
s->transparent = 1;
if (c != EOF) s->stream.avail_in++, s->stream.next_in--;
if (len != 0) s->stream.avail_in++, s->stream.next_in--;
if (c != EOF) {
s->stream.avail_in++, s->stream.next_in--;
s->transparent = 1;
}
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
return;
}
@ -260,14 +311,21 @@ local int destroy (s)
TRYFREE(s->msg);
if (s->stream.state != NULL) {
if (s->mode == 'w') {
err = deflateEnd(&(s->stream));
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateEnd(&(s->stream));
#endif
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
}
if (s->file != NULL && fclose(s->file)) {
err = Z_ERRNO;
#ifdef ESPIPE
if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
#endif
err = Z_ERRNO;
}
if (s->z_err < 0) err = s->z_err;
@ -282,13 +340,13 @@ local int destroy (s)
Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file).
*/
int gzread (file, buf, len)
int ZEXPORT gzread (file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{
gz_stream *s = (gz_stream*)file;
Bytef *start = buf; /* starting point for crc computation */
Bytef *start = (Bytef*)buf; /* starting point for crc computation */
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
@ -296,7 +354,8 @@ int gzread (file, buf, len)
if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
if (s->z_err == Z_STREAM_END) return 0; /* EOF */
s->stream.next_out = next_out = buf;
next_out = (Byte*)buf;
s->stream.next_out = (Bytef*)buf;
s->stream.avail_out = len;
while (s->stream.avail_out != 0) {
@ -317,7 +376,10 @@ int gzread (file, buf, len)
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
s->file);
}
return (int)(len - s->stream.avail_out);
len -= s->stream.avail_out;
s->stream.total_in += (uLong)len;
s->stream.total_out += (uLong)len;
return (int)len;
}
if (s->stream.avail_in == 0 && !s->z_eof) {
@ -345,7 +407,12 @@ int gzread (file, buf, len)
/* Check for concatenated .gz files: */
check_header(s);
if (s->z_err == Z_OK) {
uLong total_in = s->stream.total_in;
uLong total_out = s->stream.total_out;
inflateReset(&(s->stream));
s->stream.total_in = total_in;
s->stream.total_out = total_out;
s->crc = crc32(0L, Z_NULL, 0);
}
}
@ -357,11 +424,49 @@ int gzread (file, buf, len)
return (int)(len - s->stream.avail_out);
}
/* ===========================================================================
Reads one byte from the compressed file. gzgetc returns this byte
or -1 in case of end of file or error.
*/
int ZEXPORT gzgetc(file)
gzFile file;
{
unsigned char c;
return gzread(file, &c, 1) == 1 ? c : -1;
}
/* ===========================================================================
Reads bytes from the compressed file until len-1 characters are
read, or a newline character is read and transferred to buf, or an
end-of-file condition is encountered. The string is then terminated
with a null character.
gzgets returns buf, or Z_NULL in case of error.
The current implementation is not optimized at all.
*/
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
{
char *b = buf;
if (buf == Z_NULL || len <= 0) return Z_NULL;
while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
*buf = '\0';
return b == buf && len > 0 ? Z_NULL : b;
}
#ifndef NO_DEFLATE
/* ===========================================================================
Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error).
*/
int gzwrite (file, buf, len)
int ZEXPORT gzwrite (file, buf, len)
gzFile file;
const voidp buf;
unsigned len;
@ -370,7 +475,7 @@ int gzwrite (file, buf, len)
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
s->stream.next_in = buf;
s->stream.next_in = (Bytef*)buf;
s->stream.avail_in = len;
while (s->stream.avail_in != 0) {
@ -387,18 +492,95 @@ int gzwrite (file, buf, len)
s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err != Z_OK) break;
}
s->crc = crc32(s->crc, buf, len);
s->crc = crc32(s->crc, (const Bytef *)buf, len);
return (int)(len - s->stream.avail_in);
}
/* ===========================================================================
Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error).
*/
#ifdef STDC
#include <stdarg.h>
int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
{
char buf[Z_PRINTF_BUFSIZE];
va_list va;
int len;
va_start(va, format);
#ifdef HAS_vsnprintf
(void)vsnprintf(buf, sizeof(buf), format, va);
#else
(void)vsprintf(buf, format, va);
#endif
va_end(va);
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
if (len <= 0) return 0;
return gzwrite(file, buf, (unsigned)len);
}
#else /* not ANSI C */
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file;
const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{
char buf[Z_PRINTF_BUFSIZE];
int len;
#ifdef HAS_snprintf
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#else
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#endif
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
if (len <= 0) return 0;
return gzwrite(file, buf, len);
}
#endif
/* ===========================================================================
Writes c, converted to an unsigned char, into the compressed file.
gzputc returns the value that was written, or -1 in case of error.
*/
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
unsigned char cc = (unsigned char) c; /* required for big endian systems */
return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
}
/* ===========================================================================
Writes the given null-terminated string to the compressed file, excluding
the terminating null character.
gzputs returns the number of characters written, or -1 in case of error.
*/
int ZEXPORT gzputs(file, s)
gzFile file;
const char *s;
{
return gzwrite(file, (const voidp)s, (unsigned)strlen(s));
}
/* ===========================================================================
Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function.
gzflush should be called only when strictly necessary because it can
degrade compression.
*/
int gzflush (file, flush)
local int do_flush (file, flush)
gzFile file;
int flush;
{
@ -424,6 +606,9 @@ int gzflush (file, flush)
if (done) break;
s->z_err = deflate(&(s->stream), flush);
/* Ignore the second of two consecutive flushes: */
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
/* deflate has finished flushing only when it hasn't used up
* all the available space in the output buffer:
*/
@ -431,9 +616,154 @@ int gzflush (file, flush)
if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
}
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
int ZEXPORT gzflush (file, flush)
gzFile file;
int flush;
{
gz_stream *s = (gz_stream*)file;
int err = do_flush (file, flush);
if (err) return err;
fflush(s->file);
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
#endif /* NO_DEFLATE */
/* ===========================================================================
Sets the starting position for the next gzread or gzwrite on the given
compressed file. The offset represents a number of bytes in the
gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error.
SEEK_END is not implemented, returns error.
In this version of the library, gzseek can be extremely slow.
*/
z_off_t ZEXPORT gzseek (file, offset, whence)
gzFile file;
z_off_t offset;
int whence;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || whence == SEEK_END ||
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
return -1L;
}
if (s->mode == 'w') {
#ifdef NO_DEFLATE
return -1L;
#else
if (whence == SEEK_SET) {
offset -= s->stream.total_out;
}
if (offset < 0) return -1L;
/* At this point, offset is the number of zero bytes to write. */
if (s->inbuf == Z_NULL) {
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
zmemzero(s->inbuf, Z_BUFSIZE);
}
while (offset > 0) {
uInt size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (uInt)offset;
size = gzwrite(file, s->inbuf, size);
if (size == 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_in;
#endif
}
/* Rest of function is for reading only */
/* compute absolute position */
if (whence == SEEK_CUR) {
offset += s->stream.total_out;
}
if (offset < 0) return -1L;
if (s->transparent) {
/* map to fseek */
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
s->stream.total_in = s->stream.total_out = (uLong)offset;
return offset;
}
/* For a negative seek, rewind and use positive seek */
if ((uLong)offset >= s->stream.total_out) {
offset -= s->stream.total_out;
} else if (gzrewind(file) < 0) {
return -1L;
}
/* offset is now the number of bytes to skip. */
if (offset != 0 && s->outbuf == Z_NULL) {
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
}
while (offset > 0) {
int size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (int)offset;
size = gzread(file, s->outbuf, (uInt)size);
if (size <= 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_out;
}
/* ===========================================================================
Rewinds input file.
*/
int ZEXPORT gzrewind (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r') return -1;
s->z_err = Z_OK;
s->z_eof = 0;
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
if (s->startpos == 0) { /* not a compressed file */
rewind(s->file);
return 0;
}
(void) inflateReset(&s->stream);
return fseek(s->file, s->startpos, SEEK_SET);
}
/* ===========================================================================
Returns the starting position for the next gzread or gzwrite on the
given compressed file. This position represents a number of bytes in the
uncompressed data stream.
*/
z_off_t ZEXPORT gztell (file)
gzFile file;
{
return gzseek(file, 0L, SEEK_CUR);
}
/* ===========================================================================
Returns 1 when EOF has previously been detected reading the given
input stream, otherwise zero.
*/
int ZEXPORT gzeof (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
}
/* ===========================================================================
Outputs a long in LSB order to the given file
@ -470,7 +800,7 @@ local uLong getLong (s)
Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state.
*/
int gzclose (file)
int ZEXPORT gzclose (file)
gzFile file;
{
int err;
@ -479,14 +809,17 @@ int gzclose (file)
if (s == NULL) return Z_STREAM_ERROR;
if (s->mode == 'w') {
err = gzflush (file, Z_FINISH);
if (err != Z_OK) return destroy(file);
#ifdef NO_DEFLATE
return Z_STREAM_ERROR;
#else
err = do_flush (file, Z_FINISH);
if (err != Z_OK) return destroy((gz_stream*)file);
putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in);
#endif
}
return destroy(file);
return destroy((gz_stream*)file);
}
/* ===========================================================================
@ -496,7 +829,7 @@ int gzclose (file)
errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code.
*/
const char* gzerror (file, errnum)
const char* ZEXPORT gzerror (file, errnum)
gzFile file;
int *errnum;
{

View File

@ -1,5 +1,5 @@
/* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -25,6 +25,11 @@
extern void exit OF((int));
#endif
#ifdef USE_MMAP
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/stat.h>
#endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32)
# include <fcntl.h>
@ -44,30 +49,36 @@
# define fileno(file) file->__file
#endif
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink OF((const char *));
#endif
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz"
#endif
#define SUFFIX_LEN sizeof(GZ_SUFFIX)
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
extern int unlink OF((const char *));
#define BUFLEN 4096
#define BUFLEN 16384
#define MAX_NAME_LEN 1024
#define local static
/* For MSDOS and other systems with limitation on stack size. For Unix,
#define local
works also.
*/
#ifdef MAXSEG_64K
# define local static
/* Needed for systems with limitation on stack size. */
#else
# define local
#endif
char *prog;
void error OF((const char *msg));
void gz_compress OF((FILE *in, gzFile out));
void gz_uncompress OF((gzFile in, FILE *out));
void file_compress OF((char *file));
void file_uncompress OF((char *file));
int main OF((int argc, char *argv[]));
void error OF((const char *msg));
void gz_compress OF((FILE *in, gzFile out));
#ifdef USE_MMAP
int gz_compress_mmap OF((FILE *in, gzFile out));
#endif
void gz_uncompress OF((gzFile in, FILE *out));
void file_compress OF((char *file, char *mode));
void file_uncompress OF((char *file));
int main OF((int argc, char *argv[]));
/* ===========================================================================
* Display error message and exit
@ -82,6 +93,7 @@ void error(msg)
/* ===========================================================================
* Compress input to output then close both files.
*/
void gz_compress(in, out)
FILE *in;
gzFile out;
@ -90,6 +102,12 @@ void gz_compress(in, out)
int len;
int err;
#ifdef USE_MMAP
/* Try first compressing with mmap. If mmap fails (minigzip used in a
* pipe), use the normal fread loop.
*/
if (gz_compress_mmap(in, out) == Z_OK) return;
#endif
for (;;) {
len = fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
@ -104,6 +122,43 @@ void gz_compress(in, out)
if (gzclose(out) != Z_OK) error("failed gzclose");
}
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
/* Try compressing the input file at once using mmap. Return Z_OK if
* if success, Z_ERRNO otherwise.
*/
int gz_compress_mmap(in, out)
FILE *in;
gzFile out;
{
int len;
int err;
int ifd = fileno(in);
caddr_t buf; /* mmap'ed buffer for the entire input file */
off_t buf_len; /* length of the input file */
struct stat sb;
/* Determine the size of the file, needed for mmap: */
if (fstat(ifd, &sb) < 0) return Z_ERRNO;
buf_len = sb.st_size;
if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */
len = gzwrite(out, (char *)buf, (unsigned)buf_len);
if (len != (int)buf_len) error(gzerror(out, &err));
munmap(buf, buf_len);
fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose");
return Z_OK;
}
#endif /* USE_MMAP */
/* ===========================================================================
* Uncompress input to output then close both files.
*/
@ -134,8 +189,9 @@ void gz_uncompress(in, out)
* Compress the given file: create a corresponding .gz file and remove the
* original.
*/
void file_compress(file)
void file_compress(file, mode)
char *file;
char *mode;
{
local char outfile[MAX_NAME_LEN];
FILE *in;
@ -149,7 +205,7 @@ void file_compress(file)
perror(file);
exit(1);
}
out = gzopen(outfile, "wb"); /* use "wb9" for maximal compression */
out = gzopen(outfile, mode);
if (out == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
exit(1);
@ -201,7 +257,11 @@ void file_uncompress(file)
/* ===========================================================================
* Usage: minigzip [-d] [files...]
* Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...]
* -d : decompress
* -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY
* -1 to -9 : compression level
*/
int main(argc, argv)
@ -210,15 +270,26 @@ int main(argc, argv)
{
int uncompr = 0;
gzFile file;
char outmode[20];
strcpy(outmode, "wb6 ");
prog = argv[0];
argc--, argv++;
if (argc > 0) {
uncompr = (strcmp(*argv, "-d") == 0);
if (uncompr) {
argc--, argv++;
}
while (argc > 0) {
if (strcmp(*argv, "-d") == 0)
uncompr = 1;
else if (strcmp(*argv, "-f") == 0)
outmode[3] = 'f';
else if (strcmp(*argv, "-h") == 0)
outmode[3] = 'h';
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
(*argv)[2] == 0)
outmode[2] = (*argv)[1];
else
break;
argc--, argv++;
}
if (argc == 0) {
SET_BINARY_MODE(stdin);
@ -228,7 +299,7 @@ int main(argc, argv)
if (file == NULL) error("can't gzdopen stdin");
gz_uncompress(file, stdout);
} else {
file = gzdopen(fileno(stdout), "wb"); /* "wb9" for max compr. */
file = gzdopen(fileno(stdout), outmode);
if (file == NULL) error("can't gzdopen stdout");
gz_compress(stdin, file);
}
@ -237,7 +308,7 @@ int main(argc, argv)
if (uncompr) {
file_uncompress(*argv);
} else {
file_compress(*argv);
file_compress(*argv, outmode);
}
} while (argv++, --argc);
}

View File

@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-1996 Jean-loup Gailly
* Copyright (C) 1995-1998 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -31,6 +31,8 @@
/* $FreeBSD$ */
/* #define GEN_TREES_H */
#include "deflate.h"
#ifdef DEBUG
@ -56,16 +58,16 @@
#define REPZ_11_138 18
/* repeat a zero length 11-138 times (7 bits of repeat count) */
local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
= {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};
local int extra_dbits[D_CODES] /* extra bits for each distance code */
local const int extra_dbits[D_CODES] /* extra bits for each distance code */
= {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};
local int extra_blbits[BL_CODES]/* extra bits for each bit length code */
local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
local uch bl_order[BL_CODES]
local const uch bl_order[BL_CODES]
= {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
/* The lengths of the bit length codes are sent in order of decreasing
* probability, to avoid transmitting the lengths for unused bit length codes.
@ -80,6 +82,11 @@ local uch bl_order[BL_CODES]
* Local data. These are initialized only once.
*/
#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
#if defined(GEN_TREES_H) || !defined(STDC)
/* non ANSI compilers may not accept trees.h */
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
@ -92,13 +99,13 @@ local ct_data static_dtree[D_CODES];
* 5 bits.)
*/
local uch dist_code[512];
/* distance codes. The first 256 values correspond to the distances
uch _dist_code[DIST_CODE_LEN];
/* Distance codes. The first 256 values correspond to the distances
* 3 .. 258, the last 256 values correspond to the top 8 bits of
* the 15 bit distances.
*/
local uch length_code[MAX_MATCH-MIN_MATCH+1];
uch _length_code[MAX_MATCH-MIN_MATCH+1];
/* length code for each normalized match length (0 == MIN_MATCH) */
local int base_length[LENGTH_CODES];
@ -107,9 +114,13 @@ local int base_length[LENGTH_CODES];
local int base_dist[D_CODES];
/* First normalized distance for each code (0 = distance of 1) */
#else
# include "trees.h"
#endif /* GEN_TREES_H */
struct static_tree_desc_s {
ct_data *static_tree; /* static tree or NULL */
intf *extra_bits; /* extra bits for each code or NULL */
const ct_data *static_tree; /* static tree or NULL */
const intf *extra_bits; /* extra bits for each code or NULL */
int extra_base; /* base index for extra_bits */
int elems; /* max number of elements in the tree */
int max_length; /* max bit length for the codes */
@ -122,7 +133,7 @@ local static_tree_desc static_d_desc =
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
local static_tree_desc static_bl_desc =
{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
/* ===========================================================================
* Local (static) routines in this file.
@ -148,23 +159,20 @@ local void bi_flush OF((deflate_state *s));
local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
int header));
#ifdef GEN_TREES_H
local void gen_trees_header OF((void));
#endif
#ifndef DEBUG
# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
/* Send a code of the given tree. c and tree must not have side effects */
#else /* DEBUG */
# define send_code(s, c, tree) \
{ if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
{ if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
send_bits(s, tree[c].Code, tree[c].Len); }
#endif
#define d_code(dist) \
((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. dist_code[256] and dist_code[257] are never
* used.
*/
/* ===========================================================================
* Output a short LSB first on the stream.
* IN assertion: there is enough room in pendingBuf.
@ -226,12 +234,11 @@ local void send_bits(s, value, length)
/* the arguments must not have side effects */
/* ===========================================================================
* 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.
* Initialize the various 'constant' tables.
*/
local void tr_static_init()
{
#if defined(GEN_TREES_H) || !defined(STDC)
static int static_init_done = 0;
int n; /* iterates over tree elements */
int bits; /* bit counter */
@ -248,7 +255,7 @@ local void tr_static_init()
for (code = 0; code < LENGTH_CODES-1; code++) {
base_length[code] = length;
for (n = 0; n < (1<<extra_lbits[code]); n++) {
length_code[length++] = (uch)code;
_length_code[length++] = (uch)code;
}
}
Assert (length == 256, "tr_static_init: length != 256");
@ -256,14 +263,14 @@ local void tr_static_init()
* in two different ways: code 284 + 5 bits or code 285, so we
* overwrite length_code[255] to use the best encoding:
*/
length_code[length-1] = (uch)code;
_length_code[length-1] = (uch)code;
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
dist = 0;
for (code = 0 ; code < 16; code++) {
base_dist[code] = dist;
for (n = 0; n < (1<<extra_dbits[code]); n++) {
dist_code[dist++] = (uch)code;
_dist_code[dist++] = (uch)code;
}
}
Assert (dist == 256, "tr_static_init: dist != 256");
@ -271,7 +278,7 @@ local void tr_static_init()
for ( ; code < D_CODES; code++) {
base_dist[code] = dist << 7;
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
dist_code[256 + dist++] = (uch)code;
_dist_code[256 + dist++] = (uch)code;
}
}
Assert (dist == 256, "tr_static_init: 256+dist != 512");
@ -295,8 +302,74 @@ local void tr_static_init()
static_dtree[n].Code = bi_reverse((unsigned)n, 5);
}
static_init_done = 1;
# ifdef GEN_TREES_H
gen_trees_header();
# endif
#endif /* defined(GEN_TREES_H) || !defined(STDC) */
}
/* ===========================================================================
* Genererate the file trees.h describing the static trees.
*/
#ifdef GEN_TREES_H
# ifndef DEBUG
# include <stdio.h>
# endif
# define SEPARATOR(i, last, width) \
((i) == (last)? "\n};\n\n" : \
((i) % (width) == (width)-1 ? ",\n" : ", "))
void gen_trees_header()
{
FILE *header = fopen("trees.h", "w");
int i;
Assert (header != NULL, "Can't open trees.h");
fprintf(header,
"/* header created automatically with -DGEN_TREES_H */\n\n");
fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
for (i = 0; i < L_CODES+2; i++) {
fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
}
fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) {
fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
}
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
for (i = 0; i < DIST_CODE_LEN; i++) {
fprintf(header, "%2u%s", _dist_code[i],
SEPARATOR(i, DIST_CODE_LEN-1, 20));
}
fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
fprintf(header, "%2u%s", _length_code[i],
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
}
fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
for (i = 0; i < LENGTH_CODES; i++) {
fprintf(header, "%1u%s", base_length[i],
SEPARATOR(i, LENGTH_CODES-1, 20));
}
fprintf(header, "local const int base_dist[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) {
fprintf(header, "%5u%s", base_dist[i],
SEPARATOR(i, D_CODES-1, 10));
}
fclose(header);
}
#endif /* GEN_TREES_H */
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
@ -413,12 +486,12 @@ local void gen_bitlen(s, desc)
deflate_state *s;
tree_desc *desc; /* the tree descriptor */
{
ct_data *tree = desc->dyn_tree;
int max_code = desc->max_code;
ct_data *stree = desc->stat_desc->static_tree;
intf *extra = desc->stat_desc->extra_bits;
int base = desc->stat_desc->extra_base;
int max_length = desc->stat_desc->max_length;
ct_data *tree = desc->dyn_tree;
int max_code = desc->max_code;
const ct_data *stree = desc->stat_desc->static_tree;
const intf *extra = desc->stat_desc->extra_bits;
int base = desc->stat_desc->extra_base;
int max_length = desc->stat_desc->max_length;
int h; /* heap index */
int n, m; /* iterate over the tree elements */
int bits; /* bit length */
@ -542,9 +615,9 @@ local void build_tree(s, desc)
deflate_state *s;
tree_desc *desc; /* the tree descriptor */
{
ct_data *tree = desc->dyn_tree;
ct_data *stree = desc->stat_desc->static_tree;
int elems = desc->stat_desc->elems;
ct_data *tree = desc->dyn_tree;
const ct_data *stree = desc->stat_desc->static_tree;
int elems = desc->stat_desc->elems;
int n, m; /* iterate over heap elements */
int max_code = -1; /* largest code with non zero frequency */
int node; /* new node being created */
@ -965,12 +1038,13 @@ int _tr_tally (s, dist, lc)
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
(ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++;
}
#ifdef TRUNCATE_BLOCK
/* Try to guess if it is profitable to stop the current block here */
if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
/* Compute an upper bound for the compressed length */
ulg out_length = (ulg)s->last_lit*8L;
ulg in_length = (ulg)((long)s->strstart - s->block_start);
@ -985,6 +1059,7 @@ int _tr_tally (s, dist, lc)
100L - out_length*100L/in_length));
if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
}
#endif
return (s->last_lit == s->lit_bufsize-1);
/* We avoid equality with lit_bufsize because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
@ -1014,7 +1089,7 @@ local void compress_block(s, ltree, dtree)
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
} else {
/* Here, lc is the match length - MIN_MATCH */
code = length_code[lc];
code = _length_code[lc];
send_code(s, code+LITERALS+1, ltree); /* send the length code */
extra = extra_lbits[code];
if (extra != 0) {

View File

@ -1,5 +1,5 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -22,7 +22,7 @@
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
int uncompress (dest, destLen, source, sourceLen)
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
@ -49,7 +49,7 @@ int uncompress (dest, destLen, source, sourceLen)
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
return err;
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;

View File

@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -27,8 +27,10 @@
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateReset z_inflateReset
# define compress z_compress
# define compress2 z_compress2
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
@ -72,8 +74,10 @@
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
# define STDC
#endif
#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
# define STDC
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
# ifndef STDC
# define STDC
# endif
#endif
#ifndef STDC
@ -87,6 +91,12 @@
# define NO_DUMMY_DECL
#endif
/* Borland C incorrectly complains about missing returns: */
#if defined(__BORLANDC__)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
@ -96,13 +106,17 @@
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
1 << (windowBits+2) + 1 << (memLevel+9)
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
@ -145,6 +159,29 @@
# define FAR __far
# endif
#endif
/* Compile with -DZLIB_DLL for Windows DLL support */
#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR _cdecl _export
# endif
#else
# if defined (__BORLANDC__) && defined (_Windows) && defined (__DLL__)
# define ZEXPORT _export
# define ZEXPORTVA _export
# else
# define ZEXPORT
# define ZEXPORTVA
# endif
#endif
#ifndef FAR
# define FAR
#endif
@ -172,13 +209,44 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
#ifdef HAVE_UNISTD_H
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
/* Compile with -DZLIB_DLL for Windows DLL support */
#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
# include <windows.h>
# define EXPORT WINAPI
#else
# define EXPORT
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(inflate_blocks,"INBL")
# pragma map(inflate_blocks_new,"INBLNE")
# pragma map(inflate_blocks_free,"INBLFR")
# pragma map(inflate_blocks_reset,"INBLRE")
# pragma map(inflate_codes_free,"INCOFR")
# pragma map(inflate_codes,"INCO")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_flush,"INFLU")
# pragma map(inflate_mask,"INMA")
# pragma map(inflate_set_dictionary,"INSEDI2")
# pragma map(inflate_copyright,"INCOPY")
# pragma map(inflate_trees_bits,"INTRBI")
# pragma map(inflate_trees_dynamic,"INTRDY")
# pragma map(inflate_trees_fixed,"INTRFI")
# pragma map(inflate_trees_free,"INTRFR")
#endif
#endif /* _ZCONF_H */

View File

@ -1,12 +1,10 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* $FreeBSD$ */
#include <stdio.h>
#include "zutil.h"
struct internal_state {int dummy;}; /* for buggy compilers */
@ -28,12 +26,18 @@ const char *z_errmsg[10] = {
""};
const char *zlibVersion()
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
#ifdef DEBUG
# ifndef verbose
# define verbose 0
# endif
int z_verbose = verbose;
void z_error (m)
char *m;
{
@ -42,6 +46,16 @@ void z_error (m)
}
#endif
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
#ifndef HAVE_MEMCPY
void zmemcpy(dest, source, len)

View File

@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-1996 Jean-loup Gailly.
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -15,16 +15,16 @@
#include "zlib.h"
#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 <stddef.h>
# include <string.h>
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
extern int errno;
#else
# include <errno.h>
#endif
#ifndef local
# define local static
@ -76,7 +76,13 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef MSDOS
# define OS_CODE 0x00
# ifdef __TURBOC__
# include <alloc.h>
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
@ -92,7 +98,7 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(VAXC) || defined(VMS)
# define OS_CODE 0x02
# define FOPEN(name, mode) \
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
@ -104,8 +110,16 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
# define OS_CODE 0x05
#endif
#ifdef MACOS
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
#endif
#if defined(__MWERKS__) && !defined(fdopen)
# if __dest_os != __be_os && __dest_os != __win32_os
# define fdopen(fd,mode) NULL
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
@ -120,14 +134,19 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER >= 600))
# define fdopen(fd,type) _fdopen(fd,type)
#endif
/* Common defaults */
#ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */
#endif
#ifndef FOPEN
# define FOPEN(name, mode) fopen((name), (mode))
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
@ -142,9 +161,10 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(pyr)
# define NO_MEMCPY
#endif
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER)
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* 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).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
@ -170,16 +190,14 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* Diagnostic functions */
#ifdef DEBUG
# include <stdio.h>
# ifndef verbose
# define verbose 0
# endif
extern int z_verbose;
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 ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
@ -190,8 +208,8 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#endif
typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
typedef uLong (ZEXPORT *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));