[249] | 1 |
|
---|
| 2 | /*-------------------------------------------------------------*/
|
---|
| 3 | /*--- Library top-level functions. ---*/
|
---|
| 4 | /*--- bzlib.c ---*/
|
---|
| 5 | /*-------------------------------------------------------------*/
|
---|
| 6 |
|
---|
| 7 | /*--
|
---|
| 8 | This file is a part of bzip2 and/or libbzip2, a program and
|
---|
| 9 | library for lossless, block-sorting data compression.
|
---|
| 10 |
|
---|
| 11 | Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
---|
| 12 |
|
---|
| 13 | Redistribution and use in source and binary forms, with or without
|
---|
| 14 | modification, are permitted provided that the following conditions
|
---|
| 15 | are met:
|
---|
| 16 |
|
---|
| 17 | 1. Redistributions of source code must retain the above copyright
|
---|
| 18 | notice, this list of conditions and the following disclaimer.
|
---|
| 19 |
|
---|
| 20 | 2. The origin of this software must not be misrepresented; you must
|
---|
| 21 | not claim that you wrote the original software. If you use this
|
---|
| 22 | software in a product, an acknowledgment in the product
|
---|
| 23 | documentation would be appreciated but is not required.
|
---|
| 24 |
|
---|
| 25 | 3. Altered source versions must be plainly marked as such, and must
|
---|
| 26 | not be misrepresented as being the original software.
|
---|
| 27 |
|
---|
| 28 | 4. The name of the author may not be used to endorse or promote
|
---|
| 29 | products derived from this software without specific prior written
|
---|
| 30 | permission.
|
---|
| 31 |
|
---|
| 32 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
---|
| 33 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
---|
| 34 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
---|
| 35 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
---|
| 36 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
---|
| 37 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
---|
| 38 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
---|
| 39 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
---|
| 40 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
---|
| 41 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
---|
| 42 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
| 43 |
|
---|
| 44 | Julian Seward, Cambridge, UK.
|
---|
| 45 | jseward@acm.org
|
---|
| 46 | bzip2/libbzip2 version 1.0 of 21 March 2000
|
---|
| 47 |
|
---|
| 48 | This program is based on (at least) the work of:
|
---|
| 49 | Mike Burrows
|
---|
| 50 | David Wheeler
|
---|
| 51 | Peter Fenwick
|
---|
| 52 | Alistair Moffat
|
---|
| 53 | Radford Neal
|
---|
| 54 | Ian H. Witten
|
---|
| 55 | Robert Sedgewick
|
---|
| 56 | Jon L. Bentley
|
---|
| 57 |
|
---|
| 58 | For more information on these sources, see the manual.
|
---|
| 59 | --*/
|
---|
| 60 |
|
---|
| 61 | /*--
|
---|
| 62 | CHANGES
|
---|
| 63 | ~~~~~~~
|
---|
| 64 | 0.9.0 -- original version.
|
---|
| 65 |
|
---|
| 66 | 0.9.0a/b -- no changes in this file.
|
---|
| 67 |
|
---|
| 68 | 0.9.0c
|
---|
| 69 | * made zero-length BZ_FLUSH work correctly in bzCompress().
|
---|
| 70 | * fixed bzWrite/bzRead to ignore zero-length requests.
|
---|
| 71 | * fixed bzread to correctly handle read requests after EOF.
|
---|
| 72 | * wrong parameter order in call to bzDecompressInit in
|
---|
| 73 | bzBuffToBuffDecompress. Fixed.
|
---|
| 74 | --*/
|
---|
| 75 |
|
---|
| 76 | #include "bzlib_private.h"
|
---|
| 77 |
|
---|
| 78 | /*---------------------------------------------------*/
|
---|
| 79 | /*--- Decompression stuff ---*/
|
---|
| 80 | /*---------------------------------------------------*/
|
---|
| 81 |
|
---|
| 82 | /*---------------------------------------------------*/
|
---|
| 83 | #ifndef BZ_NO_STDIO
|
---|
| 84 | void BZ2_bz__AssertH__fail ( int errcode )
|
---|
| 85 | {
|
---|
| 86 | fprintf(stderr,
|
---|
| 87 | "\n\nbzip2/libbzip2: internal error number %d.\n"
|
---|
| 88 | "This is a bug in bzip2/libbzip2, %s.\n"
|
---|
| 89 | "Please report it to me at: jseward@acm.org. If this happened\n"
|
---|
| 90 | "when you were using some program which uses libbzip2 as a\n"
|
---|
| 91 | "component, you should also report this bug to the author(s)\n"
|
---|
| 92 | "of that program. Please make an effort to report this bug;\n"
|
---|
| 93 | "timely and accurate bug reports eventually lead to higher\n"
|
---|
| 94 | "quality software. Thanks. Julian Seward, 21 March 2000.\n\n",
|
---|
| 95 | errcode,
|
---|
| 96 | BZ2_bzlibVersion()
|
---|
| 97 | );
|
---|
| 98 | exit(3);
|
---|
| 99 | }
|
---|
| 100 | #endif
|
---|
| 101 |
|
---|
| 102 |
|
---|
| 103 | /*---------------------------------------------------*/
|
---|
| 104 | extern
|
---|
| 105 | int bz_config_ok ( void )
|
---|
| 106 | {
|
---|
| 107 | if (sizeof(int) != 4) return 0;
|
---|
| 108 | if (sizeof(short) != 2) return 0;
|
---|
| 109 | if (sizeof(char) != 1) return 0;
|
---|
| 110 | return 1;
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 | /*---------------------------------------------------*/
|
---|
| 115 | extern
|
---|
| 116 | void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
|
---|
| 117 | {
|
---|
| 118 | void* v = malloc ( items * size );
|
---|
| 119 | return v;
|
---|
| 120 | }
|
---|
| 121 |
|
---|
| 122 | extern
|
---|
| 123 | void default_bzfree ( void* opaque, void* addr )
|
---|
| 124 | {
|
---|
| 125 | if (addr != NULL) free ( addr );
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | /*---------------------------------------------------*/
|
---|
| 129 | int BZ2_bzDecompressInit
|
---|
| 130 | ( bz_stream* strm,
|
---|
| 131 | int verbosity,
|
---|
| 132 | int small )
|
---|
| 133 | {
|
---|
| 134 | DState* s;
|
---|
| 135 |
|
---|
| 136 | if (!bz_config_ok()) return BZ_CONFIG_ERROR;
|
---|
| 137 |
|
---|
| 138 | if (strm == NULL) return BZ_PARAM_ERROR;
|
---|
| 139 | if (small != 0 && small != 1) return BZ_PARAM_ERROR;
|
---|
| 140 | if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
|
---|
| 141 |
|
---|
| 142 | if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
|
---|
| 143 | if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
|
---|
| 144 |
|
---|
| 145 | s = (DState*) BZALLOC( sizeof(DState) );
|
---|
| 146 | if (s == NULL) return BZ_MEM_ERROR;
|
---|
| 147 | s->strm = strm;
|
---|
| 148 | strm->state = s;
|
---|
| 149 | s->state = BZ_X_MAGIC_1;
|
---|
| 150 | s->bsLive = 0;
|
---|
| 151 | s->bsBuff = 0;
|
---|
| 152 | s->calculatedCombinedCRC = 0;
|
---|
| 153 | strm->total_in_lo32 = 0;
|
---|
| 154 | strm->total_in_hi32 = 0;
|
---|
| 155 | strm->total_out_lo32 = 0;
|
---|
| 156 | strm->total_out_hi32 = 0;
|
---|
| 157 | s->smallDecompress = (Bool)small;
|
---|
| 158 | s->ll4 = NULL;
|
---|
| 159 | s->ll16 = NULL;
|
---|
| 160 | s->tt = NULL;
|
---|
| 161 | s->currBlockNo = 0;
|
---|
| 162 | s->verbosity = verbosity;
|
---|
| 163 |
|
---|
| 164 | return BZ_OK;
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 |
|
---|
| 168 | /*---------------------------------------------------*/
|
---|
| 169 | static
|
---|
| 170 | void unRLE_obuf_to_output_FAST ( DState* s )
|
---|
| 171 | {
|
---|
| 172 | UChar k1;
|
---|
| 173 |
|
---|
| 174 | if (s->blockRandomised) {
|
---|
| 175 |
|
---|
| 176 | while (True) {
|
---|
| 177 | /* try to finish existing run */
|
---|
| 178 | while (True) {
|
---|
| 179 | if (s->strm->avail_out == 0) return;
|
---|
| 180 | if (s->state_out_len == 0) break;
|
---|
| 181 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
---|
| 182 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
|
---|
| 183 | s->state_out_len--;
|
---|
| 184 | s->strm->next_out++;
|
---|
| 185 | s->strm->avail_out--;
|
---|
| 186 | s->strm->total_out_lo32++;
|
---|
| 187 | if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 | /* can a new run be started? */
|
---|
| 191 | if (s->nblock_used == s->save_nblock+1) return;
|
---|
| 192 |
|
---|
| 193 |
|
---|
| 194 | s->state_out_len = 1;
|
---|
| 195 | s->state_out_ch = s->k0;
|
---|
| 196 | BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
|
---|
| 197 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 198 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 199 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 200 |
|
---|
| 201 | s->state_out_len = 2;
|
---|
| 202 | BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
|
---|
| 203 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 204 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 205 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 206 |
|
---|
| 207 | s->state_out_len = 3;
|
---|
| 208 | BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
|
---|
| 209 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 210 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 211 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 212 |
|
---|
| 213 | BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
|
---|
| 214 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 215 | s->state_out_len = ((Int32)k1) + 4;
|
---|
| 216 | BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
|
---|
| 217 | s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | } else {
|
---|
| 221 |
|
---|
| 222 | /* restore */
|
---|
| 223 | UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
|
---|
| 224 | UChar c_state_out_ch = s->state_out_ch;
|
---|
| 225 | Int32 c_state_out_len = s->state_out_len;
|
---|
| 226 | Int32 c_nblock_used = s->nblock_used;
|
---|
| 227 | Int32 c_k0 = s->k0;
|
---|
| 228 | UInt32* c_tt = s->tt;
|
---|
| 229 | UInt32 c_tPos = s->tPos;
|
---|
| 230 | char* cs_next_out = s->strm->next_out;
|
---|
| 231 | unsigned int cs_avail_out = s->strm->avail_out;
|
---|
| 232 | /* end restore */
|
---|
| 233 |
|
---|
| 234 | UInt32 avail_out_INIT = cs_avail_out;
|
---|
| 235 | Int32 s_save_nblockPP = s->save_nblock+1;
|
---|
| 236 | unsigned int total_out_lo32_old;
|
---|
| 237 |
|
---|
| 238 | while (True) {
|
---|
| 239 |
|
---|
| 240 | /* try to finish existing run */
|
---|
| 241 | if (c_state_out_len > 0) {
|
---|
| 242 | while (True) {
|
---|
| 243 | if (cs_avail_out == 0) goto return_notr;
|
---|
| 244 | if (c_state_out_len == 1) break;
|
---|
| 245 | *( (UChar*)(cs_next_out) ) = c_state_out_ch;
|
---|
| 246 | BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
|
---|
| 247 | c_state_out_len--;
|
---|
| 248 | cs_next_out++;
|
---|
| 249 | cs_avail_out--;
|
---|
| 250 | }
|
---|
| 251 | s_state_out_len_eq_one:
|
---|
| 252 | {
|
---|
| 253 | if (cs_avail_out == 0) {
|
---|
| 254 | c_state_out_len = 1; goto return_notr;
|
---|
| 255 | };
|
---|
| 256 | *( (UChar*)(cs_next_out) ) = c_state_out_ch;
|
---|
| 257 | BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
|
---|
| 258 | cs_next_out++;
|
---|
| 259 | cs_avail_out--;
|
---|
| 260 | }
|
---|
| 261 | }
|
---|
| 262 | /* can a new run be started? */
|
---|
| 263 | if (c_nblock_used == s_save_nblockPP) {
|
---|
| 264 | c_state_out_len = 0; goto return_notr;
|
---|
| 265 | };
|
---|
| 266 | c_state_out_ch = c_k0;
|
---|
| 267 | BZ_GET_FAST_C(k1); c_nblock_used++;
|
---|
| 268 | if (k1 != c_k0) {
|
---|
| 269 | c_k0 = k1; goto s_state_out_len_eq_one;
|
---|
| 270 | };
|
---|
| 271 | if (c_nblock_used == s_save_nblockPP)
|
---|
| 272 | goto s_state_out_len_eq_one;
|
---|
| 273 |
|
---|
| 274 | c_state_out_len = 2;
|
---|
| 275 | BZ_GET_FAST_C(k1); c_nblock_used++;
|
---|
| 276 | if (c_nblock_used == s_save_nblockPP) continue;
|
---|
| 277 | if (k1 != c_k0) { c_k0 = k1; continue; };
|
---|
| 278 |
|
---|
| 279 | c_state_out_len = 3;
|
---|
| 280 | BZ_GET_FAST_C(k1); c_nblock_used++;
|
---|
| 281 | if (c_nblock_used == s_save_nblockPP) continue;
|
---|
| 282 | if (k1 != c_k0) { c_k0 = k1; continue; };
|
---|
| 283 |
|
---|
| 284 | BZ_GET_FAST_C(k1); c_nblock_used++;
|
---|
| 285 | c_state_out_len = ((Int32)k1) + 4;
|
---|
| 286 | BZ_GET_FAST_C(c_k0); c_nblock_used++;
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 | return_notr:
|
---|
| 290 | total_out_lo32_old = s->strm->total_out_lo32;
|
---|
| 291 | s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
|
---|
| 292 | if (s->strm->total_out_lo32 < total_out_lo32_old)
|
---|
| 293 | s->strm->total_out_hi32++;
|
---|
| 294 |
|
---|
| 295 | /* save */
|
---|
| 296 | s->calculatedBlockCRC = c_calculatedBlockCRC;
|
---|
| 297 | s->state_out_ch = c_state_out_ch;
|
---|
| 298 | s->state_out_len = c_state_out_len;
|
---|
| 299 | s->nblock_used = c_nblock_used;
|
---|
| 300 | s->k0 = c_k0;
|
---|
| 301 | s->tt = c_tt;
|
---|
| 302 | s->tPos = c_tPos;
|
---|
| 303 | s->strm->next_out = cs_next_out;
|
---|
| 304 | s->strm->avail_out = cs_avail_out;
|
---|
| 305 | /* end save */
|
---|
| 306 | }
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 |
|
---|
| 310 |
|
---|
| 311 | /*---------------------------------------------------*/
|
---|
| 312 | __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
|
---|
| 313 | {
|
---|
| 314 | Int32 nb, na, mid;
|
---|
| 315 | nb = 0;
|
---|
| 316 | na = 256;
|
---|
| 317 | do {
|
---|
| 318 | mid = (nb + na) >> 1;
|
---|
| 319 | if (indx >= cftab[mid]) nb = mid; else na = mid;
|
---|
| 320 | }
|
---|
| 321 | while (na - nb != 1);
|
---|
| 322 | return nb;
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 |
|
---|
| 326 | /*---------------------------------------------------*/
|
---|
| 327 | static
|
---|
| 328 | void unRLE_obuf_to_output_SMALL ( DState* s )
|
---|
| 329 | {
|
---|
| 330 | UChar k1;
|
---|
| 331 |
|
---|
| 332 | if (s->blockRandomised) {
|
---|
| 333 |
|
---|
| 334 | while (True) {
|
---|
| 335 | /* try to finish existing run */
|
---|
| 336 | while (True) {
|
---|
| 337 | if (s->strm->avail_out == 0) return;
|
---|
| 338 | if (s->state_out_len == 0) break;
|
---|
| 339 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
---|
| 340 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
|
---|
| 341 | s->state_out_len--;
|
---|
| 342 | s->strm->next_out++;
|
---|
| 343 | s->strm->avail_out--;
|
---|
| 344 | s->strm->total_out_lo32++;
|
---|
| 345 | if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
---|
| 346 | }
|
---|
| 347 |
|
---|
| 348 | /* can a new run be started? */
|
---|
| 349 | if (s->nblock_used == s->save_nblock+1) return;
|
---|
| 350 |
|
---|
| 351 |
|
---|
| 352 | s->state_out_len = 1;
|
---|
| 353 | s->state_out_ch = s->k0;
|
---|
| 354 | BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
|
---|
| 355 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 356 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 357 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 358 |
|
---|
| 359 | s->state_out_len = 2;
|
---|
| 360 | BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
|
---|
| 361 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 362 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 363 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 364 |
|
---|
| 365 | s->state_out_len = 3;
|
---|
| 366 | BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
|
---|
| 367 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 368 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 369 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 370 |
|
---|
| 371 | BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
|
---|
| 372 | k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 373 | s->state_out_len = ((Int32)k1) + 4;
|
---|
| 374 | BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
|
---|
| 375 | s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
|
---|
| 376 | }
|
---|
| 377 |
|
---|
| 378 | } else {
|
---|
| 379 |
|
---|
| 380 | while (True) {
|
---|
| 381 | /* try to finish existing run */
|
---|
| 382 | while (True) {
|
---|
| 383 | if (s->strm->avail_out == 0) return;
|
---|
| 384 | if (s->state_out_len == 0) break;
|
---|
| 385 | *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
---|
| 386 | BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
|
---|
| 387 | s->state_out_len--;
|
---|
| 388 | s->strm->next_out++;
|
---|
| 389 | s->strm->avail_out--;
|
---|
| 390 | s->strm->total_out_lo32++;
|
---|
| 391 | if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
---|
| 392 | }
|
---|
| 393 |
|
---|
| 394 | /* can a new run be started? */
|
---|
| 395 | if (s->nblock_used == s->save_nblock+1) return;
|
---|
| 396 |
|
---|
| 397 | s->state_out_len = 1;
|
---|
| 398 | s->state_out_ch = s->k0;
|
---|
| 399 | BZ_GET_SMALL(k1); s->nblock_used++;
|
---|
| 400 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 401 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 402 |
|
---|
| 403 | s->state_out_len = 2;
|
---|
| 404 | BZ_GET_SMALL(k1); s->nblock_used++;
|
---|
| 405 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 406 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 407 |
|
---|
| 408 | s->state_out_len = 3;
|
---|
| 409 | BZ_GET_SMALL(k1); s->nblock_used++;
|
---|
| 410 | if (s->nblock_used == s->save_nblock+1) continue;
|
---|
| 411 | if (k1 != s->k0) { s->k0 = k1; continue; };
|
---|
| 412 |
|
---|
| 413 | BZ_GET_SMALL(k1); s->nblock_used++;
|
---|
| 414 | s->state_out_len = ((Int32)k1) + 4;
|
---|
| 415 | BZ_GET_SMALL(s->k0); s->nblock_used++;
|
---|
| 416 | }
|
---|
| 417 |
|
---|
| 418 | }
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 |
|
---|
| 422 | /*---------------------------------------------------*/
|
---|
| 423 | int BZ2_bzDecompress ( bz_stream *strm )
|
---|
| 424 | {
|
---|
| 425 | DState* s;
|
---|
| 426 | if (strm == NULL) return BZ_PARAM_ERROR;
|
---|
| 427 | s = (DState*) strm->state;
|
---|
| 428 | if (s == NULL) return BZ_PARAM_ERROR;
|
---|
| 429 | if (s->strm != strm) return BZ_PARAM_ERROR;
|
---|
| 430 |
|
---|
| 431 | while (True) {
|
---|
| 432 | if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
|
---|
| 433 | if (s->state == BZ_X_OUTPUT) {
|
---|
| 434 | if (s->smallDecompress)
|
---|
| 435 | unRLE_obuf_to_output_SMALL ( s ); else
|
---|
| 436 | unRLE_obuf_to_output_FAST ( s );
|
---|
| 437 | if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
|
---|
| 438 | BZ_FINALISE_CRC ( s->calculatedBlockCRC );
|
---|
| 439 | if (s->verbosity >= 3)
|
---|
| 440 | VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
|
---|
| 441 | s->calculatedBlockCRC );
|
---|
| 442 | if (s->verbosity >= 2) VPrintf0 ( "]" );
|
---|
| 443 | if (s->calculatedBlockCRC != s->storedBlockCRC)
|
---|
| 444 | return BZ_DATA_ERROR;
|
---|
| 445 | s->calculatedCombinedCRC
|
---|
| 446 | = (s->calculatedCombinedCRC << 1) |
|
---|
| 447 | (s->calculatedCombinedCRC >> 31);
|
---|
| 448 | s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
|
---|
| 449 | s->state = BZ_X_BLKHDR_1;
|
---|
| 450 | } else {
|
---|
| 451 | return BZ_OK;
|
---|
| 452 | }
|
---|
| 453 | }
|
---|
| 454 | if (s->state >= BZ_X_MAGIC_1) {
|
---|
| 455 | Int32 r = BZ2_decompress ( s );
|
---|
| 456 | if (r == BZ_STREAM_END) {
|
---|
| 457 | if (s->verbosity >= 3)
|
---|
| 458 | VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
|
---|
| 459 | s->storedCombinedCRC, s->calculatedCombinedCRC );
|
---|
| 460 | if (s->calculatedCombinedCRC != s->storedCombinedCRC)
|
---|
| 461 | return BZ_DATA_ERROR;
|
---|
| 462 | return r;
|
---|
| 463 | }
|
---|
| 464 | if (s->state != BZ_X_OUTPUT) return r;
|
---|
| 465 | }
|
---|
| 466 | }
|
---|
| 467 |
|
---|
| 468 | AssertH ( 0, 6001 );
|
---|
| 469 |
|
---|
| 470 | return 0; /*NOTREACHED*/
|
---|
| 471 | }
|
---|
| 472 |
|
---|
| 473 |
|
---|
| 474 | /*---------------------------------------------------*/
|
---|
| 475 | int BZ2_bzDecompressEnd ( bz_stream *strm )
|
---|
| 476 | {
|
---|
| 477 | DState* s;
|
---|
| 478 | if (strm == NULL) return BZ_PARAM_ERROR;
|
---|
| 479 | s = (DState*) strm->state;
|
---|
| 480 | if (s == NULL) return BZ_PARAM_ERROR;
|
---|
| 481 | if (s->strm != strm) return BZ_PARAM_ERROR;
|
---|
| 482 |
|
---|
| 483 | if (s->tt != NULL) BZFREE(s->tt);
|
---|
| 484 | if (s->ll16 != NULL) BZFREE(s->ll16);
|
---|
| 485 | if (s->ll4 != NULL) BZFREE(s->ll4);
|
---|
| 486 |
|
---|
| 487 | BZFREE(strm->state);
|
---|
| 488 | strm->state = NULL;
|
---|
| 489 |
|
---|
| 490 | return BZ_OK;
|
---|
| 491 | }
|
---|
| 492 |
|
---|
| 493 |
|
---|
| 494 |
|
---|
| 495 | /*-------------------------------------------------------------*/
|
---|
| 496 | /*--- end bzlib.c ---*/
|
---|
| 497 | /*-------------------------------------------------------------*/
|
---|