Coverage Report

Created: 2025-07-11 07:02

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