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