Line | Count | Source |
1 | | /* deflate_p.h -- Private inline functions and macros shared with more than |
2 | | * one deflate method |
3 | | * |
4 | | * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler |
5 | | * For conditions of distribution and use, see copyright notice in zlib.h |
6 | | * |
7 | | */ |
8 | | |
9 | | #ifndef DEFLATE_P_H |
10 | | #define DEFLATE_P_H |
11 | | |
12 | | #include "functable.h" |
13 | | #include "fallback_builtins.h" |
14 | | #include "zmemory.h" |
15 | | |
16 | | /* Forward declare common non-inlined functions declared in deflate.c */ |
17 | | |
18 | | #ifdef ZLIB_DEBUG |
19 | | /* =========================================================================== |
20 | | * Check that the match at match_start is indeed a match. |
21 | | */ |
22 | | static inline void check_match(deflate_state *s, uint32_t start, uint32_t match, uint32_t length) { |
23 | | /* check that the match length is valid*/ |
24 | | if (length < STD_MIN_MATCH || length > STD_MAX_MATCH) { |
25 | | fprintf(stderr, " start %u, match %u, length %u\n", start, match, length); |
26 | | z_error("invalid match length"); |
27 | | } |
28 | | /* check that the match isn't at the same position as the start string */ |
29 | | if (match == start) { |
30 | | fprintf(stderr, " start %u, match %u, length %u\n", start, match, length); |
31 | | z_error("invalid match position"); |
32 | | } |
33 | | /* check that the match is indeed a match */ |
34 | | if (memcmp(s->window + match, s->window + start, length) != 0) { |
35 | | int32_t i = 0; |
36 | | fprintf(stderr, " start %u, match %u, length %u\n", start, match, length); |
37 | | do { |
38 | | fprintf(stderr, " %03d: match [%02x] start [%02x]\n", i++, |
39 | | s->window[match++], s->window[start++]); |
40 | | } while (--length != 0); |
41 | | z_error("invalid match"); |
42 | | } |
43 | | if (z_verbose > 1) { |
44 | | fprintf(stderr, "\\[%u,%u]", start-match, length); |
45 | | do { |
46 | | putc(s->window[start++], stderr); |
47 | | } while (--length != 0); |
48 | | } |
49 | | } |
50 | | #else |
51 | | #define check_match(s, start, match, length) |
52 | | #endif |
53 | | |
54 | | Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm); |
55 | | |
56 | | /* =========================================================================== |
57 | | * Save the match info and tally the frequency counts. Return true if |
58 | | * the current block must be flushed. |
59 | | */ |
60 | | |
61 | | extern Z_INTERNAL const unsigned char zng_length_code[]; |
62 | | extern Z_INTERNAL const unsigned char zng_dist_code[]; |
63 | | |
64 | 135M | static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { |
65 | | /* c is the unmatched char */ |
66 | 135M | unsigned int sym_next = s->sym_next; |
67 | 135M | #if OPTIMAL_CMP >= 32 |
68 | 135M | zng_memwrite_4(&s->sym_buf[sym_next], Z_U32_TO_LE((uint32_t)c << 16)); |
69 | | #else |
70 | | s->sym_buf[sym_next] = 0; |
71 | | s->sym_buf[sym_next+1] = 0; |
72 | | s->sym_buf[sym_next+2] = c; |
73 | | #endif |
74 | 135M | s->sym_next = sym_next + 3; |
75 | 135M | s->dyn_ltree[c].Freq++; |
76 | 135M | Tracevv((stderr, "%c", c)); |
77 | | #ifdef ZLIB_DEBUG |
78 | | uint32_t _c = c; |
79 | | Assert(_c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); |
80 | | #endif |
81 | 135M | return (s->sym_next == s->sym_end); |
82 | 135M | } Unexecuted instantiation: deflate.c:zng_tr_tally_lit Unexecuted instantiation: deflate_fast.c:zng_tr_tally_lit Unexecuted instantiation: deflate_huff.c:zng_tr_tally_lit deflate_medium.c:zng_tr_tally_lit Line | Count | Source | 64 | 135M | static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { | 65 | | /* c is the unmatched char */ | 66 | 135M | unsigned int sym_next = s->sym_next; | 67 | 135M | #if OPTIMAL_CMP >= 32 | 68 | 135M | zng_memwrite_4(&s->sym_buf[sym_next], Z_U32_TO_LE((uint32_t)c << 16)); | 69 | | #else | 70 | | s->sym_buf[sym_next] = 0; | 71 | | s->sym_buf[sym_next+1] = 0; | 72 | | s->sym_buf[sym_next+2] = c; | 73 | | #endif | 74 | 135M | s->sym_next = sym_next + 3; | 75 | 135M | s->dyn_ltree[c].Freq++; | 76 | 135M | Tracevv((stderr, "%c", c)); | 77 | | #ifdef ZLIB_DEBUG | 78 | | uint32_t _c = c; | 79 | | Assert(_c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); | 80 | | #endif | 81 | 135M | return (s->sym_next == s->sym_end); | 82 | 135M | } |
Unexecuted instantiation: deflate_quick.c:zng_tr_tally_lit Unexecuted instantiation: deflate_rle.c:zng_tr_tally_lit Unexecuted instantiation: deflate_slow.c:zng_tr_tally_lit Unexecuted instantiation: deflate_stored.c:zng_tr_tally_lit Unexecuted instantiation: trees.c:zng_tr_tally_lit |
83 | | |
84 | 2.38M | static inline int zng_tr_tally_dist(deflate_state* s, uint32_t dist, uint32_t len) { |
85 | | /* dist: distance of matched string */ |
86 | | /* len: match length-STD_MIN_MATCH */ |
87 | 2.38M | unsigned int sym_next = s->sym_next; |
88 | 2.38M | #if OPTIMAL_CMP >= 32 |
89 | 2.38M | zng_memwrite_4(&s->sym_buf[sym_next], Z_U32_TO_LE(dist | ((uint32_t)len << 16))); |
90 | | #else |
91 | | s->sym_buf[sym_next] = (uint8_t)(dist); |
92 | | s->sym_buf[sym_next+1] = (uint8_t)(dist >> 8); |
93 | | s->sym_buf[sym_next+2] = (uint8_t)len; |
94 | | #endif |
95 | 2.38M | s->sym_next = sym_next + 3; |
96 | 2.38M | dist--; |
97 | 2.38M | Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, |
98 | 2.38M | "zng_tr_tally: bad match"); |
99 | | |
100 | 2.38M | s->dyn_ltree[zng_length_code[len] + LITERALS + 1].Freq++; |
101 | 2.38M | s->dyn_dtree[d_code(dist)].Freq++; |
102 | 2.38M | return (s->sym_next == s->sym_end); |
103 | 2.38M | } Unexecuted instantiation: deflate.c:zng_tr_tally_dist Unexecuted instantiation: deflate_fast.c:zng_tr_tally_dist Unexecuted instantiation: deflate_huff.c:zng_tr_tally_dist deflate_medium.c:zng_tr_tally_dist Line | Count | Source | 84 | 2.38M | static inline int zng_tr_tally_dist(deflate_state* s, uint32_t dist, uint32_t len) { | 85 | | /* dist: distance of matched string */ | 86 | | /* len: match length-STD_MIN_MATCH */ | 87 | 2.38M | unsigned int sym_next = s->sym_next; | 88 | 2.38M | #if OPTIMAL_CMP >= 32 | 89 | 2.38M | zng_memwrite_4(&s->sym_buf[sym_next], Z_U32_TO_LE(dist | ((uint32_t)len << 16))); | 90 | | #else | 91 | | s->sym_buf[sym_next] = (uint8_t)(dist); | 92 | | s->sym_buf[sym_next+1] = (uint8_t)(dist >> 8); | 93 | | s->sym_buf[sym_next+2] = (uint8_t)len; | 94 | | #endif | 95 | 2.38M | s->sym_next = sym_next + 3; | 96 | 2.38M | dist--; | 97 | 2.38M | Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, | 98 | 2.38M | "zng_tr_tally: bad match"); | 99 | | | 100 | 2.38M | s->dyn_ltree[zng_length_code[len] + LITERALS + 1].Freq++; | 101 | 2.38M | s->dyn_dtree[d_code(dist)].Freq++; | 102 | 2.38M | return (s->sym_next == s->sym_end); | 103 | 2.38M | } |
Unexecuted instantiation: deflate_quick.c:zng_tr_tally_dist Unexecuted instantiation: deflate_rle.c:zng_tr_tally_dist Unexecuted instantiation: deflate_slow.c:zng_tr_tally_dist Unexecuted instantiation: deflate_stored.c:zng_tr_tally_dist Unexecuted instantiation: trees.c:zng_tr_tally_dist |
104 | | |
105 | | /* ========================================================================= |
106 | | * Flush as much pending output as possible. All deflate() output, except for some |
107 | | * deflate_stored() output, goes through this function so some applications may wish to |
108 | | * modify it to avoid allocating a large strm->next_out buffer and copying into it. |
109 | | * See also read_buf(). |
110 | | */ |
111 | 132M | Z_FORCEINLINE static void flush_pending_inline(PREFIX3(stream) *strm) { |
112 | 132M | uint32_t len; |
113 | 132M | deflate_state *s = strm->state; |
114 | | |
115 | 132M | zng_tr_flush_bits(s); |
116 | 132M | len = MIN(s->pending, strm->avail_out); |
117 | 132M | if (len == 0) |
118 | 3.72k | return; |
119 | | |
120 | 132M | Tracev((stderr, "[FLUSH]")); |
121 | 132M | memcpy(strm->next_out, s->pending_out, len); |
122 | 132M | strm->next_out += len; |
123 | 132M | s->pending_out += len; |
124 | 132M | strm->total_out += len; |
125 | 132M | strm->avail_out -= len; |
126 | 132M | s->pending -= len; |
127 | 132M | if (s->pending == 0) |
128 | 19.2k | s->pending_out = s->pending_buf; |
129 | 132M | } deflate.c:flush_pending_inline Line | Count | Source | 111 | 132M | Z_FORCEINLINE static void flush_pending_inline(PREFIX3(stream) *strm) { | 112 | 132M | uint32_t len; | 113 | 132M | deflate_state *s = strm->state; | 114 | | | 115 | 132M | zng_tr_flush_bits(s); | 116 | 132M | len = MIN(s->pending, strm->avail_out); | 117 | 132M | if (len == 0) | 118 | 3.72k | return; | 119 | | | 120 | 132M | Tracev((stderr, "[FLUSH]")); | 121 | 132M | memcpy(strm->next_out, s->pending_out, len); | 122 | 132M | strm->next_out += len; | 123 | 132M | s->pending_out += len; | 124 | 132M | strm->total_out += len; | 125 | 132M | strm->avail_out -= len; | 126 | 132M | s->pending -= len; | 127 | 132M | if (s->pending == 0) | 128 | 19.2k | s->pending_out = s->pending_buf; | 129 | 132M | } |
Unexecuted instantiation: deflate_fast.c:flush_pending_inline Unexecuted instantiation: deflate_huff.c:flush_pending_inline Unexecuted instantiation: deflate_medium.c:flush_pending_inline Unexecuted instantiation: deflate_quick.c:flush_pending_inline Unexecuted instantiation: deflate_rle.c:flush_pending_inline Unexecuted instantiation: deflate_slow.c:flush_pending_inline Unexecuted instantiation: deflate_stored.c:flush_pending_inline Unexecuted instantiation: trees.c:flush_pending_inline |
130 | | |
131 | | /* =========================================================================== |
132 | | * Reverse the first len bits of a code using bit manipulation |
133 | | */ |
134 | 2.39M | Z_FORCEINLINE static uint16_t bi_reverse(uint16_t code, int len) { |
135 | | /* code: the value to invert */ |
136 | | /* len: its bit length */ |
137 | 2.39M | Assert(len >= 1 && len <= 15, "code length must be 1-15"); |
138 | 2.39M | return zng_bitreverse16(code) >> (16 - len); |
139 | 2.39M | } Unexecuted instantiation: deflate.c:bi_reverse Unexecuted instantiation: deflate_fast.c:bi_reverse Unexecuted instantiation: deflate_huff.c:bi_reverse Unexecuted instantiation: deflate_medium.c:bi_reverse Unexecuted instantiation: deflate_quick.c:bi_reverse Unexecuted instantiation: deflate_rle.c:bi_reverse Unexecuted instantiation: deflate_slow.c:bi_reverse Unexecuted instantiation: deflate_stored.c:bi_reverse Line | Count | Source | 134 | 2.39M | Z_FORCEINLINE static uint16_t bi_reverse(uint16_t code, int len) { | 135 | | /* code: the value to invert */ | 136 | | /* len: its bit length */ | 137 | 2.39M | Assert(len >= 1 && len <= 15, "code length must be 1-15"); | 138 | 2.39M | return zng_bitreverse16(code) >> (16 - len); | 139 | 2.39M | } |
|
140 | | |
141 | | /* =========================================================================== |
142 | | * Read a new buffer from the current input stream, update the adler32 and total number of |
143 | | * bytes read. All deflate() input goes through this function so some applications may wish |
144 | | * to modify it to avoid allocating a large strm->next_in buffer and copying from it. |
145 | | * See also flush_pending_inline(). |
146 | | */ |
147 | 175M | Z_FORCEINLINE static unsigned read_buf(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { |
148 | 175M | deflate_state *s = strm->state; |
149 | 175M | uint32_t len = MIN(strm->avail_in, size); |
150 | | |
151 | 175M | if (len == 0) |
152 | 0 | return 0; |
153 | | |
154 | 175M | if (!DEFLATE_NEED_CHECKSUM(strm)) { |
155 | 0 | memcpy(buf, strm->next_in, len); |
156 | 0 | #ifdef GZIP |
157 | 175M | } else if (s->wrap == 2) { |
158 | 0 | strm->adler = FUNCTABLE_CALL(crc32_copy)(strm->adler, buf, strm->next_in, len); |
159 | 0 | #endif |
160 | 175M | } else if (s->wrap == 1) { |
161 | 175M | strm->adler = FUNCTABLE_CALL(adler32_copy)(strm->adler, buf, strm->next_in, len); |
162 | 175M | } else { |
163 | 0 | memcpy(buf, strm->next_in, len); |
164 | 0 | } |
165 | | |
166 | 175M | strm->avail_in -= len; |
167 | 175M | strm->next_in += len; |
168 | 175M | strm->total_in += len; |
169 | 175M | return len; |
170 | 175M | } Line | Count | Source | 147 | 175M | Z_FORCEINLINE static unsigned read_buf(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { | 148 | 175M | deflate_state *s = strm->state; | 149 | 175M | uint32_t len = MIN(strm->avail_in, size); | 150 | | | 151 | 175M | if (len == 0) | 152 | 0 | return 0; | 153 | | | 154 | 175M | if (!DEFLATE_NEED_CHECKSUM(strm)) { | 155 | 0 | memcpy(buf, strm->next_in, len); | 156 | 0 | #ifdef GZIP | 157 | 175M | } else if (s->wrap == 2) { | 158 | 0 | strm->adler = FUNCTABLE_CALL(crc32_copy)(strm->adler, buf, strm->next_in, len); | 159 | 0 | #endif | 160 | 175M | } else if (s->wrap == 1) { | 161 | 175M | strm->adler = FUNCTABLE_CALL(adler32_copy)(strm->adler, buf, strm->next_in, len); | 162 | 175M | } else { | 163 | 0 | memcpy(buf, strm->next_in, len); | 164 | 0 | } | 165 | | | 166 | 175M | strm->avail_in -= len; | 167 | 175M | strm->next_in += len; | 168 | 175M | strm->total_in += len; | 169 | 175M | return len; | 170 | 175M | } |
Unexecuted instantiation: deflate_fast.c:read_buf Unexecuted instantiation: deflate_huff.c:read_buf Unexecuted instantiation: deflate_medium.c:read_buf Unexecuted instantiation: deflate_quick.c:read_buf Unexecuted instantiation: deflate_rle.c:read_buf Unexecuted instantiation: deflate_slow.c:read_buf Unexecuted instantiation: deflate_stored.c:read_buf Unexecuted instantiation: trees.c:read_buf |
171 | | |
172 | | /* =========================================================================== |
173 | | * Check whether a max-length match just emitted continues at s->strstart. |
174 | | * Minimum length 8 is chosen to avoid compression losses from skipping the search for a better match elsewhere. |
175 | | * The caller must ensure s->lookahead >= MIN_LOOKAHEAD and that s->strstart + STD_MAX_MATCH fits in the window. |
176 | | * Returns 0 for no match, or a match length between 8-258. |
177 | | */ |
178 | 0 | Z_FORCEINLINE static uint32_t max_match_continues(const unsigned char *window, unsigned int strstart, uint32_t dist) { |
179 | 0 | const uint8_t *scan = (const uint8_t *)window + strstart; |
180 | |
|
181 | 0 | if (LIKELY(zng_memread_8(scan) != zng_memread_8(scan - dist))) |
182 | 0 | return 0; |
183 | | |
184 | 0 | return FUNCTABLE_CALL(compare256)(scan + 2, scan - dist + 2) + 2; |
185 | 0 | } Unexecuted instantiation: deflate.c:max_match_continues Unexecuted instantiation: deflate_fast.c:max_match_continues Unexecuted instantiation: deflate_huff.c:max_match_continues Unexecuted instantiation: deflate_medium.c:max_match_continues Unexecuted instantiation: deflate_quick.c:max_match_continues Unexecuted instantiation: deflate_rle.c:max_match_continues Unexecuted instantiation: deflate_slow.c:max_match_continues Unexecuted instantiation: deflate_stored.c:max_match_continues Unexecuted instantiation: trees.c:max_match_continues |
186 | | |
187 | | /* =========================================================================== |
188 | | * Flush the current block, with given end-of-file flag. |
189 | | * IN assertion: strstart is set to the end of the current match. |
190 | | */ |
191 | 11.7k | #define FLUSH_BLOCK_ONLY(s, window, last) { \ |
192 | 11.7k | int block_start = s->block_start; \ |
193 | 11.7k | zng_tr_flush_block(s, (block_start >= 0 ? \ |
194 | 11.7k | &window[(unsigned)block_start] : \ |
195 | 11.7k | NULL), \ |
196 | 11.7k | (uint32_t)((int)s->strstart - block_start), \ |
197 | 11.7k | (last)); \ |
198 | 11.7k | s->block_start = (int)s->strstart; \ |
199 | 11.7k | PREFIX(flush_pending)(s->strm); \ |
200 | 11.7k | } |
201 | | |
202 | | /* Same but force premature exit if necessary. */ |
203 | 11.7k | #define FLUSH_BLOCK(s, window, last) { \ |
204 | 11.7k | FLUSH_BLOCK_ONLY(s, window, last); \ |
205 | 11.7k | if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ |
206 | 11.7k | } |
207 | | |
208 | | /* Maximum stored block length in deflate format (not including header). */ |
209 | 0 | #define MAX_STORED 65535 |
210 | | |
211 | | /* Compression function. Returns the block state after the call. */ |
212 | | typedef block_state (*compress_func) (deflate_state *s, int flush); |
213 | | |
214 | | #endif |