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