Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
inffast.h File Reference

Go to the source code of this file.

Functions

void ZLIB_INTERNAL inflate_fast (z_streamp strm, unsigned start)

Function Documentation

◆ inflate_fast()

void ZLIB_INTERNAL inflate_fast ( z_streamp strm,
unsigned start )

Definition at line 50 of file inffast.c.

50 {
51 struct inflate_state FAR *state;
52 z_const unsigned char FAR *in; /* local strm->next_in */
53 z_const unsigned char FAR *last; /* have enough input while in < last */
54 unsigned char FAR *out; /* local strm->next_out */
55 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
56 unsigned char FAR *end; /* while out < end, enough space available */
57#ifdef INFLATE_STRICT
58 unsigned dmax; /* maximum distance from zlib header */
59#endif
60 unsigned wsize; /* window size or zero if not using window */
61 unsigned whave; /* valid bytes in the window */
62 unsigned wnext; /* window write index */
63 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
64 unsigned long hold; /* local strm->hold */
65 unsigned bits; /* local strm->bits */
66 code const FAR *lcode; /* local strm->lencode */
67 code const FAR *dcode; /* local strm->distcode */
68 unsigned lmask; /* mask for first level of length codes */
69 unsigned dmask; /* mask for first level of distance codes */
70 code const *here; /* retrieved table entry */
71 unsigned op; /* code bits, operation, extra bits, or */
72 /* window position, window bytes to copy */
73 unsigned len; /* match length, unused bytes */
74 unsigned dist; /* match distance */
75 unsigned char FAR *from; /* where to copy match from */
76
77 /* copy state to local variables */
78 state = (struct inflate_state FAR *)strm->state;
79 in = strm->next_in;
80 last = in + (strm->avail_in - 5);
81 out = strm->next_out;
82 beg = out - (start - strm->avail_out);
83 end = out + (strm->avail_out - 257);
84#ifdef INFLATE_STRICT
85 dmax = state->dmax;
86#endif
87 wsize = state->wsize;
88 whave = state->whave;
89 wnext = state->wnext;
90 window = state->window;
91 hold = state->hold;
92 bits = state->bits;
93 lcode = state->lencode;
94 dcode = state->distcode;
95 lmask = (1U << state->lenbits) - 1;
96 dmask = (1U << state->distbits) - 1;
97
98 /* decode literals and length/distances until end-of-block or not enough
99 input data or output space */
100 do {
101 if (bits < 15) {
102 hold += (unsigned long)(*in++) << bits;
103 bits += 8;
104 hold += (unsigned long)(*in++) << bits;
105 bits += 8;
106 }
107 here = lcode + (hold & lmask);
108 dolen:
109 op = (unsigned)(here->bits);
110 hold >>= op;
111 bits -= op;
112 op = (unsigned)(here->op);
113 if (op == 0) { /* literal */
114 Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
115 "inflate: literal '%c'\n" :
116 "inflate: literal 0x%02x\n", here->val));
117 *out++ = (unsigned char)(here->val);
118 }
119 else if (op & 16) { /* length base */
120 len = (unsigned)(here->val);
121 op &= 15; /* number of extra bits */
122 if (op) {
123 if (bits < op) {
124 hold += (unsigned long)(*in++) << bits;
125 bits += 8;
126 }
127 len += (unsigned)hold & ((1U << op) - 1);
128 hold >>= op;
129 bits -= op;
130 }
131 Tracevv((stderr, "inflate: length %u\n", len));
132 if (bits < 15) {
133 hold += (unsigned long)(*in++) << bits;
134 bits += 8;
135 hold += (unsigned long)(*in++) << bits;
136 bits += 8;
137 }
138 here = dcode + (hold & dmask);
139 dodist:
140 op = (unsigned)(here->bits);
141 hold >>= op;
142 bits -= op;
143 op = (unsigned)(here->op);
144 if (op & 16) { /* distance base */
145 dist = (unsigned)(here->val);
146 op &= 15; /* number of extra bits */
147 if (bits < op) {
148 hold += (unsigned long)(*in++) << bits;
149 bits += 8;
150 if (bits < op) {
151 hold += (unsigned long)(*in++) << bits;
152 bits += 8;
153 }
154 }
155 dist += (unsigned)hold & ((1U << op) - 1);
156#ifdef INFLATE_STRICT
157 if (dist > dmax) {
158 strm->msg = (char *)"invalid distance too far back";
159 state->mode = BAD;
160 break;
161 }
162#endif
163 hold >>= op;
164 bits -= op;
165 Tracevv((stderr, "inflate: distance %u\n", dist));
166 op = (unsigned)(out - beg); /* max distance in output */
167 if (dist > op) { /* see if copy from window */
168 op = dist - op; /* distance back in window */
169 if (op > whave) {
170 if (state->sane) {
171 strm->msg =
172 (char *)"invalid distance too far back";
173 state->mode = BAD;
174 break;
175 }
176#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
177 if (len <= op - whave) {
178 do {
179 *out++ = 0;
180 } while (--len);
181 continue;
182 }
183 len -= op - whave;
184 do {
185 *out++ = 0;
186 } while (--op > whave);
187 if (op == 0) {
188 from = out - dist;
189 do {
190 *out++ = *from++;
191 } while (--len);
192 continue;
193 }
194#endif
195 }
196 from = window;
197 if (wnext == 0) { /* very common case */
198 from += wsize - op;
199 if (op < len) { /* some from window */
200 len -= op;
201 do {
202 *out++ = *from++;
203 } while (--op);
204 from = out - dist; /* rest from output */
205 }
206 }
207 else if (wnext < op) { /* wrap around window */
208 from += wsize + wnext - op;
209 op -= wnext;
210 if (op < len) { /* some from end of window */
211 len -= op;
212 do {
213 *out++ = *from++;
214 } while (--op);
215 from = window;
216 if (wnext < len) { /* some from start of window */
217 op = wnext;
218 len -= op;
219 do {
220 *out++ = *from++;
221 } while (--op);
222 from = out - dist; /* rest from output */
223 }
224 }
225 }
226 else { /* contiguous in window */
227 from += wnext - op;
228 if (op < len) { /* some from window */
229 len -= op;
230 do {
231 *out++ = *from++;
232 } while (--op);
233 from = out - dist; /* rest from output */
234 }
235 }
236 while (len > 2) {
237 *out++ = *from++;
238 *out++ = *from++;
239 *out++ = *from++;
240 len -= 3;
241 }
242 if (len) {
243 *out++ = *from++;
244 if (len > 1)
245 *out++ = *from++;
246 }
247 }
248 else {
249 from = out - dist; /* copy direct from output */
250 do { /* minimum length is three */
251 *out++ = *from++;
252 *out++ = *from++;
253 *out++ = *from++;
254 len -= 3;
255 } while (len > 2);
256 if (len) {
257 *out++ = *from++;
258 if (len > 1)
259 *out++ = *from++;
260 }
261 }
262 }
263 else if ((op & 64) == 0) { /* 2nd level distance code */
264 here = dcode + here->val + (hold & ((1U << op) - 1));
265 goto dodist;
266 }
267 else {
268 strm->msg = (char *)"invalid distance code";
269 state->mode = BAD;
270 break;
271 }
272 }
273 else if ((op & 64) == 0) { /* 2nd level length code */
274 here = lcode + here->val + (hold & ((1U << op) - 1));
275 goto dolen;
276 }
277 else if (op & 32) { /* end-of-block */
278 Tracevv((stderr, "inflate: end of block\n"));
279 state->mode = TYPE;
280 break;
281 }
282 else {
283 strm->msg = (char *)"invalid literal/length code";
284 state->mode = BAD;
285 break;
286 }
287 } while (in < last && out < end);
288
289 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
290 len = bits >> 3;
291 in -= len;
292 bits -= len << 3;
293 hold &= (1U << bits) - 1;
294
295 /* update state and return */
296 strm->next_in = in;
297 strm->next_out = out;
298 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
299 strm->avail_out = (unsigned)(out < end ?
300 257 + (end - out) : 257 - (out - end));
301 state->hold = hold;
302 state->bits = bits;
303 return;
304}
@ TYPE
Definition inflate.h:32
@ BAD
Definition inflate.h:50
unsigned wnext
Definition inflate.h:99
unsigned long hold
Definition inflate.h:102
z_streamp strm
Definition inflate.h:83
unsigned whave
Definition inflate.h:98
unsigned char FAR * window
Definition inflate.h:100
unsigned bits
Definition inflate.h:103
unsigned wsize
Definition inflate.h:97
unsigned dmax
Definition inflate.h:91
#define Tracevv(x)
Definition zutil.h:230

Referenced by inflate(), and inflateBack().