xref: /onnv-gate/usr/src/common/bzip2/bzlib.c (revision 10843:eb166ea6e74e)
1*10843SDave.Plauger@Sun.COM 
2*10843SDave.Plauger@Sun.COM /*-------------------------------------------------------------*/
3*10843SDave.Plauger@Sun.COM /*--- Library top-level functions.                          ---*/
4*10843SDave.Plauger@Sun.COM /*---                                               bzlib.c ---*/
5*10843SDave.Plauger@Sun.COM /*-------------------------------------------------------------*/
6*10843SDave.Plauger@Sun.COM 
7*10843SDave.Plauger@Sun.COM /* ------------------------------------------------------------------
8*10843SDave.Plauger@Sun.COM    This file is part of bzip2/libbzip2, a program and library for
9*10843SDave.Plauger@Sun.COM    lossless, block-sorting data compression.
10*10843SDave.Plauger@Sun.COM 
11*10843SDave.Plauger@Sun.COM    bzip2/libbzip2 version 1.0.5 of 10 December 2007
12*10843SDave.Plauger@Sun.COM    Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
13*10843SDave.Plauger@Sun.COM 
14*10843SDave.Plauger@Sun.COM    Please read the WARNING, DISCLAIMER and PATENTS sections in the
15*10843SDave.Plauger@Sun.COM    README file.
16*10843SDave.Plauger@Sun.COM 
17*10843SDave.Plauger@Sun.COM    This program is released under the terms of the license contained
18*10843SDave.Plauger@Sun.COM    in the file LICENSE.
19*10843SDave.Plauger@Sun.COM    ------------------------------------------------------------------ */
20*10843SDave.Plauger@Sun.COM 
21*10843SDave.Plauger@Sun.COM /* CHANGES
22*10843SDave.Plauger@Sun.COM    0.9.0    -- original version.
23*10843SDave.Plauger@Sun.COM    0.9.0a/b -- no changes in this file.
24*10843SDave.Plauger@Sun.COM    0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
25*10843SDave.Plauger@Sun.COM      fixed bzWrite/bzRead to ignore zero-length requests.
26*10843SDave.Plauger@Sun.COM      fixed bzread to correctly handle read requests after EOF.
27*10843SDave.Plauger@Sun.COM      wrong parameter order in call to bzDecompressInit in
28*10843SDave.Plauger@Sun.COM      bzBuffToBuffDecompress.  Fixed.
29*10843SDave.Plauger@Sun.COM */
30*10843SDave.Plauger@Sun.COM 
31*10843SDave.Plauger@Sun.COM #include "bzlib_private.h"
32*10843SDave.Plauger@Sun.COM 
33*10843SDave.Plauger@Sun.COM 
34*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
35*10843SDave.Plauger@Sun.COM /*--- Compression stuff                           ---*/
36*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
37*10843SDave.Plauger@Sun.COM 
38*10843SDave.Plauger@Sun.COM 
39*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
40*10843SDave.Plauger@Sun.COM #ifndef BZ_NO_STDIO
BZ2_bz__AssertH__fail(int errcode)41*10843SDave.Plauger@Sun.COM void BZ2_bz__AssertH__fail ( int errcode )
42*10843SDave.Plauger@Sun.COM {
43*10843SDave.Plauger@Sun.COM    fprintf(stderr,
44*10843SDave.Plauger@Sun.COM       "\n\nbzip2/libbzip2: internal error number %d.\n"
45*10843SDave.Plauger@Sun.COM       "This is a bug in bzip2/libbzip2, %s.\n"
46*10843SDave.Plauger@Sun.COM       "Please report it to me at: jseward@bzip.org.  If this happened\n"
47*10843SDave.Plauger@Sun.COM       "when you were using some program which uses libbzip2 as a\n"
48*10843SDave.Plauger@Sun.COM       "component, you should also report this bug to the author(s)\n"
49*10843SDave.Plauger@Sun.COM       "of that program.  Please make an effort to report this bug;\n"
50*10843SDave.Plauger@Sun.COM       "timely and accurate bug reports eventually lead to higher\n"
51*10843SDave.Plauger@Sun.COM       "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
52*10843SDave.Plauger@Sun.COM       errcode,
53*10843SDave.Plauger@Sun.COM       BZ2_bzlibVersion()
54*10843SDave.Plauger@Sun.COM    );
55*10843SDave.Plauger@Sun.COM 
56*10843SDave.Plauger@Sun.COM    if (errcode == 1007) {
57*10843SDave.Plauger@Sun.COM    fprintf(stderr,
58*10843SDave.Plauger@Sun.COM       "\n*** A special note about internal error number 1007 ***\n"
59*10843SDave.Plauger@Sun.COM       "\n"
60*10843SDave.Plauger@Sun.COM       "Experience suggests that a common cause of i.e. 1007\n"
61*10843SDave.Plauger@Sun.COM       "is unreliable memory or other hardware.  The 1007 assertion\n"
62*10843SDave.Plauger@Sun.COM       "just happens to cross-check the results of huge numbers of\n"
63*10843SDave.Plauger@Sun.COM       "memory reads/writes, and so acts (unintendedly) as a stress\n"
64*10843SDave.Plauger@Sun.COM       "test of your memory system.\n"
65*10843SDave.Plauger@Sun.COM       "\n"
66*10843SDave.Plauger@Sun.COM       "I suggest the following: try compressing the file again,\n"
67*10843SDave.Plauger@Sun.COM       "possibly monitoring progress in detail with the -vv flag.\n"
68*10843SDave.Plauger@Sun.COM       "\n"
69*10843SDave.Plauger@Sun.COM       "* If the error cannot be reproduced, and/or happens at different\n"
70*10843SDave.Plauger@Sun.COM       "  points in compression, you may have a flaky memory system.\n"
71*10843SDave.Plauger@Sun.COM       "  Try a memory-test program.  I have used Memtest86\n"
72*10843SDave.Plauger@Sun.COM       "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
73*10843SDave.Plauger@Sun.COM       "  Memtest86 tests memory much more thorougly than your BIOSs\n"
74*10843SDave.Plauger@Sun.COM       "  power-on test, and may find failures that the BIOS doesn't.\n"
75*10843SDave.Plauger@Sun.COM       "\n"
76*10843SDave.Plauger@Sun.COM       "* If the error can be repeatably reproduced, this is a bug in\n"
77*10843SDave.Plauger@Sun.COM       "  bzip2, and I would very much like to hear about it.  Please\n"
78*10843SDave.Plauger@Sun.COM       "  let me know, and, ideally, save a copy of the file causing the\n"
79*10843SDave.Plauger@Sun.COM       "  problem -- without which I will be unable to investigate it.\n"
80*10843SDave.Plauger@Sun.COM       "\n"
81*10843SDave.Plauger@Sun.COM    );
82*10843SDave.Plauger@Sun.COM    }
83*10843SDave.Plauger@Sun.COM 
84*10843SDave.Plauger@Sun.COM    exit(3);
85*10843SDave.Plauger@Sun.COM }
86*10843SDave.Plauger@Sun.COM #endif
87*10843SDave.Plauger@Sun.COM 
88*10843SDave.Plauger@Sun.COM 
89*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
90*10843SDave.Plauger@Sun.COM static
bz_config_ok(void)91*10843SDave.Plauger@Sun.COM int bz_config_ok ( void )
92*10843SDave.Plauger@Sun.COM {
93*10843SDave.Plauger@Sun.COM    if (sizeof(int)   != 4) return 0;
94*10843SDave.Plauger@Sun.COM    if (sizeof(short) != 2) return 0;
95*10843SDave.Plauger@Sun.COM    if (sizeof(char)  != 1) return 0;
96*10843SDave.Plauger@Sun.COM    return 1;
97*10843SDave.Plauger@Sun.COM }
98*10843SDave.Plauger@Sun.COM 
99*10843SDave.Plauger@Sun.COM /*
100*10843SDave.Plauger@Sun.COM  * Added for Solaris kernel
101*10843SDave.Plauger@Sun.COM  */
102*10843SDave.Plauger@Sun.COM #define BZES \
103*10843SDave.Plauger@Sun.COM BZE(BZ_OK) \
104*10843SDave.Plauger@Sun.COM BZE(BZ_RUN_OK) \
105*10843SDave.Plauger@Sun.COM BZE(BZ_FLUSH_OK) \
106*10843SDave.Plauger@Sun.COM BZE(BZ_FINISH_OK) \
107*10843SDave.Plauger@Sun.COM BZE(BZ_STREAM_END) \
108*10843SDave.Plauger@Sun.COM BZE(BZ_SEQUENCE_ERROR) \
109*10843SDave.Plauger@Sun.COM BZE(BZ_PARAM_ERROR) \
110*10843SDave.Plauger@Sun.COM BZE(BZ_MEM_ERROR) \
111*10843SDave.Plauger@Sun.COM BZE(BZ_DATA_ERROR) \
112*10843SDave.Plauger@Sun.COM BZE(BZ_DATA_ERROR_MAGIC) \
113*10843SDave.Plauger@Sun.COM BZE(BZ_IO_ERROR) \
114*10843SDave.Plauger@Sun.COM BZE(BZ_UNEXPECTED_EOF) \
115*10843SDave.Plauger@Sun.COM BZE(BZ_OUTBUFF_FULL) \
116*10843SDave.Plauger@Sun.COM BZE(BZ_CONFIG_ERROR)
117*10843SDave.Plauger@Sun.COM 
BZ_API(BZ2_bzErrorString)118*10843SDave.Plauger@Sun.COM BZ_EXTERN const char * BZ_API(BZ2_bzErrorString) (
119*10843SDave.Plauger@Sun.COM       int error_code
120*10843SDave.Plauger@Sun.COM    )
121*10843SDave.Plauger@Sun.COM {
122*10843SDave.Plauger@Sun.COM 	switch (error_code)
123*10843SDave.Plauger@Sun.COM 	{
124*10843SDave.Plauger@Sun.COM #define BZE(x) case x: return (#x);
125*10843SDave.Plauger@Sun.COM BZES
126*10843SDave.Plauger@Sun.COM #undef BZE
127*10843SDave.Plauger@Sun.COM 	}
128*10843SDave.Plauger@Sun.COM 	return ("BZ_UNKNOWN_ERROR");
129*10843SDave.Plauger@Sun.COM }
130*10843SDave.Plauger@Sun.COM 
131*10843SDave.Plauger@Sun.COM #include <sys/sysmacros.h>
132*10843SDave.Plauger@Sun.COM 
133*10843SDave.Plauger@Sun.COM #ifdef _KERNEL
134*10843SDave.Plauger@Sun.COM 
135*10843SDave.Plauger@Sun.COM #include <sys/types.h>
136*10843SDave.Plauger@Sun.COM #include <sys/cmn_err.h>
137*10843SDave.Plauger@Sun.COM #include <sys/kmem.h>
138*10843SDave.Plauger@Sun.COM 
139*10843SDave.Plauger@Sun.COM void
bz_internal_error(int errcode)140*10843SDave.Plauger@Sun.COM bz_internal_error(int errcode)
141*10843SDave.Plauger@Sun.COM {
142*10843SDave.Plauger@Sun.COM 	panic("bzip2 internal error: %s\n", BZ2_bzErrorString(errcode));
143*10843SDave.Plauger@Sun.COM }
144*10843SDave.Plauger@Sun.COM 
145*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
146*10843SDave.Plauger@Sun.COM typedef struct {
147*10843SDave.Plauger@Sun.COM 	char *buf;
148*10843SDave.Plauger@Sun.COM 	size_t sz;
149*10843SDave.Plauger@Sun.COM } bzap;
150*10843SDave.Plauger@Sun.COM 
151*10843SDave.Plauger@Sun.COM static
default_bzalloc(void * opaque,Int32 items,Int32 size)152*10843SDave.Plauger@Sun.COM void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
153*10843SDave.Plauger@Sun.COM {
154*10843SDave.Plauger@Sun.COM 	size_t sz = sizeof (bzap) + BZ2_BZALLOC_ALIGN + (items * size);
155*10843SDave.Plauger@Sun.COM 	uintptr_t p = (uintptr_t)kmem_alloc(sz, KM_SLEEP);
156*10843SDave.Plauger@Sun.COM 
157*10843SDave.Plauger@Sun.COM 	if (p != NULL) {
158*10843SDave.Plauger@Sun.COM 		bzap *pp = (bzap *)((p + sizeof (bzap) + BZ2_BZALLOC_ALIGN - 1) &
159*10843SDave.Plauger@Sun.COM 		    -BZ2_BZALLOC_ALIGN);
160*10843SDave.Plauger@Sun.COM 		pp[-1].buf = (void *)p;
161*10843SDave.Plauger@Sun.COM 		pp[-1].sz = sz;
162*10843SDave.Plauger@Sun.COM 		return (pp);
163*10843SDave.Plauger@Sun.COM 	}
164*10843SDave.Plauger@Sun.COM 	return (NULL);
165*10843SDave.Plauger@Sun.COM }
166*10843SDave.Plauger@Sun.COM 
167*10843SDave.Plauger@Sun.COM static
default_bzfree(void * opaque,void * addr)168*10843SDave.Plauger@Sun.COM void default_bzfree ( void* opaque, void* addr )
169*10843SDave.Plauger@Sun.COM {
170*10843SDave.Plauger@Sun.COM 	if (addr != NULL) {
171*10843SDave.Plauger@Sun.COM 		bzap *pp = (bzap *)addr - 1;
172*10843SDave.Plauger@Sun.COM 		kmem_free(pp->buf, pp->sz);
173*10843SDave.Plauger@Sun.COM 	}
174*10843SDave.Plauger@Sun.COM }
175*10843SDave.Plauger@Sun.COM 
176*10843SDave.Plauger@Sun.COM #else
177*10843SDave.Plauger@Sun.COM 
178*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
179*10843SDave.Plauger@Sun.COM static
default_bzalloc(void * opaque,Int32 items,Int32 size)180*10843SDave.Plauger@Sun.COM void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
181*10843SDave.Plauger@Sun.COM {
182*10843SDave.Plauger@Sun.COM    void* v = malloc ( items * size );
183*10843SDave.Plauger@Sun.COM    return v;
184*10843SDave.Plauger@Sun.COM }
185*10843SDave.Plauger@Sun.COM 
186*10843SDave.Plauger@Sun.COM static
default_bzfree(void * opaque,void * addr)187*10843SDave.Plauger@Sun.COM void default_bzfree ( void* opaque, void* addr )
188*10843SDave.Plauger@Sun.COM {
189*10843SDave.Plauger@Sun.COM    if (addr != NULL) free ( addr );
190*10843SDave.Plauger@Sun.COM }
191*10843SDave.Plauger@Sun.COM #endif	/* _KERNEL */
192*10843SDave.Plauger@Sun.COM 
193*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
194*10843SDave.Plauger@Sun.COM static
prepare_new_block(EState * s)195*10843SDave.Plauger@Sun.COM void prepare_new_block ( EState* s )
196*10843SDave.Plauger@Sun.COM {
197*10843SDave.Plauger@Sun.COM    Int32 i;
198*10843SDave.Plauger@Sun.COM    s->nblock = 0;
199*10843SDave.Plauger@Sun.COM    s->numZ = 0;
200*10843SDave.Plauger@Sun.COM    s->state_out_pos = 0;
201*10843SDave.Plauger@Sun.COM    BZ_INITIALISE_CRC ( s->blockCRC );
202*10843SDave.Plauger@Sun.COM    for (i = 0; i < 256; i++) s->inUse[i] = False;
203*10843SDave.Plauger@Sun.COM    s->blockNo++;
204*10843SDave.Plauger@Sun.COM }
205*10843SDave.Plauger@Sun.COM 
206*10843SDave.Plauger@Sun.COM 
207*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
208*10843SDave.Plauger@Sun.COM static
init_RL(EState * s)209*10843SDave.Plauger@Sun.COM void init_RL ( EState* s )
210*10843SDave.Plauger@Sun.COM {
211*10843SDave.Plauger@Sun.COM    s->state_in_ch  = 256;
212*10843SDave.Plauger@Sun.COM    s->state_in_len = 0;
213*10843SDave.Plauger@Sun.COM }
214*10843SDave.Plauger@Sun.COM 
215*10843SDave.Plauger@Sun.COM 
216*10843SDave.Plauger@Sun.COM static
isempty_RL(EState * s)217*10843SDave.Plauger@Sun.COM Bool isempty_RL ( EState* s )
218*10843SDave.Plauger@Sun.COM {
219*10843SDave.Plauger@Sun.COM    if (s->state_in_ch < 256 && s->state_in_len > 0)
220*10843SDave.Plauger@Sun.COM       return False; else
221*10843SDave.Plauger@Sun.COM       return True;
222*10843SDave.Plauger@Sun.COM }
223*10843SDave.Plauger@Sun.COM 
224*10843SDave.Plauger@Sun.COM 
225*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzCompressInit)226*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzCompressInit)
227*10843SDave.Plauger@Sun.COM                     ( bz_stream* strm,
228*10843SDave.Plauger@Sun.COM                      int        blockSize100k,
229*10843SDave.Plauger@Sun.COM                      int        verbosity,
230*10843SDave.Plauger@Sun.COM                      int        workFactor )
231*10843SDave.Plauger@Sun.COM {
232*10843SDave.Plauger@Sun.COM    Int32   n;
233*10843SDave.Plauger@Sun.COM    EState* s;
234*10843SDave.Plauger@Sun.COM 
235*10843SDave.Plauger@Sun.COM    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
236*10843SDave.Plauger@Sun.COM 
237*10843SDave.Plauger@Sun.COM    if (strm == NULL ||
238*10843SDave.Plauger@Sun.COM        blockSize100k < 1 || blockSize100k > 9 ||
239*10843SDave.Plauger@Sun.COM        workFactor < 0 || workFactor > 250)
240*10843SDave.Plauger@Sun.COM      return BZ_PARAM_ERROR;
241*10843SDave.Plauger@Sun.COM 
242*10843SDave.Plauger@Sun.COM    if (workFactor == 0) workFactor = 30;
243*10843SDave.Plauger@Sun.COM    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
244*10843SDave.Plauger@Sun.COM    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
245*10843SDave.Plauger@Sun.COM 
246*10843SDave.Plauger@Sun.COM    s = BZALLOC( sizeof(EState) );
247*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_MEM_ERROR;
248*10843SDave.Plauger@Sun.COM    s->strm = strm;
249*10843SDave.Plauger@Sun.COM 
250*10843SDave.Plauger@Sun.COM    s->arr1 = NULL;
251*10843SDave.Plauger@Sun.COM    s->arr2 = NULL;
252*10843SDave.Plauger@Sun.COM    s->ftab = NULL;
253*10843SDave.Plauger@Sun.COM 
254*10843SDave.Plauger@Sun.COM    n       = 100000 * blockSize100k;
255*10843SDave.Plauger@Sun.COM    s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
256*10843SDave.Plauger@Sun.COM    s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
257*10843SDave.Plauger@Sun.COM    s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
258*10843SDave.Plauger@Sun.COM 
259*10843SDave.Plauger@Sun.COM    if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
260*10843SDave.Plauger@Sun.COM       if (s->arr1 != NULL) BZFREE(s->arr1);
261*10843SDave.Plauger@Sun.COM       if (s->arr2 != NULL) BZFREE(s->arr2);
262*10843SDave.Plauger@Sun.COM       if (s->ftab != NULL) BZFREE(s->ftab);
263*10843SDave.Plauger@Sun.COM       if (s       != NULL) BZFREE(s);
264*10843SDave.Plauger@Sun.COM       return BZ_MEM_ERROR;
265*10843SDave.Plauger@Sun.COM    }
266*10843SDave.Plauger@Sun.COM 
267*10843SDave.Plauger@Sun.COM    s->blockNo           = 0;
268*10843SDave.Plauger@Sun.COM    s->state             = BZ_S_INPUT;
269*10843SDave.Plauger@Sun.COM    s->mode              = BZ_M_RUNNING;
270*10843SDave.Plauger@Sun.COM    s->combinedCRC       = 0;
271*10843SDave.Plauger@Sun.COM    s->blockSize100k     = blockSize100k;
272*10843SDave.Plauger@Sun.COM    s->nblockMAX         = 100000 * blockSize100k - 19;
273*10843SDave.Plauger@Sun.COM    s->verbosity         = verbosity;
274*10843SDave.Plauger@Sun.COM    s->workFactor        = workFactor;
275*10843SDave.Plauger@Sun.COM 
276*10843SDave.Plauger@Sun.COM    s->block             = (UChar*)s->arr2;
277*10843SDave.Plauger@Sun.COM    s->mtfv              = (UInt16*)s->arr1;
278*10843SDave.Plauger@Sun.COM    s->zbits             = NULL;
279*10843SDave.Plauger@Sun.COM    s->ptr               = (UInt32*)s->arr1;
280*10843SDave.Plauger@Sun.COM 
281*10843SDave.Plauger@Sun.COM    strm->state          = s;
282*10843SDave.Plauger@Sun.COM    strm->total_in_lo32  = 0;
283*10843SDave.Plauger@Sun.COM    strm->total_in_hi32  = 0;
284*10843SDave.Plauger@Sun.COM    strm->total_out_lo32 = 0;
285*10843SDave.Plauger@Sun.COM    strm->total_out_hi32 = 0;
286*10843SDave.Plauger@Sun.COM    init_RL ( s );
287*10843SDave.Plauger@Sun.COM    prepare_new_block ( s );
288*10843SDave.Plauger@Sun.COM    return BZ_OK;
289*10843SDave.Plauger@Sun.COM }
290*10843SDave.Plauger@Sun.COM 
291*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
292*10843SDave.Plauger@Sun.COM /*
293*10843SDave.Plauger@Sun.COM  * returns the BZALLOC size needed for bzCompressInit
294*10843SDave.Plauger@Sun.COM  */
BZ_API(BZ2_bzCompressInitSize)295*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzCompressInitSize) (
296*10843SDave.Plauger@Sun.COM                      int        blockSize100k)
297*10843SDave.Plauger@Sun.COM {
298*10843SDave.Plauger@Sun.COM    Int32   n, t;
299*10843SDave.Plauger@Sun.COM 
300*10843SDave.Plauger@Sun.COM    n       = 100000 * blockSize100k;
301*10843SDave.Plauger@Sun.COM    t       = 0;
302*10843SDave.Plauger@Sun.COM    t += ( sizeof(EState) );
303*10843SDave.Plauger@Sun.COM    t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
304*10843SDave.Plauger@Sun.COM    t += ( n                  * sizeof(UInt32) );
305*10843SDave.Plauger@Sun.COM    t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
306*10843SDave.Plauger@Sun.COM    t += ( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
307*10843SDave.Plauger@Sun.COM    t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
308*10843SDave.Plauger@Sun.COM    t += ( 65537              * sizeof(UInt32) );
309*10843SDave.Plauger@Sun.COM    t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
310*10843SDave.Plauger@Sun.COM    return (t);
311*10843SDave.Plauger@Sun.COM }
312*10843SDave.Plauger@Sun.COM 
313*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
314*10843SDave.Plauger@Sun.COM /*
315*10843SDave.Plauger@Sun.COM  * added to allow reuse of bz_stream without malloc/free
316*10843SDave.Plauger@Sun.COM  */
BZ_API(BZ2_bzCompressReset)317*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzCompressReset) ( bz_stream *strm )
318*10843SDave.Plauger@Sun.COM {
319*10843SDave.Plauger@Sun.COM    EState* s = strm->state;
320*10843SDave.Plauger@Sun.COM 
321*10843SDave.Plauger@Sun.COM    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
322*10843SDave.Plauger@Sun.COM 
323*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_MEM_ERROR;
324*10843SDave.Plauger@Sun.COM    s->strm = strm;
325*10843SDave.Plauger@Sun.COM 
326*10843SDave.Plauger@Sun.COM    s->blockNo           = 0;
327*10843SDave.Plauger@Sun.COM    s->state             = BZ_S_INPUT;
328*10843SDave.Plauger@Sun.COM    s->mode              = BZ_M_RUNNING;
329*10843SDave.Plauger@Sun.COM    s->combinedCRC       = 0;
330*10843SDave.Plauger@Sun.COM    s->nblockMAX         = 100000 * s->blockSize100k - 19;
331*10843SDave.Plauger@Sun.COM 
332*10843SDave.Plauger@Sun.COM    s->block             = (UChar*)s->arr2;
333*10843SDave.Plauger@Sun.COM    s->mtfv              = (UInt16*)s->arr1;
334*10843SDave.Plauger@Sun.COM    s->zbits             = NULL;
335*10843SDave.Plauger@Sun.COM    s->ptr               = (UInt32*)s->arr1;
336*10843SDave.Plauger@Sun.COM 
337*10843SDave.Plauger@Sun.COM    strm->state          = s;
338*10843SDave.Plauger@Sun.COM    strm->total_in_lo32  = 0;
339*10843SDave.Plauger@Sun.COM    strm->total_in_hi32  = 0;
340*10843SDave.Plauger@Sun.COM    strm->total_out_lo32 = 0;
341*10843SDave.Plauger@Sun.COM    strm->total_out_hi32 = 0;
342*10843SDave.Plauger@Sun.COM    init_RL ( s );
343*10843SDave.Plauger@Sun.COM    prepare_new_block ( s );
344*10843SDave.Plauger@Sun.COM    return BZ_OK;
345*10843SDave.Plauger@Sun.COM }
346*10843SDave.Plauger@Sun.COM 
BZ_API(BZ2_bzDecompressReset)347*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzDecompressReset) ( bz_stream* strm )
348*10843SDave.Plauger@Sun.COM {
349*10843SDave.Plauger@Sun.COM    DState* s = strm->state;
350*10843SDave.Plauger@Sun.COM 
351*10843SDave.Plauger@Sun.COM    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
352*10843SDave.Plauger@Sun.COM 
353*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
354*10843SDave.Plauger@Sun.COM 
355*10843SDave.Plauger@Sun.COM    s->strm                  = strm;
356*10843SDave.Plauger@Sun.COM 
357*10843SDave.Plauger@Sun.COM    s->state                 = BZ_X_MAGIC_1;
358*10843SDave.Plauger@Sun.COM    s->bsLive                = 0;
359*10843SDave.Plauger@Sun.COM    s->bsBuff                = 0;
360*10843SDave.Plauger@Sun.COM    s->calculatedCombinedCRC = 0;
361*10843SDave.Plauger@Sun.COM    strm->total_in_lo32      = 0;
362*10843SDave.Plauger@Sun.COM    strm->total_in_hi32      = 0;
363*10843SDave.Plauger@Sun.COM    strm->total_out_lo32     = 0;
364*10843SDave.Plauger@Sun.COM    strm->total_out_hi32     = 0;
365*10843SDave.Plauger@Sun.COM 
366*10843SDave.Plauger@Sun.COM    s->ll4                   = NULL;
367*10843SDave.Plauger@Sun.COM    s->ll16                  = NULL;
368*10843SDave.Plauger@Sun.COM    s->tt                    = NULL;
369*10843SDave.Plauger@Sun.COM    s->currBlockNo           = 0;
370*10843SDave.Plauger@Sun.COM 
371*10843SDave.Plauger@Sun.COM 
372*10843SDave.Plauger@Sun.COM    return BZ_OK;
373*10843SDave.Plauger@Sun.COM }
374*10843SDave.Plauger@Sun.COM 
375*10843SDave.Plauger@Sun.COM 
376*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
377*10843SDave.Plauger@Sun.COM static
add_pair_to_block(EState * s)378*10843SDave.Plauger@Sun.COM void add_pair_to_block ( EState* s )
379*10843SDave.Plauger@Sun.COM {
380*10843SDave.Plauger@Sun.COM    Int32 i;
381*10843SDave.Plauger@Sun.COM    UChar ch = (UChar)(s->state_in_ch);
382*10843SDave.Plauger@Sun.COM    for (i = 0; i < s->state_in_len; i++) {
383*10843SDave.Plauger@Sun.COM       BZ_UPDATE_CRC( s->blockCRC, ch );
384*10843SDave.Plauger@Sun.COM    }
385*10843SDave.Plauger@Sun.COM    s->inUse[s->state_in_ch] = True;
386*10843SDave.Plauger@Sun.COM    switch (s->state_in_len) {
387*10843SDave.Plauger@Sun.COM       case 1:
388*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
389*10843SDave.Plauger@Sun.COM          break;
390*10843SDave.Plauger@Sun.COM       case 2:
391*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
392*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
393*10843SDave.Plauger@Sun.COM          break;
394*10843SDave.Plauger@Sun.COM       case 3:
395*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
396*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
397*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
398*10843SDave.Plauger@Sun.COM          break;
399*10843SDave.Plauger@Sun.COM       default:
400*10843SDave.Plauger@Sun.COM          s->inUse[s->state_in_len-4] = True;
401*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
402*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
403*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
404*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = (UChar)ch; s->nblock++;
405*10843SDave.Plauger@Sun.COM          s->block[s->nblock] = ((UChar)(s->state_in_len-4));
406*10843SDave.Plauger@Sun.COM          s->nblock++;
407*10843SDave.Plauger@Sun.COM          break;
408*10843SDave.Plauger@Sun.COM    }
409*10843SDave.Plauger@Sun.COM }
410*10843SDave.Plauger@Sun.COM 
411*10843SDave.Plauger@Sun.COM 
412*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
413*10843SDave.Plauger@Sun.COM static
flush_RL(EState * s)414*10843SDave.Plauger@Sun.COM void flush_RL ( EState* s )
415*10843SDave.Plauger@Sun.COM {
416*10843SDave.Plauger@Sun.COM    if (s->state_in_ch < 256) add_pair_to_block ( s );
417*10843SDave.Plauger@Sun.COM    init_RL ( s );
418*10843SDave.Plauger@Sun.COM }
419*10843SDave.Plauger@Sun.COM 
420*10843SDave.Plauger@Sun.COM 
421*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
422*10843SDave.Plauger@Sun.COM #define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
423*10843SDave.Plauger@Sun.COM {                                                 \
424*10843SDave.Plauger@Sun.COM    UInt32 zchh = (UInt32)(zchh0);                 \
425*10843SDave.Plauger@Sun.COM    /*-- fast track the common case --*/           \
426*10843SDave.Plauger@Sun.COM    if (zchh != zs->state_in_ch &&                 \
427*10843SDave.Plauger@Sun.COM        zs->state_in_len == 1) {                   \
428*10843SDave.Plauger@Sun.COM       UChar ch = (UChar)(zs->state_in_ch);        \
429*10843SDave.Plauger@Sun.COM       BZ_UPDATE_CRC( zs->blockCRC, ch );          \
430*10843SDave.Plauger@Sun.COM       zs->inUse[zs->state_in_ch] = True;          \
431*10843SDave.Plauger@Sun.COM       zs->block[zs->nblock] = (UChar)ch;          \
432*10843SDave.Plauger@Sun.COM       zs->nblock++;                               \
433*10843SDave.Plauger@Sun.COM       zs->state_in_ch = zchh;                     \
434*10843SDave.Plauger@Sun.COM    }                                              \
435*10843SDave.Plauger@Sun.COM    else                                           \
436*10843SDave.Plauger@Sun.COM    /*-- general, uncommon cases --*/              \
437*10843SDave.Plauger@Sun.COM    if (zchh != zs->state_in_ch ||                 \
438*10843SDave.Plauger@Sun.COM       zs->state_in_len == 255) {                  \
439*10843SDave.Plauger@Sun.COM       if (zs->state_in_ch < 256)                  \
440*10843SDave.Plauger@Sun.COM          add_pair_to_block ( zs );                \
441*10843SDave.Plauger@Sun.COM       zs->state_in_ch = zchh;                     \
442*10843SDave.Plauger@Sun.COM       zs->state_in_len = 1;                       \
443*10843SDave.Plauger@Sun.COM    } else {                                       \
444*10843SDave.Plauger@Sun.COM       zs->state_in_len++;                         \
445*10843SDave.Plauger@Sun.COM    }                                              \
446*10843SDave.Plauger@Sun.COM }
447*10843SDave.Plauger@Sun.COM 
448*10843SDave.Plauger@Sun.COM 
449*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
450*10843SDave.Plauger@Sun.COM static
copy_input_until_stop(EState * s)451*10843SDave.Plauger@Sun.COM Bool copy_input_until_stop ( EState* s )
452*10843SDave.Plauger@Sun.COM {
453*10843SDave.Plauger@Sun.COM    Bool progress_in = False;
454*10843SDave.Plauger@Sun.COM 
455*10843SDave.Plauger@Sun.COM    if (s->mode == BZ_M_RUNNING) {
456*10843SDave.Plauger@Sun.COM 
457*10843SDave.Plauger@Sun.COM       /*-- fast track the common case --*/
458*10843SDave.Plauger@Sun.COM       while (True) {
459*10843SDave.Plauger@Sun.COM          /*-- block full? --*/
460*10843SDave.Plauger@Sun.COM          if (s->nblock >= s->nblockMAX) break;
461*10843SDave.Plauger@Sun.COM          /*-- no input? --*/
462*10843SDave.Plauger@Sun.COM          if (s->strm->avail_in == 0) break;
463*10843SDave.Plauger@Sun.COM          progress_in = True;
464*10843SDave.Plauger@Sun.COM          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
465*10843SDave.Plauger@Sun.COM          s->strm->next_in++;
466*10843SDave.Plauger@Sun.COM          s->strm->avail_in--;
467*10843SDave.Plauger@Sun.COM          s->strm->total_in_lo32++;
468*10843SDave.Plauger@Sun.COM          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
469*10843SDave.Plauger@Sun.COM       }
470*10843SDave.Plauger@Sun.COM 
471*10843SDave.Plauger@Sun.COM    } else {
472*10843SDave.Plauger@Sun.COM 
473*10843SDave.Plauger@Sun.COM       /*-- general, uncommon case --*/
474*10843SDave.Plauger@Sun.COM       while (True) {
475*10843SDave.Plauger@Sun.COM          /*-- block full? --*/
476*10843SDave.Plauger@Sun.COM          if (s->nblock >= s->nblockMAX) break;
477*10843SDave.Plauger@Sun.COM          /*-- no input? --*/
478*10843SDave.Plauger@Sun.COM          if (s->strm->avail_in == 0) break;
479*10843SDave.Plauger@Sun.COM          /*-- flush/finish end? --*/
480*10843SDave.Plauger@Sun.COM          if (s->avail_in_expect == 0) break;
481*10843SDave.Plauger@Sun.COM          progress_in = True;
482*10843SDave.Plauger@Sun.COM          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
483*10843SDave.Plauger@Sun.COM          s->strm->next_in++;
484*10843SDave.Plauger@Sun.COM          s->strm->avail_in--;
485*10843SDave.Plauger@Sun.COM          s->strm->total_in_lo32++;
486*10843SDave.Plauger@Sun.COM          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
487*10843SDave.Plauger@Sun.COM          s->avail_in_expect--;
488*10843SDave.Plauger@Sun.COM       }
489*10843SDave.Plauger@Sun.COM    }
490*10843SDave.Plauger@Sun.COM    return progress_in;
491*10843SDave.Plauger@Sun.COM }
492*10843SDave.Plauger@Sun.COM 
493*10843SDave.Plauger@Sun.COM 
494*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
495*10843SDave.Plauger@Sun.COM static
copy_output_until_stop(EState * s)496*10843SDave.Plauger@Sun.COM Bool copy_output_until_stop ( EState* s )
497*10843SDave.Plauger@Sun.COM {
498*10843SDave.Plauger@Sun.COM    Bool progress_out = False;
499*10843SDave.Plauger@Sun.COM 
500*10843SDave.Plauger@Sun.COM    while (True) {
501*10843SDave.Plauger@Sun.COM 
502*10843SDave.Plauger@Sun.COM       /*-- no output space? --*/
503*10843SDave.Plauger@Sun.COM       if (s->strm->avail_out == 0) break;
504*10843SDave.Plauger@Sun.COM 
505*10843SDave.Plauger@Sun.COM       /*-- block done? --*/
506*10843SDave.Plauger@Sun.COM       if (s->state_out_pos >= s->numZ) break;
507*10843SDave.Plauger@Sun.COM 
508*10843SDave.Plauger@Sun.COM       progress_out = True;
509*10843SDave.Plauger@Sun.COM       *(s->strm->next_out) = s->zbits[s->state_out_pos];
510*10843SDave.Plauger@Sun.COM       s->state_out_pos++;
511*10843SDave.Plauger@Sun.COM       s->strm->avail_out--;
512*10843SDave.Plauger@Sun.COM       s->strm->next_out++;
513*10843SDave.Plauger@Sun.COM       s->strm->total_out_lo32++;
514*10843SDave.Plauger@Sun.COM       if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
515*10843SDave.Plauger@Sun.COM    }
516*10843SDave.Plauger@Sun.COM 
517*10843SDave.Plauger@Sun.COM    return progress_out;
518*10843SDave.Plauger@Sun.COM }
519*10843SDave.Plauger@Sun.COM 
520*10843SDave.Plauger@Sun.COM 
521*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
522*10843SDave.Plauger@Sun.COM static
handle_compress(bz_stream * strm)523*10843SDave.Plauger@Sun.COM Bool handle_compress ( bz_stream* strm )
524*10843SDave.Plauger@Sun.COM {
525*10843SDave.Plauger@Sun.COM    Bool progress_in  = False;
526*10843SDave.Plauger@Sun.COM    Bool progress_out = False;
527*10843SDave.Plauger@Sun.COM    EState* s = strm->state;
528*10843SDave.Plauger@Sun.COM 
529*10843SDave.Plauger@Sun.COM    while (True) {
530*10843SDave.Plauger@Sun.COM 
531*10843SDave.Plauger@Sun.COM       if (s->state == BZ_S_OUTPUT) {
532*10843SDave.Plauger@Sun.COM          progress_out |= copy_output_until_stop ( s );
533*10843SDave.Plauger@Sun.COM          if (s->state_out_pos < s->numZ) break;
534*10843SDave.Plauger@Sun.COM          if (s->mode == BZ_M_FINISHING &&
535*10843SDave.Plauger@Sun.COM              s->avail_in_expect == 0 &&
536*10843SDave.Plauger@Sun.COM              isempty_RL(s)) break;
537*10843SDave.Plauger@Sun.COM          prepare_new_block ( s );
538*10843SDave.Plauger@Sun.COM          s->state = BZ_S_INPUT;
539*10843SDave.Plauger@Sun.COM          if (s->mode == BZ_M_FLUSHING &&
540*10843SDave.Plauger@Sun.COM              s->avail_in_expect == 0 &&
541*10843SDave.Plauger@Sun.COM              isempty_RL(s)) break;
542*10843SDave.Plauger@Sun.COM       }
543*10843SDave.Plauger@Sun.COM 
544*10843SDave.Plauger@Sun.COM       if (s->state == BZ_S_INPUT) {
545*10843SDave.Plauger@Sun.COM          progress_in |= copy_input_until_stop ( s );
546*10843SDave.Plauger@Sun.COM          if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
547*10843SDave.Plauger@Sun.COM             flush_RL ( s );
548*10843SDave.Plauger@Sun.COM             BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
549*10843SDave.Plauger@Sun.COM             s->state = BZ_S_OUTPUT;
550*10843SDave.Plauger@Sun.COM          }
551*10843SDave.Plauger@Sun.COM          else
552*10843SDave.Plauger@Sun.COM          if (s->nblock >= s->nblockMAX) {
553*10843SDave.Plauger@Sun.COM             BZ2_compressBlock ( s, False );
554*10843SDave.Plauger@Sun.COM             s->state = BZ_S_OUTPUT;
555*10843SDave.Plauger@Sun.COM          }
556*10843SDave.Plauger@Sun.COM          else
557*10843SDave.Plauger@Sun.COM          if (s->strm->avail_in == 0) {
558*10843SDave.Plauger@Sun.COM             break;
559*10843SDave.Plauger@Sun.COM          }
560*10843SDave.Plauger@Sun.COM       }
561*10843SDave.Plauger@Sun.COM 
562*10843SDave.Plauger@Sun.COM    }
563*10843SDave.Plauger@Sun.COM 
564*10843SDave.Plauger@Sun.COM    return progress_in || progress_out;
565*10843SDave.Plauger@Sun.COM }
566*10843SDave.Plauger@Sun.COM 
567*10843SDave.Plauger@Sun.COM 
568*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzCompress)569*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
570*10843SDave.Plauger@Sun.COM {
571*10843SDave.Plauger@Sun.COM    Bool progress;
572*10843SDave.Plauger@Sun.COM    EState* s;
573*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
574*10843SDave.Plauger@Sun.COM    s = strm->state;
575*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_PARAM_ERROR;
576*10843SDave.Plauger@Sun.COM    if (s->strm != strm) return BZ_PARAM_ERROR;
577*10843SDave.Plauger@Sun.COM 
578*10843SDave.Plauger@Sun.COM    preswitch:
579*10843SDave.Plauger@Sun.COM    switch (s->mode) {
580*10843SDave.Plauger@Sun.COM 
581*10843SDave.Plauger@Sun.COM       case BZ_M_IDLE:
582*10843SDave.Plauger@Sun.COM          return BZ_SEQUENCE_ERROR;
583*10843SDave.Plauger@Sun.COM 
584*10843SDave.Plauger@Sun.COM       case BZ_M_RUNNING:
585*10843SDave.Plauger@Sun.COM          if (action == BZ_RUN) {
586*10843SDave.Plauger@Sun.COM             progress = handle_compress ( strm );
587*10843SDave.Plauger@Sun.COM             return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
588*10843SDave.Plauger@Sun.COM          }
589*10843SDave.Plauger@Sun.COM          else
590*10843SDave.Plauger@Sun.COM 	 if (action == BZ_FLUSH) {
591*10843SDave.Plauger@Sun.COM             s->avail_in_expect = strm->avail_in;
592*10843SDave.Plauger@Sun.COM             s->mode = BZ_M_FLUSHING;
593*10843SDave.Plauger@Sun.COM             goto preswitch;
594*10843SDave.Plauger@Sun.COM          }
595*10843SDave.Plauger@Sun.COM          else
596*10843SDave.Plauger@Sun.COM          if (action == BZ_FINISH) {
597*10843SDave.Plauger@Sun.COM             s->avail_in_expect = strm->avail_in;
598*10843SDave.Plauger@Sun.COM             s->mode = BZ_M_FINISHING;
599*10843SDave.Plauger@Sun.COM             goto preswitch;
600*10843SDave.Plauger@Sun.COM          }
601*10843SDave.Plauger@Sun.COM          else
602*10843SDave.Plauger@Sun.COM             return BZ_PARAM_ERROR;
603*10843SDave.Plauger@Sun.COM 
604*10843SDave.Plauger@Sun.COM       case BZ_M_FLUSHING:
605*10843SDave.Plauger@Sun.COM          if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
606*10843SDave.Plauger@Sun.COM          if (s->avail_in_expect != s->strm->avail_in)
607*10843SDave.Plauger@Sun.COM             return BZ_SEQUENCE_ERROR;
608*10843SDave.Plauger@Sun.COM          progress = handle_compress ( strm );
609*10843SDave.Plauger@Sun.COM          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
610*10843SDave.Plauger@Sun.COM              s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
611*10843SDave.Plauger@Sun.COM          s->mode = BZ_M_RUNNING;
612*10843SDave.Plauger@Sun.COM          return BZ_RUN_OK;
613*10843SDave.Plauger@Sun.COM 
614*10843SDave.Plauger@Sun.COM       case BZ_M_FINISHING:
615*10843SDave.Plauger@Sun.COM          if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
616*10843SDave.Plauger@Sun.COM          if (s->avail_in_expect != s->strm->avail_in)
617*10843SDave.Plauger@Sun.COM             return BZ_SEQUENCE_ERROR;
618*10843SDave.Plauger@Sun.COM          progress = handle_compress ( strm );
619*10843SDave.Plauger@Sun.COM          if (!progress) return BZ_SEQUENCE_ERROR;
620*10843SDave.Plauger@Sun.COM          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
621*10843SDave.Plauger@Sun.COM              s->state_out_pos < s->numZ) return BZ_FINISH_OK;
622*10843SDave.Plauger@Sun.COM          s->mode = BZ_M_IDLE;
623*10843SDave.Plauger@Sun.COM          return BZ_STREAM_END;
624*10843SDave.Plauger@Sun.COM    }
625*10843SDave.Plauger@Sun.COM    return BZ_OK; /*--not reached--*/
626*10843SDave.Plauger@Sun.COM }
627*10843SDave.Plauger@Sun.COM 
628*10843SDave.Plauger@Sun.COM 
629*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzCompressEnd)630*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
631*10843SDave.Plauger@Sun.COM {
632*10843SDave.Plauger@Sun.COM    EState* s;
633*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
634*10843SDave.Plauger@Sun.COM    s = strm->state;
635*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_PARAM_ERROR;
636*10843SDave.Plauger@Sun.COM    if (s->strm != strm) return BZ_PARAM_ERROR;
637*10843SDave.Plauger@Sun.COM 
638*10843SDave.Plauger@Sun.COM    if (s->arr1 != NULL) BZFREE(s->arr1);
639*10843SDave.Plauger@Sun.COM    if (s->arr2 != NULL) BZFREE(s->arr2);
640*10843SDave.Plauger@Sun.COM    if (s->ftab != NULL) BZFREE(s->ftab);
641*10843SDave.Plauger@Sun.COM    BZFREE(strm->state);
642*10843SDave.Plauger@Sun.COM 
643*10843SDave.Plauger@Sun.COM    strm->state = NULL;
644*10843SDave.Plauger@Sun.COM 
645*10843SDave.Plauger@Sun.COM    return BZ_OK;
646*10843SDave.Plauger@Sun.COM }
647*10843SDave.Plauger@Sun.COM 
648*10843SDave.Plauger@Sun.COM 
649*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
650*10843SDave.Plauger@Sun.COM /*--- Decompression stuff                         ---*/
651*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
652*10843SDave.Plauger@Sun.COM 
653*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompressInit)654*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzDecompressInit)
655*10843SDave.Plauger@Sun.COM                      ( bz_stream* strm,
656*10843SDave.Plauger@Sun.COM                        int        verbosity,
657*10843SDave.Plauger@Sun.COM                        int        small )
658*10843SDave.Plauger@Sun.COM {
659*10843SDave.Plauger@Sun.COM    DState* s;
660*10843SDave.Plauger@Sun.COM 
661*10843SDave.Plauger@Sun.COM    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
662*10843SDave.Plauger@Sun.COM 
663*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
664*10843SDave.Plauger@Sun.COM    if (small != 0 && small != 1) return BZ_PARAM_ERROR;
665*10843SDave.Plauger@Sun.COM    if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
666*10843SDave.Plauger@Sun.COM 
667*10843SDave.Plauger@Sun.COM    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
668*10843SDave.Plauger@Sun.COM    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
669*10843SDave.Plauger@Sun.COM 
670*10843SDave.Plauger@Sun.COM    s = BZALLOC( sizeof(DState) );
671*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_MEM_ERROR;
672*10843SDave.Plauger@Sun.COM    s->strm                  = strm;
673*10843SDave.Plauger@Sun.COM    strm->state              = s;
674*10843SDave.Plauger@Sun.COM    s->state                 = BZ_X_MAGIC_1;
675*10843SDave.Plauger@Sun.COM    s->bsLive                = 0;
676*10843SDave.Plauger@Sun.COM    s->bsBuff                = 0;
677*10843SDave.Plauger@Sun.COM    s->calculatedCombinedCRC = 0;
678*10843SDave.Plauger@Sun.COM    strm->total_in_lo32      = 0;
679*10843SDave.Plauger@Sun.COM    strm->total_in_hi32      = 0;
680*10843SDave.Plauger@Sun.COM    strm->total_out_lo32     = 0;
681*10843SDave.Plauger@Sun.COM    strm->total_out_hi32     = 0;
682*10843SDave.Plauger@Sun.COM    s->smallDecompress       = (Bool)small;
683*10843SDave.Plauger@Sun.COM    s->ll4                   = NULL;
684*10843SDave.Plauger@Sun.COM    s->ll16                  = NULL;
685*10843SDave.Plauger@Sun.COM    s->tt                    = NULL;
686*10843SDave.Plauger@Sun.COM    s->currBlockNo           = 0;
687*10843SDave.Plauger@Sun.COM    s->verbosity             = verbosity;
688*10843SDave.Plauger@Sun.COM 
689*10843SDave.Plauger@Sun.COM    return BZ_OK;
690*10843SDave.Plauger@Sun.COM }
691*10843SDave.Plauger@Sun.COM 
692*10843SDave.Plauger@Sun.COM 
693*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
694*10843SDave.Plauger@Sun.COM /* Return  True iff data corruption is discovered.
695*10843SDave.Plauger@Sun.COM    Returns False if there is no problem.
696*10843SDave.Plauger@Sun.COM */
697*10843SDave.Plauger@Sun.COM static
unRLE_obuf_to_output_FAST(DState * s)698*10843SDave.Plauger@Sun.COM Bool unRLE_obuf_to_output_FAST ( DState* s )
699*10843SDave.Plauger@Sun.COM {
700*10843SDave.Plauger@Sun.COM    UChar k1;
701*10843SDave.Plauger@Sun.COM 
702*10843SDave.Plauger@Sun.COM    if (s->blockRandomised) {
703*10843SDave.Plauger@Sun.COM 
704*10843SDave.Plauger@Sun.COM       while (True) {
705*10843SDave.Plauger@Sun.COM          /* try to finish existing run */
706*10843SDave.Plauger@Sun.COM          while (True) {
707*10843SDave.Plauger@Sun.COM             if (s->strm->avail_out == 0) return False;
708*10843SDave.Plauger@Sun.COM             if (s->state_out_len == 0) break;
709*10843SDave.Plauger@Sun.COM             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
710*10843SDave.Plauger@Sun.COM             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
711*10843SDave.Plauger@Sun.COM             s->state_out_len--;
712*10843SDave.Plauger@Sun.COM             s->strm->next_out++;
713*10843SDave.Plauger@Sun.COM             s->strm->avail_out--;
714*10843SDave.Plauger@Sun.COM             s->strm->total_out_lo32++;
715*10843SDave.Plauger@Sun.COM             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
716*10843SDave.Plauger@Sun.COM          }
717*10843SDave.Plauger@Sun.COM 
718*10843SDave.Plauger@Sun.COM          /* can a new run be started? */
719*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) return False;
720*10843SDave.Plauger@Sun.COM 
721*10843SDave.Plauger@Sun.COM          /* Only caused by corrupt data stream? */
722*10843SDave.Plauger@Sun.COM          if (s->nblock_used > s->save_nblock+1)
723*10843SDave.Plauger@Sun.COM             return True;
724*10843SDave.Plauger@Sun.COM 
725*10843SDave.Plauger@Sun.COM          s->state_out_len = 1;
726*10843SDave.Plauger@Sun.COM          s->state_out_ch = s->k0;
727*10843SDave.Plauger@Sun.COM          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
728*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
729*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
730*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
731*10843SDave.Plauger@Sun.COM 
732*10843SDave.Plauger@Sun.COM          s->state_out_len = 2;
733*10843SDave.Plauger@Sun.COM          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
734*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
735*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
736*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
737*10843SDave.Plauger@Sun.COM 
738*10843SDave.Plauger@Sun.COM          s->state_out_len = 3;
739*10843SDave.Plauger@Sun.COM          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
740*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
741*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
742*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
743*10843SDave.Plauger@Sun.COM 
744*10843SDave.Plauger@Sun.COM          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
745*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
746*10843SDave.Plauger@Sun.COM          s->state_out_len = ((Int32)k1) + 4;
747*10843SDave.Plauger@Sun.COM          BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
748*10843SDave.Plauger@Sun.COM          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
749*10843SDave.Plauger@Sun.COM       }
750*10843SDave.Plauger@Sun.COM 
751*10843SDave.Plauger@Sun.COM    } else {
752*10843SDave.Plauger@Sun.COM 
753*10843SDave.Plauger@Sun.COM       /* restore */
754*10843SDave.Plauger@Sun.COM       UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
755*10843SDave.Plauger@Sun.COM       UChar         c_state_out_ch       = s->state_out_ch;
756*10843SDave.Plauger@Sun.COM       Int32         c_state_out_len      = s->state_out_len;
757*10843SDave.Plauger@Sun.COM       Int32         c_nblock_used        = s->nblock_used;
758*10843SDave.Plauger@Sun.COM       Int32         c_k0                 = s->k0;
759*10843SDave.Plauger@Sun.COM       UInt32*       c_tt                 = s->tt;
760*10843SDave.Plauger@Sun.COM       UInt32        c_tPos               = s->tPos;
761*10843SDave.Plauger@Sun.COM       char*         cs_next_out          = s->strm->next_out;
762*10843SDave.Plauger@Sun.COM       unsigned int  cs_avail_out         = s->strm->avail_out;
763*10843SDave.Plauger@Sun.COM       Int32         ro_blockSize100k     = s->blockSize100k;
764*10843SDave.Plauger@Sun.COM       /* end restore */
765*10843SDave.Plauger@Sun.COM 
766*10843SDave.Plauger@Sun.COM       UInt32       avail_out_INIT = cs_avail_out;
767*10843SDave.Plauger@Sun.COM       Int32        s_save_nblockPP = s->save_nblock+1;
768*10843SDave.Plauger@Sun.COM       unsigned int total_out_lo32_old;
769*10843SDave.Plauger@Sun.COM 
770*10843SDave.Plauger@Sun.COM       while (True) {
771*10843SDave.Plauger@Sun.COM 
772*10843SDave.Plauger@Sun.COM          /* try to finish existing run */
773*10843SDave.Plauger@Sun.COM          if (c_state_out_len > 0) {
774*10843SDave.Plauger@Sun.COM             while (True) {
775*10843SDave.Plauger@Sun.COM                if (cs_avail_out == 0) goto return_notr;
776*10843SDave.Plauger@Sun.COM                if (c_state_out_len == 1) break;
777*10843SDave.Plauger@Sun.COM                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
778*10843SDave.Plauger@Sun.COM                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
779*10843SDave.Plauger@Sun.COM                c_state_out_len--;
780*10843SDave.Plauger@Sun.COM                cs_next_out++;
781*10843SDave.Plauger@Sun.COM                cs_avail_out--;
782*10843SDave.Plauger@Sun.COM             }
783*10843SDave.Plauger@Sun.COM             s_state_out_len_eq_one:
784*10843SDave.Plauger@Sun.COM             {
785*10843SDave.Plauger@Sun.COM                if (cs_avail_out == 0) {
786*10843SDave.Plauger@Sun.COM                   c_state_out_len = 1; goto return_notr;
787*10843SDave.Plauger@Sun.COM                };
788*10843SDave.Plauger@Sun.COM                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
789*10843SDave.Plauger@Sun.COM                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
790*10843SDave.Plauger@Sun.COM                cs_next_out++;
791*10843SDave.Plauger@Sun.COM                cs_avail_out--;
792*10843SDave.Plauger@Sun.COM             }
793*10843SDave.Plauger@Sun.COM          }
794*10843SDave.Plauger@Sun.COM          /* Only caused by corrupt data stream? */
795*10843SDave.Plauger@Sun.COM          if (c_nblock_used > s_save_nblockPP)
796*10843SDave.Plauger@Sun.COM             return True;
797*10843SDave.Plauger@Sun.COM 
798*10843SDave.Plauger@Sun.COM          /* can a new run be started? */
799*10843SDave.Plauger@Sun.COM          if (c_nblock_used == s_save_nblockPP) {
800*10843SDave.Plauger@Sun.COM             c_state_out_len = 0; goto return_notr;
801*10843SDave.Plauger@Sun.COM          };
802*10843SDave.Plauger@Sun.COM          c_state_out_ch = c_k0;
803*10843SDave.Plauger@Sun.COM          BZ_GET_FAST_C(k1); c_nblock_used++;
804*10843SDave.Plauger@Sun.COM          if (k1 != c_k0) {
805*10843SDave.Plauger@Sun.COM             c_k0 = k1; goto s_state_out_len_eq_one;
806*10843SDave.Plauger@Sun.COM          };
807*10843SDave.Plauger@Sun.COM          if (c_nblock_used == s_save_nblockPP)
808*10843SDave.Plauger@Sun.COM             goto s_state_out_len_eq_one;
809*10843SDave.Plauger@Sun.COM 
810*10843SDave.Plauger@Sun.COM          c_state_out_len = 2;
811*10843SDave.Plauger@Sun.COM          BZ_GET_FAST_C(k1); c_nblock_used++;
812*10843SDave.Plauger@Sun.COM          if (c_nblock_used == s_save_nblockPP) continue;
813*10843SDave.Plauger@Sun.COM          if (k1 != c_k0) { c_k0 = k1; continue; };
814*10843SDave.Plauger@Sun.COM 
815*10843SDave.Plauger@Sun.COM          c_state_out_len = 3;
816*10843SDave.Plauger@Sun.COM          BZ_GET_FAST_C(k1); c_nblock_used++;
817*10843SDave.Plauger@Sun.COM          if (c_nblock_used == s_save_nblockPP) continue;
818*10843SDave.Plauger@Sun.COM          if (k1 != c_k0) { c_k0 = k1; continue; };
819*10843SDave.Plauger@Sun.COM 
820*10843SDave.Plauger@Sun.COM          BZ_GET_FAST_C(k1); c_nblock_used++;
821*10843SDave.Plauger@Sun.COM          c_state_out_len = ((Int32)k1) + 4;
822*10843SDave.Plauger@Sun.COM          BZ_GET_FAST_C(c_k0); c_nblock_used++;
823*10843SDave.Plauger@Sun.COM       }
824*10843SDave.Plauger@Sun.COM 
825*10843SDave.Plauger@Sun.COM       return_notr:
826*10843SDave.Plauger@Sun.COM       total_out_lo32_old = s->strm->total_out_lo32;
827*10843SDave.Plauger@Sun.COM       s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
828*10843SDave.Plauger@Sun.COM       if (s->strm->total_out_lo32 < total_out_lo32_old)
829*10843SDave.Plauger@Sun.COM          s->strm->total_out_hi32++;
830*10843SDave.Plauger@Sun.COM 
831*10843SDave.Plauger@Sun.COM       /* save */
832*10843SDave.Plauger@Sun.COM       s->calculatedBlockCRC = c_calculatedBlockCRC;
833*10843SDave.Plauger@Sun.COM       s->state_out_ch       = c_state_out_ch;
834*10843SDave.Plauger@Sun.COM       s->state_out_len      = c_state_out_len;
835*10843SDave.Plauger@Sun.COM       s->nblock_used        = c_nblock_used;
836*10843SDave.Plauger@Sun.COM       s->k0                 = c_k0;
837*10843SDave.Plauger@Sun.COM       s->tt                 = c_tt;
838*10843SDave.Plauger@Sun.COM       s->tPos               = c_tPos;
839*10843SDave.Plauger@Sun.COM       s->strm->next_out     = cs_next_out;
840*10843SDave.Plauger@Sun.COM       s->strm->avail_out    = cs_avail_out;
841*10843SDave.Plauger@Sun.COM       /* end save */
842*10843SDave.Plauger@Sun.COM    }
843*10843SDave.Plauger@Sun.COM    return False;
844*10843SDave.Plauger@Sun.COM }
845*10843SDave.Plauger@Sun.COM 
846*10843SDave.Plauger@Sun.COM 
847*10843SDave.Plauger@Sun.COM 
848*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ2_indexIntoF(Int32 indx,Int32 * cftab)849*10843SDave.Plauger@Sun.COM __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
850*10843SDave.Plauger@Sun.COM {
851*10843SDave.Plauger@Sun.COM    Int32 nb, na, mid;
852*10843SDave.Plauger@Sun.COM    nb = 0;
853*10843SDave.Plauger@Sun.COM    na = 256;
854*10843SDave.Plauger@Sun.COM    do {
855*10843SDave.Plauger@Sun.COM       mid = (nb + na) >> 1;
856*10843SDave.Plauger@Sun.COM       if (indx >= cftab[mid]) nb = mid; else na = mid;
857*10843SDave.Plauger@Sun.COM    }
858*10843SDave.Plauger@Sun.COM    while (na - nb != 1);
859*10843SDave.Plauger@Sun.COM    return nb;
860*10843SDave.Plauger@Sun.COM }
861*10843SDave.Plauger@Sun.COM 
862*10843SDave.Plauger@Sun.COM 
863*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
864*10843SDave.Plauger@Sun.COM /* Return  True iff data corruption is discovered.
865*10843SDave.Plauger@Sun.COM    Returns False if there is no problem.
866*10843SDave.Plauger@Sun.COM */
867*10843SDave.Plauger@Sun.COM static
unRLE_obuf_to_output_SMALL(DState * s)868*10843SDave.Plauger@Sun.COM Bool unRLE_obuf_to_output_SMALL ( DState* s )
869*10843SDave.Plauger@Sun.COM {
870*10843SDave.Plauger@Sun.COM    UChar k1;
871*10843SDave.Plauger@Sun.COM 
872*10843SDave.Plauger@Sun.COM    if (s->blockRandomised) {
873*10843SDave.Plauger@Sun.COM 
874*10843SDave.Plauger@Sun.COM       while (True) {
875*10843SDave.Plauger@Sun.COM          /* try to finish existing run */
876*10843SDave.Plauger@Sun.COM          while (True) {
877*10843SDave.Plauger@Sun.COM             if (s->strm->avail_out == 0) return False;
878*10843SDave.Plauger@Sun.COM             if (s->state_out_len == 0) break;
879*10843SDave.Plauger@Sun.COM             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
880*10843SDave.Plauger@Sun.COM             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
881*10843SDave.Plauger@Sun.COM             s->state_out_len--;
882*10843SDave.Plauger@Sun.COM             s->strm->next_out++;
883*10843SDave.Plauger@Sun.COM             s->strm->avail_out--;
884*10843SDave.Plauger@Sun.COM             s->strm->total_out_lo32++;
885*10843SDave.Plauger@Sun.COM             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
886*10843SDave.Plauger@Sun.COM          }
887*10843SDave.Plauger@Sun.COM 
888*10843SDave.Plauger@Sun.COM          /* can a new run be started? */
889*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) return False;
890*10843SDave.Plauger@Sun.COM 
891*10843SDave.Plauger@Sun.COM          /* Only caused by corrupt data stream? */
892*10843SDave.Plauger@Sun.COM          if (s->nblock_used > s->save_nblock+1)
893*10843SDave.Plauger@Sun.COM             return True;
894*10843SDave.Plauger@Sun.COM 
895*10843SDave.Plauger@Sun.COM          s->state_out_len = 1;
896*10843SDave.Plauger@Sun.COM          s->state_out_ch = s->k0;
897*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
898*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
899*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
900*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
901*10843SDave.Plauger@Sun.COM 
902*10843SDave.Plauger@Sun.COM          s->state_out_len = 2;
903*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
904*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
905*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
906*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
907*10843SDave.Plauger@Sun.COM 
908*10843SDave.Plauger@Sun.COM          s->state_out_len = 3;
909*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
910*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
911*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
912*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
913*10843SDave.Plauger@Sun.COM 
914*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
915*10843SDave.Plauger@Sun.COM          k1 ^= BZ_RAND_MASK; s->nblock_used++;
916*10843SDave.Plauger@Sun.COM          s->state_out_len = ((Int32)k1) + 4;
917*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
918*10843SDave.Plauger@Sun.COM          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
919*10843SDave.Plauger@Sun.COM       }
920*10843SDave.Plauger@Sun.COM 
921*10843SDave.Plauger@Sun.COM    } else {
922*10843SDave.Plauger@Sun.COM 
923*10843SDave.Plauger@Sun.COM       while (True) {
924*10843SDave.Plauger@Sun.COM          /* try to finish existing run */
925*10843SDave.Plauger@Sun.COM          while (True) {
926*10843SDave.Plauger@Sun.COM             if (s->strm->avail_out == 0) return False;
927*10843SDave.Plauger@Sun.COM             if (s->state_out_len == 0) break;
928*10843SDave.Plauger@Sun.COM             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
929*10843SDave.Plauger@Sun.COM             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
930*10843SDave.Plauger@Sun.COM             s->state_out_len--;
931*10843SDave.Plauger@Sun.COM             s->strm->next_out++;
932*10843SDave.Plauger@Sun.COM             s->strm->avail_out--;
933*10843SDave.Plauger@Sun.COM             s->strm->total_out_lo32++;
934*10843SDave.Plauger@Sun.COM             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
935*10843SDave.Plauger@Sun.COM          }
936*10843SDave.Plauger@Sun.COM 
937*10843SDave.Plauger@Sun.COM          /* can a new run be started? */
938*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) return False;
939*10843SDave.Plauger@Sun.COM 
940*10843SDave.Plauger@Sun.COM          /* Only caused by corrupt data stream? */
941*10843SDave.Plauger@Sun.COM          if (s->nblock_used > s->save_nblock+1)
942*10843SDave.Plauger@Sun.COM             return True;
943*10843SDave.Plauger@Sun.COM 
944*10843SDave.Plauger@Sun.COM          s->state_out_len = 1;
945*10843SDave.Plauger@Sun.COM          s->state_out_ch = s->k0;
946*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); s->nblock_used++;
947*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
948*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
949*10843SDave.Plauger@Sun.COM 
950*10843SDave.Plauger@Sun.COM          s->state_out_len = 2;
951*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); s->nblock_used++;
952*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
953*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
954*10843SDave.Plauger@Sun.COM 
955*10843SDave.Plauger@Sun.COM          s->state_out_len = 3;
956*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); s->nblock_used++;
957*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1) continue;
958*10843SDave.Plauger@Sun.COM          if (k1 != s->k0) { s->k0 = k1; continue; };
959*10843SDave.Plauger@Sun.COM 
960*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(k1); s->nblock_used++;
961*10843SDave.Plauger@Sun.COM          s->state_out_len = ((Int32)k1) + 4;
962*10843SDave.Plauger@Sun.COM          BZ_GET_SMALL(s->k0); s->nblock_used++;
963*10843SDave.Plauger@Sun.COM       }
964*10843SDave.Plauger@Sun.COM 
965*10843SDave.Plauger@Sun.COM    }
966*10843SDave.Plauger@Sun.COM }
967*10843SDave.Plauger@Sun.COM 
968*10843SDave.Plauger@Sun.COM 
969*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompress)970*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
971*10843SDave.Plauger@Sun.COM {
972*10843SDave.Plauger@Sun.COM    Bool    corrupt;
973*10843SDave.Plauger@Sun.COM    DState* s;
974*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
975*10843SDave.Plauger@Sun.COM    s = strm->state;
976*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_PARAM_ERROR;
977*10843SDave.Plauger@Sun.COM    if (s->strm != strm) return BZ_PARAM_ERROR;
978*10843SDave.Plauger@Sun.COM 
979*10843SDave.Plauger@Sun.COM    while (True) {
980*10843SDave.Plauger@Sun.COM       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
981*10843SDave.Plauger@Sun.COM       if (s->state == BZ_X_OUTPUT) {
982*10843SDave.Plauger@Sun.COM          if (s->smallDecompress)
983*10843SDave.Plauger@Sun.COM             corrupt = unRLE_obuf_to_output_SMALL ( s ); else
984*10843SDave.Plauger@Sun.COM             corrupt = unRLE_obuf_to_output_FAST  ( s );
985*10843SDave.Plauger@Sun.COM          if (corrupt) return BZ_DATA_ERROR;
986*10843SDave.Plauger@Sun.COM          if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
987*10843SDave.Plauger@Sun.COM             BZ_FINALISE_CRC ( s->calculatedBlockCRC );
988*10843SDave.Plauger@Sun.COM             if (s->verbosity >= 3)
989*10843SDave.Plauger@Sun.COM                VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
990*10843SDave.Plauger@Sun.COM                           s->calculatedBlockCRC );
991*10843SDave.Plauger@Sun.COM             if (s->verbosity >= 2) VPrintf0 ( "]" );
992*10843SDave.Plauger@Sun.COM             if (s->calculatedBlockCRC != s->storedBlockCRC)
993*10843SDave.Plauger@Sun.COM                return BZ_DATA_ERROR;
994*10843SDave.Plauger@Sun.COM             s->calculatedCombinedCRC
995*10843SDave.Plauger@Sun.COM                = (s->calculatedCombinedCRC << 1) |
996*10843SDave.Plauger@Sun.COM                     (s->calculatedCombinedCRC >> 31);
997*10843SDave.Plauger@Sun.COM             s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
998*10843SDave.Plauger@Sun.COM             s->state = BZ_X_BLKHDR_1;
999*10843SDave.Plauger@Sun.COM          } else {
1000*10843SDave.Plauger@Sun.COM             return BZ_OK;
1001*10843SDave.Plauger@Sun.COM          }
1002*10843SDave.Plauger@Sun.COM       }
1003*10843SDave.Plauger@Sun.COM       if (s->state >= BZ_X_MAGIC_1) {
1004*10843SDave.Plauger@Sun.COM          Int32 r = BZ2_decompress ( s );
1005*10843SDave.Plauger@Sun.COM          if (r == BZ_STREAM_END) {
1006*10843SDave.Plauger@Sun.COM             if (s->verbosity >= 3)
1007*10843SDave.Plauger@Sun.COM                VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
1008*10843SDave.Plauger@Sun.COM                           s->storedCombinedCRC, s->calculatedCombinedCRC );
1009*10843SDave.Plauger@Sun.COM             if (s->calculatedCombinedCRC != s->storedCombinedCRC)
1010*10843SDave.Plauger@Sun.COM                return BZ_DATA_ERROR;
1011*10843SDave.Plauger@Sun.COM             return r;
1012*10843SDave.Plauger@Sun.COM          }
1013*10843SDave.Plauger@Sun.COM          if (s->state != BZ_X_OUTPUT) return r;
1014*10843SDave.Plauger@Sun.COM       }
1015*10843SDave.Plauger@Sun.COM    }
1016*10843SDave.Plauger@Sun.COM 
1017*10843SDave.Plauger@Sun.COM #if 0
1018*10843SDave.Plauger@Sun.COM    AssertH ( 0, 6001 );
1019*10843SDave.Plauger@Sun.COM 
1020*10843SDave.Plauger@Sun.COM    return 0;  /*NOTREACHED*/
1021*10843SDave.Plauger@Sun.COM #endif
1022*10843SDave.Plauger@Sun.COM }
1023*10843SDave.Plauger@Sun.COM 
1024*10843SDave.Plauger@Sun.COM 
1025*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompressEnd)1026*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
1027*10843SDave.Plauger@Sun.COM {
1028*10843SDave.Plauger@Sun.COM    DState* s;
1029*10843SDave.Plauger@Sun.COM    if (strm == NULL) return BZ_PARAM_ERROR;
1030*10843SDave.Plauger@Sun.COM    s = strm->state;
1031*10843SDave.Plauger@Sun.COM    if (s == NULL) return BZ_PARAM_ERROR;
1032*10843SDave.Plauger@Sun.COM    if (s->strm != strm) return BZ_PARAM_ERROR;
1033*10843SDave.Plauger@Sun.COM 
1034*10843SDave.Plauger@Sun.COM    if (s->tt   != NULL) BZFREE(s->tt);
1035*10843SDave.Plauger@Sun.COM    if (s->ll16 != NULL) BZFREE(s->ll16);
1036*10843SDave.Plauger@Sun.COM    if (s->ll4  != NULL) BZFREE(s->ll4);
1037*10843SDave.Plauger@Sun.COM 
1038*10843SDave.Plauger@Sun.COM    BZFREE(strm->state);
1039*10843SDave.Plauger@Sun.COM    strm->state = NULL;
1040*10843SDave.Plauger@Sun.COM 
1041*10843SDave.Plauger@Sun.COM    return BZ_OK;
1042*10843SDave.Plauger@Sun.COM }
1043*10843SDave.Plauger@Sun.COM 
1044*10843SDave.Plauger@Sun.COM 
1045*10843SDave.Plauger@Sun.COM #ifndef BZ_NO_STDIO
1046*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1047*10843SDave.Plauger@Sun.COM /*--- File I/O stuff                              ---*/
1048*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1049*10843SDave.Plauger@Sun.COM 
1050*10843SDave.Plauger@Sun.COM #define BZ_SETERR(eee)                    \
1051*10843SDave.Plauger@Sun.COM {                                         \
1052*10843SDave.Plauger@Sun.COM    if (bzerror != NULL) *bzerror = eee;   \
1053*10843SDave.Plauger@Sun.COM    if (bzf != NULL) bzf->lastErr = eee;   \
1054*10843SDave.Plauger@Sun.COM }
1055*10843SDave.Plauger@Sun.COM 
1056*10843SDave.Plauger@Sun.COM typedef
1057*10843SDave.Plauger@Sun.COM    struct {
1058*10843SDave.Plauger@Sun.COM       FILE*     handle;
1059*10843SDave.Plauger@Sun.COM       Char      buf[BZ_MAX_UNUSED];
1060*10843SDave.Plauger@Sun.COM       Int32     bufN;
1061*10843SDave.Plauger@Sun.COM       Bool      writing;
1062*10843SDave.Plauger@Sun.COM       bz_stream strm;
1063*10843SDave.Plauger@Sun.COM       Int32     lastErr;
1064*10843SDave.Plauger@Sun.COM       Bool      initialisedOk;
1065*10843SDave.Plauger@Sun.COM    }
1066*10843SDave.Plauger@Sun.COM    bzFile;
1067*10843SDave.Plauger@Sun.COM 
1068*10843SDave.Plauger@Sun.COM 
1069*10843SDave.Plauger@Sun.COM /*---------------------------------------------*/
myfeof(FILE * f)1070*10843SDave.Plauger@Sun.COM static Bool myfeof ( FILE* f )
1071*10843SDave.Plauger@Sun.COM {
1072*10843SDave.Plauger@Sun.COM    Int32 c = fgetc ( f );
1073*10843SDave.Plauger@Sun.COM    if (c == EOF) return True;
1074*10843SDave.Plauger@Sun.COM    ungetc ( c, f );
1075*10843SDave.Plauger@Sun.COM    return False;
1076*10843SDave.Plauger@Sun.COM }
1077*10843SDave.Plauger@Sun.COM 
1078*10843SDave.Plauger@Sun.COM 
1079*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteOpen)1080*10843SDave.Plauger@Sun.COM BZFILE* BZ_API(BZ2_bzWriteOpen)
1081*10843SDave.Plauger@Sun.COM                     ( int*  bzerror,
1082*10843SDave.Plauger@Sun.COM                       FILE* f,
1083*10843SDave.Plauger@Sun.COM                       int   blockSize100k,
1084*10843SDave.Plauger@Sun.COM                       int   verbosity,
1085*10843SDave.Plauger@Sun.COM                       int   workFactor )
1086*10843SDave.Plauger@Sun.COM {
1087*10843SDave.Plauger@Sun.COM    Int32   ret;
1088*10843SDave.Plauger@Sun.COM    bzFile* bzf = NULL;
1089*10843SDave.Plauger@Sun.COM 
1090*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1091*10843SDave.Plauger@Sun.COM 
1092*10843SDave.Plauger@Sun.COM    if (f == NULL ||
1093*10843SDave.Plauger@Sun.COM        (blockSize100k < 1 || blockSize100k > 9) ||
1094*10843SDave.Plauger@Sun.COM        (workFactor < 0 || workFactor > 250) ||
1095*10843SDave.Plauger@Sun.COM        (verbosity < 0 || verbosity > 4))
1096*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1097*10843SDave.Plauger@Sun.COM 
1098*10843SDave.Plauger@Sun.COM    if (ferror(f))
1099*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
1100*10843SDave.Plauger@Sun.COM 
1101*10843SDave.Plauger@Sun.COM    bzf = malloc ( sizeof(bzFile) );
1102*10843SDave.Plauger@Sun.COM    if (bzf == NULL)
1103*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1104*10843SDave.Plauger@Sun.COM 
1105*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1106*10843SDave.Plauger@Sun.COM    bzf->initialisedOk = False;
1107*10843SDave.Plauger@Sun.COM    bzf->bufN          = 0;
1108*10843SDave.Plauger@Sun.COM    bzf->handle        = f;
1109*10843SDave.Plauger@Sun.COM    bzf->writing       = True;
1110*10843SDave.Plauger@Sun.COM    bzf->strm.bzalloc  = NULL;
1111*10843SDave.Plauger@Sun.COM    bzf->strm.bzfree   = NULL;
1112*10843SDave.Plauger@Sun.COM    bzf->strm.opaque   = NULL;
1113*10843SDave.Plauger@Sun.COM 
1114*10843SDave.Plauger@Sun.COM    if (workFactor == 0) workFactor = 30;
1115*10843SDave.Plauger@Sun.COM    ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
1116*10843SDave.Plauger@Sun.COM                               verbosity, workFactor );
1117*10843SDave.Plauger@Sun.COM    if (ret != BZ_OK)
1118*10843SDave.Plauger@Sun.COM       { BZ_SETERR(ret); free(bzf); return NULL; };
1119*10843SDave.Plauger@Sun.COM 
1120*10843SDave.Plauger@Sun.COM    bzf->strm.avail_in = 0;
1121*10843SDave.Plauger@Sun.COM    bzf->initialisedOk = True;
1122*10843SDave.Plauger@Sun.COM    return bzf;
1123*10843SDave.Plauger@Sun.COM }
1124*10843SDave.Plauger@Sun.COM 
1125*10843SDave.Plauger@Sun.COM 
1126*10843SDave.Plauger@Sun.COM 
1127*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzWrite)1128*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzWrite)
1129*10843SDave.Plauger@Sun.COM              ( int*    bzerror,
1130*10843SDave.Plauger@Sun.COM                BZFILE* b,
1131*10843SDave.Plauger@Sun.COM                void*   buf,
1132*10843SDave.Plauger@Sun.COM                int     len )
1133*10843SDave.Plauger@Sun.COM {
1134*10843SDave.Plauger@Sun.COM    Int32 n, n2, ret;
1135*10843SDave.Plauger@Sun.COM    bzFile* bzf = (bzFile*)b;
1136*10843SDave.Plauger@Sun.COM 
1137*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1138*10843SDave.Plauger@Sun.COM    if (bzf == NULL || buf == NULL || len < 0)
1139*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return; };
1140*10843SDave.Plauger@Sun.COM    if (!(bzf->writing))
1141*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1142*10843SDave.Plauger@Sun.COM    if (ferror(bzf->handle))
1143*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_IO_ERROR); return; };
1144*10843SDave.Plauger@Sun.COM 
1145*10843SDave.Plauger@Sun.COM    if (len == 0)
1146*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_OK); return; };
1147*10843SDave.Plauger@Sun.COM 
1148*10843SDave.Plauger@Sun.COM    bzf->strm.avail_in = len;
1149*10843SDave.Plauger@Sun.COM    bzf->strm.next_in  = buf;
1150*10843SDave.Plauger@Sun.COM 
1151*10843SDave.Plauger@Sun.COM    while (True) {
1152*10843SDave.Plauger@Sun.COM       bzf->strm.avail_out = BZ_MAX_UNUSED;
1153*10843SDave.Plauger@Sun.COM       bzf->strm.next_out = bzf->buf;
1154*10843SDave.Plauger@Sun.COM       ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
1155*10843SDave.Plauger@Sun.COM       if (ret != BZ_RUN_OK)
1156*10843SDave.Plauger@Sun.COM          { BZ_SETERR(ret); return; };
1157*10843SDave.Plauger@Sun.COM 
1158*10843SDave.Plauger@Sun.COM       if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1159*10843SDave.Plauger@Sun.COM          n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1160*10843SDave.Plauger@Sun.COM          n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1161*10843SDave.Plauger@Sun.COM                        n, bzf->handle );
1162*10843SDave.Plauger@Sun.COM          if (n != n2 || ferror(bzf->handle))
1163*10843SDave.Plauger@Sun.COM             { BZ_SETERR(BZ_IO_ERROR); return; };
1164*10843SDave.Plauger@Sun.COM       }
1165*10843SDave.Plauger@Sun.COM 
1166*10843SDave.Plauger@Sun.COM       if (bzf->strm.avail_in == 0)
1167*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_OK); return; };
1168*10843SDave.Plauger@Sun.COM    }
1169*10843SDave.Plauger@Sun.COM }
1170*10843SDave.Plauger@Sun.COM 
1171*10843SDave.Plauger@Sun.COM 
1172*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteClose)1173*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzWriteClose)
1174*10843SDave.Plauger@Sun.COM                   ( int*          bzerror,
1175*10843SDave.Plauger@Sun.COM                     BZFILE*       b,
1176*10843SDave.Plauger@Sun.COM                     int           abandon,
1177*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_in,
1178*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_out )
1179*10843SDave.Plauger@Sun.COM {
1180*10843SDave.Plauger@Sun.COM    BZ2_bzWriteClose64 ( bzerror, b, abandon,
1181*10843SDave.Plauger@Sun.COM                         nbytes_in, NULL, nbytes_out, NULL );
1182*10843SDave.Plauger@Sun.COM }
1183*10843SDave.Plauger@Sun.COM 
1184*10843SDave.Plauger@Sun.COM 
BZ_API(BZ2_bzWriteClose64)1185*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzWriteClose64)
1186*10843SDave.Plauger@Sun.COM                   ( int*          bzerror,
1187*10843SDave.Plauger@Sun.COM                     BZFILE*       b,
1188*10843SDave.Plauger@Sun.COM                     int           abandon,
1189*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_in_lo32,
1190*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_in_hi32,
1191*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_out_lo32,
1192*10843SDave.Plauger@Sun.COM                     unsigned int* nbytes_out_hi32 )
1193*10843SDave.Plauger@Sun.COM {
1194*10843SDave.Plauger@Sun.COM    Int32   n, n2, ret;
1195*10843SDave.Plauger@Sun.COM    bzFile* bzf = (bzFile*)b;
1196*10843SDave.Plauger@Sun.COM 
1197*10843SDave.Plauger@Sun.COM    if (bzf == NULL)
1198*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_OK); return; };
1199*10843SDave.Plauger@Sun.COM    if (!(bzf->writing))
1200*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1201*10843SDave.Plauger@Sun.COM    if (ferror(bzf->handle))
1202*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_IO_ERROR); return; };
1203*10843SDave.Plauger@Sun.COM 
1204*10843SDave.Plauger@Sun.COM    if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
1205*10843SDave.Plauger@Sun.COM    if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1206*10843SDave.Plauger@Sun.COM    if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1207*10843SDave.Plauger@Sun.COM    if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
1208*10843SDave.Plauger@Sun.COM 
1209*10843SDave.Plauger@Sun.COM    if ((!abandon) && bzf->lastErr == BZ_OK) {
1210*10843SDave.Plauger@Sun.COM       while (True) {
1211*10843SDave.Plauger@Sun.COM          bzf->strm.avail_out = BZ_MAX_UNUSED;
1212*10843SDave.Plauger@Sun.COM          bzf->strm.next_out = bzf->buf;
1213*10843SDave.Plauger@Sun.COM          ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
1214*10843SDave.Plauger@Sun.COM          if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
1215*10843SDave.Plauger@Sun.COM             { BZ_SETERR(ret); return; };
1216*10843SDave.Plauger@Sun.COM 
1217*10843SDave.Plauger@Sun.COM          if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1218*10843SDave.Plauger@Sun.COM             n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1219*10843SDave.Plauger@Sun.COM             n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1220*10843SDave.Plauger@Sun.COM                           n, bzf->handle );
1221*10843SDave.Plauger@Sun.COM             if (n != n2 || ferror(bzf->handle))
1222*10843SDave.Plauger@Sun.COM                { BZ_SETERR(BZ_IO_ERROR); return; };
1223*10843SDave.Plauger@Sun.COM          }
1224*10843SDave.Plauger@Sun.COM 
1225*10843SDave.Plauger@Sun.COM          if (ret == BZ_STREAM_END) break;
1226*10843SDave.Plauger@Sun.COM       }
1227*10843SDave.Plauger@Sun.COM    }
1228*10843SDave.Plauger@Sun.COM 
1229*10843SDave.Plauger@Sun.COM    if ( !abandon && !ferror ( bzf->handle ) ) {
1230*10843SDave.Plauger@Sun.COM       fflush ( bzf->handle );
1231*10843SDave.Plauger@Sun.COM       if (ferror(bzf->handle))
1232*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_IO_ERROR); return; };
1233*10843SDave.Plauger@Sun.COM    }
1234*10843SDave.Plauger@Sun.COM 
1235*10843SDave.Plauger@Sun.COM    if (nbytes_in_lo32 != NULL)
1236*10843SDave.Plauger@Sun.COM       *nbytes_in_lo32 = bzf->strm.total_in_lo32;
1237*10843SDave.Plauger@Sun.COM    if (nbytes_in_hi32 != NULL)
1238*10843SDave.Plauger@Sun.COM       *nbytes_in_hi32 = bzf->strm.total_in_hi32;
1239*10843SDave.Plauger@Sun.COM    if (nbytes_out_lo32 != NULL)
1240*10843SDave.Plauger@Sun.COM       *nbytes_out_lo32 = bzf->strm.total_out_lo32;
1241*10843SDave.Plauger@Sun.COM    if (nbytes_out_hi32 != NULL)
1242*10843SDave.Plauger@Sun.COM       *nbytes_out_hi32 = bzf->strm.total_out_hi32;
1243*10843SDave.Plauger@Sun.COM 
1244*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1245*10843SDave.Plauger@Sun.COM    (void) BZ2_bzCompressEnd ( &(bzf->strm) );
1246*10843SDave.Plauger@Sun.COM    free ( bzf );
1247*10843SDave.Plauger@Sun.COM }
1248*10843SDave.Plauger@Sun.COM 
1249*10843SDave.Plauger@Sun.COM 
1250*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzReadOpen)1251*10843SDave.Plauger@Sun.COM BZFILE* BZ_API(BZ2_bzReadOpen)
1252*10843SDave.Plauger@Sun.COM                    ( int*  bzerror,
1253*10843SDave.Plauger@Sun.COM                      FILE* f,
1254*10843SDave.Plauger@Sun.COM                      int   verbosity,
1255*10843SDave.Plauger@Sun.COM                      int   small,
1256*10843SDave.Plauger@Sun.COM                      void* unused,
1257*10843SDave.Plauger@Sun.COM                      int   nUnused )
1258*10843SDave.Plauger@Sun.COM {
1259*10843SDave.Plauger@Sun.COM    bzFile* bzf = NULL;
1260*10843SDave.Plauger@Sun.COM    int     ret;
1261*10843SDave.Plauger@Sun.COM 
1262*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1263*10843SDave.Plauger@Sun.COM 
1264*10843SDave.Plauger@Sun.COM    if (f == NULL ||
1265*10843SDave.Plauger@Sun.COM        (small != 0 && small != 1) ||
1266*10843SDave.Plauger@Sun.COM        (verbosity < 0 || verbosity > 4) ||
1267*10843SDave.Plauger@Sun.COM        (unused == NULL && nUnused != 0) ||
1268*10843SDave.Plauger@Sun.COM        (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
1269*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1270*10843SDave.Plauger@Sun.COM 
1271*10843SDave.Plauger@Sun.COM    if (ferror(f))
1272*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
1273*10843SDave.Plauger@Sun.COM 
1274*10843SDave.Plauger@Sun.COM    bzf = malloc ( sizeof(bzFile) );
1275*10843SDave.Plauger@Sun.COM    if (bzf == NULL)
1276*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1277*10843SDave.Plauger@Sun.COM 
1278*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1279*10843SDave.Plauger@Sun.COM 
1280*10843SDave.Plauger@Sun.COM    bzf->initialisedOk = False;
1281*10843SDave.Plauger@Sun.COM    bzf->handle        = f;
1282*10843SDave.Plauger@Sun.COM    bzf->bufN          = 0;
1283*10843SDave.Plauger@Sun.COM    bzf->writing       = False;
1284*10843SDave.Plauger@Sun.COM    bzf->strm.bzalloc  = NULL;
1285*10843SDave.Plauger@Sun.COM    bzf->strm.bzfree   = NULL;
1286*10843SDave.Plauger@Sun.COM    bzf->strm.opaque   = NULL;
1287*10843SDave.Plauger@Sun.COM 
1288*10843SDave.Plauger@Sun.COM    while (nUnused > 0) {
1289*10843SDave.Plauger@Sun.COM       bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
1290*10843SDave.Plauger@Sun.COM       unused = ((void*)( 1 + ((UChar*)(unused))  ));
1291*10843SDave.Plauger@Sun.COM       nUnused--;
1292*10843SDave.Plauger@Sun.COM    }
1293*10843SDave.Plauger@Sun.COM 
1294*10843SDave.Plauger@Sun.COM    ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1295*10843SDave.Plauger@Sun.COM    if (ret != BZ_OK)
1296*10843SDave.Plauger@Sun.COM       { BZ_SETERR(ret); free(bzf); return NULL; };
1297*10843SDave.Plauger@Sun.COM 
1298*10843SDave.Plauger@Sun.COM    bzf->strm.avail_in = bzf->bufN;
1299*10843SDave.Plauger@Sun.COM    bzf->strm.next_in  = bzf->buf;
1300*10843SDave.Plauger@Sun.COM 
1301*10843SDave.Plauger@Sun.COM    bzf->initialisedOk = True;
1302*10843SDave.Plauger@Sun.COM    return bzf;
1303*10843SDave.Plauger@Sun.COM }
1304*10843SDave.Plauger@Sun.COM 
1305*10843SDave.Plauger@Sun.COM 
1306*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzReadClose)1307*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1308*10843SDave.Plauger@Sun.COM {
1309*10843SDave.Plauger@Sun.COM    bzFile* bzf = (bzFile*)b;
1310*10843SDave.Plauger@Sun.COM 
1311*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1312*10843SDave.Plauger@Sun.COM    if (bzf == NULL)
1313*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_OK); return; };
1314*10843SDave.Plauger@Sun.COM 
1315*10843SDave.Plauger@Sun.COM    if (bzf->writing)
1316*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1317*10843SDave.Plauger@Sun.COM 
1318*10843SDave.Plauger@Sun.COM    if (bzf->initialisedOk)
1319*10843SDave.Plauger@Sun.COM       (void) BZ2_bzDecompressEnd ( &(bzf->strm) );
1320*10843SDave.Plauger@Sun.COM    free ( bzf );
1321*10843SDave.Plauger@Sun.COM }
1322*10843SDave.Plauger@Sun.COM 
1323*10843SDave.Plauger@Sun.COM 
1324*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzRead)1325*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzRead)
1326*10843SDave.Plauger@Sun.COM            ( int*    bzerror,
1327*10843SDave.Plauger@Sun.COM              BZFILE* b,
1328*10843SDave.Plauger@Sun.COM              void*   buf,
1329*10843SDave.Plauger@Sun.COM              int     len )
1330*10843SDave.Plauger@Sun.COM {
1331*10843SDave.Plauger@Sun.COM    Int32   n, ret;
1332*10843SDave.Plauger@Sun.COM    bzFile* bzf = (bzFile*)b;
1333*10843SDave.Plauger@Sun.COM 
1334*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1335*10843SDave.Plauger@Sun.COM 
1336*10843SDave.Plauger@Sun.COM    if (bzf == NULL || buf == NULL || len < 0)
1337*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
1338*10843SDave.Plauger@Sun.COM 
1339*10843SDave.Plauger@Sun.COM    if (bzf->writing)
1340*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
1341*10843SDave.Plauger@Sun.COM 
1342*10843SDave.Plauger@Sun.COM    if (len == 0)
1343*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_OK); return 0; };
1344*10843SDave.Plauger@Sun.COM 
1345*10843SDave.Plauger@Sun.COM    bzf->strm.avail_out = len;
1346*10843SDave.Plauger@Sun.COM    bzf->strm.next_out = buf;
1347*10843SDave.Plauger@Sun.COM 
1348*10843SDave.Plauger@Sun.COM    while (True) {
1349*10843SDave.Plauger@Sun.COM 
1350*10843SDave.Plauger@Sun.COM       if (ferror(bzf->handle))
1351*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_IO_ERROR); return 0; };
1352*10843SDave.Plauger@Sun.COM 
1353*10843SDave.Plauger@Sun.COM       if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
1354*10843SDave.Plauger@Sun.COM          n = fread ( bzf->buf, sizeof(UChar),
1355*10843SDave.Plauger@Sun.COM                      BZ_MAX_UNUSED, bzf->handle );
1356*10843SDave.Plauger@Sun.COM          if (ferror(bzf->handle))
1357*10843SDave.Plauger@Sun.COM             { BZ_SETERR(BZ_IO_ERROR); return 0; };
1358*10843SDave.Plauger@Sun.COM          bzf->bufN = n;
1359*10843SDave.Plauger@Sun.COM          bzf->strm.avail_in = bzf->bufN;
1360*10843SDave.Plauger@Sun.COM          bzf->strm.next_in = bzf->buf;
1361*10843SDave.Plauger@Sun.COM       }
1362*10843SDave.Plauger@Sun.COM 
1363*10843SDave.Plauger@Sun.COM       ret = BZ2_bzDecompress ( &(bzf->strm) );
1364*10843SDave.Plauger@Sun.COM 
1365*10843SDave.Plauger@Sun.COM       if (ret != BZ_OK && ret != BZ_STREAM_END)
1366*10843SDave.Plauger@Sun.COM          { BZ_SETERR(ret); return 0; };
1367*10843SDave.Plauger@Sun.COM 
1368*10843SDave.Plauger@Sun.COM       if (ret == BZ_OK && myfeof(bzf->handle) &&
1369*10843SDave.Plauger@Sun.COM           bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
1370*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
1371*10843SDave.Plauger@Sun.COM 
1372*10843SDave.Plauger@Sun.COM       if (ret == BZ_STREAM_END)
1373*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_STREAM_END);
1374*10843SDave.Plauger@Sun.COM            return len - bzf->strm.avail_out; };
1375*10843SDave.Plauger@Sun.COM       if (bzf->strm.avail_out == 0)
1376*10843SDave.Plauger@Sun.COM          { BZ_SETERR(BZ_OK); return len; };
1377*10843SDave.Plauger@Sun.COM 
1378*10843SDave.Plauger@Sun.COM    }
1379*10843SDave.Plauger@Sun.COM 
1380*10843SDave.Plauger@Sun.COM    return 0; /*not reached*/
1381*10843SDave.Plauger@Sun.COM }
1382*10843SDave.Plauger@Sun.COM 
1383*10843SDave.Plauger@Sun.COM 
1384*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzReadGetUnused)1385*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzReadGetUnused)
1386*10843SDave.Plauger@Sun.COM                      ( int*    bzerror,
1387*10843SDave.Plauger@Sun.COM                        BZFILE* b,
1388*10843SDave.Plauger@Sun.COM                        void**  unused,
1389*10843SDave.Plauger@Sun.COM                        int*    nUnused )
1390*10843SDave.Plauger@Sun.COM {
1391*10843SDave.Plauger@Sun.COM    bzFile* bzf = (bzFile*)b;
1392*10843SDave.Plauger@Sun.COM    if (bzf == NULL)
1393*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return; };
1394*10843SDave.Plauger@Sun.COM    if (bzf->lastErr != BZ_STREAM_END)
1395*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1396*10843SDave.Plauger@Sun.COM    if (unused == NULL || nUnused == NULL)
1397*10843SDave.Plauger@Sun.COM       { BZ_SETERR(BZ_PARAM_ERROR); return; };
1398*10843SDave.Plauger@Sun.COM 
1399*10843SDave.Plauger@Sun.COM    BZ_SETERR(BZ_OK);
1400*10843SDave.Plauger@Sun.COM    *nUnused = bzf->strm.avail_in;
1401*10843SDave.Plauger@Sun.COM    *unused = bzf->strm.next_in;
1402*10843SDave.Plauger@Sun.COM }
1403*10843SDave.Plauger@Sun.COM #endif
1404*10843SDave.Plauger@Sun.COM 
1405*10843SDave.Plauger@Sun.COM 
1406*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1407*10843SDave.Plauger@Sun.COM /*--- Misc convenience stuff                      ---*/
1408*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1409*10843SDave.Plauger@Sun.COM 
1410*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzBuffToBuffCompress)1411*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzBuffToBuffCompress)
1412*10843SDave.Plauger@Sun.COM                          ( char*         dest,
1413*10843SDave.Plauger@Sun.COM                            unsigned int* destLen,
1414*10843SDave.Plauger@Sun.COM                            char*         source,
1415*10843SDave.Plauger@Sun.COM                            unsigned int  sourceLen,
1416*10843SDave.Plauger@Sun.COM                            int           blockSize100k,
1417*10843SDave.Plauger@Sun.COM                            int           verbosity,
1418*10843SDave.Plauger@Sun.COM                            int           workFactor )
1419*10843SDave.Plauger@Sun.COM {
1420*10843SDave.Plauger@Sun.COM    bz_stream strm;
1421*10843SDave.Plauger@Sun.COM    int ret;
1422*10843SDave.Plauger@Sun.COM 
1423*10843SDave.Plauger@Sun.COM    if (dest == NULL || destLen == NULL ||
1424*10843SDave.Plauger@Sun.COM        source == NULL ||
1425*10843SDave.Plauger@Sun.COM        blockSize100k < 1 || blockSize100k > 9 ||
1426*10843SDave.Plauger@Sun.COM        verbosity < 0 || verbosity > 4 ||
1427*10843SDave.Plauger@Sun.COM        workFactor < 0 || workFactor > 250)
1428*10843SDave.Plauger@Sun.COM       return BZ_PARAM_ERROR;
1429*10843SDave.Plauger@Sun.COM 
1430*10843SDave.Plauger@Sun.COM    if (workFactor == 0) workFactor = 30;
1431*10843SDave.Plauger@Sun.COM    strm.bzalloc = NULL;
1432*10843SDave.Plauger@Sun.COM    strm.bzfree = NULL;
1433*10843SDave.Plauger@Sun.COM    strm.opaque = NULL;
1434*10843SDave.Plauger@Sun.COM    ret = BZ2_bzCompressInit ( &strm, blockSize100k,
1435*10843SDave.Plauger@Sun.COM                               verbosity, workFactor );
1436*10843SDave.Plauger@Sun.COM    if (ret != BZ_OK) return ret;
1437*10843SDave.Plauger@Sun.COM 
1438*10843SDave.Plauger@Sun.COM    strm.next_in = source;
1439*10843SDave.Plauger@Sun.COM    strm.next_out = dest;
1440*10843SDave.Plauger@Sun.COM    strm.avail_in = sourceLen;
1441*10843SDave.Plauger@Sun.COM    strm.avail_out = *destLen;
1442*10843SDave.Plauger@Sun.COM 
1443*10843SDave.Plauger@Sun.COM    ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1444*10843SDave.Plauger@Sun.COM    if (ret == BZ_FINISH_OK) goto output_overflow;
1445*10843SDave.Plauger@Sun.COM    if (ret != BZ_STREAM_END) goto errhandler;
1446*10843SDave.Plauger@Sun.COM 
1447*10843SDave.Plauger@Sun.COM    /* normal termination */
1448*10843SDave.Plauger@Sun.COM    *destLen -= strm.avail_out;
1449*10843SDave.Plauger@Sun.COM    (void) BZ2_bzCompressEnd ( &strm );
1450*10843SDave.Plauger@Sun.COM    return BZ_OK;
1451*10843SDave.Plauger@Sun.COM 
1452*10843SDave.Plauger@Sun.COM    output_overflow:
1453*10843SDave.Plauger@Sun.COM    (void) BZ2_bzCompressEnd ( &strm );
1454*10843SDave.Plauger@Sun.COM    return BZ_OUTBUFF_FULL;
1455*10843SDave.Plauger@Sun.COM 
1456*10843SDave.Plauger@Sun.COM    errhandler:
1457*10843SDave.Plauger@Sun.COM    (void) BZ2_bzCompressEnd ( &strm );
1458*10843SDave.Plauger@Sun.COM    return ret;
1459*10843SDave.Plauger@Sun.COM }
1460*10843SDave.Plauger@Sun.COM 
1461*10843SDave.Plauger@Sun.COM 
1462*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzBuffToBuffDecompress)1463*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzBuffToBuffDecompress)
1464*10843SDave.Plauger@Sun.COM                            ( char*         dest,
1465*10843SDave.Plauger@Sun.COM                              unsigned int* destLen,
1466*10843SDave.Plauger@Sun.COM                              char*         source,
1467*10843SDave.Plauger@Sun.COM                              unsigned int  sourceLen,
1468*10843SDave.Plauger@Sun.COM                              int           small,
1469*10843SDave.Plauger@Sun.COM                              int           verbosity )
1470*10843SDave.Plauger@Sun.COM {
1471*10843SDave.Plauger@Sun.COM    bz_stream strm;
1472*10843SDave.Plauger@Sun.COM    int ret;
1473*10843SDave.Plauger@Sun.COM 
1474*10843SDave.Plauger@Sun.COM    if (dest == NULL || destLen == NULL ||
1475*10843SDave.Plauger@Sun.COM        source == NULL ||
1476*10843SDave.Plauger@Sun.COM        (small != 0 && small != 1) ||
1477*10843SDave.Plauger@Sun.COM        verbosity < 0 || verbosity > 4)
1478*10843SDave.Plauger@Sun.COM           return BZ_PARAM_ERROR;
1479*10843SDave.Plauger@Sun.COM 
1480*10843SDave.Plauger@Sun.COM    strm.bzalloc = NULL;
1481*10843SDave.Plauger@Sun.COM    strm.bzfree = NULL;
1482*10843SDave.Plauger@Sun.COM    strm.opaque = NULL;
1483*10843SDave.Plauger@Sun.COM    ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1484*10843SDave.Plauger@Sun.COM    if (ret != BZ_OK) return ret;
1485*10843SDave.Plauger@Sun.COM 
1486*10843SDave.Plauger@Sun.COM    strm.next_in = source;
1487*10843SDave.Plauger@Sun.COM    strm.next_out = dest;
1488*10843SDave.Plauger@Sun.COM    strm.avail_in = sourceLen;
1489*10843SDave.Plauger@Sun.COM    strm.avail_out = *destLen;
1490*10843SDave.Plauger@Sun.COM 
1491*10843SDave.Plauger@Sun.COM    ret = BZ2_bzDecompress ( &strm );
1492*10843SDave.Plauger@Sun.COM    if (ret == BZ_OK) goto output_overflow_or_eof;
1493*10843SDave.Plauger@Sun.COM    if (ret != BZ_STREAM_END) goto errhandler;
1494*10843SDave.Plauger@Sun.COM 
1495*10843SDave.Plauger@Sun.COM    /* normal termination */
1496*10843SDave.Plauger@Sun.COM    *destLen -= strm.avail_out;
1497*10843SDave.Plauger@Sun.COM    (void) BZ2_bzDecompressEnd ( &strm );
1498*10843SDave.Plauger@Sun.COM    return BZ_OK;
1499*10843SDave.Plauger@Sun.COM 
1500*10843SDave.Plauger@Sun.COM    output_overflow_or_eof:
1501*10843SDave.Plauger@Sun.COM    if (strm.avail_out > 0) {
1502*10843SDave.Plauger@Sun.COM       (void) BZ2_bzDecompressEnd ( &strm );
1503*10843SDave.Plauger@Sun.COM       return BZ_UNEXPECTED_EOF;
1504*10843SDave.Plauger@Sun.COM    } else {
1505*10843SDave.Plauger@Sun.COM       (void) BZ2_bzDecompressEnd ( &strm );
1506*10843SDave.Plauger@Sun.COM       return BZ_OUTBUFF_FULL;
1507*10843SDave.Plauger@Sun.COM    }
1508*10843SDave.Plauger@Sun.COM 
1509*10843SDave.Plauger@Sun.COM    errhandler:
1510*10843SDave.Plauger@Sun.COM    (void) BZ2_bzDecompressEnd ( &strm );
1511*10843SDave.Plauger@Sun.COM    return ret;
1512*10843SDave.Plauger@Sun.COM }
1513*10843SDave.Plauger@Sun.COM 
1514*10843SDave.Plauger@Sun.COM 
1515*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1516*10843SDave.Plauger@Sun.COM /*--
1517*10843SDave.Plauger@Sun.COM    Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
1518*10843SDave.Plauger@Sun.COM    to support better zlib compatibility.
1519*10843SDave.Plauger@Sun.COM    This code is not _officially_ part of libbzip2 (yet);
1520*10843SDave.Plauger@Sun.COM    I haven't tested it, documented it, or considered the
1521*10843SDave.Plauger@Sun.COM    threading-safeness of it.
1522*10843SDave.Plauger@Sun.COM    If this code breaks, please contact both Yoshioka and me.
1523*10843SDave.Plauger@Sun.COM --*/
1524*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1525*10843SDave.Plauger@Sun.COM 
1526*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1527*10843SDave.Plauger@Sun.COM /*--
1528*10843SDave.Plauger@Sun.COM    return version like "0.9.5d, 4-Sept-1999".
1529*10843SDave.Plauger@Sun.COM --*/
BZ_API(BZ2_bzlibVersion)1530*10843SDave.Plauger@Sun.COM const char * BZ_API(BZ2_bzlibVersion)(void)
1531*10843SDave.Plauger@Sun.COM {
1532*10843SDave.Plauger@Sun.COM    return BZ_VERSION;
1533*10843SDave.Plauger@Sun.COM }
1534*10843SDave.Plauger@Sun.COM 
1535*10843SDave.Plauger@Sun.COM 
1536*10843SDave.Plauger@Sun.COM #ifndef BZ_NO_STDIO
1537*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1538*10843SDave.Plauger@Sun.COM 
1539*10843SDave.Plauger@Sun.COM #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
1540*10843SDave.Plauger@Sun.COM #   include <fcntl.h>
1541*10843SDave.Plauger@Sun.COM #   include <io.h>
1542*10843SDave.Plauger@Sun.COM #   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
1543*10843SDave.Plauger@Sun.COM #else
1544*10843SDave.Plauger@Sun.COM #   define SET_BINARY_MODE(file)
1545*10843SDave.Plauger@Sun.COM #endif
1546*10843SDave.Plauger@Sun.COM static
bzopen_or_bzdopen(const char * path,int fd,const char * mode,int open_mode)1547*10843SDave.Plauger@Sun.COM BZFILE * bzopen_or_bzdopen
1548*10843SDave.Plauger@Sun.COM                ( const char *path,   /* no use when bzdopen */
1549*10843SDave.Plauger@Sun.COM                  int fd,             /* no use when bzdopen */
1550*10843SDave.Plauger@Sun.COM                  const char *mode,
1551*10843SDave.Plauger@Sun.COM                  int open_mode)      /* bzopen: 0, bzdopen:1 */
1552*10843SDave.Plauger@Sun.COM {
1553*10843SDave.Plauger@Sun.COM    int    bzerr;
1554*10843SDave.Plauger@Sun.COM    char   unused[BZ_MAX_UNUSED];
1555*10843SDave.Plauger@Sun.COM    int    blockSize100k = 9;
1556*10843SDave.Plauger@Sun.COM    int    writing       = 0;
1557*10843SDave.Plauger@Sun.COM    char   mode2[10]     = "";
1558*10843SDave.Plauger@Sun.COM    FILE   *fp           = NULL;
1559*10843SDave.Plauger@Sun.COM    BZFILE *bzfp         = NULL;
1560*10843SDave.Plauger@Sun.COM    int    verbosity     = 0;
1561*10843SDave.Plauger@Sun.COM    int    workFactor    = 30;
1562*10843SDave.Plauger@Sun.COM    int    smallMode     = 0;
1563*10843SDave.Plauger@Sun.COM    int    nUnused       = 0;
1564*10843SDave.Plauger@Sun.COM 
1565*10843SDave.Plauger@Sun.COM    if (mode == NULL) return NULL;
1566*10843SDave.Plauger@Sun.COM    while (*mode) {
1567*10843SDave.Plauger@Sun.COM       switch (*mode) {
1568*10843SDave.Plauger@Sun.COM       case 'r':
1569*10843SDave.Plauger@Sun.COM          writing = 0; break;
1570*10843SDave.Plauger@Sun.COM       case 'w':
1571*10843SDave.Plauger@Sun.COM          writing = 1; break;
1572*10843SDave.Plauger@Sun.COM       case 's':
1573*10843SDave.Plauger@Sun.COM          smallMode = 1; break;
1574*10843SDave.Plauger@Sun.COM       default:
1575*10843SDave.Plauger@Sun.COM          if (isdigit((int)(*mode))) {
1576*10843SDave.Plauger@Sun.COM             blockSize100k = *mode-BZ_HDR_0;
1577*10843SDave.Plauger@Sun.COM          }
1578*10843SDave.Plauger@Sun.COM       }
1579*10843SDave.Plauger@Sun.COM       mode++;
1580*10843SDave.Plauger@Sun.COM    }
1581*10843SDave.Plauger@Sun.COM    strcat(mode2, writing ? "w" : "r" );
1582*10843SDave.Plauger@Sun.COM    strcat(mode2,"b");   /* binary mode */
1583*10843SDave.Plauger@Sun.COM 
1584*10843SDave.Plauger@Sun.COM    if (open_mode==0) {
1585*10843SDave.Plauger@Sun.COM       if (path==NULL || strcmp(path,"")==0) {
1586*10843SDave.Plauger@Sun.COM         fp = (writing ? stdout : stdin);
1587*10843SDave.Plauger@Sun.COM         SET_BINARY_MODE(fp);
1588*10843SDave.Plauger@Sun.COM       } else {
1589*10843SDave.Plauger@Sun.COM         fp = fopen(path,mode2);
1590*10843SDave.Plauger@Sun.COM       }
1591*10843SDave.Plauger@Sun.COM    } else {
1592*10843SDave.Plauger@Sun.COM #ifdef BZ_STRICT_ANSI
1593*10843SDave.Plauger@Sun.COM       fp = NULL;
1594*10843SDave.Plauger@Sun.COM #else
1595*10843SDave.Plauger@Sun.COM       fp = fdopen(fd,mode2);
1596*10843SDave.Plauger@Sun.COM #endif
1597*10843SDave.Plauger@Sun.COM    }
1598*10843SDave.Plauger@Sun.COM    if (fp == NULL) return NULL;
1599*10843SDave.Plauger@Sun.COM 
1600*10843SDave.Plauger@Sun.COM    if (writing) {
1601*10843SDave.Plauger@Sun.COM       /* Guard against total chaos and anarchy -- JRS */
1602*10843SDave.Plauger@Sun.COM       if (blockSize100k < 1) blockSize100k = 1;
1603*10843SDave.Plauger@Sun.COM       if (blockSize100k > 9) blockSize100k = 9;
1604*10843SDave.Plauger@Sun.COM       bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
1605*10843SDave.Plauger@Sun.COM                              verbosity,workFactor);
1606*10843SDave.Plauger@Sun.COM    } else {
1607*10843SDave.Plauger@Sun.COM       bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1608*10843SDave.Plauger@Sun.COM                             unused,nUnused);
1609*10843SDave.Plauger@Sun.COM    }
1610*10843SDave.Plauger@Sun.COM    if (bzfp == NULL) {
1611*10843SDave.Plauger@Sun.COM       if (fp != stdin && fp != stdout) fclose(fp);
1612*10843SDave.Plauger@Sun.COM       return NULL;
1613*10843SDave.Plauger@Sun.COM    }
1614*10843SDave.Plauger@Sun.COM    return bzfp;
1615*10843SDave.Plauger@Sun.COM }
1616*10843SDave.Plauger@Sun.COM 
1617*10843SDave.Plauger@Sun.COM 
1618*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1619*10843SDave.Plauger@Sun.COM /*--
1620*10843SDave.Plauger@Sun.COM    open file for read or write.
1621*10843SDave.Plauger@Sun.COM       ex) bzopen("file","w9")
1622*10843SDave.Plauger@Sun.COM       case path="" or NULL => use stdin or stdout.
1623*10843SDave.Plauger@Sun.COM --*/
BZ_API(BZ2_bzopen)1624*10843SDave.Plauger@Sun.COM BZFILE * BZ_API(BZ2_bzopen)
1625*10843SDave.Plauger@Sun.COM                ( const char *path,
1626*10843SDave.Plauger@Sun.COM                  const char *mode )
1627*10843SDave.Plauger@Sun.COM {
1628*10843SDave.Plauger@Sun.COM    return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
1629*10843SDave.Plauger@Sun.COM }
1630*10843SDave.Plauger@Sun.COM 
1631*10843SDave.Plauger@Sun.COM 
1632*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzdopen)1633*10843SDave.Plauger@Sun.COM BZFILE * BZ_API(BZ2_bzdopen)
1634*10843SDave.Plauger@Sun.COM                ( int fd,
1635*10843SDave.Plauger@Sun.COM                  const char *mode )
1636*10843SDave.Plauger@Sun.COM {
1637*10843SDave.Plauger@Sun.COM    return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
1638*10843SDave.Plauger@Sun.COM }
1639*10843SDave.Plauger@Sun.COM 
1640*10843SDave.Plauger@Sun.COM 
1641*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzread)1642*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1643*10843SDave.Plauger@Sun.COM {
1644*10843SDave.Plauger@Sun.COM    int bzerr, nread;
1645*10843SDave.Plauger@Sun.COM    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1646*10843SDave.Plauger@Sun.COM    nread = BZ2_bzRead(&bzerr,b,buf,len);
1647*10843SDave.Plauger@Sun.COM    if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1648*10843SDave.Plauger@Sun.COM       return nread;
1649*10843SDave.Plauger@Sun.COM    } else {
1650*10843SDave.Plauger@Sun.COM       return -1;
1651*10843SDave.Plauger@Sun.COM    }
1652*10843SDave.Plauger@Sun.COM }
1653*10843SDave.Plauger@Sun.COM 
1654*10843SDave.Plauger@Sun.COM 
1655*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzwrite)1656*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1657*10843SDave.Plauger@Sun.COM {
1658*10843SDave.Plauger@Sun.COM    int bzerr;
1659*10843SDave.Plauger@Sun.COM 
1660*10843SDave.Plauger@Sun.COM    BZ2_bzWrite(&bzerr,b,buf,len);
1661*10843SDave.Plauger@Sun.COM    if(bzerr == BZ_OK){
1662*10843SDave.Plauger@Sun.COM       return len;
1663*10843SDave.Plauger@Sun.COM    }else{
1664*10843SDave.Plauger@Sun.COM       return -1;
1665*10843SDave.Plauger@Sun.COM    }
1666*10843SDave.Plauger@Sun.COM }
1667*10843SDave.Plauger@Sun.COM 
1668*10843SDave.Plauger@Sun.COM 
1669*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzflush)1670*10843SDave.Plauger@Sun.COM int BZ_API(BZ2_bzflush) (BZFILE *b)
1671*10843SDave.Plauger@Sun.COM {
1672*10843SDave.Plauger@Sun.COM    /* do nothing now... */
1673*10843SDave.Plauger@Sun.COM    return 0;
1674*10843SDave.Plauger@Sun.COM }
1675*10843SDave.Plauger@Sun.COM 
1676*10843SDave.Plauger@Sun.COM 
1677*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
BZ_API(BZ2_bzclose)1678*10843SDave.Plauger@Sun.COM void BZ_API(BZ2_bzclose) (BZFILE* b)
1679*10843SDave.Plauger@Sun.COM {
1680*10843SDave.Plauger@Sun.COM    int bzerr;
1681*10843SDave.Plauger@Sun.COM    FILE *fp;
1682*10843SDave.Plauger@Sun.COM 
1683*10843SDave.Plauger@Sun.COM    if (b==NULL) {return;}
1684*10843SDave.Plauger@Sun.COM    fp = ((bzFile *)b)->handle;
1685*10843SDave.Plauger@Sun.COM    if(((bzFile*)b)->writing){
1686*10843SDave.Plauger@Sun.COM       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
1687*10843SDave.Plauger@Sun.COM       if(bzerr != BZ_OK){
1688*10843SDave.Plauger@Sun.COM          BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
1689*10843SDave.Plauger@Sun.COM       }
1690*10843SDave.Plauger@Sun.COM    }else{
1691*10843SDave.Plauger@Sun.COM       BZ2_bzReadClose(&bzerr,b);
1692*10843SDave.Plauger@Sun.COM    }
1693*10843SDave.Plauger@Sun.COM    if(fp!=stdin && fp!=stdout){
1694*10843SDave.Plauger@Sun.COM       fclose(fp);
1695*10843SDave.Plauger@Sun.COM    }
1696*10843SDave.Plauger@Sun.COM }
1697*10843SDave.Plauger@Sun.COM 
1698*10843SDave.Plauger@Sun.COM 
1699*10843SDave.Plauger@Sun.COM /*---------------------------------------------------*/
1700*10843SDave.Plauger@Sun.COM /*--
1701*10843SDave.Plauger@Sun.COM    return last error code
1702*10843SDave.Plauger@Sun.COM --*/
1703*10843SDave.Plauger@Sun.COM static const char *bzerrorstrings[] = {
1704*10843SDave.Plauger@Sun.COM        "OK"
1705*10843SDave.Plauger@Sun.COM       ,"SEQUENCE_ERROR"
1706*10843SDave.Plauger@Sun.COM       ,"PARAM_ERROR"
1707*10843SDave.Plauger@Sun.COM       ,"MEM_ERROR"
1708*10843SDave.Plauger@Sun.COM       ,"DATA_ERROR"
1709*10843SDave.Plauger@Sun.COM       ,"DATA_ERROR_MAGIC"
1710*10843SDave.Plauger@Sun.COM       ,"IO_ERROR"
1711*10843SDave.Plauger@Sun.COM       ,"UNEXPECTED_EOF"
1712*10843SDave.Plauger@Sun.COM       ,"OUTBUFF_FULL"
1713*10843SDave.Plauger@Sun.COM       ,"CONFIG_ERROR"
1714*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1715*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1716*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1717*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1718*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1719*10843SDave.Plauger@Sun.COM       ,"???"   /* for future */
1720*10843SDave.Plauger@Sun.COM };
1721*10843SDave.Plauger@Sun.COM 
1722*10843SDave.Plauger@Sun.COM 
BZ_API(BZ2_bzerror)1723*10843SDave.Plauger@Sun.COM const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
1724*10843SDave.Plauger@Sun.COM {
1725*10843SDave.Plauger@Sun.COM    int err = ((bzFile *)b)->lastErr;
1726*10843SDave.Plauger@Sun.COM 
1727*10843SDave.Plauger@Sun.COM    if(err>0) err = 0;
1728*10843SDave.Plauger@Sun.COM    *errnum = err;
1729*10843SDave.Plauger@Sun.COM    return bzerrorstrings[err*-1];
1730*10843SDave.Plauger@Sun.COM }
1731*10843SDave.Plauger@Sun.COM #endif
1732*10843SDave.Plauger@Sun.COM 
1733*10843SDave.Plauger@Sun.COM 
1734*10843SDave.Plauger@Sun.COM /*-------------------------------------------------------------*/
1735*10843SDave.Plauger@Sun.COM /*--- end                                           bzlib.c ---*/
1736*10843SDave.Plauger@Sun.COM /*-------------------------------------------------------------*/
1737