1 | #ifndef TREES_EMIT_H_ |
2 | #define TREES_EMIT_H_ |
3 | |
4 | #include "zbuild.h" |
5 | #include "trees.h" |
6 | |
7 | #ifdef ZLIB_DEBUG |
8 | # include <ctype.h> |
9 | # include <inttypes.h> |
10 | # include <stdint.h> |
11 | #endif |
12 | |
13 | |
14 | /* trees.h */ |
15 | extern Z_INTERNAL const ct_data static_ltree[L_CODES+2]; |
16 | extern Z_INTERNAL const ct_data static_dtree[D_CODES]; |
17 | |
18 | extern const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN]; |
19 | extern const unsigned char Z_INTERNAL zng_length_code[MAX_MATCH-MIN_MATCH+1]; |
20 | |
21 | extern Z_INTERNAL const int base_length[LENGTH_CODES]; |
22 | extern Z_INTERNAL const int base_dist[D_CODES]; |
23 | |
24 | /* Bit buffer and deflate code stderr tracing */ |
25 | #ifdef ZLIB_DEBUG |
26 | # define send_bits_trace(s, value, length) { \ |
27 | Tracevv((stderr, " l %2d v %4llx ", (int)(length), (long long)(value))); \ |
28 | Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ |
29 | } |
30 | # define send_code_trace(s, c) \ |
31 | if (z_verbose > 2) { \ |
32 | fprintf(stderr, "\ncd %3d ", (c)); \ |
33 | } |
34 | #else |
35 | # define send_bits_trace(s, value, length) |
36 | # define send_code_trace(s, c) |
37 | #endif |
38 | |
39 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and |
40 | * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid)) |
41 | * unused bits in value. |
42 | */ |
43 | #define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\ |
44 | uint64_t val = (uint64_t)t_val;\ |
45 | uint32_t len = (uint32_t)t_len;\ |
46 | uint32_t total_bits = bi_valid + len;\ |
47 | send_bits_trace(s, val, len);\ |
48 | sent_bits_add(s, len);\ |
49 | if (total_bits < BIT_BUF_SIZE) {\ |
50 | bi_buf |= val << bi_valid;\ |
51 | bi_valid = total_bits;\ |
52 | } else if (bi_valid == BIT_BUF_SIZE) {\ |
53 | put_uint64(s, bi_buf);\ |
54 | bi_buf = val;\ |
55 | bi_valid = len;\ |
56 | } else {\ |
57 | bi_buf |= val << bi_valid;\ |
58 | put_uint64(s, bi_buf);\ |
59 | bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\ |
60 | bi_valid = total_bits - BIT_BUF_SIZE;\ |
61 | }\ |
62 | } |
63 | |
64 | /* Send a code of the given tree. c and tree must not have side effects */ |
65 | #ifdef ZLIB_DEBUG |
66 | # define send_code(s, c, tree, bi_buf, bi_valid) { \ |
67 | send_code_trace(s, c); \ |
68 | send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \ |
69 | } |
70 | #else |
71 | # define send_code(s, c, tree, bi_buf, bi_valid) \ |
72 | send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid) |
73 | #endif |
74 | |
75 | /* =========================================================================== |
76 | * Flush the bit buffer and align the output on a byte boundary |
77 | */ |
78 | static void bi_windup(deflate_state *s) { |
79 | if (s->bi_valid > 56) { |
80 | put_uint64(s, lld: s->bi_buf); |
81 | } else { |
82 | if (s->bi_valid > 24) { |
83 | put_uint32(s, dw: (uint32_t)s->bi_buf); |
84 | s->bi_buf >>= 32; |
85 | s->bi_valid -= 32; |
86 | } |
87 | if (s->bi_valid > 8) { |
88 | put_short(s, w: (uint16_t)s->bi_buf); |
89 | s->bi_buf >>= 16; |
90 | s->bi_valid -= 16; |
91 | } |
92 | if (s->bi_valid > 0) { |
93 | put_byte(s, s->bi_buf); |
94 | } |
95 | } |
96 | s->bi_buf = 0; |
97 | s->bi_valid = 0; |
98 | } |
99 | |
100 | /* =========================================================================== |
101 | * Emit literal code |
102 | */ |
103 | static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { |
104 | uint32_t bi_valid = s->bi_valid; |
105 | uint64_t bi_buf = s->bi_buf; |
106 | |
107 | send_code(s, c, ltree, bi_buf, bi_valid); |
108 | |
109 | s->bi_valid = bi_valid; |
110 | s->bi_buf = bi_buf; |
111 | |
112 | Tracecv(isgraph(c & 0xff), (stderr, " '%c' " , c)); |
113 | |
114 | return ltree[c].Len; |
115 | } |
116 | |
117 | /* =========================================================================== |
118 | * Emit match distance/length code |
119 | */ |
120 | static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, |
121 | uint32_t lc, uint32_t dist) { |
122 | uint32_t c, ; |
123 | uint8_t code; |
124 | uint64_t match_bits; |
125 | uint32_t match_bits_len; |
126 | uint32_t bi_valid = s->bi_valid; |
127 | uint64_t bi_buf = s->bi_buf; |
128 | |
129 | /* Send the length code, len is the match length - MIN_MATCH */ |
130 | code = zng_length_code[lc]; |
131 | c = code+LITERALS+1; |
132 | Assert(c < L_CODES, "bad l_code" ); |
133 | send_code_trace(s, c); |
134 | |
135 | match_bits = ltree[c].Code; |
136 | match_bits_len = ltree[c].Len; |
137 | extra = extra_lbits[code]; |
138 | if (extra != 0) { |
139 | lc -= base_length[code]; |
140 | match_bits |= ((uint64_t)lc << match_bits_len); |
141 | match_bits_len += extra; |
142 | } |
143 | |
144 | dist--; /* dist is now the match distance - 1 */ |
145 | code = d_code(dist); |
146 | Assert(code < D_CODES, "bad d_code" ); |
147 | send_code_trace(s, code); |
148 | |
149 | /* Send the distance code */ |
150 | match_bits |= ((uint64_t)dtree[code].Code << match_bits_len); |
151 | match_bits_len += dtree[code].Len; |
152 | extra = extra_dbits[code]; |
153 | if (extra != 0) { |
154 | dist -= base_dist[code]; |
155 | match_bits |= ((uint64_t)dist << match_bits_len); |
156 | match_bits_len += extra; |
157 | } |
158 | |
159 | send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid); |
160 | |
161 | s->bi_valid = bi_valid; |
162 | s->bi_buf = bi_buf; |
163 | |
164 | return match_bits_len; |
165 | } |
166 | |
167 | /* =========================================================================== |
168 | * Emit end block |
169 | */ |
170 | static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { |
171 | uint32_t bi_valid = s->bi_valid; |
172 | uint64_t bi_buf = s->bi_buf; |
173 | send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); |
174 | s->bi_valid = bi_valid; |
175 | s->bi_buf = bi_buf; |
176 | Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n" , |
177 | last, s->pending, (uint64_t)s->strm->total_out)); |
178 | Z_UNUSED(last); |
179 | } |
180 | |
181 | /* =========================================================================== |
182 | * Emit literal and count bits |
183 | */ |
184 | static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { |
185 | cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); |
186 | } |
187 | |
188 | /* =========================================================================== |
189 | * Emit match and count bits |
190 | */ |
191 | static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, |
192 | uint32_t lc, uint32_t dist) { |
193 | cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); |
194 | } |
195 | |
196 | /* =========================================================================== |
197 | * Emit start of block |
198 | */ |
199 | static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) { |
200 | uint32_t bi_valid = s->bi_valid; |
201 | uint64_t bi_buf = s->bi_buf; |
202 | uint32_t = (type << 1) + last; |
203 | send_bits(s, header_bits, 3, bi_buf, bi_valid); |
204 | cmpr_bits_add(s, 3); |
205 | s->bi_valid = bi_valid; |
206 | s->bi_buf = bi_buf; |
207 | Tracev((stderr, "\n--- Emit Tree: Last: %u\n" , last)); |
208 | } |
209 | |
210 | /* =========================================================================== |
211 | * Align bit buffer on a byte boundary and count bits |
212 | */ |
213 | static inline void zng_tr_emit_align(deflate_state *s) { |
214 | bi_windup(s); /* align on byte boundary */ |
215 | sent_bits_align(s); |
216 | } |
217 | |
218 | /* =========================================================================== |
219 | * Emit an end block and align bit buffer if last block |
220 | */ |
221 | static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { |
222 | zng_emit_end_block(s, ltree, last); |
223 | cmpr_bits_add(s, 7); |
224 | if (last) |
225 | zng_tr_emit_align(s); |
226 | } |
227 | |
228 | #endif |
229 | |