diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
commit | bdde4e09d21edff02ea5093b7f6eccbf166b272f (patch) | |
tree | a64632a98a6bea6e5df864d6e5b6f2e51ea69c1c /infcodes.c | |
parent | 1c71d8b13b54f91ddec361d3053ecce26e6ff761 (diff) | |
download | zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.gz zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.bz2 zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.zip |
zlib 0.92v0.92
Diffstat (limited to 'infcodes.c')
-rw-r--r-- | infcodes.c | 184 |
1 files changed, 92 insertions, 92 deletions
@@ -19,38 +19,38 @@ | |||
19 | struct inflate_codes_state { | 19 | struct inflate_codes_state { |
20 | 20 | ||
21 | /* mode */ | 21 | /* mode */ |
22 | enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ | 22 | enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ |
23 | START, /* x: set up for LEN */ | 23 | START, /* x: set up for LEN */ |
24 | LEN, /* i: get length/literal/eob next */ | 24 | LEN, /* i: get length/literal/eob next */ |
25 | LENEXT, /* i: getting length extra (have base) */ | 25 | LENEXT, /* i: getting length extra (have base) */ |
26 | DIST, /* i: get distance next */ | 26 | DIST, /* i: get distance next */ |
27 | DISTEXT, /* i: getting distance extra */ | 27 | DISTEXT, /* i: getting distance extra */ |
28 | COPY, /* o: copying bytes in window, waiting for space */ | 28 | COPY, /* o: copying bytes in window, waiting for space */ |
29 | LIT, /* o: got literal, waiting for output space */ | 29 | LIT, /* o: got literal, waiting for output space */ |
30 | WASH, /* o: got eob, possibly still output waiting */ | 30 | WASH, /* o: got eob, possibly still output waiting */ |
31 | END, /* x: got eob and all data flushed */ | 31 | END, /* x: got eob and all data flushed */ |
32 | BADCODE} /* x: got error */ | 32 | BADCODE} /* x: got error */ |
33 | mode; /* current inflate_codes mode */ | 33 | mode; /* current inflate_codes mode */ |
34 | 34 | ||
35 | /* mode dependent information */ | 35 | /* mode dependent information */ |
36 | uInt len; | 36 | uInt len; |
37 | union { | 37 | union { |
38 | struct { | 38 | struct { |
39 | inflate_huft *tree; /* pointer into tree */ | 39 | inflate_huft *tree; /* pointer into tree */ |
40 | uInt need; /* bits needed */ | 40 | uInt need; /* bits needed */ |
41 | } code; /* if LEN or DIST, where in tree */ | 41 | } code; /* if LEN or DIST, where in tree */ |
42 | uInt lit; /* if LIT, literal */ | 42 | uInt lit; /* if LIT, literal */ |
43 | struct { | 43 | struct { |
44 | uInt get; /* bits to get for extra */ | 44 | uInt get; /* bits to get for extra */ |
45 | uInt dist; /* distance back to copy from */ | 45 | uInt dist; /* distance back to copy from */ |
46 | } copy; /* if EXT or COPY, where and how much */ | 46 | } copy; /* if EXT or COPY, where and how much */ |
47 | } sub; /* submode */ | 47 | } sub; /* submode */ |
48 | 48 | ||
49 | /* mode independent information */ | 49 | /* mode independent information */ |
50 | Byte lbits; /* ltree bits decoded per branch */ | 50 | Byte lbits; /* ltree bits decoded per branch */ |
51 | Byte dbits; /* dtree bits decoder per branch */ | 51 | Byte dbits; /* dtree bits decoder per branch */ |
52 | inflate_huft *ltree; /* literal/length/eob tree */ | 52 | inflate_huft *ltree; /* literal/length/eob tree */ |
53 | inflate_huft *dtree; /* distance tree */ | 53 | inflate_huft *dtree; /* distance tree */ |
54 | 54 | ||
55 | }; | 55 | }; |
56 | 56 | ||
@@ -81,79 +81,79 @@ struct inflate_blocks_state *s; | |||
81 | z_stream *z; | 81 | z_stream *z; |
82 | int r; | 82 | int r; |
83 | { | 83 | { |
84 | uInt j; /* temporary storage */ | 84 | uInt j; /* temporary storage */ |
85 | inflate_huft *t; /* temporary pointer */ | 85 | inflate_huft *t; /* temporary pointer */ |
86 | int e; /* extra bits or operation */ | 86 | int e; /* extra bits or operation */ |
87 | uLong b; /* bit buffer */ | 87 | uLong b; /* bit buffer */ |
88 | uInt k; /* bits in bit buffer */ | 88 | uInt k; /* bits in bit buffer */ |
89 | Byte *p; /* input data pointer */ | 89 | Byte *p; /* input data pointer */ |
90 | uInt n; /* bytes available there */ | 90 | uInt n; /* bytes available there */ |
91 | Byte *q; /* output window write pointer */ | 91 | Byte *q; /* output window write pointer */ |
92 | uInt m; /* bytes to end of window or read pointer */ | 92 | uInt m; /* bytes to end of window or read pointer */ |
93 | Byte *f; /* pointer to copy strings from */ | 93 | Byte *f; /* pointer to copy strings from */ |
94 | struct inflate_codes_state *c = s->sub.codes; /* codes state */ | 94 | struct inflate_codes_state *c = s->sub.codes; /* codes state */ |
95 | 95 | ||
96 | /* copy input/output information to locals (UPDATE macro restores) */ | 96 | /* copy input/output information to locals (UPDATE macro restores) */ |
97 | LOAD | 97 | LOAD |
98 | 98 | ||
99 | /* process input and output based on current state */ | 99 | /* process input and output based on current state */ |
100 | while (1) switch (c->mode) | 100 | while (1) switch (c->mode) |
101 | { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ | 101 | { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ |
102 | case START: /* x: set up for LEN */ | 102 | case START: /* x: set up for LEN */ |
103 | #ifndef SLOW | 103 | #ifndef SLOW |
104 | if (m >= 258 && n >= 10) | 104 | if (m >= 258 && n >= 10) |
105 | { | 105 | { |
106 | UPDATE | 106 | UPDATE |
107 | r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); | 107 | r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); |
108 | LOAD | 108 | LOAD |
109 | if (r != Z_OK) | 109 | if (r != Z_OK) |
110 | { | 110 | { |
111 | c->mode = r == Z_STREAM_END ? WASH : BADCODE; | 111 | c->mode = r == Z_STREAM_END ? WASH : BADCODE; |
112 | break; | 112 | break; |
113 | } | 113 | } |
114 | } | 114 | } |
115 | #endif /* !SLOW */ | 115 | #endif /* !SLOW */ |
116 | c->sub.code.need = c->lbits; | 116 | c->sub.code.need = c->lbits; |
117 | c->sub.code.tree = c->ltree; | 117 | c->sub.code.tree = c->ltree; |
118 | c->mode = LEN; | 118 | c->mode = LEN; |
119 | case LEN: /* i: get length/literal/eob next */ | 119 | case LEN: /* i: get length/literal/eob next */ |
120 | j = c->sub.code.need; | 120 | j = c->sub.code.need; |
121 | NEEDBITS(j) | 121 | NEEDBITS(j) |
122 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); | 122 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); |
123 | DUMPBITS(t->bits) | 123 | DUMPBITS(t->bits) |
124 | if ((e = (int)(t->exop)) < 0) | 124 | if ((e = (int)(t->exop)) < 0) |
125 | { | 125 | { |
126 | if (e == -128) /* invalid code */ | 126 | if (e == -128) /* invalid code */ |
127 | { | 127 | { |
128 | c->mode = BADCODE; | 128 | c->mode = BADCODE; |
129 | z->msg = "invalid literal/length code"; | 129 | z->msg = "invalid literal/length code"; |
130 | r = Z_DATA_ERROR; | 130 | r = Z_DATA_ERROR; |
131 | LEAVE | 131 | LEAVE |
132 | } | 132 | } |
133 | e = -e; | 133 | e = -e; |
134 | if (e & 64) /* end of block */ | 134 | if (e & 64) /* end of block */ |
135 | { | 135 | { |
136 | Tracevv((stderr, "inflate: end of block\n")); | 136 | Tracevv((stderr, "inflate: end of block\n")); |
137 | c->mode = WASH; | 137 | c->mode = WASH; |
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | c->sub.code.need = e; | 140 | c->sub.code.need = e; |
141 | c->sub.code.tree = t->next; | 141 | c->sub.code.tree = t->next; |
142 | break; | 142 | break; |
143 | } | 143 | } |
144 | if (e & 16) /* literal */ | 144 | if (e & 16) /* literal */ |
145 | { | 145 | { |
146 | c->sub.lit = t->base; | 146 | c->sub.lit = t->base; |
147 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? | 147 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
148 | "inflate: literal '%c'\n" : | 148 | "inflate: literal '%c'\n" : |
149 | "inflate: literal 0x%02x\n", t->base)); | 149 | "inflate: literal 0x%02x\n", t->base)); |
150 | c->mode = LIT; | 150 | c->mode = LIT; |
151 | break; | 151 | break; |
152 | } | 152 | } |
153 | c->sub.copy.get = e; | 153 | c->sub.copy.get = e; |
154 | c->len = t->base; | 154 | c->len = t->base; |
155 | c->mode = LENEXT; | 155 | c->mode = LENEXT; |
156 | case LENEXT: /* i: getting length extra (have base) */ | 156 | case LENEXT: /* i: getting length extra (have base) */ |
157 | j = c->sub.copy.get; | 157 | j = c->sub.copy.get; |
158 | NEEDBITS(j) | 158 | NEEDBITS(j) |
159 | c->len += (uInt)b & inflate_mask[j]; | 159 | c->len += (uInt)b & inflate_mask[j]; |
@@ -162,7 +162,7 @@ int r; | |||
162 | c->sub.code.tree = c->dtree; | 162 | c->sub.code.tree = c->dtree; |
163 | Tracevv((stderr, "inflate: length %u\n", c->len)); | 163 | Tracevv((stderr, "inflate: length %u\n", c->len)); |
164 | c->mode = DIST; | 164 | c->mode = DIST; |
165 | case DIST: /* i: get distance next */ | 165 | case DIST: /* i: get distance next */ |
166 | j = c->sub.code.need; | 166 | j = c->sub.code.need; |
167 | NEEDBITS(j) | 167 | NEEDBITS(j) |
168 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); | 168 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); |
@@ -170,46 +170,46 @@ int r; | |||
170 | if ((e = (int)(t->exop)) < 0) | 170 | if ((e = (int)(t->exop)) < 0) |
171 | { | 171 | { |
172 | if (e == -128) | 172 | if (e == -128) |
173 | { | 173 | { |
174 | c->mode = BADCODE; | 174 | c->mode = BADCODE; |
175 | z->msg = "invalid distance code"; | 175 | z->msg = "invalid distance code"; |
176 | r = Z_DATA_ERROR; | 176 | r = Z_DATA_ERROR; |
177 | LEAVE | 177 | LEAVE |
178 | } | 178 | } |
179 | c->sub.code.need = -e; | 179 | c->sub.code.need = -e; |
180 | c->sub.code.tree = t->next; | 180 | c->sub.code.tree = t->next; |
181 | break; | 181 | break; |
182 | } | 182 | } |
183 | c->sub.copy.dist = t->base; | 183 | c->sub.copy.dist = t->base; |
184 | c->sub.copy.get = e; | 184 | c->sub.copy.get = e; |
185 | c->mode = DISTEXT; | 185 | c->mode = DISTEXT; |
186 | case DISTEXT: /* i: getting distance extra */ | 186 | case DISTEXT: /* i: getting distance extra */ |
187 | j = c->sub.copy.get; | 187 | j = c->sub.copy.get; |
188 | NEEDBITS(j) | 188 | NEEDBITS(j) |
189 | c->sub.copy.dist += (uInt)b & inflate_mask[j]; | 189 | c->sub.copy.dist += (uInt)b & inflate_mask[j]; |
190 | DUMPBITS(j) | 190 | DUMPBITS(j) |
191 | Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); | 191 | Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); |
192 | c->mode = COPY; | 192 | c->mode = COPY; |
193 | case COPY: /* o: copying bytes in window, waiting for space */ | 193 | case COPY: /* o: copying bytes in window, waiting for space */ |
194 | f = (uInt)(q - s->window) < c->sub.copy.dist ? | 194 | f = (uInt)(q - s->window) < c->sub.copy.dist ? |
195 | s->end - (c->sub.copy.dist - (q - s->window)) : | 195 | s->end - (c->sub.copy.dist - (q - s->window)) : |
196 | q - c->sub.copy.dist; | 196 | q - c->sub.copy.dist; |
197 | while (c->len) | 197 | while (c->len) |
198 | { | 198 | { |
199 | NEEDOUT | 199 | NEEDOUT |
200 | OUTBYTE(*f++) | 200 | OUTBYTE(*f++) |
201 | if (f == s->end) | 201 | if (f == s->end) |
202 | f = s->window; | 202 | f = s->window; |
203 | c->len--; | 203 | c->len--; |
204 | } | 204 | } |
205 | c->mode = START; | 205 | c->mode = START; |
206 | break; | 206 | break; |
207 | case LIT: /* o: got literal, waiting for output space */ | 207 | case LIT: /* o: got literal, waiting for output space */ |
208 | NEEDOUT | 208 | NEEDOUT |
209 | OUTBYTE(c->sub.lit) | 209 | OUTBYTE(c->sub.lit) |
210 | c->mode = START; | 210 | c->mode = START; |
211 | break; | 211 | break; |
212 | case WASH: /* o: got eob, possibly more output */ | 212 | case WASH: /* o: got eob, possibly more output */ |
213 | FLUSH | 213 | FLUSH |
214 | if (s->read != s->write) | 214 | if (s->read != s->write) |
215 | LEAVE | 215 | LEAVE |
@@ -217,7 +217,7 @@ int r; | |||
217 | case END: | 217 | case END: |
218 | r = Z_STREAM_END; | 218 | r = Z_STREAM_END; |
219 | LEAVE | 219 | LEAVE |
220 | case BADCODE: /* x: got error */ | 220 | case BADCODE: /* x: got error */ |
221 | r = Z_DATA_ERROR; | 221 | r = Z_DATA_ERROR; |
222 | LEAVE | 222 | LEAVE |
223 | default: | 223 | default: |