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