aboutsummaryrefslogtreecommitdiff
path: root/inflate.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:06:52 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:06:52 -0700
commit64b2e892035cf6ea98800c54dce0d63730d50272 (patch)
treee3b569f87e413eaef4a13469acfd4224b2a63d3a /inflate.c
parent4ca984fb447ac57120c394cf2fbba23837ed31c2 (diff)
downloadzlib-64b2e892035cf6ea98800c54dce0d63730d50272.tar.gz
zlib-64b2e892035cf6ea98800c54dce0d63730d50272.tar.bz2
zlib-64b2e892035cf6ea98800c54dce0d63730d50272.zip
zlib 0.9v0.9
Diffstat (limited to 'inflate.c')
-rw-r--r--inflate.c204
1 files changed, 130 insertions, 74 deletions
diff --git a/inflate.c b/inflate.c
index b76e246..bed4e54 100644
--- a/inflate.c
+++ b/inflate.c
@@ -15,38 +15,63 @@ struct internal_state {
15 enum { 15 enum {
16 METHOD, /* waiting for method byte */ 16 METHOD, /* waiting for method byte */
17 FLAG, /* waiting for flag byte */ 17 FLAG, /* waiting for flag byte */
18 START, /* make new blocks state */
19 BLOCKS, /* decompressing blocks */ 18 BLOCKS, /* decompressing blocks */
20 CHECK4, /* four check bytes to go */ 19 CHECK4, /* four check bytes to go */
21 CHECK3, /* three check bytes to go */ 20 CHECK3, /* three check bytes to go */
22 CHECK2, /* two check bytes to go */ 21 CHECK2, /* two check bytes to go */
23 CHECK1, /* one check byte to go */ 22 CHECK1, /* one check byte to go */
24 DONE, /* finished check, done */ 23 DONE, /* finished check, done */
25 INF_ERROR}/* got an error--stay here */ 24 BAD} /* got an error--stay here */
26 mode; /* current inflate mode */ 25 mode; /* current inflate mode */
27 26
28 /* mode dependent information */ 27 /* mode dependent information */
29 union { 28 union {
30 uInt method; /* if FLAGS, method byte */ 29 uInt method; /* if FLAGS, method byte */
31 struct inflate_blocks_state
32 *blocks; /* if BLOCKS, current state */
33 struct { 30 struct {
34 uLong was; /* computed check value */ 31 uLong was; /* computed check value */
35 uLong need; /* stream check value */ 32 uLong need; /* stream check value */
36 } check; /* if CHECK, check values to compare */ 33 } check; /* if CHECK, check values to compare */
34 uInt marker; /* if BAD, inflateSync's marker bytes count */
37 } sub; /* submode */ 35 } sub; /* submode */
38 36
39 /* mode independent information */ 37 /* mode independent information */
40 int nowrap; /* flag for no wrapper */ 38 int nowrap; /* flag for no wrapper */
41 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 39 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
40 struct inflate_blocks_state
41 *blocks; /* current inflate_blocks state */
42 42
43}; 43};
44 44
45 45
46int inflateInit(z) 46int inflateReset(z)
47z_stream *z; 47z_stream *z;
48{ 48{
49 return inflateInit2(z, WBITS); 49 uLong c;
50
51 if (z == Z_NULL || z->state == Z_NULL)
52 return Z_STREAM_ERROR;
53 z->total_in = z->total_out = 0;
54 z->msg = Z_NULL;
55 z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
56 inflate_blocks_reset(z->state->blocks, z, &c);
57 Trace((stderr, "inflate: reset\n"));
58 return Z_OK;
59}
60
61
62int inflateEnd(z)
63z_stream *z;
64{
65 uLong c;
66
67 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
68 return Z_STREAM_ERROR;
69 if (z->state->blocks != Z_NULL)
70 inflate_blocks_free(z->state->blocks, z, &c);
71 ZFREE(z, z->state);
72 z->state = Z_NULL;
73 Trace((stderr, "inflate: end\n"));
74 return Z_OK;
50} 75}
51 76
52 77
@@ -59,12 +84,10 @@ int w;
59 return Z_STREAM_ERROR; 84 return Z_STREAM_ERROR;
60 if (z->zalloc == Z_NULL) z->zalloc = zcalloc; 85 if (z->zalloc == Z_NULL) z->zalloc = zcalloc;
61 if (z->zfree == Z_NULL) z->zfree = zcfree; 86 if (z->zfree == Z_NULL) z->zfree = zcfree;
62 z->total_in = z->total_out = 0;
63 z->msg = Z_NULL;
64 if ((z->state = (struct internal_state *) 87 if ((z->state = (struct internal_state *)
65 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) 88 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
66 return Z_MEM_ERROR; 89 return Z_MEM_ERROR;
67 z->state->mode = METHOD; 90 z->state->blocks = Z_NULL;
68 91
69 /* handle undocumented nowrap option (no zlib header or check) */ 92 /* handle undocumented nowrap option (no zlib header or check) */
70 z->state->nowrap = 0; 93 z->state->nowrap = 0;
@@ -72,7 +95,6 @@ int w;
72 { 95 {
73 w = - w; 96 w = - w;
74 z->state->nowrap = 1; 97 z->state->nowrap = 1;
75 z->state->mode = START;
76 } 98 }
77 99
78 /* set window size */ 100 /* set window size */
@@ -81,20 +103,40 @@ int w;
81 inflateEnd(z); 103 inflateEnd(z);
82 return Z_STREAM_ERROR; 104 return Z_STREAM_ERROR;
83 } 105 }
84 z->state->wbits = w; 106 z->state->wbits = (uInt)w;
107
108 /* create inflate_blocks state */
109 if ((z->state->blocks =
110 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
111 == Z_NULL)
112 {
113 inflateEnd(z);
114 return Z_MEM_ERROR;
115 }
116 Trace((stderr, "inflate: allocated\n"));
117
118 /* reset state */
119 inflateReset(z);
85 return Z_OK; 120 return Z_OK;
86} 121}
87 122
88 123
124int inflateInit(z)
125z_stream *z;
126{
127 return inflateInit2(z, DEF_WBITS);
128}
129
130
131#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;}
89#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 132#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
90 133
91int inflate(z, f) 134int inflate(z, f)
92z_stream *z; 135z_stream *z;
93int f; 136int f;
94{ 137{
95 int r = f; /* to avoid warning about unused f */ 138 int r = f; /* to avoid warning about unused f */
96 uInt b; 139 uInt b;
97 uLong c;
98 140
99 if (z == Z_NULL || z->next_in == Z_NULL) 141 if (z == Z_NULL || z->next_in == Z_NULL)
100 return Z_STREAM_ERROR; 142 return Z_STREAM_ERROR;
@@ -102,77 +144,86 @@ int f;
102 while (1) switch (z->state->mode) 144 while (1) switch (z->state->mode)
103 { 145 {
104 case METHOD: 146 case METHOD:
105 if (z->avail_in == 0) return r; r = Z_OK; 147 NEEDBYTE
106 if (((z->state->sub.method = NEXTBYTE) & 0xf != DEFLATED)) 148 if (((z->state->sub.method = NEXTBYTE) & 0xf != DEFLATED))
107 { 149 {
108 z->state->mode = INF_ERROR; 150 z->state->mode = BAD;
109 z->msg = "unknown compression method"; 151 z->msg = "unknown compression method";
110 return Z_DATA_ERROR; 152 z->state->sub.marker = 5; /* can't try inflateSync */
153 break;
111 } 154 }
112 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 155 if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
113 { 156 {
114 z->state->mode = INF_ERROR; 157 z->state->mode = BAD;
115 z->msg = "invalid window size"; 158 z->msg = "invalid window size";
116 return Z_DATA_ERROR; 159 z->state->sub.marker = 5; /* can't try inflateSync */
160 break;
117 } 161 }
118 z->state->mode = FLAG; 162 z->state->mode = FLAG;
119 case FLAG: 163 case FLAG:
120 if (z->avail_in == 0) return r; r = Z_OK; 164 NEEDBYTE
121 if ((b = NEXTBYTE) & 0x20) 165 if ((b = NEXTBYTE) & 0x20)
122 { 166 {
123 z->state->mode = INF_ERROR; 167 z->state->mode = BAD;
124 z->msg = "invalid reserved bit"; 168 z->msg = "invalid reserved bit";
125 return Z_DATA_ERROR; 169 z->state->sub.marker = 5; /* can't try inflateSync */
170 break;
126 } 171 }
127 if (((z->state->sub.method << 8) + b) % 31) 172 if (((z->state->sub.method << 8) + b) % 31)
128 { 173 {
129 z->state->mode = INF_ERROR; 174 z->state->mode = BAD;
130 z->msg = "incorrect header check"; 175 z->msg = "incorrect header check";
131 return Z_DATA_ERROR; 176 z->state->sub.marker = 5; /* can't try inflateSync */
177 break;
132 } 178 }
133 z->state->mode = START; 179 Trace((stderr, "inflate: zlib header ok\n"));
134 case START:
135 if ((z->state->sub.blocks = inflate_blocks_new(z,
136 z->state->nowrap ? Z_NULL : adler32,
137 1<< z->state->wbits)) == Z_NULL)
138 return Z_MEM_ERROR;
139 z->state->mode = BLOCKS; 180 z->state->mode = BLOCKS;
140 case BLOCKS: 181 case BLOCKS:
141 if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END) 182 r = inflate_blocks(z->state->blocks, z, r);
142 return r; 183 if (r == Z_DATA_ERROR)
143 inflate_blocks_free(z->state->sub.blocks, z, &c); 184 {
185 z->state->mode = BAD;
186 z->state->sub.marker = 0; /* can try inflateSync */
187 break;
188 }
189 if (r != Z_STREAM_END)
190 return r;
191 r = Z_OK;
192 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
144 if (z->state->nowrap) 193 if (z->state->nowrap)
145 { 194 {
146 z->state->mode = DONE; 195 z->state->mode = DONE;
147 break; 196 break;
148 } 197 }
149 z->state->sub.check.was = c;
150 z->state->mode = CHECK4; 198 z->state->mode = CHECK4;
151 case CHECK4: 199 case CHECK4:
152 if (z->avail_in == 0) return r; r = Z_OK; 200 NEEDBYTE
153 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 201 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
154 z->state->mode = CHECK3; 202 z->state->mode = CHECK3;
155 case CHECK3: 203 case CHECK3:
156 if (z->avail_in == 0) return r; r = Z_OK; 204 NEEDBYTE
157 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 205 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
158 z->state->mode = CHECK2; 206 z->state->mode = CHECK2;
159 case CHECK2: 207 case CHECK2:
160 if (z->avail_in == 0) return r; r = Z_OK; 208 NEEDBYTE
161 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 209 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
162 z->state->mode = CHECK1; 210 z->state->mode = CHECK1;
163 case CHECK1: 211 case CHECK1:
164 if (z->avail_in == 0) return r; r = Z_OK; 212 NEEDBYTE
165 z->state->sub.check.need += (uLong)NEXTBYTE; 213 z->state->sub.check.need += (uLong)NEXTBYTE;
214
166 if (z->state->sub.check.was != z->state->sub.check.need) 215 if (z->state->sub.check.was != z->state->sub.check.need)
167 { 216 {
168 z->state->mode = INF_ERROR; 217 z->state->mode = BAD;
169 z->msg = "incorrect data check"; 218 z->msg = "incorrect data check";
170 return Z_DATA_ERROR; 219 z->state->sub.marker = 5; /* can't try inflateSync */
220 break;
171 } 221 }
222 Trace((stderr, "inflate: zlib check ok\n"));
172 z->state->mode = DONE; 223 z->state->mode = DONE;
173 case DONE: 224 case DONE:
174 return Z_STREAM_END; 225 return Z_STREAM_END;
175 case INF_ERROR: 226 case BAD:
176 return Z_DATA_ERROR; 227 return Z_DATA_ERROR;
177 default: 228 default:
178 return Z_STREAM_ERROR; 229 return Z_STREAM_ERROR;
@@ -180,41 +231,46 @@ int f;
180} 231}
181 232
182 233
183int inflateEnd(z) 234int inflateSync(z)
184z_stream *z; 235z_stream *z;
185{ 236{
186 uLong c; 237 uInt n; /* number of bytes to look at */
238 Byte *p; /* pointer to bytes */
239 uInt m; /* number of marker bytes found in a row */
240 uLong r, w; /* temporaries to save total_in and total_out */
187 241
188 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) 242 /* set up */
243 if (z == Z_NULL || z->state == Z_NULL)
189 return Z_STREAM_ERROR; 244 return Z_STREAM_ERROR;
190 if (z->state->mode == BLOCKS) 245 if (z->state->mode != BAD)
191 inflate_blocks_free(z->state->sub.blocks, z, &c); 246 z->state->sub.marker = 0;
192 ZFREE(z, z->state); 247 if ((n = z->avail_in) == 0)
193 z->state = Z_NULL; 248 return Z_BUF_ERROR;
194 return Z_OK; 249 p = z->next_in;
195} 250 m = z->state->sub.marker;
196
197
198/* inflateSync not implemented yet--this just consumes input */
199int inflateSync(z)
200z_stream *z;
201{
202 if (z == Z_NULL) return Z_STREAM_ERROR;
203 if (z->avail_in == 0) return Z_BUF_ERROR;
204 do {
205 z->total_in++;
206 } while (--z->avail_in);
207 return Z_DATA_ERROR;
208}
209 251
252 /* search */
253 while (n && m < 4)
254 {
255 if (*p == (m < 2 ? 0 : 0xff))
256 m++;
257 else if (*p || m > 2)
258 m = 0;
259 p++, n--;
260 }
210 261
211/* inflateReset not fully implemented yet--this frees and reallocates */ 262 /* restore */
212int inflateReset(z) 263 z->total_in += p - z->next_in;
213z_stream *z; 264 z->next_in = p;
214{ 265 z->avail_in = n;
215 int r; 266 z->state->sub.marker = m;
216 267
217 if ((r = inflateEnd(z)) != Z_OK) 268 /* return no joy or set up to restart on a new block */
218 return r; 269 if (m != 4)
219 return inflateInit(z); 270 return Z_DATA_ERROR;
271 r = z->total_in; w = z->total_out;
272 inflateReset(z);
273 z->total_in = r; z->total_out = w;
274 z->state->mode = BLOCKS;
275 return Z_OK;
220} 276}