Coverage Report

Created: 2022-10-15 06:07

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