summaryrefslogtreecommitdiff
path: root/inflate-0.72.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 22:52:17 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 22:52:17 -0700
commit913afb9174bb474104049906c1382dec81826424 (patch)
tree46bb8ca746088f81382b4f33970b9d43c33d9ba3 /inflate-0.72.c
parentbcf78a20978d76f64b7cd46d1a4d7a79a578c77b (diff)
downloadzlib-0.79.tar.gz
zlib-0.79.tar.bz2
zlib-0.79.zip
zlib 0.79v0.79
Diffstat (limited to 'inflate-0.72.c')
-rw-r--r--inflate-0.72.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/inflate-0.72.c b/inflate-0.72.c
new file mode 100644
index 0000000..56b0665
--- /dev/null
+++ b/inflate-0.72.c
@@ -0,0 +1,230 @@
1/* inflate.c -- zlib interface to inflate modules
2 * Copyright (C) 1995 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include "zutil.h"
7#include "infblock.h"
8
9struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
10
11/* inflate private state */
12struct internal_state {
13
14 /* mode */
15 enum {
16 METHOD, /* waiting for method byte */
17 FLAG, /* waiting for flag byte */
18 START, /* make new blocks state */
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 ERROR} /* got an error--stay here */
26 mode; /* current inflate mode */
27
28 /* mode dependent information */
29 union {
30 uInt method; /* if FLAGS, method byte */
31 struct inflate_blocks_state
32 *blocks; /* if BLOCKS, current state */
33 struct {
34 uLong was; /* computed check value */
35 uLong need; /* stream check value */
36 } check; /* if CHECK, check values to compare */
37 } sub; /* submode */
38
39 /* mode independent information */
40 int nowrap; /* flag for no wrapper */
41 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
42
43};
44
45
46int inflateInit(z)
47z_stream *z;
48{
49 return inflateInit2(z, WBITS);
50}
51
52
53int inflateInit2(z, w)
54z_stream *z;
55int w;
56{
57 /* initialize state */
58 if (z == Z_NULL)
59 return Z_STREAM_ERROR;
60 if (z->zalloc == Z_NULL) z->zalloc = zcalloc;
61 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 *)
65 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
66 return Z_MEM_ERROR;
67 z->state->mode = METHOD;
68
69 /* handle undocumented nowrap option (no zlib header or check) */
70 z->state->nowrap = 0;
71 if (w < 0)
72 {
73 w = - w;
74 z->state->nowrap = 1;
75 z->state->mode = START;
76 }
77
78 /* set window size */
79 if (w < 8 || w > 15)
80 {
81 inflateEnd(z);
82 return Z_STREAM_ERROR;
83 }
84 z->state->wbits = w;
85 return Z_OK;
86}
87
88
89#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
90
91int inflate(z, f)
92z_stream *z;
93int f;
94{
95 int r;
96 uInt b;
97 uLong c;
98
99 if (z == Z_NULL || z->next_in == Z_NULL)
100 return Z_STREAM_ERROR;
101 r = Z_BUF_ERROR;
102 while (1) switch (z->state->mode)
103 {
104 case METHOD:
105 if (z->avail_in == 0) return r; r = Z_OK;
106 if (((z->state->sub.method = NEXTBYTE) & 0xf != DEFLATED))
107 {
108 z->state->mode = ERROR;
109 z->msg = "unknown compression method";
110 return Z_DATA_ERROR;
111 }
112 if ((z->state->sub.method >> 4) > z->state->wbits)
113 {
114 z->state->mode = ERROR;
115 z->msg = "invalid window size";
116 return Z_DATA_ERROR;
117 }
118 z->state->mode = FLAG;
119 case FLAG:
120 if (z->avail_in == 0) return r; r = Z_OK;
121 if ((b = NEXTBYTE) & 0x20)
122 {
123 z->state->mode = ERROR;
124 z->msg = "invalid reserved bit";
125 return Z_DATA_ERROR;
126 }
127 if (((z->state->sub.method << 8) + b) % 31)
128 {
129 z->state->mode = ERROR;
130 z->msg = "incorrect header check";
131 return Z_DATA_ERROR;
132 }
133 z->state->mode = START;
134 case START:
135 if ((z->state->sub.blocks =
136 inflate_blocks_new(z,1<< z->state->wbits)) == Z_NULL)
137 return Z_MEM_ERROR;
138 z->state->mode = BLOCKS;
139 case BLOCKS:
140 if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END)
141 return r;
142 inflate_blocks_free(z->state->sub.blocks, z, &c, &r);
143 if (z->state->nowrap)
144 {
145 if (r != -1)
146 z->msg = "inflate bug--took one too many bytes";
147 z->state->mode = r == -1 ? DONE : ERROR;
148 break;
149 }
150 z->state->sub.check.was = c;
151 if (r != -1)
152 {
153 z->state->sub.check.need = (uLong)r << 24;
154 z->state->mode = CHECK3;
155 r = Z_OK;
156 break;
157 }
158 r = Z_OK;
159 z->state->mode = CHECK4;
160 case CHECK4:
161 if (z->avail_in == 0) return r; r = Z_OK;
162 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
163 z->state->mode = CHECK3;
164 case CHECK3:
165 if (z->avail_in == 0) return r; r = Z_OK;
166 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
167 z->state->mode = CHECK2;
168 case CHECK2:
169 if (z->avail_in == 0) return r; r = Z_OK;
170 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
171 z->state->mode = CHECK1;
172 case CHECK1:
173 if (z->avail_in == 0) return r; r = Z_OK;
174 z->state->sub.check.need += (uLong)NEXTBYTE;
175 if (z->state->sub.check.was != z->state->sub.check.need)
176 {
177 z->state->mode = ERROR;
178 z->msg = "incorrect data check";
179 return Z_DATA_ERROR;
180 }
181 z->state->mode = DONE;
182 case DONE:
183 return Z_STREAM_END;
184 case ERROR:
185 return Z_DATA_ERROR;
186 default:
187 return Z_STREAM_ERROR;
188 }
189}
190
191
192int inflateEnd(z)
193z_stream *z;
194{
195 uLong c;
196 int e;
197
198 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
199 return Z_STREAM_ERROR;
200 if (z->state->mode == BLOCKS)
201 inflate_blocks_free(z->state->sub.blocks, z, &c, &e);
202 ZFREE(z, z->state);
203 z->state = Z_NULL;
204 return Z_OK;
205}
206
207
208/* inflateSync not implemented yet--this just consumes input */
209int inflateSync(z)
210z_stream *z;
211{
212 if (z == Z_NULL) return Z_STREAM_ERROR;
213 if (z->avail_in == 0) return Z_BUF_ERROR;
214 do {
215 z->total_in++;
216 } while (--z->avail_in);
217 return Z_DATA_ERROR;
218}
219
220
221/* inflateReset not fully implemented yet--this frees and reallocates */
222int inflateReset(z)
223z_stream *z;
224{
225 int r;
226
227 if ((r = inflateEnd(z)) != Z_OK)
228 return r;
229 return inflateInit(z);
230}