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