]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/inflate.c
1 /* inflate.c -- zlib interface to inflate modules
2 * Copyright (C) 1995-2002 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 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
54 int ZEXPORT
inflateReset(z_streamp z
)
56 int ZEXPORT
inflateReset(z
)
60 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
61 return Z_STREAM_ERROR
;
62 z
->total_in
= z
->total_out
= 0;
64 z
->state
->mode
= z
->state
->nowrap
? BLOCKS
: METHOD
;
65 inflate_blocks_reset(z
->state
->blocks
, z
, Z_NULL
);
66 Tracev((stderr
, "inflate: reset\n"));
71 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
72 int ZEXPORT
inflateEnd(z_streamp z
)
74 int ZEXPORT
inflateEnd(z
)
78 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->zfree
== Z_NULL
)
79 return Z_STREAM_ERROR
;
80 if (z
->state
->blocks
!= Z_NULL
)
81 inflate_blocks_free(z
->state
->blocks
, z
);
84 Tracev((stderr
, "inflate: end\n"));
88 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
89 int ZEXPORT
inflateInit2_(z_streamp z
, int w
, const char* version
, int stream_size
)
91 int ZEXPORT
inflateInit2_(z
, w
, version
, stream_size
)
98 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
99 stream_size
!= sizeof(z_stream
))
100 return Z_VERSION_ERROR
;
102 /* initialize state */
104 return Z_STREAM_ERROR
;
106 if (z
->zalloc
== Z_NULL
)
109 z
->opaque
= (voidpf
)0;
111 if (z
->zfree
== Z_NULL
) z
->zfree
= zcfree
;
112 if ((z
->state
= (struct internal_state FAR
*)
113 ZALLOC(z
,1,sizeof(struct internal_state
))) == Z_NULL
)
115 z
->state
->blocks
= Z_NULL
;
117 /* handle undocumented nowrap option (no zlib header or check) */
118 z
->state
->nowrap
= 0;
122 z
->state
->nowrap
= 1;
125 /* set window size */
129 return Z_STREAM_ERROR
;
131 z
->state
->wbits
= (uInt
)w
;
133 /* create inflate_blocks state */
134 if ((z
->state
->blocks
=
135 inflate_blocks_new(z
, z
->state
->nowrap
? Z_NULL
: adler32
, (uInt
)1 << w
))
141 Tracev((stderr
, "inflate: allocated\n"));
148 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
149 int ZEXPORT
inflateInit_(z_streamp z
, const char* version
, int stream_size
)
151 int ZEXPORT
inflateInit_(z
, version
, stream_size
)
157 return inflateInit2_(z
, DEF_WBITS
, version
, stream_size
);
160 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
161 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
163 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
164 int ZEXPORT
inflate(z_streamp z
, int f
)
166 int ZEXPORT
inflate(z
, f
)
174 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->next_in
== Z_NULL
)
175 return Z_STREAM_ERROR
;
176 f
= f
== Z_FINISH
? Z_BUF_ERROR
: Z_OK
;
178 while (1) switch (z
->state
->mode
)
182 if (((z
->state
->sub
.method
= NEXTBYTE
) & 0xf) != Z_DEFLATED
)
184 z
->state
->mode
= BAD
;
185 z
->msg
= (char*)"unknown compression method";
186 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
189 if ((z
->state
->sub
.method
>> 4) + 8 > z
->state
->wbits
)
191 z
->state
->mode
= BAD
;
192 z
->msg
= (char*)"invalid window size";
193 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
196 z
->state
->mode
= FLAG
;
200 if (((z
->state
->sub
.method
<< 8) + b
) % 31)
202 z
->state
->mode
= BAD
;
203 z
->msg
= (char*)"incorrect header check";
204 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
207 Tracev((stderr
, "inflate: zlib header ok\n"));
208 if (!(b
& PRESET_DICT
))
210 z
->state
->mode
= BLOCKS
;
213 z
->state
->mode
= DICT4
;
216 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
217 z
->state
->mode
= DICT3
;
220 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
221 z
->state
->mode
= DICT2
;
224 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
225 z
->state
->mode
= DICT1
;
228 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
229 z
->adler
= z
->state
->sub
.check
.need
;
230 z
->state
->mode
= DICT0
;
233 z
->state
->mode
= BAD
;
234 z
->msg
= (char*)"need dictionary";
235 z
->state
->sub
.marker
= 0; /* can try inflateSync */
236 return Z_STREAM_ERROR
;
238 r
= inflate_blocks(z
->state
->blocks
, z
, r
);
239 if (r
== Z_DATA_ERROR
)
241 z
->state
->mode
= BAD
;
242 z
->state
->sub
.marker
= 0; /* can try inflateSync */
247 if (r
!= Z_STREAM_END
)
250 inflate_blocks_reset(z
->state
->blocks
, z
, &z
->state
->sub
.check
.was
);
251 if (z
->state
->nowrap
)
253 z
->state
->mode
= DONE
;
256 z
->state
->mode
= CHECK4
;
259 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
260 z
->state
->mode
= CHECK3
;
263 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
264 z
->state
->mode
= CHECK2
;
267 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
268 z
->state
->mode
= CHECK1
;
271 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
273 if (z
->state
->sub
.check
.was
!= z
->state
->sub
.check
.need
)
275 z
->state
->mode
= BAD
;
276 z
->msg
= (char*)"incorrect data check";
277 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
280 Tracev((stderr
, "inflate: zlib check ok\n"));
281 z
->state
->mode
= DONE
;
287 return Z_STREAM_ERROR
;
289 #ifdef NEED_DUMMY_RETURN
290 return Z_STREAM_ERROR
; /* Some dumb compilers complain without this */
294 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
295 int ZEXPORT
inflateSetDictionary(z_streamp z
, const Bytef
* dictionary
, uInt dictLength
)
297 int ZEXPORT
inflateSetDictionary(z
, dictionary
, dictLength
)
299 const Bytef
*dictionary
;
303 uInt length
= dictLength
;
305 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->mode
!= DICT0
)
306 return Z_STREAM_ERROR
;
308 if (adler32(1L, dictionary
, dictLength
) != z
->adler
) return Z_DATA_ERROR
;
311 if (length
>= ((uInt
)1<<z
->state
->wbits
))
313 length
= (1<<z
->state
->wbits
)-1;
314 dictionary
+= dictLength
- length
;
316 inflate_set_dictionary(z
->state
->blocks
, dictionary
, length
);
317 z
->state
->mode
= BLOCKS
;
321 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
322 int ZEXPORT
inflateSync(z_streamp z
)
324 int ZEXPORT
inflateSync(z
)
328 uInt n
; /* number of bytes to look at */
329 Bytef
*p
; /* pointer to bytes */
330 uInt m
; /* number of marker bytes found in a row */
331 uLong r
, w
; /* temporaries to save total_in and total_out */
334 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
335 return Z_STREAM_ERROR
;
336 if (z
->state
->mode
!= BAD
)
338 z
->state
->mode
= BAD
;
339 z
->state
->sub
.marker
= 0;
341 if ((n
= z
->avail_in
) == 0)
344 m
= z
->state
->sub
.marker
;
349 static const Byte mark
[4] = {0, 0, 0xff, 0xff};
360 z
->total_in
+= p
- z
->next_in
;
363 z
->state
->sub
.marker
= m
;
365 /* return no joy or set up to restart on a new block */
368 r
= z
->total_in
; w
= z
->total_out
;
370 z
->total_in
= r
; z
->total_out
= w
;
371 z
->state
->mode
= BLOCKS
;
375 /* Returns true if inflate is currently at the end of a block generated
376 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
377 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
378 * but removes the length bytes of the resulting empty stored block. When
379 * decompressing, PPP checks that at the end of input packet, inflate is
380 * waiting for these length bytes.
382 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */
383 int ZEXPORT
inflateSyncPoint(z_streamp z
)
385 int ZEXPORT
inflateSyncPoint(z
)
389 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->blocks
== Z_NULL
)
390 return Z_STREAM_ERROR
;
391 return inflate_blocks_sync_point(z
->state
->blocks
);