From 94db38358c3f9b5f8ddbe25b5711c71eba3d3700 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Tue, 4 Feb 2014 13:39:55 -0800 Subject: [PATCH] add zlib/minizip so we can load compressed data (github/git is bad in handling large binary files) --- btgui/minizip/crypt.h | 131 + btgui/minizip/ioapi.c | 235 ++ btgui/minizip/ioapi.h | 200 ++ btgui/minizip/unzip.c | 2125 +++++++++++++++++ btgui/minizip/unzip.h | 437 ++++ btgui/minizip/zip.c | 2004 ++++++++++++++++ btgui/minizip/zip.h | 362 +++ btgui/zlib/adler32.c | 179 ++ btgui/zlib/compress.c | 80 + btgui/zlib/crc32.c | 425 ++++ btgui/zlib/crc32.h | 441 ++++ btgui/zlib/deflate.c | 1967 +++++++++++++++ btgui/zlib/deflate.h | 346 +++ btgui/zlib/gzclose.c | 25 + btgui/zlib/gzguts.h | 209 ++ btgui/zlib/gzlib.c | 634 +++++ btgui/zlib/gzread.c | 594 +++++ btgui/zlib/gzwrite.c | 577 +++++ btgui/zlib/infback.c | 640 +++++ btgui/zlib/inffast.c | 340 +++ btgui/zlib/inffast.h | 11 + btgui/zlib/inffixed.h | 94 + btgui/zlib/inflate.c | 1512 ++++++++++++ btgui/zlib/inflate.h | 122 + btgui/zlib/inftrees.c | 306 +++ btgui/zlib/inftrees.h | 62 + btgui/zlib/trees.c | 1226 ++++++++++ btgui/zlib/trees.h | 128 + btgui/zlib/uncompr.c | 59 + btgui/zlib/zconf.h | 511 ++++ btgui/zlib/zlib.h | 1768 ++++++++++++++ btgui/zlib/zutil.c | 324 +++ btgui/zlib/zutil.h | 253 ++ data/unittest_data.zip | Bin 0 -> 574900 bytes .../ParallelPrimitives/b3LauncherCL.cpp | 4 +- .../ParallelPrimitives/b3LauncherCL.h | 10 + .../testExecuteBullet3NarrowphaseKernels.cpp | 495 ++++ test/TestBullet3OpenCL/premake4.lua | 8 +- 38 files changed, 18842 insertions(+), 2 deletions(-) create mode 100644 btgui/minizip/crypt.h create mode 100644 btgui/minizip/ioapi.c create mode 100644 btgui/minizip/ioapi.h create mode 100644 btgui/minizip/unzip.c create mode 100644 btgui/minizip/unzip.h create mode 100644 btgui/minizip/zip.c create mode 100644 btgui/minizip/zip.h create mode 100644 btgui/zlib/adler32.c create mode 100644 btgui/zlib/compress.c create mode 100644 btgui/zlib/crc32.c create mode 100644 btgui/zlib/crc32.h create mode 100644 btgui/zlib/deflate.c create mode 100644 btgui/zlib/deflate.h create mode 100644 btgui/zlib/gzclose.c create mode 100644 btgui/zlib/gzguts.h create mode 100644 btgui/zlib/gzlib.c create mode 100644 btgui/zlib/gzread.c create mode 100644 btgui/zlib/gzwrite.c create mode 100644 btgui/zlib/infback.c create mode 100644 btgui/zlib/inffast.c create mode 100644 btgui/zlib/inffast.h create mode 100644 btgui/zlib/inffixed.h create mode 100644 btgui/zlib/inflate.c create mode 100644 btgui/zlib/inflate.h create mode 100644 btgui/zlib/inftrees.c create mode 100644 btgui/zlib/inftrees.h create mode 100644 btgui/zlib/trees.c create mode 100644 btgui/zlib/trees.h create mode 100644 btgui/zlib/uncompr.c create mode 100644 btgui/zlib/zconf.h create mode 100644 btgui/zlib/zlib.h create mode 100644 btgui/zlib/zutil.c create mode 100644 btgui/zlib/zutil.h create mode 100644 data/unittest_data.zip create mode 100644 test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp diff --git a/btgui/minizip/crypt.h b/btgui/minizip/crypt.h new file mode 100644 index 000000000..a01d08d93 --- /dev/null +++ b/btgui/minizip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned long* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/btgui/minizip/ioapi.c b/btgui/minizip/ioapi.c new file mode 100644 index 000000000..49958f61f --- /dev/null +++ b/btgui/minizip/ioapi.c @@ -0,0 +1,235 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if (defined(_WIN32)) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen64((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = ftello64((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/btgui/minizip/ioapi.h b/btgui/minizip/ioapi.h new file mode 100644 index 000000000..6e98495eb --- /dev/null +++ b/btgui/minizip/ioapi.h @@ -0,0 +1,200 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include +#include +#include "../zlib/zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/btgui/minizip/unzip.c b/btgui/minizip/unzip.c new file mode 100644 index 000000000..21878de0f --- /dev/null +++ b/btgui/minizip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "../zlib/zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == (unsigned long)-1) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if (err==UNZ_OK) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/btgui/minizip/unzip.h b/btgui/minizip/unzip.h new file mode 100644 index 000000000..910dda07a --- /dev/null +++ b/btgui/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "../zlib/zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/btgui/minizip/zip.c b/btgui/minizip/zip.c new file mode 100644 index 000000000..a024136a0 --- /dev/null +++ b/btgui/minizip/zip.c @@ -0,0 +1,2004 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "../zlib/zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/btgui/minizip/zip.h b/btgui/minizip/zip.h new file mode 100644 index 000000000..510907c5b --- /dev/null +++ b/btgui/minizip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "../zlib/zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/btgui/zlib/adler32.c b/btgui/zlib/adler32.c new file mode 100644 index 000000000..a868f073d --- /dev/null +++ b/btgui/zlib/adler32.c @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/btgui/zlib/compress.c b/btgui/zlib/compress.c new file mode 100644 index 000000000..6e9762676 --- /dev/null +++ b/btgui/zlib/compress.c @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/btgui/zlib/crc32.c b/btgui/zlib/crc32.c new file mode 100644 index 000000000..979a7190a --- /dev/null +++ b/btgui/zlib/crc32.c @@ -0,0 +1,425 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + z_crc_t endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/btgui/zlib/crc32.h b/btgui/zlib/crc32.h new file mode 100644 index 000000000..9e0c77810 --- /dev/null +++ b/btgui/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/btgui/zlib/deflate.c b/btgui/zlib/deflate.c new file mode 100644 index 000000000..696957705 --- /dev/null +++ b/btgui/zlib/deflate.c @@ -0,0 +1,1967 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/btgui/zlib/deflate.h b/btgui/zlib/deflate.h new file mode 100644 index 000000000..ce0299edd --- /dev/null +++ b/btgui/zlib/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/btgui/zlib/gzclose.c b/btgui/zlib/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/btgui/zlib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/btgui/zlib/gzguts.h b/btgui/zlib/gzguts.h new file mode 100644 index 000000000..d87659d03 --- /dev/null +++ b/btgui/zlib/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/btgui/zlib/gzlib.c b/btgui/zlib/gzlib.c new file mode 100644 index 000000000..fae202ef8 --- /dev/null +++ b/btgui/zlib/gzlib.c @@ -0,0 +1,634 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/btgui/zlib/gzread.c b/btgui/zlib/gzread.c new file mode 100644 index 000000000..bf4538eb2 --- /dev/null +++ b/btgui/zlib/gzread.c @@ -0,0 +1,594 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/btgui/zlib/gzwrite.c b/btgui/zlib/gzwrite.c new file mode 100644 index 000000000..aa767fbf6 --- /dev/null +++ b/btgui/zlib/gzwrite.c @@ -0,0 +1,577 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (z_const Bytef *)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/btgui/zlib/infback.c b/btgui/zlib/infback.c new file mode 100644 index 000000000..f3833c2e4 --- /dev/null +++ b/btgui/zlib/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/btgui/zlib/inffast.c b/btgui/zlib/inffast.c new file mode 100644 index 000000000..bda59ceb6 --- /dev/null +++ b/btgui/zlib/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/btgui/zlib/inffast.h b/btgui/zlib/inffast.h new file mode 100644 index 000000000..e5c1aa4ca --- /dev/null +++ b/btgui/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/btgui/zlib/inffixed.h b/btgui/zlib/inffixed.h new file mode 100644 index 000000000..d62832776 --- /dev/null +++ b/btgui/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/btgui/zlib/inflate.c b/btgui/zlib/inflate.c new file mode 100644 index 000000000..870f89bb4 --- /dev/null +++ b/btgui/zlib/inflate.c @@ -0,0 +1,1512 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, end, copy) +z_streamp strm; +const Bytef *end; +unsigned copy; +{ + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +const unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/btgui/zlib/inflate.h b/btgui/zlib/inflate.h new file mode 100644 index 000000000..95f4986d4 --- /dev/null +++ b/btgui/zlib/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/btgui/zlib/inftrees.c b/btgui/zlib/inftrees.c new file mode 100644 index 000000000..44d89cf24 --- /dev/null +++ b/btgui/zlib/inftrees.c @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/btgui/zlib/inftrees.h b/btgui/zlib/inftrees.h new file mode 100644 index 000000000..baa53a0b1 --- /dev/null +++ b/btgui/zlib/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/btgui/zlib/trees.c b/btgui/zlib/trees.c new file mode 100644 index 000000000..1fd7759ef --- /dev/null +++ b/btgui/zlib/trees.c @@ -0,0 +1,1226 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/btgui/zlib/trees.h b/btgui/zlib/trees.h new file mode 100644 index 000000000..d35639d82 --- /dev/null +++ b/btgui/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/btgui/zlib/uncompr.c b/btgui/zlib/uncompr.c new file mode 100644 index 000000000..242e9493d --- /dev/null +++ b/btgui/zlib/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/btgui/zlib/zconf.h b/btgui/zlib/zconf.h new file mode 100644 index 000000000..9987a7755 --- /dev/null +++ b/btgui/zlib/zconf.h @@ -0,0 +1,511 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/btgui/zlib/zlib.h b/btgui/zlib/zlib.h new file mode 100644 index 000000000..3e0c7672a --- /dev/null +++ b/btgui/zlib/zlib.h @@ -0,0 +1,1768 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.8, April 28th, 2013 + + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/btgui/zlib/zutil.c b/btgui/zlib/zutil.c new file mode 100644 index 000000000..23d2ebef0 --- /dev/null +++ b/btgui/zlib/zutil.c @@ -0,0 +1,324 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +z_const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/btgui/zlib/zutil.h b/btgui/zlib/zutil.h new file mode 100644 index 000000000..24ab06b1c --- /dev/null +++ b/btgui/zlib/zutil.h @@ -0,0 +1,253 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/data/unittest_data.zip b/data/unittest_data.zip new file mode 100644 index 0000000000000000000000000000000000000000..2de6cdc569018816562f828a2bd8ac05cb1ff27e GIT binary patch literal 574900 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þiVh5x9ke{Aeo?EZ<4_WVw*uNO0w1@9rlZi@B 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%0A)17iIU{{Y(=Qd<3bG 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⩔k;pDif_w{^EN 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

7>nYBlzN9iNjbkm}o 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 literal 0 HcmV?d00001 diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp index 7dfcd9c5c..94590d11c 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp @@ -22,8 +22,10 @@ b3LauncherCL::~b3LauncherCL() { for (int i=0;igetBufferCL()); + delete (m_arrays[i]); } + + m_arrays.clear(); if (gDebugLauncherCL) { static int counter = 0; diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h index 055f70da0..1b267b31e 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h @@ -63,6 +63,16 @@ class b3LauncherCL int serializeArguments(unsigned char* destBuffer, int destBufferCapacity); + int getNumArguments() const + { + return m_kernelArguments.size(); + } + + b3KernelArgData getArgument(int index) + { + return m_kernelArguments[index]; + } + void serializeToFile(const char* fileName, int numWorkItems); template diff --git a/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp b/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp new file mode 100644 index 000000000..b11de392c --- /dev/null +++ b/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp @@ -0,0 +1,495 @@ + +#include +#include "Bullet3Common/b3Logging.h" +#include "Bullet3Common/b3CommandLineArgs.h" +#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" + +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/satKernels.h" +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/mprKernels.h" +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/satConcaveKernels.h" +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.h" +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h" +#include "Bullet3OpenCL/NarrowphaseCollision/kernels/primitiveContacts.h" + +#ifdef B3_USE_ZLIB +#include "../btgui/minizip/unzip.h" +#endif + +#include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" +extern int gArgc; +extern char** gArgv; + +namespace +{ + struct ExecuteBullet3NarrowphaseKernels : public ::testing::Test + { + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + ExecuteBullet3NarrowphaseKernels() + :m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) + { + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc,gArgv); + int preferredDeviceIndex=-1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; + + + initCL(preferredDeviceIndex, preferredPlatformIndex, allowCpuOpenCL); + } + + virtual ~ExecuteBullet3NarrowphaseKernels() + { + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + void initCL(int preferredDeviceIndex, int preferredPlatformIndex, bool allowCpuOpenCL) + { + void* glCtx=0; + void* glDC = 0; + + + + int ciErrNum = 0; + + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; + if (allowCpuOpenCL) + deviceType = CL_DEVICE_TYPE_ALL; + + + + // if (useInterop) + // { + // m_data->m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + // } else + { + m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex,&m_platformId); + ASSERT_FALSE(m_clContext==0); + } + + + ASSERT_EQ(ciErrNum, CL_SUCCESS); + + int numDev = b3OpenCLUtils::getNumDevices(m_clContext); + EXPECT_GT(numDev,0); + + if (numDev>0) + { + m_clDevice= b3OpenCLUtils::getDevice(m_clContext,0); + ASSERT_FALSE(m_clDevice==0); + + m_clQueue = clCreateCommandQueue(m_clContext, m_clDevice, 0, &ciErrNum); + ASSERT_FALSE(m_clQueue==0); + + ASSERT_EQ(ciErrNum, CL_SUCCESS); + + + b3OpenCLDeviceInfo info; + b3OpenCLUtils::getDeviceInfo(m_clDevice,&info); + m_clDeviceName = info.m_deviceName; + } + } + + void exitCL() + { + clReleaseCommandQueue(m_clQueue); + clReleaseContext(m_clContext); + } + + virtual void SetUp() + { + + + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } + }; + +#if 0 + TEST_F(ExecuteBullet3NarrowphaseKernels,satKernelsCL) + { + cl_int errNum=0; + + char flags[1024]={0}; + + cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satKernelsCL,&errNum,flags,0,true); + ASSERT_EQ(errNum,CL_SUCCESS); + + + { + cl_kernel m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findSeparatingAxisKernel ); + } + + { + cl_kernel m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisVertexFaceKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findSeparatingAxisVertexFaceKernel); + } + + { + cl_kernel m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisEdgeEdgeKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findSeparatingAxisEdgeEdgeKernel); + } + + { + cl_kernel m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findConcaveSeparatingAxisKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findConcaveSeparatingAxisKernel ); + } + + + { + cl_kernel m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findCompoundPairsKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findCompoundPairsKernel); + } + + { + cl_kernel m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "processCompoundPairsKernel",&errNum,satProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_processCompoundPairsKernel); + } + + clReleaseProgram(satProg); + + } + + TEST_F(ExecuteBullet3NarrowphaseKernels,satConcaveKernelsCL) + { + cl_int errNum=0; + + char flags[1024]={0}; + + cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satConcaveKernelsCL,&errNum,flags,0,true); + ASSERT_EQ(errNum,CL_SUCCESS); + + { + cl_kernel m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satConcaveKernelsCL, "findConcaveSeparatingAxisVertexFaceKernel",&errNum,satConcaveProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel); + } + + { + cl_kernel m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satConcaveKernelsCL, "findConcaveSeparatingAxisEdgeEdgeKernel",&errNum,satConcaveProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel); + } + + clReleaseProgram(satConcaveProg); + } + + + TEST_F(ExecuteBullet3NarrowphaseKernels,satClipKernelsCL) + { + + char flags[1024]={0}; + cl_int errNum=0; +//#ifdef CL_PLATFORM_INTEL +// sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl"); +//#endif + + cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satClipKernelsCL,&errNum,flags,0,true); + ASSERT_EQ(errNum,CL_SUCCESS); + + { + cl_kernel m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipHullHullKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_clipHullHullKernel); + } + + { + cl_kernel m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipCompoundsHullHullKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(m_clipCompoundsHullHullKernel); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "findClippingFacesKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipFacesAndFindContactsKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipHullHullConcaveConvexKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, + "newContactReductionKernel",&errNum,satClipContactsProg); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + clReleaseProgram(satClipContactsProg); + } + + + TEST_F(ExecuteBullet3NarrowphaseKernels,bvhTraversalKernels) + { + + + cl_int errNum=0; + cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,bvhTraversalKernelCL,&errNum,"",0,true); + ASSERT_EQ(errNum,CL_SUCCESS); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,bvhTraversalKernelCL, "bvhTraversalKernel",&errNum,bvhTraversalProg,""); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + clReleaseProgram(bvhTraversalProg); + } + + TEST_F(ExecuteBullet3NarrowphaseKernels,primitiveContactsKernelsCL) + { + cl_int errNum=0; + cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,primitiveContactsKernelsCL,&errNum,"",0,true); + ASSERT_EQ(errNum,CL_SUCCESS); + + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "primitiveContactsKernel",&errNum,primitiveContactsProg,""); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "findConcaveSphereContactsKernel",&errNum,primitiveContactsProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "processCompoundPairsPrimitivesKernel",&errNum,primitiveContactsProg,""); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + clReleaseProgram(primitiveContactsProg); + } + +#endif + + unsigned char* openFile(const char* fileName, int* sizeInBytesPtr) + { + *sizeInBytesPtr=0; + + unsigned char* buffer = 0; + const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; + int numPrefixes = sizeof(prefix)/sizeof(const char*); + char relativeFileName[1024]; + + +#ifdef B3_USE_ZLIB + + { + FILE* f=0; + int result = 0; + + for (int i=0;!f && i totalContactsOut(this->m_clContext,this->m_clQueue); + totalContactsOut.setFromOpenCLBuffer(data.m_clBuffer,1); + int numContacts = totalContactsOut.at(0); + ASSERT_EQ(numContacts,results[i]); + } + //printf("numContacts = %d\n",numContacts); + + //nContacts = m_totalContactsOut.at(0); + } + + + + + + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,mprKernelsCL, "findSeparatingAxisUnitSphereKernel",&errNum,mprProg ); + ASSERT_EQ(errNum,CL_SUCCESS); + clReleaseKernel(k); + } + + + clReleaseProgram(mprProg); + } + + +}; diff --git a/test/TestBullet3OpenCL/premake4.lua b/test/TestBullet3OpenCL/premake4.lua index 56147e2f0..d0fa62745 100644 --- a/test/TestBullet3OpenCL/premake4.lua +++ b/test/TestBullet3OpenCL/premake4.lua @@ -24,7 +24,13 @@ function createProject(vendor) -- "Bullet3Geometry", "Bullet3Common" } - + + --you can comment out the following few lines, then you need to unzip the untest_data.zip manually + defines {"B3_USE_ZLIB"} + files { + "../../btgui/minizip/*.c", + "../../btgui/zlib/*.c", + } files { "**.cpp",