Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/zlib/inffast.c

Issue 8806004: Update zlib to 1.2.5. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/zlib/inffast.h ('k') | third_party/zlib/inflate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* inffast.c -- fast decoding 1 /* inffast.c -- fast decoding
2 * Copyright (C) 1995-2004 Mark Adler 2 * Copyright (C) 1995-2008, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6 #include "zutil.h" 6 #include "zutil.h"
7 #include "inftrees.h" 7 #include "inftrees.h"
8 #include "inflate.h" 8 #include "inflate.h"
9 #include "inffast.h" 9 #include "inffast.h"
10 10
11 #ifndef ASMINF 11 #ifndef ASMINF
12 12
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 length code, 5 bits for the length extra, 15 bits for the distance code, 57 length code, 5 bits for the length extra, 15 bits for the distance code,
58 and 13 bits for the distance extra. This totals 48 bits, or six bytes. 58 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
59 Therefore if strm->avail_in >= 6, then there is enough input to avoid 59 Therefore if strm->avail_in >= 6, then there is enough input to avoid
60 checking for available input while decoding. 60 checking for available input while decoding.
61 61
62 - The maximum bytes that a single length/distance pair can output is 258 62 - The maximum bytes that a single length/distance pair can output is 258
63 bytes, which is the maximum length that can be coded. inflate_fast() 63 bytes, which is the maximum length that can be coded. inflate_fast()
64 requires strm->avail_out >= 258 for each loop to avoid checking for 64 requires strm->avail_out >= 258 for each loop to avoid checking for
65 output space. 65 output space.
66 */ 66 */
67 void inflate_fast(strm, start) 67 void ZLIB_INTERNAL inflate_fast(strm, start)
68 z_streamp strm; 68 z_streamp strm;
69 unsigned start; /* inflate()'s starting value for strm->avail_out */ 69 unsigned start; /* inflate()'s starting value for strm->avail_out */
70 { 70 {
71 struct inflate_state FAR *state; 71 struct inflate_state FAR *state;
72 unsigned char FAR *in; /* local strm->next_in */ 72 unsigned char FAR *in; /* local strm->next_in */
73 unsigned char FAR *last; /* while in < last, enough input available */ 73 unsigned char FAR *last; /* while in < last, enough input available */
74 unsigned char FAR *out; /* local strm->next_out */ 74 unsigned char FAR *out; /* local strm->next_out */
75 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ 75 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
76 unsigned char FAR *end; /* while out < end, enough space available */ 76 unsigned char FAR *end; /* while out < end, enough space available */
77 #ifdef INFLATE_STRICT 77 #ifdef INFLATE_STRICT
78 unsigned dmax; /* maximum distance from zlib header */ 78 unsigned dmax; /* maximum distance from zlib header */
79 #endif 79 #endif
80 unsigned wsize; /* window size or zero if not using window */ 80 unsigned wsize; /* window size or zero if not using window */
81 unsigned whave; /* valid bytes in the window */ 81 unsigned whave; /* valid bytes in the window */
82 unsigned write; /* window write index */ 82 unsigned wnext; /* window write index */
83 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ 83 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
84 unsigned long hold; /* local strm->hold */ 84 unsigned long hold; /* local strm->hold */
85 unsigned bits; /* local strm->bits */ 85 unsigned bits; /* local strm->bits */
86 code const FAR *lcode; /* local strm->lencode */ 86 code const FAR *lcode; /* local strm->lencode */
87 code const FAR *dcode; /* local strm->distcode */ 87 code const FAR *dcode; /* local strm->distcode */
88 unsigned lmask; /* mask for first level of length codes */ 88 unsigned lmask; /* mask for first level of length codes */
89 unsigned dmask; /* mask for first level of distance codes */ 89 unsigned dmask; /* mask for first level of distance codes */
90 code this; /* retrieved table entry */ 90 code here; /* retrieved table entry */
91 unsigned op; /* code bits, operation, extra bits, or */ 91 unsigned op; /* code bits, operation, extra bits, or */
92 /* window position, window bytes to copy */ 92 /* window position, window bytes to copy */
93 unsigned len; /* match length, unused bytes */ 93 unsigned len; /* match length, unused bytes */
94 unsigned dist; /* match distance */ 94 unsigned dist; /* match distance */
95 unsigned char FAR *from; /* where to copy match from */ 95 unsigned char FAR *from; /* where to copy match from */
96 96
97 /* copy state to local variables */ 97 /* copy state to local variables */
98 state = (struct inflate_state FAR *)strm->state; 98 state = (struct inflate_state FAR *)strm->state;
99 in = strm->next_in - OFF; 99 in = strm->next_in - OFF;
100 last = in + (strm->avail_in - 5); 100 last = in + (strm->avail_in - 5);
101 out = strm->next_out - OFF; 101 out = strm->next_out - OFF;
102 beg = out - (start - strm->avail_out); 102 beg = out - (start - strm->avail_out);
103 end = out + (strm->avail_out - 257); 103 end = out + (strm->avail_out - 257);
104 #ifdef INFLATE_STRICT 104 #ifdef INFLATE_STRICT
105 dmax = state->dmax; 105 dmax = state->dmax;
106 #endif 106 #endif
107 wsize = state->wsize; 107 wsize = state->wsize;
108 whave = state->whave; 108 whave = state->whave;
109 write = state->write; 109 wnext = state->wnext;
110 window = state->window; 110 window = state->window;
111 hold = state->hold; 111 hold = state->hold;
112 bits = state->bits; 112 bits = state->bits;
113 lcode = state->lencode; 113 lcode = state->lencode;
114 dcode = state->distcode; 114 dcode = state->distcode;
115 lmask = (1U << state->lenbits) - 1; 115 lmask = (1U << state->lenbits) - 1;
116 dmask = (1U << state->distbits) - 1; 116 dmask = (1U << state->distbits) - 1;
117 117
118 /* decode literals and length/distances until end-of-block or not enough 118 /* decode literals and length/distances until end-of-block or not enough
119 input data or output space */ 119 input data or output space */
120 do { 120 do {
121 if (bits < 15) { 121 if (bits < 15) {
122 hold += (unsigned long)(PUP(in)) << bits; 122 hold += (unsigned long)(PUP(in)) << bits;
123 bits += 8; 123 bits += 8;
124 hold += (unsigned long)(PUP(in)) << bits; 124 hold += (unsigned long)(PUP(in)) << bits;
125 bits += 8; 125 bits += 8;
126 } 126 }
127 this = lcode[hold & lmask]; 127 here = lcode[hold & lmask];
128 dolen: 128 dolen:
129 op = (unsigned)(this.bits); 129 op = (unsigned)(here.bits);
130 hold >>= op; 130 hold >>= op;
131 bits -= op; 131 bits -= op;
132 op = (unsigned)(this.op); 132 op = (unsigned)(here.op);
133 if (op == 0) { /* literal */ 133 if (op == 0) { /* literal */
134 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? 134 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
135 "inflate: literal '%c'\n" : 135 "inflate: literal '%c'\n" :
136 "inflate: literal 0x%02x\n", this.val)); 136 "inflate: literal 0x%02x\n", here.val));
137 PUP(out) = (unsigned char)(this.val); 137 PUP(out) = (unsigned char)(here.val);
138 } 138 }
139 else if (op & 16) { /* length base */ 139 else if (op & 16) { /* length base */
140 len = (unsigned)(this.val); 140 len = (unsigned)(here.val);
141 op &= 15; /* number of extra bits */ 141 op &= 15; /* number of extra bits */
142 if (op) { 142 if (op) {
143 if (bits < op) { 143 if (bits < op) {
144 hold += (unsigned long)(PUP(in)) << bits; 144 hold += (unsigned long)(PUP(in)) << bits;
145 bits += 8; 145 bits += 8;
146 } 146 }
147 len += (unsigned)hold & ((1U << op) - 1); 147 len += (unsigned)hold & ((1U << op) - 1);
148 hold >>= op; 148 hold >>= op;
149 bits -= op; 149 bits -= op;
150 } 150 }
151 Tracevv((stderr, "inflate: length %u\n", len)); 151 Tracevv((stderr, "inflate: length %u\n", len));
152 if (bits < 15) { 152 if (bits < 15) {
153 hold += (unsigned long)(PUP(in)) << bits; 153 hold += (unsigned long)(PUP(in)) << bits;
154 bits += 8; 154 bits += 8;
155 hold += (unsigned long)(PUP(in)) << bits; 155 hold += (unsigned long)(PUP(in)) << bits;
156 bits += 8; 156 bits += 8;
157 } 157 }
158 this = dcode[hold & dmask]; 158 here = dcode[hold & dmask];
159 dodist: 159 dodist:
160 op = (unsigned)(this.bits); 160 op = (unsigned)(here.bits);
161 hold >>= op; 161 hold >>= op;
162 bits -= op; 162 bits -= op;
163 op = (unsigned)(this.op); 163 op = (unsigned)(here.op);
164 if (op & 16) { /* distance base */ 164 if (op & 16) { /* distance base */
165 dist = (unsigned)(this.val); 165 dist = (unsigned)(here.val);
166 op &= 15; /* number of extra bits */ 166 op &= 15; /* number of extra bits */
167 if (bits < op) { 167 if (bits < op) {
168 hold += (unsigned long)(PUP(in)) << bits; 168 hold += (unsigned long)(PUP(in)) << bits;
169 bits += 8; 169 bits += 8;
170 if (bits < op) { 170 if (bits < op) {
171 hold += (unsigned long)(PUP(in)) << bits; 171 hold += (unsigned long)(PUP(in)) << bits;
172 bits += 8; 172 bits += 8;
173 } 173 }
174 } 174 }
175 dist += (unsigned)hold & ((1U << op) - 1); 175 dist += (unsigned)hold & ((1U << op) - 1);
176 #ifdef INFLATE_STRICT 176 #ifdef INFLATE_STRICT
177 if (dist > dmax) { 177 if (dist > dmax) {
178 strm->msg = (char *)"invalid distance too far back"; 178 strm->msg = (char *)"invalid distance too far back";
179 state->mode = BAD; 179 state->mode = BAD;
180 break; 180 break;
181 } 181 }
182 #endif 182 #endif
183 hold >>= op; 183 hold >>= op;
184 bits -= op; 184 bits -= op;
185 Tracevv((stderr, "inflate: distance %u\n", dist)); 185 Tracevv((stderr, "inflate: distance %u\n", dist));
186 op = (unsigned)(out - beg); /* max distance in output */ 186 op = (unsigned)(out - beg); /* max distance in output */
187 if (dist > op) { /* see if copy from window */ 187 if (dist > op) { /* see if copy from window */
188 op = dist - op; /* distance back in window */ 188 op = dist - op; /* distance back in window */
189 if (op > whave) { 189 if (op > whave) {
190 strm->msg = (char *)"invalid distance too far back"; 190 if (state->sane) {
191 state->mode = BAD; 191 strm->msg =
192 break; 192 (char *)"invalid distance too far back";
193 state->mode = BAD;
194 break;
195 }
196 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
197 if (len <= op - whave) {
198 do {
199 PUP(out) = 0;
200 } while (--len);
201 continue;
202 }
203 len -= op - whave;
204 do {
205 PUP(out) = 0;
206 } while (--op > whave);
207 if (op == 0) {
208 from = out - dist;
209 do {
210 PUP(out) = PUP(from);
211 } while (--len);
212 continue;
213 }
214 #endif
193 } 215 }
194 from = window - OFF; 216 from = window - OFF;
195 if (write == 0) { /* very common case */ 217 if (wnext == 0) { /* very common case */
196 from += wsize - op; 218 from += wsize - op;
197 if (op < len) { /* some from window */ 219 if (op < len) { /* some from window */
198 len -= op; 220 len -= op;
199 do { 221 do {
200 PUP(out) = PUP(from); 222 PUP(out) = PUP(from);
201 } while (--op); 223 } while (--op);
202 from = out - dist; /* rest from output */ 224 from = out - dist; /* rest from output */
203 } 225 }
204 } 226 }
205 else if (write < op) { /* wrap around window */ 227 else if (wnext < op) { /* wrap around window */
206 from += wsize + write - op; 228 from += wsize + wnext - op;
207 op -= write; 229 op -= wnext;
208 if (op < len) { /* some from end of window */ 230 if (op < len) { /* some from end of window */
209 len -= op; 231 len -= op;
210 do { 232 do {
211 PUP(out) = PUP(from); 233 PUP(out) = PUP(from);
212 } while (--op); 234 } while (--op);
213 from = window - OFF; 235 from = window - OFF;
214 if (write < len) { /* some from start of window */ 236 if (wnext < len) { /* some from start of window */
215 op = write; 237 op = wnext;
216 len -= op; 238 len -= op;
217 do { 239 do {
218 PUP(out) = PUP(from); 240 PUP(out) = PUP(from);
219 } while (--op); 241 } while (--op);
220 from = out - dist; /* rest from output */ 242 from = out - dist; /* rest from output */
221 } 243 }
222 } 244 }
223 } 245 }
224 else { /* contiguous in window */ 246 else { /* contiguous in window */
225 from += write - op; 247 from += wnext - op;
226 if (op < len) { /* some from window */ 248 if (op < len) { /* some from window */
227 len -= op; 249 len -= op;
228 do { 250 do {
229 PUP(out) = PUP(from); 251 PUP(out) = PUP(from);
230 } while (--op); 252 } while (--op);
231 from = out - dist; /* rest from output */ 253 from = out - dist; /* rest from output */
232 } 254 }
233 } 255 }
234 while (len > 2) { 256 while (len > 2) {
235 PUP(out) = PUP(from); 257 PUP(out) = PUP(from);
(...skipping 16 matching lines...) Expand all
252 len -= 3; 274 len -= 3;
253 } while (len > 2); 275 } while (len > 2);
254 if (len) { 276 if (len) {
255 PUP(out) = PUP(from); 277 PUP(out) = PUP(from);
256 if (len > 1) 278 if (len > 1)
257 PUP(out) = PUP(from); 279 PUP(out) = PUP(from);
258 } 280 }
259 } 281 }
260 } 282 }
261 else if ((op & 64) == 0) { /* 2nd level distance code */ 283 else if ((op & 64) == 0) { /* 2nd level distance code */
262 this = dcode[this.val + (hold & ((1U << op) - 1))]; 284 here = dcode[here.val + (hold & ((1U << op) - 1))];
263 goto dodist; 285 goto dodist;
264 } 286 }
265 else { 287 else {
266 strm->msg = (char *)"invalid distance code"; 288 strm->msg = (char *)"invalid distance code";
267 state->mode = BAD; 289 state->mode = BAD;
268 break; 290 break;
269 } 291 }
270 } 292 }
271 else if ((op & 64) == 0) { /* 2nd level length code */ 293 else if ((op & 64) == 0) { /* 2nd level length code */
272 this = lcode[this.val + (hold & ((1U << op) - 1))]; 294 here = lcode[here.val + (hold & ((1U << op) - 1))];
273 goto dolen; 295 goto dolen;
274 } 296 }
275 else if (op & 32) { /* end-of-block */ 297 else if (op & 32) { /* end-of-block */
276 Tracevv((stderr, "inflate: end of block\n")); 298 Tracevv((stderr, "inflate: end of block\n"));
277 state->mode = TYPE; 299 state->mode = TYPE;
278 break; 300 break;
279 } 301 }
280 else { 302 else {
281 strm->msg = (char *)"invalid literal/length code"; 303 strm->msg = (char *)"invalid literal/length code";
282 state->mode = BAD; 304 state->mode = BAD;
(...skipping 15 matching lines...) Expand all
298 257 + (end - out) : 257 - (out - end)); 320 257 + (end - out) : 257 - (out - end));
299 state->hold = hold; 321 state->hold = hold;
300 state->bits = bits; 322 state->bits = bits;
301 return; 323 return;
302 } 324 }
303 325
304 /* 326 /*
305 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): 327 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
306 - Using bit fields for code structure 328 - Using bit fields for code structure
307 - Different op definition to avoid & for extra bits (do & for table bits) 329 - Different op definition to avoid & for extra bits (do & for table bits)
308 - Three separate decoding do-loops for direct, window, and write == 0 330 - Three separate decoding do-loops for direct, window, and wnext == 0
309 - Special case for distance > 1 copies to do overlapped load and store copy 331 - Special case for distance > 1 copies to do overlapped load and store copy
310 - Explicit branch predictions (based on measured branch probabilities) 332 - Explicit branch predictions (based on measured branch probabilities)
311 - Deferring match copy and interspersed it with decoding subsequent codes 333 - Deferring match copy and interspersed it with decoding subsequent codes
312 - Swapping literal/length else 334 - Swapping literal/length else
313 - Swapping window/direct else 335 - Swapping window/direct else
314 - Larger unrolled copy loops (three is about right) 336 - Larger unrolled copy loops (three is about right)
315 - Moving len -= 3 statement into middle of loop 337 - Moving len -= 3 statement into middle of loop
316 */ 338 */
317 339
318 #endif /* !ASMINF */ 340 #endif /* !ASMINF */
OLDNEW
« no previous file with comments | « third_party/zlib/inffast.h ('k') | third_party/zlib/inflate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698