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