Coverage Report

Created: 2026-10-28 06:38

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