~ubuntu-branches/ubuntu/wily/ruby-ferret/wily

« back to all changes in this revision

Viewing changes to ext/BZLIB_bzlib.c

  • Committer: Package Import Robot
  • Author(s): Cédric Boutillier
  • Date: 2013-11-25 01:09:16 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20131125010916-4wj3pwzcjjp8b9et
Tags: 0.11.8.5-1
* Imported Upstream version 0.11.8.5
* debian/control:
  + remove obsolete DM-Upload-Allowed flag
  + use canonical URI in Vcs-* fields
  + update my email address
  + bump Standards-Version to 3.9.5 (no changes needed)
  + drop transitional packages
* Remove single-debian-patch option
* Drop fix_compatibility_with_minitest.patch and
  block_variables_have_local_scopes.patch (applied upstream)
* Remove indications that the source has been repacked (not true anymore)
* Remove embedded copy of bzlib when cleaning instead of repacking
* Add copyright notice for the embedded copy of bzlib
* Install RELEASE_NOTES as documentation

Show diffs side-by-side

added added

removed removed

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