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 | | |
15 | | /* Forward declare common non-inlined functions declared in deflate.c */ |
16 | | |
17 | | #ifdef ZLIB_DEBUG |
18 | | /* =========================================================================== |
19 | | * Check that the match at match_start is indeed a match. |
20 | | */ |
21 | | static inline void check_match(deflate_state *s, uint32_t start, uint32_t match, int length) { |
22 | | /* check that the match length is valid*/ |
23 | | if (length < STD_MIN_MATCH || length > STD_MAX_MATCH) { |
24 | | fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); |
25 | | z_error("invalid match length"); |
26 | | } |
27 | | /* check that the match isn't at the same position as the start string */ |
28 | | if (match == start) { |
29 | | fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); |
30 | | z_error("invalid match position"); |
31 | | } |
32 | | /* check that the match is indeed a match */ |
33 | | if (memcmp(s->window + match, s->window + start, length) != 0) { |
34 | | int32_t i = 0; |
35 | | fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); |
36 | | do { |
37 | | fprintf(stderr, " %03d: match [%02x] start [%02x]\n", i++, |
38 | | s->window[match++], s->window[start++]); |
39 | | } while (--length != 0); |
40 | | z_error("invalid match"); |
41 | | } |
42 | | if (z_verbose > 1) { |
43 | | fprintf(stderr, "\\[%u,%d]", start-match, length); |
44 | | do { |
45 | | putc(s->window[start++], stderr); |
46 | | } while (--length != 0); |
47 | | } |
48 | | } |
49 | | #else |
50 | | #define check_match(s, start, match, length) |
51 | | #endif |
52 | | |
53 | | Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm); |
54 | | |
55 | | /* =========================================================================== |
56 | | * Save the match info and tally the frequency counts. Return true if |
57 | | * the current block must be flushed. |
58 | | */ |
59 | | |
60 | | extern const unsigned char Z_INTERNAL zng_length_code[]; |
61 | | extern const unsigned char Z_INTERNAL zng_dist_code[]; |
62 | | |
63 | 295M | static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { |
64 | | /* c is the unmatched char */ |
65 | 295M | #ifdef LIT_MEM |
66 | 295M | s->d_buf[s->sym_next] = 0; |
67 | 295M | s->l_buf[s->sym_next++] = c; |
68 | | #else |
69 | | s->sym_buf[s->sym_next++] = 0; |
70 | | s->sym_buf[s->sym_next++] = 0; |
71 | | s->sym_buf[s->sym_next++] = c; |
72 | | #endif |
73 | 295M | s->dyn_ltree[c].Freq++; |
74 | 295M | Tracevv((stderr, "%c", c)); |
75 | 295M | Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); |
76 | 295M | return (s->sym_next == s->sym_end); |
77 | 295M | } 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 | 63 | 197M | static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { | 64 | | /* c is the unmatched char */ | 65 | 197M | #ifdef LIT_MEM | 66 | 197M | s->d_buf[s->sym_next] = 0; | 67 | 197M | s->l_buf[s->sym_next++] = c; | 68 | | #else | 69 | | s->sym_buf[s->sym_next++] = 0; | 70 | | s->sym_buf[s->sym_next++] = 0; | 71 | | s->sym_buf[s->sym_next++] = c; | 72 | | #endif | 73 | 197M | s->dyn_ltree[c].Freq++; | 74 | 197M | Tracevv((stderr, "%c", c)); | 75 | 197M | Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); | 76 | 197M | return (s->sym_next == s->sym_end); | 77 | 197M | } |
Unexecuted instantiation: deflate_quick.c:zng_tr_tally_lit Unexecuted instantiation: deflate_rle.c:zng_tr_tally_lit deflate_slow.c:zng_tr_tally_lit Line | Count | Source | 63 | 98.2M | static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { | 64 | | /* c is the unmatched char */ | 65 | 98.2M | #ifdef LIT_MEM | 66 | 98.2M | s->d_buf[s->sym_next] = 0; | 67 | 98.2M | s->l_buf[s->sym_next++] = c; | 68 | | #else | 69 | | s->sym_buf[s->sym_next++] = 0; | 70 | | s->sym_buf[s->sym_next++] = 0; | 71 | | s->sym_buf[s->sym_next++] = c; | 72 | | #endif | 73 | 98.2M | s->dyn_ltree[c].Freq++; | 74 | 98.2M | Tracevv((stderr, "%c", c)); | 75 | 98.2M | Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); | 76 | 98.2M | return (s->sym_next == s->sym_end); | 77 | 98.2M | } |
Unexecuted instantiation: deflate_stored.c:zng_tr_tally_lit Unexecuted instantiation: trees.c:zng_tr_tally_lit |
78 | | |
79 | 11.2M | static inline int zng_tr_tally_dist(deflate_state* s, uint32_t dist, uint32_t len) { |
80 | | /* dist: distance of matched string */ |
81 | | /* len: match length-STD_MIN_MATCH */ |
82 | 11.2M | #ifdef LIT_MEM |
83 | 11.2M | Assert(dist <= UINT16_MAX, "dist should fit in uint16_t"); |
84 | 11.2M | Assert(len <= UINT8_MAX, "len should fit in uint8_t"); |
85 | 11.2M | s->d_buf[s->sym_next] = (uint16_t)dist; |
86 | 11.2M | s->l_buf[s->sym_next++] = (uint8_t)len; |
87 | | #else |
88 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist); |
89 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); |
90 | | s->sym_buf[s->sym_next++] = (uint8_t)len; |
91 | | #endif |
92 | 11.2M | s->matches++; |
93 | 11.2M | dist--; |
94 | 11.2M | Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, |
95 | 11.2M | "zng_tr_tally: bad match"); |
96 | | |
97 | 11.2M | s->dyn_ltree[zng_length_code[len] + LITERALS + 1].Freq++; |
98 | 11.2M | s->dyn_dtree[d_code(dist)].Freq++; |
99 | 11.2M | return (s->sym_next == s->sym_end); |
100 | 11.2M | } 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 | 79 | 7.85M | static inline int zng_tr_tally_dist(deflate_state* s, uint32_t dist, uint32_t len) { | 80 | | /* dist: distance of matched string */ | 81 | | /* len: match length-STD_MIN_MATCH */ | 82 | 7.85M | #ifdef LIT_MEM | 83 | 7.85M | Assert(dist <= UINT16_MAX, "dist should fit in uint16_t"); | 84 | 7.85M | Assert(len <= UINT8_MAX, "len should fit in uint8_t"); | 85 | 7.85M | s->d_buf[s->sym_next] = (uint16_t)dist; | 86 | 7.85M | s->l_buf[s->sym_next++] = (uint8_t)len; | 87 | | #else | 88 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist); | 89 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); | 90 | | s->sym_buf[s->sym_next++] = (uint8_t)len; | 91 | | #endif | 92 | 7.85M | s->matches++; | 93 | 7.85M | dist--; | 94 | 7.85M | Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, | 95 | 7.85M | "zng_tr_tally: bad match"); | 96 | | | 97 | 7.85M | s->dyn_ltree[zng_length_code[len] + LITERALS + 1].Freq++; | 98 | 7.85M | s->dyn_dtree[d_code(dist)].Freq++; | 99 | 7.85M | return (s->sym_next == s->sym_end); | 100 | 7.85M | } |
Unexecuted instantiation: deflate_quick.c:zng_tr_tally_dist Unexecuted instantiation: deflate_rle.c:zng_tr_tally_dist deflate_slow.c:zng_tr_tally_dist Line | Count | Source | 79 | 3.36M | static inline int zng_tr_tally_dist(deflate_state* s, uint32_t dist, uint32_t len) { | 80 | | /* dist: distance of matched string */ | 81 | | /* len: match length-STD_MIN_MATCH */ | 82 | 3.36M | #ifdef LIT_MEM | 83 | 3.36M | Assert(dist <= UINT16_MAX, "dist should fit in uint16_t"); | 84 | 3.36M | Assert(len <= UINT8_MAX, "len should fit in uint8_t"); | 85 | 3.36M | s->d_buf[s->sym_next] = (uint16_t)dist; | 86 | 3.36M | s->l_buf[s->sym_next++] = (uint8_t)len; | 87 | | #else | 88 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist); | 89 | | s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); | 90 | | s->sym_buf[s->sym_next++] = (uint8_t)len; | 91 | | #endif | 92 | 3.36M | s->matches++; | 93 | 3.36M | dist--; | 94 | 3.36M | Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, | 95 | 3.36M | "zng_tr_tally: bad match"); | 96 | | | 97 | 3.36M | s->dyn_ltree[zng_length_code[len] + LITERALS + 1].Freq++; | 98 | 3.36M | s->dyn_dtree[d_code(dist)].Freq++; | 99 | 3.36M | return (s->sym_next == s->sym_end); | 100 | 3.36M | } |
Unexecuted instantiation: deflate_stored.c:zng_tr_tally_dist Unexecuted instantiation: trees.c:zng_tr_tally_dist |
101 | | |
102 | | /* ========================================================================= |
103 | | * Flush as much pending output as possible. All deflate() output, except for some |
104 | | * deflate_stored() output, goes through this function so some applications may wish to |
105 | | * modify it to avoid allocating a large strm->next_out buffer and copying into it. |
106 | | * See also read_buf(). |
107 | | */ |
108 | 67.7k | Z_FORCEINLINE static void flush_pending_inline(PREFIX3(stream) *strm) { |
109 | 67.7k | uint32_t len; |
110 | 67.7k | deflate_state *s = strm->state; |
111 | | |
112 | 67.7k | zng_tr_flush_bits(s); |
113 | 67.7k | len = MIN(s->pending, strm->avail_out); |
114 | 67.7k | if (len == 0) |
115 | 0 | return; |
116 | | |
117 | 67.7k | Tracev((stderr, "[FLUSH]")); |
118 | 67.7k | memcpy(strm->next_out, s->pending_out, len); |
119 | 67.7k | strm->next_out += len; |
120 | 67.7k | s->pending_out += len; |
121 | 67.7k | strm->total_out += len; |
122 | 67.7k | strm->avail_out -= len; |
123 | 67.7k | s->pending -= len; |
124 | 67.7k | if (s->pending == 0) |
125 | 67.7k | s->pending_out = s->pending_buf; |
126 | 67.7k | } deflate.c:flush_pending_inline Line | Count | Source | 108 | 67.7k | Z_FORCEINLINE static void flush_pending_inline(PREFIX3(stream) *strm) { | 109 | 67.7k | uint32_t len; | 110 | 67.7k | deflate_state *s = strm->state; | 111 | | | 112 | 67.7k | zng_tr_flush_bits(s); | 113 | 67.7k | len = MIN(s->pending, strm->avail_out); | 114 | 67.7k | if (len == 0) | 115 | 0 | return; | 116 | | | 117 | 67.7k | Tracev((stderr, "[FLUSH]")); | 118 | 67.7k | memcpy(strm->next_out, s->pending_out, len); | 119 | 67.7k | strm->next_out += len; | 120 | 67.7k | s->pending_out += len; | 121 | 67.7k | strm->total_out += len; | 122 | 67.7k | strm->avail_out -= len; | 123 | 67.7k | s->pending -= len; | 124 | 67.7k | if (s->pending == 0) | 125 | 67.7k | s->pending_out = s->pending_buf; | 126 | 67.7k | } |
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 |
127 | | |
128 | | /* =========================================================================== |
129 | | * Reverse the first len bits of a code using bit manipulation |
130 | | */ |
131 | 5.64M | Z_FORCEINLINE static uint16_t bi_reverse(uint16_t code, int len) { |
132 | | /* code: the value to invert */ |
133 | | /* len: its bit length */ |
134 | 5.64M | Assert(len >= 1 && len <= 15, "code length must be 1-15"); |
135 | 5.64M | return __builtin_bitreverse16(code) >> (16 - len); |
136 | 5.64M | } 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 | 131 | 5.64M | Z_FORCEINLINE static uint16_t bi_reverse(uint16_t code, int len) { | 132 | | /* code: the value to invert */ | 133 | | /* len: its bit length */ | 134 | 5.64M | Assert(len >= 1 && len <= 15, "code length must be 1-15"); | 135 | 5.64M | return __builtin_bitreverse16(code) >> (16 - len); | 136 | 5.64M | } |
|
137 | | |
138 | | /* =========================================================================== |
139 | | * Read a new buffer from the current input stream, update the adler32 and total number of |
140 | | * bytes read. All deflate() input goes through this function so some applications may wish |
141 | | * to modify it to avoid allocating a large strm->next_in buffer and copying from it. |
142 | | * See also flush_pending_inline(). |
143 | | */ |
144 | 35.3k | Z_FORCEINLINE static unsigned read_buf(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { |
145 | 35.3k | deflate_state *s = strm->state; |
146 | 35.3k | uint32_t len = MIN(strm->avail_in, size); |
147 | | |
148 | 35.3k | if (len == 0) |
149 | 0 | return 0; |
150 | | |
151 | 35.3k | if (!DEFLATE_NEED_CHECKSUM(strm)) { |
152 | 0 | memcpy(buf, strm->next_in, len); |
153 | 0 | #ifdef GZIP |
154 | 35.3k | } else if (s->wrap == 2) { |
155 | 0 | FUNCTABLE_CALL(crc32_fold_copy)(&s->crc_fold, buf, strm->next_in, len); |
156 | 0 | #endif |
157 | 35.3k | } else if (s->wrap == 1) { |
158 | 35.3k | strm->adler = FUNCTABLE_CALL(adler32_copy)(strm->adler, buf, strm->next_in, len); |
159 | 35.3k | } else { |
160 | 0 | memcpy(buf, strm->next_in, len); |
161 | 0 | } |
162 | | |
163 | 35.3k | strm->avail_in -= len; |
164 | 35.3k | strm->next_in += len; |
165 | 35.3k | strm->total_in += len; |
166 | 35.3k | return len; |
167 | 35.3k | } Line | Count | Source | 144 | 35.3k | Z_FORCEINLINE static unsigned read_buf(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { | 145 | 35.3k | deflate_state *s = strm->state; | 146 | 35.3k | uint32_t len = MIN(strm->avail_in, size); | 147 | | | 148 | 35.3k | if (len == 0) | 149 | 0 | return 0; | 150 | | | 151 | 35.3k | if (!DEFLATE_NEED_CHECKSUM(strm)) { | 152 | 0 | memcpy(buf, strm->next_in, len); | 153 | 0 | #ifdef GZIP | 154 | 35.3k | } else if (s->wrap == 2) { | 155 | 0 | FUNCTABLE_CALL(crc32_fold_copy)(&s->crc_fold, buf, strm->next_in, len); | 156 | 0 | #endif | 157 | 35.3k | } else if (s->wrap == 1) { | 158 | 35.3k | strm->adler = FUNCTABLE_CALL(adler32_copy)(strm->adler, buf, strm->next_in, len); | 159 | 35.3k | } else { | 160 | 0 | memcpy(buf, strm->next_in, len); | 161 | 0 | } | 162 | | | 163 | 35.3k | strm->avail_in -= len; | 164 | 35.3k | strm->next_in += len; | 165 | 35.3k | strm->total_in += len; | 166 | 35.3k | return len; | 167 | 35.3k | } |
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 |
168 | | |
169 | | /* =========================================================================== |
170 | | * Flush the current block, with given end-of-file flag. |
171 | | * IN assertion: strstart is set to the end of the current match. |
172 | | */ |
173 | 29.9k | #define FLUSH_BLOCK_ONLY(s, last) { \ |
174 | 29.9k | zng_tr_flush_block(s, (s->block_start >= 0 ? \ |
175 | 29.9k | (char *)&s->window[(unsigned)s->block_start] : \ |
176 | 29.9k | NULL), \ |
177 | 29.9k | (uint32_t)((int)s->strstart - s->block_start), \ |
178 | 29.9k | (last)); \ |
179 | 29.9k | s->block_start = (int)s->strstart; \ |
180 | 29.9k | PREFIX(flush_pending)(s->strm); \ |
181 | 29.9k | } |
182 | | |
183 | | /* Same but force premature exit if necessary. */ |
184 | 24.3k | #define FLUSH_BLOCK(s, last) { \ |
185 | 24.3k | FLUSH_BLOCK_ONLY(s, last); \ |
186 | 24.3k | if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ |
187 | 24.3k | } |
188 | | |
189 | | /* Maximum stored block length in deflate format (not including header). */ |
190 | 0 | #define MAX_STORED 65535 |
191 | | |
192 | | /* Compression function. Returns the block state after the call. */ |
193 | | typedef block_state (*compress_func) (deflate_state *s, int flush); |
194 | | /* Match function. Returns the longest match. */ |
195 | | typedef uint32_t (*match_func) (deflate_state *const s, uint32_t cur_match); |
196 | | |
197 | | #endif |