Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninflate.c
Go to the documentation of this file.
00001 /* inflate.c -- zlib interface to inflate modules 00002 * Copyright (C) 1995-2002 Mark Adler 00003 * For conditions of distribution and use, see copyright notice in zlib.h 00004 */ 00005 00006 #include "zutil.h" 00007 #include "infblock.h" 00008 00009 #define DONE INFLATE_DONE 00010 #define BAD INFLATE_BAD 00011 00012 typedef enum { 00013 METHOD, /* waiting for method byte */ 00014 FLAG, /* waiting for flag byte */ 00015 DICT4, /* four dictionary check bytes to go */ 00016 DICT3, /* three dictionary check bytes to go */ 00017 DICT2, /* two dictionary check bytes to go */ 00018 DICT1, /* one dictionary check byte to go */ 00019 DICT0, /* waiting for inflateSetDictionary */ 00020 BLOCKS, /* decompressing blocks */ 00021 CHECK4, /* four check bytes to go */ 00022 CHECK3, /* three check bytes to go */ 00023 CHECK2, /* two check bytes to go */ 00024 CHECK1, /* one check byte to go */ 00025 DONE, /* finished check, done */ 00026 BAD} /* got an error--stay here */ 00027 inflate_mode; 00028 00029 /* inflate private state */ 00030 struct internal_state { 00031 00032 /* mode */ 00033 inflate_mode mode; /* current inflate mode */ 00034 00035 /* mode dependent information */ 00036 union { 00037 uInt method; /* if FLAGS, method byte */ 00038 struct { 00039 uLong was; /* computed check value */ 00040 uLong need; /* stream check value */ 00041 } check; /* if CHECK, check values to compare */ 00042 uInt marker; /* if BAD, inflateSync's marker bytes count */ 00043 } sub; /* submode */ 00044 00045 /* mode independent information */ 00046 int nowrap; /* flag for no wrapper */ 00047 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 00048 inflate_blocks_statef 00049 *blocks; /* current inflate_blocks state */ 00050 00051 }; 00052 00053 00054 ZEXPORT(int) inflateReset( /* z) */ 00055 z_streamp z ) 00056 { 00057 if (z == Z_NULL || z->state == Z_NULL) 00058 return Z_STREAM_ERROR; 00059 z->total_in = z->total_out = 0; 00060 z->msg = Z_NULL; 00061 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 00062 inflate_blocks_reset(z->state->blocks, z, Z_NULL); 00063 Tracev((stderr, "inflate: reset\n")); 00064 return Z_OK; 00065 } 00066 00067 00068 ZEXPORT(int) inflateEnd( /* z) */ 00069 z_streamp z ) 00070 { 00071 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) 00072 return Z_STREAM_ERROR; 00073 if (z->state->blocks != Z_NULL) 00074 inflate_blocks_free(z->state->blocks, z); 00075 ZFREE(z, z->state); 00076 z->state = Z_NULL; 00077 Tracev((stderr, "inflate: end\n")); 00078 return Z_OK; 00079 } 00080 00081 00082 ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ 00083 z_streamp z, 00084 int w, 00085 const char *version, 00086 int stream_size ) 00087 { 00088 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 00089 stream_size != sizeof(z_stream)) 00090 return Z_VERSION_ERROR; 00091 00092 /* initialize state */ 00093 if (z == Z_NULL) 00094 return Z_STREAM_ERROR; 00095 z->msg = Z_NULL; 00096 if (z->zalloc == Z_NULL) 00097 { 00098 z->zalloc = zcalloc; 00099 z->opaque = (voidpf)0; 00100 } 00101 if (z->zfree == Z_NULL) z->zfree = zcfree; 00102 if ((z->state = (struct internal_state FAR *) 00103 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) 00104 return Z_MEM_ERROR; 00105 z->state->blocks = Z_NULL; 00106 00107 /* handle undocumented nowrap option (no zlib header or check) */ 00108 z->state->nowrap = 0; 00109 if (w < 0) 00110 { 00111 w = - w; 00112 z->state->nowrap = 1; 00113 } 00114 00115 /* set window size */ 00116 if (w < 8 || w > 15) 00117 { 00118 inflateEnd(z); 00119 return Z_STREAM_ERROR; 00120 } 00121 z->state->wbits = (uInt)w; 00122 00123 /* create inflate_blocks state */ 00124 if ((z->state->blocks = 00125 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) 00126 == Z_NULL) 00127 { 00128 inflateEnd(z); 00129 return Z_MEM_ERROR; 00130 } 00131 Tracev((stderr, "inflate: allocated\n")); 00132 00133 /* reset state */ 00134 inflateReset(z); 00135 return Z_OK; 00136 } 00137 00138 00139 00140 #undef NEEDBYTE 00141 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;} 00142 00143 #undef NEXTBYTE 00144 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 00145 00146 00147 ZEXPORT(int) inflate( /* z, f) */ 00148 z_streamp z, 00149 int f ) 00150 { 00151 int r; 00152 uInt b; 00153 00154 if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) 00155 return Z_STREAM_ERROR; 00156 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 00157 r = Z_BUF_ERROR; 00158 while (1) switch (z->state->mode) 00159 { 00160 case METHOD: 00161 NEEDBYTE 00162 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 00163 { 00164 z->state->mode = BAD; 00165 z->msg = (char*)"unknown compression method"; 00166 z->state->sub.marker = 5; /* can't try inflateSync */ 00167 break; 00168 } 00169 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 00170 { 00171 z->state->mode = BAD; 00172 z->msg = (char*)"invalid window size"; 00173 z->state->sub.marker = 5; /* can't try inflateSync */ 00174 break; 00175 } 00176 z->state->mode = FLAG; 00177 case FLAG: 00178 NEEDBYTE 00179 b = NEXTBYTE; 00180 if (((z->state->sub.method << 8) + b) % 31) 00181 { 00182 z->state->mode = BAD; 00183 z->msg = (char*)"incorrect header check"; 00184 z->state->sub.marker = 5; /* can't try inflateSync */ 00185 break; 00186 } 00187 Tracev((stderr, "inflate: zlib header ok\n")); 00188 if (!(b & PRESET_DICT)) 00189 { 00190 z->state->mode = BLOCKS; 00191 break; 00192 } 00193 z->state->mode = DICT4; 00194 case DICT4: 00195 NEEDBYTE 00196 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 00197 z->state->mode = DICT3; 00198 case DICT3: 00199 NEEDBYTE 00200 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 00201 z->state->mode = DICT2; 00202 case DICT2: 00203 NEEDBYTE 00204 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 00205 z->state->mode = DICT1; 00206 case DICT1: 00207 NEEDBYTE 00208 z->state->sub.check.need += (uLong)NEXTBYTE; 00209 z->adler = z->state->sub.check.need; 00210 z->state->mode = DICT0; 00211 return Z_NEED_DICT; 00212 case DICT0: 00213 z->state->mode = BAD; 00214 z->msg = (char*)"need dictionary"; 00215 z->state->sub.marker = 0; /* can try inflateSync */ 00216 return Z_STREAM_ERROR; 00217 case BLOCKS: 00218 r = inflate_blocks(z->state->blocks, z, r); 00219 if (r == Z_DATA_ERROR) 00220 { 00221 z->state->mode = BAD; 00222 z->state->sub.marker = 0; /* can try inflateSync */ 00223 break; 00224 } 00225 if (r == Z_OK) 00226 r = f; 00227 if (r != Z_STREAM_END) 00228 return r; 00229 r = f; 00230 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 00231 if (z->state->nowrap) 00232 { 00233 z->state->mode = DONE; 00234 break; 00235 } 00236 z->state->mode = CHECK4; 00237 case CHECK4: 00238 NEEDBYTE 00239 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 00240 z->state->mode = CHECK3; 00241 case CHECK3: 00242 NEEDBYTE 00243 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 00244 z->state->mode = CHECK2; 00245 case CHECK2: 00246 NEEDBYTE 00247 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 00248 z->state->mode = CHECK1; 00249 case CHECK1: 00250 NEEDBYTE 00251 z->state->sub.check.need += (uLong)NEXTBYTE; 00252 00253 if (z->state->sub.check.was != z->state->sub.check.need) 00254 { 00255 z->state->mode = BAD; 00256 z->msg = (char*)"incorrect data check"; 00257 z->state->sub.marker = 5; /* can't try inflateSync */ 00258 break; 00259 } 00260 Tracev((stderr, "inflate: zlib check ok\n")); 00261 z->state->mode = DONE; 00262 case DONE: 00263 return Z_STREAM_END; 00264 case BAD: 00265 return Z_DATA_ERROR; 00266 default: 00267 return Z_STREAM_ERROR; 00268 } 00269 #ifdef NEED_DUMMY_RETURN 00270 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 00271 #endif 00272 } 00273 Generated on Sun May 27 2012 04:33:51 for ReactOS by
1.7.6.1
|