Coverage Report

Created: 2026-02-09 06:05

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