summaryrefslogtreecommitdiff
path: root/lib/libz/trees.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libz/trees.c')
-rw-r--r--lib/libz/trees.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/lib/libz/trees.c b/lib/libz/trees.c
index b02b5277f48a..2497001742d3 100644
--- a/lib/libz/trees.c
+++ b/lib/libz/trees.c
@@ -29,7 +29,7 @@
* Addison-Wesley, 1983. ISBN 0-201-06672-6.
*/
-/* @(#) $Id: trees.c,v 1.1.1.3 1999/01/10 09:46:57 peter Exp $ */
+/* $FreeBSD$ */
/* #define GEN_TREES_H */
@@ -250,13 +250,6 @@ local void tr_static_init()
if (static_init_done) return;
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
/* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0;
for (code = 0; code < LENGTH_CODES-1; code++) {
@@ -385,6 +378,8 @@ void _tr_init(s)
{
tr_static_init();
+ s->compressed_len = 0L;
+
s->l_desc.dyn_tree = s->dyn_ltree;
s->l_desc.stat_desc = &static_l_desc;
@@ -398,7 +393,6 @@ void _tr_init(s)
s->bi_valid = 0;
s->last_eob_len = 8; /* enough lookahead for inflate */
#ifdef DEBUG
- s->compressed_len = 0L;
s->bits_sent = 0L;
#endif
@@ -871,10 +865,9 @@ void _tr_stored_block(s, buf, stored_len, eof)
int eof; /* true if this is the last block for a file */
{
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3;
-#endif
+
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
}
@@ -894,9 +887,7 @@ void _tr_align(s)
{
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
bi_flush(s);
/* Of the 10 bits for the empty block, we have already sent
* (10 - bi_valid) bits. The lookahead for the last real code (before
@@ -906,9 +897,7 @@ void _tr_align(s)
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);
-#ifdef DEBUG
s->compressed_len += 10L;
-#endif
bi_flush(s);
}
s->last_eob_len = 7;
@@ -916,9 +905,10 @@ void _tr_align(s)
/* ===========================================================================
* Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
*/
-void _tr_flush_block(s, buf, stored_len, eof)
+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 */
@@ -965,6 +955,25 @@ void _tr_flush_block(s, buf, stored_len, eof)
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),
+ * the whole file is transformed into a stored file:
+ */
+#ifdef STORED_FILE_OK
+# ifdef FORCE_STORED_FILE
+ if (eof && s->compressed_len == 0L) { /* force stored file */
+# else
+ 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 */
+ s->compressed_len = stored_len << 3;
+ s->method = STORED;
+ } else
+#endif /* STORED_FILE_OK */
+
#ifdef FORCE_STORED
if (buf != (char*)0) { /* force stored block */
#else
@@ -986,32 +995,25 @@ void _tr_flush_block(s, buf, stored_len, eof)
#endif
send_bits(s, (STATIC_TREES<<1)+eof, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
s->compressed_len += 3 + s->static_len;
-#endif
} else {
send_bits(s, (DYN_TREES<<1)+eof, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1);
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
s->compressed_len += 3 + s->opt_len;
-#endif
}
Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
init_block(s);
if (eof) {
bi_windup(s);
-#ifdef DEBUG
s->compressed_len += 7; /* align on byte boundary */
-#endif
}
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
s->compressed_len-7*eof));
+
+ return s->compressed_len >> 3;
}
/* ===========================================================================