modules/libbz2/src/decompress.c

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*-------------------------------------------------------------*/
michael@0 3 /*--- Decompression machinery ---*/
michael@0 4 /*--- decompress.c ---*/
michael@0 5 /*-------------------------------------------------------------*/
michael@0 6
michael@0 7 /* ------------------------------------------------------------------
michael@0 8 This file is part of bzip2/libbzip2, a program and library for
michael@0 9 lossless, block-sorting data compression.
michael@0 10
michael@0 11 bzip2/libbzip2 version 1.0.4 of 20 December 2006
michael@0 12 Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
michael@0 13
michael@0 14 Please read the WARNING, DISCLAIMER and PATENTS sections in the
michael@0 15 README file.
michael@0 16
michael@0 17 This program is released under the terms of the license contained
michael@0 18 in the file LICENSE.
michael@0 19 ------------------------------------------------------------------ */
michael@0 20
michael@0 21
michael@0 22 #include "bzlib_private.h"
michael@0 23
michael@0 24
michael@0 25 /*---------------------------------------------------*/
michael@0 26 static
michael@0 27 void makeMaps_d ( DState* s )
michael@0 28 {
michael@0 29 Int32 i;
michael@0 30 s->nInUse = 0;
michael@0 31 for (i = 0; i < 256; i++)
michael@0 32 if (s->inUse[i]) {
michael@0 33 s->seqToUnseq[s->nInUse] = i;
michael@0 34 s->nInUse++;
michael@0 35 }
michael@0 36 }
michael@0 37
michael@0 38
michael@0 39 /*---------------------------------------------------*/
michael@0 40 #define RETURN(rrr) \
michael@0 41 { retVal = rrr; goto save_state_and_return; };
michael@0 42
michael@0 43 #define GET_BITS(lll,vvv,nnn) \
michael@0 44 case lll: s->state = lll; \
michael@0 45 while (True) { \
michael@0 46 if (s->bsLive >= nnn) { \
michael@0 47 UInt32 v; \
michael@0 48 v = (s->bsBuff >> \
michael@0 49 (s->bsLive-nnn)) & ((1 << nnn)-1); \
michael@0 50 s->bsLive -= nnn; \
michael@0 51 vvv = v; \
michael@0 52 break; \
michael@0 53 } \
michael@0 54 if (s->strm->avail_in == 0) RETURN(BZ_OK); \
michael@0 55 s->bsBuff \
michael@0 56 = (s->bsBuff << 8) | \
michael@0 57 ((UInt32) \
michael@0 58 (*((UChar*)(s->strm->next_in)))); \
michael@0 59 s->bsLive += 8; \
michael@0 60 s->strm->next_in++; \
michael@0 61 s->strm->avail_in--; \
michael@0 62 s->strm->total_in_lo32++; \
michael@0 63 if (s->strm->total_in_lo32 == 0) \
michael@0 64 s->strm->total_in_hi32++; \
michael@0 65 }
michael@0 66
michael@0 67 #define GET_UCHAR(lll,uuu) \
michael@0 68 GET_BITS(lll,uuu,8)
michael@0 69
michael@0 70 #define GET_BIT(lll,uuu) \
michael@0 71 GET_BITS(lll,uuu,1)
michael@0 72
michael@0 73 /*---------------------------------------------------*/
michael@0 74 #define GET_MTF_VAL(label1,label2,lval) \
michael@0 75 { \
michael@0 76 if (groupPos == 0) { \
michael@0 77 groupNo++; \
michael@0 78 if (groupNo >= nSelectors) \
michael@0 79 RETURN(BZ_DATA_ERROR); \
michael@0 80 groupPos = BZ_G_SIZE; \
michael@0 81 gSel = s->selector[groupNo]; \
michael@0 82 gMinlen = s->minLens[gSel]; \
michael@0 83 gLimit = &(s->limit[gSel][0]); \
michael@0 84 gPerm = &(s->perm[gSel][0]); \
michael@0 85 gBase = &(s->base[gSel][0]); \
michael@0 86 } \
michael@0 87 groupPos--; \
michael@0 88 zn = gMinlen; \
michael@0 89 GET_BITS(label1, zvec, zn); \
michael@0 90 while (1) { \
michael@0 91 if (zn > 20 /* the longest code */) \
michael@0 92 RETURN(BZ_DATA_ERROR); \
michael@0 93 if (zvec <= gLimit[zn]) break; \
michael@0 94 zn++; \
michael@0 95 GET_BIT(label2, zj); \
michael@0 96 zvec = (zvec << 1) | zj; \
michael@0 97 }; \
michael@0 98 if (zvec - gBase[zn] < 0 \
michael@0 99 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
michael@0 100 RETURN(BZ_DATA_ERROR); \
michael@0 101 lval = gPerm[zvec - gBase[zn]]; \
michael@0 102 }
michael@0 103
michael@0 104
michael@0 105 /*---------------------------------------------------*/
michael@0 106 Int32 BZ2_decompress ( DState* s )
michael@0 107 {
michael@0 108 UChar uc;
michael@0 109 Int32 retVal;
michael@0 110 Int32 minLen, maxLen;
michael@0 111 bz_stream* strm = s->strm;
michael@0 112
michael@0 113 /* stuff that needs to be saved/restored */
michael@0 114 Int32 i;
michael@0 115 Int32 j;
michael@0 116 Int32 t;
michael@0 117 Int32 alphaSize;
michael@0 118 Int32 nGroups;
michael@0 119 Int32 nSelectors;
michael@0 120 Int32 EOB;
michael@0 121 Int32 groupNo;
michael@0 122 Int32 groupPos;
michael@0 123 Int32 nextSym;
michael@0 124 Int32 nblockMAX;
michael@0 125 Int32 nblock;
michael@0 126 Int32 es;
michael@0 127 Int32 N;
michael@0 128 Int32 curr;
michael@0 129 Int32 zt;
michael@0 130 Int32 zn;
michael@0 131 Int32 zvec;
michael@0 132 Int32 zj;
michael@0 133 Int32 gSel;
michael@0 134 Int32 gMinlen;
michael@0 135 Int32* gLimit;
michael@0 136 Int32* gBase;
michael@0 137 Int32* gPerm;
michael@0 138
michael@0 139 if (s->state == BZ_X_MAGIC_1) {
michael@0 140 /*initialise the save area*/
michael@0 141 s->save_i = 0;
michael@0 142 s->save_j = 0;
michael@0 143 s->save_t = 0;
michael@0 144 s->save_alphaSize = 0;
michael@0 145 s->save_nGroups = 0;
michael@0 146 s->save_nSelectors = 0;
michael@0 147 s->save_EOB = 0;
michael@0 148 s->save_groupNo = 0;
michael@0 149 s->save_groupPos = 0;
michael@0 150 s->save_nextSym = 0;
michael@0 151 s->save_nblockMAX = 0;
michael@0 152 s->save_nblock = 0;
michael@0 153 s->save_es = 0;
michael@0 154 s->save_N = 0;
michael@0 155 s->save_curr = 0;
michael@0 156 s->save_zt = 0;
michael@0 157 s->save_zn = 0;
michael@0 158 s->save_zvec = 0;
michael@0 159 s->save_zj = 0;
michael@0 160 s->save_gSel = 0;
michael@0 161 s->save_gMinlen = 0;
michael@0 162 s->save_gLimit = NULL;
michael@0 163 s->save_gBase = NULL;
michael@0 164 s->save_gPerm = NULL;
michael@0 165 }
michael@0 166
michael@0 167 /*restore from the save area*/
michael@0 168 i = s->save_i;
michael@0 169 j = s->save_j;
michael@0 170 t = s->save_t;
michael@0 171 alphaSize = s->save_alphaSize;
michael@0 172 nGroups = s->save_nGroups;
michael@0 173 nSelectors = s->save_nSelectors;
michael@0 174 EOB = s->save_EOB;
michael@0 175 groupNo = s->save_groupNo;
michael@0 176 groupPos = s->save_groupPos;
michael@0 177 nextSym = s->save_nextSym;
michael@0 178 nblockMAX = s->save_nblockMAX;
michael@0 179 nblock = s->save_nblock;
michael@0 180 es = s->save_es;
michael@0 181 N = s->save_N;
michael@0 182 curr = s->save_curr;
michael@0 183 zt = s->save_zt;
michael@0 184 zn = s->save_zn;
michael@0 185 zvec = s->save_zvec;
michael@0 186 zj = s->save_zj;
michael@0 187 gSel = s->save_gSel;
michael@0 188 gMinlen = s->save_gMinlen;
michael@0 189 gLimit = s->save_gLimit;
michael@0 190 gBase = s->save_gBase;
michael@0 191 gPerm = s->save_gPerm;
michael@0 192
michael@0 193 retVal = BZ_OK;
michael@0 194
michael@0 195 switch (s->state) {
michael@0 196
michael@0 197 GET_UCHAR(BZ_X_MAGIC_1, uc);
michael@0 198 if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
michael@0 199
michael@0 200 GET_UCHAR(BZ_X_MAGIC_2, uc);
michael@0 201 if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
michael@0 202
michael@0 203 GET_UCHAR(BZ_X_MAGIC_3, uc)
michael@0 204 if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
michael@0 205
michael@0 206 GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
michael@0 207 if (s->blockSize100k < (BZ_HDR_0 + 1) ||
michael@0 208 s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
michael@0 209 s->blockSize100k -= BZ_HDR_0;
michael@0 210
michael@0 211 if (s->smallDecompress) {
michael@0 212 s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
michael@0 213 s->ll4 = BZALLOC(
michael@0 214 ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
michael@0 215 );
michael@0 216 if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
michael@0 217 } else {
michael@0 218 s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
michael@0 219 if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
michael@0 220 }
michael@0 221
michael@0 222 GET_UCHAR(BZ_X_BLKHDR_1, uc);
michael@0 223
michael@0 224 if (uc == 0x17) goto endhdr_2;
michael@0 225 if (uc != 0x31) RETURN(BZ_DATA_ERROR);
michael@0 226 GET_UCHAR(BZ_X_BLKHDR_2, uc);
michael@0 227 if (uc != 0x41) RETURN(BZ_DATA_ERROR);
michael@0 228 GET_UCHAR(BZ_X_BLKHDR_3, uc);
michael@0 229 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
michael@0 230 GET_UCHAR(BZ_X_BLKHDR_4, uc);
michael@0 231 if (uc != 0x26) RETURN(BZ_DATA_ERROR);
michael@0 232 GET_UCHAR(BZ_X_BLKHDR_5, uc);
michael@0 233 if (uc != 0x53) RETURN(BZ_DATA_ERROR);
michael@0 234 GET_UCHAR(BZ_X_BLKHDR_6, uc);
michael@0 235 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
michael@0 236
michael@0 237 s->currBlockNo++;
michael@0 238 if (s->verbosity >= 2)
michael@0 239 VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
michael@0 240
michael@0 241 s->storedBlockCRC = 0;
michael@0 242 GET_UCHAR(BZ_X_BCRC_1, uc);
michael@0 243 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
michael@0 244 GET_UCHAR(BZ_X_BCRC_2, uc);
michael@0 245 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
michael@0 246 GET_UCHAR(BZ_X_BCRC_3, uc);
michael@0 247 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
michael@0 248 GET_UCHAR(BZ_X_BCRC_4, uc);
michael@0 249 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
michael@0 250
michael@0 251 GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
michael@0 252
michael@0 253 s->origPtr = 0;
michael@0 254 GET_UCHAR(BZ_X_ORIGPTR_1, uc);
michael@0 255 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
michael@0 256 GET_UCHAR(BZ_X_ORIGPTR_2, uc);
michael@0 257 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
michael@0 258 GET_UCHAR(BZ_X_ORIGPTR_3, uc);
michael@0 259 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
michael@0 260
michael@0 261 if (s->origPtr < 0)
michael@0 262 RETURN(BZ_DATA_ERROR);
michael@0 263 if (s->origPtr > 10 + 100000*s->blockSize100k)
michael@0 264 RETURN(BZ_DATA_ERROR);
michael@0 265
michael@0 266 /*--- Receive the mapping table ---*/
michael@0 267 for (i = 0; i < 16; i++) {
michael@0 268 GET_BIT(BZ_X_MAPPING_1, uc);
michael@0 269 if (uc == 1)
michael@0 270 s->inUse16[i] = True; else
michael@0 271 s->inUse16[i] = False;
michael@0 272 }
michael@0 273
michael@0 274 for (i = 0; i < 256; i++) s->inUse[i] = False;
michael@0 275
michael@0 276 for (i = 0; i < 16; i++)
michael@0 277 if (s->inUse16[i])
michael@0 278 for (j = 0; j < 16; j++) {
michael@0 279 GET_BIT(BZ_X_MAPPING_2, uc);
michael@0 280 if (uc == 1) s->inUse[i * 16 + j] = True;
michael@0 281 }
michael@0 282 makeMaps_d ( s );
michael@0 283 if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
michael@0 284 alphaSize = s->nInUse+2;
michael@0 285
michael@0 286 /*--- Now the selectors ---*/
michael@0 287 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
michael@0 288 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
michael@0 289 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
michael@0 290 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
michael@0 291 for (i = 0; i < nSelectors; i++) {
michael@0 292 j = 0;
michael@0 293 while (True) {
michael@0 294 GET_BIT(BZ_X_SELECTOR_3, uc);
michael@0 295 if (uc == 0) break;
michael@0 296 j++;
michael@0 297 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
michael@0 298 }
michael@0 299 s->selectorMtf[i] = j;
michael@0 300 }
michael@0 301
michael@0 302 /*--- Undo the MTF values for the selectors. ---*/
michael@0 303 {
michael@0 304 UChar pos[BZ_N_GROUPS], tmp, v;
michael@0 305 for (v = 0; v < nGroups; v++) pos[v] = v;
michael@0 306
michael@0 307 for (i = 0; i < nSelectors; i++) {
michael@0 308 v = s->selectorMtf[i];
michael@0 309 tmp = pos[v];
michael@0 310 while (v > 0) { pos[v] = pos[v-1]; v--; }
michael@0 311 pos[0] = tmp;
michael@0 312 s->selector[i] = tmp;
michael@0 313 }
michael@0 314 }
michael@0 315
michael@0 316 /*--- Now the coding tables ---*/
michael@0 317 for (t = 0; t < nGroups; t++) {
michael@0 318 GET_BITS(BZ_X_CODING_1, curr, 5);
michael@0 319 for (i = 0; i < alphaSize; i++) {
michael@0 320 while (True) {
michael@0 321 if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
michael@0 322 GET_BIT(BZ_X_CODING_2, uc);
michael@0 323 if (uc == 0) break;
michael@0 324 GET_BIT(BZ_X_CODING_3, uc);
michael@0 325 if (uc == 0) curr++; else curr--;
michael@0 326 }
michael@0 327 s->len[t][i] = curr;
michael@0 328 }
michael@0 329 }
michael@0 330
michael@0 331 /*--- Create the Huffman decoding tables ---*/
michael@0 332 for (t = 0; t < nGroups; t++) {
michael@0 333 minLen = 32;
michael@0 334 maxLen = 0;
michael@0 335 for (i = 0; i < alphaSize; i++) {
michael@0 336 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
michael@0 337 if (s->len[t][i] < minLen) minLen = s->len[t][i];
michael@0 338 }
michael@0 339 BZ2_hbCreateDecodeTables (
michael@0 340 &(s->limit[t][0]),
michael@0 341 &(s->base[t][0]),
michael@0 342 &(s->perm[t][0]),
michael@0 343 &(s->len[t][0]),
michael@0 344 minLen, maxLen, alphaSize
michael@0 345 );
michael@0 346 s->minLens[t] = minLen;
michael@0 347 }
michael@0 348
michael@0 349 /*--- Now the MTF values ---*/
michael@0 350
michael@0 351 EOB = s->nInUse+1;
michael@0 352 nblockMAX = 100000 * s->blockSize100k;
michael@0 353 groupNo = -1;
michael@0 354 groupPos = 0;
michael@0 355
michael@0 356 for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
michael@0 357
michael@0 358 /*-- MTF init --*/
michael@0 359 {
michael@0 360 Int32 ii, jj, kk;
michael@0 361 kk = MTFA_SIZE-1;
michael@0 362 for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
michael@0 363 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
michael@0 364 s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
michael@0 365 kk--;
michael@0 366 }
michael@0 367 s->mtfbase[ii] = kk + 1;
michael@0 368 }
michael@0 369 }
michael@0 370 /*-- end MTF init --*/
michael@0 371
michael@0 372 nblock = 0;
michael@0 373 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
michael@0 374
michael@0 375 while (True) {
michael@0 376
michael@0 377 if (nextSym == EOB) break;
michael@0 378
michael@0 379 if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
michael@0 380
michael@0 381 es = -1;
michael@0 382 N = 1;
michael@0 383 do {
michael@0 384 if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
michael@0 385 if (nextSym == BZ_RUNB) es = es + (1+1) * N;
michael@0 386 N = N * 2;
michael@0 387 GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
michael@0 388 }
michael@0 389 while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
michael@0 390
michael@0 391 es++;
michael@0 392 uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
michael@0 393 s->unzftab[uc] += es;
michael@0 394
michael@0 395 if (s->smallDecompress)
michael@0 396 while (es > 0) {
michael@0 397 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
michael@0 398 s->ll16[nblock] = (UInt16)uc;
michael@0 399 nblock++;
michael@0 400 es--;
michael@0 401 }
michael@0 402 else
michael@0 403 while (es > 0) {
michael@0 404 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
michael@0 405 s->tt[nblock] = (UInt32)uc;
michael@0 406 nblock++;
michael@0 407 es--;
michael@0 408 };
michael@0 409
michael@0 410 continue;
michael@0 411
michael@0 412 } else {
michael@0 413
michael@0 414 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
michael@0 415
michael@0 416 /*-- uc = MTF ( nextSym-1 ) --*/
michael@0 417 {
michael@0 418 Int32 ii, jj, kk, pp, lno, off;
michael@0 419 UInt32 nn;
michael@0 420 nn = (UInt32)(nextSym - 1);
michael@0 421
michael@0 422 if (nn < MTFL_SIZE) {
michael@0 423 /* avoid general-case expense */
michael@0 424 pp = s->mtfbase[0];
michael@0 425 uc = s->mtfa[pp+nn];
michael@0 426 while (nn > 3) {
michael@0 427 Int32 z = pp+nn;
michael@0 428 s->mtfa[(z) ] = s->mtfa[(z)-1];
michael@0 429 s->mtfa[(z)-1] = s->mtfa[(z)-2];
michael@0 430 s->mtfa[(z)-2] = s->mtfa[(z)-3];
michael@0 431 s->mtfa[(z)-3] = s->mtfa[(z)-4];
michael@0 432 nn -= 4;
michael@0 433 }
michael@0 434 while (nn > 0) {
michael@0 435 s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
michael@0 436 };
michael@0 437 s->mtfa[pp] = uc;
michael@0 438 } else {
michael@0 439 /* general case */
michael@0 440 lno = nn / MTFL_SIZE;
michael@0 441 off = nn % MTFL_SIZE;
michael@0 442 pp = s->mtfbase[lno] + off;
michael@0 443 uc = s->mtfa[pp];
michael@0 444 while (pp > s->mtfbase[lno]) {
michael@0 445 s->mtfa[pp] = s->mtfa[pp-1]; pp--;
michael@0 446 };
michael@0 447 s->mtfbase[lno]++;
michael@0 448 while (lno > 0) {
michael@0 449 s->mtfbase[lno]--;
michael@0 450 s->mtfa[s->mtfbase[lno]]
michael@0 451 = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
michael@0 452 lno--;
michael@0 453 }
michael@0 454 s->mtfbase[0]--;
michael@0 455 s->mtfa[s->mtfbase[0]] = uc;
michael@0 456 if (s->mtfbase[0] == 0) {
michael@0 457 kk = MTFA_SIZE-1;
michael@0 458 for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
michael@0 459 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
michael@0 460 s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
michael@0 461 kk--;
michael@0 462 }
michael@0 463 s->mtfbase[ii] = kk + 1;
michael@0 464 }
michael@0 465 }
michael@0 466 }
michael@0 467 }
michael@0 468 /*-- end uc = MTF ( nextSym-1 ) --*/
michael@0 469
michael@0 470 s->unzftab[s->seqToUnseq[uc]]++;
michael@0 471 if (s->smallDecompress)
michael@0 472 s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
michael@0 473 s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
michael@0 474 nblock++;
michael@0 475
michael@0 476 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
michael@0 477 continue;
michael@0 478 }
michael@0 479 }
michael@0 480
michael@0 481 /* Now we know what nblock is, we can do a better sanity
michael@0 482 check on s->origPtr.
michael@0 483 */
michael@0 484 if (s->origPtr < 0 || s->origPtr >= nblock)
michael@0 485 RETURN(BZ_DATA_ERROR);
michael@0 486
michael@0 487 /*-- Set up cftab to facilitate generation of T^(-1) --*/
michael@0 488 s->cftab[0] = 0;
michael@0 489 for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
michael@0 490 for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
michael@0 491 for (i = 0; i <= 256; i++) {
michael@0 492 if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
michael@0 493 /* s->cftab[i] can legitimately be == nblock */
michael@0 494 RETURN(BZ_DATA_ERROR);
michael@0 495 }
michael@0 496 }
michael@0 497
michael@0 498 s->state_out_len = 0;
michael@0 499 s->state_out_ch = 0;
michael@0 500 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
michael@0 501 s->state = BZ_X_OUTPUT;
michael@0 502 if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
michael@0 503
michael@0 504 if (s->smallDecompress) {
michael@0 505
michael@0 506 /*-- Make a copy of cftab, used in generation of T --*/
michael@0 507 for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
michael@0 508
michael@0 509 /*-- compute the T vector --*/
michael@0 510 for (i = 0; i < nblock; i++) {
michael@0 511 uc = (UChar)(s->ll16[i]);
michael@0 512 SET_LL(i, s->cftabCopy[uc]);
michael@0 513 s->cftabCopy[uc]++;
michael@0 514 }
michael@0 515
michael@0 516 /*-- Compute T^(-1) by pointer reversal on T --*/
michael@0 517 i = s->origPtr;
michael@0 518 j = GET_LL(i);
michael@0 519 do {
michael@0 520 Int32 tmp = GET_LL(j);
michael@0 521 SET_LL(j, i);
michael@0 522 i = j;
michael@0 523 j = tmp;
michael@0 524 }
michael@0 525 while (i != s->origPtr);
michael@0 526
michael@0 527 s->tPos = s->origPtr;
michael@0 528 s->nblock_used = 0;
michael@0 529 if (s->blockRandomised) {
michael@0 530 BZ_RAND_INIT_MASK;
michael@0 531 BZ_GET_SMALL(s->k0); s->nblock_used++;
michael@0 532 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
michael@0 533 } else {
michael@0 534 BZ_GET_SMALL(s->k0); s->nblock_used++;
michael@0 535 }
michael@0 536
michael@0 537 } else {
michael@0 538
michael@0 539 /*-- compute the T^(-1) vector --*/
michael@0 540 for (i = 0; i < nblock; i++) {
michael@0 541 uc = (UChar)(s->tt[i] & 0xff);
michael@0 542 s->tt[s->cftab[uc]] |= (i << 8);
michael@0 543 s->cftab[uc]++;
michael@0 544 }
michael@0 545
michael@0 546 s->tPos = s->tt[s->origPtr] >> 8;
michael@0 547 s->nblock_used = 0;
michael@0 548 if (s->blockRandomised) {
michael@0 549 BZ_RAND_INIT_MASK;
michael@0 550 BZ_GET_FAST(s->k0); s->nblock_used++;
michael@0 551 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
michael@0 552 } else {
michael@0 553 BZ_GET_FAST(s->k0); s->nblock_used++;
michael@0 554 }
michael@0 555
michael@0 556 }
michael@0 557
michael@0 558 RETURN(BZ_OK);
michael@0 559
michael@0 560
michael@0 561
michael@0 562 endhdr_2:
michael@0 563
michael@0 564 GET_UCHAR(BZ_X_ENDHDR_2, uc);
michael@0 565 if (uc != 0x72) RETURN(BZ_DATA_ERROR);
michael@0 566 GET_UCHAR(BZ_X_ENDHDR_3, uc);
michael@0 567 if (uc != 0x45) RETURN(BZ_DATA_ERROR);
michael@0 568 GET_UCHAR(BZ_X_ENDHDR_4, uc);
michael@0 569 if (uc != 0x38) RETURN(BZ_DATA_ERROR);
michael@0 570 GET_UCHAR(BZ_X_ENDHDR_5, uc);
michael@0 571 if (uc != 0x50) RETURN(BZ_DATA_ERROR);
michael@0 572 GET_UCHAR(BZ_X_ENDHDR_6, uc);
michael@0 573 if (uc != 0x90) RETURN(BZ_DATA_ERROR);
michael@0 574
michael@0 575 s->storedCombinedCRC = 0;
michael@0 576 GET_UCHAR(BZ_X_CCRC_1, uc);
michael@0 577 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
michael@0 578 GET_UCHAR(BZ_X_CCRC_2, uc);
michael@0 579 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
michael@0 580 GET_UCHAR(BZ_X_CCRC_3, uc);
michael@0 581 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
michael@0 582 GET_UCHAR(BZ_X_CCRC_4, uc);
michael@0 583 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
michael@0 584
michael@0 585 s->state = BZ_X_IDLE;
michael@0 586 RETURN(BZ_STREAM_END);
michael@0 587
michael@0 588 default: AssertH ( False, 4001 );
michael@0 589 }
michael@0 590
michael@0 591 AssertH ( False, 4002 );
michael@0 592
michael@0 593 save_state_and_return:
michael@0 594
michael@0 595 s->save_i = i;
michael@0 596 s->save_j = j;
michael@0 597 s->save_t = t;
michael@0 598 s->save_alphaSize = alphaSize;
michael@0 599 s->save_nGroups = nGroups;
michael@0 600 s->save_nSelectors = nSelectors;
michael@0 601 s->save_EOB = EOB;
michael@0 602 s->save_groupNo = groupNo;
michael@0 603 s->save_groupPos = groupPos;
michael@0 604 s->save_nextSym = nextSym;
michael@0 605 s->save_nblockMAX = nblockMAX;
michael@0 606 s->save_nblock = nblock;
michael@0 607 s->save_es = es;
michael@0 608 s->save_N = N;
michael@0 609 s->save_curr = curr;
michael@0 610 s->save_zt = zt;
michael@0 611 s->save_zn = zn;
michael@0 612 s->save_zvec = zvec;
michael@0 613 s->save_zj = zj;
michael@0 614 s->save_gSel = gSel;
michael@0 615 s->save_gMinlen = gMinlen;
michael@0 616 s->save_gLimit = gLimit;
michael@0 617 s->save_gBase = gBase;
michael@0 618 s->save_gPerm = gPerm;
michael@0 619
michael@0 620 return retVal;
michael@0 621 }
michael@0 622
michael@0 623
michael@0 624 /*-------------------------------------------------------------*/
michael@0 625 /*--- end decompress.c ---*/
michael@0 626 /*-------------------------------------------------------------*/

mercurial