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 #define DONE INFLATE_DONE
10 #define BAD INFLATE_BAD
13 METHOD
, /* waiting for method byte */
14 FLAG
, /* waiting for flag byte */
15 DICT4
, /* four dictionary check bytes to go */
16 DICT3
, /* three dictionary check bytes to go */
17 DICT2
, /* two dictionary check bytes to go */
18 DICT1
, /* one dictionary check byte to go */
19 DICT0
, /* waiting for inflateSetDictionary */
20 BLOCKS
, /* decompressing blocks */
21 CHECK4
, /* four check bytes to go */
22 CHECK3
, /* three check bytes to go */
23 CHECK2
, /* two check bytes to go */
24 CHECK1
, /* one check byte to go */
25 DONE
, /* finished check, done */
26 BAD
} /* got an error--stay here */
29 /* inflate private state */
30 struct internal_state
{
33 inflate_mode mode
; /* current inflate mode */
35 /* mode dependent information */
37 uInt method
; /* if FLAGS, method byte */
39 uLong was
; /* computed check value */
40 uLong need
; /* stream check value */
41 } check
; /* if CHECK, check values to compare */
42 uInt marker
; /* if BAD, inflateSync's marker bytes count */
45 /* mode independent information */
46 int nowrap
; /* flag for no wrapper */
47 uInt wbits
; /* log2(window size) (8..15, defaults to 15) */
49 *blocks
; /* current inflate_blocks state */
54 ZEXPORT(int) inflateReset( /* z) */
57 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
58 return Z_STREAM_ERROR
;
59 z
->total_in
= z
->total_out
= 0;
61 z
->state
->mode
= z
->state
->nowrap
? BLOCKS
: METHOD
;
62 inflate_blocks_reset(z
->state
->blocks
, z
, Z_NULL
);
63 Tracev((stderr
, "inflate: reset\n"));
68 ZEXPORT(int) inflateEnd( /* z) */
71 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->zfree
== Z_NULL
)
72 return Z_STREAM_ERROR
;
73 if (z
->state
->blocks
!= Z_NULL
)
74 inflate_blocks_free(z
->state
->blocks
, z
);
77 Tracev((stderr
, "inflate: end\n"));
82 ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */
88 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
89 stream_size
!= sizeof(z_stream
))
90 return Z_VERSION_ERROR
;
92 /* initialize state */
94 return Z_STREAM_ERROR
;
96 if (z
->zalloc
== Z_NULL
)
99 z
->opaque
= (voidpf
)0;
101 if (z
->zfree
== Z_NULL
) z
->zfree
= zcfree
;
102 if ((z
->state
= (struct internal_state FAR
*)
103 ZALLOC(z
,1,sizeof(struct internal_state
))) == Z_NULL
)
105 z
->state
->blocks
= Z_NULL
;
107 /* handle undocumented nowrap option (no zlib header or check) */
108 z
->state
->nowrap
= 0;
112 z
->state
->nowrap
= 1;
115 /* set window size */
119 return Z_STREAM_ERROR
;
121 z
->state
->wbits
= (uInt
)w
;
123 /* create inflate_blocks state */
124 if ((z
->state
->blocks
=
125 inflate_blocks_new(z
, z
->state
->nowrap
? Z_NULL
: adler32
, (uInt
)1 << w
))
131 Tracev((stderr
, "inflate: allocated\n"));
141 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
144 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
147 ZEXPORT(int) inflate( /* z, f) */
154 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->next_in
== Z_NULL
)
155 return Z_STREAM_ERROR
;
156 f
= f
== Z_FINISH
? Z_BUF_ERROR
: Z_OK
;
158 while (1) switch (z
->state
->mode
)
162 if (((z
->state
->sub
.method
= NEXTBYTE
) & 0xf) != Z_DEFLATED
)
164 z
->state
->mode
= BAD
;
165 z
->msg
= (char*)"unknown compression method";
166 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
169 if ((z
->state
->sub
.method
>> 4) + 8 > z
->state
->wbits
)
171 z
->state
->mode
= BAD
;
172 z
->msg
= (char*)"invalid window size";
173 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
176 z
->state
->mode
= FLAG
;
180 if (((z
->state
->sub
.method
<< 8) + b
) % 31)
182 z
->state
->mode
= BAD
;
183 z
->msg
= (char*)"incorrect header check";
184 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
187 Tracev((stderr
, "inflate: zlib header ok\n"));
188 if (!(b
& PRESET_DICT
))
190 z
->state
->mode
= BLOCKS
;
193 z
->state
->mode
= DICT4
;
196 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
197 z
->state
->mode
= DICT3
;
200 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
201 z
->state
->mode
= DICT2
;
204 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
205 z
->state
->mode
= DICT1
;
208 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
209 z
->adler
= z
->state
->sub
.check
.need
;
210 z
->state
->mode
= DICT0
;
213 z
->state
->mode
= BAD
;
214 z
->msg
= (char*)"need dictionary";
215 z
->state
->sub
.marker
= 0; /* can try inflateSync */
216 return Z_STREAM_ERROR
;
218 r
= inflate_blocks(z
->state
->blocks
, z
, r
);
219 if (r
== Z_DATA_ERROR
)
221 z
->state
->mode
= BAD
;
222 z
->state
->sub
.marker
= 0; /* can try inflateSync */
227 if (r
!= Z_STREAM_END
)
230 inflate_blocks_reset(z
->state
->blocks
, z
, &z
->state
->sub
.check
.was
);
231 if (z
->state
->nowrap
)
233 z
->state
->mode
= DONE
;
236 z
->state
->mode
= CHECK4
;
239 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
240 z
->state
->mode
= CHECK3
;
243 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
244 z
->state
->mode
= CHECK2
;
247 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
248 z
->state
->mode
= CHECK1
;
251 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
253 if (z
->state
->sub
.check
.was
!= z
->state
->sub
.check
.need
)
255 z
->state
->mode
= BAD
;
256 z
->msg
= (char*)"incorrect data check";
257 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
260 Tracev((stderr
, "inflate: zlib check ok\n"));
261 z
->state
->mode
= DONE
;
267 return Z_STREAM_ERROR
;
269 #ifdef NEED_DUMMY_RETURN
270 return Z_STREAM_ERROR
; /* Some dumb compilers complain without this */