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