blob: a5750520cc40487d20430d60c11dac0a9f5076c0 [file] [log] [blame]
wdenk710e3502003-08-29 20:57:53 +00001#include <config.h>
wdenk8f08c5b2004-10-11 22:43:02 +00002#include <common.h>
3#include <watchdog.h>
wdenk710e3502003-08-29 20:57:53 +00004#ifdef CONFIG_BZIP2
5
6/*-------------------------------------------------------------*/
7/*--- Decompression machinery ---*/
8/*--- decompress.c ---*/
9/*-------------------------------------------------------------*/
10
11/*--
12 This file is a part of bzip2 and/or libbzip2, a program and
13 library for lossless, block-sorting data compression.
14
15 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
16
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions
19 are met:
20
21 1. Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23
24 2. The origin of this software must not be misrepresented; you must
25 not claim that you wrote the original software. If you use this
26 software in a product, an acknowledgment in the product
27 documentation would be appreciated but is not required.
28
29 3. Altered source versions must be plainly marked as such, and must
30 not be misrepresented as being the original software.
31
32 4. The name of the author may not be used to endorse or promote
33 products derived from this software without specific prior written
34 permission.
35
36 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 Julian Seward, Cambridge, UK.
49 jseward@acm.org
50 bzip2/libbzip2 version 1.0 of 21 March 2000
51
52 This program is based on (at least) the work of:
53 Mike Burrows
54 David Wheeler
55 Peter Fenwick
56 Alistair Moffat
57 Radford Neal
58 Ian H. Witten
59 Robert Sedgewick
60 Jon L. Bentley
61
62 For more information on these sources, see the manual.
63--*/
64
65
66#include "bzlib_private.h"
67
68
69/*---------------------------------------------------*/
70static
71void makeMaps_d ( DState* s )
72{
73 Int32 i;
74 s->nInUse = 0;
75 for (i = 0; i < 256; i++)
76 if (s->inUse[i]) {
wdenk9c53f402003-10-15 23:53:47 +000077 s->seqToUnseq[s->nInUse] = i;
78 s->nInUse++;
wdenk710e3502003-08-29 20:57:53 +000079 }
80}
81
82
83/*---------------------------------------------------*/
84#define RETURN(rrr) \
85 { retVal = rrr; goto save_state_and_return; };
86
87#define GET_BITS(lll,vvv,nnn) \
88 case lll: s->state = lll; \
89 while (True) { \
90 if (s->bsLive >= nnn) { \
wdenk9c53f402003-10-15 23:53:47 +000091 UInt32 v; \
92 v = (s->bsBuff >> \
93 (s->bsLive-nnn)) & ((1 << nnn)-1); \
94 s->bsLive -= nnn; \
95 vvv = v; \
96 break; \
wdenk710e3502003-08-29 20:57:53 +000097 } \
98 if (s->strm->avail_in == 0) RETURN(BZ_OK); \
99 s->bsBuff \
wdenk9c53f402003-10-15 23:53:47 +0000100 = (s->bsBuff << 8) | \
101 ((UInt32) \
102 (*((UChar*)(s->strm->next_in)))); \
wdenk710e3502003-08-29 20:57:53 +0000103 s->bsLive += 8; \
104 s->strm->next_in++; \
105 s->strm->avail_in--; \
106 s->strm->total_in_lo32++; \
107 if (s->strm->total_in_lo32 == 0) \
wdenk9c53f402003-10-15 23:53:47 +0000108 s->strm->total_in_hi32++; \
wdenk710e3502003-08-29 20:57:53 +0000109 }
110
111#define GET_UCHAR(lll,uuu) \
112 GET_BITS(lll,uuu,8)
113
114#define GET_BIT(lll,uuu) \
115 GET_BITS(lll,uuu,1)
116
117/*---------------------------------------------------*/
118#define GET_MTF_VAL(label1,label2,lval) \
119{ \
120 if (groupPos == 0) { \
121 groupNo++; \
122 if (groupNo >= nSelectors) \
wdenk9c53f402003-10-15 23:53:47 +0000123 RETURN(BZ_DATA_ERROR); \
wdenk710e3502003-08-29 20:57:53 +0000124 groupPos = BZ_G_SIZE; \
125 gSel = s->selector[groupNo]; \
126 gMinlen = s->minLens[gSel]; \
127 gLimit = &(s->limit[gSel][0]); \
128 gPerm = &(s->perm[gSel][0]); \
129 gBase = &(s->base[gSel][0]); \
130 } \
131 groupPos--; \
132 zn = gMinlen; \
133 GET_BITS(label1, zvec, zn); \
134 while (1) { \
135 if (zn > 20 /* the longest code */) \
wdenk9c53f402003-10-15 23:53:47 +0000136 RETURN(BZ_DATA_ERROR); \
wdenk710e3502003-08-29 20:57:53 +0000137 if (zvec <= gLimit[zn]) break; \
138 zn++; \
139 GET_BIT(label2, zj); \
140 zvec = (zvec << 1) | zj; \
141 }; \
142 if (zvec - gBase[zn] < 0 \
143 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
144 RETURN(BZ_DATA_ERROR); \
145 lval = gPerm[zvec - gBase[zn]]; \
146}
147
148
149/*---------------------------------------------------*/
150Int32 BZ2_decompress ( DState* s )
151{
152 UChar uc;
153 Int32 retVal;
154 Int32 minLen, maxLen;
155 bz_stream* strm = s->strm;
156
157 /* stuff that needs to be saved/restored */
158 Int32 i;
159 Int32 j;
160 Int32 t;
161 Int32 alphaSize;
162 Int32 nGroups;
163 Int32 nSelectors;
164 Int32 EOB;
165 Int32 groupNo;
166 Int32 groupPos;
167 Int32 nextSym;
168 Int32 nblockMAX;
169 Int32 nblock;
170 Int32 es;
171 Int32 N;
172 Int32 curr;
173 Int32 zt;
174 Int32 zn;
175 Int32 zvec;
176 Int32 zj;
177 Int32 gSel;
178 Int32 gMinlen;
179 Int32* gLimit;
180 Int32* gBase;
181 Int32* gPerm;
182
183 if (s->state == BZ_X_MAGIC_1) {
184 /*initialise the save area*/
185 s->save_i = 0;
186 s->save_j = 0;
187 s->save_t = 0;
188 s->save_alphaSize = 0;
189 s->save_nGroups = 0;
190 s->save_nSelectors = 0;
191 s->save_EOB = 0;
192 s->save_groupNo = 0;
193 s->save_groupPos = 0;
194 s->save_nextSym = 0;
195 s->save_nblockMAX = 0;
196 s->save_nblock = 0;
197 s->save_es = 0;
198 s->save_N = 0;
199 s->save_curr = 0;
200 s->save_zt = 0;
201 s->save_zn = 0;
202 s->save_zvec = 0;
203 s->save_zj = 0;
204 s->save_gSel = 0;
205 s->save_gMinlen = 0;
206 s->save_gLimit = NULL;
207 s->save_gBase = NULL;
208 s->save_gPerm = NULL;
209 }
210
211 /*restore from the save area*/
212 i = s->save_i;
213 j = s->save_j;
214 t = s->save_t;
215 alphaSize = s->save_alphaSize;
216 nGroups = s->save_nGroups;
217 nSelectors = s->save_nSelectors;
218 EOB = s->save_EOB;
219 groupNo = s->save_groupNo;
220 groupPos = s->save_groupPos;
221 nextSym = s->save_nextSym;
222 nblockMAX = s->save_nblockMAX;
223 nblock = s->save_nblock;
224 es = s->save_es;
225 N = s->save_N;
226 curr = s->save_curr;
227 zt = s->save_zt;
228 zn = s->save_zn;
229 zvec = s->save_zvec;
230 zj = s->save_zj;
231 gSel = s->save_gSel;
232 gMinlen = s->save_gMinlen;
233 gLimit = s->save_gLimit;
234 gBase = s->save_gBase;
235 gPerm = s->save_gPerm;
236
237 retVal = BZ_OK;
238
239 switch (s->state) {
240
241 GET_UCHAR(BZ_X_MAGIC_1, uc);
242 if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
243
244 GET_UCHAR(BZ_X_MAGIC_2, uc);
245 if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
246
247 GET_UCHAR(BZ_X_MAGIC_3, uc)
248 if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
249
250 GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
251 if (s->blockSize100k < (BZ_HDR_0 + 1) ||
wdenk9c53f402003-10-15 23:53:47 +0000252 s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
wdenk710e3502003-08-29 20:57:53 +0000253 s->blockSize100k -= BZ_HDR_0;
254
255 if (s->smallDecompress) {
wdenk9c53f402003-10-15 23:53:47 +0000256 s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
257 s->ll4 = BZALLOC(
258 ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
259 );
260 if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000261 } else {
wdenk9c53f402003-10-15 23:53:47 +0000262 s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
263 if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000264 }
265
266 GET_UCHAR(BZ_X_BLKHDR_1, uc);
267
268 if (uc == 0x17) goto endhdr_2;
269 if (uc != 0x31) RETURN(BZ_DATA_ERROR);
270 GET_UCHAR(BZ_X_BLKHDR_2, uc);
271 if (uc != 0x41) RETURN(BZ_DATA_ERROR);
272 GET_UCHAR(BZ_X_BLKHDR_3, uc);
273 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
274 GET_UCHAR(BZ_X_BLKHDR_4, uc);
275 if (uc != 0x26) RETURN(BZ_DATA_ERROR);
276 GET_UCHAR(BZ_X_BLKHDR_5, uc);
277 if (uc != 0x53) RETURN(BZ_DATA_ERROR);
278 GET_UCHAR(BZ_X_BLKHDR_6, uc);
279 if (uc != 0x59) RETURN(BZ_DATA_ERROR);
280
281 s->currBlockNo++;
282 if (s->verbosity >= 2)
wdenk9c53f402003-10-15 23:53:47 +0000283 VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
wdenk710e3502003-08-29 20:57:53 +0000284
285 s->storedBlockCRC = 0;
286 GET_UCHAR(BZ_X_BCRC_1, uc);
287 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
288 GET_UCHAR(BZ_X_BCRC_2, uc);
289 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
290 GET_UCHAR(BZ_X_BCRC_3, uc);
291 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
292 GET_UCHAR(BZ_X_BCRC_4, uc);
293 s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
294
295 GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
296
297 s->origPtr = 0;
298 GET_UCHAR(BZ_X_ORIGPTR_1, uc);
299 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
300 GET_UCHAR(BZ_X_ORIGPTR_2, uc);
301 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
302 GET_UCHAR(BZ_X_ORIGPTR_3, uc);
303 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
304
305 if (s->origPtr < 0)
wdenk9c53f402003-10-15 23:53:47 +0000306 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000307 if (s->origPtr > 10 + 100000*s->blockSize100k)
wdenk9c53f402003-10-15 23:53:47 +0000308 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000309
310 /*--- Receive the mapping table ---*/
311 for (i = 0; i < 16; i++) {
wdenk9c53f402003-10-15 23:53:47 +0000312 GET_BIT(BZ_X_MAPPING_1, uc);
313 if (uc == 1)
314 s->inUse16[i] = True; else
315 s->inUse16[i] = False;
wdenk710e3502003-08-29 20:57:53 +0000316 }
317
318 for (i = 0; i < 256; i++) s->inUse[i] = False;
319
320 for (i = 0; i < 16; i++)
wdenk9c53f402003-10-15 23:53:47 +0000321 if (s->inUse16[i])
322 for (j = 0; j < 16; j++) {
323 GET_BIT(BZ_X_MAPPING_2, uc);
324 if (uc == 1) s->inUse[i * 16 + j] = True;
325 }
wdenk710e3502003-08-29 20:57:53 +0000326 makeMaps_d ( s );
327 if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
328 alphaSize = s->nInUse+2;
329
330 /*--- Now the selectors ---*/
331 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
332 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
333 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
334 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
335 for (i = 0; i < nSelectors; i++) {
wdenk9c53f402003-10-15 23:53:47 +0000336 j = 0;
337 while (True) {
338 GET_BIT(BZ_X_SELECTOR_3, uc);
339 if (uc == 0) break;
340 j++;
341 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
342 }
343 s->selectorMtf[i] = j;
wdenk710e3502003-08-29 20:57:53 +0000344 }
345
346 /*--- Undo the MTF values for the selectors. ---*/
347 {
wdenk9c53f402003-10-15 23:53:47 +0000348 UChar pos[BZ_N_GROUPS], tmp, v;
349 for (v = 0; v < nGroups; v++) pos[v] = v;
wdenk710e3502003-08-29 20:57:53 +0000350
wdenk9c53f402003-10-15 23:53:47 +0000351 for (i = 0; i < nSelectors; i++) {
352 v = s->selectorMtf[i];
353 tmp = pos[v];
354 while (v > 0) { pos[v] = pos[v-1]; v--; }
355 pos[0] = tmp;
356 s->selector[i] = tmp;
357 }
wdenk710e3502003-08-29 20:57:53 +0000358 }
359
360 /*--- Now the coding tables ---*/
361 for (t = 0; t < nGroups; t++) {
wdenk9c53f402003-10-15 23:53:47 +0000362 GET_BITS(BZ_X_CODING_1, curr, 5);
363 for (i = 0; i < alphaSize; i++) {
364 while (True) {
365 if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
366 GET_BIT(BZ_X_CODING_2, uc);
367 if (uc == 0) break;
368 GET_BIT(BZ_X_CODING_3, uc);
369 if (uc == 0) curr++; else curr--;
370 }
371 s->len[t][i] = curr;
372 }
wdenk710e3502003-08-29 20:57:53 +0000373 }
374
375 /*--- Create the Huffman decoding tables ---*/
376 for (t = 0; t < nGroups; t++) {
wdenk9c53f402003-10-15 23:53:47 +0000377 minLen = 32;
378 maxLen = 0;
379 for (i = 0; i < alphaSize; i++) {
380 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
381 if (s->len[t][i] < minLen) minLen = s->len[t][i];
382 }
383 BZ2_hbCreateDecodeTables (
384 &(s->limit[t][0]),
385 &(s->base[t][0]),
386 &(s->perm[t][0]),
387 &(s->len[t][0]),
388 minLen, maxLen, alphaSize
389 );
390 s->minLens[t] = minLen;
wdenk710e3502003-08-29 20:57:53 +0000391 }
392
393 /*--- Now the MTF values ---*/
394
395 EOB = s->nInUse+1;
396 nblockMAX = 100000 * s->blockSize100k;
397 groupNo = -1;
398 groupPos = 0;
399
400 for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
401
402 /*-- MTF init --*/
403 {
wdenk9c53f402003-10-15 23:53:47 +0000404 Int32 ii, jj, kk;
405 kk = MTFA_SIZE-1;
406 for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
407 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
408 s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
409 kk--;
410 }
411 s->mtfbase[ii] = kk + 1;
412 }
wdenk710e3502003-08-29 20:57:53 +0000413 }
414 /*-- end MTF init --*/
415
416 nblock = 0;
417 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
418
419 while (True) {
420
wdenk8f08c5b2004-10-11 22:43:02 +0000421#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
422 WATCHDOG_RESET();
423#endif
wdenk9c53f402003-10-15 23:53:47 +0000424 if (nextSym == EOB) break;
wdenk710e3502003-08-29 20:57:53 +0000425
wdenk9c53f402003-10-15 23:53:47 +0000426 if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
wdenk710e3502003-08-29 20:57:53 +0000427
wdenk9c53f402003-10-15 23:53:47 +0000428 es = -1;
429 N = 1;
430 do {
431 if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
432 if (nextSym == BZ_RUNB) es = es + (1+1) * N;
433 N = N * 2;
434 GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
435 }
436 while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
wdenk710e3502003-08-29 20:57:53 +0000437
wdenk9c53f402003-10-15 23:53:47 +0000438 es++;
439 uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
440 s->unzftab[uc] += es;
wdenk710e3502003-08-29 20:57:53 +0000441
wdenk9c53f402003-10-15 23:53:47 +0000442 if (s->smallDecompress)
443 while (es > 0) {
444 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
445 s->ll16[nblock] = (UInt16)uc;
446 nblock++;
447 es--;
448 }
449 else
450 while (es > 0) {
451 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
452 s->tt[nblock] = (UInt32)uc;
453 nblock++;
454 es--;
455 };
wdenk710e3502003-08-29 20:57:53 +0000456
wdenk9c53f402003-10-15 23:53:47 +0000457 continue;
wdenk710e3502003-08-29 20:57:53 +0000458
wdenk9c53f402003-10-15 23:53:47 +0000459 } else {
wdenk710e3502003-08-29 20:57:53 +0000460
wdenk9c53f402003-10-15 23:53:47 +0000461 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000462
wdenk9c53f402003-10-15 23:53:47 +0000463 /*-- uc = MTF ( nextSym-1 ) --*/
464 {
465 Int32 ii, jj, kk, pp, lno, off;
466 UInt32 nn;
467 nn = (UInt32)(nextSym - 1);
wdenk710e3502003-08-29 20:57:53 +0000468
wdenk9c53f402003-10-15 23:53:47 +0000469 if (nn < MTFL_SIZE) {
470 /* avoid general-case expense */
471 pp = s->mtfbase[0];
472 uc = s->mtfa[pp+nn];
473 while (nn > 3) {
474 Int32 z = pp+nn;
475 s->mtfa[(z) ] = s->mtfa[(z)-1];
476 s->mtfa[(z)-1] = s->mtfa[(z)-2];
477 s->mtfa[(z)-2] = s->mtfa[(z)-3];
478 s->mtfa[(z)-3] = s->mtfa[(z)-4];
479 nn -= 4;
480 }
481 while (nn > 0) {
482 s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
483 };
484 s->mtfa[pp] = uc;
485 } else {
486 /* general case */
487 lno = nn / MTFL_SIZE;
488 off = nn % MTFL_SIZE;
489 pp = s->mtfbase[lno] + off;
490 uc = s->mtfa[pp];
491 while (pp > s->mtfbase[lno]) {
492 s->mtfa[pp] = s->mtfa[pp-1]; pp--;
493 };
494 s->mtfbase[lno]++;
495 while (lno > 0) {
496 s->mtfbase[lno]--;
497 s->mtfa[s->mtfbase[lno]]
498 = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
499 lno--;
500 }
501 s->mtfbase[0]--;
502 s->mtfa[s->mtfbase[0]] = uc;
503 if (s->mtfbase[0] == 0) {
504 kk = MTFA_SIZE-1;
505 for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
wdenk8f08c5b2004-10-11 22:43:02 +0000506#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
507 WATCHDOG_RESET();
508#endif
wdenk9c53f402003-10-15 23:53:47 +0000509 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
510 s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
511 kk--;
512 }
513 s->mtfbase[ii] = kk + 1;
514 }
515 }
516 }
517 }
518 /*-- end uc = MTF ( nextSym-1 ) --*/
wdenk710e3502003-08-29 20:57:53 +0000519
wdenk9c53f402003-10-15 23:53:47 +0000520 s->unzftab[s->seqToUnseq[uc]]++;
521 if (s->smallDecompress)
522 s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
523 s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
524 nblock++;
wdenk710e3502003-08-29 20:57:53 +0000525
wdenk9c53f402003-10-15 23:53:47 +0000526 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
527 continue;
528 }
wdenk710e3502003-08-29 20:57:53 +0000529 }
530
531 /* Now we know what nblock is, we can do a better sanity
wdenk9c53f402003-10-15 23:53:47 +0000532 check on s->origPtr.
wdenk710e3502003-08-29 20:57:53 +0000533 */
534 if (s->origPtr < 0 || s->origPtr >= nblock)
wdenk9c53f402003-10-15 23:53:47 +0000535 RETURN(BZ_DATA_ERROR);
wdenk710e3502003-08-29 20:57:53 +0000536
537 s->state_out_len = 0;
538 s->state_out_ch = 0;
539 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
540 s->state = BZ_X_OUTPUT;
541 if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
542
543 /*-- Set up cftab to facilitate generation of T^(-1) --*/
544 s->cftab[0] = 0;
545 for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
546 for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
547
548 if (s->smallDecompress) {
549
wdenk9c53f402003-10-15 23:53:47 +0000550 /*-- Make a copy of cftab, used in generation of T --*/
551 for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
wdenk710e3502003-08-29 20:57:53 +0000552
wdenk9c53f402003-10-15 23:53:47 +0000553 /*-- compute the T vector --*/
554 for (i = 0; i < nblock; i++) {
555 uc = (UChar)(s->ll16[i]);
556 SET_LL(i, s->cftabCopy[uc]);
557 s->cftabCopy[uc]++;
558 }
wdenk710e3502003-08-29 20:57:53 +0000559
wdenk9c53f402003-10-15 23:53:47 +0000560 /*-- Compute T^(-1) by pointer reversal on T --*/
561 i = s->origPtr;
562 j = GET_LL(i);
563 do {
564 Int32 tmp = GET_LL(j);
565 SET_LL(j, i);
566 i = j;
567 j = tmp;
568 }
569 while (i != s->origPtr);
wdenk710e3502003-08-29 20:57:53 +0000570
wdenk8f08c5b2004-10-11 22:43:02 +0000571#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
572 WATCHDOG_RESET();
573#endif
wdenk9c53f402003-10-15 23:53:47 +0000574 s->tPos = s->origPtr;
575 s->nblock_used = 0;
576 if (s->blockRandomised) {
577 BZ_RAND_INIT_MASK;
578 BZ_GET_SMALL(s->k0); s->nblock_used++;
579 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
580 } else {
581 BZ_GET_SMALL(s->k0); s->nblock_used++;
582 }
wdenk710e3502003-08-29 20:57:53 +0000583
584 } else {
585
wdenk8f08c5b2004-10-11 22:43:02 +0000586#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
587 WATCHDOG_RESET();
588#endif
wdenk9c53f402003-10-15 23:53:47 +0000589 /*-- compute the T^(-1) vector --*/
590 for (i = 0; i < nblock; i++) {
591 uc = (UChar)(s->tt[i] & 0xff);
592 s->tt[s->cftab[uc]] |= (i << 8);
593 s->cftab[uc]++;
594 }
wdenk710e3502003-08-29 20:57:53 +0000595
wdenk9c53f402003-10-15 23:53:47 +0000596 s->tPos = s->tt[s->origPtr] >> 8;
597 s->nblock_used = 0;
598 if (s->blockRandomised) {
599 BZ_RAND_INIT_MASK;
600 BZ_GET_FAST(s->k0); s->nblock_used++;
601 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
602 } else {
603 BZ_GET_FAST(s->k0); s->nblock_used++;
604 }
wdenk710e3502003-08-29 20:57:53 +0000605
606 }
607
608 RETURN(BZ_OK);
609
610
wdenk710e3502003-08-29 20:57:53 +0000611 endhdr_2:
612
613 GET_UCHAR(BZ_X_ENDHDR_2, uc);
614 if (uc != 0x72) RETURN(BZ_DATA_ERROR);
615 GET_UCHAR(BZ_X_ENDHDR_3, uc);
616 if (uc != 0x45) RETURN(BZ_DATA_ERROR);
617 GET_UCHAR(BZ_X_ENDHDR_4, uc);
618 if (uc != 0x38) RETURN(BZ_DATA_ERROR);
619 GET_UCHAR(BZ_X_ENDHDR_5, uc);
620 if (uc != 0x50) RETURN(BZ_DATA_ERROR);
621 GET_UCHAR(BZ_X_ENDHDR_6, uc);
622 if (uc != 0x90) RETURN(BZ_DATA_ERROR);
623
624 s->storedCombinedCRC = 0;
625 GET_UCHAR(BZ_X_CCRC_1, uc);
626 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
627 GET_UCHAR(BZ_X_CCRC_2, uc);
628 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
629 GET_UCHAR(BZ_X_CCRC_3, uc);
630 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
631 GET_UCHAR(BZ_X_CCRC_4, uc);
632 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
633
634 s->state = BZ_X_IDLE;
635 RETURN(BZ_STREAM_END);
636
637 default: AssertH ( False, 4001 );
638 }
639
640 AssertH ( False, 4002 );
641
642 save_state_and_return:
643
644 s->save_i = i;
645 s->save_j = j;
646 s->save_t = t;
647 s->save_alphaSize = alphaSize;
648 s->save_nGroups = nGroups;
649 s->save_nSelectors = nSelectors;
650 s->save_EOB = EOB;
651 s->save_groupNo = groupNo;
652 s->save_groupPos = groupPos;
653 s->save_nextSym = nextSym;
654 s->save_nblockMAX = nblockMAX;
655 s->save_nblock = nblock;
656 s->save_es = es;
657 s->save_N = N;
658 s->save_curr = curr;
659 s->save_zt = zt;
660 s->save_zn = zn;
661 s->save_zvec = zvec;
662 s->save_zj = zj;
663 s->save_gSel = gSel;
664 s->save_gMinlen = gMinlen;
665 s->save_gLimit = gLimit;
666 s->save_gBase = gBase;
667 s->save_gPerm = gPerm;
668
669 return retVal;
670}
671
672
673/*-------------------------------------------------------------*/
674/*--- end decompress.c ---*/
675/*-------------------------------------------------------------*/
676
677#endif /* CONFIG_BZIP2 */