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