Coverage Report

Created: 2026-03-12 06:35

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.26k
{
93
1.26k
   if (sizeof(int)   != 4) return 0;
94
1.26k
   if (sizeof(short) != 2) return 0;
95
1.26k
   if (sizeof(char)  != 1) return 0;
96
1.26k
   return 1;
97
1.26k
}
98
99
100
/*---------------------------------------------------*/
101
static
102
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
103
2.43k
{
104
2.43k
   void* v = malloc ( items * size );
105
2.43k
   return v;
106
2.43k
}
107
108
static
109
void default_bzfree ( void* opaque, void* addr )
110
2.43k
{
111
2.43k
   if (addr != NULL) free ( addr );
112
2.43k
}
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.26k
{
501
1.26k
   DState* s;
502
503
1.26k
   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
504
505
1.26k
   if (strm == NULL) return BZ_PARAM_ERROR;
506
1.26k
   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
507
1.26k
   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
508
509
1.26k
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
510
1.26k
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
511
512
1.26k
   s = BZALLOC( sizeof(DState) );
513
1.26k
   if (s == NULL) return BZ_MEM_ERROR;
514
1.26k
   s->strm                  = strm;
515
1.26k
   strm->state              = s;
516
1.26k
   s->state                 = BZ_X_MAGIC_1;
517
1.26k
   s->bsLive                = 0;
518
1.26k
   s->bsBuff                = 0;
519
1.26k
   s->calculatedCombinedCRC = 0;
520
1.26k
   strm->total_in_lo32      = 0;
521
1.26k
   strm->total_in_hi32      = 0;
522
1.26k
   strm->total_out_lo32     = 0;
523
1.26k
   strm->total_out_hi32     = 0;
524
1.26k
   s->smallDecompress       = (Bool)small;
525
1.26k
   s->ll4                   = NULL;
526
1.26k
   s->ll16                  = NULL;
527
1.26k
   s->tt                    = NULL;
528
1.26k
   s->currBlockNo           = 0;
529
1.26k
   s->verbosity             = verbosity;
530
531
1.26k
   return BZ_OK;
532
1.26k
}
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
1.36k
{
542
1.36k
   UChar k1;
543
544
1.36k
   if (s->blockRandomised) {
545
546
1.68M
      while (True) {
547
         /* try to finish existing run */
548
26.4M
         while (True) {
549
26.4M
            if (s->strm->avail_out == 0) return False;
550
26.4M
            if (s->state_out_len == 0) break;
551
24.7M
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
552
24.7M
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
553
24.7M
            s->state_out_len--;
554
24.7M
            s->strm->next_out++;
555
24.7M
            s->strm->avail_out--;
556
24.7M
            s->strm->total_out_lo32++;
557
24.7M
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
558
24.7M
         }
559
560
         /* can a new run be started? */
561
1.68M
         if (s->nblock_used == s->save_nblock+1) return False;
562
               
563
         /* Only caused by corrupt data stream? */
564
1.68M
         if (s->nblock_used > s->save_nblock+1)
565
10
            return True;
566
   
567
1.68M
         s->state_out_len = 1;
568
1.68M
         s->state_out_ch = s->k0;
569
1.68M
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
570
1.68M
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
571
1.68M
         if (s->nblock_used == s->save_nblock+1) continue;
572
1.68M
         if (k1 != s->k0) { s->k0 = k1; continue; };
573
   
574
946k
         s->state_out_len = 2;
575
946k
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
576
946k
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
577
946k
         if (s->nblock_used == s->save_nblock+1) continue;
578
946k
         if (k1 != s->k0) { s->k0 = k1; continue; };
579
   
580
897k
         s->state_out_len = 3;
581
897k
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
582
897k
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
583
897k
         if (s->nblock_used == s->save_nblock+1) continue;
584
897k
         if (k1 != s->k0) { s->k0 = k1; continue; };
585
   
586
775k
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
587
775k
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
588
775k
         s->state_out_len = ((Int32)k1) + 4;
589
775k
         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
590
775k
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
591
775k
      }
592
593
916
   } else {
594
595
      /* restore */
596
916
      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
597
916
      UChar         c_state_out_ch       = s->state_out_ch;
598
916
      Int32         c_state_out_len      = s->state_out_len;
599
916
      Int32         c_nblock_used        = s->nblock_used;
600
916
      Int32         c_k0                 = s->k0;
601
916
      UInt32*       c_tt                 = s->tt;
602
916
      UInt32        c_tPos               = s->tPos;
603
916
      char*         cs_next_out          = s->strm->next_out;
604
916
      unsigned int  cs_avail_out         = s->strm->avail_out;
605
916
      Int32         ro_blockSize100k     = s->blockSize100k;
606
      /* end restore */
607
608
916
      UInt32       avail_out_INIT = cs_avail_out;
609
916
      Int32        s_save_nblockPP = s->save_nblock+1;
610
916
      unsigned int total_out_lo32_old;
611
612
1.66M
      while (True) {
613
614
         /* try to finish existing run */
615
1.66M
         if (c_state_out_len > 0) {
616
43.5M
            while (True) {
617
43.5M
               if (cs_avail_out == 0) goto return_notr;
618
43.5M
               if (c_state_out_len == 1) break;
619
41.8M
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
620
41.8M
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
621
41.8M
               c_state_out_len--;
622
41.8M
               cs_next_out++;
623
41.8M
               cs_avail_out--;
624
41.8M
            }
625
3.37M
            s_state_out_len_eq_one:
626
3.37M
            {
627
3.37M
               if (cs_avail_out == 0) { 
628
32
                  c_state_out_len = 1; goto return_notr;
629
3.37M
               };
630
3.37M
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
631
3.37M
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
632
3.37M
               cs_next_out++;
633
3.37M
               cs_avail_out--;
634
3.37M
            }
635
3.37M
         }   
636
         /* Only caused by corrupt data stream? */
637
3.37M
         if (c_nblock_used > s_save_nblockPP)
638
10
            return True;
639
640
         /* can a new run be started? */
641
3.37M
         if (c_nblock_used == s_save_nblockPP) {
642
240
            c_state_out_len = 0; goto return_notr;
643
3.37M
         };   
644
3.37M
         c_state_out_ch = c_k0;
645
3.37M
         BZ_GET_FAST_C(k1); c_nblock_used++;
646
3.37M
         if (k1 != c_k0) { 
647
1.70M
            c_k0 = k1; goto s_state_out_len_eq_one; 
648
1.70M
         };
649
1.66M
         if (c_nblock_used == s_save_nblockPP) 
650
44
            goto s_state_out_len_eq_one;
651
   
652
1.66M
         c_state_out_len = 2;
653
1.66M
         BZ_GET_FAST_C(k1); c_nblock_used++;
654
1.66M
         if (c_nblock_used == s_save_nblockPP) continue;
655
1.66M
         if (k1 != c_k0) { c_k0 = k1; continue; };
656
   
657
1.59M
         c_state_out_len = 3;
658
1.59M
         BZ_GET_FAST_C(k1); c_nblock_used++;
659
1.59M
         if (c_nblock_used == s_save_nblockPP) continue;
660
1.59M
         if (k1 != c_k0) { c_k0 = k1; continue; };
661
   
662
1.58M
         BZ_GET_FAST_C(k1); c_nblock_used++;
663
1.58M
         c_state_out_len = ((Int32)k1) + 4;
664
1.58M
         BZ_GET_FAST_C(c_k0); c_nblock_used++;
665
1.58M
      }
666
667
906
      return_notr:
668
906
      total_out_lo32_old = s->strm->total_out_lo32;
669
906
      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
670
906
      if (s->strm->total_out_lo32 < total_out_lo32_old)
671
0
         s->strm->total_out_hi32++;
672
673
      /* save */
674
906
      s->calculatedBlockCRC = c_calculatedBlockCRC;
675
906
      s->state_out_ch       = c_state_out_ch;
676
906
      s->state_out_len      = c_state_out_len;
677
906
      s->nblock_used        = c_nblock_used;
678
906
      s->k0                 = c_k0;
679
906
      s->tt                 = c_tt;
680
906
      s->tPos               = c_tPos;
681
906
      s->strm->next_out     = cs_next_out;
682
906
      s->strm->avail_out    = cs_avail_out;
683
      /* end save */
684
906
   }
685
906
   return False;
686
1.36k
}
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
2.23k
{
814
2.23k
   Bool    corrupt;
815
2.23k
   DState* s;
816
2.23k
   if (strm == NULL) return BZ_PARAM_ERROR;
817
2.23k
   s = strm->state;
818
2.23k
   if (s == NULL) return BZ_PARAM_ERROR;
819
2.23k
   if (s->strm != strm) return BZ_PARAM_ERROR;
820
821
2.61k
   while (True) {
822
2.61k
      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
823
2.61k
      if (s->state == BZ_X_OUTPUT) {
824
1.36k
         if (s->smallDecompress)
825
0
            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
826
1.36k
            corrupt = unRLE_obuf_to_output_FAST  ( s );
827
1.36k
         if (corrupt) return BZ_DATA_ERROR;
828
1.34k
         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
829
314
            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
830
314
            if (s->verbosity >= 3) 
831
0
               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
832
314
                          s->calculatedBlockCRC );
833
314
            if (s->verbosity >= 2) VPrintf0 ( "]" );
834
314
            if (s->calculatedBlockCRC != s->storedBlockCRC)
835
228
               return BZ_DATA_ERROR;
836
86
            s->calculatedCombinedCRC 
837
86
               = (s->calculatedCombinedCRC << 1) | 
838
86
                    (s->calculatedCombinedCRC >> 31);
839
86
            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
840
86
            s->state = BZ_X_BLKHDR_1;
841
1.03k
         } else {
842
1.03k
            return BZ_OK;
843
1.03k
         }
844
1.34k
      }
845
1.33k
      if (s->state >= BZ_X_MAGIC_1) {
846
1.33k
         Int32 r = BZ2_decompress ( s );
847
1.33k
         if (r == BZ_STREAM_END) {
848
162
            if (s->verbosity >= 3)
849
0
               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
850
162
                          s->storedCombinedCRC, s->calculatedCombinedCRC );
851
162
            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
852
80
               return BZ_DATA_ERROR;
853
82
            return r;
854
162
         }
855
1.17k
         if (s->state != BZ_X_OUTPUT) return r;
856
1.17k
      }
857
1.33k
   }
858
859
0
   AssertH ( 0, 6001 );
860
861
0
   return 0;  /*NOTREACHED*/
862
2.23k
}
863
864
865
/*---------------------------------------------------*/
866
int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
867
1.26k
{
868
1.26k
   DState* s;
869
1.26k
   if (strm == NULL) return BZ_PARAM_ERROR;
870
1.26k
   s = strm->state;
871
1.26k
   if (s == NULL) return BZ_PARAM_ERROR;
872
1.26k
   if (s->strm != strm) return BZ_PARAM_ERROR;
873
874
1.26k
   if (s->tt   != NULL) BZFREE(s->tt);
875
1.26k
   if (s->ll16 != NULL) BZFREE(s->ll16);
876
1.26k
   if (s->ll4  != NULL) BZFREE(s->ll4);
877
878
1.26k
   BZFREE(strm->state);
879
1.26k
   strm->state = NULL;
880
881
1.26k
   return BZ_OK;
882
1.26k
}
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((int)(*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
/*-------------------------------------------------------------*/