1ca3e8d8Dave Plauger
2ca3e8d8Dave Plauger/*-------------------------------------------------------------*/
3ca3e8d8Dave Plauger/*--- Library top-level functions.                          ---*/
4ca3e8d8Dave Plauger/*---                                               bzlib.c ---*/
5ca3e8d8Dave Plauger/*-------------------------------------------------------------*/
6ca3e8d8Dave Plauger
7ca3e8d8Dave Plauger/* ------------------------------------------------------------------
8ca3e8d8Dave Plauger   This file is part of bzip2/libbzip2, a program and library for
9ca3e8d8Dave Plauger   lossless, block-sorting data compression.
10ca3e8d8Dave Plauger
11b9071c3Gordon Ross   bzip2/libbzip2 version 1.0.6 of 6 September 2010
12b9071c3Gordon Ross   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13ca3e8d8Dave Plauger
14238e18aToomas Soome   Please read the WARNING, DISCLAIMER and PATENTS sections in the
15ca3e8d8Dave Plauger   README file.
16ca3e8d8Dave Plauger
17ca3e8d8Dave Plauger   This program is released under the terms of the license contained
18ca3e8d8Dave Plauger   in the file LICENSE.
19ca3e8d8Dave Plauger   ------------------------------------------------------------------ */
20ca3e8d8Dave Plauger
21ca3e8d8Dave Plauger/* CHANGES
22ca3e8d8Dave Plauger   0.9.0    -- original version.
23ca3e8d8Dave Plauger   0.9.0a/b -- no changes in this file.
24ca3e8d8Dave Plauger   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
25ca3e8d8Dave Plauger     fixed bzWrite/bzRead to ignore zero-length requests.
26ca3e8d8Dave Plauger     fixed bzread to correctly handle read requests after EOF.
27ca3e8d8Dave Plauger     wrong parameter order in call to bzDecompressInit in
28ca3e8d8Dave Plauger     bzBuffToBuffDecompress.  Fixed.
29ca3e8d8Dave Plauger*/
30ca3e8d8Dave Plauger
31ca3e8d8Dave Plauger#include "bzlib_private.h"
32ca3e8d8Dave Plauger
33fce880dToomas Soome#ifndef BZ_NO_COMPRESS
34ca3e8d8Dave Plauger
35ca3e8d8Dave Plauger/*---------------------------------------------------*/
36ca3e8d8Dave Plauger/*--- Compression stuff                           ---*/
37ca3e8d8Dave Plauger/*---------------------------------------------------*/
38ca3e8d8Dave Plauger
39ca3e8d8Dave Plauger
40ca3e8d8Dave Plauger/*---------------------------------------------------*/
41ca3e8d8Dave Plauger#ifndef BZ_NO_STDIO
42ca3e8d8Dave Plaugervoid BZ2_bz__AssertH__fail ( int errcode )
43ca3e8d8Dave Plauger{
44238e18aToomas Soome   fprintf(stderr,
45ca3e8d8Dave Plauger      "\n\nbzip2/libbzip2: internal error number %d.\n"
46ca3e8d8Dave Plauger      "This is a bug in bzip2/libbzip2, %s.\n"
47ca3e8d8Dave Plauger      "Please report it to me at: jseward@bzip.org.  If this happened\n"
48ca3e8d8Dave Plauger      "when you were using some program which uses libbzip2 as a\n"
49ca3e8d8Dave Plauger      "component, you should also report this bug to the author(s)\n"
50ca3e8d8Dave Plauger      "of that program.  Please make an effort to report this bug;\n"
51ca3e8d8Dave Plauger      "timely and accurate bug reports eventually lead to higher\n"
52ca3e8d8Dave Plauger      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
53ca3e8d8Dave Plauger      errcode,
54ca3e8d8Dave Plauger      BZ2_bzlibVersion()
55ca3e8d8Dave Plauger   );
56ca3e8d8Dave Plauger
57ca3e8d8Dave Plauger   if (errcode == 1007) {
58ca3e8d8Dave Plauger   fprintf(stderr,
59ca3e8d8Dave Plauger      "\n*** A special note about internal error number 1007 ***\n"
60ca3e8d8Dave Plauger      "\n"
61ca3e8d8Dave Plauger      "Experience suggests that a common cause of i.e. 1007\n"
62ca3e8d8Dave Plauger      "is unreliable memory or other hardware.  The 1007 assertion\n"
63ca3e8d8Dave Plauger      "just happens to cross-check the results of huge numbers of\n"
64ca3e8d8Dave Plauger      "memory reads/writes, and so acts (unintendedly) as a stress\n"
65ca3e8d8Dave Plauger      "test of your memory system.\n"
66ca3e8d8Dave Plauger      "\n"
67ca3e8d8Dave Plauger      "I suggest the following: try compressing the file again,\n"
68ca3e8d8Dave Plauger      "possibly monitoring progress in detail with the -vv flag.\n"
69ca3e8d8Dave Plauger      "\n"
70ca3e8d8Dave Plauger      "* If the error cannot be reproduced, and/or happens at different\n"
71ca3e8d8Dave Plauger      "  points in compression, you may have a flaky memory system.\n"
72ca3e8d8Dave Plauger      "  Try a memory-test program.  I have used Memtest86\n"
73ca3e8d8Dave Plauger      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
74ca3e8d8Dave Plauger      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
75ca3e8d8Dave Plauger      "  power-on test, and may find failures that the BIOS doesn't.\n"
76ca3e8d8Dave Plauger      "\n"
77ca3e8d8Dave Plauger      "* If the error can be repeatably reproduced, this is a bug in\n"
78ca3e8d8Dave Plauger      "  bzip2, and I would very much like to hear about it.  Please\n"
79ca3e8d8Dave Plauger      "  let me know, and, ideally, save a copy of the file causing the\n"
80ca3e8d8Dave Plauger      "  problem -- without which I will be unable to investigate it.\n"
81ca3e8d8Dave Plauger      "\n"
82ca3e8d8Dave Plauger   );
83ca3e8d8Dave Plauger   }
84ca3e8d8Dave Plauger
85ca3e8d8Dave Plauger   exit(3);
86ca3e8d8Dave Plauger}
87ca3e8d8Dave Plauger#endif
88ca3e8d8Dave Plauger
89fce880dToomas Soome#endif /* BZ_NO_COMPRESS */
90ca3e8d8Dave Plauger
91ca3e8d8Dave Plauger/*---------------------------------------------------*/
92ca3e8d8Dave Plaugerstatic
93ca3e8d8Dave Plaugerint bz_config_ok ( void )
94ca3e8d8Dave Plauger{
95ca3e8d8Dave Plauger   if (sizeof(int)   != 4) return 0;
96ca3e8d8Dave Plauger   if (sizeof(short) != 2) return 0;
97ca3e8d8Dave Plauger   if (sizeof(char)  != 1) return 0;
98ca3e8d8Dave Plauger   return 1;
99ca3e8d8Dave Plauger}
100ca3e8d8Dave Plauger
101ca3e8d8Dave Plauger/*
102ca3e8d8Dave Plauger * Added for Solaris kernel
103ca3e8d8Dave Plauger */
104ca3e8d8Dave Plauger#define BZES \
105ca3e8d8Dave PlaugerBZE(BZ_OK) \
106ca3e8d8Dave PlaugerBZE(BZ_RUN_OK) \
107ca3e8d8Dave PlaugerBZE(BZ_FLUSH_OK) \
108ca3e8d8Dave PlaugerBZE(BZ_FINISH_OK) \
109ca3e8d8Dave PlaugerBZE(BZ_STREAM_END) \
110ca3e8d8Dave PlaugerBZE(BZ_SEQUENCE_ERROR) \
111ca3e8d8Dave PlaugerBZE(BZ_PARAM_ERROR) \
112ca3e8d8Dave PlaugerBZE(BZ_MEM_ERROR) \
113ca3e8d8Dave PlaugerBZE(BZ_DATA_ERROR) \
114ca3e8d8Dave PlaugerBZE(BZ_DATA_ERROR_MAGIC) \
115ca3e8d8Dave PlaugerBZE(BZ_IO_ERROR) \
116ca3e8d8Dave PlaugerBZE(BZ_UNEXPECTED_EOF) \
117ca3e8d8Dave PlaugerBZE(BZ_OUTBUFF_FULL) \
118238e18aToomas SoomeBZE(BZ_CONFIG_ERROR)
119ca3e8d8Dave Plauger
120238e18aToomas Soomeconst char * BZ_API(BZ2_bzErrorString) (
121ca3e8d8Dave Plauger      int error_code
122ca3e8d8Dave Plauger   )
123ca3e8d8Dave Plauger{
124ca3e8d8Dave Plauger	switch (error_code)
125ca3e8d8Dave Plauger	{
126ca3e8d8Dave Plauger#define BZE(x) case x: return (#x);
127ca3e8d8Dave PlaugerBZES
128ca3e8d8Dave Plauger#undef BZE
129ca3e8d8Dave Plauger	}
130ca3e8d8Dave Plauger	return ("BZ_UNKNOWN_ERROR");
131ca3e8d8Dave Plauger}
132ca3e8d8Dave Plauger
133f9227b3Yuri Pankov#ifndef BZ_LOADER
134ca3e8d8Dave Plauger#include <sys/sysmacros.h>
135f9227b3Yuri Pankov#endif
136ca3e8d8Dave Plauger
137ca3e8d8Dave Plauger#ifdef _KERNEL
138ca3e8d8Dave Plauger
139ca3e8d8Dave Plauger#include <sys/types.h>
140ca3e8d8Dave Plauger#include <sys/cmn_err.h>
141ca3e8d8Dave Plauger#include <sys/kmem.h>
142ca3e8d8Dave Plauger
143ca3e8d8Dave Plaugervoid
144ca3e8d8Dave Plaugerbz_internal_error(int errcode)
145ca3e8d8Dave Plauger{
146ca3e8d8Dave Plauger	panic("bzip2 internal error: %s\n", BZ2_bzErrorString(errcode));
147ca3e8d8Dave Plauger}
148ca3e8d8Dave Plauger
149ca3e8d8Dave Plauger/*---------------------------------------------------*/
150ca3e8d8Dave Plaugertypedef struct {
151ca3e8d8Dave Plauger	char *buf;
152ca3e8d8Dave Plauger	size_t sz;
153ca3e8d8Dave Plauger} bzap;
154ca3e8d8Dave Plauger
155ca3e8d8Dave Plaugerstatic
156ca3e8d8Dave Plaugervoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
157ca3e8d8Dave Plauger{
158ca3e8d8Dave Plauger	size_t sz = sizeof (bzap) + BZ2_BZALLOC_ALIGN + (items * size);
159ca3e8d8Dave Plauger	uintptr_t p = (uintptr_t)kmem_alloc(sz, KM_SLEEP);
160ca3e8d8Dave Plauger
161ca3e8d8Dave Plauger	if (p != NULL) {
162ca3e8d8Dave Plauger		bzap *pp = (bzap *)((p + sizeof (bzap) + BZ2_BZALLOC_ALIGN - 1) &
163ca3e8d8Dave Plauger		    -BZ2_BZALLOC_ALIGN);
164ca3e8d8Dave Plauger		pp[-1].buf = (void *)p;
165ca3e8d8Dave Plauger		pp[-1].sz = sz;
166ca3e8d8Dave Plauger		return (pp);
167ca3e8d8Dave Plauger	}
168ca3e8d8Dave Plauger	return (NULL);
169ca3e8d8Dave Plauger}
170ca3e8d8Dave Plauger
171ca3e8d8Dave Plaugerstatic
172ca3e8d8Dave Plaugervoid default_bzfree ( void* opaque, void* addr )
173ca3e8d8Dave Plauger{
174ca3e8d8Dave Plauger	if (addr != NULL) {
175ca3e8d8Dave Plauger		bzap *pp = (bzap *)addr - 1;
176ca3e8d8Dave Plauger		kmem_free(pp->buf, pp->sz);
177ca3e8d8Dave Plauger	}
178ca3e8d8Dave Plauger}
179ca3e8d8Dave Plauger
180ca3e8d8Dave Plauger#else
181ca3e8d8Dave Plauger
182ca3e8d8Dave Plauger/*---------------------------------------------------*/
183ca3e8d8Dave Plaugerstatic
18405876afToomas Soomevoid* default_bzalloc ( void* opaque __unused, Int32 items, Int32 size )
185ca3e8d8Dave Plauger{
186ca3e8d8Dave Plauger   void* v = malloc ( items * size );
187ca3e8d8Dave Plauger   return v;
188ca3e8d8Dave Plauger}
189ca3e8d8Dave Plauger
190ca3e8d8Dave Plaugerstatic
19105876afToomas Soomevoid default_bzfree ( void* opaque __unused, void* addr )
192ca3e8d8Dave Plauger{
193ca3e8d8Dave Plauger   if (addr != NULL) free ( addr );
194ca3e8d8Dave Plauger}
195ca3e8d8Dave Plauger#endif	/* _KERNEL */
196ca3e8d8Dave Plauger
197ca3e8d8Dave Plauger/*---------------------------------------------------*/
198fce880dToomas Soome#ifndef BZ_NO_COMPRESS
199ca3e8d8Dave Plaugerstatic
200ca3e8d8Dave Plaugervoid prepare_new_block ( EState* s )
201ca3e8d8Dave Plauger{
202ca3e8d8Dave Plauger   Int32 i;
203ca3e8d8Dave Plauger   s->nblock = 0;
204ca3e8d8Dave Plauger   s->numZ = 0;
205ca3e8d8Dave Plauger   s->state_out_pos = 0;
206ca3e8d8Dave Plauger   BZ_INITIALISE_CRC ( s->blockCRC );
207ca3e8d8Dave Plauger   for (i = 0; i < 256; i++) s->inUse[i] = False;
208ca3e8d8Dave Plauger   s->blockNo++;
209ca3e8d8Dave Plauger}
210ca3e8d8Dave Plauger
211ca3e8d8Dave Plauger
212ca3e8d8Dave Plauger/*---------------------------------------------------*/
213ca3e8d8Dave Plaugerstatic
214ca3e8d8Dave Plaugervoid init_RL ( EState* s )
215ca3e8d8Dave Plauger{
216ca3e8d8Dave Plauger   s->state_in_ch  = 256;
217ca3e8d8Dave Plauger   s->state_in_len = 0;
218ca3e8d8Dave Plauger}
219ca3e8d8Dave Plauger
220ca3e8d8Dave Plauger
221ca3e8d8Dave Plaugerstatic
222ca3e8d8Dave PlaugerBool isempty_RL ( EState* s )
223ca3e8d8Dave Plauger{
224ca3e8d8Dave Plauger   if (s->state_in_ch < 256 && s->state_in_len > 0)
225ca3e8d8Dave Plauger      return False; else
226ca3e8d8Dave Plauger      return True;
227ca3e8d8Dave Plauger}
228ca3e8d8Dave Plauger
229ca3e8d8Dave Plauger
230ca3e8d8Dave Plauger/*---------------------------------------------------*/
231238e18aToomas Soomeint BZ_API(BZ2_bzCompressInit)
232238e18aToomas Soome                    ( bz_stream* strm,
233ca3e8d8Dave Plauger                     int        blockSize100k,
234ca3e8d8Dave Plauger                     int        verbosity,
235ca3e8d8Dave Plauger                     int        workFactor )
236ca3e8d8Dave Plauger{
237ca3e8d8Dave Plauger   Int32   n;
238ca3e8d8Dave Plauger   EState* s;
239ca3e8d8Dave Plauger
240ca3e8d8Dave Plauger   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
241ca3e8d8Dave Plauger
242238e18aToomas Soome   if (strm == NULL ||
243ca3e8d8Dave Plauger       blockSize100k < 1 || blockSize100k > 9 ||
244ca3e8d8Dave Plauger       workFactor < 0 || workFactor > 250)
245ca3e8d8Dave Plauger     return BZ_PARAM_ERROR;
246ca3e8d8Dave Plauger
247ca3e8d8Dave Plauger   if (workFactor == 0) workFactor = 30;
248ca3e8d8Dave Plauger   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
249ca3e8d8Dave Plauger   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
250ca3e8d8Dave Plauger
251ca3e8d8Dave Plauger   s = BZALLOC( sizeof(EState) );
252ca3e8d8Dave Plauger   if (s == NULL) return BZ_MEM_ERROR;
253ca3e8d8Dave Plauger   s->strm = strm;
254ca3e8d8Dave Plauger
255ca3e8d8Dave Plauger   s->arr1 = NULL;
256ca3e8d8Dave Plauger   s->arr2 = NULL;
257ca3e8d8Dave Plauger   s->ftab = NULL;
258ca3e8d8Dave Plauger
259ca3e8d8Dave Plauger   n       = 100000 * blockSize100k;
260ca3e8d8Dave Plauger   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
261ca3e8d8Dave Plauger   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
262ca3e8d8Dave Plauger   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
263ca3e8d8Dave Plauger
264ca3e8d8Dave Plauger   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
265ca3e8d8Dave Plauger      if (s->arr1 != NULL) BZFREE(s->arr1);
266ca3e8d8Dave Plauger      if (s->arr2 != NULL) BZFREE(s->arr2);
267ca3e8d8Dave Plauger      if (s->ftab != NULL) BZFREE(s->ftab);
268ca3e8d8Dave Plauger      if (s       != NULL) BZFREE(s);
269ca3e8d8Dave Plauger      return BZ_MEM_ERROR;
270ca3e8d8Dave Plauger   }
271ca3e8d8Dave Plauger
272ca3e8d8Dave Plauger   s->blockNo           = 0;
273ca3e8d8Dave Plauger   s->state             = BZ_S_INPUT;
274ca3e8d8Dave Plauger   s->mode              = BZ_M_RUNNING;
275ca3e8d8Dave Plauger   s->combinedCRC       = 0;
276ca3e8d8Dave Plauger   s->blockSize100k     = blockSize100k;
277ca3e8d8Dave Plauger   s->nblockMAX         = 100000 * blockSize100k - 19;
278ca3e8d8Dave Plauger   s->verbosity         = verbosity;
279ca3e8d8Dave Plauger   s->workFactor        = workFactor;
280ca3e8d8Dave Plauger
281ca3e8d8Dave Plauger   s->block             = (UChar*)s->arr2;
282ca3e8d8Dave Plauger   s->mtfv              = (UInt16*)s->arr1;
283ca3e8d8Dave Plauger   s->zbits             = NULL;
284ca3e8d8Dave Plauger   s->ptr               = (UInt32*)s->arr1;
285ca3e8d8Dave Plauger
286ca3e8d8Dave Plauger   strm->state          = s;
287ca3e8d8Dave Plauger   strm->total_in_lo32  = 0;
288ca3e8d8Dave Plauger   strm->total_in_hi32  = 0;
289ca3e8d8Dave Plauger   strm->total_out_lo32 = 0;
290ca3e8d8Dave Plauger   strm->total_out_hi32 = 0;
291ca3e8d8Dave Plauger   init_RL ( s );
292ca3e8d8Dave Plauger   prepare_new_block ( s );
293ca3e8d8Dave Plauger   return BZ_OK;
294ca3e8d8Dave Plauger}
295ca3e8d8Dave Plauger
296ca3e8d8Dave Plauger/*---------------------------------------------------*/
297ca3e8d8Dave Plauger/*
298ca3e8d8Dave Plauger * returns the BZALLOC size needed for bzCompressInit
299ca3e8d8Dave Plauger */
300238e18aToomas Soomeint BZ_API(BZ2_bzCompressInitSize) (
301ca3e8d8Dave Plauger                     int        blockSize100k)
302ca3e8d8Dave Plauger{
303ca3e8d8Dave Plauger   Int32   n, t;
304ca3e8d8Dave Plauger
305ca3e8d8Dave Plauger   n       = 100000 * blockSize100k;
306ca3e8d8Dave Plauger   t       = 0;
307ca3e8d8Dave Plauger   t += ( sizeof(EState) );
308ca3e8d8Dave Plauger   t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
309ca3e8d8Dave Plauger   t += ( n                  * sizeof(UInt32) );
310ca3e8d8Dave Plauger   t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
311ca3e8d8Dave Plauger   t += ( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
312ca3e8d8Dave Plauger   t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
313ca3e8d8Dave Plauger   t += ( 65537              * sizeof(UInt32) );
314ca3e8d8Dave Plauger   t = P2ROUNDUP(t, BZ2_BZALLOC_ALIGN);
315ca3e8d8Dave Plauger   return (t);
316ca3e8d8Dave Plauger}
317ca3e8d8Dave Plauger
318ca3e8d8Dave Plauger/*---------------------------------------------------*/
319ca3e8d8Dave Plauger/*
320ca3e8d8Dave Plauger * added to allow reuse of bz_stream without malloc/free
321ca3e8d8Dave Plauger */
322ca3e8d8Dave Plaugerint BZ_API(BZ2_bzCompressReset) ( bz_stream *strm )
323ca3e8d8Dave Plauger{
324ca3e8d8Dave Plauger   EState* s = strm->state;
325ca3e8d8Dave Plauger
326ca3e8d8Dave Plauger   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
327ca3e8d8Dave Plauger
328ca3e8d8Dave Plauger   if (s == NULL) return BZ_MEM_ERROR;
329ca3e8d8Dave Plauger   s->strm = strm;
330ca3e8d8Dave Plauger
331ca3e8d8Dave Plauger   s->blockNo           = 0;
332ca3e8d8Dave Plauger   s->state             = BZ_S_INPUT;
333ca3e8d8Dave Plauger   s->mode              = BZ_M_RUNNING;
334ca3e8d8Dave Plauger   s->combinedCRC       = 0;
335ca3e8d8Dave Plauger   s->nblockMAX         = 100000 * s->blockSize100k - 19;
336ca3e8d8Dave Plauger
337ca3e8d8Dave Plauger   s->block             = (UChar*)s->arr2;
338ca3e8d8Dave Plauger   s->mtfv              = (UInt16*)s->arr1;
339ca3e8d8Dave Plauger   s->zbits             = NULL;
340ca3e8d8Dave Plauger   s->ptr               = (UInt32*)s->arr1;
341ca3e8d8Dave Plauger
342ca3e8d8Dave Plauger   strm->state          = s;
343ca3e8d8Dave Plauger   strm->total_in_lo32  = 0;
344ca3e8d8Dave Plauger   strm->total_in_hi32  = 0;
345ca3e8d8Dave Plauger   strm->total_out_lo32 = 0;
346ca3e8d8Dave Plauger   strm->total_out_hi32 = 0;
347ca3e8d8Dave Plauger   init_RL ( s );
348ca3e8d8Dave Plauger   prepare_new_block ( s );
349ca3e8d8Dave Plauger   return BZ_OK;
350ca3e8d8Dave Plauger}
351ca3e8d8Dave Plauger
352ca3e8d8Dave Plauger
353ca3e8d8Dave Plauger/*---------------------------------------------------*/
354ca3e8d8Dave Plaugerstatic
355ca3e8d8Dave Plaugervoid add_pair_to_block ( EState* s )
356ca3e8d8Dave Plauger{
357ca3e8d8Dave Plauger   Int32 i;
358ca3e8d8Dave Plauger   UChar ch = (UChar)(s->state_in_ch);
359ca3e8d8Dave Plauger   for (i = 0; i < s->state_in_len; i++) {
360ca3e8d8Dave Plauger      BZ_UPDATE_CRC( s->blockCRC, ch );
361ca3e8d8Dave Plauger   }
362ca3e8d8Dave Plauger   s->inUse[s->state_in_ch] = True;
363ca3e8d8Dave Plauger   switch (s->state_in_len) {
364ca3e8d8Dave Plauger      case 1:
365ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
366ca3e8d8Dave Plauger         break;
367ca3e8d8Dave Plauger      case 2:
368ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
369ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
370ca3e8d8Dave Plauger         break;
371ca3e8d8Dave Plauger      case 3:
372ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
373ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
374ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
375ca3e8d8Dave Plauger         break;
376ca3e8d8Dave Plauger      default:
377ca3e8d8Dave Plauger         s->inUse[s->state_in_len-4] = True;
378ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
379ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
380ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
381ca3e8d8Dave Plauger         s->block[s->nblock] = (UChar)ch; s->nblock++;
382ca3e8d8Dave Plauger         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
383ca3e8d8Dave Plauger         s->nblock++;
384ca3e8d8Dave Plauger         break;
385ca3e8d8Dave Plauger   }
386ca3e8d8Dave Plauger}
387ca3e8d8Dave Plauger
388ca3e8d8Dave Plauger
389ca3e8d8Dave Plauger/*---------------------------------------------------*/
390ca3e8d8Dave Plaugerstatic
391ca3e8d8Dave Plaugervoid flush_RL ( EState* s )
392ca3e8d8Dave Plauger{
393ca3e8d8Dave Plauger   if (s->state_in_ch < 256) add_pair_to_block ( s );
394ca3e8d8Dave Plauger   init_RL ( s );
395ca3e8d8Dave Plauger}
396ca3e8d8Dave Plauger
397ca3e8d8Dave Plauger
398ca3e8d8Dave Plauger/*---------------------------------------------------*/
399ca3e8d8Dave Plauger#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
400ca3e8d8Dave Plauger{                                                 \
401ca3e8d8Dave Plauger   UInt32 zchh = (UInt32)(zchh0);                 \
402ca3e8d8Dave Plauger   /*-- fast track the common case --*/           \
403ca3e8d8Dave Plauger   if (zchh != zs->state_in_ch &&                 \
404ca3e8d8Dave Plauger       zs->state_in_len == 1) {                   \
405ca3e8d8Dave Plauger      UChar ch = (UChar)(zs->state_in_ch);        \
406ca3e8d8Dave Plauger      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
407ca3e8d8Dave Plauger      zs->inUse[zs->state_in_ch] = True;          \
408ca3e8d8Dave Plauger      zs->block[zs->nblock] = (UChar)ch;          \
409ca3e8d8Dave Plauger      zs->nblock++;                               \
410ca3e8d8Dave Plauger      zs->state_in_ch = zchh;                     \
411ca3e8d8Dave Plauger   }                                              \
412ca3e8d8Dave Plauger   else                                           \
413ca3e8d8Dave Plauger   /*-- general, uncommon cases --*/              \
414ca3e8d8Dave Plauger   if (zchh != zs->state_in_ch ||                 \
415ca3e8d8Dave Plauger      zs->state_in_len == 255) {                  \
416ca3e8d8Dave Plauger      if (zs->state_in_ch < 256)                  \
417ca3e8d8Dave Plauger         add_pair_to_block ( zs );                \
418ca3e8d8Dave Plauger      zs->state_in_ch = zchh;                     \
419ca3e8d8Dave Plauger      zs->state_in_len = 1;                       \
420ca3e8d8Dave Plauger   } else {                                       \
421ca3e8d8Dave Plauger      zs->state_in_len++;                         \
422ca3e8d8Dave Plauger   }                                              \
423ca3e8d8Dave Plauger}
424ca3e8d8Dave Plauger
425ca3e8d8Dave Plauger
426ca3e8d8Dave Plauger/*---------------------------------------------------*/
427ca3e8d8Dave Plaugerstatic
428ca3e8d8Dave PlaugerBool copy_input_until_stop ( EState* s )
429ca3e8d8Dave Plauger{
430ca3e8d8Dave Plauger   Bool progress_in = False;
431ca3e8d8Dave Plauger
432ca3e8d8Dave Plauger   if (s->mode == BZ_M_RUNNING) {
433ca3e8d8Dave Plauger
434ca3e8d8Dave Plauger      /*-- fast track the common case --*/
435ca3e8d8Dave Plauger      while (True) {
436ca3e8d8Dave Plauger         /*-- block full? --*/
437ca3e8d8Dave Plauger         if (s->nblock >= s->nblockMAX) break;
438ca3e8d8Dave Plauger         /*-- no input? --*/
439ca3e8d8Dave Plauger         if (s->strm->avail_in == 0) break;
440ca3e8d8Dave Plauger         progress_in = True;
441238e18aToomas Soome         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
442ca3e8d8Dave Plauger         s->strm->next_in++;
443ca3e8d8Dave Plauger         s->strm->avail_in--;
444ca3e8d8Dave Plauger         s->strm->total_in_lo32++;
445ca3e8d8Dave Plauger         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
446ca3e8d8Dave Plauger      }
447ca3e8d8Dave Plauger
448ca3e8d8Dave Plauger   } else {
449ca3e8d8Dave Plauger
450ca3e8d8Dave Plauger      /*-- general, uncommon case --*/
451ca3e8d8Dave Plauger      while (True) {
452ca3e8d8Dave Plauger         /*-- block full? --*/
453ca3e8d8Dave Plauger         if (s->nblock >= s->nblockMAX) break;
454ca3e8d8Dave Plauger         /*-- no input? --*/
455ca3e8d8Dave Plauger         if (s->strm->avail_in == 0) break;
456ca3e8d8Dave Plauger         /*-- flush/finish end? --*/
457ca3e8d8Dave Plauger         if (s->avail_in_expect == 0) break;
458ca3e8d8Dave Plauger         progress_in = True;
459238e18aToomas Soome         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
460ca3e8d8Dave Plauger         s->strm->next_in++;
461ca3e8d8Dave Plauger         s->strm->avail_in--;
462ca3e8d8Dave Plauger         s->strm->total_in_lo32++;
463ca3e8d8Dave Plauger         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
464ca3e8d8Dave Plauger         s->avail_in_expect--;
465ca3e8d8Dave Plauger      }
466ca3e8d8Dave Plauger   }
467ca3e8d8Dave Plauger   return progress_in;
468ca3e8d8Dave Plauger}
469ca3e8d8Dave Plauger
470ca3e8d8Dave Plauger
471ca3e8d8Dave Plauger/*---------------------------------------------------*/
472ca3e8d8Dave Plaugerstatic
473ca3e8d8Dave PlaugerBool copy_output_until_stop ( EState* s )
474ca3e8d8Dave Plauger{
475ca3e8d8Dave Plauger   Bool progress_out = False;
476ca3e8d8Dave Plauger
477ca3e8d8Dave Plauger   while (True) {
478ca3e8d8Dave Plauger
479ca3e8d8Dave Plauger      /*-- no output space? --*/
480ca3e8d8Dave Plauger      if (s->strm->avail_out == 0) break;
481ca3e8d8Dave Plauger
482ca3e8d8Dave Plauger      /*-- block done? --*/
483ca3e8d8Dave Plauger      if (s->state_out_pos >= s->numZ) break;
484ca3e8d8Dave Plauger
485ca3e8d8Dave Plauger      progress_out = True;
486ca3e8d8Dave Plauger      *(s->strm->next_out) = s->zbits[s->state_out_pos];
487ca3e8d8Dave Plauger      s->state_out_pos++;
488ca3e8d8Dave Plauger      s->strm->avail_out--;
489ca3e8d8Dave Plauger      s->strm->next_out++;
490ca3e8d8Dave Plauger      s->strm->total_out_lo32++;
491ca3e8d8Dave Plauger      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
492ca3e8d8Dave Plauger   }
493ca3e8d8Dave Plauger
494ca3e8d8Dave Plauger   return progress_out;
495ca3e8d8Dave Plauger}
496ca3e8d8Dave Plauger
497ca3e8d8Dave Plauger
498ca3e8d8Dave Plauger/*---------------------------------------------------*/
499ca3e8d8Dave Plaugerstatic
500ca3e8d8Dave PlaugerBool handle_compress ( bz_stream* strm )
501ca3e8d8Dave Plauger{
502ca3e8d8Dave Plauger   Bool progress_in  = False;
503ca3e8d8Dave Plauger   Bool progress_out = False;
504ca3e8d8Dave Plauger   EState* s = strm->state;
505238e18aToomas Soome
506ca3e8d8Dave Plauger   while (True) {
507ca3e8d8Dave Plauger
508ca3e8d8Dave Plauger      if (s->state == BZ_S_OUTPUT) {
509ca3e8d8Dave Plauger         progress_out |= copy_output_until_stop ( s );
510ca3e8d8Dave Plauger         if (s->state_out_pos < s->numZ) break;
511238e18aToomas Soome         if (s->mode == BZ_M_FINISHING &&
512ca3e8d8Dave Plauger             s->avail_in_expect == 0 &&
513ca3e8d8Dave Plauger             isempty_RL(s)) break;
514ca3e8d8Dave Plauger         prepare_new_block ( s );
515ca3e8d8Dave Plauger         s->state = BZ_S_INPUT;
516238e18aToomas Soome         if (s->mode == BZ_M_FLUSHING &&
517ca3e8d8Dave Plauger             s->avail_in_expect == 0 &&
518ca3e8d8Dave Plauger             isempty_RL(s)) break;
519ca3e8d8Dave Plauger      }
520ca3e8d8Dave Plauger
521ca3e8d8Dave Plauger      if (s->state == BZ_S_INPUT) {
522ca3e8d8Dave Plauger         progress_in |= copy_input_until_stop ( s );
523ca3e8d8Dave Plauger         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
524ca3e8d8Dave Plauger            flush_RL ( s );
525ca3e8d8Dave Plauger            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
526ca3e8d8Dave Plauger            s->state = BZ_S_OUTPUT;
527ca3e8d8Dave Plauger         }
528ca3e8d8Dave Plauger         else
529ca3e8d8Dave Plauger         if (s->nblock >= s->nblockMAX) {
530ca3e8d8Dave Plauger            BZ2_compressBlock ( s, False );
531ca3e8d8Dave Plauger            s->state = BZ_S_OUTPUT;
532ca3e8d8Dave Plauger         }
533ca3e8d8Dave Plauger         else
534ca3e8d8Dave Plauger         if (s->strm->avail_in == 0) {
535ca3e8d8Dave Plauger            break;
536ca3e8d8Dave Plauger         }
537ca3e8d8Dave Plauger      }
538ca3e8d8Dave Plauger
539ca3e8d8Dave Plauger   }
540ca3e8d8Dave Plauger
541ca3e8d8Dave Plauger   return progress_in || progress_out;
542ca3e8d8Dave Plauger}
543ca3e8d8Dave Plauger
544ca3e8d8Dave Plauger
545ca3e8d8Dave Plauger/*---------------------------------------------------*/
546ca3e8d8Dave Plaugerint BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
547ca3e8d8Dave Plauger{
548ca3e8d8Dave Plauger   Bool progress;
549ca3e8d8Dave Plauger   EState* s;
550ca3e8d8Dave Plauger   if (strm == NULL) return BZ_PARAM_ERROR;
551ca3e8d8Dave Plauger   s = strm->state;
552ca3e8d8Dave Plauger   if (s == NULL) return BZ_PARAM_ERROR;
553ca3e8d8Dave Plauger   if (s->strm != strm) return BZ_PARAM_ERROR;
554ca3e8d8Dave Plauger
555ca3e8d8Dave Plauger   preswitch:
556ca3e8d8Dave Plauger   switch (s->mode) {
557ca3e8d8Dave Plauger
558ca3e8d8Dave Plauger      case BZ_M_IDLE:
559ca3e8d8Dave Plauger         return BZ_SEQUENCE_ERROR;
560ca3e8d8Dave Plauger
561ca3e8d8Dave Plauger      case BZ_M_RUNNING:
562ca3e8d8Dave Plauger         if (action == BZ_RUN) {
563ca3e8d8Dave Plauger            progress = handle_compress ( strm );
564ca3e8d8Dave Plauger            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
565238e18aToomas Soome         }
566ca3e8d8Dave Plauger         else
567ca3e8d8Dave Plauger	 if (action == BZ_FLUSH) {
568ca3e8d8Dave Plauger            s->avail_in_expect = strm->avail_in;
569ca3e8d8Dave Plauger            s->mode = BZ_M_FLUSHING;
570ca3e8d8Dave Plauger            goto preswitch;
571ca3e8d8Dave Plauger         }
572ca3e8d8Dave Plauger         else
573ca3e8d8Dave Plauger         if (action == BZ_FINISH) {
574ca3e8d8Dave Plauger            s->avail_in_expect = strm->avail_in;
575ca3e8d8Dave Plauger            s->mode = BZ_M_FINISHING;
576ca3e8d8Dave Plauger            goto preswitch;
577ca3e8d8Dave Plauger         }
578238e18aToomas Soome         else
579ca3e8d8Dave Plauger            return BZ_PARAM_ERROR;
580ca3e8d8Dave Plauger
581ca3e8d8Dave Plauger      case BZ_M_FLUSHING:
582ca3e8d8Dave Plauger         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
583238e18aToomas Soome         if (s->avail_in_expect != s->strm->avail_in)
584ca3e8d8Dave Plauger            return BZ_SEQUENCE_ERROR;
585ca3e8d8Dave Plauger         progress = handle_compress ( strm );
586ca3e8d8Dave Plauger         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
587ca3e8d8Dave Plauger             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
588ca3e8d8Dave Plauger         s->mode = BZ_M_RUNNING;
589ca3e8d8Dave Plauger         return BZ_RUN_OK;
590ca3e8d8Dave Plauger
591ca3e8d8Dave Plauger      case BZ_M_FINISHING:
592ca3e8d8Dave Plauger         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
593238e18aToomas Soome         if (s->avail_in_expect != s->strm->avail_in)
594ca3e8d8Dave Plauger            return BZ_SEQUENCE_ERROR;
595ca3e8d8Dave Plauger         progress = handle_compress ( strm );
596ca3e8d8Dave Plauger         if (!progress) return BZ_SEQUENCE_ERROR;
597ca3e8d8Dave Plauger         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
598ca3e8d8Dave Plauger             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
599ca3e8d8Dave Plauger         s->mode = BZ_M_IDLE;
600ca3e8d8Dave Plauger         return BZ_STREAM_END;
601ca3e8d8Dave Plauger   }
602ca3e8d8Dave Plauger   return BZ_OK; /*--not reached--*/
603ca3e8d8Dave Plauger}
604ca3e8d8Dave Plauger
605ca3e8d8Dave Plauger
606ca3e8d8Dave Plauger/*---------------------------------------------------*/
607ca3e8d8Dave Plaugerint BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
608ca3e8d8Dave Plauger{
609ca3e8d8Dave Plauger   EState* s;
610ca3e8d8Dave Plauger   if (strm == NULL) return BZ_PARAM_ERROR;
611ca3e8d8Dave Plauger   s = strm->state;
612ca3e8d8Dave Plauger   if (s == NULL) return BZ_PARAM_ERROR;
613ca3e8d8Dave Plauger   if (s->strm != strm) return BZ_PARAM_ERROR;
614ca3e8d8Dave Plauger
615ca3e8d8Dave Plauger   if (s->arr1 != NULL) BZFREE(s->arr1);
616ca3e8d8Dave Plauger   if (s->arr2 != NULL) BZFREE(s->arr2);
617ca3e8d8Dave Plauger   if (s->ftab != NULL) BZFREE(s->ftab);
618ca3e8d8Dave Plauger   BZFREE(strm->state);
619ca3e8d8Dave Plauger
620238e18aToomas Soome   strm->state = NULL;
621ca3e8d8Dave Plauger
622ca3e8d8Dave Plauger   return BZ_OK;
623ca3e8d8Dave Plauger}
624ca3e8d8Dave Plauger
625fce880dToomas Soome#endif /* BZ_NO_COMPRESS */
626ca3e8d8Dave Plauger
627ca3e8d8Dave Plauger/*---------------------------------------------------*/
628ca3e8d8Dave Plauger/*--- Decompression stuff                         ---*/
629ca3e8d8Dave Plauger/*---------------------------------------------------*/
630ca3e8d8Dave Plauger
631ca3e8d8Dave Plauger/*---------------------------------------------------*/
632238e18aToomas Soomeint BZ_API(BZ2_bzDecompressInit)
633238e18aToomas Soome                     ( bz_stream* strm,
634ca3e8d8Dave Plauger                       int        verbosity,
635ca3e8d8Dave Plauger                       int        small )
636ca3e8d8Dave Plauger{
637ca3e8d8Dave Plauger   DState* s;
638ca3e8d8Dave Plauger
639ca3e8d8Dave Plauger   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
640ca3e8d8Dave Plauger
641ca3e8d8Dave Plauger   if (strm == NULL) return BZ_PARAM_ERROR;
642ca3e8d8Dave Plauger   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
643ca3e8d8Dave Plauger   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
644ca3e8d8Dave Plauger
645ca3e8d8Dave Plauger   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
646ca3e8d8Dave Plauger   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
647ca3e8d8Dave Plauger
648ca3e8d8Dave Plauger   s = BZALLOC( sizeof(DState) );
649ca3e8d8Dave Plauger   if (s == NULL) return BZ_MEM_ERROR;
650ca3e8d8Dave Plauger   s->strm                  = strm;
651ca3e8d8Dave Plauger   strm->state              = s;
652ca3e8d8Dave Plauger   s->state                 = BZ_X_MAGIC_1;
653ca3e8d8Dave Plauger   s->bsLive                = 0;
654ca3e8d8Dave Plauger   s->bsBuff                = 0;
655ca3e8d8Dave Plauger   s->calculatedCombinedCRC = 0;
656ca3e8d8Dave Plauger   strm->total_in_lo32      = 0;
657ca3e8d8Dave Plauger   strm->total_in_hi32      = 0;
658ca3e8d8Dave Plauger   strm->total_out_lo32     = 0;
659ca3e8d8Dave Plauger   strm->total_out_hi32     = 0;
660ca3e8d8Dave Plauger   s->smallDecompress       = (Bool)small;
661ca3e8d8Dave Plauger   s->ll4                   = NULL;
662ca3e8d8Dave Plauger   s->ll16                  = NULL;
663ca3e8d8Dave Plauger   s->tt                    = NULL;
664ca3e8d8Dave Plauger   s->currBlockNo           = 0;
665ca3e8d8Dave Plauger   s->verbosity             = verbosity;
666ca3e8d8Dave Plauger
667ca3e8d8Dave Plauger   return BZ_OK;
668ca3e8d8Dave Plauger}
669ca3e8d8Dave Plauger
670fce880dToomas Soome/*---------------------------------------------------*/
671fce880dToomas Soome/*
672fce880dToomas Soome * added to allow reuse of bz_stream without malloc/free
673fce880dToomas Soome */
674fce880dToomas Soomeint BZ_API(BZ2_bzDecompressReset) ( bz_stream* strm )
675fce880dToomas Soome{
6767957da4John Levon   DState* s;
677fce880dToomas Soome
678fce880dToomas Soome   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
679fce880dToomas Soome
680fce880dToomas Soome   if (strm == NULL) return BZ_PARAM_ERROR;
681fce880dToomas Soome
6827957da4John Levon   s = strm->state;
683fce880dToomas Soome   s->strm                  = strm;
684fce880dToomas Soome
685fce880dToomas Soome   s->state                 = BZ_X_MAGIC_1;
686fce880dToomas Soome   s->bsLive                = 0;
687fce880dToomas Soome   s->bsBuff                = 0;
688fce880dToomas Soome   s->calculatedCombinedCRC = 0;
689fce880dToomas Soome   strm->total_in_lo32      = 0;
690fce880dToomas Soome   strm->total_in_hi32      = 0;
691fce880dToomas Soome   strm->total_out_lo32     = 0;
692fce880dToomas Soome   strm->total_out_hi32     = 0;
693fce880dToomas Soome
694fce880dToomas Soome   s->ll4                   = NULL;
695fce880dToomas Soome   s->ll16                  = NULL;
696fce880dToomas Soome   s->tt                    = NULL;
697fce880dToomas Soome   s->currBlockNo           = 0;
698fce880dToomas Soome
699fce880dToomas Soome
700fce880dToomas Soome   return BZ_OK;
701fce880dToomas Soome}
702fce880dToomas Soome
703ca3e8d8Dave Plauger
704ca3e8d8Dave Plauger/*---------------------------------------------------*/
705ca3e8d8Dave Plauger/* Return  True iff data corruption is discovered.
706ca3e8d8Dave Plauger   Returns False if there is no problem.
707ca3e8d8Dave Plauger*/
708ca3e8d8Dave Plaugerstatic
709ca3e8d8Dave PlaugerBool unRLE_obuf_to_output_FAST ( DState* s )
710ca3e8d8Dave Plauger{
711ca3e8d8Dave Plauger   UChar k1;
712ca3e8d8Dave Plauger
713ca3e8d8Dave Plauger   if (s->blockRandomised) {
714ca3e8d8Dave Plauger
715ca3e8d8Dave Plauger      while (True) {
716ca3e8d8Dave Plauger         /* try to finish existing run */
717ca3e8d8Dave Plauger         while (True) {
718ca3e8d8Dave Plauger            if (s->strm->avail_out == 0) return False;
719ca3e8d8Dave Plauger            if (s->state_out_len == 0) break;
720ca3e8d8Dave Plauger            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
721ca3e8d8Dave Plauger            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
722ca3e8d8Dave Plauger            s->state_out_len--;
723ca3e8d8Dave Plauger            s->strm->next_out++;
724ca3e8d8Dave Plauger            s->strm->avail_out--;
725ca3e8d8Dave Plauger            s->strm->total_out_lo32++;
726ca3e8d8Dave Plauger            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
727ca3e8d8Dave Plauger         }
728ca3e8d8Dave Plauger
729ca3e8d8Dave Plauger         /* can a new run be started? */
730ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) return False;
731238e18aToomas Soome
732ca3e8d8Dave Plauger         /* Only caused by corrupt data stream? */
733ca3e8d8Dave Plauger         if (s->nblock_used > s->save_nblock+1)
734ca3e8d8Dave Plauger            return True;
735238e18aToomas Soome
736ca3e8d8Dave Plauger         s->state_out_len = 1;
737ca3e8d8Dave Plauger         s->state_out_ch = s->k0;
738238e18aToomas Soome         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
739ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
740ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
741ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
742238e18aToomas Soome
743ca3e8d8Dave Plauger         s->state_out_len = 2;
744238e18aToomas Soome         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
745ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
746ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
747ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
748238e18aToomas Soome
749ca3e8d8Dave Plauger         s->state_out_len = 3;
750238e18aToomas Soome         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
751ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
752ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
753ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
754238e18aToomas Soome
755238e18aToomas Soome         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
756ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
757ca3e8d8Dave Plauger         s->state_out_len = ((Int32)k1) + 4;
758238e18aToomas Soome         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
759ca3e8d8Dave Plauger         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
760ca3e8d8Dave Plauger      }
761ca3e8d8Dave Plauger
762ca3e8d8Dave Plauger   } else {
763ca3e8d8Dave Plauger
764ca3e8d8Dave Plauger      /* restore */
765ca3e8d8Dave Plauger      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
766ca3e8d8Dave Plauger      UChar         c_state_out_ch       = s->state_out_ch;
767ca3e8d8Dave Plauger      Int32         c_state_out_len      = s->state_out_len;
768ca3e8d8Dave Plauger      Int32         c_nblock_used        = s->nblock_used;
769ca3e8d8Dave Plauger      Int32         c_k0                 = s->k0;
770ca3e8d8Dave Plauger      UInt32*       c_tt                 = s->tt;
771ca3e8d8Dave Plauger      UInt32        c_tPos               = s->tPos;
772ca3e8d8Dave Plauger      char*         cs_next_out          = s->strm->next_out;
773ca3e8d8Dave Plauger      unsigned int  cs_avail_out         = s->strm->avail_out;
774ca3e8d8Dave Plauger      Int32         ro_blockSize100k     = s->blockSize100k;
775ca3e8d8Dave Plauger      /* end restore */
776ca3e8d8Dave Plauger
777ca3e8d8Dave Plauger      UInt32       avail_out_INIT = cs_avail_out;
778ca3e8d8Dave Plauger      Int32        s_save_nblockPP = s->save_nblock+1;
779ca3e8d8Dave Plauger      unsigned int total_out_lo32_old;
780ca3e8d8Dave Plauger
781ca3e8d8Dave Plauger      while (True) {
782ca3e8d8Dave Plauger
783ca3e8d8Dave Plauger         /* try to finish existing run */
784ca3e8d8Dave Plauger         if (c_state_out_len > 0) {
785ca3e8d8Dave Plauger            while (True) {
786ca3e8d8Dave Plauger               if (cs_avail_out == 0) goto return_notr;
787ca3e8d8Dave Plauger               if (c_state_out_len == 1) break;
788ca3e8d8Dave Plauger               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
789ca3e8d8Dave Plauger               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
790ca3e8d8Dave Plauger               c_state_out_len--;
791ca3e8d8Dave Plauger               cs_next_out++;
792ca3e8d8Dave Plauger               cs_avail_out--;
793ca3e8d8Dave Plauger            }
794ca3e8d8Dave Plauger            s_state_out_len_eq_one:
795ca3e8d8Dave Plauger            {
796238e18aToomas Soome               if (cs_avail_out == 0) {
797ca3e8d8Dave Plauger                  c_state_out_len = 1; goto return_notr;
798ca3e8d8Dave Plauger               };
799ca3e8d8Dave Plauger               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
800ca3e8d8Dave Plauger               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
801ca3e8d8Dave Plauger               cs_next_out++;
802ca3e8d8Dave Plauger               cs_avail_out--;
803ca3e8d8Dave Plauger            }
804238e18aToomas Soome         }
805ca3e8d8Dave Plauger         /* Only caused by corrupt data stream? */
806ca3e8d8Dave Plauger         if (c_nblock_used > s_save_nblockPP)
807ca3e8d8Dave Plauger            return True;
808ca3e8d8Dave Plauger
809ca3e8d8Dave Plauger         /* can a new run be started? */
810ca3e8d8Dave Plauger         if (c_nblock_used == s_save_nblockPP) {
811ca3e8d8Dave Plauger            c_state_out_len = 0; goto return_notr;
812238e18aToomas Soome         };
813ca3e8d8Dave Plauger         c_state_out_ch = c_k0;
814238e18aToomas Soome         BZ_GET_FAST_C(k1);
815238e18aToomas Soome	 c_nblock_used++;
816238e18aToomas Soome         if (k1 != c_k0) {
817238e18aToomas Soome            c_k0 = k1; goto s_state_out_len_eq_one;
818ca3e8d8Dave Plauger         };
819238e18aToomas Soome         if (c_nblock_used == s_save_nblockPP)
820ca3e8d8Dave Plauger            goto s_state_out_len_eq_one;
821238e18aToomas Soome
822ca3e8d8Dave Plauger         c_state_out_len = 2;
823238e18aToomas Soome         BZ_GET_FAST_C(k1);
824238e18aToomas Soome	 c_nblock_used++;
825ca3e8d8Dave Plauger         if (c_nblock_used == s_save_nblockPP) continue;
826ca3e8d8Dave Plauger         if (k1 != c_k0) { c_k0 = k1; continue; };
827238e18aToomas Soome
828ca3e8d8Dave Plauger         c_state_out_len = 3;
829238e18aToomas Soome         BZ_GET_FAST_C(k1);
830238e18aToomas Soome	 c_nblock_used++;
831ca3e8d8Dave Plauger         if (c_nblock_used == s_save_nblockPP) continue;
832ca3e8d8Dave Plauger         if (k1 != c_k0) { c_k0 = k1; continue; };
833238e18aToomas Soome
834238e18aToomas Soome         BZ_GET_FAST_C(k1);
835238e18aToomas Soome	 c_nblock_used++;
836ca3e8d8Dave Plauger         c_state_out_len = ((Int32)k1) + 4;
837ca3e8d8Dave Plauger         BZ_GET_FAST_C(c_k0); c_nblock_used++;
838ca3e8d8Dave Plauger      }
839ca3e8d8Dave Plauger
840ca3e8d8Dave Plauger      return_notr:
841ca3e8d8Dave Plauger      total_out_lo32_old = s->strm->total_out_lo32;
842ca3e8d8Dave Plauger      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
843ca3e8d8Dave Plauger      if (s->strm->total_out_lo32 < total_out_lo32_old)
844ca3e8d8Dave Plauger         s->strm->total_out_hi32++;
845ca3e8d8Dave Plauger
846ca3e8d8Dave Plauger      /* save */
847ca3e8d8Dave Plauger      s->calculatedBlockCRC = c_calculatedBlockCRC;
848ca3e8d8Dave Plauger      s->state_out_ch       = c_state_out_ch;
849ca3e8d8Dave Plauger      s->state_out_len      = c_state_out_len;
850ca3e8d8Dave Plauger      s->nblock_used        = c_nblock_used;
851ca3e8d8Dave Plauger      s->k0                 = c_k0;
852ca3e8d8Dave Plauger      s->tt                 = c_tt;
853ca3e8d8Dave Plauger      s->tPos               = c_tPos;
854ca3e8d8Dave Plauger      s->strm->next_out     = cs_next_out;
855ca3e8d8Dave Plauger      s->strm->avail_out    = cs_avail_out;
856ca3e8d8Dave Plauger      /* end save */
857ca3e8d8Dave Plauger   }
858ca3e8d8Dave Plauger   return False;
859ca3e8d8Dave Plauger}
860ca3e8d8Dave Plauger
861ca3e8d8Dave Plauger
862ca3e8d8Dave Plauger
863ca3e8d8Dave Plauger/*---------------------------------------------------*/
864ca3e8d8Dave Plauger__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
865ca3e8d8Dave Plauger{
866ca3e8d8Dave Plauger   Int32 nb, na, mid;
867ca3e8d8Dave Plauger   nb = 0;
868ca3e8d8Dave Plauger   na = 256;
869ca3e8d8Dave Plauger   do {
870ca3e8d8Dave Plauger      mid = (nb + na) >> 1;
871ca3e8d8Dave Plauger      if (indx >= cftab[mid]) nb = mid; else na = mid;
872ca3e8d8Dave Plauger   }
873ca3e8d8Dave Plauger   while (na - nb != 1);
874ca3e8d8Dave Plauger   return nb;
875ca3e8d8Dave Plauger}
876ca3e8d8Dave Plauger
877ca3e8d8Dave Plauger
878ca3e8d8Dave Plauger/*---------------------------------------------------*/
879ca3e8d8Dave Plauger/* Return  True iff data corruption is discovered.
880ca3e8d8Dave Plauger   Returns False if there is no problem.
881ca3e8d8Dave Plauger*/
882ca3e8d8Dave Plaugerstatic
883ca3e8d8Dave PlaugerBool unRLE_obuf_to_output_SMALL ( DState* s )
884ca3e8d8Dave Plauger{
885ca3e8d8Dave Plauger   UChar k1;
886ca3e8d8Dave Plauger
887ca3e8d8Dave Plauger   if (s->blockRandomised) {
888ca3e8d8Dave Plauger
889ca3e8d8Dave Plauger      while (True) {
890ca3e8d8Dave Plauger         /* try to finish existing run */
891ca3e8d8Dave Plauger         while (True) {
892ca3e8d8Dave Plauger            if (s->strm->avail_out == 0) return False;
893ca3e8d8Dave Plauger            if (s->state_out_len == 0) break;
894ca3e8d8Dave Plauger            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
895ca3e8d8Dave Plauger            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
896ca3e8d8Dave Plauger            s->state_out_len--;
897ca3e8d8Dave Plauger            s->strm->next_out++;
898ca3e8d8Dave Plauger            s->strm->avail_out--;
899ca3e8d8Dave Plauger            s->strm->total_out_lo32++;
900ca3e8d8Dave Plauger            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
901ca3e8d8Dave Plauger         }
902238e18aToomas Soome
903ca3e8d8Dave Plauger         /* can a new run be started? */
904ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) return False;
905ca3e8d8Dave Plauger
906ca3e8d8Dave Plauger         /* Only caused by corrupt data stream? */
907ca3e8d8Dave Plauger         if (s->nblock_used > s->save_nblock+1)
908ca3e8d8Dave Plauger            return True;
909238e18aToomas Soome
910ca3e8d8Dave Plauger         s->state_out_len = 1;
911ca3e8d8Dave Plauger         s->state_out_ch = s->k0;
912238e18aToomas Soome         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
913ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
914ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
915ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
916238e18aToomas Soome
917ca3e8d8Dave Plauger         s->state_out_len = 2;
918238e18aToomas Soome         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
919ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
920ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
921ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
922238e18aToomas Soome
923ca3e8d8Dave Plauger         s->state_out_len = 3;
924238e18aToomas Soome         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
925ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
926ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
927ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
928238e18aToomas Soome
929238e18aToomas Soome         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
930ca3e8d8Dave Plauger         k1 ^= BZ_RAND_MASK; s->nblock_used++;
931ca3e8d8Dave Plauger         s->state_out_len = ((Int32)k1) + 4;
932238e18aToomas Soome         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
933ca3e8d8Dave Plauger         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
934ca3e8d8Dave Plauger      }
935ca3e8d8Dave Plauger
936ca3e8d8Dave Plauger   } else {
937ca3e8d8Dave Plauger
938ca3e8d8Dave Plauger      while (True) {
939ca3e8d8Dave Plauger         /* try to finish existing run */
940ca3e8d8Dave Plauger         while (True) {
941ca3e8d8Dave Plauger            if (s->strm->avail_out == 0) return False;
942ca3e8d8Dave Plauger            if (s->state_out_len == 0) break;
943ca3e8d8Dave Plauger            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
944ca3e8d8Dave Plauger            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
945ca3e8d8Dave Plauger            s->state_out_len--;
946ca3e8d8Dave Plauger            s->strm->next_out++;
947ca3e8d8Dave Plauger            s->strm->avail_out--;
948ca3e8d8Dave Plauger            s->strm->total_out_lo32++;
949ca3e8d8Dave Plauger            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
950ca3e8d8Dave Plauger         }
951238e18aToomas Soome
952ca3e8d8Dave Plauger         /* can a new run be started? */
953ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) return False;
954ca3e8d8Dave Plauger
955ca3e8d8Dave Plauger         /* Only caused by corrupt data stream? */
956ca3e8d8Dave Plauger         if (s->nblock_used > s->save_nblock+1)
957ca3e8d8Dave Plauger            return True;
958238e18aToomas Soome
959ca3e8d8Dave Plauger         s->state_out_len = 1;
960ca3e8d8Dave Plauger         s->state_out_ch = s->k0;
961238e18aToomas Soome         BZ_GET_SMALL(k1);
962238e18aToomas Soome	 s->nblock_used++;
963ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
964ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
965238e18aToomas Soome
966ca3e8d8Dave Plauger         s->state_out_len = 2;
967238e18aToomas Soome         BZ_GET_SMALL(k1);
968238e18aToomas Soome	 s->nblock_used++;
969ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
970ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
971238e18aToomas Soome
972ca3e8d8Dave Plauger         s->state_out_len = 3;
973238e18aToomas Soome         BZ_GET_SMALL(k1);
974238e18aToomas Soome	 s->nblock_used++;
975ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1) continue;
976ca3e8d8Dave Plauger         if (k1 != s->k0) { s->k0 = k1; continue; };
977238e18aToomas Soome
978238e18aToomas Soome         BZ_GET_SMALL(k1);
979238e18aToomas Soome	 s->nblock_used++;
980ca3e8d8Dave Plauger         s->state_out_len = ((Int32)k1) + 4;
981ca3e8d8Dave Plauger         BZ_GET_SMALL(s->k0); s->nblock_used++;
982ca3e8d8Dave Plauger      }
983ca3e8d8Dave Plauger
984ca3e8d8Dave Plauger   }
985ca3e8d8Dave Plauger}
986ca3e8d8Dave Plauger
987ca3e8d8Dave Plauger
988ca3e8d8Dave Plauger/*---------------------------------------------------*/
989ca3e8d8Dave Plaugerint BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
990ca3e8d8Dave Plauger{
991ca3e8d8Dave Plauger   Bool    corrupt;
992ca3e8d8Dave Plauger   DState* s;
993ca3e8d8Dave Plauger   if (strm == NULL) return BZ_PARAM_ERROR;
994ca3e8d8Dave Plauger   s = strm->state;
995ca3e8d8Dave Plauger   if (s == NULL) return BZ_PARAM_ERROR;
996ca3e8d8Dave Plauger   if (s->strm != strm) return BZ_PARAM_ERROR;
997ca3e8d8Dave Plauger
998ca3e8d8Dave Plauger   while (True) {
999ca3e8d8Dave Plauger      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
1000ca3e8d8Dave Plauger      if (s->state == BZ_X_OUTPUT) {
1001ca3e8d8Dave Plauger         if (s->smallDecompress)
1002ca3e8d8Dave Plauger            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
1003ca3e8d8Dave Plauger            corrupt = unRLE_obuf_to_output_FAST  ( s );
1004ca3e8d8Dave Plauger         if (corrupt) return BZ_DATA_ERROR;
1005ca3e8d8Dave Plauger         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
1006ca3e8d8Dave Plauger            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
1007238e18aToomas Soome            if (s->verbosity >= 3)
1008238e18aToomas Soome               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
1009ca3e8d8Dave Plauger                          s->calculatedBlockCRC );
1010ca3e8d8Dave Plauger            if (s->verbosity >= 2) VPrintf0 ( "]" );
1011ca3e8d8Dave Plauger            if (s->calculatedBlockCRC != s->storedBlockCRC)
1012ca3e8d8Dave Plauger               return BZ_DATA_ERROR;
1013238e18aToomas Soome            s->calculatedCombinedCRC
1014238e18aToomas Soome               = (s->calculatedCombinedCRC << 1) |
1015ca3e8d8Dave Plauger                    (s->calculatedCombinedCRC >> 31);
1016ca3e8d8Dave Plauger            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
1017ca3e8d8Dave Plauger            s->state = BZ_X_BLKHDR_1;
1018ca3e8d8Dave Plauger         } else {
1019ca3e8d8Dave Plauger            return BZ_OK;
1020ca3e8d8Dave Plauger         }
1021ca3e8d8Dave Plauger      }
1022ca3e8d8Dave Plauger      if (s->state >= BZ_X_MAGIC_1) {
1023ca3e8d8Dave Plauger         Int32 r = BZ2_decompress ( s );
1024ca3e8d8Dave Plauger         if (r == BZ_STREAM_END) {
1025ca3e8d8Dave Plauger            if (s->verbosity >= 3)
1026238e18aToomas Soome               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
1027ca3e8d8Dave Plauger                          s->storedCombinedCRC, s->calculatedCombinedCRC );
1028ca3e8d8Dave Plauger            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
1029ca3e8d8Dave Plauger               return BZ_DATA_ERROR;
1030ca3e8d8Dave Plauger            return r;
1031ca3e8d8Dave Plauger         }
1032ca3e8d8Dave Plauger         if (s->state != BZ_X_OUTPUT) return r;
1033ca3e8d8Dave Plauger      }
1034ca3e8d8Dave Plauger   }
1035ca3e8d8Dave Plauger
1036ca3e8d8Dave Plauger#if 0
1037ca3e8d8Dave Plauger   AssertH ( 0, 6001 );
1038ca3e8d8Dave Plauger
1039ca3e8d8Dave Plauger   return 0;  /*NOTREACHED*/
1040ca3e8d8Dave Plauger#endif
1041ca3e8d8Dave Plauger}
1042ca3e8d8Dave Plauger
1043ca3e8d8Dave Plauger
1044ca3e8d8Dave Plauger/*---------------------------------------------------*/
1045ca3e8d8Dave Plaugerint BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
1046ca3e8d8Dave Plauger{
1047ca3e8d8Dave Plauger   DState* s;
1048ca3e8d8Dave Plauger   if (strm == NULL) return BZ_PARAM_ERROR;
1049ca3e8d8Dave Plauger   s = strm->state;
1050ca3e8d8Dave Plauger   if (s == NULL) return BZ_PARAM_ERROR;
1051ca3e8d8Dave Plauger   if (s->strm != strm) return BZ_PARAM_ERROR;
1052ca3e8d8Dave Plauger
1053ca3e8d8Dave Plauger   if (s->tt   != NULL) BZFREE(s->tt);
1054ca3e8d8Dave Plauger   if (s->ll16 != NULL) BZFREE(s->ll16);
1055ca3e8d8Dave Plauger   if (s->ll4  != NULL) BZFREE(s->ll4);
1056ca3e8d8Dave Plauger
1057ca3e8d8Dave Plauger   BZFREE(strm->state);
1058ca3e8d8Dave Plauger   strm->state = NULL;
1059ca3e8d8Dave Plauger
1060ca3e8d8Dave Plauger   return BZ_OK;
1061ca3e8d8Dave Plauger}
1062ca3e8d8Dave Plauger
1063fce880dToomas Soome#ifndef BZ_NO_COMPRESS
1064ca3e8d8Dave Plauger
1065ca3e8d8Dave Plauger#ifndef BZ_NO_STDIO
1066ca3e8d8Dave Plauger/*---------------------------------------------------*/
1067ca3e8d8Dave Plauger/*--- File I/O stuff                              ---*/
1068ca3e8d8Dave Plauger/*---------------------------------------------------*/
1069ca3e8d8Dave Plauger
1070ca3e8d8Dave Plauger#define BZ_SETERR(eee)                    \
1071ca3e8d8Dave Plauger{                                         \
1072ca3e8d8Dave Plauger   if (bzerror != NULL) *bzerror = eee;   \
1073ca3e8d8Dave Plauger   if (bzf != NULL) bzf->lastErr = eee;   \
1074ca3e8d8Dave Plauger}
1075ca3e8d8Dave Plauger
1076238e18aToomas Soometypedef
1077ca3e8d8Dave Plauger   struct {
1078ca3e8d8Dave Plauger      FILE*     handle;
1079ca3e8d8Dave Plauger      Char      buf[BZ_MAX_UNUSED];
1080ca3e8d8Dave Plauger      Int32     bufN;
1081ca3e8d8Dave Plauger      Bool      writing;
1082ca3e8d8Dave Plauger      bz_stream strm;
1083ca3e8d8Dave Plauger      Int32     lastErr;
1084ca3e8d8Dave Plauger      Bool      initialisedOk;
1085ca3e8d8Dave Plauger   }
1086ca3e8d8Dave Plauger   bzFile;
1087ca3e8d8Dave Plauger
1088ca3e8d8Dave Plauger
1089ca3e8d8Dave Plauger/*---------------------------------------------*/
1090ca3e8d8Dave Plaugerstatic Bool myfeof ( FILE* f )
1091ca3e8d8Dave Plauger{
1092ca3e8d8Dave Plauger   Int32 c = fgetc ( f );
1093ca3e8d8Dave Plauger   if (c == EOF) return True;
1094ca3e8d8Dave Plauger   ungetc ( c, f );
1095ca3e8d8Dave Plauger   return False;
1096ca3e8d8Dave Plauger}
1097ca3e8d8Dave Plauger
1098ca3e8d8Dave Plauger
1099ca3e8d8Dave Plauger/*---------------------------------------------------*/
1100238e18aToomas SoomeBZFILE* BZ_API(BZ2_bzWriteOpen)
1101238e18aToomas Soome                    ( int*  bzerror,
1102238e18aToomas Soome                      FILE* f,
1103238e18aToomas Soome                      int   blockSize100k,
1104ca3e8d8Dave Plauger                      int   verbosity,
1105ca3e8d8Dave Plauger                      int   workFactor )
1106ca3e8d8Dave Plauger{
1107ca3e8d8Dave Plauger   Int32   ret;
1108ca3e8d8Dave Plauger   bzFile* bzf = NULL;
1109ca3e8d8Dave Plauger
1110ca3e8d8Dave Plauger   BZ_SETERR(BZ_OK);
1111ca3e8d8Dave Plauger
1112ca3e8d8Dave Plauger   if (f == NULL ||
1113ca3e8d8Dave Plauger       (blockSize100k < 1 || blockSize100k > 9) ||
1114ca3e8d8Dave Plauger       (workFactor < 0 || workFactor > 250) ||
1115ca3e8d8Dave Plauger       (verbosity < 0 || verbosity > 4))
1116ca3e8d8Dave Plauger      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1117ca3e8d8Dave Plauger