diff options
Diffstat (limited to 'trees.c')
-rw-r--r-- | trees.c | 54 |
1 files changed, 39 insertions, 15 deletions
@@ -1,5 +1,6 @@ | |||
1 | /* trees.c -- output deflated data using Huffman coding | 1 | /* trees.c -- output deflated data using Huffman coding |
2 | * Copyright (C) 1995-2005 Jean-loup Gailly | 2 | * Copyright (C) 1995-2006 Jean-loup Gailly |
3 | * detect_data_type() function provided freely by Cosmin Truta, 2006 | ||
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 4 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 5 | */ |
5 | 6 | ||
@@ -152,7 +153,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, | |||
152 | int blcodes)); | 153 | int blcodes)); |
153 | local void compress_block OF((deflate_state *s, ct_data *ltree, | 154 | local void compress_block OF((deflate_state *s, ct_data *ltree, |
154 | ct_data *dtree)); | 155 | ct_data *dtree)); |
155 | local void set_data_type OF((deflate_state *s)); | 156 | local int detect_data_type OF((deflate_state *s)); |
156 | local unsigned bi_reverse OF((unsigned value, int length)); | 157 | local unsigned bi_reverse OF((unsigned value, int length)); |
157 | local void bi_windup OF((deflate_state *s)); | 158 | local void bi_windup OF((deflate_state *s)); |
158 | local void bi_flush OF((deflate_state *s)); | 159 | local void bi_flush OF((deflate_state *s)); |
@@ -250,11 +251,13 @@ local void tr_static_init() | |||
250 | if (static_init_done) return; | 251 | if (static_init_done) return; |
251 | 252 | ||
252 | /* For some embedded targets, global variables are not initialized: */ | 253 | /* For some embedded targets, global variables are not initialized: */ |
254 | #ifdef NO_INIT_GLOBAL_POINTERS | ||
253 | static_l_desc.static_tree = static_ltree; | 255 | static_l_desc.static_tree = static_ltree; |
254 | static_l_desc.extra_bits = extra_lbits; | 256 | static_l_desc.extra_bits = extra_lbits; |
255 | static_d_desc.static_tree = static_dtree; | 257 | static_d_desc.static_tree = static_dtree; |
256 | static_d_desc.extra_bits = extra_dbits; | 258 | static_d_desc.extra_bits = extra_dbits; |
257 | static_bl_desc.extra_bits = extra_blbits; | 259 | static_bl_desc.extra_bits = extra_blbits; |
260 | #endif | ||
258 | 261 | ||
259 | /* Initialize the mapping length (0..255) -> length code (0..28) */ | 262 | /* Initialize the mapping length (0..255) -> length code (0..28) */ |
260 | length = 0; | 263 | length = 0; |
@@ -931,8 +934,8 @@ void _tr_flush_block(s, buf, stored_len, eof) | |||
931 | if (s->level > 0) { | 934 | if (s->level > 0) { |
932 | 935 | ||
933 | /* Check if the file is binary or text */ | 936 | /* Check if the file is binary or text */ |
934 | if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) | 937 | if (s->strm->data_type == Z_UNKNOWN) |
935 | set_data_type(s); | 938 | s->strm->data_type = detect_data_type(s); |
936 | 939 | ||
937 | /* Construct the literal and distance trees */ | 940 | /* Construct the literal and distance trees */ |
938 | build_tree(s, (tree_desc *)(&(s->l_desc))); | 941 | build_tree(s, (tree_desc *)(&(s->l_desc))); |
@@ -1118,24 +1121,45 @@ local void compress_block(s, ltree, dtree) | |||
1118 | } | 1121 | } |
1119 | 1122 | ||
1120 | /* =========================================================================== | 1123 | /* =========================================================================== |
1121 | * Set the data type to BINARY or TEXT, using a crude approximation: | 1124 | * Check if the data type is TEXT or BINARY, using the following algorithm: |
1122 | * set it to Z_TEXT if all symbols are either printable characters (33 to 255) | 1125 | * - TEXT if the two conditions below are satisfied: |
1123 | * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. | 1126 | * a) There are no non-portable control characters belonging to the |
1127 | * "black list" (0..6, 14..25, 28..31). | ||
1128 | * b) There is at least one printable character belonging to the | ||
1129 | * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). | ||
1130 | * - BINARY otherwise. | ||
1131 | * - The following partially-portable control characters form a | ||
1132 | * "gray list" that is ignored in this detection algorithm: | ||
1133 | * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). | ||
1124 | * IN assertion: the fields Freq of dyn_ltree are set. | 1134 | * IN assertion: the fields Freq of dyn_ltree are set. |
1125 | */ | 1135 | */ |
1126 | local void set_data_type(s) | 1136 | local int detect_data_type(s) |
1127 | deflate_state *s; | 1137 | deflate_state *s; |
1128 | { | 1138 | { |
1139 | /* black_mask is the bit mask of black-listed bytes | ||
1140 | * set bits 0..6, 14..25, and 28..31 | ||
1141 | * 0xf3ffc07f = binary 11110011111111111100000001111111 | ||
1142 | */ | ||
1143 | unsigned long black_mask = 0xf3ffc07fUL; | ||
1129 | int n; | 1144 | int n; |
1130 | 1145 | ||
1131 | for (n = 0; n < 9; n++) | 1146 | /* Check for non-textual ("black-listed") bytes. */ |
1147 | for (n = 0; n <= 31; n++, black_mask >>= 1) | ||
1148 | if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) | ||
1149 | return Z_BINARY; | ||
1150 | |||
1151 | /* Check for textual ("white-listed") bytes. */ | ||
1152 | if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 | ||
1153 | || s->dyn_ltree[13].Freq != 0) | ||
1154 | return Z_TEXT; | ||
1155 | for (n = 32; n < LITERALS; n++) | ||
1132 | if (s->dyn_ltree[n].Freq != 0) | 1156 | if (s->dyn_ltree[n].Freq != 0) |
1133 | break; | 1157 | return Z_TEXT; |
1134 | if (n == 9) | 1158 | |
1135 | for (n = 14; n < 32; n++) | 1159 | /* There are no "black-listed" or "white-listed" bytes: |
1136 | if (s->dyn_ltree[n].Freq != 0) | 1160 | * this stream either is empty or has tolerated ("gray-listed") bytes only. |
1137 | break; | 1161 | */ |
1138 | s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; | 1162 | return Z_BINARY; |
1139 | } | 1163 | } |
1140 | 1164 | ||
1141 | /* =========================================================================== | 1165 | /* =========================================================================== |