bzlib.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
57221209d11b05aa0373cc3892d5df89ba96ebf9Christian Maeder#pragma prototyped
57221209d11b05aa0373cc3892d5df89ba96ebf9Christian Maeder
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder/*-------------------------------------------------------------*/
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder/*--- Library top-level functions. ---*/
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski/*--- bzlib.c ---*/
1549f3abf73c1122acff724f718b615c82fa3648Till Mossakowski/*-------------------------------------------------------------*/
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder/*--
3f69b6948966979163bdfe8331c38833d5d90ecdChristian Maeder This file is a part of bzip2 and/or libbzip2, a program and
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder library for lossless, block-sorting data compression.
351145cfe8c03b4d47133c96b209f2bd6cfbf504Christian Maeder
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder Copyright (C) 1996-1998 Julian R Seward. All rights reserved.
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski
1549f3abf73c1122acff724f718b615c82fa3648Till Mossakowski Redistribution and use in source and binary forms, with or without
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder modification, are permitted provided that the following conditions
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder are met:
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder 1. Redistributions of source code must retain the above copyright
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder notice, this list of conditions and the following disclaimer.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder 2. The origin of this software must not be misrepresented; you must
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder not claim that you wrote the original software. If you use this
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder software in a product, an acknowledgment in the product
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder documentation would be appreciated but is not required.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder 3. Altered source versions must be plainly marked as such, and must
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder not be misrepresented as being the original software.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder 4. The name of the author may not be used to endorse or promote
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder products derived from this software without specific prior written
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder permission.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Julian Seward, Guildford, Surrey, UK.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder jseward@acm.org
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder bzip2/libbzip2 version 0.9.0c of 18 October 1998
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder This program is based on (at least) the work of:
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Mike Burrows
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder David Wheeler
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Peter Fenwick
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Alistair Moffat
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Radford Neal
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Ian H. Witten
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Robert Sedgewick
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder Jon L. Bentley
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder For more information on these sources, see the manual.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder--*/
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder/*--
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder CHANGES
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder ~~~~~~~
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder 0.9.0 -- original version.
351391e0e3226210e7ffb183b334da9f96de36eaChristian Maeder
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder 0.9.0a/b -- no changes in this file.
f8b715ab2993083761c0aedb78f1819bcf67b6ccChristian Maeder
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder 0.9.0c
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder * made zero-length BZ_FLUSH work correctly in bzCompress().
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder * fixed bzWrite/bzRead to ignore zero-length requests.
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder * fixed bzread to correctly handle read requests after EOF.
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder * wrong parameter order in call to bzDecompressInit in
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski bzBuffToBuffDecompress. Fixed.
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang--*/
23a00c966f2aa8da525d7a7c51933c99964426c0Christian Maeder
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder#include "bzhdr.h"
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder
8e9c3881fb6e710b1e08bf5ac8ff9d393df2e74eChristian Maeder
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang/*---------------------------------------------------*/
8c63cd89ef840cd7a3d3b75f0207dc800388c800Christian Maeder/*--- Compression stuff ---*/
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder/*---------------------------------------------------*/
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski/*---------------------------------------------------*/
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder#ifndef BZ_NO_STDIO
0e2ae85e2453466d03c1fc5884a3d693235bb9d9Christian Maedervoid bz__AssertH__fail ( int errcode )
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder{
90c174bac60a72ffd81bc3bf5ae2dd9a61943b8bChristian Maeder fprintf(stderr,
2561b4bfc45d280ee2be8a7870314670e4e682e4Christian Maeder "\n\nbzip2/libbzip2, v0.9.0c: internal error number %d.\n"
ca020e82eb3567e7bdbb1cf70729efbd07e9caa4Klaus Luettich "This is a bug in bzip2/libbzip2, v0.9.0c. Please report\n"
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder "it to me at: jseward@acm.org. If this happened when\n"
ca020e82eb3567e7bdbb1cf70729efbd07e9caa4Klaus Luettich "you were using some program which uses libbzip2 as a\n"
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder "component, you should also report this bug to the author(s)\n"
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski "of that program. Please make an effort to report this bug;\n"
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder "timely and accurate bug reports eventually lead to higher\n"
c7e03d0708369f944b6f235057b39142a21599f2Mihai Codescu "quality software. Thx. Julian Seward, 18 October 1998.\n\n",
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder errcode
986d3f255182539098a97ac86da9eeee5b7a72e3Christian Maeder );
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder exit(3);
8e80792f474d154ff11762fac081a422e34f1accChristian Maeder}
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder#endif
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder/*---------------------------------------------------*/
03136b84a0c70d877e227444f0875e209506b9e4Christian Maederstatic
03136b84a0c70d877e227444f0875e209506b9e4Christian Maedervoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
16e124196c6b204769042028c74f533509c9b5d3Christian Maeder{
4c7f058cdd19ce67b2b5d4b7f69703d0f8a21e38Christian Maeder void* v = malloc ( items * size );
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder return v;
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder}
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maederstatic
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maedervoid default_bzfree ( void* opaque, void* addr )
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder{
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder if (addr != NULL) free ( addr );
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder}
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder/*---------------------------------------------------*/
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maederstatic
e6dccba746efe07338d3107fed512e713fd50b28Christian Maedervoid prepare_new_block ( EState* s )
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder{
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder Int32 i;
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder s->nblock = 0;
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder s->numZ = 0;
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder s->state_out_pos = 0;
351145cfe8c03b4d47133c96b209f2bd6cfbf504Christian Maeder BZ_INITIALISE_CRC ( s->blockCRC );
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder for (i = 0; i < 256; i++) s->inUse[i] = False;
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder s->blockNo++;
9a6779c8495854bdf36e4a87f98f095e8d0a6e45Christian Maeder}
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian Maeder
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder/*---------------------------------------------------*/
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian Maederstatic
351145cfe8c03b4d47133c96b209f2bd6cfbf504Christian Maedervoid init_RL ( EState* s )
351145cfe8c03b4d47133c96b209f2bd6cfbf504Christian Maeder{
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder s->state_in_ch = 256;
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian Maeder s->state_in_len = 0;
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian Maeder}
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder
351145cfe8c03b4d47133c96b209f2bd6cfbf504Christian Maeder
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maederstatic
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian MaederBool isempty_RL ( EState* s )
81101b83a042f5a1bdeeef93b1b49aff05817e44Christian Maeder{
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder if (s->state_in_ch < 256 && s->state_in_len > 0)
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder return False; else
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder return True;
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder}
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder/*---------------------------------------------------*/
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maederint BZ_API(bzCompressInit)
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder ( bz_stream* strm,
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder int blockSize100k,
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder int verbosity,
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder int workFactor )
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder{
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder Int32 n;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder EState* s;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder
fa167e362877db231378e17ba49c66fbb84862fcChristian Maeder if (strm == NULL ||
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder blockSize100k < 1 || blockSize100k > 9 ||
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder workFactor < 0 || workFactor > 250)
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder return BZ_PARAM_ERROR;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder
6a22b2854c3bc9cb4877cb7d29049d6559238639Christian Maeder if (workFactor == 0) workFactor = 30;
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder s = BZALLOC( sizeof(EState) );
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski if (s == NULL) return BZ_MEM_ERROR;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski s->strm = strm;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder s->block = NULL;
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder s->quadrant = NULL;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->zptr = NULL;
4b6aa93c12e4db86ccc7694a48a73e9cf7262d06Christian Maeder s->ftab = NULL;
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder n = 100000 * blockSize100k;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder s->block = BZALLOC( (n + BZ_NUM_OVERSHOOT_BYTES) * sizeof(UChar) );
4601edb679f0ba530bbb085b25d82a411cd070aaChristian Maeder s->quadrant = BZALLOC( (n + BZ_NUM_OVERSHOOT_BYTES) * sizeof(Int16) );
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->zptr = BZALLOC( n * sizeof(Int32) );
26d11a256b1433604a3dbc69913b520fff7586acChristian Maeder s->ftab = BZALLOC( 65537 * sizeof(Int32) );
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder if (s->block == NULL || s->quadrant == NULL ||
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->zptr == NULL || s->ftab == NULL) {
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder if (s->block != NULL) BZFREE(s->block);
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder if (s->quadrant != NULL) BZFREE(s->quadrant);
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder if (s->zptr != NULL) BZFREE(s->zptr);
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder if (s->ftab != NULL) BZFREE(s->ftab);
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder if (s != NULL) BZFREE(s);
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder return BZ_MEM_ERROR;
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder }
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->szptr = (UInt16*)(s->zptr);
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder s->blockNo = 0;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->state = BZ_S_INPUT;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->mode = BZ_M_RUNNING;
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder s->combinedCRC = 0;
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski s->blockSize100k = blockSize100k;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder s->nblockMAX = 100000 * blockSize100k - 19;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder s->verbosity = verbosity;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder s->workFactor = workFactor;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder s->nBlocksRandomised = 0;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder strm->state = s;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder strm->total_in = 0;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder strm->total_out = 0;
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder init_RL ( s );
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz prepare_new_block ( s );
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder return BZ_OK;
b2026c46f0e4c6a05931f1bf0ab2e84ce884c814Christian Maeder}
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder/*---------------------------------------------------*/
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maederstatic
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maedervoid add_pair_to_block ( EState* s )
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder{
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder Int32 i;
4e3c46a1ca40d50a045342c5fab25b5db4fa9a87Christian Maeder UChar ch = (UChar)(s->state_in_ch);
4e3c46a1ca40d50a045342c5fab25b5db4fa9a87Christian Maeder for (i = 0; i < s->state_in_len; i++) {
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder BZ_UPDATE_CRC( s->blockCRC, ch );
ef60398f3b9f24614b074f8f0f1349ab527e1c77Christian Maeder }
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz s->inUse[s->state_in_ch] = True;
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz switch (s->state_in_len) {
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz case 1:
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz s->block[s->nblock] = (UChar)ch; s->nblock++;
bdf2e01977470bedcb4425e2dadabc9e9f6ba149Ewaryst Schulz break;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder case 2:
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder break;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder case 3:
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder break;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder default:
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->inUse[s->state_in_len-4] = True;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
ee152ae82dc19d6415119c0019ae1bfa991b1f02Christian Maeder s->block[s->nblock] = (UChar)ch; s->nblock++;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->block[s->nblock] = (UChar)(s->state_in_len-4);
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder s->nblock++;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder break;
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder }
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder}
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder/*---------------------------------------------------*/
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maederstatic
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maedervoid flush_RL ( EState* s )
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder{
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder if (s->state_in_ch < 256) add_pair_to_block ( s );
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder init_RL ( s );
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder}
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder/*---------------------------------------------------*/
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder{ \
4e144aa4be1f50519f8fa377a7883edfbc76d406Christian Maeder UInt32 zchh = (UInt32)(zchh0); \
568da6120906d5283c4322114eee10f24ea8dd6dChristian Maeder /*-- fast track the common case --*/ \
8c63cd89ef840cd7a3d3b75f0207dc800388c800Christian Maeder if (zchh != zs->state_in_ch && \
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder zs->state_in_len == 1) { \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder UChar ch = (UChar)(zs->state_in_ch); \
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder BZ_UPDATE_CRC( zs->blockCRC, ch ); \
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder zs->inUse[zs->state_in_ch] = True; \
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder zs->block[zs->nblock] = (UChar)ch; \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->nblock++; \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->state_in_ch = zchh; \
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder } \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder else \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder /*-- general, uncommon cases --*/ \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder if (zchh != zs->state_in_ch || \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->state_in_len == 255) { \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder if (zs->state_in_ch < 256) \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder add_pair_to_block ( zs ); \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->state_in_ch = zchh; \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->state_in_len = 1; \
8c63cd89ef840cd7a3d3b75f0207dc800388c800Christian Maeder } else { \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder zs->state_in_len++; \
8cceb39f451593f3904acbf9d64bea6af9860b57Christian Maeder } \
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski}
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder/*---------------------------------------------------*/
99476ac2689c74251219db4782e57fe713a24a52Christian Maederstatic
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian MaederBool copy_input_until_stop ( EState* s )
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder{
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder Bool progress_in = False;
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder if (s->mode == BZ_M_RUNNING) {
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder /*-- fast track the common case --*/
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder while (True) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder /*-- block full? --*/
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->nblock >= s->nblockMAX) break;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder /*-- no input? --*/
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder if (s->strm->avail_in == 0) break;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder progress_in = True;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder s->strm->next_in++;
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder s->strm->avail_in--;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->strm->total_in++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder }
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder } else {
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder /*-- general, uncommon case --*/
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder while (True) {
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder /*-- block full? --*/
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder if (s->nblock >= s->nblockMAX) break;
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder /*-- no input? --*/
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder if (s->strm->avail_in == 0) break;
88124ca824f94153b0a2a24ea1e4b089fff7011fChristian Maeder /*-- flush/finish end? --*/
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder if (s->avail_in_expect == 0) break;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder progress_in = True;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder s->strm->next_in++;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->strm->avail_in--;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->strm->total_in++;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder s->avail_in_expect--;
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder }
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder }
8c63cd89ef840cd7a3d3b75f0207dc800388c800Christian Maeder return progress_in;
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder}
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder/*---------------------------------------------------*/
ee152ae82dc19d6415119c0019ae1bfa991b1f02Christian Maederstatic
ee152ae82dc19d6415119c0019ae1bfa991b1f02Christian MaederBool copy_output_until_stop ( EState* s )
ee152ae82dc19d6415119c0019ae1bfa991b1f02Christian Maeder{
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder Bool progress_out = False;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder while (True) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder /*-- no output space? --*/
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->strm->avail_out == 0) break;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder /*-- block done? --*/
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder if (s->state_out_pos >= s->numZ) break;
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder progress_out = True;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder *(s->strm->next_out) = ((UChar*)(s->quadrant))[s->state_out_pos];
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->state_out_pos++;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder s->strm->avail_out--;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->strm->next_out++;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->strm->total_out++;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder }
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder return progress_out;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder}
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder/*---------------------------------------------------*/
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maederstatic
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian MaederBool handle_compress ( bz_stream* strm )
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder{
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder Bool progress_in = False;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder Bool progress_out = False;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder EState* s = strm->state;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder while (True) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->state == BZ_S_OUTPUT) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder progress_out |= copy_output_until_stop ( s );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->state_out_pos < s->numZ) break;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->mode == BZ_M_FINISHING &&
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->avail_in_expect == 0 &&
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder isempty_RL(s)) break;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder prepare_new_block ( s );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->state = BZ_S_INPUT;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->mode == BZ_M_FLUSHING &&
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder s->avail_in_expect == 0 &&
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder isempty_RL(s)) break;
99476ac2689c74251219db4782e57fe713a24a52Christian Maeder }
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder if (s->state == BZ_S_INPUT) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder progress_in |= copy_input_until_stop ( s );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder flush_RL ( s );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder compressBlock ( s, s->mode == BZ_M_FINISHING );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->state = BZ_S_OUTPUT;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder }
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder else
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->nblock >= s->nblockMAX) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder compressBlock ( s, False );
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder s->state = BZ_S_OUTPUT;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder }
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder else
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (s->strm->avail_in == 0) {
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder break;
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder }
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder }
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder }
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder return progress_in || progress_out;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder}
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder/*---------------------------------------------------*/
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maederint BZ_API(bzCompress) ( bz_stream *strm, int action )
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder{
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder Bool progress;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder EState* s;
d6c6b2543c509ec7f6213e4cba675d96304a7fd6Christian Maeder if (strm == NULL) return BZ_PARAM_ERROR;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski s = strm->state;
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder if (s == NULL) return BZ_PARAM_ERROR;
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder if (s->strm != strm) return BZ_PARAM_ERROR;
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder preswitch:
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder switch (s->mode) {
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder case BZ_M_IDLE:
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder return BZ_SEQUENCE_ERROR;
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder case BZ_M_RUNNING:
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder if (action == BZ_RUN) {
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder progress = handle_compress ( strm );
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder }
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder else
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder if (action == BZ_FLUSH) {
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder s->avail_in_expect = strm->avail_in;
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder s->mode = BZ_M_FLUSHING;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder goto preswitch;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder }
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder else
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder if (action == BZ_FINISH) {
e82587ca2892d246aa4405c2f5b9f30f287f9ebfChristian Maeder s->avail_in_expect = strm->avail_in;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder s->mode = BZ_M_FINISHING;
2561b4bfc45d280ee2be8a7870314670e4e682e4Christian Maeder goto preswitch;
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder }
01aafb6a9520f05df5ff467b591ecb5474dcfc86Christian Maeder else
fa167e362877db231378e17ba49c66fbb84862fcChristian Maeder return BZ_PARAM_ERROR;
fa167e362877db231378e17ba49c66fbb84862fcChristian Maeder
fa167e362877db231378e17ba49c66fbb84862fcChristian Maeder case BZ_M_FLUSHING:
fa167e362877db231378e17ba49c66fbb84862fcChristian Maeder if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR;
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder progress = handle_compress ( strm );
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder if (s->avail_in_expect > 0 || !isempty_RL(s) ||
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder s->mode = BZ_M_RUNNING;
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder return BZ_RUN_OK;
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder case BZ_M_FINISHING:
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
86b1d0c80abdd4ca36491cf7025b718a5fea5080Christian Maeder if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR;
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder progress = handle_compress ( strm );
86b1d0c80abdd4ca36491cf7025b718a5fea5080Christian Maeder if (!progress) return BZ_SEQUENCE_ERROR;
a23e572c8f957cc051a1b0831abd6fe9380d45c7Christian Maeder if (s->avail_in_expect > 0 || !isempty_RL(s) ||
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder s->state_out_pos < s->numZ) return BZ_FINISH_OK;
68138d26bcddf5e89c30206aa83ab5ec006d170dChristian Maeder s->mode = BZ_M_IDLE;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder return BZ_STREAM_END;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder }
68138d26bcddf5e89c30206aa83ab5ec006d170dChristian Maeder return BZ_OK; /*--not reached--*/
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder}
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder
e01299e9b22b96b31b720ca1e9f9f5f25af9b024Christian Maeder
e0f1794e365dd347e97b37d7d22b2fce27296fa1Christian Maeder/*---------------------------------------------------*/
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maederint BZ_API(bzCompressEnd) ( bz_stream *strm )
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder{
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder EState* s;
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder if (strm == NULL) return BZ_PARAM_ERROR;
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder s = strm->state;
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder if (s == NULL) return BZ_PARAM_ERROR;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder if (s->strm != strm) return BZ_PARAM_ERROR;
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder if (s->block != NULL) BZFREE(s->block);
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder if (s->quadrant != NULL) BZFREE(s->quadrant);
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder if (s->zptr != NULL) BZFREE(s->zptr);
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder if (s->ftab != NULL) BZFREE(s->ftab);
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder BZFREE(strm->state);
4072adb8c5d2c86123e8e1c1918263968f187829Christian Maeder
d5833d2ee7bafcbf2fdd2bdfd9a728c769b100c7Christian Maeder strm->state = NULL;
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder return BZ_OK;
86b1d0c80abdd4ca36491cf7025b718a5fea5080Christian Maeder}
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder
86b1d0c80abdd4ca36491cf7025b718a5fea5080Christian Maeder
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski/*---------------------------------------------------*/
74d9a385499bf903b24848dff450a153f525bda7Christian Maeder/*--- Decompression stuff ---*/
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder/*---------------------------------------------------*/
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder/*---------------------------------------------------*/
5e46b572ed576c0494768998b043d9d340594122Till Mossakowskiint BZ_API(bzDecompressInit)
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski ( bz_stream* strm,
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder int verbosity,
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder int small )
ebc51e8081f6f1fe2f3d39ceff81d8dd0169c0b0Christian Maeder{
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski DState* s;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder if (strm == NULL) return BZ_PARAM_ERROR;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder if (small != 0 && small != 1) return BZ_PARAM_ERROR;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s = BZALLOC( sizeof(DState) );
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder if (s == NULL) return BZ_MEM_ERROR;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->strm = strm;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder strm->state = s;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->state = BZ_X_MAGIC_1;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->bsLive = 0;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->bsBuff = 0;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->calculatedCombinedCRC = 0;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder strm->total_in = 0;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder strm->total_out = 0;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->smallDecompress = (Bool)small;
dece9056c18ada64bcc8f2fba285270374139ee8Christian Maeder s->ll4 = NULL;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder s->ll16 = NULL;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder s->tt = NULL;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder s->currBlockNo = 0;
be98c516a8ff1d496fcdeb9b8be8c5f4b908ab95Christian Maeder s->verbosity = verbosity;
22eea35d0effc6582b2951a28b5240fa7a82f3dfChristian Maeder
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder return BZ_OK;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder}
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder/*---------------------------------------------------*/
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maederstatic
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maedervoid unRLE_obuf_to_output_FAST ( DState* s )
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder{
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder UChar k1;
d058429727dd696a0327cdc28cadd268c34c36baChristian Maeder
329d1810c6d5a5a0827e1d07503d94431578d176Christian Maeder if (s->blockRandomised) {
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski
329d1810c6d5a5a0827e1d07503d94431578d176Christian Maeder while (True) {
329d1810c6d5a5a0827e1d07503d94431578d176Christian Maeder /* try to finish existing run */
d058429727dd696a0327cdc28cadd268c34c36baChristian Maeder while (True) {
d058429727dd696a0327cdc28cadd268c34c36baChristian Maeder if (s->strm->avail_out == 0) return;
03136b84a0c70d877e227444f0875e209506b9e4Christian Maeder if (s->state_out_len == 0) break;
5a9a06d23910b9521e1d1cd39865ac7912ccee4bChristian Maeder *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5a9a06d23910b9521e1d1cd39865ac7912ccee4bChristian Maeder BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder s->state_out_len--;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder s->strm->next_out++;
329d1810c6d5a5a0827e1d07503d94431578d176Christian Maeder s->strm->avail_out--;
5e46b572ed576c0494768998b043d9d340594122Till Mossakowski s->strm->total_out++;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder }
2feea92963a4b1b7482a4b72ee85148d842d9ad6Christian Maeder
86b1d0c80abdd4ca36491cf7025b718a5fea5080Christian Maeder /* can a new run be started? */
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder if (s->nblock_used == s->save_nblock+1) return;
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder s->state_out_len = 1;
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder s->state_out_ch = s->k0;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder k1 ^= BZ_RAND_MASK; s->nblock_used++;
40d15f6c5f4d15866e085c588f8b5130dfd6cf63Christian Maeder if (s->nblock_used == s->save_nblock+1) continue;
40d15f6c5f4d15866e085c588f8b5130dfd6cf63Christian Maeder if (k1 != s->k0) { s->k0 = k1; continue; };
40d15f6c5f4d15866e085c588f8b5130dfd6cf63Christian Maeder
b0442fc87b3d8a47626543df44e4227d6933f8bdChristian Maeder s->state_out_len = 2;
0e2ae85e2453466d03c1fc5884a3d693235bb9d9Christian Maeder BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder k1 ^= BZ_RAND_MASK; s->nblock_used++;
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder if (s->nblock_used == s->save_nblock+1) continue;
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski if (k1 != s->k0) { s->k0 = k1; continue; };
32562a567baac248a00782d2727716c13117dc4aChristian Maeder
32562a567baac248a00782d2727716c13117dc4aChristian Maeder s->state_out_len = 3;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder k1 ^= BZ_RAND_MASK; s->nblock_used++;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder if (s->nblock_used == s->save_nblock+1) continue;
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder if (k1 != s->k0) { s->k0 = k1; continue; };
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder
fa373bc327620e08861294716b4454be8d25669fChristian Maeder BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder k1 ^= BZ_RAND_MASK; s->nblock_used++;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder s->state_out_len = ((Int32)k1) + 4;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder }
fa373bc327620e08861294716b4454be8d25669fChristian Maeder
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder } else {
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder
32562a567baac248a00782d2727716c13117dc4aChristian Maeder /* restore */
32562a567baac248a00782d2727716c13117dc4aChristian Maeder UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder UChar c_state_out_ch = s->state_out_ch;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder Int32 c_state_out_len = s->state_out_len;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder Int32 c_nblock_used = s->nblock_used;
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder Int32 c_k0 = s->k0;
7857a35e3af533dfbd0f0e18638ebd211e6358a0Christian Maeder UInt32* c_tt = s->tt;
746440cc1b984a852f5864235b8fa3930963a081Christian Maeder UInt32 c_tPos = s->tPos;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder char* cs_next_out = s->strm->next_out;
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder unsigned int cs_avail_out = s->strm->avail_out;
7a47fbe6b987bd69a5056ce5d00fc8710f6c5e8aChristian Maeder /* end restore */
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder UInt32 avail_out_INIT = cs_avail_out;
e68f45f355ed9d4026ee9baff5aa75aa7c911cc2Christian Maeder Int32 s_save_nblockPP = s->save_nblock+1;
e68f45f355ed9d4026ee9baff5aa75aa7c911cc2Christian Maeder
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder while (True) {
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder /* try to finish existing run */
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (c_state_out_len > 0) {
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder while (True) {
4aa35aadcb28f8a962096efc70d3bdb58ab7d9faChristian Maeder if (cs_avail_out == 0) goto return_notr;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (c_state_out_len == 1) break;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder *( (UChar*)(cs_next_out) ) = c_state_out_ch;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder c_state_out_len--;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder cs_next_out++;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder cs_avail_out--;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder }
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder s_state_out_len_eq_one:
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder {
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (cs_avail_out == 0) {
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder c_state_out_len = 1; goto return_notr;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder };
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder *( (UChar*)(cs_next_out) ) = c_state_out_ch;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder cs_next_out++;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder cs_avail_out--;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder }
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder }
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder /* can a new run be started? */
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (c_nblock_used == s_save_nblockPP) {
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder c_state_out_len = 0; goto return_notr;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder };
e7ddd5495421698701a2bbc57a5b3390a11d12caChristian Maeder c_state_out_ch = c_k0;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder BZ_GET_FAST_C(k1); c_nblock_used++;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder if (k1 != c_k0) {
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder c_k0 = k1; goto s_state_out_len_eq_one;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder };
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (c_nblock_used == s_save_nblockPP)
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder goto s_state_out_len_eq_one;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder c_state_out_len = 2;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder BZ_GET_FAST_C(k1); c_nblock_used++;
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder if (c_nblock_used == s_save_nblockPP) continue;
575a55eadc8dcab8ee350324b417cbd9e52e69c0Christian Maeder if (k1 != c_k0) { c_k0 = k1; continue; };
d79a4d0d842c212f82f9507fff178ffe4ba2e214Christian Maeder
e7ddd5495421698701a2bbc57a5b3390a11d12caChristian Maeder c_state_out_len = 3;
e7ddd5495421698701a2bbc57a5b3390a11d12caChristian Maeder BZ_GET_FAST_C(k1); c_nblock_used++;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder if (c_nblock_used == s_save_nblockPP) continue;
32562a567baac248a00782d2727716c13117dc4aChristian Maeder if (k1 != c_k0) { c_k0 = k1; continue; };
32562a567baac248a00782d2727716c13117dc4aChristian Maeder
fa373bc327620e08861294716b4454be8d25669fChristian Maeder BZ_GET_FAST_C(k1); c_nblock_used++;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder c_state_out_len = ((Int32)k1) + 4;
fa373bc327620e08861294716b4454be8d25669fChristian Maeder BZ_GET_FAST_C(c_k0); c_nblock_used++;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder }
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder return_notr:
32562a567baac248a00782d2727716c13117dc4aChristian Maeder s->strm->total_out += (avail_out_INIT - cs_avail_out);
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder /* save */
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder s->calculatedBlockCRC = c_calculatedBlockCRC;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder s->state_out_ch = c_state_out_ch;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder s->state_out_len = c_state_out_len;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder s->nblock_used = c_nblock_used;
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder s->k0 = c_k0;
812ee1f62e0e0e7235f3c05b41a0b173497b54ffChristian Maeder s->tt = c_tt;
3c8d067accf18572352351ec42ff905c7297a8a5Christian Maeder s->tPos = c_tPos;
3b70d8ee5c2927f843d5d907e6ef724f867f1b40Till Mossakowski s->strm->next_out = cs_next_out;
a001917177db7ae636853b37c0d0f9f4e90a83ffChristian Maeder s->strm->avail_out = cs_avail_out;
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder /* end save */
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder }
3b70d8ee5c2927f843d5d907e6ef724f867f1b40Till Mossakowski}
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder/*---------------------------------------------------*/
ca732bc259f74cb4f3f725daab7fe80fc7e1d9a0Till Mossakowski__inline__ Int32 indexIntoF ( Int32 indx, Int32 *cftab )
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder{
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder Int32 nb, na, mid;
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder nb = 0;
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder na = 256;
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder do {
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder mid = (nb + na) >> 1;
2766ec926fcf3faf72248b10c3305b715b8c3249Christian Maeder if (indx >= cftab[mid]) nb = mid; else na = mid;
ca732bc259f74cb4f3f725daab7fe80fc7e1d9a0Till Mossakowski }
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang while (na - nb != 1);
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang return nb;
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang}
aea143fff7a50aceb809845fbc42698b0b3f545aChristian Maeder
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder/*---------------------------------------------------*/
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maederstatic
fc033b8680245bf692c9c09723fd3046ff38971eChristian Maedervoid unRLE_obuf_to_output_SMALL ( DState* s )
2b2f3b72e82e28b34db9c69af2d1ec38f228272eChristian Maeder{
2b2f3b72e82e28b34db9c69af2d1ec38f228272eChristian Maeder UChar k1;
9ecf13b5fd914bc7272f1fc17348d7f4a8c77061Christian Maeder
5824312cc0cfccce61f195fbe92307a21a467049Christian Maeder if (s->blockRandomised) {
2b2f3b72e82e28b34db9c69af2d1ec38f228272eChristian Maeder
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder while (True) {
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder /* try to finish existing run */
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder while (True) {
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder if (s->strm->avail_out == 0) return;
2b2f3b72e82e28b34db9c69af2d1ec38f228272eChristian Maeder if (s->state_out_len == 0) break;
fc033b8680245bf692c9c09723fd3046ff38971eChristian Maeder *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
fc033b8680245bf692c9c09723fd3046ff38971eChristian Maeder BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
40d15f6c5f4d15866e085c588f8b5130dfd6cf63Christian Maeder s->state_out_len--;
40d15f6c5f4d15866e085c588f8b5130dfd6cf63Christian Maeder s->strm->next_out++;
d0c66a832d7b556e20ea4af4852cdc27a5463d51Christian Maeder s->strm->avail_out--;
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder s->strm->total_out++;
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder }
2b2f3b72e82e28b34db9c69af2d1ec38f228272eChristian Maeder
db453fe9625a9dab5d108f7a5e464598814144b8Jian Chun Wang /* can a new run be started? */
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder if (s->nblock_used == s->save_nblock+1) return;
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder
0ccfc8f86bd6518556ef09e367a0ce2bd1a69c91Christian Maeder
7830e8fa7442fb7452af7ecdba102bc297ae367eChristian Maeder s->state_out_len = 1;
s->state_out_ch = s->k0;
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
k1 ^= BZ_RAND_MASK; s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
s->state_out_len = 2;
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
k1 ^= BZ_RAND_MASK; s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
s->state_out_len = 3;
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
k1 ^= BZ_RAND_MASK; s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
k1 ^= BZ_RAND_MASK; s->nblock_used++;
s->state_out_len = ((Int32)k1) + 4;
BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
}
} else {
while (True) {
/* try to finish existing run */
while (True) {
if (s->strm->avail_out == 0) return;
if (s->state_out_len == 0) break;
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
s->state_out_len--;
s->strm->next_out++;
s->strm->avail_out--;
s->strm->total_out++;
}
/* can a new run be started? */
if (s->nblock_used == s->save_nblock+1) return;
s->state_out_len = 1;
s->state_out_ch = s->k0;
BZ_GET_SMALL(k1); s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
s->state_out_len = 2;
BZ_GET_SMALL(k1); s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
s->state_out_len = 3;
BZ_GET_SMALL(k1); s->nblock_used++;
if (s->nblock_used == s->save_nblock+1) continue;
if (k1 != s->k0) { s->k0 = k1; continue; };
BZ_GET_SMALL(k1); s->nblock_used++;
s->state_out_len = ((Int32)k1) + 4;
BZ_GET_SMALL(s->k0); s->nblock_used++;
}
}
}
/*---------------------------------------------------*/
int BZ_API(bzDecompress) ( bz_stream *strm )
{
DState* s;
if (strm == NULL) return BZ_PARAM_ERROR;
s = strm->state;
if (s == NULL) return BZ_PARAM_ERROR;
if (s->strm != strm) return BZ_PARAM_ERROR;
while (True) {
if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
if (s->state == BZ_X_OUTPUT) {
if (s->smallDecompress)
unRLE_obuf_to_output_SMALL ( s ); else
unRLE_obuf_to_output_FAST ( s );
if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
BZ_FINALISE_CRC ( s->calculatedBlockCRC );
if (s->verbosity >= 3)
VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
s->calculatedBlockCRC );
if (s->verbosity >= 2) VPrintf0 ( "]" );
if (s->calculatedBlockCRC != s->storedBlockCRC)
return BZ_DATA_ERROR;
s->calculatedCombinedCRC
= (s->calculatedCombinedCRC << 1) |
(s->calculatedCombinedCRC >> 31);
s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
s->state = BZ_X_BLKHDR_1;
} else {
return BZ_OK;
}
}
if (s->state >= BZ_X_MAGIC_1) {
Int32 r = decompress ( s );
if (r == BZ_STREAM_END) {
if (s->verbosity >= 3)
VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
s->storedCombinedCRC, s->calculatedCombinedCRC );
if (s->calculatedCombinedCRC != s->storedCombinedCRC)
return BZ_DATA_ERROR;
return r;
}
if (s->state != BZ_X_OUTPUT) return r;
}
}
AssertH ( 0, 6001 );
/*notreached*/
}
/*---------------------------------------------------*/
int BZ_API(bzDecompressEnd) ( bz_stream *strm )
{
DState* s;
if (strm == NULL) return BZ_PARAM_ERROR;
s = strm->state;
if (s == NULL) return BZ_PARAM_ERROR;
if (s->strm != strm) return BZ_PARAM_ERROR;
if (s->tt != NULL) BZFREE(s->tt);
if (s->ll16 != NULL) BZFREE(s->ll16);
if (s->ll4 != NULL) BZFREE(s->ll4);
BZFREE(strm->state);
strm->state = NULL;
return BZ_OK;
}
#ifndef BZ_NO_STDIO
/*---------------------------------------------------*/
/*--- File I/O stuff ---*/
/*---------------------------------------------------*/
#define BZ_SETERR(eee) \
{ \
if (bzerror != NULL) *bzerror = eee; \
if (bzf != NULL) bzf->lastErr = eee; \
}
typedef
struct {
FILE* handle;
Char buf[BZ_MAX_UNUSED];
Int32 bufN;
Bool writing;
bz_stream strm;
Int32 lastErr;
Bool initialisedOk;
Bool noclose;
}
bzFile;
/*---------------------------------------------*/
static Bool myfeof ( FILE* f )
{
Int32 c = fgetc ( f );
if (c == EOF) return True;
ungetc ( c, f );
return False;
}
/*---------------------------------------------------*/
BZFILE* BZ_API(bzWriteOpen)
( int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor )
{
Int32 ret;
bzFile* bzf = NULL;
BZ_SETERR(BZ_OK);
if (f == NULL ||
(blockSize100k < 1 || blockSize100k > 9) ||
(workFactor < 0 || workFactor > 250) ||
(verbosity < 0 || verbosity > 4))
{ BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
if (ferror(f))
{ BZ_SETERR(BZ_IO_ERROR); return NULL; };
bzf = malloc ( sizeof(bzFile) );
if (bzf == NULL)
{ BZ_SETERR(BZ_MEM_ERROR); return NULL; };
BZ_SETERR(BZ_OK);
bzf->initialisedOk = False;
bzf->bufN = 0;
bzf->handle = f;
bzf->writing = True;
bzf->strm.bzalloc = NULL;
bzf->strm.bzfree = NULL;
bzf->strm.opaque = NULL;
if (workFactor == 0) workFactor = 30;
ret = bzCompressInit ( &(bzf->strm), blockSize100k,
verbosity, workFactor );
if (ret != BZ_OK)
{ BZ_SETERR(ret); free(bzf); return NULL; };
bzf->strm.avail_in = 0;
bzf->initialisedOk = True;
return bzf;
}
/*---------------------------------------------------*/
void BZ_API(bzWrite)
( int* bzerror,
BZFILE* b,
void* buf,
int len )
{
Int32 n, n2, ret;
bzFile* bzf = (bzFile*)b;
BZ_SETERR(BZ_OK);
if (bzf == NULL || buf == NULL || len < 0)
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
if (!(bzf->writing))
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
if (ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return; };
if (len == 0)
{ BZ_SETERR(BZ_OK); return; };
bzf->strm.avail_in = len;
bzf->strm.next_in = buf;
while (True) {
bzf->strm.avail_out = BZ_MAX_UNUSED;
bzf->strm.next_out = bzf->buf;
ret = bzCompress ( &(bzf->strm), BZ_RUN );
if (ret != BZ_RUN_OK)
{ BZ_SETERR(ret); return; };
if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
n = BZ_MAX_UNUSED - bzf->strm.avail_out;
n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
n, bzf->handle );
if (n != n2 || ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return; };
}
if (bzf->strm.avail_in == 0)
{ BZ_SETERR(BZ_OK); return; };
}
}
/*---------------------------------------------------*/
void BZ_API(bzWriteClose)
( int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out )
{
Int32 n, n2, ret;
bzFile* bzf = (bzFile*)b;
if (bzf == NULL)
{ BZ_SETERR(BZ_OK); return; };
if (!(bzf->writing))
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
if (ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return; };
if (nbytes_in != NULL) *nbytes_in = 0;
if (nbytes_out != NULL) *nbytes_out = 0;
if ((!abandon) && bzf->lastErr == BZ_OK) {
while (True) {
bzf->strm.avail_out = BZ_MAX_UNUSED;
bzf->strm.next_out = bzf->buf;
ret = bzCompress ( &(bzf->strm), BZ_FINISH );
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
{ BZ_SETERR(ret); return; };
if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
n = BZ_MAX_UNUSED - bzf->strm.avail_out;
n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
n, bzf->handle );
if (n != n2 || ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return; };
}
if (ret == BZ_STREAM_END) break;
}
}
if ( !abandon && !ferror ( bzf->handle ) ) {
fflush ( bzf->handle );
if (ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return; };
}
if (nbytes_in != NULL) *nbytes_in = bzf->strm.total_in;
if (nbytes_out != NULL) *nbytes_out = bzf->strm.total_out;
BZ_SETERR(BZ_OK);
bzCompressEnd ( &(bzf->strm) );
free ( bzf );
}
/*---------------------------------------------------*/
BZFILE* BZ_API(bzReadOpen)
( int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused )
{
bzFile* bzf = NULL;
int ret;
BZ_SETERR(BZ_OK);
if (f == NULL ||
(small != 0 && small != 1) ||
(verbosity < 0 || verbosity > 4) ||
(unused == NULL && nUnused != 0) ||
(unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
{ BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
if (ferror(f))
{ BZ_SETERR(BZ_IO_ERROR); return NULL; };
bzf = malloc ( sizeof(bzFile) );
if (bzf == NULL)
{ BZ_SETERR(BZ_MEM_ERROR); return NULL; };
BZ_SETERR(BZ_OK);
bzf->initialisedOk = False;
bzf->handle = f;
bzf->bufN = 0;
bzf->writing = False;
bzf->strm.bzalloc = NULL;
bzf->strm.bzfree = NULL;
bzf->strm.opaque = NULL;
while (nUnused > 0) {
bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
unused = ((void*)( 1 + ((UChar*)(unused)) ));
nUnused--;
}
ret = bzDecompressInit ( &(bzf->strm), verbosity, small );
if (ret != BZ_OK)
{ BZ_SETERR(ret); free(bzf); return NULL; };
bzf->strm.avail_in = bzf->bufN;
bzf->strm.next_in = bzf->buf;
bzf->initialisedOk = True;
return bzf;
}
/*---------------------------------------------------*/
void BZ_API(bzReadClose) ( int *bzerror, BZFILE *b )
{
bzFile* bzf = (bzFile*)b;
BZ_SETERR(BZ_OK);
if (bzf == NULL)
{ BZ_SETERR(BZ_OK); return; };
if (bzf->writing)
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
if (bzf->initialisedOk)
(void)bzDecompressEnd ( &(bzf->strm) );
free ( bzf );
}
/*---------------------------------------------------*/
int BZ_API(bzRead)
( int* bzerror,
BZFILE* b,
void* buf,
int len )
{
Int32 n, ret;
bzFile* bzf = (bzFile*)b;
BZ_SETERR(BZ_OK);
if (bzf == NULL || buf == NULL || len < 0)
{ BZ_SETERR(BZ_PARAM_ERROR); return 0; };
if (bzf->writing)
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
if (len == 0)
{ BZ_SETERR(BZ_OK); return 0; };
bzf->strm.avail_out = len;
bzf->strm.next_out = buf;
while (True) {
if (ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
n = fread ( bzf->buf, sizeof(UChar),
BZ_MAX_UNUSED, bzf->handle );
if (ferror(bzf->handle))
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
bzf->bufN = n;
bzf->strm.avail_in = bzf->bufN;
bzf->strm.next_in = bzf->buf;
}
ret = bzDecompress ( &(bzf->strm) );
if (ret != BZ_OK && ret != BZ_STREAM_END)
{ BZ_SETERR(ret); return 0; };
if (ret == BZ_OK && myfeof(bzf->handle) &&
bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
{ BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
if (ret == BZ_STREAM_END)
{ BZ_SETERR(BZ_STREAM_END);
return len - bzf->strm.avail_out; };
if (bzf->strm.avail_out == 0)
{ BZ_SETERR(BZ_OK); return len; };
}
return 0; /*not reached*/
}
/*---------------------------------------------------*/
void BZ_API(bzReadGetUnused)
( int* bzerror,
BZFILE* b,
void* vUnused,
int* nUnused )
{
void** unused = (void*)vUnused;
bzFile* bzf = (bzFile*)b;
if (bzf == NULL)
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
if (bzf->lastErr != BZ_STREAM_END)
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
if (unused == NULL || nUnused == NULL)
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
BZ_SETERR(BZ_OK);
*nUnused = bzf->strm.avail_in;
*unused = bzf->strm.next_in;
}
#endif
/*---------------------------------------------------*/
/*--- Misc convenience stuff ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
int BZ_API(bzBuffToBuffCompress)
( char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor )
{
bz_stream strm;
int ret;
if (dest == NULL || destLen == NULL ||
source == NULL ||
blockSize100k < 1 || blockSize100k > 9 ||
verbosity < 0 || verbosity > 4 ||
workFactor < 0 || workFactor > 250)
return BZ_PARAM_ERROR;
if (workFactor == 0) workFactor = 30;
strm.bzalloc = NULL;
strm.bzfree = NULL;
strm.opaque = NULL;
ret = bzCompressInit ( &strm, blockSize100k,
verbosity, workFactor );
if (ret != BZ_OK) return ret;
strm.next_in = source;
strm.next_out = dest;
strm.avail_in = sourceLen;
strm.avail_out = *destLen;
ret = bzCompress ( &strm, BZ_FINISH );
if (ret == BZ_FINISH_OK) goto output_overflow;
if (ret != BZ_STREAM_END) goto errhandler;
/* normal termination */
*destLen -= strm.avail_out;
bzCompressEnd ( &strm );
return BZ_OK;
output_overflow:
bzCompressEnd ( &strm );
return BZ_OUTBUFF_FULL;
errhandler:
bzCompressEnd ( &strm );
return ret;
}
/*---------------------------------------------------*/
int BZ_API(bzBuffToBuffDecompress)
( char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity )
{
bz_stream strm;
int ret;
if (dest == NULL || destLen == NULL ||
source == NULL ||
(small != 0 && small != 1) ||
verbosity < 0 || verbosity > 4)
return BZ_PARAM_ERROR;
strm.bzalloc = NULL;
strm.bzfree = NULL;
strm.opaque = NULL;
ret = bzDecompressInit ( &strm, verbosity, small );
if (ret != BZ_OK) return ret;
strm.next_in = source;
strm.next_out = dest;
strm.avail_in = sourceLen;
strm.avail_out = *destLen;
ret = bzDecompress ( &strm );
if (ret == BZ_OK) goto output_overflow_or_eof;
if (ret != BZ_STREAM_END) goto errhandler;
/* normal termination */
*destLen -= strm.avail_out;
bzDecompressEnd ( &strm );
return BZ_OK;
output_overflow_or_eof:
if (strm.avail_out > 0) {
bzDecompressEnd ( &strm );
return BZ_UNEXPECTED_EOF;
} else {
bzDecompressEnd ( &strm );
return BZ_OUTBUFF_FULL;
};
errhandler:
bzDecompressEnd ( &strm );
return BZ_SEQUENCE_ERROR;
}
/*---------------------------------------------------*/
/*--
Code contributed by Yoshioka Tsuneo
(QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
/*--
return version like "0.9.0c".
--*/
const char * BZ_API(bzlibVersion)(void)
{
return BZ_VERSION;
}
#ifndef BZ_NO_STDIO
/*---------------------------------------------------*/
#if defined(_WIN32) && !_WINIX || defined(OS2) || defined(MSDOS)
# include <fcntl.h>
# include <io.h>
# ifdef _MSC_VER
# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
# else
# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
# endif
#else
# define SET_BINARY_MODE(file)
#endif
static
BZFILE * bzopen_internal
( const char *path, /* if !=0 */
FILE *fp, /* if !=0 && path==0 */
int fd, /* if path==0 && fp==0 */
const char *mode,
const void* buf,
unsigned int len)
{
int bzerr;
char unused[BZ_MAX_UNUSED];
char mode2[10];
int blockSize100k = 9;
int writing = 0;
BZFILE *bzfp = NULL;
int verbosity = 0;
int workFactor = 30;
int smallMode = 0;
int nUnused = 0;
int noClose = 0;
if(mode==NULL){return NULL;}
while(*mode){
switch(*mode){
case 'r':
writing = 0;break;
case 'w':
writing = 1;break;
case 's':
smallMode = 1;break;
case 'o':
noClose = 1;break;
default:
if(isdigit(*mode)){
blockSize100k = 0;
while(isdigit(*mode)){
blockSize100k = blockSize100k*10 + *mode-'0';
mode++;
}
}else{
/* ignore */
}
}
mode++;
}
strcpy(mode2, writing ? "w" : "r" );
strcat(mode2,"b"); /* binary mode */
if(path) {
if(path[0]==0){
fp = (writing ? stdout : stdin);
noClose = 1;
SET_BINARY_MODE(fp);
}else{
fp = fopen(path,mode2);
}
}else if (fp==0) {
#ifdef BZ_STRICT_ANSI
fp = NULL;
#else
fp = fdopen(fd,mode2);
#endif
}
if(fp==NULL){return NULL;}
if(writing){
bzfp = bzWriteOpen(&bzerr,fp,blockSize100k,verbosity,workFactor);
}else{
bzfp = bzReadOpen(&bzerr,fp,verbosity,smallMode,unused,nUnused);
}
if(bzfp==NULL){
if(!noClose) fclose(fp);
return NULL;
}
((bzFile*)bzfp)->noclose = noClose;
return bzfp;
}
/*---------------------------------------------------*/
/*--
open file for read or write.
ex) bzopen("file","w9")
case path="" or NULL => use stdin or stdout.
--*/
BZFILE * BZ_API(bzopen)
( const char *path,
const char *mode )
{
return bzopen_internal(path,NULL,-1,mode,NULL,0);
}
/*---------------------------------------------------*/
BZFILE * BZ_API(bzfopen)
( FILE *fp,
const char *mode )
{
return bzopen_internal(NULL,fp,-1,mode,NULL,0);
}
/*---------------------------------------------------*/
BZFILE * BZ_API(bzdopen)
( int fd,
const char *mode )
{
return bzopen_internal(NULL,NULL,fd,mode,NULL,0);
}
/*---------------------------------------------------*/
BZFILE * BZ_API(bzbopen)
( int fd,
const char* mode,
const void* buf,
unsigned int len )
{
return bzopen_internal(NULL,NULL,fd,mode,buf,len);
}
/*---------------------------------------------------*/
int BZ_API(bzread) (BZFILE* b, void* buf, int len )
{
int bzerr, nread;
if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
nread = bzRead(&bzerr,b,buf,len);
if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
return nread;
} else {
return -1;
}
}
/*---------------------------------------------------*/
int BZ_API(bzwrite) (BZFILE* b, const void* buf, int len )
{
int bzerr;
bzWrite(&bzerr,b,(void*)buf,len);
if(bzerr == BZ_OK){
return len;
}else{
return -1;
}
}
/*---------------------------------------------------*/
int BZ_API(bzflush) (BZFILE *b)
{
Int32 n, n2, ret;
bzFile* bzf = (bzFile*)b;
if (bzf == NULL)
return -1;
if (!(bzf->writing))
return 0;
if (ferror(bzf->handle))
return -1;
do {
bzf->strm.avail_out = BZ_MAX_UNUSED;
bzf->strm.next_out = bzf->buf;
ret = bzCompress ( &(bzf->strm), BZ_FLUSH );
if (ret != BZ_FLUSH_OK && ret != BZ_RUN_OK)
return -1;
if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
n = BZ_MAX_UNUSED - bzf->strm.avail_out;
n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), n, bzf->handle );
if (n != n2 || ferror(bzf->handle))
return -1;
}
} while (ret == BZ_FLUSH_OK);
return 0;
}
/*---------------------------------------------------*/
int BZ_API(bzclose) (BZFILE* b)
{
int bzerr;
FILE *fp = ((bzFile *)b)->handle;
if(b==NULL){return -1;}
if(((bzFile*)b)->writing){
bzWriteClose(&bzerr,b,0,NULL,NULL);
if(bzerr != BZ_OK){
bzWriteClose(NULL,b,1,NULL,NULL);
return -1;
}
}else{
bzReadClose(&bzerr,b);
if(bzerr != BZ_OK)
return -1;
}
if(!((bzFile*)b)->noclose){
return fclose(fp);
}
return 0;
}
/*---------------------------------------------------*/
/*--
return last error code
--*/
static char *bzerrorstrings[] = {
"OK"
,"SEQUENCE_ERROR"
,"PARAM_ERROR"
,"MEM_ERROR"
,"DATA_ERROR"
,"DATA_ERROR_MAGIC"
,"IO_ERROR"
,"UNEXPECTED_EOF"
,"OUTBUFF_FULL"
,"???" /* for future */
,"???" /* for future */
,"???" /* for future */
,"???" /* for future */
,"???" /* for future */
,"???" /* for future */
};
const char * BZ_API(bzerror) (BZFILE *b, int *errnum)
{
int err = ((bzFile *)b)->lastErr;
if(err>0) err = 0;
*errnum = err;
return bzerrorstrings[err*-1];
}
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.c ---*/
/*-------------------------------------------------------------*/