Coverage Report

Created: 2023-11-30 06:31

/src/bzip2/bzlib.c
Line
Count
Source (jump to first uncovered line)
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
27.3k
{
93
27.3k
   if (sizeof(int)   != 4) return 0;
94
27.3k
   if (sizeof(short) != 2) return 0;
95
27.3k
   if (sizeof(char)  != 1) return 0;
96
27.3k
   return 1;
97
27.3k
}
98
99
100
/*---------------------------------------------------*/
101
static
102
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
103
79.5k
{
104
79.5k
   void* v = malloc ( items * size );
105
79.5k
   return v;
106
79.5k
}
107
108
static
109
void default_bzfree ( void* opaque, void* addr )
110
79.5k
{
111
79.5k
   if (addr != NULL) free ( addr );
112
79.5k
}
113
114
115
/*---------------------------------------------------*/
116
static
117
void prepare_new_block ( EState* s )
118
14.4k
{
119
14.4k
   Int32 i;
120
14.4k
   s->nblock = 0;
121
14.4k
   s->numZ = 0;
122
14.4k
   s->state_out_pos = 0;
123
14.4k
   BZ_INITIALISE_CRC ( s->blockCRC );
124
3.71M
   for (i = 0; i < 256; i++) s->inUse[i] = False;
125
14.4k
   s->blockNo++;
126
14.4k
}
127
128
129
/*---------------------------------------------------*/
130
static
131
void init_RL ( EState* s )
132
24.6k
{
133
24.6k
   s->state_in_ch  = 256;
134
24.6k
   s->state_in_len = 0;
135
24.6k
}
136
137
138
static
139
Bool isempty_RL ( EState* s )
140
45.4k
{
141
45.4k
   if (s->state_in_ch < 256 && s->state_in_len > 0)
142
960
      return False; else
143
44.4k
      return True;
144
45.4k
}
145
146
147
/*---------------------------------------------------*/
148
int BZ_API(BZ2_bzCompressInit) 
149
                    ( bz_stream* strm, 
150
                     int        blockSize100k,
151
                     int        verbosity,
152
                     int        workFactor )
153
12.3k
{
154
12.3k
   Int32   n;
155
12.3k
   EState* s;
156
157
12.3k
   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
158
159
12.3k
   if (strm == NULL || 
160
12.3k
       blockSize100k < 1 || blockSize100k > 9 ||
161
12.3k
       workFactor < 0 || workFactor > 250)
162
0
     return BZ_PARAM_ERROR;
163
164
12.3k
   if (workFactor == 0) workFactor = 30;
165
12.3k
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
166
12.3k
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
167
168
12.3k
   s = BZALLOC( sizeof(EState) );
169
12.3k
   if (s == NULL) return BZ_MEM_ERROR;
170
12.3k
   s->strm = strm;
171
172
12.3k
   s->arr1 = NULL;
173
12.3k
   s->arr2 = NULL;
174
12.3k
   s->ftab = NULL;
175
176
12.3k
   n       = 100000 * blockSize100k;
177
12.3k
   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
178
12.3k
   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
179
12.3k
   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
180
181
12.3k
   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
12.3k
   s->blockNo           = 0;
190
12.3k
   s->state             = BZ_S_INPUT;
191
12.3k
   s->mode              = BZ_M_RUNNING;
192
12.3k
   s->combinedCRC       = 0;
193
12.3k
   s->blockSize100k     = blockSize100k;
194
12.3k
   s->nblockMAX         = 100000 * blockSize100k - 19;
195
12.3k
   s->verbosity         = verbosity;
196
12.3k
   s->workFactor        = workFactor;
197
198
12.3k
   s->block             = (UChar*)s->arr2;
199
12.3k
   s->mtfv              = (UInt16*)s->arr1;
200
12.3k
   s->zbits             = NULL;
201
12.3k
   s->ptr               = (UInt32*)s->arr1;
202
203
12.3k
   strm->state          = s;
204
12.3k
   strm->total_in_lo32  = 0;
205
12.3k
   strm->total_in_hi32  = 0;
206
12.3k
   strm->total_out_lo32 = 0;
207
12.3k
   strm->total_out_hi32 = 0;
208
12.3k
   init_RL ( s );
209
12.3k
   prepare_new_block ( s );
210
12.3k
   return BZ_OK;
211
12.3k
}
212
213
214
/*---------------------------------------------------*/
215
static
216
void add_pair_to_block ( EState* s )
217
125M
{
218
125M
   Int32 i;
219
125M
   UChar ch = (UChar)(s->state_in_ch);
220
607M
   for (i = 0; i < s->state_in_len; i++) {
221
481M
      BZ_UPDATE_CRC( s->blockCRC, ch );
222
481M
   }
223
125M
   s->inUse[s->state_in_ch] = True;
224
125M
   switch (s->state_in_len) {
225
8.52k
      case 1:
226
8.52k
         s->block[s->nblock] = (UChar)ch; s->nblock++;
227
8.52k
         break;
228
16.2M
      case 2:
229
16.2M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
230
16.2M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
231
16.2M
         break;
232
3.34M
      case 3:
233
3.34M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
234
3.34M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
235
3.34M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
236
3.34M
         break;
237
106M
      default:
238
106M
         s->inUse[s->state_in_len-4] = True;
239
106M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
240
106M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
241
106M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
242
106M
         s->block[s->nblock] = (UChar)ch; s->nblock++;
243
106M
         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
244
106M
         s->nblock++;
245
106M
         break;
246
125M
   }
247
125M
}
248
249
250
/*---------------------------------------------------*/
251
static
252
void flush_RL ( EState* s )
253
12.3k
{
254
12.3k
   if (s->state_in_ch < 256) add_pair_to_block ( s );
255
12.3k
   init_RL ( s );
256
12.3k
}
257
258
259
/*---------------------------------------------------*/
260
939M
#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
261
939M
{                                                 \
262
939M
   UInt32 zchh = (UInt32)(zchh0);                 \
263
939M
   /*-- fast track the common case --*/           \
264
939M
   if (zchh != zs->state_in_ch &&                 \
265
939M
       zs->state_in_len == 1) {                   \
266
457M
      UChar ch = (UChar)(zs->state_in_ch);        \
267
457M
      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
268
457M
      zs->inUse[zs->state_in_ch] = True;          \
269
457M
      zs->block[zs->nblock] = (UChar)ch;          \
270
457M
      zs->nblock++;                               \
271
457M
      zs->state_in_ch = zchh;                     \
272
457M
   }                                              \
273
939M
   else                                           \
274
939M
   /*-- general, uncommon cases --*/              \
275
939M
   if (zchh != zs->state_in_ch ||                 \
276
481M
      zs->state_in_len == 255) {                  \
277
125M
      if (zs->state_in_ch < 256)                  \
278
125M
         add_pair_to_block ( zs );                \
279
125M
      zs->state_in_ch = zchh;                     \
280
125M
      zs->state_in_len = 1;                       \
281
355M
   } else {                                       \
282
355M
      zs->state_in_len++;                         \
283
355M
   }                                              \
284
939M
}
285
286
287
/*---------------------------------------------------*/
288
static
289
Bool copy_input_until_stop ( EState* s )
290
22.2k
{
291
22.2k
   Bool progress_in = False;
292
293
22.2k
   if (s->mode == BZ_M_RUNNING) {
294
295
      /*-- fast track the common case --*/
296
610M
      while (True) {
297
         /*-- block full? --*/
298
610M
         if (s->nblock >= s->nblockMAX) break;
299
         /*-- no input? --*/
300
610M
         if (s->strm->avail_in == 0) break;
301
610M
         progress_in = True;
302
610M
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
303
610M
         s->strm->next_in++;
304
610M
         s->strm->avail_in--;
305
610M
         s->strm->total_in_lo32++;
306
610M
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
307
610M
      }
308
309
14.0k
   } else {
310
311
      /*-- general, uncommon case --*/
312
328M
      while (True) {
313
         /*-- block full? --*/
314
328M
         if (s->nblock >= s->nblockMAX) break;
315
         /*-- no input? --*/
316
328M
         if (s->strm->avail_in == 0) break;
317
         /*-- flush/finish end? --*/
318
328M
         if (s->avail_in_expect == 0) break;
319
328M
         progress_in = True;
320
328M
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
321
328M
         s->strm->next_in++;
322
328M
         s->strm->avail_in--;
323
328M
         s->strm->total_in_lo32++;
324
328M
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
325
328M
         s->avail_in_expect--;
326
328M
      }
327
14.0k
   }
328
22.2k
   return progress_in;
329
22.2k
}
330
331
332
/*---------------------------------------------------*/
333
static
334
Bool copy_output_until_stop ( EState* s )
335
50.1k
{
336
50.1k
   Bool progress_out = False;
337
338
320M
   while (True) {
339
340
      /*-- no output space? --*/
341
320M
      if (s->strm->avail_out == 0) break;
342
343
      /*-- block done? --*/
344
320M
      if (s->state_out_pos >= s->numZ) break;
345
346
320M
      progress_out = True;
347
320M
      *(s->strm->next_out) = s->zbits[s->state_out_pos];
348
320M
      s->state_out_pos++;
349
320M
      s->strm->avail_out--;
350
320M
      s->strm->next_out++;
351
320M
      s->strm->total_out_lo32++;
352
320M
      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
353
320M
   }
354
355
50.1k
   return progress_out;
356
50.1k
}
357
358
359
/*---------------------------------------------------*/
360
static
361
Bool handle_compress ( bz_stream* strm )
362
55.7k
{
363
55.7k
   Bool progress_in  = False;
364
55.7k
   Bool progress_out = False;
365
55.7k
   EState* s = strm->state;
366
   
367
70.1k
   while (True) {
368
369
70.1k
      if (s->state == BZ_S_OUTPUT) {
370
50.1k
         progress_out |= copy_output_until_stop ( s );
371
50.1k
         if (s->state_out_pos < s->numZ) break;
372
14.4k
         if (s->mode == BZ_M_FINISHING && 
373
14.4k
             s->avail_in_expect == 0 &&
374
14.4k
             isempty_RL(s)) break;
375
2.12k
         prepare_new_block ( s );
376
2.12k
         s->state = BZ_S_INPUT;
377
2.12k
         if (s->mode == BZ_M_FLUSHING && 
378
2.12k
             s->avail_in_expect == 0 &&
379
2.12k
             isempty_RL(s)) break;
380
2.12k
      }
381
382
22.2k
      if (s->state == BZ_S_INPUT) {
383
22.2k
         progress_in |= copy_input_until_stop ( s );
384
22.2k
         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
385
12.3k
            flush_RL ( s );
386
12.3k
            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
387
12.3k
            s->state = BZ_S_OUTPUT;
388
12.3k
         }
389
9.88k
         else
390
9.88k
         if (s->nblock >= s->nblockMAX) {
391
2.12k
            BZ2_compressBlock ( s, False );
392
2.12k
            s->state = BZ_S_OUTPUT;
393
2.12k
         }
394
7.75k
         else
395
7.75k
         if (s->strm->avail_in == 0) {
396
7.75k
            break;
397
7.75k
         }
398
22.2k
      }
399
400
22.2k
   }
401
402
55.7k
   return progress_in || progress_out;
403
55.7k
}
404
405
406
/*---------------------------------------------------*/
407
int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
408
55.7k
{
409
55.7k
   Bool progress;
410
55.7k
   EState* s;
411
55.7k
   if (strm == NULL) return BZ_PARAM_ERROR;
412
55.7k
   s = strm->state;
413
55.7k
   if (s == NULL) return BZ_PARAM_ERROR;
414
55.7k
   if (s->strm != strm) return BZ_PARAM_ERROR;
415
416
68.0k
   preswitch:
417
68.0k
   switch (s->mode) {
418
419
0
      case BZ_M_IDLE:
420
0
         return BZ_SEQUENCE_ERROR;
421
422
35.0k
      case BZ_M_RUNNING:
423
35.0k
         if (action == BZ_RUN) {
424
22.6k
            progress = handle_compress ( strm );
425
22.6k
            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
426
22.6k
         } 
427
12.3k
         else
428
12.3k
   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
12.3k
         else
434
12.3k
         if (action == BZ_FINISH) {
435
12.3k
            s->avail_in_expect = strm->avail_in;
436
12.3k
            s->mode = BZ_M_FINISHING;
437
12.3k
            goto preswitch;
438
12.3k
         }
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.0k
      case BZ_M_FINISHING:
453
33.0k
         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
454
33.0k
         if (s->avail_in_expect != s->strm->avail_in) 
455
0
            return BZ_SEQUENCE_ERROR;
456
33.0k
         progress = handle_compress ( strm );
457
33.0k
         if (!progress) return BZ_SEQUENCE_ERROR;
458
33.0k
         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
459
33.0k
             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
460
12.3k
         s->mode = BZ_M_IDLE;
461
12.3k
         return BZ_STREAM_END;
462
68.0k
   }
463
0
   return BZ_OK; /*--not reached--*/
464
68.0k
}
465
466
467
/*---------------------------------------------------*/
468
int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
469
12.3k
{
470
12.3k
   EState* s;
471
12.3k
   if (strm == NULL) return BZ_PARAM_ERROR;
472
12.3k
   s = strm->state;
473
12.3k
   if (s == NULL) return BZ_PARAM_ERROR;
474
12.3k
   if (s->strm != strm) return BZ_PARAM_ERROR;
475
476
12.3k
   if (s->arr1 != NULL) BZFREE(s->arr1);
477
12.3k
   if (s->arr2 != NULL) BZFREE(s->arr2);
478
12.3k
   if (s->ftab != NULL) BZFREE(s->ftab);
479
12.3k
   BZFREE(strm->state);
480
481
12.3k
   strm->state = NULL;   
482
483
12.3k
   return BZ_OK;
484
12.3k
}
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
15.0k
{
497
15.0k
   DState* s;
498
499
15.0k
   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
500
501
15.0k
   if (strm == NULL) return BZ_PARAM_ERROR;
502
15.0k
   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
503
15.0k
   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
504
505
15.0k
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
506
15.0k
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
507
508
15.0k
   s = BZALLOC( sizeof(DState) );
509
15.0k
   if (s == NULL) return BZ_MEM_ERROR;
510
15.0k
   s->strm                  = strm;
511
15.0k
   strm->state              = s;
512
15.0k
   s->state                 = BZ_X_MAGIC_1;
513
15.0k
   s->bsLive                = 0;
514
15.0k
   s->bsBuff                = 0;
515
15.0k
   s->calculatedCombinedCRC = 0;
516
15.0k
   strm->total_in_lo32      = 0;
517
15.0k
   strm->total_in_hi32      = 0;
518
15.0k
   strm->total_out_lo32     = 0;
519
15.0k
   strm->total_out_hi32     = 0;
520
15.0k
   s->smallDecompress       = (Bool)small;
521
15.0k
   s->ll4                   = NULL;
522
15.0k
   s->ll16                  = NULL;
523
15.0k
   s->tt                    = NULL;
524
15.0k
   s->currBlockNo           = 0;
525
15.0k
   s->verbosity             = verbosity;
526
527
15.0k
   return BZ_OK;
528
15.0k
}
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
185k
{
538
185k
   UChar k1;
539
540
185k
   if (s->blockRandomised) {
541
542
5.42M
      while (True) {
543
         /* try to finish existing run */
544
26.0M
         while (True) {
545
26.0M
            if (s->strm->avail_out == 0) return False;
546
26.0M
            if (s->state_out_len == 0) break;
547
20.6M
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
548
20.6M
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
549
20.6M
            s->state_out_len--;
550
20.6M
            s->strm->next_out++;
551
20.6M
            s->strm->avail_out--;
552
20.6M
            s->strm->total_out_lo32++;
553
20.6M
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
554
20.6M
         }
555
556
         /* can a new run be started? */
557
5.42M
         if (s->nblock_used == s->save_nblock+1) return False;
558
               
559
         /* Only caused by corrupt data stream? */
560
5.41M
         if (s->nblock_used > s->save_nblock+1)
561
1
            return True;
562
   
563
5.41M
         s->state_out_len = 1;
564
5.41M
         s->state_out_ch = s->k0;
565
5.41M
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
566
5.41M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
567
5.41M
         if (s->nblock_used == s->save_nblock+1) continue;
568
5.41M
         if (k1 != s->k0) { s->k0 = k1; continue; };
569
   
570
4.55M
         s->state_out_len = 2;
571
4.55M
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
572
4.55M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
573
4.55M
         if (s->nblock_used == s->save_nblock+1) continue;
574
4.55M
         if (k1 != s->k0) { s->k0 = k1; continue; };
575
   
576
4.29M
         s->state_out_len = 3;
577
4.29M
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
578
4.29M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
579
4.29M
         if (s->nblock_used == s->save_nblock+1) continue;
580
4.29M
         if (k1 != s->k0) { s->k0 = k1; continue; };
581
   
582
4.08M
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
583
4.08M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
584
4.08M
         s->state_out_len = ((Int32)k1) + 4;
585
4.08M
         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
586
4.08M
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
587
4.08M
      }
588
589
178k
   } else {
590
591
      /* restore */
592
178k
      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
593
178k
      UChar         c_state_out_ch       = s->state_out_ch;
594
178k
      Int32         c_state_out_len      = s->state_out_len;
595
178k
      Int32         c_nblock_used        = s->nblock_used;
596
178k
      Int32         c_k0                 = s->k0;
597
178k
      UInt32*       c_tt                 = s->tt;
598
178k
      UInt32        c_tPos               = s->tPos;
599
178k
      char*         cs_next_out          = s->strm->next_out;
600
178k
      unsigned int  cs_avail_out         = s->strm->avail_out;
601
178k
      Int32         ro_blockSize100k     = s->blockSize100k;
602
      /* end restore */
603
604
178k
      UInt32       avail_out_INIT = cs_avail_out;
605
178k
      Int32        s_save_nblockPP = s->save_nblock+1;
606
178k
      unsigned int total_out_lo32_old;
607
608
79.6M
      while (True) {
609
610
         /* try to finish existing run */
611
79.6M
         if (c_state_out_len > 0) {
612
312M
            while (True) {
613
312M
               if (cs_avail_out == 0) goto return_notr;
614
312M
               if (c_state_out_len == 1) break;
615
232M
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
616
232M
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
617
232M
               c_state_out_len--;
618
232M
               cs_next_out++;
619
232M
               cs_avail_out--;
620
232M
            }
621
376M
            s_state_out_len_eq_one:
622
376M
            {
623
376M
               if (cs_avail_out == 0) { 
624
36.8k
                  c_state_out_len = 1; goto return_notr;
625
376M
               };
626
376M
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
627
376M
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
628
376M
               cs_next_out++;
629
376M
               cs_avail_out--;
630
376M
            }
631
376M
         }   
632
         /* Only caused by corrupt data stream? */
633
376M
         if (c_nblock_used > s_save_nblockPP)
634
3
            return True;
635
636
         /* can a new run be started? */
637
376M
         if (c_nblock_used == s_save_nblockPP) {
638
95.8k
            c_state_out_len = 0; goto return_notr;
639
376M
         };   
640
376M
         c_state_out_ch = c_k0;
641
376M
         BZ_GET_FAST_C(k1); c_nblock_used++;
642
376M
         if (k1 != c_k0) { 
643
296M
            c_k0 = k1; goto s_state_out_len_eq_one; 
644
296M
         };
645
79.4M
         if (c_nblock_used == s_save_nblockPP) 
646
1.02k
            goto s_state_out_len_eq_one;
647
   
648
79.4M
         c_state_out_len = 2;
649
79.4M
         BZ_GET_FAST_C(k1); c_nblock_used++;
650
79.4M
         if (c_nblock_used == s_save_nblockPP) continue;
651
79.4M
         if (k1 != c_k0) { c_k0 = k1; continue; };
652
   
653
70.0M
         c_state_out_len = 3;
654
70.0M
         BZ_GET_FAST_C(k1); c_nblock_used++;
655
70.0M
         if (c_nblock_used == s_save_nblockPP) continue;
656
69.9M
         if (k1 != c_k0) { c_k0 = k1; continue; };
657
   
658
67.1M
         BZ_GET_FAST_C(k1); c_nblock_used++;
659
67.1M
         c_state_out_len = ((Int32)k1) + 4;
660
67.1M
         BZ_GET_FAST_C(c_k0); c_nblock_used++;
661
67.1M
      }
662
663
178k
      return_notr:
664
178k
      total_out_lo32_old = s->strm->total_out_lo32;
665
178k
      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
666
178k
      if (s->strm->total_out_lo32 < total_out_lo32_old)
667
0
         s->strm->total_out_hi32++;
668
669
      /* save */
670
178k
      s->calculatedBlockCRC = c_calculatedBlockCRC;
671
178k
      s->state_out_ch       = c_state_out_ch;
672
178k
      s->state_out_len      = c_state_out_len;
673
178k
      s->nblock_used        = c_nblock_used;
674
178k
      s->k0                 = c_k0;
675
178k
      s->tt                 = c_tt;
676
178k
      s->tPos               = c_tPos;
677
178k
      s->strm->next_out     = cs_next_out;
678
178k
      s->strm->avail_out    = cs_avail_out;
679
      /* end save */
680
178k
   }
681
178k
   return False;
682
185k
}
683
684
685
686
/*---------------------------------------------------*/
687
__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
688
188M
{
689
188M
   Int32 nb, na, mid;
690
188M
   nb = 0;
691
188M
   na = 256;
692
1.50G
   do {
693
1.50G
      mid = (nb + na) >> 1;
694
1.50G
      if (indx >= cftab[mid]) nb = mid; else na = mid;
695
1.50G
   }
696
1.50G
   while (na - nb != 1);
697
188M
   return nb;
698
188M
}
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
107k
{
708
107k
   UChar k1;
709
710
107k
   if (s->blockRandomised) {
711
712
5.31M
      while (True) {
713
         /* try to finish existing run */
714
23.8M
         while (True) {
715
23.8M
            if (s->strm->avail_out == 0) return False;
716
23.8M
            if (s->state_out_len == 0) break;
717
18.5M
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
718
18.5M
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
719
18.5M
            s->state_out_len--;
720
18.5M
            s->strm->next_out++;
721
18.5M
            s->strm->avail_out--;
722
18.5M
            s->strm->total_out_lo32++;
723
18.5M
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
724
18.5M
         }
725
   
726
         /* can a new run be started? */
727
5.31M
         if (s->nblock_used == s->save_nblock+1) return False;
728
729
         /* Only caused by corrupt data stream? */
730
5.30M
         if (s->nblock_used > s->save_nblock+1)
731
3
            return True;
732
   
733
5.30M
         s->state_out_len = 1;
734
5.30M
         s->state_out_ch = s->k0;
735
5.30M
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
736
5.30M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
737
5.30M
         if (s->nblock_used == s->save_nblock+1) continue;
738
5.30M
         if (k1 != s->k0) { s->k0 = k1; continue; };
739
   
740
4.31M
         s->state_out_len = 2;
741
4.31M
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
742
4.31M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
743
4.31M
         if (s->nblock_used == s->save_nblock+1) continue;
744
4.31M
         if (k1 != s->k0) { s->k0 = k1; continue; };
745
   
746
3.97M
         s->state_out_len = 3;
747
3.97M
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
748
3.97M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
749
3.97M
         if (s->nblock_used == s->save_nblock+1) continue;
750
3.97M
         if (k1 != s->k0) { s->k0 = k1; continue; };
751
   
752
3.68M
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
753
3.68M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
754
3.68M
         s->state_out_len = ((Int32)k1) + 4;
755
3.68M
         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
756
3.68M
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
757
3.68M
      }
758
759
98.0k
   } else {
760
761
96.9M
      while (True) {
762
         /* try to finish existing run */
763
252M
         while (True) {
764
252M
            if (s->strm->avail_out == 0) return False;
765
252M
            if (s->state_out_len == 0) break;
766
155M
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
767
155M
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
768
155M
            s->state_out_len--;
769
155M
            s->strm->next_out++;
770
155M
            s->strm->avail_out--;
771
155M
            s->strm->total_out_lo32++;
772
155M
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
773
155M
         }
774
   
775
         /* can a new run be started? */
776
96.9M
         if (s->nblock_used == s->save_nblock+1) return False;
777
778
         /* Only caused by corrupt data stream? */
779
96.8M
         if (s->nblock_used > s->save_nblock+1)
780
6
            return True;
781
   
782
96.8M
         s->state_out_len = 1;
783
96.8M
         s->state_out_ch = s->k0;
784
96.8M
         BZ_GET_SMALL(k1); s->nblock_used++;
785
96.8M
         if (s->nblock_used == s->save_nblock+1) continue;
786
96.8M
         if (k1 != s->k0) { s->k0 = k1; continue; };
787
   
788
19.0M
         s->state_out_len = 2;
789
19.0M
         BZ_GET_SMALL(k1); s->nblock_used++;
790
19.0M
         if (s->nblock_used == s->save_nblock+1) continue;
791
19.0M
         if (k1 != s->k0) { s->k0 = k1; continue; };
792
   
793
17.7M
         s->state_out_len = 3;
794
17.7M
         BZ_GET_SMALL(k1); s->nblock_used++;
795
17.7M
         if (s->nblock_used == s->save_nblock+1) continue;
796
17.6M
         if (k1 != s->k0) { s->k0 = k1; continue; };
797
   
798
16.9M
         BZ_GET_SMALL(k1); s->nblock_used++;
799
16.9M
         s->state_out_len = ((Int32)k1) + 4;
800
16.9M
         BZ_GET_SMALL(s->k0); s->nblock_used++;
801
16.9M
      }
802
803
98.0k
   }
804
107k
}
805
806
807
/*---------------------------------------------------*/
808
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
809
123k
{
810
123k
   Bool    corrupt;
811
123k
   DState* s;
812
123k
   if (strm == NULL) return BZ_PARAM_ERROR;
813
123k
   s = strm->state;
814
123k
   if (s == NULL) return BZ_PARAM_ERROR;
815
123k
   if (s->strm != strm) return BZ_PARAM_ERROR;
816
817
334k
   while (True) {
818
334k
      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
819
334k
      if (s->state == BZ_X_OUTPUT) {
820
293k
         if (s->smallDecompress)
821
107k
            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
822
185k
            corrupt = unRLE_obuf_to_output_FAST  ( s );
823
293k
         if (corrupt) return BZ_DATA_ERROR;
824
293k
         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
825
210k
            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
826
210k
            if (s->verbosity >= 3) 
827
0
               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
828
210k
                          s->calculatedBlockCRC );
829
210k
            if (s->verbosity >= 2) VPrintf0 ( "]" );
830
210k
            if (s->calculatedBlockCRC != s->storedBlockCRC)
831
264
               return BZ_DATA_ERROR;
832
210k
            s->calculatedCombinedCRC 
833
210k
               = (s->calculatedCombinedCRC << 1) | 
834
210k
                    (s->calculatedCombinedCRC >> 31);
835
210k
            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
836
210k
            s->state = BZ_X_BLKHDR_1;
837
210k
         } else {
838
82.7k
            return BZ_OK;
839
82.7k
         }
840
293k
      }
841
251k
      if (s->state >= BZ_X_MAGIC_1) {
842
251k
         Int32 r = BZ2_decompress ( s );
843
251k
         if (r == BZ_STREAM_END) {
844
8.98k
            if (s->verbosity >= 3)
845
0
               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
846
8.98k
                          s->storedCombinedCRC, s->calculatedCombinedCRC );
847
8.98k
            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
848
107
               return BZ_DATA_ERROR;
849
8.88k
            return r;
850
8.98k
         }
851
242k
         if (s->state != BZ_X_OUTPUT) return r;
852
242k
      }
853
251k
   }
854
855
0
   AssertH ( 0, 6001 );
856
857
0
   return 0;  /*NOTREACHED*/
858
123k
}
859
860
861
/*---------------------------------------------------*/
862
int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
863
15.0k
{
864
15.0k
   DState* s;
865
15.0k
   if (strm == NULL) return BZ_PARAM_ERROR;
866
15.0k
   s = strm->state;
867
15.0k
   if (s == NULL) return BZ_PARAM_ERROR;
868
15.0k
   if (s->strm != strm) return BZ_PARAM_ERROR;
869
870
15.0k
   if (s->tt   != NULL) BZFREE(s->tt);
871
15.0k
   if (s->ll16 != NULL) BZFREE(s->ll16);
872
15.0k
   if (s->ll4  != NULL) BZFREE(s->ll4);
873
874
15.0k
   BZFREE(strm->state);
875
15.0k
   strm->state = NULL;
876
877
15.0k
   return BZ_OK;
878
15.0k
}
879
880
881
#ifndef BZ_NO_STDIO
882
/*---------------------------------------------------*/
883
/*--- File I/O stuff                              ---*/
884
/*---------------------------------------------------*/
885
886
245k
#define BZ_SETERR(eee)                    \
887
245k
{                                         \
888
245k
   if (bzerror != NULL) *bzerror = eee;   \
889
245k
   if (bzf != NULL) bzf->lastErr = eee;   \
890
245k
}
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
145k
{
908
145k
   Int32 c = fgetc ( f );
909
145k
   if (c == EOF) return True;
910
72.6k
   ungetc ( c, f );
911
72.6k
   return False;
912
145k
}
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
7.80k
{
923
7.80k
   Int32   ret;
924
7.80k
   bzFile* bzf = NULL;
925
926
7.80k
   BZ_SETERR(BZ_OK);
927
928
7.80k
   if (f == NULL ||
929
7.80k
       (blockSize100k < 1 || blockSize100k > 9) ||
930
7.80k
       (workFactor < 0 || workFactor > 250) ||
931
7.80k
       (verbosity < 0 || verbosity > 4))
932
7.80k
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
933
934
7.80k
   if (ferror(f))
935
7.80k
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
936
937
7.80k
   bzf = malloc ( sizeof(bzFile) );
938
7.80k
   if (bzf == NULL)
939
7.80k
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
940
941
7.80k
   BZ_SETERR(BZ_OK);
942
7.80k
   bzf->initialisedOk = False;
943
7.80k
   bzf->bufN          = 0;
944
7.80k
   bzf->handle        = f;
945
7.80k
   bzf->writing       = True;
946
7.80k
   bzf->strm.bzalloc  = NULL;
947
7.80k
   bzf->strm.bzfree   = NULL;
948
7.80k
   bzf->strm.opaque   = NULL;
949
950
7.80k
   if (workFactor == 0) workFactor = 30;
951
7.80k
   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
952
7.80k
                              verbosity, workFactor );
953
7.80k
   if (ret != BZ_OK)
954
7.80k
      { BZ_SETERR(ret); free(bzf); return NULL; };
955
956
7.80k
   bzf->strm.avail_in = 0;
957
7.80k
   bzf->initialisedOk = True;
958
7.80k
   return bzf;   
959
7.80k
}
960
961
962
963
/*---------------------------------------------------*/
964
void BZ_API(BZ2_bzWrite)
965
             ( int*    bzerror, 
966
               BZFILE* b, 
967
               void*   buf, 
968
               int     len )
969
7.80k
{
970
7.80k
   Int32 n, n2, ret;
971
7.80k
   bzFile* bzf = (bzFile*)b;
972
973
7.80k
   BZ_SETERR(BZ_OK);
974
7.80k
   if (bzf == NULL || buf == NULL || len < 0)
975
7.80k
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
976
7.80k
   if (!(bzf->writing))
977
7.80k
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
978
7.80k
   if (ferror(bzf->handle))
979
7.80k
      { BZ_SETERR(BZ_IO_ERROR); return; };
980
981
7.80k
   if (len == 0)
982
7.80k
      { BZ_SETERR(BZ_OK); return; };
983
984
7.80k
   bzf->strm.avail_in = len;
985
7.80k
   bzf->strm.next_in  = buf;
986
987
22.6k
   while (True) {
988
22.6k
      bzf->strm.avail_out = BZ_MAX_UNUSED;
989
22.6k
      bzf->strm.next_out = bzf->buf;
990
22.6k
      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
991
22.6k
      if (ret != BZ_RUN_OK)
992
22.6k
         { BZ_SETERR(ret); return; };
993
994
22.6k
      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
995
15.3k
         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
996
15.3k
         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
997
15.3k
                       n, bzf->handle );
998
15.3k
         if (n != n2 || ferror(bzf->handle))
999
15.3k
            { BZ_SETERR(BZ_IO_ERROR); return; };
1000
15.3k
      }
1001
1002
22.6k
      if (bzf->strm.avail_in == 0)
1003
14.8k
         { BZ_SETERR(BZ_OK); return; };
1004
14.8k
   }
1005
7.80k
}
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
7.80k
{
1030
7.80k
   Int32   n, n2, ret;
1031
7.80k
   bzFile* bzf = (bzFile*)b;
1032
1033
7.80k
   if (bzf == NULL)
1034
7.80k
      { BZ_SETERR(BZ_OK); return; };
1035
7.80k
   if (!(bzf->writing))
1036
7.80k
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1037
7.80k
   if (ferror(bzf->handle))
1038
7.80k
      { BZ_SETERR(BZ_IO_ERROR); return; };
1039
1040
7.80k
   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
1041
7.80k
   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1042
7.80k
   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1043
7.80k
   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
1044
1045
7.80k
   if ((!abandon) && bzf->lastErr == BZ_OK) {
1046
28.5k
      while (True) {
1047
28.5k
         bzf->strm.avail_out = BZ_MAX_UNUSED;
1048
28.5k
         bzf->strm.next_out = bzf->buf;
1049
28.5k
         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
1050
28.5k
         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
1051
28.5k
            { BZ_SETERR(ret); return; };
1052
1053
28.5k
         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1054
28.5k
            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1055
28.5k
            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
1056
28.5k
                          n, bzf->handle );
1057
28.5k
            if (n != n2 || ferror(bzf->handle))
1058
28.5k
               { BZ_SETERR(BZ_IO_ERROR); return; };
1059
28.5k
         }
1060
1061
28.5k
         if (ret == BZ_STREAM_END) break;
1062
28.5k
      }
1063
7.80k
   }
1064
1065
7.80k
   if ( !abandon && !ferror ( bzf->handle ) ) {
1066
7.80k
      fflush ( bzf->handle );
1067
7.80k
      if (ferror(bzf->handle))
1068
7.80k
         { BZ_SETERR(BZ_IO_ERROR); return; };
1069
7.80k
   }
1070
1071
7.80k
   if (nbytes_in_lo32 != NULL)
1072
7.80k
      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
1073
7.80k
   if (nbytes_in_hi32 != NULL)
1074
7.80k
      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
1075
7.80k
   if (nbytes_out_lo32 != NULL)
1076
7.80k
      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
1077
7.80k
   if (nbytes_out_hi32 != NULL)
1078
7.80k
      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
1079
1080
7.80k
   BZ_SETERR(BZ_OK);
1081
7.80k
   BZ2_bzCompressEnd ( &(bzf->strm) );
1082
7.80k
   free ( bzf );
1083
7.80k
}
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
7.80k
{
1095
7.80k
   bzFile* bzf = NULL;
1096
7.80k
   int     ret;
1097
1098
7.80k
   BZ_SETERR(BZ_OK);
1099
1100
7.80k
   if (f == NULL || 
1101
7.80k
       (small != 0 && small != 1) ||
1102
7.80k
       (verbosity < 0 || verbosity > 4) ||
1103
7.80k
       (unused == NULL && nUnused != 0) ||
1104
7.80k
       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
1105
7.80k
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1106
1107
7.80k
   if (ferror(f))
1108
7.80k
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
1109
1110
7.80k
   bzf = malloc ( sizeof(bzFile) );
1111
7.80k
   if (bzf == NULL) 
1112
7.80k
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1113
1114
7.80k
   BZ_SETERR(BZ_OK);
1115
1116
7.80k
   bzf->initialisedOk = False;
1117
7.80k
   bzf->handle        = f;
1118
7.80k
   bzf->bufN          = 0;
1119
7.80k
   bzf->writing       = False;
1120
7.80k
   bzf->strm.bzalloc  = NULL;
1121
7.80k
   bzf->strm.bzfree   = NULL;
1122
7.80k
   bzf->strm.opaque   = NULL;
1123
   
1124
7.80k
   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
7.80k
   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1131
7.80k
   if (ret != BZ_OK)
1132
7.80k
      { BZ_SETERR(ret); free(bzf); return NULL; };
1133
1134
7.80k
   bzf->strm.avail_in = bzf->bufN;
1135
7.80k
   bzf->strm.next_in  = bzf->buf;
1136
1137
7.80k
   bzf->initialisedOk = True;
1138
7.80k
   return bzf;   
1139
7.80k
}
1140
1141
1142
/*---------------------------------------------------*/
1143
void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1144
7.80k
{
1145
7.80k
   bzFile* bzf = (bzFile*)b;
1146
1147
7.80k
   BZ_SETERR(BZ_OK);
1148
7.80k
   if (bzf == NULL)
1149
7.80k
      { BZ_SETERR(BZ_OK); return; };
1150
1151
7.80k
   if (bzf->writing)
1152
7.80k
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1153
1154
7.80k
   if (bzf->initialisedOk)
1155
7.80k
      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
1156
7.80k
   free ( bzf );
1157
7.80k
}
1158
1159
1160
/*---------------------------------------------------*/
1161
int BZ_API(BZ2_bzRead) 
1162
           ( int*    bzerror, 
1163
             BZFILE* b, 
1164
             void*   buf, 
1165
             int     len )
1166
89.9k
{
1167
89.9k
   Int32   n, ret;
1168
89.9k
   bzFile* bzf = (bzFile*)b;
1169
1170
89.9k
   BZ_SETERR(BZ_OK);
1171
1172
89.9k
   if (bzf == NULL || buf == NULL || len < 0)
1173
89.9k
      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
1174
1175
89.9k
   if (bzf->writing)
1176
89.9k
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
1177
1178
89.9k
   if (len == 0)
1179
89.9k
      { BZ_SETERR(BZ_OK); return 0; };
1180
1181
89.9k
   bzf->strm.avail_out = len;
1182
89.9k
   bzf->strm.next_out = buf;
1183
1184
115k
   while (True) {
1185
1186
115k
      if (ferror(bzf->handle)) 
1187
115k
         { BZ_SETERR(BZ_IO_ERROR); return 0; };
1188
1189
115k
      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
1190
30.1k
         n = fread ( bzf->buf, sizeof(UChar), 
1191
30.1k
                     BZ_MAX_UNUSED, bzf->handle );
1192
30.1k
         if (ferror(bzf->handle))
1193
30.1k
            { BZ_SETERR(BZ_IO_ERROR); return 0; };
1194
30.1k
         bzf->bufN = n;
1195
30.1k
         bzf->strm.avail_in = bzf->bufN;
1196
30.1k
         bzf->strm.next_in = bzf->buf;
1197
30.1k
      }
1198
1199
115k
      ret = BZ2_bzDecompress ( &(bzf->strm) );
1200
1201
115k
      if (ret != BZ_OK && ret != BZ_STREAM_END)
1202
115k
         { BZ_SETERR(ret); return 0; };
1203
1204
115k
      if (ret == BZ_OK && myfeof(bzf->handle) && 
1205
115k
          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
1206
112k
         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
1207
1208
112k
      if (ret == BZ_STREAM_END)
1209
4.34k
         { BZ_SETERR(BZ_STREAM_END);
1210
107k
           return len - bzf->strm.avail_out; };
1211
107k
      if (bzf->strm.avail_out == 0)
1212
82.1k
         { BZ_SETERR(BZ_OK); return len; };
1213
      
1214
25.8k
   }
1215
1216
0
   return 0; /*not reached*/
1217
89.9k
}
1218
1219
1220
/*---------------------------------------------------*/
1221
void BZ_API(BZ2_bzReadGetUnused) 
1222
                     ( int*    bzerror, 
1223
                       BZFILE* b, 
1224
                       void**  unused, 
1225
                       int*    nUnused )
1226
3.45k
{
1227
3.45k
   bzFile* bzf = (bzFile*)b;
1228
3.45k
   if (bzf == NULL)
1229
3.45k
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
1230
3.45k
   if (bzf->lastErr != BZ_STREAM_END)
1231
3.45k
      { 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
4.53k
{
1256
4.53k
   bz_stream strm;
1257
4.53k
   int ret;
1258
1259
4.53k
   if (dest == NULL || destLen == NULL || 
1260
4.53k
       source == NULL ||
1261
4.53k
       blockSize100k < 1 || blockSize100k > 9 ||
1262
4.53k
       verbosity < 0 || verbosity > 4 ||
1263
4.53k
       workFactor < 0 || workFactor > 250) 
1264
0
      return BZ_PARAM_ERROR;
1265
1266
4.53k
   if (workFactor == 0) workFactor = 30;
1267
4.53k
   strm.bzalloc = NULL;
1268
4.53k
   strm.bzfree = NULL;
1269
4.53k
   strm.opaque = NULL;
1270
4.53k
   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
1271
4.53k
                              verbosity, workFactor );
1272
4.53k
   if (ret != BZ_OK) return ret;
1273
1274
4.53k
   strm.next_in = source;
1275
4.53k
   strm.next_out = dest;
1276
4.53k
   strm.avail_in = sourceLen;
1277
4.53k
   strm.avail_out = *destLen;
1278
1279
4.53k
   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1280
4.53k
   if (ret == BZ_FINISH_OK) goto output_overflow;
1281
4.53k
   if (ret != BZ_STREAM_END) goto errhandler;
1282
1283
   /* normal termination */
1284
4.53k
   *destLen -= strm.avail_out;   
1285
4.53k
   BZ2_bzCompressEnd ( &strm );
1286
4.53k
   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
4.53k
}
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
7.23k
{
1307
7.23k
   bz_stream strm;
1308
7.23k
   int ret;
1309
1310
7.23k
   if (dest == NULL || destLen == NULL || 
1311
7.23k
       source == NULL ||
1312
7.23k
       (small != 0 && small != 1) ||
1313
7.23k
       verbosity < 0 || verbosity > 4) 
1314
0
          return BZ_PARAM_ERROR;
1315
1316
7.23k
   strm.bzalloc = NULL;
1317
7.23k
   strm.bzfree = NULL;
1318
7.23k
   strm.opaque = NULL;
1319
7.23k
   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1320
7.23k
   if (ret != BZ_OK) return ret;
1321
1322
7.23k
   strm.next_in = source;
1323
7.23k
   strm.next_out = dest;
1324
7.23k
   strm.avail_in = sourceLen;
1325
7.23k
   strm.avail_out = *destLen;
1326
1327
7.23k
   ret = BZ2_bzDecompress ( &strm );
1328
7.23k
   if (ret == BZ_OK) goto output_overflow_or_eof;
1329
5.48k
   if (ret != BZ_STREAM_END) goto errhandler;
1330
1331
   /* normal termination */
1332
4.53k
   *destLen -= strm.avail_out;
1333
4.53k
   BZ2_bzDecompressEnd ( &strm );
1334
4.53k
   return BZ_OK;
1335
1336
1.74k
   output_overflow_or_eof:
1337
1.74k
   if (strm.avail_out > 0) {
1338
1.13k
      BZ2_bzDecompressEnd ( &strm );
1339
1.13k
      return BZ_UNEXPECTED_EOF;
1340
1.13k
   } else {
1341
615
      BZ2_bzDecompressEnd ( &strm );
1342
615
      return BZ_OUTBUFF_FULL;
1343
615
   };      
1344
1345
954
   errhandler:
1346
954
   BZ2_bzDecompressEnd ( &strm );
1347
954
   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
7.80k
{
1368
7.80k
   return BZ_VERSION;
1369
7.80k
}
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
7.80k
{
1389
7.80k
   int    bzerr;
1390
7.80k
   char   unused[BZ_MAX_UNUSED];
1391
7.80k
   int    blockSize100k = 9;
1392
7.80k
   int    writing       = 0;
1393
7.80k
   char   mode2[10]     = "";
1394
7.80k
   FILE   *fp           = NULL;
1395
7.80k
   BZFILE *bzfp         = NULL;
1396
7.80k
   int    verbosity     = 0;
1397
7.80k
   int    workFactor    = 30;
1398
7.80k
   int    smallMode     = 0;
1399
7.80k
   int    nUnused       = 0; 
1400
1401
7.80k
   if (mode == NULL) return NULL;
1402
23.4k
   while (*mode) {
1403
15.6k
      switch (*mode) {
1404
7.80k
      case 'r':
1405
7.80k
         writing = 0; break;
1406
0
      case 'w':
1407
0
         writing = 1; break;
1408
0
      case 's':
1409
0
         smallMode = 1; break;
1410
7.80k
      default:
1411
7.80k
         if (isdigit((int)(*mode))) {
1412
0
            blockSize100k = *mode-BZ_HDR_0;
1413
0
         }
1414
15.6k
      }
1415
15.6k
      mode++;
1416
15.6k
   }
1417
7.80k
   strcat(mode2, writing ? "w" : "r" );
1418
7.80k
   strcat(mode2,"b");   /* binary mode */
1419
1420
7.80k
   if (open_mode==0) {
1421
4.34k
      if (path==NULL || strcmp(path,"")==0) {
1422
0
        fp = (writing ? stdout : stdin);
1423
0
        SET_BINARY_MODE(fp);
1424
4.34k
      } else {
1425
4.34k
        fp = fopen(path,mode2);
1426
4.34k
      }
1427
4.34k
   } else {
1428
#ifdef BZ_STRICT_ANSI
1429
      fp = NULL;
1430
#else
1431
3.45k
      fp = fdopen(fd,mode2);
1432
3.45k
#endif
1433
3.45k
   }
1434
7.80k
   if (fp == NULL) return NULL;
1435
1436
7.80k
   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
7.80k
   } else {
1443
7.80k
      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1444
7.80k
                            unused,nUnused);
1445
7.80k
   }
1446
7.80k
   if (bzfp == NULL) {
1447
0
      if (fp != stdin && fp != stdout) fclose(fp);
1448
0
      return NULL;
1449
0
   }
1450
7.80k
   return bzfp;
1451
7.80k
}
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
4.34k
{
1464
4.34k
   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
1465
4.34k
}
1466
1467
1468
/*---------------------------------------------------*/
1469
BZFILE * BZ_API(BZ2_bzdopen)
1470
               ( int fd,
1471
                 const char *mode )
1472
3.45k
{
1473
3.45k
   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
1474
3.45k
}
1475
1476
1477
/*---------------------------------------------------*/
1478
int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1479
3.45k
{
1480
3.45k
   int bzerr, nread;
1481
3.45k
   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1482
3.45k
   nread = BZ2_bzRead(&bzerr,b,buf,len);
1483
3.45k
   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1484
0
      return nread;
1485
3.45k
   } else {
1486
3.45k
      return -1;
1487
3.45k
   }
1488
3.45k
}
1489
1490
1491
/*---------------------------------------------------*/
1492
int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1493
3.45k
{
1494
3.45k
   int bzerr;
1495
1496
3.45k
   BZ2_bzWrite(&bzerr,b,buf,len);
1497
3.45k
   if(bzerr == BZ_OK){
1498
3.45k
      return len;
1499
3.45k
   }else{
1500
0
      return -1;
1501
0
   }
1502
3.45k
}
1503
1504
1505
/*---------------------------------------------------*/
1506
int BZ_API(BZ2_bzflush) (BZFILE *b)
1507
7.80k
{
1508
   /* do nothing now... */
1509
7.80k
   return 0;
1510
7.80k
}
1511
1512
1513
/*---------------------------------------------------*/
1514
void BZ_API(BZ2_bzclose) (BZFILE* b)
1515
3.45k
{
1516
3.45k
   int bzerr;
1517
3.45k
   FILE *fp;
1518
   
1519
3.45k
   if (b==NULL) {return;}
1520
3.45k
   fp = ((bzFile *)b)->handle;
1521
3.45k
   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.45k
   }else{
1527
3.45k
      BZ2_bzReadClose(&bzerr,b);
1528
3.45k
   }
1529
3.45k
   if(fp!=stdin && fp!=stdout){
1530
3.45k
      fclose(fp);
1531
3.45k
   }
1532
3.45k
}
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
/*-------------------------------------------------------------*/