Coverage Report

Created: 2026-10-17 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zlib-ng/trees_emit.h
Line
Count
Source
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 Z_INTERNAL const unsigned char zng_dist_code[DIST_CODE_LEN];
18
extern Z_INTERNAL const unsigned char zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1];
19
20
/* Combined mask + extra_bits tables for single-lookup optimization */
21
extern Z_INTERNAL const uint16_t lmask_extra[LENGTH_CODES];
22
extern Z_INTERNAL const uint32_t dmask_extra[D_CODES];
23
24
/* Bit buffer and deflate code stderr tracing */
25
#ifdef ZLIB_DEBUG
26
#  define trace_bits(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 trace_code(c) \
31
    if (z_verbose > 2) { \
32
        fprintf(stderr, "\ncd %3d ", (c)); \
33
    }
34
#else
35
#  define trace_bits(s, value, length)
36
#  define trace_code(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
93.8k
#define send_bits(s, t_val, t_len, bi_buf, bi_valid) do {\
44
93.8k
    Assert(bi_valid <= 64, "Too many bits in bi_valid");\
45
93.8k
    uint64_t val = (uint64_t)t_val;\
46
93.8k
    uint32_t len = (uint32_t)t_len;\
47
93.8k
    uint32_t total_bits = bi_valid + len;\
48
93.8k
    trace_bits(s, val, len);\
49
93.8k
    sent_bits_add(s, len);\
50
93.8k
    \
51
93.8k
    /* Unconditionally shift and merge values into the buffer */\
52
93.8k
    bi_buf |= val << bi_valid;\
53
93.8k
    \
54
93.8k
    /* Check if the 64-bit boundary was crossed */\
55
93.8k
    if (total_bits >= 64) {\
56
2.46k
        total_bits -= 64;\
57
2.46k
        put_uint64(s, bi_buf);\
58
2.46k
        \
59
2.46k
        /* Secure shift: prevent Undefined Behavior when bi_valid is 0 */\
60
2.46k
        /* If bi_valid is 0, we shift by 0 (via the mask) and overwrite bi_buf completely */\
61
2.46k
        bi_buf = (val >> 1) >> (~bi_valid & 63);\
62
2.46k
    }\
63
93.8k
    bi_valid = total_bits;\
64
93.8k
} while (0)
65
66
/* Merge bits into the bit buffer without flushing. The caller must guarantee room,
67
 * i.e. bi_valid + len <= 64. Pair with send_bits_flush, which leaves at most 7 bits. */
68
1.72M
#define send_bits_merge(s, t_val, t_len, bi_buf, bi_valid) do { \
69
1.72M
    Assert((bi_valid) + (uint32_t)(t_len) <= 64, "bit buffer overflow"); \
70
1.72M
    trace_bits(s, (uint64_t)(t_val), (uint32_t)(t_len)); \
71
1.72M
    sent_bits_add(s, t_len); \
72
1.72M
    bi_buf |= (uint64_t)(t_val) << (bi_valid); \
73
1.72M
    bi_valid += (uint32_t)(t_len); \
74
1.72M
} while (0)
75
76
/* Store the bit buffer unconditionally and consume its complete bytes, leaving at most
77
 * 7 valid bits. The unconditional 8-byte store reaches up to 7 bytes past the logical
78
 * output position, which the pending buffer layout must reserve room for
79
 * (see PENDING_BUF_PAD in deflate.c). */
80
1.72M
#define send_bits_flush(s, bi_buf, bi_valid, pending) do { \
81
1.72M
    zng_memwrite_8((s)->pending_buf + (pending), Z_U64_TO_LE(bi_buf)); \
82
1.72M
    pending += (bi_valid) >> 3; \
83
1.72M
    bi_buf >>= ((bi_valid) & ~7U); \
84
1.72M
    bi_valid &= 7; \
85
1.72M
} while (0)
86
87
/* Send a code of the given tree. c and tree must not have side effects */
88
#ifdef ZLIB_DEBUG
89
#  define send_code(s, c, tree, bi_buf, bi_valid) { \
90
    trace_code(c); \
91
    send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \
92
}
93
#else
94
#  define send_code(s, c, tree, bi_buf, bi_valid) \
95
27.3k
    send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid)
96
#endif
97
98
/* Merge a code of the given tree without flushing. c and tree must not have side effects */
99
#ifdef ZLIB_DEBUG
100
#  define send_code_merge(s, c, tree, bi_buf, bi_valid) { \
101
    trace_code(c); \
102
    send_bits_merge(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \
103
}
104
#else
105
#  define send_code_merge(s, c, tree, bi_buf, bi_valid) \
106
3.79k
    send_bits_merge(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid)
107
#endif
108
109
/* ===========================================================================
110
 * Flush the bit buffer and align the output on a byte boundary
111
 */
112
3.07k
static inline void bi_windup(deflate_state *s) {
113
3.07k
    if (s->bi_valid > 56) {
114
0
        put_uint64(s, s->bi_buf);
115
3.07k
    } else {
116
3.07k
        if (s->bi_valid > 24) {
117
259
            put_uint32(s, (uint32_t)s->bi_buf);
118
259
            s->bi_buf >>= 32;
119
259
            s->bi_valid -= 32;
120
259
        }
121
3.07k
        if (s->bi_valid > 8) {
122
1.36k
            put_short(s, (uint16_t)s->bi_buf);
123
1.36k
            s->bi_buf >>= 16;
124
1.36k
            s->bi_valid -= 16;
125
1.36k
        }
126
3.07k
        if (s->bi_valid > 0) {
127
1.53k
            put_byte(s, s->bi_buf);
128
1.53k
        }
129
3.07k
    }
130
3.07k
    s->bi_used = ((s->bi_valid - 1) & 7) + 1;
131
3.07k
    s->bi_buf = 0;
132
3.07k
    s->bi_valid = 0;
133
3.07k
}
Unexecuted instantiation: deflate_quick.c:bi_windup
trees.c:bi_windup
Line
Count
Source
112
3.07k
static inline void bi_windup(deflate_state *s) {
113
3.07k
    if (s->bi_valid > 56) {
114
0
        put_uint64(s, s->bi_buf);
115
3.07k
    } else {
116
3.07k
        if (s->bi_valid > 24) {
117
259
            put_uint32(s, (uint32_t)s->bi_buf);
118
259
            s->bi_buf >>= 32;
119
259
            s->bi_valid -= 32;
120
259
        }
121
3.07k
        if (s->bi_valid > 8) {
122
1.36k
            put_short(s, (uint16_t)s->bi_buf);
123
1.36k
            s->bi_buf >>= 16;
124
1.36k
            s->bi_valid -= 16;
125
1.36k
        }
126
3.07k
        if (s->bi_valid > 0) {
127
1.53k
            put_byte(s, s->bi_buf);
128
1.53k
        }
129
3.07k
    }
130
3.07k
    s->bi_used = ((s->bi_valid - 1) & 7) + 1;
131
3.07k
    s->bi_buf = 0;
132
3.07k
    s->bi_valid = 0;
133
3.07k
}
134
135
/* ===========================================================================
136
 * Emit literal code
137
 */
138
Z_FORCEINLINE static void zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c,
139
0
                                uint64_t *bi_buf, uint32_t *bi_valid) {
140
0
    send_code(s, c, ltree, *bi_buf, *bi_valid);
141
0
    Tracecv(isgraph(c & 0xff), (stderr, " '%c' ", c));
142
0
}
Unexecuted instantiation: deflate_quick.c:zng_emit_lit
Unexecuted instantiation: trees.c:zng_emit_lit
143
144
/* ===========================================================================
145
 * Assemble a match's length code + extra bits + distance code + extra bits into
146
 * a single bit string, at most 48 bits. Returns the bits, length via *bits_len.
147
 */
148
1.72M
Z_FORCEINLINE static uint64_t zng_assemble_dist(const ct_data *ltree, const ct_data *dtree, uint32_t lc, uint32_t dist, uint32_t *bits_len) {
149
1.72M
    uint64_t match_bits;
150
1.72M
    uint32_t match_bits_len;
151
1.72M
    uint32_t mask_ext;  // Contains both mask and extra, can safely be used directly as mask
152
                        // due to extra bits being outside the range of lc and dist data.
153
1.72M
    uint32_t c, extra;
154
1.72M
    uint8_t code;
155
156
    /* 1. Process Length Code */
157
1.72M
    code = zng_length_code[lc];
158
1.72M
    c = code + LITERALS + 1;
159
1.72M
    Assert(c < L_CODES, "bad l_code");
160
1.72M
    trace_code(c);
161
162
    /*    Send length code, len is the match length - STD_MIN_MATCH */
163
1.72M
    match_bits = ltree[c].Code;
164
1.72M
    match_bits_len = ltree[c].Len;
165
166
    /* 2. Get extra bits count and mask */
167
1.72M
    mask_ext = lmask_extra[code];
168
1.72M
    extra = mask_ext >> 8;
169
170
    /*    Send length extra bits */
171
1.72M
    match_bits |= (uint64_t)(lc & mask_ext) << match_bits_len;
172
1.72M
    match_bits_len += extra;
173
174
    /* 3. Process Distance Code */
175
1.72M
    dist--; /* dist is now the match distance - 1 */
176
1.72M
    code = d_code(dist);
177
1.72M
    Assert(code < D_CODES, "bad d_code");
178
1.72M
    trace_code(code);
179
180
    /*    Send distance code */
181
1.72M
    match_bits |= ((uint64_t)dtree[code].Code << match_bits_len);
182
1.72M
    match_bits_len += dtree[code].Len;
183
184
    /* 4. Get extra bits count and mask */
185
1.72M
    mask_ext = dmask_extra[code];
186
1.72M
    extra = mask_ext >> 16;
187
188
    /*    Send dist extra bits */
189
1.72M
    match_bits |= ((uint64_t)(dist & mask_ext) << match_bits_len);
190
1.72M
    match_bits_len += extra;
191
192
1.72M
    *bits_len = match_bits_len;
193
1.72M
    return match_bits;
194
1.72M
}
Unexecuted instantiation: deflate_quick.c:zng_assemble_dist
trees.c:zng_assemble_dist
Line
Count
Source
148
1.72M
Z_FORCEINLINE static uint64_t zng_assemble_dist(const ct_data *ltree, const ct_data *dtree, uint32_t lc, uint32_t dist, uint32_t *bits_len) {
149
1.72M
    uint64_t match_bits;
150
1.72M
    uint32_t match_bits_len;
151
1.72M
    uint32_t mask_ext;  // Contains both mask and extra, can safely be used directly as mask
152
                        // due to extra bits being outside the range of lc and dist data.
153
1.72M
    uint32_t c, extra;
154
1.72M
    uint8_t code;
155
156
    /* 1. Process Length Code */
157
1.72M
    code = zng_length_code[lc];
158
1.72M
    c = code + LITERALS + 1;
159
1.72M
    Assert(c < L_CODES, "bad l_code");
160
1.72M
    trace_code(c);
161
162
    /*    Send length code, len is the match length - STD_MIN_MATCH */
163
1.72M
    match_bits = ltree[c].Code;
164
1.72M
    match_bits_len = ltree[c].Len;
165
166
    /* 2. Get extra bits count and mask */
167
1.72M
    mask_ext = lmask_extra[code];
168
1.72M
    extra = mask_ext >> 8;
169
170
    /*    Send length extra bits */
171
1.72M
    match_bits |= (uint64_t)(lc & mask_ext) << match_bits_len;
172
1.72M
    match_bits_len += extra;
173
174
    /* 3. Process Distance Code */
175
1.72M
    dist--; /* dist is now the match distance - 1 */
176
1.72M
    code = d_code(dist);
177
1.72M
    Assert(code < D_CODES, "bad d_code");
178
1.72M
    trace_code(code);
179
180
    /*    Send distance code */
181
1.72M
    match_bits |= ((uint64_t)dtree[code].Code << match_bits_len);
182
1.72M
    match_bits_len += dtree[code].Len;
183
184
    /* 4. Get extra bits count and mask */
185
1.72M
    mask_ext = dmask_extra[code];
186
1.72M
    extra = mask_ext >> 16;
187
188
    /*    Send dist extra bits */
189
1.72M
    match_bits |= ((uint64_t)(dist & mask_ext) << match_bits_len);
190
1.72M
    match_bits_len += extra;
191
192
1.72M
    *bits_len = match_bits_len;
193
1.72M
    return match_bits;
194
1.72M
}
195
196
/* ===========================================================================
197
 * Emit match distance/length code
198
 */
199
static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree,
200
0
                                     uint32_t lc, uint32_t dist, uint64_t *bi_buf, uint32_t *bi_valid) {
201
0
    uint32_t match_bits_len;
202
0
    uint64_t match_bits = zng_assemble_dist(ltree, dtree, lc, dist, &match_bits_len);
203
204
0
    send_bits(s, match_bits, match_bits_len, *bi_buf, *bi_valid);
205
206
0
    return match_bits_len;
207
0
}
Unexecuted instantiation: deflate_quick.c:zng_emit_dist
Unexecuted instantiation: trees.c:zng_emit_dist
208
209
/* ===========================================================================
210
 * Emit end block
211
 */
212
static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last,
213
3.07k
                                      uint64_t *bi_buf, uint32_t *bi_valid) {
214
3.07k
    send_code(s, END_BLOCK, ltree, *bi_buf, *bi_valid);
215
3.07k
    Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n",
216
3.07k
        last, s->pending, (uint64_t)s->strm->total_out));
217
3.07k
    Z_UNUSED(last);
218
3.07k
}
Unexecuted instantiation: deflate_quick.c:zng_emit_end_block
trees.c:zng_emit_end_block
Line
Count
Source
213
3.07k
                                      uint64_t *bi_buf, uint32_t *bi_valid) {
214
3.07k
    send_code(s, END_BLOCK, ltree, *bi_buf, *bi_valid);
215
3.07k
    Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n",
216
3.07k
        last, s->pending, (uint64_t)s->strm->total_out));
217
3.07k
    Z_UNUSED(last);
218
3.07k
}
219
220
/* ===========================================================================
221
 * Emit literal and count bits
222
 */
223
0
static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) {
224
0
    uint64_t bi_buf = s->bi_buf;
225
0
    uint32_t bi_valid = s->bi_valid;
226
0
    zng_emit_lit(s, ltree, c, &bi_buf, &bi_valid);
227
0
    s->bi_buf = bi_buf;
228
0
    s->bi_valid = bi_valid;
229
0
    cmpr_bits_add(s, ltree[c].Len);
230
0
}
Unexecuted instantiation: deflate_quick.c:zng_tr_emit_lit
Unexecuted instantiation: trees.c:zng_tr_emit_lit
231
232
/* ===========================================================================
233
 * Emit match and count bits
234
 */
235
static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree,
236
0
    uint32_t lc, uint32_t dist) {
237
0
    uint64_t bi_buf = s->bi_buf;
238
0
    uint32_t bi_valid = s->bi_valid;
239
0
    uint32_t bits = zng_emit_dist(s, ltree, dtree, lc, dist, &bi_buf, &bi_valid);
240
0
    s->bi_buf = bi_buf;
241
0
    s->bi_valid = bi_valid;
242
0
    cmpr_bits_add(s, bits);
243
0
}
Unexecuted instantiation: deflate_quick.c:zng_tr_emit_dist
Unexecuted instantiation: trees.c:zng_tr_emit_dist
244
245
/* ===========================================================================
246
 * Emit start of block
247
 */
248
4.61k
static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) {
249
4.61k
    uint32_t bi_valid = s->bi_valid;
250
4.61k
    uint64_t bi_buf = s->bi_buf;
251
4.61k
    uint32_t header_bits = (type << 1) + last;
252
4.61k
    send_bits(s, header_bits, 3, bi_buf, bi_valid);
253
4.61k
    cmpr_bits_add(s, 3);
254
4.61k
    s->bi_valid = bi_valid;
255
4.61k
    s->bi_buf = bi_buf;
256
4.61k
    Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last));
257
4.61k
}
Unexecuted instantiation: deflate_quick.c:zng_tr_emit_tree
trees.c:zng_tr_emit_tree
Line
Count
Source
248
4.61k
static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) {
249
4.61k
    uint32_t bi_valid = s->bi_valid;
250
4.61k
    uint64_t bi_buf = s->bi_buf;
251
4.61k
    uint32_t header_bits = (type << 1) + last;
252
4.61k
    send_bits(s, header_bits, 3, bi_buf, bi_valid);
253
4.61k
    cmpr_bits_add(s, 3);
254
4.61k
    s->bi_valid = bi_valid;
255
4.61k
    s->bi_buf = bi_buf;
256
4.61k
    Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last));
257
4.61k
}
258
259
/* ===========================================================================
260
 * Align bit buffer on a byte boundary and count bits
261
 */
262
3.07k
static inline void zng_tr_emit_align(deflate_state *s) {
263
3.07k
    bi_windup(s); /* align on byte boundary */
264
3.07k
    sent_bits_align(s);
265
3.07k
}
Unexecuted instantiation: deflate_quick.c:zng_tr_emit_align
trees.c:zng_tr_emit_align
Line
Count
Source
262
3.07k
static inline void zng_tr_emit_align(deflate_state *s) {
263
3.07k
    bi_windup(s); /* align on byte boundary */
264
3.07k
    sent_bits_align(s);
265
3.07k
}
266
267
/* ===========================================================================
268
 * Emit an end block and align bit buffer if last block
269
 */
270
0
static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) {
271
0
    uint64_t bi_buf = s->bi_buf;
272
0
    uint32_t bi_valid = s->bi_valid;
273
0
    zng_emit_end_block(s, ltree, last, &bi_buf, &bi_valid);
274
0
    s->bi_buf = bi_buf;
275
0
    s->bi_valid = bi_valid;
276
0
    cmpr_bits_add(s, 7);
277
0
    if (last)
278
0
        zng_tr_emit_align(s);
279
0
}
Unexecuted instantiation: deflate_quick.c:zng_tr_emit_end_block
Unexecuted instantiation: trees.c:zng_tr_emit_end_block
280
281
#endif