Coverage Report

Created: 2026-03-31 06:05

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