blob: 53695c13bfc180afb0fcfc10dcc2027854f76eee [file] [log] [blame]
wdenk710e3502003-08-29 20:57:53 +00001#include <config.h>
wdenk8f08c5b2004-10-11 22:43:02 +00002#include <watchdog.h>
wdenk710e3502003-08-29 20:57:53 +00003
4/*-------------------------------------------------------------*/
5/*--- Decompression machinery ---*/
6/*--- decompress.c ---*/
7/*-------------------------------------------------------------*/
8
9/*--
10 This file is a part of bzip2 and/or libbzip2, a program and
11 library for lossless, block-sorting data compression.
12
13 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
14
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions
17 are met:
18
19 1. Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21
22 2. The origin of this software must not be misrepresented; you must
23 not claim that you wrote the original software. If you use this
24 software in a product, an acknowledgment in the product
25 documentation would be appreciated but is not required.
26
27 3. Altered source versions must be plainly marked as such, and must
28 not be misrepresented as being the original software.
29
30 4. The name of the author may not be used to endorse or promote
31 products derived from this software without specific prior written
32 permission.
33
34 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
35 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
38 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
46 Julian Seward, Cambridge, UK.
47 jseward@acm.org
48 bzip2/libbzip2 version 1.0 of 21 March 2000
49
50 This program is based on (at least) the work of:
51 Mike Burrows
52 David Wheeler
53 Peter Fenwick
54 Alistair Moffat
55 Radford Neal
56 Ian H. Witten
57 Robert Sedgewick
58 Jon L. Bentley
59
60 For more information on these sources, see the manual.
61--*/
62
wdenk710e3502003-08-29 20:57:53 +000063#include "bzlib_private.h"
64
wdenk710e3502003-08-29 20:57:53 +000065/*---------------------------------------------------*/
66static
67void makeMaps_d ( DState* s )
68{
69 Int32 i;
70 s->nInUse = 0;
71 for (i = 0; i < 256; i++)
72 if (s->inUse[i]) {
wdenk9c53f402003-10-15 23:53:47 +000073 s->seqToUnseq[s->nInUse] = i;
74 s->nInUse++;
wdenk710e3502003-08-29 20:57:53 +000075 }
76}
77
wdenk710e3502003-08-29 20:57:53 +000078/*---------------------------------------------------*/
79#define RETURN(rrr) \
80 { retVal = rrr; goto save_state_and_return; };
81
82#define GET_BITS(lll,vvv,nnn) \
83 case lll: s->state = lll; \
84 while (True) { \
85 if (s->bsLive >= nnn) { \
wdenk9c53f402003-10-15 23:53:47 +000086 UInt32 v; \
87 v = (s->bsBuff >> \
88 (s->bsLive-nnn)) & ((1 << nnn)-1); \
89 s->bsLive -= nnn; \
90 vvv = v; \
91 break; \
wdenk710e3502003-08-29 20:57:53 +000092 } \
93 if (s->strm->avail_in == 0) RETURN(BZ_OK); \
94 s->bsBuff \
wdenk9c53f402003-10-15 23:53:47 +000095 = (s->bsBuff << 8) | \
96 ((UInt32) \
97 (*((UChar*)(s->strm->next_in)))); \
wdenk710e3502003-08-29 20:57:53 +000098 s->bsLive += 8; \
99 s->strm->next_in++; \
100 s->strm->avail_in--; \
101 s->strm->total_in_lo32++; \
102 if (s->strm->total_in_lo32 == 0) \
wdenk9c53f402003-10-15 23:53:47 +0000103 s->strm->total_in_hi32++; \
wdenk710e3502003-08-29 20:57:53 +0000104 }
105
106#define GET_UCHAR(lll,uuu) \
107 GET_BITS(lll,uuu,8)
108
109#define GET_BIT(lll,uuu) \
110 GET_BITS(lll,uuu,1)
111
112/*---------------------------------------------------*/
113#define GET_MTF_VAL(label1,label2,lval) \
114{ \
115 if (groupPos == 0) { \
116 groupNo++; \
117 if (groupNo >= nSelectors) \
wdenk9c53f402003-10-15 23:53:47 +0000118 RETURN(BZ_DATA_ERROR); \
wdenk710e3502003-08-29 20:57:53 +0000119 groupPos = BZ_G_SIZE; \
120 gSel = s->selector[groupNo]; \
121 gMinlen = s->minLens[gSel]; \
122 gLimit = &(s->limit[gSel][0]); \
123 gPerm = &(s->perm[gSel][0]); \
124 gBase = &(s->base[gSel][0]); \
125 } \
126 groupPos--; \
127 zn = gMinlen; \
128 GET_BITS(label1, zvec, zn); \
129 while (1) { \
130 if (zn > 20 /* the longest code */) \
wdenk9c53f402003-10-15 23:53:47 +0000131 RETURN(BZ_DATA_ERROR); \
wdenk710e3502003-08-29 20:57:53 +0000132 if (zvec <= gLimit[zn]) break; \
133 zn++; \
134 GET_BIT(label2, zj); \
135 zvec = (zvec << 1) | zj; \
136 }; \
137 if (zvec - gBase[zn] < 0 \
138 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
139 RETURN(BZ_DATA_ERROR); \
140 lval = gPerm[zvec - gBase[zn]]; \
141}
142
wdenk710e3502003-08-29 20:57:53 +0000143/*---------------------------------------------------*/
144Int32 BZ2_decompress ( DState* s )
145{
146 UChar uc;
147 Int32 retVal;
148 Int32 minLen, maxLen;
149 bz_stream* strm = s->strm;
150
151 /* stuff that needs to be saved/restored */
152 Int32 i;
153 Int32 j;
154 Int32 t;
155 Int32 alphaSize;
156 Int32 nGroups;
157 Int32 nSelectors;
158 Int32 EOB;
159 Int32 groupNo;
160 Int32 groupPos;
161 Int32 nextSym;
162 Int32 nblockMAX;
163 Int32 nblock;
164 Int32 es;
165 Int32 N;
166 Int32 curr;
167 Int32 zt;
168 Int32 zn;
169 Int32 zvec;
170 Int32 zj;
171 Int32 gSel;
172 Int32 gMinlen;
173 Int32* gLimit;
174 Int32* gBase;
175 Int32* gPerm;
176
177 if (s->state == BZ_X_MAGIC_1) {
178 /*initialise the save area*/
179 s->save_i = 0;
180 s->save_j = 0;
181 s->save_t = 0;
182 s->save_alphaSize = 0;
183 s->save_nGroups = 0;
184 s->save_nSelectors = 0;
185 s->save_EOB = 0;
186 s->save_groupNo = 0;
187 s->save_groupPos = 0;
188 s->save_nextSym = 0;
189 s->save_nblockMAX = 0;
190 s->save_nblock = 0;
191 s->save_es = 0;
192 s->save_N = 0;
193 s->save_curr = 0;
194 s->save_zt = 0;
195 s->save_zn = 0;
196 s->save_zvec = 0;
197 s->save_zj = 0;
198 s->save_gSel = 0;
199 s->save_gMinlen = 0;
200 s->save_gLimit = NULL;
201 s->save_gBase = NULL;
202 s->save_gPerm = NULL;
203 }
204
205 /*restore from the save area*/
206 i = s->save_i;
207 j = s->save_j;
208 t = s->save_t;
209 alphaSize = s->save_alphaSize;
210 nGroups = s->save_nGroups;
211 nSelectors = s->save_nSelectors;
212 EOB = s->save_EOB;
213 groupNo = s->save_groupNo;
214 groupPos = s->save_groupPos;
215 nextSym = s->save_nextSym;
216 nblockMAX = s->save_nblockMAX;
217 nblock = s->save_nblock;
218 es = s->save_es;
219 N = s->save_N;
220 curr = s->save_curr;
221 zt = s->save_zt;
222 zn = s->save_zn;
223 zvec = s->save_zvec;
224 zj = s->save_zj;
225 gSel = s->save_gSel;
226 gMinlen = s->save_gMinlen;
227 gLimit = s->save_gLimit;
228 gBase = s->save_gBase;
229 gPerm = s->save_gPerm;
230
231 retVal = BZ_OK;
232
233 switch (s->state) {
234
235 GET_UCHAR(BZ_X_MAGIC_1, uc);
236 if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
237
238 GET_UCHAR(BZ_X_MAGIC_2, uc);
239 if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
240
241 GET_UCHAR(BZ_X_MAGIC_3, uc)
242 if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
243
244 GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
245 if (s->blockSize100k < (BZ_HDR_0 + 1) ||
wdenk9c53f402003-10-15 23:53:47 +0000246 s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
wdenk710e3502003-08-29 20:57:53 +0000247 s->blockSize100k -= BZ_HDR_0;
248
249 if (s->smallDecompress) {
wdenk9c53f402003-10-15 23:53:47 +0000250 s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
251 s->ll4 = BZALLOC(
252 ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
253 );
254 if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000255 } else {
wdenk9c53f402003-10-15 23:53:47 +0000256 s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
257 if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000258 }
259
260 GET_UCHAR(BZ_X_BLKHDR_1, uc);
261
262 if (uc == 0x17) goto endhdr_2;
263 if (uc != 0x31) RETURN(BZ_DATA_ERROR);
264 GET_UCHAR(BZ_X_BLKHDR_2, uc);
265 if (uc != 0x41) RETURN(BZ_DATA_ERROR);
266 GET_UCHAR(BZ_X_BLKHDR_3, uc);
267 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
268 GET_UCHAR(BZ_X_BLKHDR_4, uc);
269 if (uc != 0x26) RETURN(BZ_DATA_ERROR);
270 GET_UCHAR(BZ_X_BLKHDR_5, uc);
271 if (uc != 0x53) RETURN(BZ_DATA_ERROR);
272 GET_UCHAR(BZ_X_BLKHDR_6, uc);
273 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
274
275 s->currBlockNo++;
276 if (s->verbosity >= 2)
wdenk9c53f402003-10-15 23:53:47 +0000277 VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
wdenk710e3502003-08-29 20:57:53 +0000278
279 s->storedBlockCRC = 0;
280 GET_UCHAR(BZ_X_BCRC_1, uc);
281 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
282 GET_UCHAR(BZ_X_BCRC_2, uc);
283 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
284 GET_UCHAR(BZ_X_BCRC_3, uc);
285 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
286 GET_UCHAR(BZ_X_BCRC_4, uc);
287 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
288
289 GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
290
291 s->origPtr = 0;
292 GET_UCHAR(BZ_X_ORIGPTR_1, uc);
293 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
294 GET_UCHAR(BZ_X_ORIGPTR_2, uc);
295 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
296 GET_UCHAR(BZ_X_ORIGPTR_3, uc);
297 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
298
299 if (s->origPtr < 0)
wdenk9c53f402003-10-15 23:53:47 +0000300 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000301 if (s->origPtr > 10 + 100000*s->blockSize100k)
wdenk9c53f402003-10-15 23:53:47 +0000302 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000303
304 /*--- Receive the mapping table ---*/
305 for (i = 0; i < 16; i++) {
wdenk9c53f402003-10-15 23:53:47 +0000306 GET_BIT(BZ_X_MAPPING_1, uc);
307 if (uc == 1)
308 s->inUse16[i] = True; else
309 s->inUse16[i] = False;
wdenk710e3502003-08-29 20:57:53 +0000310 }
311
312 for (i = 0; i < 256; i++) s->inUse[i] = False;
313
314 for (i = 0; i < 16; i++)
wdenk9c53f402003-10-15 23:53:47 +0000315 if (s->inUse16[i])
316 for (j = 0; j < 16; j++) {
317 GET_BIT(BZ_X_MAPPING_2, uc);
318 if (uc == 1) s->inUse[i * 16 + j] = True;
319 }
wdenk710e3502003-08-29 20:57:53 +0000320 makeMaps_d ( s );
321 if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
322 alphaSize = s->nInUse+2;
323
324 /*--- Now the selectors ---*/
325 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
326 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
327 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
328 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
329 for (i = 0; i < nSelectors; i++) {
wdenk9c53f402003-10-15 23:53:47 +0000330 j = 0;
331 while (True) {
332 GET_BIT(BZ_X_SELECTOR_3, uc);
333 if (uc == 0) break;
334 j++;
335 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
336 }
337 s->selectorMtf[i] = j;
wdenk710e3502003-08-29 20:57:53 +0000338 }
339
340 /*--- Undo the MTF values for the selectors. ---*/
341 {
wdenk9c53f402003-10-15 23:53:47 +0000342 UChar pos[BZ_N_GROUPS], tmp, v;
343 for (v = 0; v < nGroups; v++) pos[v] = v;
wdenk710e3502003-08-29 20:57:53 +0000344
wdenk9c53f402003-10-15 23:53:47 +0000345 for (i = 0; i < nSelectors; i++) {
346 v = s->selectorMtf[i];
347 tmp = pos[v];
348 while (v > 0) { pos[v] = pos[v-1]; v--; }
349 pos[0] = tmp;
350 s->selector[i] = tmp;
351 }
wdenk710e3502003-08-29 20:57:53 +0000352 }
353
354 /*--- Now the coding tables ---*/
355 for (t = 0; t < nGroups; t++) {
wdenk9c53f402003-10-15 23:53:47 +0000356 GET_BITS(BZ_X_CODING_1, curr, 5);
357 for (i = 0; i < alphaSize; i++) {
358 while (True) {
359 if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
360 GET_BIT(BZ_X_CODING_2, uc);
361 if (uc == 0) break;
362 GET_BIT(BZ_X_CODING_3, uc);
363 if (uc == 0) curr++; else curr--;
364 }
365 s->len[t][i] = curr;
366 }
wdenk710e3502003-08-29 20:57:53 +0000367 }
368
369 /*--- Create the Huffman decoding tables ---*/
370 for (t = 0; t < nGroups; t++) {
wdenk9c53f402003-10-15 23:53:47 +0000371 minLen = 32;
372 maxLen = 0;
373 for (i = 0; i < alphaSize; i++) {
374 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
375 if (s->len[t][i] < minLen) minLen = s->len[t][i];
376 }
377 BZ2_hbCreateDecodeTables (
378 &(s->limit[t][0]),
379 &(s->base[t][0]),
380 &(s->perm[t][0]),
381 &(s->len[t][0]),
382 minLen, maxLen, alphaSize
383 );
384 s->minLens[t] = minLen;
wdenk710e3502003-08-29 20:57:53 +0000385 }
386
387 /*--- Now the MTF values ---*/
388
389 EOB = s->nInUse+1;
390 nblockMAX = 100000 * s->blockSize100k;
391 groupNo = -1;
392 groupPos = 0;
393
394 for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
395
396 /*-- MTF init --*/
397 {
wdenk9c53f402003-10-15 23:53:47 +0000398 Int32 ii, jj, kk;
399 kk = MTFA_SIZE-1;
400 for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
401 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
402 s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
403 kk--;
404 }
405 s->mtfbase[ii] = kk + 1;
406 }
wdenk710e3502003-08-29 20:57:53 +0000407 }
408 /*-- end MTF init --*/
409
410 nblock = 0;
411 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
412
413 while (True) {
414
wdenk8f08c5b2004-10-11 22:43:02 +0000415#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Stefan Roese80877fa2022-09-02 14:10:46 +0200416 schedule();
wdenk8f08c5b2004-10-11 22:43:02 +0000417#endif
wdenk9c53f402003-10-15 23:53:47 +0000418 if (nextSym == EOB) break;
wdenk710e3502003-08-29 20:57:53 +0000419
wdenk9c53f402003-10-15 23:53:47 +0000420 if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
wdenk710e3502003-08-29 20:57:53 +0000421
wdenk9c53f402003-10-15 23:53:47 +0000422 es = -1;
423 N = 1;
424 do {
425 if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
426 if (nextSym == BZ_RUNB) es = es + (1+1) * N;
427 N = N * 2;
428 GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
429 }
430 while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
wdenk710e3502003-08-29 20:57:53 +0000431
wdenk9c53f402003-10-15 23:53:47 +0000432 es++;
433 uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
434 s->unzftab[uc] += es;
wdenk710e3502003-08-29 20:57:53 +0000435
wdenk9c53f402003-10-15 23:53:47 +0000436 if (s->smallDecompress)
437 while (es > 0) {
438 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
439 s->ll16[nblock] = (UInt16)uc;
440 nblock++;
441 es--;
442 }
443 else
444 while (es > 0) {
445 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
446 s->tt[nblock] = (UInt32)uc;
447 nblock++;
448 es--;
449 };
wdenk710e3502003-08-29 20:57:53 +0000450
wdenk9c53f402003-10-15 23:53:47 +0000451 continue;
wdenk710e3502003-08-29 20:57:53 +0000452
wdenk9c53f402003-10-15 23:53:47 +0000453 } else {
wdenk710e3502003-08-29 20:57:53 +0000454
wdenk9c53f402003-10-15 23:53:47 +0000455 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000456
wdenk9c53f402003-10-15 23:53:47 +0000457 /*-- uc = MTF ( nextSym-1 ) --*/
458 {
459 Int32 ii, jj, kk, pp, lno, off;
460 UInt32 nn;
461 nn = (UInt32)(nextSym - 1);
wdenk710e3502003-08-29 20:57:53 +0000462
wdenk9c53f402003-10-15 23:53:47 +0000463 if (nn < MTFL_SIZE) {
464 /* avoid general-case expense */
465 pp = s->mtfbase[0];
466 uc = s->mtfa[pp+nn];
467 while (nn > 3) {
468 Int32 z = pp+nn;
469 s->mtfa[(z) ] = s->mtfa[(z)-1];
470 s->mtfa[(z)-1] = s->mtfa[(z)-2];
471 s->mtfa[(z)-2] = s->mtfa[(z)-3];
472 s->mtfa[(z)-3] = s->mtfa[(z)-4];
473 nn -= 4;
474 }
475 while (nn > 0) {
476 s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
477 };
478 s->mtfa[pp] = uc;
479 } else {
480 /* general case */
481 lno = nn / MTFL_SIZE;
482 off = nn % MTFL_SIZE;
483 pp = s->mtfbase[lno] + off;
484 uc = s->mtfa[pp];
485 while (pp > s->mtfbase[lno]) {
486 s->mtfa[pp] = s->mtfa[pp-1]; pp--;
487 };
488 s->mtfbase[lno]++;
489 while (lno > 0) {
490 s->mtfbase[lno]--;
491 s->mtfa[s->mtfbase[lno]]
492 = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
493 lno--;
494 }
495 s->mtfbase[0]--;
496 s->mtfa[s->mtfbase[0]] = uc;
497 if (s->mtfbase[0] == 0) {
498 kk = MTFA_SIZE-1;
499 for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
wdenk8f08c5b2004-10-11 22:43:02 +0000500#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Stefan Roese80877fa2022-09-02 14:10:46 +0200501 schedule();
wdenk8f08c5b2004-10-11 22:43:02 +0000502#endif
wdenk9c53f402003-10-15 23:53:47 +0000503 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
504 s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
505 kk--;
506 }
507 s->mtfbase[ii] = kk + 1;
508 }
509 }
510 }
511 }
512 /*-- end uc = MTF ( nextSym-1 ) --*/
wdenk710e3502003-08-29 20:57:53 +0000513
wdenk9c53f402003-10-15 23:53:47 +0000514 s->unzftab[s->seqToUnseq[uc]]++;
515 if (s->smallDecompress)
516 s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
517 s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
518 nblock++;
wdenk710e3502003-08-29 20:57:53 +0000519
wdenk9c53f402003-10-15 23:53:47 +0000520 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
521 continue;
522 }
wdenk710e3502003-08-29 20:57:53 +0000523 }
524
525 /* Now we know what nblock is, we can do a better sanity
wdenk9c53f402003-10-15 23:53:47 +0000526 check on s->origPtr.
wdenk710e3502003-08-29 20:57:53 +0000527 */
528 if (s->origPtr < 0 || s->origPtr >= nblock)
wdenk9c53f402003-10-15 23:53:47 +0000529 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000530
531 s->state_out_len = 0;
532 s->state_out_ch = 0;
533 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
534 s->state = BZ_X_OUTPUT;
535 if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
536
537 /*-- Set up cftab to facilitate generation of T^(-1) --*/
538 s->cftab[0] = 0;
539 for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
540 for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
541
542 if (s->smallDecompress) {
543
wdenk9c53f402003-10-15 23:53:47 +0000544 /*-- Make a copy of cftab, used in generation of T --*/
545 for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
wdenk710e3502003-08-29 20:57:53 +0000546
wdenk9c53f402003-10-15 23:53:47 +0000547 /*-- compute the T vector --*/
548 for (i = 0; i < nblock; i++) {
549 uc = (UChar)(s->ll16[i]);
550 SET_LL(i, s->cftabCopy[uc]);
551 s->cftabCopy[uc]++;
552 }
wdenk710e3502003-08-29 20:57:53 +0000553
wdenk9c53f402003-10-15 23:53:47 +0000554 /*-- Compute T^(-1) by pointer reversal on T --*/
555 i = s->origPtr;
556 j = GET_LL(i);
557 do {
558 Int32 tmp = GET_LL(j);
559 SET_LL(j, i);
560 i = j;
561 j = tmp;
562 }
563 while (i != s->origPtr);
wdenk710e3502003-08-29 20:57:53 +0000564
wdenk8f08c5b2004-10-11 22:43:02 +0000565#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Stefan Roese80877fa2022-09-02 14:10:46 +0200566 schedule();
wdenk8f08c5b2004-10-11 22:43:02 +0000567#endif
wdenk9c53f402003-10-15 23:53:47 +0000568 s->tPos = s->origPtr;
569 s->nblock_used = 0;
570 if (s->blockRandomised) {
571 BZ_RAND_INIT_MASK;
572 BZ_GET_SMALL(s->k0); s->nblock_used++;
573 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
574 } else {
575 BZ_GET_SMALL(s->k0); s->nblock_used++;
576 }
wdenk710e3502003-08-29 20:57:53 +0000577
578 } else {
579
wdenk8f08c5b2004-10-11 22:43:02 +0000580#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
Stefan Roese80877fa2022-09-02 14:10:46 +0200581 schedule();
wdenk8f08c5b2004-10-11 22:43:02 +0000582#endif
wdenk9c53f402003-10-15 23:53:47 +0000583 /*-- compute the T^(-1) vector --*/
584 for (i = 0; i < nblock; i++) {
585 uc = (UChar)(s->tt[i] & 0xff);
586 s->tt[s->cftab[uc]] |= (i << 8);
587 s->cftab[uc]++;
588 }
wdenk710e3502003-08-29 20:57:53 +0000589
wdenk9c53f402003-10-15 23:53:47 +0000590 s->tPos = s->tt[s->origPtr] >> 8;
591 s->nblock_used = 0;
592 if (s->blockRandomised) {
593 BZ_RAND_INIT_MASK;
594 BZ_GET_FAST(s->k0); s->nblock_used++;
595 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
596 } else {
597 BZ_GET_FAST(s->k0); s->nblock_used++;
598 }
wdenk710e3502003-08-29 20:57:53 +0000599
600 }
601
602 RETURN(BZ_OK);
603
wdenk710e3502003-08-29 20:57:53 +0000604 endhdr_2:
605
606 GET_UCHAR(BZ_X_ENDHDR_2, uc);
607 if (uc != 0x72) RETURN(BZ_DATA_ERROR);
608 GET_UCHAR(BZ_X_ENDHDR_3, uc);
609 if (uc != 0x45) RETURN(BZ_DATA_ERROR);
610 GET_UCHAR(BZ_X_ENDHDR_4, uc);
611 if (uc != 0x38) RETURN(BZ_DATA_ERROR);
612 GET_UCHAR(BZ_X_ENDHDR_5, uc);
613 if (uc != 0x50) RETURN(BZ_DATA_ERROR);
614 GET_UCHAR(BZ_X_ENDHDR_6, uc);
615 if (uc != 0x90) RETURN(BZ_DATA_ERROR);
616
617 s->storedCombinedCRC = 0;
618 GET_UCHAR(BZ_X_CCRC_1, uc);
619 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
620 GET_UCHAR(BZ_X_CCRC_2, uc);
621 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
622 GET_UCHAR(BZ_X_CCRC_3, uc);
623 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
624 GET_UCHAR(BZ_X_CCRC_4, uc);
625 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
626
627 s->state = BZ_X_IDLE;
628 RETURN(BZ_STREAM_END);
629
630 default: AssertH ( False, 4001 );
631 }
632
633 AssertH ( False, 4002 );
634
635 save_state_and_return:
636
637 s->save_i = i;
638 s->save_j = j;
639 s->save_t = t;
640 s->save_alphaSize = alphaSize;
641 s->save_nGroups = nGroups;
642 s->save_nSelectors = nSelectors;
643 s->save_EOB = EOB;
644 s->save_groupNo = groupNo;
645 s->save_groupPos = groupPos;
646 s->save_nextSym = nextSym;
647 s->save_nblockMAX = nblockMAX;
648 s->save_nblock = nblock;
649 s->save_es = es;
650 s->save_N = N;
651 s->save_curr = curr;
652 s->save_zt = zt;
653 s->save_zn = zn;
654 s->save_zvec = zvec;
655 s->save_zj = zj;
656 s->save_gSel = gSel;
657 s->save_gMinlen = gMinlen;
658 s->save_gLimit = gLimit;
659 s->save_gBase = gBase;
660 s->save_gPerm = gPerm;
661
662 return retVal;
663}
664
wdenk710e3502003-08-29 20:57:53 +0000665/*-------------------------------------------------------------*/
666/*--- end decompress.c ---*/
667/*-------------------------------------------------------------*/