1*9a747e4fSDavid du Colombier #include <u.h>
2*9a747e4fSDavid du Colombier #include <libc.h>
3*9a747e4fSDavid du Colombier #include <bio.h>
4*9a747e4fSDavid du Colombier #include "bzfs.h"
5*9a747e4fSDavid du Colombier
6*9a747e4fSDavid du Colombier /*
7*9a747e4fSDavid du Colombier * THIS FILE IS NOT IDENTICAL TO THE ORIGINAL
8*9a747e4fSDavid du Colombier * FROM THE BZIP2 DISTRIBUTION.
9*9a747e4fSDavid du Colombier *
10*9a747e4fSDavid du Colombier * It has been modified, mainly to break the library
11*9a747e4fSDavid du Colombier * into smaller pieces.
12*9a747e4fSDavid du Colombier *
13*9a747e4fSDavid du Colombier * Russ Cox
14*9a747e4fSDavid du Colombier * rsc@plan9.bell-labs.com
15*9a747e4fSDavid du Colombier * July 2000
16*9a747e4fSDavid du Colombier */
17*9a747e4fSDavid du Colombier
18*9a747e4fSDavid du Colombier /*---------------------------------------------*/
19*9a747e4fSDavid du Colombier /*--
20*9a747e4fSDavid du Colombier Place a 1 beside your platform, and 0 elsewhere.
21*9a747e4fSDavid du Colombier Attempts to autosniff this even if you don't.
22*9a747e4fSDavid du Colombier --*/
23*9a747e4fSDavid du Colombier
24*9a747e4fSDavid du Colombier
25*9a747e4fSDavid du Colombier /*--
26*9a747e4fSDavid du Colombier Plan 9 from Bell Labs
27*9a747e4fSDavid du Colombier --*/
28*9a747e4fSDavid du Colombier #define BZ_PLAN9 1
29*9a747e4fSDavid du Colombier #define BZ_UNIX 0
30*9a747e4fSDavid du Colombier
31*9a747e4fSDavid du Colombier #define exit(x) exits((x) ? "whoops" : nil)
32*9a747e4fSDavid du Colombier #define size_t ulong
33*9a747e4fSDavid du Colombier
34*9a747e4fSDavid du Colombier #ifdef __GNUC__
35*9a747e4fSDavid du Colombier # define NORETURN __attribute__ ((noreturn))
36*9a747e4fSDavid du Colombier #else
37*9a747e4fSDavid du Colombier # define NORETURN /**/
38*9a747e4fSDavid du Colombier #endif
39*9a747e4fSDavid du Colombier
40*9a747e4fSDavid du Colombier /*--
41*9a747e4fSDavid du Colombier Some more stuff for all platforms :-)
42*9a747e4fSDavid du Colombier This might have to get moved into the platform-specific
43*9a747e4fSDavid du Colombier header files if we encounter a machine with different sizes.
44*9a747e4fSDavid du Colombier --*/
45*9a747e4fSDavid du Colombier
46*9a747e4fSDavid du Colombier typedef char Char;
47*9a747e4fSDavid du Colombier typedef unsigned char Bool;
48*9a747e4fSDavid du Colombier typedef unsigned char UChar;
49*9a747e4fSDavid du Colombier typedef int Int32;
50*9a747e4fSDavid du Colombier typedef unsigned int UInt32;
51*9a747e4fSDavid du Colombier typedef short Int16;
52*9a747e4fSDavid du Colombier typedef unsigned short UInt16;
53*9a747e4fSDavid du Colombier
54*9a747e4fSDavid du Colombier #define True ((Bool)1)
55*9a747e4fSDavid du Colombier #define False ((Bool)0)
56*9a747e4fSDavid du Colombier
57*9a747e4fSDavid du Colombier /*--
58*9a747e4fSDavid du Colombier IntNative is your platform's `native' int size.
59*9a747e4fSDavid du Colombier Only here to avoid probs with 64-bit platforms.
60*9a747e4fSDavid du Colombier --*/
61*9a747e4fSDavid du Colombier typedef int IntNative;
62*9a747e4fSDavid du Colombier
63*9a747e4fSDavid du Colombier #include "bzfs.h"
64*9a747e4fSDavid du Colombier #include "bzlib.h"
65*9a747e4fSDavid du Colombier #include "bzlib_private.h"
66*9a747e4fSDavid du Colombier
67*9a747e4fSDavid du Colombier static int
bunzip(int ofd,char * ofile,Biobuf * bin)68*9a747e4fSDavid du Colombier bunzip(int ofd, char *ofile, Biobuf *bin)
69*9a747e4fSDavid du Colombier {
70*9a747e4fSDavid du Colombier int e, n, done, onemore;
71*9a747e4fSDavid du Colombier char buf[8192];
72*9a747e4fSDavid du Colombier char obuf[8192];
73*9a747e4fSDavid du Colombier Biobuf bout;
74*9a747e4fSDavid du Colombier bz_stream strm;
75*9a747e4fSDavid du Colombier
76*9a747e4fSDavid du Colombier USED(ofile);
77*9a747e4fSDavid du Colombier
78*9a747e4fSDavid du Colombier memset(&strm, 0, sizeof strm);
79*9a747e4fSDavid du Colombier BZ2_bzDecompressInit(&strm, 0, 0);
80*9a747e4fSDavid du Colombier
81*9a747e4fSDavid du Colombier strm.next_in = buf;
82*9a747e4fSDavid du Colombier strm.avail_in = 0;
83*9a747e4fSDavid du Colombier strm.next_out = obuf;
84*9a747e4fSDavid du Colombier strm.avail_out = sizeof obuf;
85*9a747e4fSDavid du Colombier
86*9a747e4fSDavid du Colombier done = 0;
87*9a747e4fSDavid du Colombier Binit(&bout, ofd, OWRITE);
88*9a747e4fSDavid du Colombier
89*9a747e4fSDavid du Colombier /*
90*9a747e4fSDavid du Colombier * onemore is a crummy hack to go 'round the loop
91*9a747e4fSDavid du Colombier * once after we finish, to flush the output buffer.
92*9a747e4fSDavid du Colombier */
93*9a747e4fSDavid du Colombier onemore = 1;
94*9a747e4fSDavid du Colombier SET(e);
95*9a747e4fSDavid du Colombier do {
96*9a747e4fSDavid du Colombier if(!done && strm.avail_in < sizeof buf) {
97*9a747e4fSDavid du Colombier if(strm.avail_in)
98*9a747e4fSDavid du Colombier memmove(buf, strm.next_in, strm.avail_in);
99*9a747e4fSDavid du Colombier
100*9a747e4fSDavid du Colombier n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
101*9a747e4fSDavid du Colombier if(n <= 0)
102*9a747e4fSDavid du Colombier done = 1;
103*9a747e4fSDavid du Colombier else
104*9a747e4fSDavid du Colombier strm.avail_in += n;
105*9a747e4fSDavid du Colombier strm.next_in = buf;
106*9a747e4fSDavid du Colombier }
107*9a747e4fSDavid du Colombier if(strm.avail_out < sizeof obuf) {
108*9a747e4fSDavid du Colombier Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out);
109*9a747e4fSDavid du Colombier strm.next_out = obuf;
110*9a747e4fSDavid du Colombier strm.avail_out = sizeof obuf;
111*9a747e4fSDavid du Colombier }
112*9a747e4fSDavid du Colombier
113*9a747e4fSDavid du Colombier if(onemore == 0)
114*9a747e4fSDavid du Colombier break;
115*9a747e4fSDavid du Colombier } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--);
116*9a747e4fSDavid du Colombier
117*9a747e4fSDavid du Colombier if(e != BZ_STREAM_END) {
118*9a747e4fSDavid du Colombier fprint(2, "bunzip2: decompress failed\n");
119*9a747e4fSDavid du Colombier return 0;
120*9a747e4fSDavid du Colombier }
121*9a747e4fSDavid du Colombier
122*9a747e4fSDavid du Colombier if(BZ2_bzDecompressEnd(&strm) != BZ_OK) {
123*9a747e4fSDavid du Colombier fprint(2, "bunzip2: decompress end failed (can't happen)\n");
124*9a747e4fSDavid du Colombier return 0;
125*9a747e4fSDavid du Colombier }
126*9a747e4fSDavid du Colombier
127*9a747e4fSDavid du Colombier Bterm(&bout);
128*9a747e4fSDavid du Colombier
129*9a747e4fSDavid du Colombier return 1;
130*9a747e4fSDavid du Colombier }
131*9a747e4fSDavid du Colombier
132*9a747e4fSDavid du Colombier void
_unbzip(int in,int out)133*9a747e4fSDavid du Colombier _unbzip(int in, int out)
134*9a747e4fSDavid du Colombier {
135*9a747e4fSDavid du Colombier Biobuf bin;
136*9a747e4fSDavid du Colombier
137*9a747e4fSDavid du Colombier Binit(&bin, in, OREAD);
138*9a747e4fSDavid du Colombier if(bunzip(out, nil, &bin) != 1) {
139*9a747e4fSDavid du Colombier fprint(2, "bunzip2 failed\n");
140*9a747e4fSDavid du Colombier _exits("bunzip2");
141*9a747e4fSDavid du Colombier }
142*9a747e4fSDavid du Colombier }
143*9a747e4fSDavid du Colombier
144*9a747e4fSDavid du Colombier int
unbzip(int in)145*9a747e4fSDavid du Colombier unbzip(int in)
146*9a747e4fSDavid du Colombier {
147*9a747e4fSDavid du Colombier int rv, out, p[2];
148*9a747e4fSDavid du Colombier
149*9a747e4fSDavid du Colombier if(pipe(p) < 0)
150*9a747e4fSDavid du Colombier sysfatal("pipe: %r");
151*9a747e4fSDavid du Colombier
152*9a747e4fSDavid du Colombier rv = p[0];
153*9a747e4fSDavid du Colombier out = p[1];
154*9a747e4fSDavid du Colombier switch(rfork(RFPROC|RFFDG|RFNOTEG|RFMEM)){
155*9a747e4fSDavid du Colombier case -1:
156*9a747e4fSDavid du Colombier sysfatal("fork: %r");
157*9a747e4fSDavid du Colombier case 0:
158*9a747e4fSDavid du Colombier close(rv);
159*9a747e4fSDavid du Colombier break;
160*9a747e4fSDavid du Colombier default:
161*9a747e4fSDavid du Colombier close(in);
162*9a747e4fSDavid du Colombier close(out);
163*9a747e4fSDavid du Colombier return rv;
164*9a747e4fSDavid du Colombier }
165*9a747e4fSDavid du Colombier
166*9a747e4fSDavid du Colombier _unbzip(in, out);
167*9a747e4fSDavid du Colombier _exits(0);
168*9a747e4fSDavid du Colombier return -1; /* not reached */
169*9a747e4fSDavid du Colombier }
170*9a747e4fSDavid du Colombier
bz_config_ok(void)171*9a747e4fSDavid du Colombier int bz_config_ok ( void )
172*9a747e4fSDavid du Colombier {
173*9a747e4fSDavid du Colombier if (sizeof(int) != 4) return 0;
174*9a747e4fSDavid du Colombier if (sizeof(short) != 2) return 0;
175*9a747e4fSDavid du Colombier if (sizeof(char) != 1) return 0;
176*9a747e4fSDavid du Colombier return 1;
177*9a747e4fSDavid du Colombier }
178*9a747e4fSDavid du Colombier
default_bzalloc(void * o,int items,int size)179*9a747e4fSDavid du Colombier void* default_bzalloc(void *o, int items, int size)
180*9a747e4fSDavid du Colombier {
181*9a747e4fSDavid du Colombier USED(o);
182*9a747e4fSDavid du Colombier return sbrk(items*size);
183*9a747e4fSDavid du Colombier }
184*9a747e4fSDavid du Colombier
default_bzfree(void *,void *)185*9a747e4fSDavid du Colombier void default_bzfree(void*, void*)
186*9a747e4fSDavid du Colombier {
187*9a747e4fSDavid du Colombier }
188*9a747e4fSDavid du Colombier
189*9a747e4fSDavid du Colombier void
bz_internal_error(int)190*9a747e4fSDavid du Colombier bz_internal_error(int)
191*9a747e4fSDavid du Colombier {
192*9a747e4fSDavid du Colombier abort();
193*9a747e4fSDavid du Colombier }
194*9a747e4fSDavid du Colombier
195*9a747e4fSDavid du Colombier /*-------------------------------------------------------------*/
196*9a747e4fSDavid du Colombier /*--- Decompression machinery ---*/
197*9a747e4fSDavid du Colombier /*--- decompress.c ---*/
198*9a747e4fSDavid du Colombier /*-------------------------------------------------------------*/
199*9a747e4fSDavid du Colombier
200*9a747e4fSDavid du Colombier /*--
201*9a747e4fSDavid du Colombier This file is a part of bzip2 and/or libbzip2, a program and
202*9a747e4fSDavid du Colombier library for lossless, block-sorting data compression.
203*9a747e4fSDavid du Colombier
204*9a747e4fSDavid du Colombier Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
205*9a747e4fSDavid du Colombier
206*9a747e4fSDavid du Colombier Redistribution and use in source and binary forms, with or without
207*9a747e4fSDavid du Colombier modification, are permitted provided that the following conditions
208*9a747e4fSDavid du Colombier are met:
209*9a747e4fSDavid du Colombier
210*9a747e4fSDavid du Colombier 1. Redistributions of source code must retain the above copyright
211*9a747e4fSDavid du Colombier notice, this list of conditions and the following disclaimer.
212*9a747e4fSDavid du Colombier
213*9a747e4fSDavid du Colombier 2. The origin of this software must not be misrepresented; you must
214*9a747e4fSDavid du Colombier not claim that you wrote the original software. If you use this
215*9a747e4fSDavid du Colombier software in a product, an acknowledgment in the product
216*9a747e4fSDavid du Colombier documentation would be appreciated but is not required.
217*9a747e4fSDavid du Colombier
218*9a747e4fSDavid du Colombier 3. Altered source versions must be plainly marked as such, and must
219*9a747e4fSDavid du Colombier not be misrepresented as being the original software.
220*9a747e4fSDavid du Colombier
221*9a747e4fSDavid du Colombier 4. The name of the author may not be used to endorse or promote
222*9a747e4fSDavid du Colombier products derived from this software without specific prior written
223*9a747e4fSDavid du Colombier permission.
224*9a747e4fSDavid du Colombier
225*9a747e4fSDavid du Colombier THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
226*9a747e4fSDavid du Colombier OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
227*9a747e4fSDavid du Colombier WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228*9a747e4fSDavid du Colombier ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
229*9a747e4fSDavid du Colombier DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
230*9a747e4fSDavid du Colombier DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
231*9a747e4fSDavid du Colombier GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
232*9a747e4fSDavid du Colombier INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
233*9a747e4fSDavid du Colombier WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
234*9a747e4fSDavid du Colombier NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
235*9a747e4fSDavid du Colombier SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
236*9a747e4fSDavid du Colombier
237*9a747e4fSDavid du Colombier Julian Seward, Cambridge, UK.
238*9a747e4fSDavid du Colombier jseward@acm.org
239*9a747e4fSDavid du Colombier bzip2/libbzip2 version 1.0 of 21 March 2000
240*9a747e4fSDavid du Colombier
241*9a747e4fSDavid du Colombier This program is based on (at least) the work of:
242*9a747e4fSDavid du Colombier Mike Burrows
243*9a747e4fSDavid du Colombier David Wheeler
244*9a747e4fSDavid du Colombier Peter Fenwick
245*9a747e4fSDavid du Colombier Alistair Moffat
246*9a747e4fSDavid du Colombier Radford Neal
247*9a747e4fSDavid du Colombier Ian H. Witten
248*9a747e4fSDavid du Colombier Robert Sedgewick
249*9a747e4fSDavid du Colombier Jon L. Bentley
250*9a747e4fSDavid du Colombier
251*9a747e4fSDavid du Colombier For more information on these sources, see the manual.
252*9a747e4fSDavid du Colombier --*/
253*9a747e4fSDavid du Colombier
254*9a747e4fSDavid du Colombier
255*9a747e4fSDavid du Colombier
256*9a747e4fSDavid du Colombier /*---------------------------------------------------*/
257*9a747e4fSDavid du Colombier static
makeMaps_d(DState * s)258*9a747e4fSDavid du Colombier void makeMaps_d ( DState* s )
259*9a747e4fSDavid du Colombier {
260*9a747e4fSDavid du Colombier Int32 i;
261*9a747e4fSDavid du Colombier s->nInUse = 0;
262*9a747e4fSDavid du Colombier for (i = 0; i < 256; i++)
263*9a747e4fSDavid du Colombier if (s->inUse[i]) {
264*9a747e4fSDavid du Colombier s->seqToUnseq[s->nInUse] = i;
265*9a747e4fSDavid du Colombier s->nInUse++;
266*9a747e4fSDavid du Colombier }
267*9a747e4fSDavid du Colombier }
268*9a747e4fSDavid du Colombier
269*9a747e4fSDavid du Colombier
270*9a747e4fSDavid du Colombier /*---------------------------------------------------*/
271*9a747e4fSDavid du Colombier #define RETURN(rrr) \
272*9a747e4fSDavid du Colombier { retVal = rrr; goto save_state_and_return; };
273*9a747e4fSDavid du Colombier
274*9a747e4fSDavid du Colombier #define GET_BITS(lll,vvv,nnn) \
275*9a747e4fSDavid du Colombier case lll: \
276*9a747e4fSDavid du Colombier { int x; if((retVal = getbits(s, lll, &x, nnn)) != 99) \
277*9a747e4fSDavid du Colombier goto save_state_and_return; vvv=x; }\
278*9a747e4fSDavid du Colombier
279*9a747e4fSDavid du Colombier int
getbits(DState * s,int lll,int * vvv,int nnn)280*9a747e4fSDavid du Colombier getbits(DState *s, int lll, int *vvv, int nnn)
281*9a747e4fSDavid du Colombier {
282*9a747e4fSDavid du Colombier s->state = lll;
283*9a747e4fSDavid du Colombier
284*9a747e4fSDavid du Colombier for(;;) {
285*9a747e4fSDavid du Colombier if (s->bsLive >= nnn) {
286*9a747e4fSDavid du Colombier UInt32 v;
287*9a747e4fSDavid du Colombier v = (s->bsBuff >>
288*9a747e4fSDavid du Colombier (s->bsLive-nnn)) & ((1 << nnn)-1);
289*9a747e4fSDavid du Colombier s->bsLive -= nnn;
290*9a747e4fSDavid du Colombier *vvv = v;
291*9a747e4fSDavid du Colombier return 99;
292*9a747e4fSDavid du Colombier }
293*9a747e4fSDavid du Colombier if (s->strm->avail_in == 0) return BZ_OK;
294*9a747e4fSDavid du Colombier s->bsBuff
295*9a747e4fSDavid du Colombier = (s->bsBuff << 8) |
296*9a747e4fSDavid du Colombier ((UInt32)
297*9a747e4fSDavid du Colombier (*((UChar*)(s->strm->next_in))));
298*9a747e4fSDavid du Colombier s->bsLive += 8;
299*9a747e4fSDavid du Colombier s->strm->next_in++;
300*9a747e4fSDavid du Colombier s->strm->avail_in--;
301*9a747e4fSDavid du Colombier s->strm->total_in_lo32++;
302*9a747e4fSDavid du Colombier if (s->strm->total_in_lo32 == 0)
303*9a747e4fSDavid du Colombier s->strm->total_in_hi32++;
304*9a747e4fSDavid du Colombier }
305*9a747e4fSDavid du Colombier }
306*9a747e4fSDavid du Colombier
307*9a747e4fSDavid du Colombier #define GET_UCHAR(lll,uuu) \
308*9a747e4fSDavid du Colombier GET_BITS(lll,uuu,8)
309*9a747e4fSDavid du Colombier
310*9a747e4fSDavid du Colombier #define GET_BIT(lll,uuu) \
311*9a747e4fSDavid du Colombier GET_BITS(lll,uuu,1)
312*9a747e4fSDavid du Colombier
313*9a747e4fSDavid du Colombier /*---------------------------------------------------*/
314*9a747e4fSDavid du Colombier #define GET_MTF_VAL(label1,label2,lval) \
315*9a747e4fSDavid du Colombier { \
316*9a747e4fSDavid du Colombier if (groupPos == 0) { \
317*9a747e4fSDavid du Colombier groupNo++; \
318*9a747e4fSDavid du Colombier if (groupNo >= nSelectors) \
319*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR); \
320*9a747e4fSDavid du Colombier groupPos = BZ_G_SIZE; \
321*9a747e4fSDavid du Colombier gSel = s->selector[groupNo]; \
322*9a747e4fSDavid du Colombier gMinlen = s->minLens[gSel]; \
323*9a747e4fSDavid du Colombier gLimit = &(s->limit[gSel][0]); \
324*9a747e4fSDavid du Colombier gPerm = &(s->perm[gSel][0]); \
325*9a747e4fSDavid du Colombier gBase = &(s->base[gSel][0]); \
326*9a747e4fSDavid du Colombier } \
327*9a747e4fSDavid du Colombier groupPos--; \
328*9a747e4fSDavid du Colombier zn = gMinlen; \
329*9a747e4fSDavid du Colombier GET_BITS(label1, zvec, zn); \
330*9a747e4fSDavid du Colombier while (1) { \
331*9a747e4fSDavid du Colombier if (zn > 20 /* the longest code */) \
332*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR); \
333*9a747e4fSDavid du Colombier if (zvec <= gLimit[zn]) break; \
334*9a747e4fSDavid du Colombier zn++; \
335*9a747e4fSDavid du Colombier GET_BIT(label2, zj); \
336*9a747e4fSDavid du Colombier zvec = (zvec << 1) | zj; \
337*9a747e4fSDavid du Colombier }; \
338*9a747e4fSDavid du Colombier if (zvec - gBase[zn] < 0 \
339*9a747e4fSDavid du Colombier || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
340*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR); \
341*9a747e4fSDavid du Colombier lval = gPerm[zvec - gBase[zn]]; \
342*9a747e4fSDavid du Colombier }
343*9a747e4fSDavid du Colombier
344*9a747e4fSDavid du Colombier
345*9a747e4fSDavid du Colombier /*---------------------------------------------------*/
BZ2_decompress(DState * s)346*9a747e4fSDavid du Colombier Int32 BZ2_decompress ( DState* s )
347*9a747e4fSDavid du Colombier {
348*9a747e4fSDavid du Colombier UChar uc;
349*9a747e4fSDavid du Colombier Int32 retVal;
350*9a747e4fSDavid du Colombier Int32 minLen, maxLen;
351*9a747e4fSDavid du Colombier bz_stream* strm = s->strm;
352*9a747e4fSDavid du Colombier
353*9a747e4fSDavid du Colombier /* stuff that needs to be saved/restored */
354*9a747e4fSDavid du Colombier Int32 i;
355*9a747e4fSDavid du Colombier Int32 j;
356*9a747e4fSDavid du Colombier Int32 t;
357*9a747e4fSDavid du Colombier Int32 alphaSize;
358*9a747e4fSDavid du Colombier Int32 nGroups;
359*9a747e4fSDavid du Colombier Int32 nSelectors;
360*9a747e4fSDavid du Colombier Int32 EOB;
361*9a747e4fSDavid du Colombier Int32 groupNo;
362*9a747e4fSDavid du Colombier Int32 groupPos;
363*9a747e4fSDavid du Colombier Int32 nextSym;
364*9a747e4fSDavid du Colombier Int32 nblockMAX;
365*9a747e4fSDavid du Colombier Int32 nblock;
366*9a747e4fSDavid du Colombier Int32 es;
367*9a747e4fSDavid du Colombier Int32 N;
368*9a747e4fSDavid du Colombier Int32 curr;
369*9a747e4fSDavid du Colombier Int32 zt;
370*9a747e4fSDavid du Colombier Int32 zn;
371*9a747e4fSDavid du Colombier Int32 zvec;
372*9a747e4fSDavid du Colombier Int32 zj;
373*9a747e4fSDavid du Colombier Int32 gSel;
374*9a747e4fSDavid du Colombier Int32 gMinlen;
375*9a747e4fSDavid du Colombier Int32* gLimit;
376*9a747e4fSDavid du Colombier Int32* gBase;
377*9a747e4fSDavid du Colombier Int32* gPerm;
378*9a747e4fSDavid du Colombier
379*9a747e4fSDavid du Colombier if (s->state == BZ_X_MAGIC_1) {
380*9a747e4fSDavid du Colombier /*initialise the save area*/
381*9a747e4fSDavid du Colombier s->save_i = 0;
382*9a747e4fSDavid du Colombier s->save_j = 0;
383*9a747e4fSDavid du Colombier s->save_t = 0;
384*9a747e4fSDavid du Colombier s->save_alphaSize = 0;
385*9a747e4fSDavid du Colombier s->save_nGroups = 0;
386*9a747e4fSDavid du Colombier s->save_nSelectors = 0;
387*9a747e4fSDavid du Colombier s->save_EOB = 0;
388*9a747e4fSDavid du Colombier s->save_groupNo = 0;
389*9a747e4fSDavid du Colombier s->save_groupPos = 0;
390*9a747e4fSDavid du Colombier s->save_nextSym = 0;
391*9a747e4fSDavid du Colombier s->save_nblockMAX = 0;
392*9a747e4fSDavid du Colombier s->save_nblock = 0;
393*9a747e4fSDavid du Colombier s->save_es = 0;
394*9a747e4fSDavid du Colombier s->save_N = 0;
395*9a747e4fSDavid du Colombier s->save_curr = 0;
396*9a747e4fSDavid du Colombier s->save_zt = 0;
397*9a747e4fSDavid du Colombier s->save_zn = 0;
398*9a747e4fSDavid du Colombier s->save_zvec = 0;
399*9a747e4fSDavid du Colombier s->save_zj = 0;
400*9a747e4fSDavid du Colombier s->save_gSel = 0;
401*9a747e4fSDavid du Colombier s->save_gMinlen = 0;
402*9a747e4fSDavid du Colombier s->save_gLimit = NULL;
403*9a747e4fSDavid du Colombier s->save_gBase = NULL;
404*9a747e4fSDavid du Colombier s->save_gPerm = NULL;
405*9a747e4fSDavid du Colombier }
406*9a747e4fSDavid du Colombier
407*9a747e4fSDavid du Colombier /*restore from the save area*/
408*9a747e4fSDavid du Colombier i = s->save_i;
409*9a747e4fSDavid du Colombier j = s->save_j;
410*9a747e4fSDavid du Colombier t = s->save_t;
411*9a747e4fSDavid du Colombier alphaSize = s->save_alphaSize;
412*9a747e4fSDavid du Colombier nGroups = s->save_nGroups;
413*9a747e4fSDavid du Colombier nSelectors = s->save_nSelectors;
414*9a747e4fSDavid du Colombier EOB = s->save_EOB;
415*9a747e4fSDavid du Colombier groupNo = s->save_groupNo;
416*9a747e4fSDavid du Colombier groupPos = s->save_groupPos;
417*9a747e4fSDavid du Colombier nextSym = s->save_nextSym;
418*9a747e4fSDavid du Colombier nblockMAX = s->save_nblockMAX;
419*9a747e4fSDavid du Colombier nblock = s->save_nblock;
420*9a747e4fSDavid du Colombier es = s->save_es;
421*9a747e4fSDavid du Colombier N = s->save_N;
422*9a747e4fSDavid du Colombier curr = s->save_curr;
423*9a747e4fSDavid du Colombier zt = s->save_zt;
424*9a747e4fSDavid du Colombier zn = s->save_zn;
425*9a747e4fSDavid du Colombier zvec = s->save_zvec;
426*9a747e4fSDavid du Colombier zj = s->save_zj;
427*9a747e4fSDavid du Colombier gSel = s->save_gSel;
428*9a747e4fSDavid du Colombier gMinlen = s->save_gMinlen;
429*9a747e4fSDavid du Colombier gLimit = s->save_gLimit;
430*9a747e4fSDavid du Colombier gBase = s->save_gBase;
431*9a747e4fSDavid du Colombier gPerm = s->save_gPerm;
432*9a747e4fSDavid du Colombier
433*9a747e4fSDavid du Colombier retVal = BZ_OK;
434*9a747e4fSDavid du Colombier
435*9a747e4fSDavid du Colombier switch (s->state) {
436*9a747e4fSDavid du Colombier
437*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_MAGIC_1, uc);
438*9a747e4fSDavid du Colombier if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC);
439*9a747e4fSDavid du Colombier
440*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_MAGIC_2, uc);
441*9a747e4fSDavid du Colombier if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC);
442*9a747e4fSDavid du Colombier
443*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_MAGIC_3, uc)
444*9a747e4fSDavid du Colombier if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC);
445*9a747e4fSDavid du Colombier
446*9a747e4fSDavid du Colombier GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
447*9a747e4fSDavid du Colombier if (s->blockSize100k < '1' ||
448*9a747e4fSDavid du Colombier s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC);
449*9a747e4fSDavid du Colombier s->blockSize100k -= '0';
450*9a747e4fSDavid du Colombier
451*9a747e4fSDavid du Colombier if (0 && s->smallDecompress) {
452*9a747e4fSDavid du Colombier s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
453*9a747e4fSDavid du Colombier s->ll4 = BZALLOC(
454*9a747e4fSDavid du Colombier ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
455*9a747e4fSDavid du Colombier );
456*9a747e4fSDavid du Colombier if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
457*9a747e4fSDavid du Colombier } else {
458*9a747e4fSDavid du Colombier s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
459*9a747e4fSDavid du Colombier if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
460*9a747e4fSDavid du Colombier }
461*9a747e4fSDavid du Colombier
462*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_1, uc);
463*9a747e4fSDavid du Colombier
464*9a747e4fSDavid du Colombier if (uc == 0x17) goto endhdr_2;
465*9a747e4fSDavid du Colombier if (uc != 0x31) RETURN(BZ_DATA_ERROR);
466*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_2, uc);
467*9a747e4fSDavid du Colombier if (uc != 0x41) RETURN(BZ_DATA_ERROR);
468*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_3, uc);
469*9a747e4fSDavid du Colombier if (uc != 0x59) RETURN(BZ_DATA_ERROR);
470*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_4, uc);
471*9a747e4fSDavid du Colombier if (uc != 0x26) RETURN(BZ_DATA_ERROR);
472*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_5, uc);
473*9a747e4fSDavid du Colombier if (uc != 0x53) RETURN(BZ_DATA_ERROR);
474*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BLKHDR_6, uc);
475*9a747e4fSDavid du Colombier if (uc != 0x59) RETURN(BZ_DATA_ERROR);
476*9a747e4fSDavid du Colombier
477*9a747e4fSDavid du Colombier s->currBlockNo++;
478*9a747e4fSDavid du Colombier // if (s->verbosity >= 2)
479*9a747e4fSDavid du Colombier // VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
480*9a747e4fSDavid du Colombier
481*9a747e4fSDavid du Colombier s->storedBlockCRC = 0;
482*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BCRC_1, uc);
483*9a747e4fSDavid du Colombier s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
484*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BCRC_2, uc);
485*9a747e4fSDavid du Colombier s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
486*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BCRC_3, uc);
487*9a747e4fSDavid du Colombier s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
488*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_BCRC_4, uc);
489*9a747e4fSDavid du Colombier s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
490*9a747e4fSDavid du Colombier
491*9a747e4fSDavid du Colombier GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
492*9a747e4fSDavid du Colombier
493*9a747e4fSDavid du Colombier s->origPtr = 0;
494*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ORIGPTR_1, uc);
495*9a747e4fSDavid du Colombier s->origPtr = (s->origPtr << 8) | ((Int32)uc);
496*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ORIGPTR_2, uc);
497*9a747e4fSDavid du Colombier s->origPtr = (s->origPtr << 8) | ((Int32)uc);
498*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ORIGPTR_3, uc);
499*9a747e4fSDavid du Colombier s->origPtr = (s->origPtr << 8) | ((Int32)uc);
500*9a747e4fSDavid du Colombier
501*9a747e4fSDavid du Colombier if (s->origPtr < 0)
502*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR);
503*9a747e4fSDavid du Colombier if (s->origPtr > 10 + 100000*s->blockSize100k)
504*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR);
505*9a747e4fSDavid du Colombier
506*9a747e4fSDavid du Colombier /*--- Receive the mapping table ---*/
507*9a747e4fSDavid du Colombier for (i = 0; i < 16; i++) {
508*9a747e4fSDavid du Colombier GET_BIT(BZ_X_MAPPING_1, uc);
509*9a747e4fSDavid du Colombier if (uc == 1)
510*9a747e4fSDavid du Colombier s->inUse16[i] = True; else
511*9a747e4fSDavid du Colombier s->inUse16[i] = False;
512*9a747e4fSDavid du Colombier }
513*9a747e4fSDavid du Colombier
514*9a747e4fSDavid du Colombier for (i = 0; i < 256; i++) s->inUse[i] = False;
515*9a747e4fSDavid du Colombier
516*9a747e4fSDavid du Colombier for (i = 0; i < 16; i++)
517*9a747e4fSDavid du Colombier if (s->inUse16[i])
518*9a747e4fSDavid du Colombier for (j = 0; j < 16; j++) {
519*9a747e4fSDavid du Colombier GET_BIT(BZ_X_MAPPING_2, uc);
520*9a747e4fSDavid du Colombier if (uc == 1) s->inUse[i * 16 + j] = True;
521*9a747e4fSDavid du Colombier }
522*9a747e4fSDavid du Colombier makeMaps_d ( s );
523*9a747e4fSDavid du Colombier if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
524*9a747e4fSDavid du Colombier alphaSize = s->nInUse+2;
525*9a747e4fSDavid du Colombier
526*9a747e4fSDavid du Colombier /*--- Now the selectors ---*/
527*9a747e4fSDavid du Colombier GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
528*9a747e4fSDavid du Colombier if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
529*9a747e4fSDavid du Colombier GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
530*9a747e4fSDavid du Colombier if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
531*9a747e4fSDavid du Colombier for (i = 0; i < nSelectors; i++) {
532*9a747e4fSDavid du Colombier j = 0;
533*9a747e4fSDavid du Colombier while (True) {
534*9a747e4fSDavid du Colombier GET_BIT(BZ_X_SELECTOR_3, uc);
535*9a747e4fSDavid du Colombier if (uc == 0) break;
536*9a747e4fSDavid du Colombier j++;
537*9a747e4fSDavid du Colombier if (j >= nGroups) RETURN(BZ_DATA_ERROR);
538*9a747e4fSDavid du Colombier }
539*9a747e4fSDavid du Colombier s->selectorMtf[i] = j;
540*9a747e4fSDavid du Colombier }
541*9a747e4fSDavid du Colombier
542*9a747e4fSDavid du Colombier /*--- Undo the MTF values for the selectors. ---*/
543*9a747e4fSDavid du Colombier {
544*9a747e4fSDavid du Colombier UChar pos[BZ_N_GROUPS], tmp, v;
545*9a747e4fSDavid du Colombier for (v = 0; v < nGroups; v++) pos[v] = v;
546*9a747e4fSDavid du Colombier
547*9a747e4fSDavid du Colombier for (i = 0; i < nSelectors; i++) {
548*9a747e4fSDavid du Colombier v = s->selectorMtf[i];
549*9a747e4fSDavid du Colombier tmp = pos[v];
550*9a747e4fSDavid du Colombier while (v > 0) { pos[v] = pos[v-1]; v--; }
551*9a747e4fSDavid du Colombier pos[0] = tmp;
552*9a747e4fSDavid du Colombier s->selector[i] = tmp;
553*9a747e4fSDavid du Colombier }
554*9a747e4fSDavid du Colombier }
555*9a747e4fSDavid du Colombier
556*9a747e4fSDavid du Colombier /*--- Now the coding tables ---*/
557*9a747e4fSDavid du Colombier for (t = 0; t < nGroups; t++) {
558*9a747e4fSDavid du Colombier GET_BITS(BZ_X_CODING_1, curr, 5);
559*9a747e4fSDavid du Colombier for (i = 0; i < alphaSize; i++) {
560*9a747e4fSDavid du Colombier while (True) {
561*9a747e4fSDavid du Colombier if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
562*9a747e4fSDavid du Colombier GET_BIT(BZ_X_CODING_2, uc);
563*9a747e4fSDavid du Colombier if (uc == 0) break;
564*9a747e4fSDavid du Colombier GET_BIT(BZ_X_CODING_3, uc);
565*9a747e4fSDavid du Colombier if (uc == 0) curr++; else curr--;
566*9a747e4fSDavid du Colombier }
567*9a747e4fSDavid du Colombier s->len[t][i] = curr;
568*9a747e4fSDavid du Colombier }
569*9a747e4fSDavid du Colombier }
570*9a747e4fSDavid du Colombier
571*9a747e4fSDavid du Colombier /*--- Create the Huffman decoding tables ---*/
572*9a747e4fSDavid du Colombier for (t = 0; t < nGroups; t++) {
573*9a747e4fSDavid du Colombier minLen = 32;
574*9a747e4fSDavid du Colombier maxLen = 0;
575*9a747e4fSDavid du Colombier for (i = 0; i < alphaSize; i++) {
576*9a747e4fSDavid du Colombier if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
577*9a747e4fSDavid du Colombier if (s->len[t][i] < minLen) minLen = s->len[t][i];
578*9a747e4fSDavid du Colombier }
579*9a747e4fSDavid du Colombier BZ2_hbCreateDecodeTables (
580*9a747e4fSDavid du Colombier &(s->limit[t][0]),
581*9a747e4fSDavid du Colombier &(s->base[t][0]),
582*9a747e4fSDavid du Colombier &(s->perm[t][0]),
583*9a747e4fSDavid du Colombier &(s->len[t][0]),
584*9a747e4fSDavid du Colombier minLen, maxLen, alphaSize
585*9a747e4fSDavid du Colombier );
586*9a747e4fSDavid du Colombier s->minLens[t] = minLen;
587*9a747e4fSDavid du Colombier }
588*9a747e4fSDavid du Colombier
589*9a747e4fSDavid du Colombier /*--- Now the MTF values ---*/
590*9a747e4fSDavid du Colombier
591*9a747e4fSDavid du Colombier EOB = s->nInUse+1;
592*9a747e4fSDavid du Colombier nblockMAX = 100000 * s->blockSize100k;
593*9a747e4fSDavid du Colombier groupNo = -1;
594*9a747e4fSDavid du Colombier groupPos = 0;
595*9a747e4fSDavid du Colombier
596*9a747e4fSDavid du Colombier for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
597*9a747e4fSDavid du Colombier
598*9a747e4fSDavid du Colombier /*-- MTF init --*/
599*9a747e4fSDavid du Colombier {
600*9a747e4fSDavid du Colombier Int32 ii, jj, kk;
601*9a747e4fSDavid du Colombier kk = MTFA_SIZE-1;
602*9a747e4fSDavid du Colombier for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
603*9a747e4fSDavid du Colombier for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
604*9a747e4fSDavid du Colombier s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
605*9a747e4fSDavid du Colombier kk--;
606*9a747e4fSDavid du Colombier }
607*9a747e4fSDavid du Colombier s->mtfbase[ii] = kk + 1;
608*9a747e4fSDavid du Colombier }
609*9a747e4fSDavid du Colombier }
610*9a747e4fSDavid du Colombier /*-- end MTF init --*/
611*9a747e4fSDavid du Colombier
612*9a747e4fSDavid du Colombier nblock = 0;
613*9a747e4fSDavid du Colombier GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
614*9a747e4fSDavid du Colombier
615*9a747e4fSDavid du Colombier while (True) {
616*9a747e4fSDavid du Colombier
617*9a747e4fSDavid du Colombier if (nextSym == EOB) break;
618*9a747e4fSDavid du Colombier
619*9a747e4fSDavid du Colombier if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
620*9a747e4fSDavid du Colombier
621*9a747e4fSDavid du Colombier es = -1;
622*9a747e4fSDavid du Colombier N = 1;
623*9a747e4fSDavid du Colombier do {
624*9a747e4fSDavid du Colombier if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
625*9a747e4fSDavid du Colombier if (nextSym == BZ_RUNB) es = es + (1+1) * N;
626*9a747e4fSDavid du Colombier N = N * 2;
627*9a747e4fSDavid du Colombier GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
628*9a747e4fSDavid du Colombier }
629*9a747e4fSDavid du Colombier while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
630*9a747e4fSDavid du Colombier
631*9a747e4fSDavid du Colombier es++;
632*9a747e4fSDavid du Colombier uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
633*9a747e4fSDavid du Colombier s->unzftab[uc] += es;
634*9a747e4fSDavid du Colombier
635*9a747e4fSDavid du Colombier if (0 && s->smallDecompress)
636*9a747e4fSDavid du Colombier while (es > 0) {
637*9a747e4fSDavid du Colombier if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
638*9a747e4fSDavid du Colombier s->ll16[nblock] = (UInt16)uc;
639*9a747e4fSDavid du Colombier nblock++;
640*9a747e4fSDavid du Colombier es--;
641*9a747e4fSDavid du Colombier }
642*9a747e4fSDavid du Colombier else
643*9a747e4fSDavid du Colombier while (es > 0) {
644*9a747e4fSDavid du Colombier if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
645*9a747e4fSDavid du Colombier s->tt[nblock] = (UInt32)uc;
646*9a747e4fSDavid du Colombier nblock++;
647*9a747e4fSDavid du Colombier es--;
648*9a747e4fSDavid du Colombier };
649*9a747e4fSDavid du Colombier
650*9a747e4fSDavid du Colombier continue;
651*9a747e4fSDavid du Colombier
652*9a747e4fSDavid du Colombier } else {
653*9a747e4fSDavid du Colombier
654*9a747e4fSDavid du Colombier if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
655*9a747e4fSDavid du Colombier
656*9a747e4fSDavid du Colombier /*-- uc = MTF ( nextSym-1 ) --*/
657*9a747e4fSDavid du Colombier {
658*9a747e4fSDavid du Colombier Int32 ii, jj, kk, pp, lno, off;
659*9a747e4fSDavid du Colombier UInt32 nn;
660*9a747e4fSDavid du Colombier nn = (UInt32)(nextSym - 1);
661*9a747e4fSDavid du Colombier
662*9a747e4fSDavid du Colombier if (nn < MTFL_SIZE) {
663*9a747e4fSDavid du Colombier /* avoid general-case expense */
664*9a747e4fSDavid du Colombier pp = s->mtfbase[0];
665*9a747e4fSDavid du Colombier uc = s->mtfa[pp+nn];
666*9a747e4fSDavid du Colombier while (nn > 3) {
667*9a747e4fSDavid du Colombier Int32 z = pp+nn;
668*9a747e4fSDavid du Colombier s->mtfa[(z) ] = s->mtfa[(z)-1];
669*9a747e4fSDavid du Colombier s->mtfa[(z)-1] = s->mtfa[(z)-2];
670*9a747e4fSDavid du Colombier s->mtfa[(z)-2] = s->mtfa[(z)-3];
671*9a747e4fSDavid du Colombier s->mtfa[(z)-3] = s->mtfa[(z)-4];
672*9a747e4fSDavid du Colombier nn -= 4;
673*9a747e4fSDavid du Colombier }
674*9a747e4fSDavid du Colombier while (nn > 0) {
675*9a747e4fSDavid du Colombier s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
676*9a747e4fSDavid du Colombier };
677*9a747e4fSDavid du Colombier s->mtfa[pp] = uc;
678*9a747e4fSDavid du Colombier } else {
679*9a747e4fSDavid du Colombier /* general case */
680*9a747e4fSDavid du Colombier lno = nn / MTFL_SIZE;
681*9a747e4fSDavid du Colombier off = nn % MTFL_SIZE;
682*9a747e4fSDavid du Colombier pp = s->mtfbase[lno] + off;
683*9a747e4fSDavid du Colombier uc = s->mtfa[pp];
684*9a747e4fSDavid du Colombier while (pp > s->mtfbase[lno]) {
685*9a747e4fSDavid du Colombier s->mtfa[pp] = s->mtfa[pp-1]; pp--;
686*9a747e4fSDavid du Colombier };
687*9a747e4fSDavid du Colombier s->mtfbase[lno]++;
688*9a747e4fSDavid du Colombier while (lno > 0) {
689*9a747e4fSDavid du Colombier s->mtfbase[lno]--;
690*9a747e4fSDavid du Colombier s->mtfa[s->mtfbase[lno]]
691*9a747e4fSDavid du Colombier = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
692*9a747e4fSDavid du Colombier lno--;
693*9a747e4fSDavid du Colombier }
694*9a747e4fSDavid du Colombier s->mtfbase[0]--;
695*9a747e4fSDavid du Colombier s->mtfa[s->mtfbase[0]] = uc;
696*9a747e4fSDavid du Colombier if (s->mtfbase[0] == 0) {
697*9a747e4fSDavid du Colombier kk = MTFA_SIZE-1;
698*9a747e4fSDavid du Colombier for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
699*9a747e4fSDavid du Colombier for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
700*9a747e4fSDavid du Colombier s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
701*9a747e4fSDavid du Colombier kk--;
702*9a747e4fSDavid du Colombier }
703*9a747e4fSDavid du Colombier s->mtfbase[ii] = kk + 1;
704*9a747e4fSDavid du Colombier }
705*9a747e4fSDavid du Colombier }
706*9a747e4fSDavid du Colombier }
707*9a747e4fSDavid du Colombier }
708*9a747e4fSDavid du Colombier /*-- end uc = MTF ( nextSym-1 ) --*/
709*9a747e4fSDavid du Colombier
710*9a747e4fSDavid du Colombier s->unzftab[s->seqToUnseq[uc]]++;
711*9a747e4fSDavid du Colombier if (0 && s->smallDecompress)
712*9a747e4fSDavid du Colombier s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
713*9a747e4fSDavid du Colombier s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
714*9a747e4fSDavid du Colombier nblock++;
715*9a747e4fSDavid du Colombier
716*9a747e4fSDavid du Colombier GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
717*9a747e4fSDavid du Colombier continue;
718*9a747e4fSDavid du Colombier }
719*9a747e4fSDavid du Colombier }
720*9a747e4fSDavid du Colombier
721*9a747e4fSDavid du Colombier /* Now we know what nblock is, we can do a better sanity
722*9a747e4fSDavid du Colombier check on s->origPtr.
723*9a747e4fSDavid du Colombier */
724*9a747e4fSDavid du Colombier if (s->origPtr < 0 || s->origPtr >= nblock)
725*9a747e4fSDavid du Colombier RETURN(BZ_DATA_ERROR);
726*9a747e4fSDavid du Colombier
727*9a747e4fSDavid du Colombier s->state_out_len = 0;
728*9a747e4fSDavid du Colombier s->state_out_ch = 0;
729*9a747e4fSDavid du Colombier BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
730*9a747e4fSDavid du Colombier s->state = BZ_X_OUTPUT;
731*9a747e4fSDavid du Colombier // if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
732*9a747e4fSDavid du Colombier
733*9a747e4fSDavid du Colombier /*-- Set up cftab to facilitate generation of T^(-1) --*/
734*9a747e4fSDavid du Colombier s->cftab[0] = 0;
735*9a747e4fSDavid du Colombier for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
736*9a747e4fSDavid du Colombier for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
737*9a747e4fSDavid du Colombier
738*9a747e4fSDavid du Colombier if (0 && s->smallDecompress) {
739*9a747e4fSDavid du Colombier
740*9a747e4fSDavid du Colombier /*-- Make a copy of cftab, used in generation of T --*/
741*9a747e4fSDavid du Colombier for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
742*9a747e4fSDavid du Colombier
743*9a747e4fSDavid du Colombier /*-- compute the T vector --*/
744*9a747e4fSDavid du Colombier for (i = 0; i < nblock; i++) {
745*9a747e4fSDavid du Colombier uc = (UChar)(s->ll16[i]);
746*9a747e4fSDavid du Colombier SET_LL(i, s->cftabCopy[uc]);
747*9a747e4fSDavid du Colombier s->cftabCopy[uc]++;
748*9a747e4fSDavid du Colombier }
749*9a747e4fSDavid du Colombier
750*9a747e4fSDavid du Colombier /*-- Compute T^(-1) by pointer reversal on T --*/
751*9a747e4fSDavid du Colombier i = s->origPtr;
752*9a747e4fSDavid du Colombier j = GET_LL(i);
753*9a747e4fSDavid du Colombier do {
754*9a747e4fSDavid du Colombier Int32 tmp = GET_LL(j);
755*9a747e4fSDavid du Colombier SET_LL(j, i);
756*9a747e4fSDavid du Colombier i = j;
757*9a747e4fSDavid du Colombier j = tmp;
758*9a747e4fSDavid du Colombier }
759*9a747e4fSDavid du Colombier while (i != s->origPtr);
760*9a747e4fSDavid du Colombier
761*9a747e4fSDavid du Colombier s->tPos = s->origPtr;
762*9a747e4fSDavid du Colombier s->nblock_used = 0;
763*9a747e4fSDavid du Colombier if (s->blockRandomised) {
764*9a747e4fSDavid du Colombier BZ_RAND_INIT_MASK;
765*9a747e4fSDavid du Colombier BZ_GET_SMALL(s->k0); s->nblock_used++;
766*9a747e4fSDavid du Colombier BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
767*9a747e4fSDavid du Colombier } else {
768*9a747e4fSDavid du Colombier BZ_GET_SMALL(s->k0); s->nblock_used++;
769*9a747e4fSDavid du Colombier }
770*9a747e4fSDavid du Colombier
771*9a747e4fSDavid du Colombier } else {
772*9a747e4fSDavid du Colombier
773*9a747e4fSDavid du Colombier /*-- compute the T^(-1) vector --*/
774*9a747e4fSDavid du Colombier for (i = 0; i < nblock; i++) {
775*9a747e4fSDavid du Colombier uc = (UChar)(s->tt[i] & 0xff);
776*9a747e4fSDavid du Colombier s->tt[s->cftab[uc]] |= (i << 8);
777*9a747e4fSDavid du Colombier s->cftab[uc]++;
778*9a747e4fSDavid du Colombier }
779*9a747e4fSDavid du Colombier
780*9a747e4fSDavid du Colombier s->tPos = s->tt[s->origPtr] >> 8;
781*9a747e4fSDavid du Colombier s->nblock_used = 0;
782*9a747e4fSDavid du Colombier if (s->blockRandomised) {
783*9a747e4fSDavid du Colombier BZ_RAND_INIT_MASK;
784*9a747e4fSDavid du Colombier BZ_GET_FAST(s->k0); s->nblock_used++;
785*9a747e4fSDavid du Colombier BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
786*9a747e4fSDavid du Colombier } else {
787*9a747e4fSDavid du Colombier BZ_GET_FAST(s->k0); s->nblock_used++;
788*9a747e4fSDavid du Colombier }
789*9a747e4fSDavid du Colombier
790*9a747e4fSDavid du Colombier }
791*9a747e4fSDavid du Colombier
792*9a747e4fSDavid du Colombier RETURN(BZ_OK);
793*9a747e4fSDavid du Colombier
794*9a747e4fSDavid du Colombier
795*9a747e4fSDavid du Colombier
796*9a747e4fSDavid du Colombier endhdr_2:
797*9a747e4fSDavid du Colombier
798*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ENDHDR_2, uc);
799*9a747e4fSDavid du Colombier if (uc != 0x72) RETURN(BZ_DATA_ERROR);
800*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ENDHDR_3, uc);
801*9a747e4fSDavid du Colombier if (uc != 0x45) RETURN(BZ_DATA_ERROR);
802*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ENDHDR_4, uc);
803*9a747e4fSDavid du Colombier if (uc != 0x38) RETURN(BZ_DATA_ERROR);
804*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ENDHDR_5, uc);
805*9a747e4fSDavid du Colombier if (uc != 0x50) RETURN(BZ_DATA_ERROR);
806*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_ENDHDR_6, uc);
807*9a747e4fSDavid du Colombier if (uc != 0x90) RETURN(BZ_DATA_ERROR);
808*9a747e4fSDavid du Colombier
809*9a747e4fSDavid du Colombier s->storedCombinedCRC = 0;
810*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_CCRC_1, uc);
811*9a747e4fSDavid du Colombier s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
812*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_CCRC_2, uc);
813*9a747e4fSDavid du Colombier s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
814*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_CCRC_3, uc);
815*9a747e4fSDavid du Colombier s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
816*9a747e4fSDavid du Colombier GET_UCHAR(BZ_X_CCRC_4, uc);
817*9a747e4fSDavid du Colombier s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
818*9a747e4fSDavid du Colombier
819*9a747e4fSDavid du Colombier s->state = BZ_X_IDLE;
820*9a747e4fSDavid du Colombier RETURN(BZ_STREAM_END);
821*9a747e4fSDavid du Colombier
822*9a747e4fSDavid du Colombier default: AssertH ( False, 4001 );
823*9a747e4fSDavid du Colombier }
824*9a747e4fSDavid du Colombier
825*9a747e4fSDavid du Colombier AssertH ( False, 4002 );
826*9a747e4fSDavid du Colombier
827*9a747e4fSDavid du Colombier save_state_and_return:
828*9a747e4fSDavid du Colombier
829*9a747e4fSDavid du Colombier s->save_i = i;
830*9a747e4fSDavid du Colombier s->save_j = j;
831*9a747e4fSDavid du Colombier s->save_t = t;
832*9a747e4fSDavid du Colombier s->save_alphaSize = alphaSize;
833*9a747e4fSDavid du Colombier s->save_nGroups = nGroups;
834*9a747e4fSDavid du Colombier s->save_nSelectors = nSelectors;
835*9a747e4fSDavid du Colombier s->save_EOB = EOB;
836*9a747e4fSDavid du Colombier s->save_groupNo = groupNo;
837*9a747e4fSDavid du Colombier s->save_groupPos = groupPos;
838*9a747e4fSDavid du Colombier s->save_nextSym = nextSym;
839*9a747e4fSDavid du Colombier s->save_nblockMAX = nblockMAX;
840*9a747e4fSDavid du Colombier s->save_nblock = nblock;
841*9a747e4fSDavid du Colombier s->save_es = es;
842*9a747e4fSDavid du Colombier s->save_N = N;
843*9a747e4fSDavid du Colombier s->save_curr = curr;
844*9a747e4fSDavid du Colombier s->save_zt = zt;
845*9a747e4fSDavid du Colombier s->save_zn = zn;
846*9a747e4fSDavid du Colombier s->save_zvec = zvec;
847*9a747e4fSDavid du Colombier s->save_zj = zj;
848*9a747e4fSDavid du Colombier s->save_gSel = gSel;
849*9a747e4fSDavid du Colombier s->save_gMinlen = gMinlen;
850*9a747e4fSDavid du Colombier s->save_gLimit = gLimit;
851*9a747e4fSDavid du Colombier s->save_gBase = gBase;
852*9a747e4fSDavid du Colombier s->save_gPerm = gPerm;
853*9a747e4fSDavid du Colombier
854*9a747e4fSDavid du Colombier return retVal;
855*9a747e4fSDavid du Colombier }
856*9a747e4fSDavid du Colombier
857*9a747e4fSDavid du Colombier
858*9a747e4fSDavid du Colombier /*-------------------------------------------------------------*/
859*9a747e4fSDavid du Colombier /*--- end decompress.c ---*/
860*9a747e4fSDavid du Colombier /*-------------------------------------------------------------*/
861