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 4 */ 5 6#include "zutil.h" 7#include "infblock.h" 8 9#define DONE INFLATE_DONE 10#define BAD INFLATE_BAD 11 12typedef enum { 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 */ 27inflate_mode; 28 29/* inflate private state */ 30struct internal_state { 31 32 /* mode */ 33 inflate_mode mode; /* current inflate mode */ 34 35 /* mode dependent information */ 36 union { 37 uInt method; /* if FLAGS, method byte */ 38 struct { 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 */ 43 } sub; /* submode */ 44 45 /* mode independent information */ 46 int nowrap; /* flag for no wrapper */ 47 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 48 inflate_blocks_statef 49 *blocks; /* current inflate_blocks state */ 50 51}; 52 53 54ZEXPORT(int) inflateReset( /* z) */ 55z_streamp z ) 56{ 57 if (z == Z_NULL || z->state == Z_NULL) 58 return Z_STREAM_ERROR; 59 z->total_in = z->total_out = 0; 60 z->msg = Z_NULL; 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")); 64 return Z_OK; 65} 66 67 68ZEXPORT(int) inflateEnd( /* z) */ 69z_streamp z ) 70{ 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); 75 ZFREE(z, z->state); 76 z->state = Z_NULL; 77 Tracev((stderr, "inflate: end\n")); 78 return Z_OK; 79} 80 81 82ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ 83z_streamp z, 84int w, 85const char *version, 86int stream_size ) 87{ 88 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 89 stream_size != sizeof(z_stream)) 90 return Z_VERSION_ERROR; 91 92 /* initialize state */ 93 if (z == Z_NULL) 94 return Z_STREAM_ERROR; 95 z->msg = Z_NULL; 96 if (z->zalloc == Z_NULL) 97 { 98 z->zalloc = zcalloc; 99 z->opaque = (voidpf)0; 100 } 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) 104 return Z_MEM_ERROR; 105 z->state->blocks = Z_NULL; 106 107 /* handle undocumented nowrap option (no zlib header or check) */ 108 z->state->nowrap = 0; 109 if (w < 0) 110 { 111 w = - w; 112 z->state->nowrap = 1; 113 } 114 115 /* set window size */ 116 if (w < 8 || w > 15) 117 { 118 inflateEnd(z); 119 return Z_STREAM_ERROR; 120 } 121 z->state->wbits = (uInt)w; 122 123 /* create inflate_blocks state */ 124 if ((z->state->blocks = 125 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) 126 == Z_NULL) 127 { 128 inflateEnd(z); 129 return Z_MEM_ERROR; 130 } 131 Tracev((stderr, "inflate: allocated\n")); 132 133 /* reset state */ 134 inflateReset(z); 135 return Z_OK; 136} 137 138 139 140#undef NEEDBYTE 141#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} 142 143#undef NEXTBYTE 144#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 145 146 147ZEXPORT(int) inflate( /* z, f) */ 148z_streamp z, 149int f ) 150{ 151 int r; 152 uInt b; 153 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; 157 r = Z_BUF_ERROR; 158 while (1) switch (z->state->mode) 159 { 160 case METHOD: 161 NEEDBYTE 162 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 163 { 164 z->state->mode = BAD; 165 z->msg = (char*)"unknown compression method"; 166 z->state->sub.marker = 5; /* can't try inflateSync */ 167 break; 168 } 169 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 170 { 171 z->state->mode = BAD; 172 z->msg = (char*)"invalid window size"; 173 z->state->sub.marker = 5; /* can't try inflateSync */ 174 break; 175 } 176 z->state->mode = FLAG; 177 case FLAG: 178 NEEDBYTE 179 b = NEXTBYTE; 180 if (((z->state->sub.method << 8) + b) % 31) 181 { 182 z->state->mode = BAD; 183 z->msg = (char*)"incorrect header check"; 184 z->state->sub.marker = 5; /* can't try inflateSync */ 185 break; 186 } 187 Tracev((stderr, "inflate: zlib header ok\n")); 188 if (!(b & PRESET_DICT)) 189 { 190 z->state->mode = BLOCKS; 191 break; 192 } 193 z->state->mode = DICT4; 194 case DICT4: 195 NEEDBYTE 196 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 197 z->state->mode = DICT3; 198 case DICT3: 199 NEEDBYTE 200 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 201 z->state->mode = DICT2; 202 case DICT2: 203 NEEDBYTE 204 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 205 z->state->mode = DICT1; 206 case DICT1: 207 NEEDBYTE 208 z->state->sub.check.need += (uLong)NEXTBYTE; 209 z->adler = z->state->sub.check.need; 210 z->state->mode = DICT0; 211 return Z_NEED_DICT; 212 case 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; 217 case BLOCKS: 218 r = inflate_blocks(z->state->blocks, z, r); 219 if (r == Z_DATA_ERROR) 220 { 221 z->state->mode = BAD; 222 z->state->sub.marker = 0; /* can try inflateSync */ 223 break; 224 } 225 if (r == Z_OK) 226 r = f; 227 if (r != Z_STREAM_END) 228 return r; 229 r = f; 230 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 231 if (z->state->nowrap) 232 { 233 z->state->mode = DONE; 234 break; 235 } 236 z->state->mode = CHECK4; 237 case CHECK4: 238 NEEDBYTE 239 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 240 z->state->mode = CHECK3; 241 case CHECK3: 242 NEEDBYTE 243 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 244 z->state->mode = CHECK2; 245 case CHECK2: 246 NEEDBYTE 247 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 248 z->state->mode = CHECK1; 249 case CHECK1: 250 NEEDBYTE 251 z->state->sub.check.need += (uLong)NEXTBYTE; 252 253 if (z->state->sub.check.was != z->state->sub.check.need) 254 { 255 z->state->mode = BAD; 256 z->msg = (char*)"incorrect data check"; 257 z->state->sub.marker = 5; /* can't try inflateSync */ 258 break; 259 } 260 Tracev((stderr, "inflate: zlib check ok\n")); 261 z->state->mode = DONE; 262 case DONE: 263 return Z_STREAM_END; 264 case BAD: 265 return Z_DATA_ERROR; 266 default: 267 return Z_STREAM_ERROR; 268 } 269#ifdef NEED_DUMMY_RETURN 270 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 271#endif 272} 273 274