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