summaryrefslogtreecommitdiffstats
path: root/cpukit/zlib/trees.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2011-03-18 10:11:29 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2011-03-18 10:11:29 +0000
commit6121dc77366dbc5b7fe28e6d405e498e79630c15 (patch)
treeda2e2000ca12b6e2c1c739f123d867b0f182c841 /cpukit/zlib/trees.c
parentThis commit was generated by cvs2svn to compensate for changes in r25189, (diff)
downloadrtems-6121dc77366dbc5b7fe28e6d405e498e79630c15.tar.bz2
2010-03-22 Joel Sherrill <joel.sherrill@oarcorp.com>
* ChangeLog.zlib, FAQ, Makefile.am, README, adler32.c, compress.c, crc32.c, deflate.c, deflate.h, infback.c, inffast.c, inflate.c, inflate.h, inftrees.c, inftrees.h, trees.c, uncompr.c, zconf.h, zlib.3, zlib.h, zutil.c, zutil.h: Update to zlib 1.2.4. * gzclose.c, gzguts.h, gzlib.c, gzread.c, gzwrite.c, doc/algorithm.txt: New files. * algorithm.txt, gzio.c: Removed.
Diffstat (limited to 'cpukit/zlib/trees.c')
-rw-r--r--cpukit/zlib/trees.c204
1 files changed, 114 insertions, 90 deletions
diff --git a/cpukit/zlib/trees.c b/cpukit/zlib/trees.c
index d368348dd7..1a6e997ac0 100644
--- a/cpukit/zlib/trees.c
+++ b/cpukit/zlib/trees.c
@@ -1,5 +1,6 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
+ * Copyright (C) 1995-2009 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -152,7 +153,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes));
local void compress_block OF((deflate_state *s, ct_data *ltree,
ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
+local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length));
local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s));
@@ -203,12 +204,12 @@ local void send_bits(s, value, length)
* unused bits in value.
*/
if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
+ s->bi_buf |= (ush)value << s->bi_valid;
put_short(s, s->bi_buf);
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
s->bi_valid += length - Buf_size;
} else {
- s->bi_buf |= value << s->bi_valid;
+ s->bi_buf |= (ush)value << s->bi_valid;
s->bi_valid += length;
}
}
@@ -218,12 +219,12 @@ local void send_bits(s, value, length)
{ int len = length;\
if (s->bi_valid > (int)Buf_size - len) {\
int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
+ s->bi_buf |= (ush)val << s->bi_valid;\
put_short(s, s->bi_buf);\
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
s->bi_valid += len - Buf_size;\
} else {\
- s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
s->bi_valid += len;\
}\
}
@@ -235,7 +236,7 @@ local void send_bits(s, value, length)
/* ===========================================================================
* Initialize the various 'constant' tables.
*/
-local void tr_static_init(void)
+local void tr_static_init()
{
#if defined(GEN_TREES_H) || !defined(STDC)
static int static_init_done = 0;
@@ -250,11 +251,13 @@ local void tr_static_init(void)
if (static_init_done) return;
/* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
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;
+#endif
/* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0;
@@ -379,8 +382,8 @@ void gen_trees_header()
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
-void _tr_init(
- deflate_state *s)
+void _tr_init(s)
+ deflate_state *s;
{
tr_static_init();
@@ -408,8 +411,8 @@ void _tr_init(
/* ===========================================================================
* Initialize a new block.
*/
-local void init_block(
- deflate_state *s)
+local void init_block(s)
+ deflate_state *s;
{
int n; /* iterates over tree elements */
@@ -452,10 +455,10 @@ local void init_block(
* when the heap property is re-established (each father smaller than its
* two sons).
*/
-local void pqdownheap(
- deflate_state *s,
- ct_data *tree, /* the tree to restore */
- int k) /* node to move down */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
{
int v = s->heap[k];
int j = k << 1; /* left son of k */
@@ -487,9 +490,9 @@ local void pqdownheap(
* The length opt_len is updated; static_len is also updated if stree is
* not null.
*/
-local void gen_bitlen(
- deflate_state *s,
- tree_desc *desc) /* the tree descriptor */
+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;
@@ -574,10 +577,10 @@ local void gen_bitlen(
* OUT assertion: the field code is set for all tree elements of non
* zero code length.
*/
-local void gen_codes (
- ct_data *tree, /* the tree to decorate */
- int max_code, /* largest code with non zero frequency */
- ushf *bl_count) /* number of codes at each bit length */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
{
ush next_code[MAX_BITS+1]; /* next code value for each bit length */
ush code = 0; /* running code value */
@@ -616,9 +619,9 @@ local void gen_codes (
* and corresponding code. The length opt_len is updated; static_len is
* also updated if stree is not null. The field max_code is set.
*/
-local void build_tree(
- deflate_state *s,
- tree_desc *desc) /* the tree descriptor */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
{
ct_data *tree = desc->dyn_tree;
const ct_data *stree = desc->stat_desc->static_tree;
@@ -704,10 +707,10 @@ local void build_tree(
* Scan a literal or distance tree to determine the frequencies of the codes
* in the bit length tree.
*/
-local void scan_tree (
- deflate_state *s,
- ct_data *tree, /* the tree to be scanned */
- int max_code) /* and its largest code of non zero frequency */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
{
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
@@ -749,10 +752,10 @@ local void scan_tree (
* Send a literal or distance tree in compressed form, using the codes in
* bl_tree.
*/
-local void send_tree (
- deflate_state *s,
- ct_data *tree, /* the tree to be scanned */
- int max_code) /* and its largest code of non zero frequency */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
{
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
@@ -800,8 +803,8 @@ local void send_tree (
* Construct the Huffman tree for the bit lengths and return the index in
* bl_order of the last bit length code to send.
*/
-local int build_bl_tree(
- deflate_state *s)
+local int build_bl_tree(s)
+ deflate_state *s;
{
int max_blindex; /* index of last bit length code of non zero freq */
@@ -835,9 +838,9 @@ local int build_bl_tree(
* lengths of the bit length codes, the literal tree and the distance tree.
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
*/
-local void send_all_trees(
- deflate_state *s,
- int lcodes, int dcodes, int blcodes) /* number of codes for each tree */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
{
int rank; /* index in bl_order */
@@ -864,13 +867,13 @@ local void send_all_trees(
/* ===========================================================================
* Send a stored block
*/
-void _tr_stored_block(
- 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 */
+void _tr_stored_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
#ifdef DEBUG
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3;
@@ -889,8 +892,8 @@ void _tr_stored_block(
* To simplify the code, we assume the worst case of last real code encoded
* on one bit only.
*/
-void _tr_align(
- deflate_state *s)
+void _tr_align(s)
+ deflate_state *s;
{
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
@@ -918,11 +921,11 @@ void _tr_align(
* Determine the best encoding for the current block: dynamic trees, static
* trees or store, and output the encoded block to the zip file.
*/
-void _tr_flush_block(
- deflate_state *s,
- charf *buf, /* input block, or NULL if too old */
- ulg stored_len, /* length of input block */
- int eof) /* true if this is the last block for a file */
+void _tr_flush_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
{
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
int max_blindex = 0; /* index of last bit length code of non zero freq */
@@ -931,8 +934,8 @@ void _tr_flush_block(
if (s->level > 0) {
/* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -978,20 +981,20 @@ void _tr_flush_block(
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block.
*/
- _tr_stored_block(s, buf, stored_len, eof);
+ _tr_stored_block(s, buf, stored_len, last);
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ send_bits(s, (STATIC_TREES<<1)+last, 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_bits(s, (DYN_TREES<<1)+last, 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);
@@ -1005,24 +1008,24 @@ void _tr_flush_block(
*/
init_block(s);
- if (eof) {
+ if (last) {
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));
+ s->compressed_len-7*last));
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
-int _tr_tally (
- deflate_state *s,
- unsigned dist, /* distance of matched string */
- unsigned lc) /* match length-MIN_MATCH or unmatched char (if dist==0) */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ 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;
@@ -1069,10 +1072,10 @@ int _tr_tally (
/* ===========================================================================
* Send the block data compressed using the given Huffman trees
*/
-local void compress_block(
- deflate_state *s,
- ct_data *ltree, /* literal tree */
- ct_data *dtree) /* distance tree */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
{
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
@@ -1118,24 +1121,45 @@ local void compress_block(
}
/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
* IN assertion: the fields Freq of dyn_ltree are set.
*/
-local void set_data_type(
- deflate_state *s)
+local int detect_data_type(s)
+ deflate_state *s;
{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
int n;
- for (n = 0; n < 9; n++)
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
}
/* ===========================================================================
@@ -1143,9 +1167,9 @@ local void set_data_type(
* method would use a table)
* IN assertion: 1 <= len <= 15
*/
-local unsigned bi_reverse(
- unsigned code, /* the value to invert */
- int len) /* its bit length */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
{
register unsigned res = 0;
do {
@@ -1158,8 +1182,8 @@ local unsigned bi_reverse(
/* ===========================================================================
* Flush the bit buffer, keeping at most 7 bits in it.
*/
-local void bi_flush(
- deflate_state *s)
+local void bi_flush(s)
+ deflate_state *s;
{
if (s->bi_valid == 16) {
put_short(s, s->bi_buf);
@@ -1175,8 +1199,8 @@ local void bi_flush(
/* ===========================================================================
* Flush the bit buffer and align the output on a byte boundary
*/
-local void bi_windup(
- deflate_state *s)
+local void bi_windup(s)
+ deflate_state *s;
{
if (s->bi_valid > 8) {
put_short(s, s->bi_buf);
@@ -1194,11 +1218,11 @@ local void bi_windup(
* Copy a stored block, storing first the length and its
* one's complement if requested.
*/
-local void copy_block(
- deflate_state *s,
- charf *buf, /* the input data */
- unsigned len, /* its length */
- int header) /* true if block header must be written */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
{
bi_windup(s); /* align on byte boundary */
s->last_eob_len = 8; /* enough lookahead for inflate */