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