~ubuntu-branches/ubuntu/natty/clamav/natty-security

« back to all changes in this revision

Viewing changes to win32/3rdparty/bzip2/bzlib.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2011-02-19 09:51:33 UTC
  • mfrom: (0.35.19 sid)
  • Revision ID: james.westby@ubuntu.com-20110219095133-sde2dyj8a6bjbkdh
Tags: 0.97+dfsg-0ubuntu1
* Merge from debian unstable (0ubuntu1 because the Debian upload was
  inadvertently left marked UNRELEASED).  Remaining changes:
  - Drop initial signature definitions from clamav-base
  - Drop build-dep on electric-fence (in Universe)
  - Add apparmor profiles for clamd and freshclam along with maintainer
    script changes

Show diffs side-by-side

added added

removed removed

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