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