00001
00002
00003
00004
00005
00006 #include "zutil.h"
00007 #include "infblock.h"
00008
00009 struct inflate_blocks_state {int dummy;};
00010
00011 typedef enum {
00012 METHOD,
00013 FLAG,
00014 DICT4,
00015 DICT3,
00016 DICT2,
00017 DICT1,
00018 DICT0,
00019 BLOCKS,
00020 CHECK4,
00021 CHECK3,
00022 CHECK2,
00023 CHECK1,
00024 DONE,
00025 BAD}
00026 inflate_mode;
00027
00028
00029 struct internal_state {
00030
00031
00032 inflate_mode mode;
00033
00034
00035 union {
00036 uInt method;
00037 struct {
00038 uLong was;
00039 uLong need;
00040 } check;
00041 uInt marker;
00042 } sub;
00043
00044
00045 int nowrap;
00046 uInt wbits;
00047 inflate_blocks_statef
00048 *blocks;
00049
00050 };
00051
00052
00053 int ZEXPORT inflateReset(z)
00054 z_streamp z;
00055 {
00056 if (z == Z_NULL || z->state == Z_NULL)
00057 return Z_STREAM_ERROR;
00058 z->total_in = z->total_out = 0;
00059 z->msg = Z_NULL;
00060 z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
00061 inflate_blocks_reset(z->state->blocks, z, Z_NULL);
00062 Tracev((stderr, "inflate: reset\n"));
00063 return Z_OK;
00064 }
00065
00066
00067 int ZEXPORT inflateEnd(z)
00068 z_streamp z;
00069 {
00070 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
00071 return Z_STREAM_ERROR;
00072 if (z->state->blocks != Z_NULL)
00073 inflate_blocks_free(z->state->blocks, z);
00074 ZFREE(z, z->state);
00075 z->state = Z_NULL;
00076 Tracev((stderr, "inflate: end\n"));
00077 return Z_OK;
00078 }
00079
00080
00081 int ZEXPORT inflateInit2_(z, w, version, stream_size)
00082 z_streamp z;
00083 int w;
00084 const char *version;
00085 int stream_size;
00086 {
00087 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
00088 stream_size != sizeof(z_stream))
00089 return Z_VERSION_ERROR;
00090
00091
00092 if (z == Z_NULL)
00093 return Z_STREAM_ERROR;
00094 z->msg = Z_NULL;
00095 if (z->zalloc == Z_NULL)
00096 {
00097 z->zalloc = zcalloc;
00098 z->opaque = (voidpf)0;
00099 }
00100 if (z->zfree == Z_NULL) z->zfree = zcfree;
00101 if ((z->state = (struct internal_state FAR *)
00102 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
00103 return Z_MEM_ERROR;
00104 z->state->blocks = Z_NULL;
00105
00106
00107 z->state->nowrap = 0;
00108 if (w < 0)
00109 {
00110 w = - w;
00111 z->state->nowrap = 1;
00112 }
00113
00114
00115 if (w < 8 || w > 15)
00116 {
00117 inflateEnd(z);
00118 return Z_STREAM_ERROR;
00119 }
00120 z->state->wbits = (uInt)w;
00121
00122
00123 if ((z->state->blocks =
00124 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
00125 == Z_NULL)
00126 {
00127 inflateEnd(z);
00128 return Z_MEM_ERROR;
00129 }
00130 Tracev((stderr, "inflate: allocated\n"));
00131
00132
00133 inflateReset(z);
00134 return Z_OK;
00135 }
00136
00137
00138 int ZEXPORT inflateInit_(z, version, stream_size)
00139 z_streamp z;
00140 const char *version;
00141 int stream_size;
00142 {
00143 return inflateInit2_(z, DEF_WBITS, version, stream_size);
00144 }
00145
00146
00147 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
00148 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
00149
00150 int ZEXPORT inflate(z, f)
00151 z_streamp z;
00152 int f;
00153 {
00154 int r;
00155 uInt b;
00156
00157 if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
00158 return Z_STREAM_ERROR;
00159 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
00160 r = Z_BUF_ERROR;
00161 while (1) switch (z->state->mode)
00162 {
00163 case METHOD:
00164 NEEDBYTE
00165 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
00166 {
00167 z->state->mode = BAD;
00168 z->msg = (char*)"unknown compression method";
00169 z->state->sub.marker = 5;
00170 break;
00171 }
00172 if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
00173 {
00174 z->state->mode = BAD;
00175 z->msg = (char*)"invalid window size";
00176 z->state->sub.marker = 5;
00177 break;
00178 }
00179 z->state->mode = FLAG;
00180 case FLAG:
00181 NEEDBYTE
00182 b = NEXTBYTE;
00183 if (((z->state->sub.method << 8) + b) % 31)
00184 {
00185 z->state->mode = BAD;
00186 z->msg = (char*)"incorrect header check";
00187 z->state->sub.marker = 5;
00188 break;
00189 }
00190 Tracev((stderr, "inflate: zlib header ok\n"));
00191 if (!(b & PRESET_DICT))
00192 {
00193 z->state->mode = BLOCKS;
00194 break;
00195 }
00196 z->state->mode = DICT4;
00197 case DICT4:
00198 NEEDBYTE
00199 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
00200 z->state->mode = DICT3;
00201 case DICT3:
00202 NEEDBYTE
00203 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
00204 z->state->mode = DICT2;
00205 case DICT2:
00206 NEEDBYTE
00207 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
00208 z->state->mode = DICT1;
00209 case DICT1:
00210 NEEDBYTE
00211 z->state->sub.check.need += (uLong)NEXTBYTE;
00212 z->adler = z->state->sub.check.need;
00213 z->state->mode = DICT0;
00214 return Z_NEED_DICT;
00215 case DICT0:
00216 z->state->mode = BAD;
00217 z->msg = (char*)"need dictionary";
00218 z->state->sub.marker = 0;
00219 return Z_STREAM_ERROR;
00220 case BLOCKS:
00221 r = inflate_blocks(z->state->blocks, z, r);
00222 if (r == Z_DATA_ERROR)
00223 {
00224 z->state->mode = BAD;
00225 z->state->sub.marker = 0;
00226 break;
00227 }
00228 if (r == Z_OK)
00229 r = f;
00230 if (r != Z_STREAM_END)
00231 return r;
00232 r = f;
00233 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
00234 if (z->state->nowrap)
00235 {
00236 z->state->mode = DONE;
00237 break;
00238 }
00239 z->state->mode = CHECK4;
00240 case CHECK4:
00241 NEEDBYTE
00242 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
00243 z->state->mode = CHECK3;
00244 case CHECK3:
00245 NEEDBYTE
00246 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
00247 z->state->mode = CHECK2;
00248 case CHECK2:
00249 NEEDBYTE
00250 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
00251 z->state->mode = CHECK1;
00252 case CHECK1:
00253 NEEDBYTE
00254 z->state->sub.check.need += (uLong)NEXTBYTE;
00255
00256 if (z->state->sub.check.was != z->state->sub.check.need)
00257 {
00258 z->state->mode = BAD;
00259 z->msg = (char*)"incorrect data check";
00260 z->state->sub.marker = 5;
00261 break;
00262 }
00263 Tracev((stderr, "inflate: zlib check ok\n"));
00264 z->state->mode = DONE;
00265 case DONE:
00266 return Z_STREAM_END;
00267 case BAD:
00268 return Z_DATA_ERROR;
00269 default:
00270 return Z_STREAM_ERROR;
00271 }
00272 #ifdef NEED_DUMMY_RETURN
00273 return Z_STREAM_ERROR;
00274 #endif
00275 }
00276
00277
00278 int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
00279 z_streamp z;
00280 const Bytef *dictionary;
00281 uInt dictLength;
00282 {
00283 uInt length = dictLength;
00284
00285 if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
00286 return Z_STREAM_ERROR;
00287
00288 if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
00289 z->adler = 1L;
00290
00291 if (length >= ((uInt)1<<z->state->wbits))
00292 {
00293 length = (1<<z->state->wbits)-1;
00294 dictionary += dictLength - length;
00295 }
00296 inflate_set_dictionary(z->state->blocks, dictionary, length);
00297 z->state->mode = BLOCKS;
00298 return Z_OK;
00299 }
00300
00301
00302 int ZEXPORT inflateSync(z)
00303 z_streamp z;
00304 {
00305 uInt n;
00306 Bytef *p;
00307 uInt m;
00308 uLong r, w;
00309
00310
00311 if (z == Z_NULL || z->state == Z_NULL)
00312 return Z_STREAM_ERROR;
00313 if (z->state->mode != BAD)
00314 {
00315 z->state->mode = BAD;
00316 z->state->sub.marker = 0;
00317 }
00318 if ((n = z->avail_in) == 0)
00319 return Z_BUF_ERROR;
00320 p = z->next_in;
00321 m = z->state->sub.marker;
00322
00323
00324 while (n && m < 4)
00325 {
00326 static const Byte mark[4] = {0, 0, 0xff, 0xff};
00327 if (*p == mark[m])
00328 m++;
00329 else if (*p)
00330 m = 0;
00331 else
00332 m = 4 - m;
00333 p++, n--;
00334 }
00335
00336
00337 z->total_in += p - z->next_in;
00338 z->next_in = p;
00339 z->avail_in = n;
00340 z->state->sub.marker = m;
00341
00342
00343 if (m != 4)
00344 return Z_DATA_ERROR;
00345 r = z->total_in; w = z->total_out;
00346 inflateReset(z);
00347 z->total_in = r; z->total_out = w;
00348 z->state->mode = BLOCKS;
00349 return Z_OK;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 int ZEXPORT inflateSyncPoint(z)
00361 z_streamp z;
00362 {
00363 if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
00364 return Z_STREAM_ERROR;
00365 return inflate_blocks_sync_point(z->state->blocks);
00366 }