]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/inflate.c
1 /* inflate.c -- zlib interface to inflate modules
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
9 struct inflate_blocks_state
{int dummy
;}; /* for buggy compilers */
12 METHOD
, /* waiting for method byte */
13 FLAG
, /* waiting for flag byte */
14 DICT4
, /* four dictionary check bytes to go */
15 DICT3
, /* three dictionary check bytes to go */
16 DICT2
, /* two dictionary check bytes to go */
17 DICT1
, /* one dictionary check byte to go */
18 DICT0
, /* waiting for inflateSetDictionary */
19 BLOCKS
, /* decompressing blocks */
20 CHECK4
, /* four check bytes to go */
21 CHECK3
, /* three check bytes to go */
22 CHECK2
, /* two check bytes to go */
23 CHECK1
, /* one check byte to go */
24 DONE
, /* finished check, done */
25 BAD
} /* got an error--stay here */
28 /* inflate private state */
29 struct internal_state
{
32 inflate_mode mode
; /* current inflate mode */
34 /* mode dependent information */
36 uInt method
; /* if FLAGS, method byte */
38 uLong was
; /* computed check value */
39 uLong need
; /* stream check value */
40 } check
; /* if CHECK, check values to compare */
41 uInt marker
; /* if BAD, inflateSync's marker bytes count */
44 /* mode independent information */
45 int nowrap
; /* flag for no wrapper */
46 uInt wbits
; /* log2(window size) (8..15, defaults to 15) */
48 *blocks
; /* current inflate_blocks state */
53 int ZEXPORT
inflateReset(z
)
56 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
57 return Z_STREAM_ERROR
;
58 z
->total_in
= z
->total_out
= 0;
60 z
->state
->mode
= z
->state
->nowrap
? BLOCKS
: METHOD
;
61 inflate_blocks_reset(z
->state
->blocks
, z
, Z_NULL
);
62 Tracev((stderr
, "inflate: reset\n"));
67 int ZEXPORT
inflateEnd(z
)
70 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->zfree
== Z_NULL
)
71 return Z_STREAM_ERROR
;
72 if (z
->state
->blocks
!= Z_NULL
)
73 inflate_blocks_free(z
->state
->blocks
, z
);
76 Tracev((stderr
, "inflate: end\n"));
81 int ZEXPORT
inflateInit2_(z
, w
, version
, stream_size
)
87 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
88 stream_size
!= sizeof(z_stream
))
89 return Z_VERSION_ERROR
;
91 /* initialize state */
93 return Z_STREAM_ERROR
;
95 if (z
->zalloc
== Z_NULL
)
98 z
->opaque
= (voidpf
)0;
100 if (z
->zfree
== Z_NULL
) z
->zfree
= zcfree
;
101 if ((z
->state
= (struct internal_state FAR
*)
102 ZALLOC(z
,1,sizeof(struct internal_state
))) == Z_NULL
)
104 z
->state
->blocks
= Z_NULL
;
106 /* handle undocumented nowrap option (no zlib header or check) */
107 z
->state
->nowrap
= 0;
111 z
->state
->nowrap
= 1;
114 /* set window size */
118 return Z_STREAM_ERROR
;
120 z
->state
->wbits
= (uInt
)w
;
122 /* create inflate_blocks state */
123 if ((z
->state
->blocks
=
124 inflate_blocks_new(z
, z
->state
->nowrap
? Z_NULL
: adler32
, (uInt
)1 << w
))
130 Tracev((stderr
, "inflate: allocated\n"));
138 int ZEXPORT
inflateInit_(z
, version
, stream_size
)
143 return inflateInit2_(z
, DEF_WBITS
, version
, stream_size
);
147 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
148 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
150 int ZEXPORT
inflate(z
, f
)
157 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->next_in
== Z_NULL
)
158 return Z_STREAM_ERROR
;
159 f
= f
== Z_FINISH
? Z_BUF_ERROR
: Z_OK
;
161 while (1) switch (z
->state
->mode
)
165 if (((z
->state
->sub
.method
= NEXTBYTE
) & 0xf) != Z_DEFLATED
)
167 z
->state
->mode
= BAD
;
168 z
->msg
= (char*)"unknown compression method";
169 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
172 if ((z
->state
->sub
.method
>> 4) + 8 > z
->state
->wbits
)
174 z
->state
->mode
= BAD
;
175 z
->msg
= (char*)"invalid window size";
176 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
179 z
->state
->mode
= FLAG
;
183 if (((z
->state
->sub
.method
<< 8) + b
) % 31)
185 z
->state
->mode
= BAD
;
186 z
->msg
= (char*)"incorrect header check";
187 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
190 Tracev((stderr
, "inflate: zlib header ok\n"));
191 if (!(b
& PRESET_DICT
))
193 z
->state
->mode
= BLOCKS
;
196 z
->state
->mode
= DICT4
;
199 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
200 z
->state
->mode
= DICT3
;
203 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
204 z
->state
->mode
= DICT2
;
207 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
208 z
->state
->mode
= DICT1
;
211 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
212 z
->adler
= z
->state
->sub
.check
.need
;
213 z
->state
->mode
= DICT0
;
216 z
->state
->mode
= BAD
;
217 z
->msg
= (char*)"need dictionary";
218 z
->state
->sub
.marker
= 0; /* can try inflateSync */
219 return Z_STREAM_ERROR
;
221 r
= inflate_blocks(z
->state
->blocks
, z
, r
);
222 if (r
== Z_DATA_ERROR
)
224 z
->state
->mode
= BAD
;
225 z
->state
->sub
.marker
= 0; /* can try inflateSync */
230 if (r
!= Z_STREAM_END
)
233 inflate_blocks_reset(z
->state
->blocks
, z
, &z
->state
->sub
.check
.was
);
234 if (z
->state
->nowrap
)
236 z
->state
->mode
= DONE
;
239 z
->state
->mode
= CHECK4
;
242 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
243 z
->state
->mode
= CHECK3
;
246 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
247 z
->state
->mode
= CHECK2
;
250 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
251 z
->state
->mode
= CHECK1
;
254 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
256 if (z
->state
->sub
.check
.was
!= z
->state
->sub
.check
.need
)
258 z
->state
->mode
= BAD
;
259 z
->msg
= (char*)"incorrect data check";
260 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
263 Tracev((stderr
, "inflate: zlib check ok\n"));
264 z
->state
->mode
= DONE
;
270 return Z_STREAM_ERROR
;
272 #ifdef NEED_DUMMY_RETURN
273 return Z_STREAM_ERROR
; /* Some dumb compilers complain without this */
278 int ZEXPORT
inflateSetDictionary(z
, dictionary
, dictLength
)
280 const Bytef
*dictionary
;
283 uInt length
= dictLength
;
285 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->mode
!= DICT0
)
286 return Z_STREAM_ERROR
;
288 if (adler32(1L, dictionary
, dictLength
) != z
->adler
) return Z_DATA_ERROR
;
291 if (length
>= ((uInt
)1<<z
->state
->wbits
))
293 length
= (1<<z
->state
->wbits
)-1;
294 dictionary
+= dictLength
- length
;
296 inflate_set_dictionary(z
->state
->blocks
, dictionary
, length
);
297 z
->state
->mode
= BLOCKS
;
302 int ZEXPORT
inflateSync(z
)
305 uInt n
; /* number of bytes to look at */
306 Bytef
*p
; /* pointer to bytes */
307 uInt m
; /* number of marker bytes found in a row */
308 uLong r
, w
; /* temporaries to save total_in and total_out */
311 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
312 return Z_STREAM_ERROR
;
313 if (z
->state
->mode
!= BAD
)
315 z
->state
->mode
= BAD
;
316 z
->state
->sub
.marker
= 0;
318 if ((n
= z
->avail_in
) == 0)
321 m
= z
->state
->sub
.marker
;
326 static const Byte mark
[4] = {0, 0, 0xff, 0xff};
337 z
->total_in
+= p
- z
->next_in
;
340 z
->state
->sub
.marker
= m
;
342 /* return no joy or set up to restart on a new block */
345 r
= z
->total_in
; w
= z
->total_out
;
347 z
->total_in
= r
; z
->total_out
= w
;
348 z
->state
->mode
= BLOCKS
;
353 /* Returns true if inflate is currently at the end of a block generated
354 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
355 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
356 * but removes the length bytes of the resulting empty stored block. When
357 * decompressing, PPP checks that at the end of input packet, inflate is
358 * waiting for these length bytes.
360 int ZEXPORT
inflateSyncPoint(z
)
363 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->blocks
== Z_NULL
)
364 return Z_STREAM_ERROR
;
365 return inflate_blocks_sync_point(z
->state
->blocks
);