diff options
Diffstat (limited to 'trees.c')
-rw-r--r-- | trees.c | 48 |
1 files changed, 34 insertions, 14 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* trees.c -- output deflated data using Huffman coding | 1 | /* trees.c -- output deflated data using Huffman coding |
2 | * Copyright (C) 1995-2003 Jean-loup Gailly | 2 | * Copyright (C) 1995-2004 Jean-loup Gailly |
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -930,8 +930,25 @@ void _tr_flush_block(s, buf, stored_len, eof) | |||
930 | /* Build the Huffman trees unless a stored block is forced */ | 930 | /* Build the Huffman trees unless a stored block is forced */ |
931 | if (s->level > 0) { | 931 | if (s->level > 0) { |
932 | 932 | ||
933 | /* Check if the file is ascii or binary */ | 933 | /* Check if the file is binary or text */ |
934 | if (s->strm->data_type == Z_UNKNOWN) set_data_type(s); | 934 | if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) |
935 | set_data_type(s); | ||
936 | |||
937 | #ifdef DEBUG | ||
938 | /* Write out literal/length frequencies for benchmarking */ | ||
939 | if (z_verbose) { | ||
940 | FILE *freq; | ||
941 | freq = fopen("defreq.txt", "a"); | ||
942 | if (freq != NULL) { | ||
943 | int n; | ||
944 | fputs("ltree:", freq); | ||
945 | for (n = 0; n < L_CODES; n++) | ||
946 | fprintf(freq, " %d", s->dyn_ltree[n].Freq); | ||
947 | putc('\n', freq); | ||
948 | fclose(freq); | ||
949 | } | ||
950 | } | ||
951 | #endif | ||
935 | 952 | ||
936 | /* Construct the literal and distance trees */ | 953 | /* Construct the literal and distance trees */ |
937 | build_tree(s, (tree_desc *)(&(s->l_desc))); | 954 | build_tree(s, (tree_desc *)(&(s->l_desc))); |
@@ -1117,21 +1134,24 @@ local void compress_block(s, ltree, dtree) | |||
1117 | } | 1134 | } |
1118 | 1135 | ||
1119 | /* =========================================================================== | 1136 | /* =========================================================================== |
1120 | * Set the data type to ASCII or BINARY, using a crude approximation: | 1137 | * Set the data type to BINARY or TEXT, using a crude approximation: |
1121 | * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. | 1138 | * set it to Z_TEXT if all symbols are either printable characters (33 to 255) |
1122 | * IN assertion: the fields freq of dyn_ltree are set and the total of all | 1139 | * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. |
1123 | * frequencies does not exceed 64K (to fit in an int on 16 bit machines). | 1140 | * IN assertion: the fields Freq of dyn_ltree are set. |
1124 | */ | 1141 | */ |
1125 | local void set_data_type(s) | 1142 | local void set_data_type(s) |
1126 | deflate_state *s; | 1143 | deflate_state *s; |
1127 | { | 1144 | { |
1128 | int n = 0; | 1145 | int n; |
1129 | unsigned ascii_freq = 0; | 1146 | |
1130 | unsigned bin_freq = 0; | 1147 | for (n = 0; n < 9; n++) |
1131 | while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; | 1148 | if (s->dyn_ltree[n].Freq != 0) |
1132 | while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; | 1149 | break; |
1133 | while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; | 1150 | if (n == 9) |
1134 | s->strm->data_type = bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII; | 1151 | for (n = 14; n < 32; n++) |
1152 | if (s->dyn_ltree[n].Freq != 0) | ||
1153 | break; | ||
1154 | s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; | ||
1135 | } | 1155 | } |
1136 | 1156 | ||
1137 | /* =========================================================================== | 1157 | /* =========================================================================== |