Mercurial > repos > blastem
annotate zlib/trees.c @ 1925:039553703c20
Don't apply address and cd register changes to the 'live' registers until pending flag is cleared, but do preserve the upper address bits in the latch. Fixes regression in Overdrive 2 while preserving fix to Mona in 344 bytes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 13 Apr 2020 20:43:25 -0700 |
parents | 00d788dac91a |
children |
rev | line source |
---|---|
1530
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 /* trees.c -- output deflated data using Huffman coding |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 * Copyright (C) 1995-2017 Jean-loup Gailly |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 * detect_data_type() function provided freely by Cosmin Truta, 2006 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 * For conditions of distribution and use, see copyright notice in zlib.h |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 /* |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 * ALGORITHM |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 * The "deflation" process uses several Huffman trees. The more |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 * common source values are represented by shorter bit sequences. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 * Each code tree is stored in a compressed form which is itself |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 * a Huffman encoding of the lengths of all the code strings (in |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 * ascending order by source values). The actual code strings are |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 * reconstructed from the lengths in the inflate process, as described |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 * in the deflate specification. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 * REFERENCES |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 * Storer, James A. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 * Data Compression: Methods and Theory, pp. 49-50. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 * Computer Science Press, 1988. ISBN 0-7167-8156-5. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 * Sedgewick, R. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 * Algorithms, p290. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 * Addison-Wesley, 1983. ISBN 0-201-06672-6. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 /* @(#) $Id$ */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 /* #define GEN_TREES_H */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 #include "deflate.h" |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 # include <ctype.h> |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 * Constants |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 #define MAX_BL_BITS 7 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 /* Bit length codes must not exceed MAX_BL_BITS bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 #define END_BLOCK 256 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 /* end of block literal code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 #define REP_3_6 16 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 #define REPZ_3_10 17 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 /* repeat a zero length 3-10 times (3 bits of repeat count) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 #define REPZ_11_138 18 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 /* repeat a zero length 11-138 times (7 bits of repeat count) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 = {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}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 local const int extra_dbits[D_CODES] /* extra bits for each distance code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 = {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}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 local const uch bl_order[BL_CODES] |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 /* The lengths of the bit length codes are sent in order of decreasing |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 * probability, to avoid transmitting the lengths for unused bit length codes. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 * Local data. These are initialized only once. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 #if defined(GEN_TREES_H) || !defined(STDC) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 /* non ANSI compilers may not accept trees.h */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 local ct_data static_ltree[L_CODES+2]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 /* The static literal tree. Since the bit lengths are imposed, there is no |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 * need for the L_CODES extra codes used during heap construction. However |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 * below). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 local ct_data static_dtree[D_CODES]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 /* The static distance tree. (Actually a trivial tree since all codes use |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 * 5 bits.) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 uch _dist_code[DIST_CODE_LEN]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 /* Distance codes. The first 256 values correspond to the distances |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 * 3 .. 258, the last 256 values correspond to the top 8 bits of |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 * the 15 bit distances. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 uch _length_code[MAX_MATCH-MIN_MATCH+1]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 /* length code for each normalized match length (0 == MIN_MATCH) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 local int base_length[LENGTH_CODES]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 /* First normalized length for each code (0 = MIN_MATCH) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 local int base_dist[D_CODES]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 /* First normalized distance for each code (0 = distance of 1) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 #else |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 # include "trees.h" |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 #endif /* GEN_TREES_H */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 struct static_tree_desc_s { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 const ct_data *static_tree; /* static tree or NULL */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 const intf *extra_bits; /* extra bits for each code or NULL */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 int extra_base; /* base index for extra_bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 int elems; /* max number of elements in the tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 int max_length; /* max bit length for the codes */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 }; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 local const static_tree_desc static_l_desc = |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 local const static_tree_desc static_d_desc = |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 local const static_tree_desc static_bl_desc = |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 * Local (static) routines in this file. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 local void tr_static_init OF((void)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 local void init_block OF((deflate_state *s)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 local void build_tree OF((deflate_state *s, tree_desc *desc)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 local int build_bl_tree OF((deflate_state *s)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 int blcodes)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 local void compress_block OF((deflate_state *s, const ct_data *ltree, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 const ct_data *dtree)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 local int detect_data_type OF((deflate_state *s)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 local unsigned bi_reverse OF((unsigned value, int length)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 local void bi_windup OF((deflate_state *s)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 local void bi_flush OF((deflate_state *s)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 #ifdef GEN_TREES_H |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 local void gen_trees_header OF((void)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 #ifndef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 /* Send a code of the given tree. c and tree must not have side effects */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 #else /* !ZLIB_DEBUG */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 # define send_code(s, c, tree) \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 send_bits(s, tree[c].Code, tree[c].Len); } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 * Output a short LSB first on the stream. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 * IN assertion: there is enough room in pendingBuf. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 #define put_short(s, w) { \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
175 put_byte(s, (uch)((w) & 0xff)); \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 put_byte(s, (uch)((ush)(w) >> 8)); \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 * Send a value on a given number of bits. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 * IN assertion: length <= 16 and value fits in length bits. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
182 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 local void send_bits OF((deflate_state *s, int value, int length)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 local void send_bits(s, value, length) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 int value; /* value to send */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 int length; /* number of bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 Tracevv((stderr," l %2d v %4x ", length, value)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 Assert(length > 0 && length <= 15, "invalid length"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
193 s->bits_sent += (ulg)length; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
194 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
195 /* If not enough room in bi_buf, use (valid) bits from bi_buf and |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
196 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 * unused bits in value. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
198 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
199 if (s->bi_valid > (int)Buf_size - length) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
200 s->bi_buf |= (ush)value << s->bi_valid; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
201 put_short(s, s->bi_buf); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
202 s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 s->bi_valid += length - Buf_size; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 s->bi_buf |= (ush)value << s->bi_valid; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 s->bi_valid += length; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
207 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
208 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
209 #else /* !ZLIB_DEBUG */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
210 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
211 #define send_bits(s, value, length) \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
212 { int len = length;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
213 if (s->bi_valid > (int)Buf_size - len) {\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 int val = (int)value;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
215 s->bi_buf |= (ush)val << s->bi_valid;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 put_short(s, s->bi_buf);\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
217 s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 s->bi_valid += len - Buf_size;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 } else {\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
220 s->bi_buf |= (ush)(value) << s->bi_valid;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 s->bi_valid += len;\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
222 }\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
223 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 #endif /* ZLIB_DEBUG */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 /* the arguments must not have side effects */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
228 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 * Initialize the various 'constant' tables. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
232 local void tr_static_init() |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
233 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
234 #if defined(GEN_TREES_H) || !defined(STDC) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
235 static int static_init_done = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
236 int n; /* iterates over tree elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
237 int bits; /* bit counter */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 int length; /* length value */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
239 int code; /* code value */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 int dist; /* distance index */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 ush bl_count[MAX_BITS+1]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 /* number of codes at each bit length for an optimal tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
244 if (static_init_done) return; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
245 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
246 /* For some embedded targets, global variables are not initialized: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
247 #ifdef NO_INIT_GLOBAL_POINTERS |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
248 static_l_desc.static_tree = static_ltree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
249 static_l_desc.extra_bits = extra_lbits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
250 static_d_desc.static_tree = static_dtree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
251 static_d_desc.extra_bits = extra_dbits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
252 static_bl_desc.extra_bits = extra_blbits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
253 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
255 /* Initialize the mapping length (0..255) -> length code (0..28) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
256 length = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
257 for (code = 0; code < LENGTH_CODES-1; code++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
258 base_length[code] = length; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
259 for (n = 0; n < (1<<extra_lbits[code]); n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
260 _length_code[length++] = (uch)code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
261 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
262 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
263 Assert (length == 256, "tr_static_init: length != 256"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
264 /* Note that the length 255 (match length 258) can be represented |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
265 * in two different ways: code 284 + 5 bits or code 285, so we |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
266 * overwrite length_code[255] to use the best encoding: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
267 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
268 _length_code[length-1] = (uch)code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
269 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
270 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
271 dist = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
272 for (code = 0 ; code < 16; code++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
273 base_dist[code] = dist; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
274 for (n = 0; n < (1<<extra_dbits[code]); n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
275 _dist_code[dist++] = (uch)code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
276 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
277 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
278 Assert (dist == 256, "tr_static_init: dist != 256"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
279 dist >>= 7; /* from now on, all distances are divided by 128 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
280 for ( ; code < D_CODES; code++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
281 base_dist[code] = dist << 7; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
282 for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
283 _dist_code[256 + dist++] = (uch)code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
284 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
285 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
286 Assert (dist == 256, "tr_static_init: 256+dist != 512"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
287 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
288 /* Construct the codes of the static literal tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
289 for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
290 n = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
291 while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
292 while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
293 while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
294 while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
295 /* Codes 286 and 287 do not exist, but we must include them in the |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
296 * tree construction to get a canonical Huffman tree (longest code |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
297 * all ones) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
298 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
299 gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
300 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
301 /* The static distance tree is trivial: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
302 for (n = 0; n < D_CODES; n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
303 static_dtree[n].Len = 5; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
304 static_dtree[n].Code = bi_reverse((unsigned)n, 5); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
305 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
306 static_init_done = 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
307 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
308 # ifdef GEN_TREES_H |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
309 gen_trees_header(); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
310 # endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
311 #endif /* defined(GEN_TREES_H) || !defined(STDC) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
312 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
313 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
314 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
315 * Genererate the file trees.h describing the static trees. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
316 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
317 #ifdef GEN_TREES_H |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
318 # ifndef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
319 # include <stdio.h> |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
320 # endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
321 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
322 # define SEPARATOR(i, last, width) \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
323 ((i) == (last)? "\n};\n\n" : \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
324 ((i) % (width) == (width)-1 ? ",\n" : ", ")) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
325 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
326 void gen_trees_header() |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
327 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
328 FILE *header = fopen("trees.h", "w"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
329 int i; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
330 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
331 Assert (header != NULL, "Can't open trees.h"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
332 fprintf(header, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
333 "/* header created automatically with -DGEN_TREES_H */\n\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
334 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
335 fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
336 for (i = 0; i < L_CODES+2; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
337 fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
338 static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
339 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
340 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
341 fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
342 for (i = 0; i < D_CODES; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
343 fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
344 static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
345 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
346 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
347 fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
348 for (i = 0; i < DIST_CODE_LEN; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
349 fprintf(header, "%2u%s", _dist_code[i], |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
350 SEPARATOR(i, DIST_CODE_LEN-1, 20)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
351 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
352 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
353 fprintf(header, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
354 "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
355 for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
356 fprintf(header, "%2u%s", _length_code[i], |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
357 SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
358 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
359 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
360 fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
361 for (i = 0; i < LENGTH_CODES; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
362 fprintf(header, "%1u%s", base_length[i], |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
363 SEPARATOR(i, LENGTH_CODES-1, 20)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
364 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
365 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
366 fprintf(header, "local const int base_dist[D_CODES] = {\n"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
367 for (i = 0; i < D_CODES; i++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
368 fprintf(header, "%5u%s", base_dist[i], |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
369 SEPARATOR(i, D_CODES-1, 10)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
370 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
371 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
372 fclose(header); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
373 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
374 #endif /* GEN_TREES_H */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
375 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
376 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
377 * Initialize the tree data structures for a new zlib stream. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
378 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
379 void ZLIB_INTERNAL _tr_init(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
380 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
381 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
382 tr_static_init(); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
383 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
384 s->l_desc.dyn_tree = s->dyn_ltree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
385 s->l_desc.stat_desc = &static_l_desc; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
386 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
387 s->d_desc.dyn_tree = s->dyn_dtree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
388 s->d_desc.stat_desc = &static_d_desc; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
389 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
390 s->bl_desc.dyn_tree = s->bl_tree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
391 s->bl_desc.stat_desc = &static_bl_desc; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
392 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
393 s->bi_buf = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
394 s->bi_valid = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
395 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
396 s->compressed_len = 0L; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
397 s->bits_sent = 0L; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
398 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
399 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
400 /* Initialize the first block of the first file: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
401 init_block(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
402 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
403 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
404 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
405 * Initialize a new block. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
406 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
407 local void init_block(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
408 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
409 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
410 int n; /* iterates over tree elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
411 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
412 /* Initialize the trees. */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
413 for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
414 for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
415 for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
416 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
417 s->dyn_ltree[END_BLOCK].Freq = 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
418 s->opt_len = s->static_len = 0L; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
419 s->last_lit = s->matches = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
420 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
421 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
422 #define SMALLEST 1 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
423 /* Index within the heap array of least frequent node in the Huffman tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
424 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
425 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
426 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
427 * Remove the smallest element from the heap and recreate the heap with |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
428 * one less element. Updates heap and heap_len. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
429 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
430 #define pqremove(s, tree, top) \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
431 {\ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
432 top = s->heap[SMALLEST]; \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
433 s->heap[SMALLEST] = s->heap[s->heap_len--]; \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
434 pqdownheap(s, tree, SMALLEST); \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
435 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
436 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
437 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
438 * Compares to subtrees, using the tree depth as tie breaker when |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
439 * the subtrees have equal frequency. This minimizes the worst case length. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
440 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
441 #define smaller(tree, n, m, depth) \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
442 (tree[n].Freq < tree[m].Freq || \ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
443 (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
444 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
445 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
446 * Restore the heap property by moving down the tree starting at node k, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
447 * exchanging a node with the smallest of its two sons if necessary, stopping |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
448 * when the heap property is re-established (each father smaller than its |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
449 * two sons). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
450 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
451 local void pqdownheap(s, tree, k) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
452 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
453 ct_data *tree; /* the tree to restore */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
454 int k; /* node to move down */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
455 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
456 int v = s->heap[k]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
457 int j = k << 1; /* left son of k */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
458 while (j <= s->heap_len) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
459 /* Set j to the smallest of the two sons: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
460 if (j < s->heap_len && |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
461 smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
462 j++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
463 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
464 /* Exit if v is smaller than both sons */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
465 if (smaller(tree, v, s->heap[j], s->depth)) break; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
466 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
467 /* Exchange v with the smallest son */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
468 s->heap[k] = s->heap[j]; k = j; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
469 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
470 /* And continue down the tree, setting j to the left son of k */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
471 j <<= 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
472 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
473 s->heap[k] = v; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
474 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
475 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
476 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
477 * Compute the optimal bit lengths for a tree and update the total bit length |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
478 * for the current block. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
479 * IN assertion: the fields freq and dad are set, heap[heap_max] and |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
480 * above are the tree nodes sorted by increasing frequency. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
481 * OUT assertions: the field len is set to the optimal bit length, the |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
482 * array bl_count contains the frequencies for each bit length. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
483 * The length opt_len is updated; static_len is also updated if stree is |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
484 * not null. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
485 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
486 local void gen_bitlen(s, desc) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
487 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
488 tree_desc *desc; /* the tree descriptor */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
489 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
490 ct_data *tree = desc->dyn_tree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
491 int max_code = desc->max_code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
492 const ct_data *stree = desc->stat_desc->static_tree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
493 const intf *extra = desc->stat_desc->extra_bits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
494 int base = desc->stat_desc->extra_base; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
495 int max_length = desc->stat_desc->max_length; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
496 int h; /* heap index */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
497 int n, m; /* iterate over the tree elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
498 int bits; /* bit length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
499 int xbits; /* extra bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
500 ush f; /* frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
501 int overflow = 0; /* number of elements with bit length too large */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
502 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
503 for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
504 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
505 /* In a first pass, compute the optimal bit lengths (which may |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
506 * overflow in the case of the bit length tree). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
507 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
508 tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
509 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
510 for (h = s->heap_max+1; h < HEAP_SIZE; h++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
511 n = s->heap[h]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
512 bits = tree[tree[n].Dad].Len + 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
513 if (bits > max_length) bits = max_length, overflow++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
514 tree[n].Len = (ush)bits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
515 /* We overwrite tree[n].Dad which is no longer needed */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
516 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
517 if (n > max_code) continue; /* not a leaf node */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
518 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
519 s->bl_count[bits]++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
520 xbits = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
521 if (n >= base) xbits = extra[n-base]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
522 f = tree[n].Freq; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
523 s->opt_len += (ulg)f * (unsigned)(bits + xbits); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
524 if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
525 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
526 if (overflow == 0) return; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
527 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
528 Tracev((stderr,"\nbit length overflow\n")); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
529 /* This happens for example on obj2 and pic of the Calgary corpus */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
530 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
531 /* Find the first bit length which could increase: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
532 do { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
533 bits = max_length-1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
534 while (s->bl_count[bits] == 0) bits--; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
535 s->bl_count[bits]--; /* move one leaf down the tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
536 s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
537 s->bl_count[max_length]--; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
538 /* The brother of the overflow item also moves one step up, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
539 * but this does not affect bl_count[max_length] |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
540 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
541 overflow -= 2; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
542 } while (overflow > 0); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
543 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
544 /* Now recompute all bit lengths, scanning in increasing frequency. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
545 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
546 * lengths instead of fixing only the wrong ones. This idea is taken |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
547 * from 'ar' written by Haruhiko Okumura.) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
548 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
549 for (bits = max_length; bits != 0; bits--) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
550 n = s->bl_count[bits]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
551 while (n != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
552 m = s->heap[--h]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
553 if (m > max_code) continue; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
554 if ((unsigned) tree[m].Len != (unsigned) bits) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
555 Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
556 s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
557 tree[m].Len = (ush)bits; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
558 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
559 n--; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
560 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
561 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
562 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
563 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
564 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
565 * Generate the codes for a given tree and bit counts (which need not be |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
566 * optimal). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
567 * IN assertion: the array bl_count contains the bit length statistics for |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
568 * the given tree and the field len is set for all tree elements. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
569 * OUT assertion: the field code is set for all tree elements of non |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
570 * zero code length. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
571 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
572 local void gen_codes (tree, max_code, bl_count) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
573 ct_data *tree; /* the tree to decorate */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
574 int max_code; /* largest code with non zero frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
575 ushf *bl_count; /* number of codes at each bit length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
576 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
577 ush next_code[MAX_BITS+1]; /* next code value for each bit length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
578 unsigned code = 0; /* running code value */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
579 int bits; /* bit index */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
580 int n; /* code index */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
581 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
582 /* The distribution counts are first used to generate the code values |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
583 * without bit reversal. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
584 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
585 for (bits = 1; bits <= MAX_BITS; bits++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
586 code = (code + bl_count[bits-1]) << 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
587 next_code[bits] = (ush)code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
588 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
589 /* Check that the bit counts in bl_count are consistent. The last code |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
590 * must be all ones. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
591 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
592 Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
593 "inconsistent bit counts"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
594 Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
595 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
596 for (n = 0; n <= max_code; n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
597 int len = tree[n].Len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
598 if (len == 0) continue; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
599 /* Now reverse the bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
600 tree[n].Code = (ush)bi_reverse(next_code[len]++, len); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
601 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
602 Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
603 n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
604 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
605 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
606 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
607 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
608 * Construct one Huffman tree and assigns the code bit strings and lengths. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
609 * Update the total bit length for the current block. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
610 * IN assertion: the field freq is set for all tree elements. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
611 * OUT assertions: the fields len and code are set to the optimal bit length |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
612 * and corresponding code. The length opt_len is updated; static_len is |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
613 * also updated if stree is not null. The field max_code is set. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
614 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
615 local void build_tree(s, desc) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
616 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
617 tree_desc *desc; /* the tree descriptor */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
618 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
619 ct_data *tree = desc->dyn_tree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
620 const ct_data *stree = desc->stat_desc->static_tree; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
621 int elems = desc->stat_desc->elems; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
622 int n, m; /* iterate over heap elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
623 int max_code = -1; /* largest code with non zero frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
624 int node; /* new node being created */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
625 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
626 /* Construct the initial heap, with least frequent element in |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
627 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
628 * heap[0] is not used. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
629 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
630 s->heap_len = 0, s->heap_max = HEAP_SIZE; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
631 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
632 for (n = 0; n < elems; n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
633 if (tree[n].Freq != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
634 s->heap[++(s->heap_len)] = max_code = n; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
635 s->depth[n] = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
636 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
637 tree[n].Len = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
638 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
639 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
640 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
641 /* The pkzip format requires that at least one distance code exists, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
642 * and that at least one bit should be sent even if there is only one |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
643 * possible code. So to avoid special checks later on we force at least |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
644 * two codes of non zero frequency. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
645 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
646 while (s->heap_len < 2) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
647 node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
648 tree[node].Freq = 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
649 s->depth[node] = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
650 s->opt_len--; if (stree) s->static_len -= stree[node].Len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
651 /* node is 0 or 1 so it does not have extra bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
652 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
653 desc->max_code = max_code; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
654 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
655 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
656 * establish sub-heaps of increasing lengths: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
657 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
658 for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
659 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
660 /* Construct the Huffman tree by repeatedly combining the least two |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
661 * frequent nodes. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
662 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
663 node = elems; /* next internal node of the tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
664 do { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
665 pqremove(s, tree, n); /* n = node of least frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
666 m = s->heap[SMALLEST]; /* m = node of next least frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
667 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
668 s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
669 s->heap[--(s->heap_max)] = m; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
670 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
671 /* Create a new node father of n and m */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
672 tree[node].Freq = tree[n].Freq + tree[m].Freq; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
673 s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
674 s->depth[n] : s->depth[m]) + 1); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
675 tree[n].Dad = tree[m].Dad = (ush)node; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
676 #ifdef DUMP_BL_TREE |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
677 if (tree == s->bl_tree) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
678 fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
679 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
680 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
681 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
682 /* and insert the new node in the heap */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
683 s->heap[SMALLEST] = node++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
684 pqdownheap(s, tree, SMALLEST); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
685 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
686 } while (s->heap_len >= 2); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
687 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
688 s->heap[--(s->heap_max)] = s->heap[SMALLEST]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
689 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
690 /* At this point, the fields freq and dad are set. We can now |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
691 * generate the bit lengths. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
692 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
693 gen_bitlen(s, (tree_desc *)desc); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
694 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
695 /* The field len is now set, we can generate the bit codes */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
696 gen_codes ((ct_data *)tree, max_code, s->bl_count); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
697 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
698 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
699 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
700 * Scan a literal or distance tree to determine the frequencies of the codes |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
701 * in the bit length tree. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
702 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
703 local void scan_tree (s, tree, max_code) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
704 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
705 ct_data *tree; /* the tree to be scanned */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
706 int max_code; /* and its largest code of non zero frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
707 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
708 int n; /* iterates over all tree elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
709 int prevlen = -1; /* last emitted length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
710 int curlen; /* length of current code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
711 int nextlen = tree[0].Len; /* length of next code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
712 int count = 0; /* repeat count of the current code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
713 int max_count = 7; /* max repeat count */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
714 int min_count = 4; /* min repeat count */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
715 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
716 if (nextlen == 0) max_count = 138, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
717 tree[max_code+1].Len = (ush)0xffff; /* guard */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
718 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
719 for (n = 0; n <= max_code; n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
720 curlen = nextlen; nextlen = tree[n+1].Len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
721 if (++count < max_count && curlen == nextlen) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
722 continue; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
723 } else if (count < min_count) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
724 s->bl_tree[curlen].Freq += count; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
725 } else if (curlen != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
726 if (curlen != prevlen) s->bl_tree[curlen].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
727 s->bl_tree[REP_3_6].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
728 } else if (count <= 10) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
729 s->bl_tree[REPZ_3_10].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
730 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
731 s->bl_tree[REPZ_11_138].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
732 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
733 count = 0; prevlen = curlen; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
734 if (nextlen == 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
735 max_count = 138, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
736 } else if (curlen == nextlen) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
737 max_count = 6, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
738 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
739 max_count = 7, min_count = 4; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
740 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
741 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
742 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
743 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
744 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
745 * Send a literal or distance tree in compressed form, using the codes in |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
746 * bl_tree. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
747 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
748 local void send_tree (s, tree, max_code) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
749 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
750 ct_data *tree; /* the tree to be scanned */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
751 int max_code; /* and its largest code of non zero frequency */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
752 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
753 int n; /* iterates over all tree elements */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
754 int prevlen = -1; /* last emitted length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
755 int curlen; /* length of current code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
756 int nextlen = tree[0].Len; /* length of next code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
757 int count = 0; /* repeat count of the current code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
758 int max_count = 7; /* max repeat count */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
759 int min_count = 4; /* min repeat count */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
760 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
761 /* tree[max_code+1].Len = -1; */ /* guard already set */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
762 if (nextlen == 0) max_count = 138, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
763 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
764 for (n = 0; n <= max_code; n++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
765 curlen = nextlen; nextlen = tree[n+1].Len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
766 if (++count < max_count && curlen == nextlen) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
767 continue; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
768 } else if (count < min_count) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
769 do { send_code(s, curlen, s->bl_tree); } while (--count != 0); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
770 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
771 } else if (curlen != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
772 if (curlen != prevlen) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
773 send_code(s, curlen, s->bl_tree); count--; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
774 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
775 Assert(count >= 3 && count <= 6, " 3_6?"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
776 send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
777 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
778 } else if (count <= 10) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
779 send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
780 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
781 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
782 send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
783 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
784 count = 0; prevlen = curlen; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
785 if (nextlen == 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
786 max_count = 138, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
787 } else if (curlen == nextlen) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
788 max_count = 6, min_count = 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
789 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
790 max_count = 7, min_count = 4; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
791 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
792 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
793 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
794 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
795 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
796 * Construct the Huffman tree for the bit lengths and return the index in |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
797 * bl_order of the last bit length code to send. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
798 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
799 local int build_bl_tree(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
800 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
801 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
802 int max_blindex; /* index of last bit length code of non zero freq */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
803 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
804 /* Determine the bit length frequencies for literal and distance trees */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
805 scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
806 scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
807 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
808 /* Build the bit length tree: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
809 build_tree(s, (tree_desc *)(&(s->bl_desc))); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
810 /* opt_len now includes the length of the tree representations, except |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
811 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
812 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
813 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
814 /* Determine the number of bit length codes to send. The pkzip format |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
815 * requires that at least 4 bit length codes be sent. (appnote.txt says |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
816 * 3 but the actual value used is 4.) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
817 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
818 for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
819 if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
820 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
821 /* Update opt_len to include the bit length tree and counts */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
822 s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
823 Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
824 s->opt_len, s->static_len)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
825 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
826 return max_blindex; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
827 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
828 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
829 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
830 * Send the header for a block using dynamic Huffman trees: the counts, the |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
831 * lengths of the bit length codes, the literal tree and the distance tree. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
832 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
833 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
834 local void send_all_trees(s, lcodes, dcodes, blcodes) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
835 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
836 int lcodes, dcodes, blcodes; /* number of codes for each tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
837 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
838 int rank; /* index in bl_order */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
839 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
840 Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
841 Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
842 "too many codes"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
843 Tracev((stderr, "\nbl counts: ")); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
844 send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
845 send_bits(s, dcodes-1, 5); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
846 send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
847 for (rank = 0; rank < blcodes; rank++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
848 Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
849 send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
850 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
851 Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
852 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
853 send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
854 Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
855 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
856 send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
857 Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
858 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
859 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
860 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
861 * Send a stored block |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
862 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
863 void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
864 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
865 charf *buf; /* input block */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
866 ulg stored_len; /* length of input block */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
867 int last; /* one if this is the last block for a file */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
868 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
869 send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
870 bi_windup(s); /* align on byte boundary */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
871 put_short(s, (ush)stored_len); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
872 put_short(s, (ush)~stored_len); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
873 zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
874 s->pending += stored_len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
875 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
876 s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
877 s->compressed_len += (stored_len + 4) << 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
878 s->bits_sent += 2*16; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
879 s->bits_sent += stored_len<<3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
880 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
881 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
882 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
883 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
884 * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
885 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
886 void ZLIB_INTERNAL _tr_flush_bits(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
887 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
888 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
889 bi_flush(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
890 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
891 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
892 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
893 * Send one empty static block to give enough lookahead for inflate. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
894 * This takes 10 bits, of which 7 may remain in the bit buffer. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
895 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
896 void ZLIB_INTERNAL _tr_align(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
897 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
898 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
899 send_bits(s, STATIC_TREES<<1, 3); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
900 send_code(s, END_BLOCK, static_ltree); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
901 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
902 s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
903 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
904 bi_flush(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
905 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
906 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
907 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
908 * Determine the best encoding for the current block: dynamic trees, static |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
909 * trees or store, and write out the encoded block. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
910 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
911 void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
912 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
913 charf *buf; /* input block, or NULL if too old */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
914 ulg stored_len; /* length of input block */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
915 int last; /* one if this is the last block for a file */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
916 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
917 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
918 int max_blindex = 0; /* index of last bit length code of non zero freq */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
919 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
920 /* Build the Huffman trees unless a stored block is forced */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
921 if (s->level > 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
922 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
923 /* Check if the file is binary or text */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
924 if (s->strm->data_type == Z_UNKNOWN) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
925 s->strm->data_type = detect_data_type(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
926 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
927 /* Construct the literal and distance trees */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
928 build_tree(s, (tree_desc *)(&(s->l_desc))); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
929 Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
930 s->static_len)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
931 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
932 build_tree(s, (tree_desc *)(&(s->d_desc))); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
933 Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
934 s->static_len)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
935 /* At this point, opt_len and static_len are the total bit lengths of |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
936 * the compressed block data, excluding the tree representations. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
937 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
938 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
939 /* Build the bit length tree for the above two trees, and get the index |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
940 * in bl_order of the last bit length code to send. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
941 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
942 max_blindex = build_bl_tree(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
943 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
944 /* Determine the best encoding. Compute the block lengths in bytes. */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
945 opt_lenb = (s->opt_len+3+7)>>3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
946 static_lenb = (s->static_len+3+7)>>3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
947 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
948 Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
949 opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
950 s->last_lit)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
951 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
952 if (static_lenb <= opt_lenb) opt_lenb = static_lenb; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
953 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
954 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
955 Assert(buf != (char*)0, "lost buf"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
956 opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
957 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
958 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
959 #ifdef FORCE_STORED |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
960 if (buf != (char*)0) { /* force stored block */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
961 #else |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
962 if (stored_len+4 <= opt_lenb && buf != (char*)0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
963 /* 4: two words for the lengths */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
964 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
965 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
966 * Otherwise we can't have processed more than WSIZE input bytes since |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
967 * the last block flush, because compression would have been |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
968 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
969 * transform a block into a stored block. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
970 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
971 _tr_stored_block(s, buf, stored_len, last); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
972 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
973 #ifdef FORCE_STATIC |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
974 } else if (static_lenb >= 0) { /* force static trees */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
975 #else |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
976 } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
977 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
978 send_bits(s, (STATIC_TREES<<1)+last, 3); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
979 compress_block(s, (const ct_data *)static_ltree, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
980 (const ct_data *)static_dtree); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
981 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
982 s->compressed_len += 3 + s->static_len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
983 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
984 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
985 send_bits(s, (DYN_TREES<<1)+last, 3); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
986 send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
987 max_blindex+1); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
988 compress_block(s, (const ct_data *)s->dyn_ltree, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
989 (const ct_data *)s->dyn_dtree); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
990 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
991 s->compressed_len += 3 + s->opt_len; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
992 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
993 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
994 Assert (s->compressed_len == s->bits_sent, "bad compressed size"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
995 /* The above check is made mod 2^32, for files larger than 512 MB |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
996 * and uLong implemented on 32 bits. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
997 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
998 init_block(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
999 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1000 if (last) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1001 bi_windup(s); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1002 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1003 s->compressed_len += 7; /* align on byte boundary */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1004 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1005 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1006 Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1007 s->compressed_len-7*last)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1008 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1009 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1010 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1011 * Save the match info and tally the frequency counts. Return true if |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1012 * the current block must be flushed. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1013 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1014 int ZLIB_INTERNAL _tr_tally (s, dist, lc) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1015 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1016 unsigned dist; /* distance of matched string */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1017 unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1018 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1019 s->d_buf[s->last_lit] = (ush)dist; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1020 s->l_buf[s->last_lit++] = (uch)lc; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1021 if (dist == 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1022 /* lc is the unmatched char */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1023 s->dyn_ltree[lc].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1024 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1025 s->matches++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1026 /* Here, lc is the match length - MIN_MATCH */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1027 dist--; /* dist = match distance - 1 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1028 Assert((ush)dist < (ush)MAX_DIST(s) && |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1029 (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1030 (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1031 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1032 s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1033 s->dyn_dtree[d_code(dist)].Freq++; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1034 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1035 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1036 #ifdef TRUNCATE_BLOCK |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1037 /* Try to guess if it is profitable to stop the current block here */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1038 if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1039 /* Compute an upper bound for the compressed length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1040 ulg out_length = (ulg)s->last_lit*8L; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1041 ulg in_length = (ulg)((long)s->strstart - s->block_start); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1042 int dcode; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1043 for (dcode = 0; dcode < D_CODES; dcode++) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1044 out_length += (ulg)s->dyn_dtree[dcode].Freq * |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1045 (5L+extra_dbits[dcode]); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1046 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1047 out_length >>= 3; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1048 Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1049 s->last_lit, in_length, out_length, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1050 100L - out_length*100L/in_length)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1051 if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1052 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1053 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1054 return (s->last_lit == s->lit_bufsize-1); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1055 /* We avoid equality with lit_bufsize because of wraparound at 64K |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1056 * on 16 bit machines and because stored blocks are restricted to |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1057 * 64K-1 bytes. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1058 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1059 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1060 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1061 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1062 * Send the block data compressed using the given Huffman trees |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1063 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1064 local void compress_block(s, ltree, dtree) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1065 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1066 const ct_data *ltree; /* literal tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1067 const ct_data *dtree; /* distance tree */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1068 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1069 unsigned dist; /* distance of matched string */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1070 int lc; /* match length or unmatched char (if dist == 0) */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1071 unsigned lx = 0; /* running index in l_buf */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1072 unsigned code; /* the code to send */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1073 int extra; /* number of extra bits to send */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1074 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1075 if (s->last_lit != 0) do { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1076 dist = s->d_buf[lx]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1077 lc = s->l_buf[lx++]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1078 if (dist == 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1079 send_code(s, lc, ltree); /* send a literal byte */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1080 Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1081 } else { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1082 /* Here, lc is the match length - MIN_MATCH */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1083 code = _length_code[lc]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1084 send_code(s, code+LITERALS+1, ltree); /* send the length code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1085 extra = extra_lbits[code]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1086 if (extra != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1087 lc -= base_length[code]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1088 send_bits(s, lc, extra); /* send the extra length bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1089 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1090 dist--; /* dist is now the match distance - 1 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1091 code = d_code(dist); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1092 Assert (code < D_CODES, "bad d_code"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1093 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1094 send_code(s, code, dtree); /* send the distance code */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1095 extra = extra_dbits[code]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1096 if (extra != 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1097 dist -= (unsigned)base_dist[code]; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1098 send_bits(s, dist, extra); /* send the extra distance bits */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1099 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1100 } /* literal or match pair ? */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1101 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1102 /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1103 Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1104 "pendingBuf overflow"); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1105 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1106 } while (lx < s->last_lit); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1107 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1108 send_code(s, END_BLOCK, ltree); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1109 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1110 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1111 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1112 * Check if the data type is TEXT or BINARY, using the following algorithm: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1113 * - TEXT if the two conditions below are satisfied: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1114 * a) There are no non-portable control characters belonging to the |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1115 * "black list" (0..6, 14..25, 28..31). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1116 * b) There is at least one printable character belonging to the |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1117 * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1118 * - BINARY otherwise. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1119 * - The following partially-portable control characters form a |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1120 * "gray list" that is ignored in this detection algorithm: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1121 * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1122 * IN assertion: the fields Freq of dyn_ltree are set. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1123 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1124 local int detect_data_type(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1125 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1126 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1127 /* black_mask is the bit mask of black-listed bytes |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1128 * set bits 0..6, 14..25, and 28..31 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1129 * 0xf3ffc07f = binary 11110011111111111100000001111111 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1130 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1131 unsigned long black_mask = 0xf3ffc07fUL; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1132 int n; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1133 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1134 /* Check for non-textual ("black-listed") bytes. */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1135 for (n = 0; n <= 31; n++, black_mask >>= 1) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1136 if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1137 return Z_BINARY; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1138 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1139 /* Check for textual ("white-listed") bytes. */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1140 if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1141 || s->dyn_ltree[13].Freq != 0) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1142 return Z_TEXT; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1143 for (n = 32; n < LITERALS; n++) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1144 if (s->dyn_ltree[n].Freq != 0) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1145 return Z_TEXT; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1146 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1147 /* There are no "black-listed" or "white-listed" bytes: |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1148 * this stream either is empty or has tolerated ("gray-listed") bytes only. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1149 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1150 return Z_BINARY; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1151 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1152 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1153 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1154 * Reverse the first len bits of a code, using straightforward code (a faster |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1155 * method would use a table) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1156 * IN assertion: 1 <= len <= 15 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1157 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1158 local unsigned bi_reverse(code, len) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1159 unsigned code; /* the value to invert */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1160 int len; /* its bit length */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1161 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1162 register unsigned res = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1163 do { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1164 res |= code & 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1165 code >>= 1, res <<= 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1166 } while (--len > 0); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1167 return res >> 1; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1168 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1169 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1170 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1171 * Flush the bit buffer, keeping at most 7 bits in it. |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1172 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1173 local void bi_flush(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1174 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1175 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1176 if (s->bi_valid == 16) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1177 put_short(s, s->bi_buf); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1178 s->bi_buf = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1179 s->bi_valid = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1180 } else if (s->bi_valid >= 8) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1181 put_byte(s, (Byte)s->bi_buf); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1182 s->bi_buf >>= 8; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1183 s->bi_valid -= 8; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1184 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1185 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1186 |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1187 /* =========================================================================== |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1188 * Flush the bit buffer and align the output on a byte boundary |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1189 */ |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1190 local void bi_windup(s) |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1191 deflate_state *s; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1192 { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1193 if (s->bi_valid > 8) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1194 put_short(s, s->bi_buf); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1195 } else if (s->bi_valid > 0) { |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1196 put_byte(s, (Byte)s->bi_buf); |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1197 } |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1198 s->bi_buf = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1199 s->bi_valid = 0; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1200 #ifdef ZLIB_DEBUG |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1201 s->bits_sent = (s->bits_sent+7) & ~7; |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1202 #endif |
00d788dac91a
Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1203 } |