annotate src/bzip2-1.0.6/decompress.c @ 83:ae30d91d2ffe

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