1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 /*-------------------------------------------------------------*/
18 /*--- Decompression machinery                               ---*/
19 /*---                                        decompress.cpp ---*/
20 /*-------------------------------------------------------------*/
21 
22 /* ------------------------------------------------------------------
23    The original source for this example:
24    This file is part of bzip2/libbzip2, a program and library for
25    lossless, block-sorting data compression.
26 
27    bzip2/libbzip2 version 1.0.6 of 6 September 2010
28    Copyright (C) 1996-2010 Julian Seward <[email protected]>
29 
30    This program, "bzip2", the associated library "libbzip2", and all
31    documentation, are copyright (C) 1996-2010 Julian R Seward.  All
32    rights reserved.
33 
34    Redistribution and use in source and binary forms, with or without
35    modification, are permitted provided that the following conditions
36    are met:
37 
38    1. Redistributions of source code must retain the above copyright
39    notice, this list of conditions and the following disclaimer.
40 
41    2. The origin of this software must not be misrepresented; you must
42    not claim that you wrote the original software.  If you use this
43    software in a product, an acknowledgment in the product
44    documentation would be appreciated but is not required.
45 
46    3. Altered source versions must be plainly marked as such, and must
47    not be misrepresented as being the original software.
48 
49    4. The name of the author may not be used to endorse or promote
50    products derived from this software without specific prior written
51    permission.
52 
53    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
54    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
57    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
59    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
61    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 
65    Julian Seward, [email protected]
66    bzip2/libbzip2 version 1.0.6 of 6 September 2010
67    ------------------------------------------------------------------ */
68 
69 #include "bzlib_private.hpp"
70 
71 /*---------------------------------------------------*/
makeMaps_d(DState * s)72 static void makeMaps_d(DState* s) {
73     Int32 i;
74     s->nInUse = 0;
75     for (i = 0; i < 256; i++)
76         if (s->inUse[i]) {
77             s->seqToUnseq[s->nInUse] = i;
78             s->nInUse++;
79         }
80 }
81 
82 /*---------------------------------------------------*/
83 #define RETURN(rrr)                 \
84     {                               \
85         retVal = rrr;               \
86         goto save_state_and_return; \
87     };
88 
89 #define GET_BITS(lll, vvv, nnn)                                                       \
90     case lll:                                                                         \
91         s->state = lll;                                                               \
92         while (True) {                                                                \
93             if (s->bsLive >= nnn) {                                                   \
94                 UInt32 v;                                                             \
95                 v = (s->bsBuff >> (s->bsLive - nnn)) & ((1 << nnn) - 1);              \
96                 s->bsLive -= nnn;                                                     \
97                 vvv = v;                                                              \
98                 break;                                                                \
99             }                                                                         \
100             if (s->strm->avail_in == 0)                                               \
101                 RETURN(BZ_OK);                                                        \
102             s->bsBuff = (s->bsBuff << 8) | ((UInt32)(*((UChar*)(s->strm->next_in)))); \
103             s->bsLive += 8;                                                           \
104             s->strm->next_in++;                                                       \
105             s->strm->avail_in--;                                                      \
106             s->strm->total_in_lo32++;                                                 \
107             if (s->strm->total_in_lo32 == 0)                                          \
108                 s->strm->total_in_hi32++;                                             \
109         }
110 
111 #define GET_UCHAR(lll, uuu) GET_BITS(lll, uuu, 8)
112 
113 #define GET_BIT(lll, uuu) GET_BITS(lll, uuu, 1)
114 
115 /*---------------------------------------------------*/
116 #define GET_MTF_VAL(label1, label2, lval)                                  \
117     {                                                                      \
118         if (groupPos == 0) {                                               \
119             groupNo++;                                                     \
120             if (groupNo >= nSelectors)                                     \
121                 RETURN(BZ_DATA_ERROR);                                     \
122             groupPos = BZ_G_SIZE;                                          \
123             gSel = s->selector[groupNo];                                   \
124             gMinlen = s->minLens[gSel];                                    \
125             gLimit = &(s->limit[gSel][0]);                                 \
126             gPerm = &(s->perm[gSel][0]);                                   \
127             gBase = &(s->base[gSel][0]);                                   \
128         }                                                                  \
129         groupPos--;                                                        \
130         zn = gMinlen;                                                      \
131         GET_BITS(label1, zvec, zn);                                        \
132         while (1) {                                                        \
133             if (zn > 20 /* the longest code */)                            \
134                 RETURN(BZ_DATA_ERROR);                                     \
135             if (zvec <= gLimit[zn])                                        \
136                 break;                                                     \
137             zn++;                                                          \
138             GET_BIT(label2, zj);                                           \
139             zvec = (zvec << 1) | zj;                                       \
140         };                                                                 \
141         if (zvec - gBase[zn] < 0 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
142             RETURN(BZ_DATA_ERROR);                                         \
143         lval = gPerm[zvec - gBase[zn]];                                    \
144     }
145 
146 /*---------------------------------------------------*/
BZ2_decompress(DState * s)147 Int32 BZ2_decompress(DState* s) {
148     UChar uc;
149     Int32 retVal;
150     Int32 minLen, maxLen;
151     bz_stream* strm = s->strm;
152 
153     /* stuff that needs to be saved/restored */
154     Int32 i;
155     Int32 j;
156     Int32 t;
157     Int32 alphaSize;
158     Int32 nGroups;
159     Int32 nSelectors;
160     Int32 EOB;
161     Int32 groupNo;
162     Int32 groupPos;
163     Int32 nextSym;
164     Int32 nblockMAX;
165     Int32 nblock;
166     Int32 es;
167     Int32 N;
168     Int32 curr;
169     Int32 zt;
170     Int32 zn;
171     Int32 zvec;
172     Int32 zj;
173     Int32 gSel;
174     Int32 gMinlen;
175     Int32* gLimit;
176     Int32* gBase;
177     Int32* gPerm;
178 
179     if (s->state == BZ_X_MAGIC_1) {
180         /*initialise the save area*/
181         s->save_i = 0;
182         s->save_j = 0;
183         s->save_t = 0;
184         s->save_alphaSize = 0;
185         s->save_nGroups = 0;
186         s->save_nSelectors = 0;
187         s->save_EOB = 0;
188         s->save_groupNo = 0;
189         s->save_groupPos = 0;
190         s->save_nextSym = 0;
191         s->save_nblockMAX = 0;
192         s->save_nblock = 0;
193         s->save_es = 0;
194         s->save_N = 0;
195         s->save_curr = 0;
196         s->save_zt = 0;
197         s->save_zn = 0;
198         s->save_zvec = 0;
199         s->save_zj = 0;
200         s->save_gSel = 0;
201         s->save_gMinlen = 0;
202         s->save_gLimit = nullptr;
203         s->save_gBase = nullptr;
204         s->save_gPerm = nullptr;
205     }
206 
207     /*restore from the save area*/
208     i = s->save_i;
209     j = s->save_j;
210     t = s->save_t;
211     alphaSize = s->save_alphaSize;
212     nGroups = s->save_nGroups;
213     nSelectors = s->save_nSelectors;
214     EOB = s->save_EOB;
215     groupNo = s->save_groupNo;
216     groupPos = s->save_groupPos;
217     nextSym = s->save_nextSym;
218     nblockMAX = s->save_nblockMAX;
219     nblock = s->save_nblock;
220     es = s->save_es;
221     N = s->save_N;
222     curr = s->save_curr;
223     zt = s->save_zt;
224     zn = s->save_zn;
225     zvec = s->save_zvec;
226     zj = s->save_zj;
227     gSel = s->save_gSel;
228     gMinlen = s->save_gMinlen;
229     gLimit = s->save_gLimit;
230     gBase = s->save_gBase;
231     gPerm = s->save_gPerm;
232 
233     retVal = BZ_OK;
234 
235     switch (s->state) {
236         GET_UCHAR(BZ_X_MAGIC_1, uc);
237         if (uc != BZ_HDR_B)
238             RETURN(BZ_DATA_ERROR_MAGIC);
239 
240         GET_UCHAR(BZ_X_MAGIC_2, uc);
241         if (uc != BZ_HDR_Z)
242             RETURN(BZ_DATA_ERROR_MAGIC);
243 
244         GET_UCHAR(BZ_X_MAGIC_3, uc)
245         if (uc != BZ_HDR_h)
246             RETURN(BZ_DATA_ERROR_MAGIC);
247 
248         GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
249         if (s->blockSize100k < (BZ_HDR_0 + 1) || s->blockSize100k > (BZ_HDR_0 + 9))
250             RETURN(BZ_DATA_ERROR_MAGIC);
251         s->blockSize100k -= BZ_HDR_0;
252 
253         if (s->smallDecompress) {
254             s->ll16 = (UInt16*)BZALLOC(s->blockSize100k * 100000 * sizeof(UInt16));
255             s->ll4 = (UChar*)BZALLOC(((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar));
256             if (s->ll16 == nullptr || s->ll4 == nullptr)
257                 RETURN(BZ_MEM_ERROR);
258         }
259         else {
260             s->tt = (UInt32*)BZALLOC(s->blockSize100k * 100000 * sizeof(Int32));
261             if (s->tt == nullptr)
262                 RETURN(BZ_MEM_ERROR);
263         }
264 
265         GET_UCHAR(BZ_X_BLKHDR_1, uc);
266 
267         if (uc == 0x17)
268             goto endhdr_2;
269         if (uc != 0x31)
270             RETURN(BZ_DATA_ERROR);
271         GET_UCHAR(BZ_X_BLKHDR_2, uc);
272         if (uc != 0x41)
273             RETURN(BZ_DATA_ERROR);
274         GET_UCHAR(BZ_X_BLKHDR_3, uc);
275         if (uc != 0x59)
276             RETURN(BZ_DATA_ERROR);
277         GET_UCHAR(BZ_X_BLKHDR_4, uc);
278         if (uc != 0x26)
279             RETURN(BZ_DATA_ERROR);
280         GET_UCHAR(BZ_X_BLKHDR_5, uc);
281         if (uc != 0x53)
282             RETURN(BZ_DATA_ERROR);
283         GET_UCHAR(BZ_X_BLKHDR_6, uc);
284         if (uc != 0x59)
285             RETURN(BZ_DATA_ERROR);
286 
287         s->currBlockNo++;
288         if (s->verbosity >= 2)
289             VPrintf1("\n    [%d: huff+mtf ", s->currBlockNo);
290 
291         s->storedBlockCRC = 0;
292         GET_UCHAR(BZ_X_BCRC_1, uc);
293         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
294         GET_UCHAR(BZ_X_BCRC_2, uc);
295         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
296         GET_UCHAR(BZ_X_BCRC_3, uc);
297         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
298         GET_UCHAR(BZ_X_BCRC_4, uc);
299         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
300 
301         GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
302 
303         s->origPtr = 0;
304         GET_UCHAR(BZ_X_ORIGPTR_1, uc);
305         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
306         GET_UCHAR(BZ_X_ORIGPTR_2, uc);
307         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
308         GET_UCHAR(BZ_X_ORIGPTR_3, uc);
309         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
310 
311         if (s->origPtr < 0)
312             RETURN(BZ_DATA_ERROR);
313         if (s->origPtr > 10 + 100000 * s->blockSize100k)
314             RETURN(BZ_DATA_ERROR);
315 
316         /*--- Receive the mapping table ---*/
317         for (i = 0; i < 16; i++) {
318             GET_BIT(BZ_X_MAPPING_1, uc);
319             if (uc == 1)
320                 s->inUse16[i] = True;
321             else
322                 s->inUse16[i] = False;
323         }
324 
325         for (i = 0; i < 256; i++)
326             s->inUse[i] = False;
327 
328         for (i = 0; i < 16; i++)
329             if (s->inUse16[i])
330                 for (j = 0; j < 16; j++) {
331                     GET_BIT(BZ_X_MAPPING_2, uc);
332                     if (uc == 1)
333                         s->inUse[i * 16 + j] = True;
334                 }
335         makeMaps_d(s);
336         if (s->nInUse == 0)
337             RETURN(BZ_DATA_ERROR);
338         alphaSize = s->nInUse + 2;
339 
340         /*--- Now the selectors ---*/
341         GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
342         if (nGroups < 2 || nGroups > 6)
343             RETURN(BZ_DATA_ERROR);
344         GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
345         if (nSelectors < 1)
346             RETURN(BZ_DATA_ERROR);
347         for (i = 0; i < nSelectors; i++) {
348             j = 0;
349             while (True) {
350                 GET_BIT(BZ_X_SELECTOR_3, uc);
351                 if (uc == 0)
352                     break;
353                 j++;
354                 if (j >= nGroups)
355                     RETURN(BZ_DATA_ERROR);
356             }
357             s->selectorMtf[i] = j;
358         }
359 
360         /*--- Undo the MTF values for the selectors. ---*/
361         {
362             UChar pos[BZ_N_GROUPS], tmp, v;
363             for (i = 0; i < nGroups; i++)
364                 pos[i] = i;
365 
366             for (i = 0; i < nSelectors; i++) {
367                 v = s->selectorMtf[i];
368                 tmp = pos[v];
369                 while (v > 0) {
370                     pos[v] = pos[v - 1];
371                     v--;
372                 }
373                 pos[0] = tmp;
374                 s->selector[i] = tmp;
375             }
376         }
377 
378         /*--- Now the coding tables ---*/
379         for (j = 0; j < nGroups; j++) {
380             GET_BITS(BZ_X_CODING_1, curr, 5);
381             for (i = 0; i < alphaSize; i++) {
382                 while (True) {
383                     if (curr < 1 || curr > 20)
384                         RETURN(BZ_DATA_ERROR);
385                     GET_BIT(BZ_X_CODING_2, uc);
386                     if (uc == 0)
387                         break;
388                     GET_BIT(BZ_X_CODING_3, uc);
389                     if (uc == 0)
390                         curr++;
391                     else
392                         curr--;
393                 }
394                 s->len[j][i] = curr;
395             }
396         }
397 
398         /*--- Create the Huffman decoding tables ---*/
399         for (j = 0; j < nGroups; j++) {
400             minLen = 32;
401             maxLen = 0;
402             for (i = 0; i < alphaSize; i++) {
403                 if (s->len[j][i] > maxLen)
404                     maxLen = s->len[j][i];
405                 if (s->len[j][i] < minLen)
406                     minLen = s->len[j][i];
407             }
408             BZ2_hbCreateDecodeTables(&(s->limit[j][0]),
409                                      &(s->base[j][0]),
410                                      &(s->perm[j][0]),
411                                      &(s->len[j][0]),
412                                      minLen,
413                                      maxLen,
414                                      alphaSize);
415             s->minLens[j] = minLen;
416         }
417 
418         /*--- Now the MTF values ---*/
419 
420         EOB = s->nInUse + 1;
421         nblockMAX = 100000 * s->blockSize100k;
422         groupNo = -1;
423         groupPos = 0;
424 
425         for (i = 0; i <= 255; i++)
426             s->unzftab[i] = 0;
427 
428         /*-- MTF init --*/
429         {
430             Int32 l, j, k;
431             k = MTFA_SIZE - 1;
432             for (l = 256 / MTFL_SIZE - 1; l >= 0; l--) {
433                 for (j = MTFL_SIZE - 1; j >= 0; j--) {
434                     s->mtfa[k] = (UChar)(l * MTFL_SIZE + j);
435                     k--;
436                 }
437                 s->mtfbase[l] = k + 1;
438             }
439         }
440         /*-- end MTF init --*/
441 
442         nblock = 0;
443         GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
444 
445         while (True) {
446             if (nextSym == EOB)
447                 break;
448 
449             if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
450                 es = -1;
451                 N = 1;
452                 do {
453                     /* Check that N doesn't get too big, so that es doesn't
454                   go negative.  The maximum value that can be
455                   RUNA/RUNB encoded is equal to the block size (post
456                   the initial RLE), viz, 900k, so bounding N at 2
457                   million should guard against overflow without
458                   rejecting any legitimate inputs. */
459                     if (N >= 2 * 1024 * 1024)
460                         RETURN(BZ_DATA_ERROR);
461                     if (nextSym == BZ_RUNA)
462                         es = es + (0 + 1) * N;
463                     else if (nextSym == BZ_RUNB)
464                         es = es + (1 + 1) * N;
465                     N = N * 2;
466                     GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
467                 } while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
468 
469                 es++;
470                 uc = s->seqToUnseq[s->mtfa[s->mtfbase[0]]];
471                 s->unzftab[uc] += es;
472 
473                 if (s->smallDecompress)
474                     while (es > 0) {
475                         if (nblock >= nblockMAX)
476                             RETURN(BZ_DATA_ERROR);
477                         s->ll16[nblock] = (UInt16)uc;
478                         nblock++;
479                         es--;
480                     }
481                 else
482                     while (es > 0) {
483                         if (nblock >= nblockMAX)
484                             RETURN(BZ_DATA_ERROR);
485                         s->tt[nblock] = (UInt32)uc;
486                         nblock++;
487                         es--;
488                     };
489 
490                 continue;
491             }
492             else {
493                 if (nblock >= nblockMAX)
494                     RETURN(BZ_DATA_ERROR);
495 
496                 /*-- uc = MTF ( nextSym-1 ) --*/
497                 {
498                     Int32 i, j, k, l, lno, off;
499                     UInt32 nn;
500                     nn = (UInt32)(nextSym - 1);
501 
502                     if (nn < MTFL_SIZE) {
503                         /* avoid general-case expense */
504                         l = s->mtfbase[0];
505                         uc = s->mtfa[l + nn];
506                         while (nn > 3) {
507                             Int32 z = l + nn;
508                             s->mtfa[(z)] = s->mtfa[(z)-1];
509                             s->mtfa[(z)-1] = s->mtfa[(z)-2];
510                             s->mtfa[(z)-2] = s->mtfa[(z)-3];
511                             s->mtfa[(z)-3] = s->mtfa[(z)-4];
512                             nn -= 4;
513                         }
514                         while (nn > 0) {
515                             s->mtfa[(l + nn)] = s->mtfa[(l + nn) - 1];
516                             nn--;
517                         };
518                         s->mtfa[l] = uc;
519                     }
520                     else {
521                         /* general case */
522                         lno = nn / MTFL_SIZE;
523                         off = nn % MTFL_SIZE;
524                         l = s->mtfbase[lno] + off;
525                         uc = s->mtfa[l];
526                         while (l > s->mtfbase[lno]) {
527                             s->mtfa[l] = s->mtfa[l - 1];
528                             l--;
529                         };
530                         s->mtfbase[lno]++;
531                         while (lno > 0) {
532                             s->mtfbase[lno]--;
533                             s->mtfa[s->mtfbase[lno]] = s->mtfa[s->mtfbase[lno - 1] + MTFL_SIZE - 1];
534                             lno--;
535                         }
536                         s->mtfbase[0]--;
537                         s->mtfa[s->mtfbase[0]] = uc;
538                         if (s->mtfbase[0] == 0) {
539                             k = MTFA_SIZE - 1;
540                             for (i = 256 / MTFL_SIZE - 1; i >= 0; i--) {
541                                 for (j = MTFL_SIZE - 1; j >= 0; j--) {
542                                     s->mtfa[k] = s->mtfa[s->mtfbase[i] + j];
543                                     k--;
544                                 }
545                                 s->mtfbase[i] = k + 1;
546                             }
547                         }
548                     }
549                 }
550                 /*-- end uc = MTF ( nextSym-1 ) --*/
551 
552                 s->unzftab[s->seqToUnseq[uc]]++;
553                 if (s->smallDecompress)
554                     s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]);
555                 else
556                     s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
557                 nblock++;
558 
559                 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
560                 continue;
561             }
562         }
563 
564         /* Now we know what nblock is, we can do a better sanity
565          check on s->origPtr.
566       */
567         if (s->origPtr < 0 || s->origPtr >= nblock)
568             RETURN(BZ_DATA_ERROR);
569 
570         /*-- Set up cftab to facilitate generation of T^(-1) --*/
571         /* Check: unzftab entries in range. */
572         for (i = 0; i <= 255; i++) {
573             if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
574                 RETURN(BZ_DATA_ERROR);
575         }
576         /* Actually generate cftab. */
577         s->cftab[0] = 0;
578         for (i = 1; i <= 256; i++)
579             s->cftab[i] = s->unzftab[i - 1];
580         for (i = 1; i <= 256; i++)
581             s->cftab[i] += s->cftab[i - 1];
582         /* Check: cftab entries in range. */
583         for (i = 0; i <= 256; i++) {
584             if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
585                 /* s->cftab[i] can legitimately be == nblock */
586                 RETURN(BZ_DATA_ERROR);
587             }
588         }
589         /* Check: cftab entries non-descending. */
590         for (i = 1; i <= 256; i++) {
591             if (s->cftab[i - 1] > s->cftab[i]) {
592                 RETURN(BZ_DATA_ERROR);
593             }
594         }
595 
596         s->state_out_len = 0;
597         s->state_out_ch = 0;
598         BZ_INITIALISE_CRC(s->calculatedBlockCRC);
599         s->state = BZ_X_OUTPUT;
600         if (s->verbosity >= 2)
601             VPrintf0("rt+rld");
602 
603         if (s->smallDecompress) {
604             /*-- Make a copy of cftab, used in generation of T --*/
605             for (i = 0; i <= 256; i++)
606                 s->cftabCopy[i] = s->cftab[i];
607 
608             /*-- compute the T vector --*/
609             for (i = 0; i < nblock; i++) {
610                 uc = (UChar)(s->ll16[i]);
611                 SET_LL(i, s->cftabCopy[uc]);
612                 s->cftabCopy[uc]++;
613             }
614 
615             /*-- Compute T^(-1) by pointer reversal on T --*/
616             i = s->origPtr;
617             j = GET_LL(i);
618             do {
619                 Int32 tmp = GET_LL(j);
620                 SET_LL(j, i);
621                 i = j;
622                 j = tmp;
623             } while (i != s->origPtr);
624 
625             s->tPos = s->origPtr;
626             s->nblock_used = 0;
627             if (s->blockRandomised) {
628                 BZ_RAND_INIT_MASK;
629                 BZ_GET_SMALL(s->k0);
630                 s->nblock_used++;
631                 BZ_RAND_UPD_MASK;
632                 s->k0 ^= BZ_RAND_MASK;
633             }
634             else {
635                 BZ_GET_SMALL(s->k0);
636                 s->nblock_used++;
637             }
638         }
639         else {
640             /*-- compute the T^(-1) vector --*/
641             for (i = 0; i < nblock; i++) {
642                 uc = (UChar)(s->tt[i] & 0xff);
643                 s->tt[s->cftab[uc]] |= (i << 8);
644                 s->cftab[uc]++;
645             }
646 
647             s->tPos = s->tt[s->origPtr] >> 8;
648             s->nblock_used = 0;
649             if (s->blockRandomised) {
650                 BZ_RAND_INIT_MASK;
651                 BZ_GET_FAST(s->k0);
652                 s->nblock_used++;
653                 BZ_RAND_UPD_MASK;
654                 s->k0 ^= BZ_RAND_MASK;
655             }
656             else {
657                 BZ_GET_FAST(s->k0);
658                 s->nblock_used++;
659             }
660         }
661 
662         RETURN(BZ_OK);
663 
664     endhdr_2:
665 
666         GET_UCHAR(BZ_X_ENDHDR_2, uc);
667         if (uc != 0x72)
668             RETURN(BZ_DATA_ERROR);
669         GET_UCHAR(BZ_X_ENDHDR_3, uc);
670         if (uc != 0x45)
671             RETURN(BZ_DATA_ERROR);
672         GET_UCHAR(BZ_X_ENDHDR_4, uc);
673         if (uc != 0x38)
674             RETURN(BZ_DATA_ERROR);
675         GET_UCHAR(BZ_X_ENDHDR_5, uc);
676         if (uc != 0x50)
677             RETURN(BZ_DATA_ERROR);
678         GET_UCHAR(BZ_X_ENDHDR_6, uc);
679         if (uc != 0x90)
680             RETURN(BZ_DATA_ERROR);
681 
682         s->storedCombinedCRC = 0;
683         GET_UCHAR(BZ_X_CCRC_1, uc);
684         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
685         GET_UCHAR(BZ_X_CCRC_2, uc);
686         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
687         GET_UCHAR(BZ_X_CCRC_3, uc);
688         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
689         GET_UCHAR(BZ_X_CCRC_4, uc);
690         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
691 
692         s->state = BZ_X_IDLE;
693         RETURN(BZ_STREAM_END);
694 
695         default: AssertH(False, 4001);
696     }
697 
698     AssertH(False, 4002);
699 
700 save_state_and_return:
701 
702     s->save_i = i;
703     s->save_j = j;
704     s->save_t = t;
705     s->save_alphaSize = alphaSize;
706     s->save_nGroups = nGroups;
707     s->save_nSelectors = nSelectors;
708     s->save_EOB = EOB;
709     s->save_groupNo = groupNo;
710     s->save_groupPos = groupPos;
711     s->save_nextSym = nextSym;
712     s->save_nblockMAX = nblockMAX;
713     s->save_nblock = nblock;
714     s->save_es = es;
715     s->save_N = N;
716     s->save_curr = curr;
717     s->save_zt = zt;
718     s->save_zn = zn;
719     s->save_zvec = zvec;
720     s->save_zj = zj;
721     s->save_gSel = gSel;
722     s->save_gMinlen = gMinlen;
723     s->save_gLimit = gLimit;
724     s->save_gBase = gBase;
725     s->save_gPerm = gPerm;
726 
727     return retVal;
728 }
729 
730 /*-------------------------------------------------------------*/
731 /*--- end                                      decompress.c ---*/
732 /*-------------------------------------------------------------*/
733