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