FreeBSD/Linux Kernel Cross Reference
sys/lib/libz/inffast.c
1 /* $NetBSD: inffast.c,v 1.5 2003/03/18 20:00:48 mycroft Exp $ */
2
3 /* inffast.c -- process literals and length/distance pairs fast
4 * Copyright (C) 1995-2002 Mark Adler
5 * For conditions of distribution and use, see copyright notice in zlib.h
6 */
7
8 #include "zutil.h"
9 #include "inftrees.h"
10 #include "infblock.h"
11 #include "infcodes.h"
12 #include "infutil.h"
13 #include "inffast.h"
14
15 struct inflate_codes_state {int dummy;}; /* for buggy compilers */
16
17 /* simplify the use of the inflate_huft type with some defines */
18 #define exop word.what.Exop
19 #define bits word.what.Bits
20
21 /* macros for bit input with no checking and for returning unused bytes */
22 #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
23 #define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24
25 /* Called with number of bytes left to write in window at least 258
26 (the maximum string length) and number of input bytes available
27 at least ten. The ten bytes are six bytes for the longest length/
28 distance pair plus four bytes for overloading the bit buffer. */
29
30 int inflate_fast(bl, bd, tl, td, s, z)
31 uInt bl, bd;
32 const inflate_huft *tl;
33 const inflate_huft *td; /* need separate declaration for Borland C++ */
34 inflate_blocks_statef *s;
35 z_streamp z;
36 {
37 const inflate_huft *t;/* temporary pointer */
38 uInt e; /* extra bits or operation */
39 uLong b; /* bit buffer */
40 uInt k; /* bits in bit buffer */
41 Bytef *p; /* input data pointer */
42 uInt n; /* bytes available there */
43 Bytef *q; /* output window write pointer */
44 uInt m; /* bytes to end of window or read pointer */
45 uInt ml; /* mask for literal/length tree */
46 uInt md; /* mask for distance tree */
47 uInt c; /* bytes to copy */
48 uInt d; /* distance back to copy from */
49 Bytef *r; /* copy source pointer */
50
51 /* load input, output, bit values */
52 LOAD
53
54 /* initialize masks */
55 ml = inflate_mask[bl];
56 md = inflate_mask[bd];
57
58 /* do until not enough input or output space for fast loop */
59 do { /* assume called with m >= 258 && n >= 10 */
60 /* get literal/length code */
61 GRABBITS(20) /* max bits for literal/length code */
62 if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
63 {
64 DUMPBITS(t->bits)
65 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
66 "inflate: * literal '%c'\n" :
67 "inflate: * literal 0x%02x\n", t->base));
68 *q++ = (Byte)t->base;
69 m--;
70 continue;
71 }
72 do {
73 DUMPBITS(t->bits)
74 if (e & 16)
75 {
76 /* get extra bits for length */
77 e &= 15;
78 c = t->base + ((uInt)b & inflate_mask[e]);
79 DUMPBITS(e)
80 Tracevv((stderr, "inflate: * length %u\n", c));
81
82 /* decode distance base of block to copy */
83 GRABBITS(15); /* max bits for distance code */
84 e = (t = td + ((uInt)b & md))->exop;
85 do {
86 DUMPBITS(t->bits)
87 if (e & 16)
88 {
89 /* get extra bits to add to distance base */
90 e &= 15;
91 GRABBITS(e) /* get extra bits (up to 13) */
92 d = t->base + ((uInt)b & inflate_mask[e]);
93 DUMPBITS(e)
94 Tracevv((stderr, "inflate: * distance %u\n", d));
95
96 /* do the copy */
97 m -= c;
98 r = q - d;
99 if (r < s->window) /* wrap if needed */
100 {
101 do {
102 r += s->end - s->window; /* force pointer in window */
103 } while (r < s->window); /* covers invalid distances */
104 e = s->end - r;
105 if (c > e)
106 {
107 c -= e; /* wrapped copy */
108 do {
109 *q++ = *r++;
110 } while (--e);
111 r = s->window;
112 do {
113 *q++ = *r++;
114 } while (--c);
115 }
116 else /* normal copy */
117 {
118 *q++ = *r++; c--;
119 *q++ = *r++; c--;
120 do {
121 *q++ = *r++;
122 } while (--c);
123 }
124 }
125 else /* normal copy */
126 {
127 *q++ = *r++; c--;
128 *q++ = *r++; c--;
129 do {
130 *q++ = *r++;
131 } while (--c);
132 }
133 break;
134 }
135 else if ((e & 64) == 0)
136 {
137 t += t->base;
138 e = (t += ((uInt)b & inflate_mask[e]))->exop;
139 }
140 else
141 {
142 z->msg = (char*)"invalid distance code";
143 UNGRAB
144 UPDATE
145 return Z_DATA_ERROR;
146 }
147 } while (1);
148 break;
149 }
150 if ((e & 64) == 0)
151 {
152 t += t->base;
153 if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
154 {
155 DUMPBITS(t->bits)
156 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
157 "inflate: * literal '%c'\n" :
158 "inflate: * literal 0x%02x\n", t->base));
159 *q++ = (Byte)t->base;
160 m--;
161 break;
162 }
163 }
164 else if (e & 32)
165 {
166 Tracevv((stderr, "inflate: * end of block\n"));
167 UNGRAB
168 UPDATE
169 return Z_STREAM_END;
170 }
171 else
172 {
173 z->msg = (char*)"invalid literal/length code";
174 UNGRAB
175 UPDATE
176 return Z_DATA_ERROR;
177 }
178 } while (1);
179 } while (m >= 258 && n >= 10);
180
181 /* not enough input or output--restore pointers and return */
182 UNGRAB
183 UPDATE
184 return Z_OK;
185 }
Cache object: a2bfb836e96f5d284080bd79d662273d
|