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