Updated wx/zlib code (fixes build break on later MSVC versions).
This commit is contained in:
parent
647ce6ae78
commit
9a0404f410
|
@ -1,6 +1,623 @@
|
|||
|
||||
ChangeLog file for zlib
|
||||
|
||||
Changes in 1.2.8 (28 Apr 2013)
|
||||
- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
|
||||
- Do not force Z_CONST for C++
|
||||
- Clean up contrib/vstudio [Ro§]
|
||||
- Correct spelling error in zlib.h
|
||||
- Fix mixed line endings in contrib/vstudio
|
||||
|
||||
Changes in 1.2.7.3 (13 Apr 2013)
|
||||
- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
|
||||
|
||||
Changes in 1.2.7.2 (13 Apr 2013)
|
||||
- Change check for a four-byte type back to hexadecimal
|
||||
- Fix typo in win32/Makefile.msc
|
||||
- Add casts in gzwrite.c for pointer differences
|
||||
|
||||
Changes in 1.2.7.1 (24 Mar 2013)
|
||||
- Replace use of unsafe string functions with snprintf if available
|
||||
- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
|
||||
- Fix gzgetc undefine when Z_PREFIX set [Turk]
|
||||
- Eliminate use of mktemp in Makefile (not always available)
|
||||
- Fix bug in 'F' mode for gzopen()
|
||||
- Add inflateGetDictionary() function
|
||||
- Correct comment in deflate.h
|
||||
- Use _snprintf for snprintf in Microsoft C
|
||||
- On Darwin, only use /usr/bin/libtool if libtool is not Apple
|
||||
- Delete "--version" file if created by "ar --version" [Richard G.]
|
||||
- Fix configure check for veracity of compiler error return codes
|
||||
- Fix CMake compilation of static lib for MSVC2010 x64
|
||||
- Remove unused variable in infback9.c
|
||||
- Fix argument checks in gzlog_compress() and gzlog_write()
|
||||
- Clean up the usage of z_const and respect const usage within zlib
|
||||
- Clean up examples/gzlog.[ch] comparisons of different types
|
||||
- Avoid shift equal to bits in type (caused endless loop)
|
||||
- Fix unintialized value bug in gzputc() introduced by const patches
|
||||
- Fix memory allocation error in examples/zran.c [Nor]
|
||||
- Fix bug where gzopen(), gzclose() would write an empty file
|
||||
- Fix bug in gzclose() when gzwrite() runs out of memory
|
||||
- Check for input buffer malloc failure in examples/gzappend.c
|
||||
- Add note to contrib/blast to use binary mode in stdio
|
||||
- Fix comparisons of differently signed integers in contrib/blast
|
||||
- Check for invalid code length codes in contrib/puff
|
||||
- Fix serious but very rare decompression bug in inftrees.c
|
||||
- Update inflateBack() comments, since inflate() can be faster
|
||||
- Use underscored I/O function names for WINAPI_FAMILY
|
||||
- Add _tr_flush_bits to the external symbols prefixed by --zprefix
|
||||
- Add contrib/vstudio/vc10 pre-build step for static only
|
||||
- Quote --version-script argument in CMakeLists.txt
|
||||
- Don't specify --version-script on Apple platforms in CMakeLists.txt
|
||||
- Fix casting error in contrib/testzlib/testzlib.c
|
||||
- Fix types in contrib/minizip to match result of get_crc_table()
|
||||
- Simplify contrib/vstudio/vc10 with 'd' suffix
|
||||
- Add TOP support to win32/Makefile.msc
|
||||
- Suport i686 and amd64 assembler builds in CMakeLists.txt
|
||||
- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
|
||||
- Add vc11 and vc12 build files to contrib/vstudio
|
||||
- Add gzvprintf() as an undocumented function in zlib
|
||||
- Fix configure for Sun shell
|
||||
- Remove runtime check in configure for four-byte integer type
|
||||
- Add casts and consts to ease user conversion to C++
|
||||
- Add man pages for minizip and miniunzip
|
||||
- In Makefile uninstall, don't rm if preceding cd fails
|
||||
- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
|
||||
|
||||
Changes in 1.2.7 (2 May 2012)
|
||||
- Replace use of memmove() with a simple copy for portability
|
||||
- Test for existence of strerror
|
||||
- Restore gzgetc_ for backward compatibility with 1.2.6
|
||||
- Fix build with non-GNU make on Solaris
|
||||
- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
|
||||
- Include unistd.h for Watcom C
|
||||
- Use __WATCOMC__ instead of __WATCOM__
|
||||
- Do not use the visibility attribute if NO_VIZ defined
|
||||
- Improve the detection of no hidden visibility attribute
|
||||
- Avoid using __int64 for gcc or solo compilation
|
||||
- Cast to char * in gzprintf to avoid warnings [Zinser]
|
||||
- Fix make_vms.com for VAX [Zinser]
|
||||
- Don't use library or built-in byte swaps
|
||||
- Simplify test and use of gcc hidden attribute
|
||||
- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
|
||||
- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
|
||||
- Fix bug in test/minigzip.c for configure --solo
|
||||
- Fix contrib/vstudio project link errors [Mohanathas]
|
||||
- Add ability to choose the builder in make_vms.com [Schweda]
|
||||
- Add DESTDIR support to mingw32 win32/Makefile.gcc
|
||||
- Fix comments in win32/Makefile.gcc for proper usage
|
||||
- Allow overriding the default install locations for cmake
|
||||
- Generate and install the pkg-config file with cmake
|
||||
- Build both a static and a shared version of zlib with cmake
|
||||
- Include version symbols for cmake builds
|
||||
- If using cmake with MSVC, add the source directory to the includes
|
||||
- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
|
||||
- Move obsolete emx makefile to old [Truta]
|
||||
- Allow the use of -Wundef when compiling or using zlib
|
||||
- Avoid the use of the -u option with mktemp
|
||||
- Improve inflate() documentation on the use of Z_FINISH
|
||||
- Recognize clang as gcc
|
||||
- Add gzopen_w() in Windows for wide character path names
|
||||
- Rename zconf.h in CMakeLists.txt to move it out of the way
|
||||
- Add source directory in CMakeLists.txt for building examples
|
||||
- Look in build directory for zlib.pc in CMakeLists.txt
|
||||
- Remove gzflags from zlibvc.def in vc9 and vc10
|
||||
- Fix contrib/minizip compilation in the MinGW environment
|
||||
- Update ./configure for Solaris, support --64 [Mooney]
|
||||
- Remove -R. from Solaris shared build (possible security issue)
|
||||
- Avoid race condition for parallel make (-j) running example
|
||||
- Fix type mismatch between get_crc_table() and crc_table
|
||||
- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
|
||||
- Fix the path to zlib.map in CMakeLists.txt
|
||||
- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
|
||||
- Add instructions to win32/Makefile.gcc for shared install [Torri]
|
||||
|
||||
Changes in 1.2.6.1 (12 Feb 2012)
|
||||
- Avoid the use of the Objective-C reserved name "id"
|
||||
- Include io.h in gzguts.h for Microsoft compilers
|
||||
- Fix problem with ./configure --prefix and gzgetc macro
|
||||
- Include gz_header definition when compiling zlib solo
|
||||
- Put gzflags() functionality back in zutil.c
|
||||
- Avoid library header include in crc32.c for Z_SOLO
|
||||
- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
|
||||
- Minor cleanup in contrib/minizip/zip.c [Vollant]
|
||||
- Update make_vms.com [Zinser]
|
||||
- Remove unnecessary gzgetc_ function
|
||||
- Use optimized byte swap operations for Microsoft and GNU [Snyder]
|
||||
- Fix minor typo in zlib.h comments [Rzesniowiecki]
|
||||
|
||||
Changes in 1.2.6 (29 Jan 2012)
|
||||
- Update the Pascal interface in contrib/pascal
|
||||
- Fix function numbers for gzgetc_ in zlibvc.def files
|
||||
- Fix configure.ac for contrib/minizip [Schiffer]
|
||||
- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
|
||||
- Have ./configure use the compiler return code for error indication
|
||||
- Fix CMakeLists.txt for cross compilation [McClure]
|
||||
- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
|
||||
- Fix compilation of contrib/minizip on FreeBSD [Marquez]
|
||||
- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
|
||||
- Include io.h for Turbo C / Borland C on all platforms [Truta]
|
||||
- Make version explicit in contrib/minizip/configure.ac [Bosmans]
|
||||
- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
|
||||
- Minor cleanup up contrib/minizip/unzip.c [Vollant]
|
||||
- Fix bug when compiling minizip with C++ [Vollant]
|
||||
- Protect for long name and extra fields in contrib/minizip [Vollant]
|
||||
- Avoid some warnings in contrib/minizip [Vollant]
|
||||
- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
|
||||
- Add missing libs to minizip linker command
|
||||
- Add support for VPATH builds in contrib/minizip
|
||||
- Add an --enable-demos option to contrib/minizip/configure
|
||||
- Add the generation of configure.log by ./configure
|
||||
- Exit when required parameters not provided to win32/Makefile.gcc
|
||||
- Have gzputc return the character written instead of the argument
|
||||
- Use the -m option on ldconfig for BSD systems [Tobias]
|
||||
- Correct in zlib.map when deflateResetKeep was added
|
||||
|
||||
Changes in 1.2.5.3 (15 Jan 2012)
|
||||
- Restore gzgetc function for binary compatibility
|
||||
- Do not use _lseeki64 under Borland C++ [Truta]
|
||||
- Update win32/Makefile.msc to build test/*.c [Truta]
|
||||
- Remove old/visualc6 given CMakefile and other alternatives
|
||||
- Update AS400 build files and documentation [Monnerat]
|
||||
- Update win32/Makefile.gcc to build test/*.c [Truta]
|
||||
- Permit stronger flushes after Z_BLOCK flushes
|
||||
- Avoid extraneous empty blocks when doing empty flushes
|
||||
- Permit Z_NULL arguments to deflatePending
|
||||
- Allow deflatePrime() to insert bits in the middle of a stream
|
||||
- Remove second empty static block for Z_PARTIAL_FLUSH
|
||||
- Write out all of the available bits when using Z_BLOCK
|
||||
- Insert the first two strings in the hash table after a flush
|
||||
|
||||
Changes in 1.2.5.2 (17 Dec 2011)
|
||||
- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
|
||||
- use relative symlinks for shared libs
|
||||
- Avoid searching past window for Z_RLE strategy
|
||||
- Assure that high-water mark initialization is always applied in deflate
|
||||
- Add assertions to fill_window() in deflate.c to match comments
|
||||
- Update python link in README
|
||||
- Correct spelling error in gzread.c
|
||||
- Fix bug in gzgets() for a concatenated empty gzip stream
|
||||
- Correct error in comment for gz_make()
|
||||
- Change gzread() and related to ignore junk after gzip streams
|
||||
- Allow gzread() and related to continue after gzclearerr()
|
||||
- Allow gzrewind() and gzseek() after a premature end-of-file
|
||||
- Simplify gzseek() now that raw after gzip is ignored
|
||||
- Change gzgetc() to a macro for speed (~40% speedup in testing)
|
||||
- Fix gzclose() to return the actual error last encountered
|
||||
- Always add large file support for windows
|
||||
- Include zconf.h for windows large file support
|
||||
- Include zconf.h.cmakein for windows large file support
|
||||
- Update zconf.h.cmakein on make distclean
|
||||
- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
|
||||
- Clarify how gzopen() appends in zlib.h comments
|
||||
- Correct documentation of gzdirect() since junk at end now ignored
|
||||
- Add a transparent write mode to gzopen() when 'T' is in the mode
|
||||
- Update python link in zlib man page
|
||||
- Get inffixed.h and MAKEFIXED result to match
|
||||
- Add a ./config --solo option to make zlib subset with no libary use
|
||||
- Add undocumented inflateResetKeep() function for CAB file decoding
|
||||
- Add --cover option to ./configure for gcc coverage testing
|
||||
- Add #define ZLIB_CONST option to use const in the z_stream interface
|
||||
- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
|
||||
- Note behavior of uncompress() to provide as much data as it can
|
||||
- Add files in contrib/minizip to aid in building libminizip
|
||||
- Split off AR options in Makefile.in and configure
|
||||
- Change ON macro to Z_ARG to avoid application conflicts
|
||||
- Facilitate compilation with Borland C++ for pragmas and vsnprintf
|
||||
- Include io.h for Turbo C / Borland C++
|
||||
- Move example.c and minigzip.c to test/
|
||||
- Simplify incomplete code table filling in inflate_table()
|
||||
- Remove code from inflate.c and infback.c that is impossible to execute
|
||||
- Test the inflate code with full coverage
|
||||
- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
|
||||
- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
|
||||
- Fix gzwrite.c to accommodate reduced memory zlib compilation
|
||||
- Have inflate() with Z_FINISH avoid the allocation of a window
|
||||
- Do not set strm->adler when doing raw inflate
|
||||
- Fix gzeof() to behave just like feof() when read is not past end of file
|
||||
- Fix bug in gzread.c when end-of-file is reached
|
||||
- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
|
||||
- Document gzread() capability to read concurrently written files
|
||||
- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
|
||||
|
||||
Changes in 1.2.5.1 (10 Sep 2011)
|
||||
- Update FAQ entry on shared builds (#13)
|
||||
- Avoid symbolic argument to chmod in Makefile.in
|
||||
- Fix bug and add consts in contrib/puff [Oberhumer]
|
||||
- Update contrib/puff/zeros.raw test file to have all block types
|
||||
- Add full coverage test for puff in contrib/puff/Makefile
|
||||
- Fix static-only-build install in Makefile.in
|
||||
- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
|
||||
- Add libz.a dependency to shared in Makefile.in for parallel builds
|
||||
- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
|
||||
- Replace $(...) with `...` in configure for non-bash sh [Bowler]
|
||||
- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
|
||||
- Add solaris* to Linux* in configure to allow gcc use [Groffen]
|
||||
- Add *bsd* to Linux* case in configure [Bar-Lev]
|
||||
- Add inffast.obj to dependencies in win32/Makefile.msc
|
||||
- Correct spelling error in deflate.h [Kohler]
|
||||
- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
|
||||
- Add test to configure for GNU C looking for gcc in output of $cc -v
|
||||
- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
|
||||
- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
|
||||
- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
|
||||
- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
|
||||
- Make stronger test in zconf.h to include unistd.h for LFS
|
||||
- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
|
||||
- Fix zlib.h LFS support when Z_PREFIX used
|
||||
- Add updated as400 support (removed from old) [Monnerat]
|
||||
- Avoid deflate sensitivity to volatile input data
|
||||
- Avoid division in adler32_combine for NO_DIVIDE
|
||||
- Clarify the use of Z_FINISH with deflateBound() amount of space
|
||||
- Set binary for output file in puff.c
|
||||
- Use u4 type for crc_table to avoid conversion warnings
|
||||
- Apply casts in zlib.h to avoid conversion warnings
|
||||
- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
|
||||
- Improve inflateSync() documentation to note indeterminancy
|
||||
- Add deflatePending() function to return the amount of pending output
|
||||
- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
|
||||
- Add a check in configure for stdarg.h, use for gzprintf()
|
||||
- Check that pointers fit in ints when gzprint() compiled old style
|
||||
- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
|
||||
- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
|
||||
- Add debug records in assmebler code [Londer]
|
||||
- Update RFC references to use http://tools.ietf.org/html/... [Li]
|
||||
- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
|
||||
|
||||
Changes in 1.2.5 (19 Apr 2010)
|
||||
- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
|
||||
- Default to libdir as sharedlibdir in configure [Nieder]
|
||||
- Update copyright dates on modified source files
|
||||
- Update trees.c to be able to generate modified trees.h
|
||||
- Exit configure for MinGW, suggesting win32/Makefile.gcc
|
||||
- Check for NULL path in gz_open [Homurlu]
|
||||
|
||||
Changes in 1.2.4.5 (18 Apr 2010)
|
||||
- Set sharedlibdir in configure [Torok]
|
||||
- Set LDFLAGS in Makefile.in [Bar-Lev]
|
||||
- Avoid mkdir objs race condition in Makefile.in [Bowler]
|
||||
- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
|
||||
- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
|
||||
- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
|
||||
|
||||
Changes in 1.2.4.4 (18 Apr 2010)
|
||||
- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
|
||||
- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
|
||||
- Try to use bash or ksh regardless of functionality of /bin/sh
|
||||
- Fix configure incompatibility with NetBSD sh
|
||||
- Remove attempt to run under bash or ksh since have better NetBSD fix
|
||||
- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
|
||||
- Add diagnostic messages when using CROSS_PREFIX in configure
|
||||
- Added --sharedlibdir option to configure [Weigelt]
|
||||
- Use hidden visibility attribute when available [Frysinger]
|
||||
|
||||
Changes in 1.2.4.3 (10 Apr 2010)
|
||||
- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
|
||||
- Use CROSS_PREFIX for nm [Bar-Lev]
|
||||
- Assume _LARGEFILE64_SOURCE defined is equivalent to true
|
||||
- Avoid use of undefined symbols in #if with && and ||
|
||||
- Make *64 prototypes in gzguts.h consistent with functions
|
||||
- Add -shared load option for MinGW in configure [Bowler]
|
||||
- Move z_off64_t to public interface, use instead of off64_t
|
||||
- Remove ! from shell test in configure (not portable to Solaris)
|
||||
- Change +0 macro tests to -0 for possibly increased portability
|
||||
|
||||
Changes in 1.2.4.2 (9 Apr 2010)
|
||||
- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
|
||||
- Really provide prototypes for *64 functions when building without LFS
|
||||
- Only define unlink() in minigzip.c if unistd.h not included
|
||||
- Update README to point to contrib/vstudio project files
|
||||
- Move projects/vc6 to old/ and remove projects/
|
||||
- Include stdlib.h in minigzip.c for setmode() definition under WinCE
|
||||
- Clean up assembler builds in win32/Makefile.msc [Rowe]
|
||||
- Include sys/types.h for Microsoft for off_t definition
|
||||
- Fix memory leak on error in gz_open()
|
||||
- Symbolize nm as $NM in configure [Weigelt]
|
||||
- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
|
||||
- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
|
||||
- Fix bug in gzeof() to take into account unused input data
|
||||
- Avoid initialization of structures with variables in puff.c
|
||||
- Updated win32/README-WIN32.txt [Rowe]
|
||||
|
||||
Changes in 1.2.4.1 (28 Mar 2010)
|
||||
- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
|
||||
- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
|
||||
- Restore "for debugging" comment on sprintf() in gzlib.c
|
||||
- Remove fdopen for MVS from gzguts.h
|
||||
- Put new README-WIN32.txt in win32 [Rowe]
|
||||
- Add check for shell to configure and invoke another shell if needed
|
||||
- Fix big fat stinking bug in gzseek() on uncompressed files
|
||||
- Remove vestigial F_OPEN64 define in zutil.h
|
||||
- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
|
||||
- Avoid errors on non-LFS systems when applications define LFS macros
|
||||
- Set EXE to ".exe" in configure for MINGW [Kahle]
|
||||
- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
|
||||
- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
|
||||
- Add DLL install in win32/makefile.gcc [Bar-Lev]
|
||||
- Allow Linux* or linux* from uname in configure [Bar-Lev]
|
||||
- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
|
||||
- Add cross-compilation prefixes to configure [Bar-Lev]
|
||||
- Match type exactly in gz_load() invocation in gzread.c
|
||||
- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
|
||||
- Provide prototypes for *64 functions when building zlib without LFS
|
||||
- Don't use -lc when linking shared library on MinGW
|
||||
- Remove errno.h check in configure and vestigial errno code in zutil.h
|
||||
|
||||
Changes in 1.2.4 (14 Mar 2010)
|
||||
- Fix VER3 extraction in configure for no fourth subversion
|
||||
- Update zlib.3, add docs to Makefile.in to make .pdf out of it
|
||||
- Add zlib.3.pdf to distribution
|
||||
- Don't set error code in gzerror() if passed pointer is NULL
|
||||
- Apply destination directory fixes to CMakeLists.txt [Lowman]
|
||||
- Move #cmakedefine's to a new zconf.in.cmakein
|
||||
- Restore zconf.h for builds that don't use configure or cmake
|
||||
- Add distclean to dummy Makefile for convenience
|
||||
- Update and improve INDEX, README, and FAQ
|
||||
- Update CMakeLists.txt for the return of zconf.h [Lowman]
|
||||
- Update contrib/vstudio/vc9 and vc10 [Vollant]
|
||||
- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
|
||||
- Apply license and readme changes to contrib/asm686 [Raiter]
|
||||
- Check file name lengths and add -c option in minigzip.c [Li]
|
||||
- Update contrib/amd64 and contrib/masmx86/ [Vollant]
|
||||
- Avoid use of "eof" parameter in trees.c to not shadow library variable
|
||||
- Update make_vms.com for removal of zlibdefs.h [Zinser]
|
||||
- Update assembler code and vstudio projects in contrib [Vollant]
|
||||
- Remove outdated assembler code contrib/masm686 and contrib/asm586
|
||||
- Remove old vc7 and vc8 from contrib/vstudio
|
||||
- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
|
||||
- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
|
||||
- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
|
||||
- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
|
||||
- Fix bug in void-returning vsprintf() case in gzwrite.c
|
||||
- Fix name change from inflate.h in contrib/inflate86/inffas86.c
|
||||
- Check if temporary file exists before removing in make_vms.com [Zinser]
|
||||
- Fix make install and uninstall for --static option
|
||||
- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
|
||||
- Update readme.txt in contrib/masmx64 and masmx86 to assemble
|
||||
|
||||
Changes in 1.2.3.9 (21 Feb 2010)
|
||||
- Expunge gzio.c
|
||||
- Move as400 build information to old
|
||||
- Fix updates in contrib/minizip and contrib/vstudio
|
||||
- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
|
||||
- Delete zconf.h (made by configure) [Weigelt]
|
||||
- Change zconf.in.h to zconf.h.in per convention [Weigelt]
|
||||
- Check for NULL buf in gzgets()
|
||||
- Return empty string for gzgets() with len == 1 (like fgets())
|
||||
- Fix description of gzgets() in zlib.h for end-of-file, NULL return
|
||||
- Update minizip to 1.1 [Vollant]
|
||||
- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
|
||||
- Note in zlib.h that gzerror() should be used to distinguish from EOF
|
||||
- Remove use of snprintf() from gzlib.c
|
||||
- Fix bug in gzseek()
|
||||
- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
|
||||
- Fix zconf.h generation in CMakeLists.txt [Lowman]
|
||||
- Improve comments in zconf.h where modified by configure
|
||||
|
||||
Changes in 1.2.3.8 (13 Feb 2010)
|
||||
- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
|
||||
- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
|
||||
- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
|
||||
- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
|
||||
- Fix missing error return in gzflush(), add zlib.h note
|
||||
- Add *64 functions to zlib.map [Levin]
|
||||
- Fix signed/unsigned comparison in gz_comp()
|
||||
- Use SFLAGS when testing shared linking in configure
|
||||
- Add --64 option to ./configure to use -m64 with gcc
|
||||
- Fix ./configure --help to correctly name options
|
||||
- Have make fail if a test fails [Levin]
|
||||
- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
|
||||
- Remove assembler object files from contrib
|
||||
|
||||
Changes in 1.2.3.7 (24 Jan 2010)
|
||||
- Always gzopen() with O_LARGEFILE if available
|
||||
- Fix gzdirect() to work immediately after gzopen() or gzdopen()
|
||||
- Make gzdirect() more precise when the state changes while reading
|
||||
- Improve zlib.h documentation in many places
|
||||
- Catch memory allocation failure in gz_open()
|
||||
- Complete close operation if seek forward in gzclose_w() fails
|
||||
- Return Z_ERRNO from gzclose_r() if close() fails
|
||||
- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
|
||||
- Return zero for gzwrite() errors to match zlib.h description
|
||||
- Return -1 on gzputs() error to match zlib.h description
|
||||
- Add zconf.in.h to allow recovery from configure modification [Weigelt]
|
||||
- Fix static library permissions in Makefile.in [Weigelt]
|
||||
- Avoid warnings in configure tests that hide functionality [Weigelt]
|
||||
- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
|
||||
- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
|
||||
- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
|
||||
- Keep object files in subdirectories to reduce the clutter somewhat
|
||||
- Remove default Makefile and zlibdefs.h, add dummy Makefile
|
||||
- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
|
||||
- Remove zlibdefs.h completely -- modify zconf.h instead
|
||||
|
||||
Changes in 1.2.3.6 (17 Jan 2010)
|
||||
- Avoid void * arithmetic in gzread.c and gzwrite.c
|
||||
- Make compilers happier with const char * for gz_error message
|
||||
- Avoid unused parameter warning in inflate.c
|
||||
- Avoid signed-unsigned comparison warning in inflate.c
|
||||
- Indent #pragma's for traditional C
|
||||
- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
|
||||
- Correct email address in configure for system options
|
||||
- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
|
||||
- Update zlib.map [Brown]
|
||||
- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
|
||||
- Apply various fixes to CMakeLists.txt [Lowman]
|
||||
- Add checks on len in gzread() and gzwrite()
|
||||
- Add error message for no more room for gzungetc()
|
||||
- Remove zlib version check in gzwrite()
|
||||
- Defer compression of gzprintf() result until need to
|
||||
- Use snprintf() in gzdopen() if available
|
||||
- Remove USE_MMAP configuration determination (only used by minigzip)
|
||||
- Remove examples/pigz.c (available separately)
|
||||
- Update examples/gun.c to 1.6
|
||||
|
||||
Changes in 1.2.3.5 (8 Jan 2010)
|
||||
- Add space after #if in zutil.h for some compilers
|
||||
- Fix relatively harmless bug in deflate_fast() [Exarevsky]
|
||||
- Fix same problem in deflate_slow()
|
||||
- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
|
||||
- Add deflate_rle() for faster Z_RLE strategy run-length encoding
|
||||
- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
|
||||
- Change name of "write" variable in inffast.c to avoid library collisions
|
||||
- Fix premature EOF from gzread() in gzio.c [Brown]
|
||||
- Use zlib header window size if windowBits is 0 in inflateInit2()
|
||||
- Remove compressBound() call in deflate.c to avoid linking compress.o
|
||||
- Replace use of errno in gz* with functions, support WinCE [Alves]
|
||||
- Provide alternative to perror() in minigzip.c for WinCE [Alves]
|
||||
- Don't use _vsnprintf on later versions of MSVC [Lowman]
|
||||
- Add CMake build script and input file [Lowman]
|
||||
- Update contrib/minizip to 1.1 [Svensson, Vollant]
|
||||
- Moved nintendods directory from contrib to .
|
||||
- Replace gzio.c with a new set of routines with the same functionality
|
||||
- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
|
||||
- Update contrib/minizip to 1.1b
|
||||
- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
|
||||
|
||||
Changes in 1.2.3.4 (21 Dec 2009)
|
||||
- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
|
||||
- Update comments in configure and Makefile.in for default --shared
|
||||
- Fix test -z's in configure [Marquess]
|
||||
- Build examplesh and minigzipsh when not testing
|
||||
- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
|
||||
- Import LDFLAGS from the environment in configure
|
||||
- Fix configure to populate SFLAGS with discovered CFLAGS options
|
||||
- Adapt make_vms.com to the new Makefile.in [Zinser]
|
||||
- Add zlib2ansi script for C++ compilation [Marquess]
|
||||
- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
|
||||
- Add AMD64 assembler code for longest match to contrib [Teterin]
|
||||
- Include options from $SFLAGS when doing $LDSHARED
|
||||
- Simplify 64-bit file support by introducing z_off64_t type
|
||||
- Make shared object files in objs directory to work around old Sun cc
|
||||
- Use only three-part version number for Darwin shared compiles
|
||||
- Add rc option to ar in Makefile.in for when ./configure not run
|
||||
- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
|
||||
- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
|
||||
- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
|
||||
- Rename Makefile.in targets allstatic to static and allshared to shared
|
||||
- Fix static and shared Makefile.in targets to be independent
|
||||
- Correct error return bug in gz_open() by setting state [Brown]
|
||||
- Put spaces before ;;'s in configure for better sh compatibility
|
||||
- Add pigz.c (parallel implementation of gzip) to examples/
|
||||
- Correct constant in crc32.c to UL [Leventhal]
|
||||
- Reject negative lengths in crc32_combine()
|
||||
- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
|
||||
- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
|
||||
- Correct typo in doc/algorithm.txt [Janik]
|
||||
- Fix bug in adler32_combine() [Zhu]
|
||||
- Catch missing-end-of-block-code error in all inflates and in puff
|
||||
Assures that random input to inflate eventually results in an error
|
||||
- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
|
||||
- Update ENOUGH and its usage to reflect discovered bounds
|
||||
- Fix gzerror() error report on empty input file [Brown]
|
||||
- Add ush casts in trees.c to avoid pedantic runtime errors
|
||||
- Fix typo in zlib.h uncompress() description [Reiss]
|
||||
- Correct inflate() comments with regard to automatic header detection
|
||||
- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
|
||||
- Put new version of gzlog (2.0) in examples with interruption recovery
|
||||
- Add puff compile option to permit invalid distance-too-far streams
|
||||
- Add puff TEST command options, ability to read piped input
|
||||
- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
|
||||
_LARGEFILE64_SOURCE not defined
|
||||
- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
|
||||
- Fix deflateSetDictionary() to use all 32K for output consistency
|
||||
- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
|
||||
- Clear bytes after deflate lookahead to avoid use of uninitialized data
|
||||
- Change a limit in inftrees.c to be more transparent to Coverity Prevent
|
||||
- Update win32/zlib.def with exported symbols from zlib.h
|
||||
- Correct spelling errors in zlib.h [Willem, Sobrado]
|
||||
- Allow Z_BLOCK for deflate() to force a new block
|
||||
- Allow negative bits in inflatePrime() to delete existing bit buffer
|
||||
- Add Z_TREES flush option to inflate() to return at end of trees
|
||||
- Add inflateMark() to return current state information for random access
|
||||
- Add Makefile for NintendoDS to contrib [Costa]
|
||||
- Add -w in configure compile tests to avoid spurious warnings [Beucler]
|
||||
- Fix typos in zlib.h comments for deflateSetDictionary()
|
||||
- Fix EOF detection in transparent gzread() [Maier]
|
||||
|
||||
Changes in 1.2.3.3 (2 October 2006)
|
||||
- Make --shared the default for configure, add a --static option
|
||||
- Add compile option to permit invalid distance-too-far streams
|
||||
- Add inflateUndermine() function which is required to enable above
|
||||
- Remove use of "this" variable name for C++ compatibility [Marquess]
|
||||
- Add testing of shared library in make test, if shared library built
|
||||
- Use ftello() and fseeko() if available instead of ftell() and fseek()
|
||||
- Provide two versions of all functions that use the z_off_t type for
|
||||
binary compatibility -- a normal version and a 64-bit offset version,
|
||||
per the Large File Support Extension when _LARGEFILE64_SOURCE is
|
||||
defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
|
||||
is defined to be 64
|
||||
- Add a --uname= option to configure to perhaps help with cross-compiling
|
||||
|
||||
Changes in 1.2.3.2 (3 September 2006)
|
||||
- Turn off silly Borland warnings [Hay]
|
||||
- Use off64_t and define _LARGEFILE64_SOURCE when present
|
||||
- Fix missing dependency on inffixed.h in Makefile.in
|
||||
- Rig configure --shared to build both shared and static [Teredesai, Truta]
|
||||
- Remove zconf.in.h and instead create a new zlibdefs.h file
|
||||
- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
|
||||
- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
|
||||
|
||||
Changes in 1.2.3.1 (16 August 2006)
|
||||
- Add watcom directory with OpenWatcom make files [Daniel]
|
||||
- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
|
||||
- Update make_vms.com [Zinser]
|
||||
- Use -fPIC for shared build in configure [Teredesai, Nicholson]
|
||||
- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
|
||||
- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck]
|
||||
- Add some FAQ entries about the contrib directory
|
||||
- Update the MVS question in the FAQ
|
||||
- Avoid extraneous reads after EOF in gzio.c [Brown]
|
||||
- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
|
||||
- Add comments to zlib.h about gzerror() usage [Brown]
|
||||
- Set extra flags in gzip header in gzopen() like deflate() does
|
||||
- Make configure options more compatible with double-dash conventions
|
||||
[Weigelt]
|
||||
- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
|
||||
- Fix uninstall target in Makefile.in [Truta]
|
||||
- Add pkgconfig support [Weigelt]
|
||||
- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
|
||||
- Replace set_data_type() with a more accurate detect_data_type() in
|
||||
trees.c, according to the txtvsbin.txt document [Truta]
|
||||
- Swap the order of #include <stdio.h> and #include "zlib.h" in
|
||||
gzio.c, example.c and minigzip.c [Truta]
|
||||
- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
|
||||
Truta] (where?)
|
||||
- Fix target "clean" from win32/Makefile.bor [Truta]
|
||||
- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
|
||||
- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
|
||||
- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
|
||||
- Enable browse info in the "Debug" and "ASM Debug" configurations in
|
||||
the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
|
||||
- Add pkgconfig support [Weigelt]
|
||||
- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
|
||||
for use in win32/zlib1.rc [Polushin, Rowe, Truta]
|
||||
- Add a document that explains the new text detection scheme to
|
||||
doc/txtvsbin.txt [Truta]
|
||||
- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
|
||||
- Move algorithm.txt into doc/ [Truta]
|
||||
- Synchronize FAQ with website
|
||||
- Fix compressBound(), was low for some pathological cases [Fearnley]
|
||||
- Take into account wrapper variations in deflateBound()
|
||||
- Set examples/zpipe.c input and output to binary mode for Windows
|
||||
- Update examples/zlib_how.html with new zpipe.c (also web site)
|
||||
- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
|
||||
that gcc became pickier in 4.0)
|
||||
- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
|
||||
un-versioned, the patch adds versioning only for symbols introduced in
|
||||
zlib-1.2.0 or later. It also declares as local those symbols which are
|
||||
not designed to be exported." [Levin]
|
||||
- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
|
||||
- Do not initialize global static by default in trees.c, add a response
|
||||
NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
|
||||
- Don't use strerror() in gzio.c under WinCE [Yakimov]
|
||||
- Don't use errno.h in zutil.h under WinCE [Yakimov]
|
||||
- Move arguments for AR to its usage to allow replacing ar [Marot]
|
||||
- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
|
||||
- Improve inflateInit() and inflateInit2() documentation
|
||||
- Fix structure size comment in inflate.h
|
||||
- Change configure help option from --h* to --help [Santos]
|
||||
|
||||
Changes in 1.2.3 (18 July 2005)
|
||||
- Apply security vulnerability fixes to contrib/infback9 as well
|
||||
- Clean up some text files (carriage returns, trailing space)
|
||||
|
@ -13,7 +630,7 @@ Changes in 1.2.2.4 (11 July 2005)
|
|||
compile
|
||||
- Fix some spelling errors in comments [Betts]
|
||||
- Correct inflateInit2() error return documentation in zlib.h
|
||||
- Added zran.c example of compressed data random access to examples
|
||||
- Add zran.c example of compressed data random access to examples
|
||||
directory, shows use of inflatePrime()
|
||||
- Fix cast for assignments to strm->state in inflate.c and infback.c
|
||||
- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
|
||||
|
@ -599,7 +1216,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
|
||||
- added makelcc.bat for lcc-win32 (Tom St Denis)
|
||||
- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
|
||||
- Avoid expanded $Id: ChangeLog 35458 2005-09-10 21:15:17Z MW $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
|
||||
- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
|
||||
- check for unistd.h in configure (for off_t)
|
||||
- remove useless check parameter in inflate_blocks_free
|
||||
- avoid useless assignment of s->check to itself in inflate_blocks_new
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
|
||||
Frequently Asked Questions about zlib
|
||||
|
||||
|
||||
If your question is not there, please check the zlib home page
|
||||
http://zlib.net/ which may have more recent information.
|
||||
The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
|
||||
|
||||
|
||||
1. Is zlib Y2K-compliant?
|
||||
|
||||
Yes. zlib doesn't handle dates.
|
||||
|
||||
2. Where can I get a Windows DLL version?
|
||||
|
||||
The zlib sources can be compiled without change to produce a DLL. See the
|
||||
file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
|
||||
precompiled DLL are found in the zlib web site at http://zlib.net/ .
|
||||
|
||||
3. Where can I get a Visual Basic interface to zlib?
|
||||
|
||||
See
|
||||
* http://marknelson.us/1997/01/01/zlib-engine/
|
||||
* win32/DLL_FAQ.txt in the zlib distribution
|
||||
|
||||
4. compress() returns Z_BUF_ERROR.
|
||||
|
||||
Make sure that before the call of compress(), the length of the compressed
|
||||
buffer is equal to the available size of the compressed buffer and not
|
||||
zero. For Visual Basic, check that this parameter is passed by reference
|
||||
("as any"), not by value ("as long").
|
||||
|
||||
5. deflate() or inflate() returns Z_BUF_ERROR.
|
||||
|
||||
Before making the call, make sure that avail_in and avail_out are not zero.
|
||||
When setting the parameter flush equal to Z_FINISH, also make sure that
|
||||
avail_out is big enough to allow processing all pending input. Note that a
|
||||
Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
|
||||
made with more input or output space. A Z_BUF_ERROR may in fact be
|
||||
unavoidable depending on how the functions are used, since it is not
|
||||
possible to tell whether or not there is more output pending when
|
||||
strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
|
||||
heavily annotated example.
|
||||
|
||||
6. Where's the zlib documentation (man pages, etc.)?
|
||||
|
||||
It's in zlib.h . Examples of zlib usage are in the files test/example.c
|
||||
and test/minigzip.c, with more in examples/ .
|
||||
|
||||
7. Why don't you use GNU autoconf or libtool or ...?
|
||||
|
||||
Because we would like to keep zlib as a very small and simple package.
|
||||
zlib is rather portable and doesn't need much configuration.
|
||||
|
||||
8. I found a bug in zlib.
|
||||
|
||||
Most of the time, such problems are due to an incorrect usage of zlib.
|
||||
Please try to reproduce the problem with a small program and send the
|
||||
corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
|
||||
data files without prior agreement.
|
||||
|
||||
9. Why do I get "undefined reference to gzputc"?
|
||||
|
||||
If "make test" produces something like
|
||||
|
||||
example.o(.text+0x154): undefined reference to `gzputc'
|
||||
|
||||
check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
|
||||
/usr/X11R6/lib. Remove any old versions, then do "make install".
|
||||
|
||||
10. I need a Delphi interface to zlib.
|
||||
|
||||
See the contrib/delphi directory in the zlib distribution.
|
||||
|
||||
11. Can zlib handle .zip archives?
|
||||
|
||||
Not by itself, no. See the directory contrib/minizip in the zlib
|
||||
distribution.
|
||||
|
||||
12. Can zlib handle .Z files?
|
||||
|
||||
No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
|
||||
the code of uncompress on your own.
|
||||
|
||||
13. How can I make a Unix shared library?
|
||||
|
||||
By default a shared (and a static) library is built for Unix. So:
|
||||
|
||||
make distclean
|
||||
./configure
|
||||
make
|
||||
|
||||
14. How do I install a shared zlib library on Unix?
|
||||
|
||||
After the above, then:
|
||||
|
||||
make install
|
||||
|
||||
However, many flavors of Unix come with a shared zlib already installed.
|
||||
Before going to the trouble of compiling a shared version of zlib and
|
||||
trying to install it, you may want to check if it's already there! If you
|
||||
can #include <zlib.h>, it's there. The -lz option will probably link to
|
||||
it. You can check the version at the top of zlib.h or with the
|
||||
ZLIB_VERSION symbol defined in zlib.h .
|
||||
|
||||
15. I have a question about OttoPDF.
|
||||
|
||||
We are not the authors of OttoPDF. The real author is on the OttoPDF web
|
||||
site: Joel Hainley, jhainley@myndkryme.com.
|
||||
|
||||
16. Can zlib decode Flate data in an Adobe PDF file?
|
||||
|
||||
Yes. See http://www.pdflib.com/ . To modify PDF forms, see
|
||||
http://sourceforge.net/projects/acroformtool/ .
|
||||
|
||||
17. Why am I getting this "register_frame_info not found" error on Solaris?
|
||||
|
||||
After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
|
||||
generates an error such as:
|
||||
|
||||
ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
|
||||
symbol __register_frame_info: referenced symbol not found
|
||||
|
||||
The symbol __register_frame_info is not part of zlib, it is generated by
|
||||
the C compiler (cc or gcc). You must recompile applications using zlib
|
||||
which have this problem. This problem is specific to Solaris. See
|
||||
http://www.sunfreeware.com for Solaris versions of zlib and applications
|
||||
using zlib.
|
||||
|
||||
18. Why does gzip give an error on a file I make with compress/deflate?
|
||||
|
||||
The compress and deflate functions produce data in the zlib format, which
|
||||
is different and incompatible with the gzip format. The gz* functions in
|
||||
zlib on the other hand use the gzip format. Both the zlib and gzip formats
|
||||
use the same compressed data format internally, but have different headers
|
||||
and trailers around the compressed data.
|
||||
|
||||
19. Ok, so why are there two different formats?
|
||||
|
||||
The gzip format was designed to retain the directory information about a
|
||||
single file, such as the name and last modification date. The zlib format
|
||||
on the other hand was designed for in-memory and communication channel
|
||||
applications, and has a much more compact header and trailer and uses a
|
||||
faster integrity check than gzip.
|
||||
|
||||
20. Well that's nice, but how do I make a gzip file in memory?
|
||||
|
||||
You can request that deflate write the gzip format instead of the zlib
|
||||
format using deflateInit2(). You can also request that inflate decode the
|
||||
gzip format using inflateInit2(). Read zlib.h for more details.
|
||||
|
||||
21. Is zlib thread-safe?
|
||||
|
||||
Yes. However any library routines that zlib uses and any application-
|
||||
provided memory allocation routines must also be thread-safe. zlib's gz*
|
||||
functions use stdio library routines, and most of zlib's functions use the
|
||||
library memory allocation routines by default. zlib's *Init* functions
|
||||
allow for the application to provide custom memory allocation routines.
|
||||
|
||||
Of course, you should only operate on any given zlib or gzip stream from a
|
||||
single thread at a time.
|
||||
|
||||
22. Can I use zlib in my commercial application?
|
||||
|
||||
Yes. Please read the license in zlib.h.
|
||||
|
||||
23. Is zlib under the GNU license?
|
||||
|
||||
No. Please read the license in zlib.h.
|
||||
|
||||
24. The license says that altered source versions must be "plainly marked". So
|
||||
what exactly do I need to do to meet that requirement?
|
||||
|
||||
You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
|
||||
particular, the final version number needs to be changed to "f", and an
|
||||
identification string should be appended to ZLIB_VERSION. Version numbers
|
||||
x.x.x.f are reserved for modifications to zlib by others than the zlib
|
||||
maintainers. For example, if the version of the base zlib you are altering
|
||||
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
|
||||
ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
|
||||
update the version strings in deflate.c and inftrees.c.
|
||||
|
||||
For altered source distributions, you should also note the origin and
|
||||
nature of the changes in zlib.h, as well as in ChangeLog and README, along
|
||||
with the dates of the alterations. The origin should include at least your
|
||||
name (or your company's name), and an email address to contact for help or
|
||||
issues with the library.
|
||||
|
||||
Note that distributing a compiled zlib library along with zlib.h and
|
||||
zconf.h is also a source distribution, and so you should change
|
||||
ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
|
||||
in zlib.h as you would for a full source distribution.
|
||||
|
||||
25. Will zlib work on a big-endian or little-endian architecture, and can I
|
||||
exchange compressed data between them?
|
||||
|
||||
Yes and yes.
|
||||
|
||||
26. Will zlib work on a 64-bit machine?
|
||||
|
||||
Yes. It has been tested on 64-bit machines, and has no dependence on any
|
||||
data types being limited to 32-bits in length. If you have any
|
||||
difficulties, please provide a complete problem report to zlib@gzip.org
|
||||
|
||||
27. Will zlib decompress data from the PKWare Data Compression Library?
|
||||
|
||||
No. The PKWare DCL uses a completely different compressed data format than
|
||||
does PKZIP and zlib. However, you can look in zlib's contrib/blast
|
||||
directory for a possible solution to your problem.
|
||||
|
||||
28. Can I access data randomly in a compressed stream?
|
||||
|
||||
No, not without some preparation. If when compressing you periodically use
|
||||
Z_FULL_FLUSH, carefully write all the pending data at those points, and
|
||||
keep an index of those locations, then you can start decompression at those
|
||||
points. You have to be careful to not use Z_FULL_FLUSH too often, since it
|
||||
can significantly degrade compression. Alternatively, you can scan a
|
||||
deflate stream once to generate an index, and then use that index for
|
||||
random access. See examples/zran.c .
|
||||
|
||||
29. Does zlib work on MVS, OS/390, CICS, etc.?
|
||||
|
||||
It has in the past, but we have not heard of any recent evidence. There
|
||||
were working ports of zlib 1.1.4 to MVS, but those links no longer work.
|
||||
If you know of recent, successful applications of zlib on these operating
|
||||
systems, please let us know. Thanks.
|
||||
|
||||
30. Is there some simpler, easier to read version of inflate I can look at to
|
||||
understand the deflate format?
|
||||
|
||||
First off, you should read RFC 1951. Second, yes. Look in zlib's
|
||||
contrib/puff directory.
|
||||
|
||||
31. Does zlib infringe on any patents?
|
||||
|
||||
As far as we know, no. In fact, that was originally the whole point behind
|
||||
zlib. Look here for some more information:
|
||||
|
||||
http://www.gzip.org/#faq11
|
||||
|
||||
32. Can zlib work with greater than 4 GB of data?
|
||||
|
||||
Yes. inflate() and deflate() will process any amount of data correctly.
|
||||
Each call of inflate() or deflate() is limited to input and output chunks
|
||||
of the maximum value that can be stored in the compiler's "unsigned int"
|
||||
type, but there is no limit to the number of chunks. Note however that the
|
||||
strm.total_in and strm_total_out counters may be limited to 4 GB. These
|
||||
counters are provided as a convenience and are not used internally by
|
||||
inflate() or deflate(). The application can easily set up its own counters
|
||||
updated after each call of inflate() or deflate() to count beyond 4 GB.
|
||||
compress() and uncompress() may be limited to 4 GB, since they operate in a
|
||||
single call. gzseek() and gztell() may be limited to 4 GB depending on how
|
||||
zlib is compiled. See the zlibCompileFlags() function in zlib.h.
|
||||
|
||||
The word "may" appears several times above since there is a 4 GB limit only
|
||||
if the compiler's "long" type is 32 bits. If the compiler's "long" type is
|
||||
64 bits, then the limit is 16 exabytes.
|
||||
|
||||
33. Does zlib have any security vulnerabilities?
|
||||
|
||||
The only one that we are aware of is potentially in gzprintf(). If zlib is
|
||||
compiled to use sprintf() or vsprintf(), then there is no protection
|
||||
against a buffer overflow of an 8K string space (or other value as set by
|
||||
gzbuffer()), other than the caller of gzprintf() assuring that the output
|
||||
will not exceed 8K. On the other hand, if zlib is compiled to use
|
||||
snprintf() or vsnprintf(), which should normally be the case, then there is
|
||||
no vulnerability. The ./configure script will display warnings if an
|
||||
insecure variation of sprintf() will be used by gzprintf(). Also the
|
||||
zlibCompileFlags() function will return information on what variant of
|
||||
sprintf() is used by gzprintf().
|
||||
|
||||
If you don't have snprintf() or vsnprintf() and would like one, you can
|
||||
find a portable implementation here:
|
||||
|
||||
http://www.ijs.si/software/snprintf/
|
||||
|
||||
Note that you should be using the most recent version of zlib. Versions
|
||||
1.1.3 and before were subject to a double-free vulnerability, and versions
|
||||
1.2.1 and 1.2.2 were subject to an access exception when decompressing
|
||||
invalid compressed data.
|
||||
|
||||
34. Is there a Java version of zlib?
|
||||
|
||||
Probably what you want is to use zlib in Java. zlib is already included
|
||||
as part of the Java SDK in the java.util.zip package. If you really want
|
||||
a version of zlib written in the Java language, look on the zlib home
|
||||
page for links: http://zlib.net/ .
|
||||
|
||||
35. I get this or that compiler or source-code scanner warning when I crank it
|
||||
up to maximally-pedantic. Can't you guys write proper code?
|
||||
|
||||
Many years ago, we gave up attempting to avoid warnings on every compiler
|
||||
in the universe. It just got to be a waste of time, and some compilers
|
||||
were downright silly as well as contradicted each other. So now, we simply
|
||||
make sure that the code always works.
|
||||
|
||||
36. Valgrind (or some similar memory access checker) says that deflate is
|
||||
performing a conditional jump that depends on an uninitialized value.
|
||||
Isn't that a bug?
|
||||
|
||||
No. That is intentional for performance reasons, and the output of deflate
|
||||
is not affected. This only started showing up recently since zlib 1.2.x
|
||||
uses malloc() by default for allocations, whereas earlier versions used
|
||||
calloc(), which zeros out the allocated memory. Even though the code was
|
||||
correct, versions 1.2.4 and later was changed to not stimulate these
|
||||
checkers.
|
||||
|
||||
37. Will zlib read the (insert any ancient or arcane format here) compressed
|
||||
data format?
|
||||
|
||||
Probably not. Look in the comp.compression FAQ for pointers to various
|
||||
formats and associated software.
|
||||
|
||||
38. How can I encrypt/decrypt zip files with zlib?
|
||||
|
||||
zlib doesn't support encryption. The original PKZIP encryption is very
|
||||
weak and can be broken with freely available programs. To get strong
|
||||
encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
|
||||
compression. For PKZIP compatible "encryption", look at
|
||||
http://www.info-zip.org/
|
||||
|
||||
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
|
||||
|
||||
"gzip" is the gzip format, and "deflate" is the zlib format. They should
|
||||
probably have called the second one "zlib" instead to avoid confusion with
|
||||
the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
|
||||
correctly points to the zlib specification in RFC 1950 for the "deflate"
|
||||
transfer encoding, there have been reports of servers and browsers that
|
||||
incorrectly produce or expect raw deflate data per the deflate
|
||||
specification in RFC 1951, most notably Microsoft. So even though the
|
||||
"deflate" transfer encoding using the zlib format would be the more
|
||||
efficient approach (and in fact exactly what the zlib format was designed
|
||||
for), using the "gzip" transfer encoding is probably more reliable due to
|
||||
an unfortunate choice of name on the part of the HTTP 1.1 authors.
|
||||
|
||||
Bottom line: use the gzip format for HTTP 1.1 encoding.
|
||||
|
||||
40. Does zlib support the new "Deflate64" format introduced by PKWare?
|
||||
|
||||
No. PKWare has apparently decided to keep that format proprietary, since
|
||||
they have not documented it as they have previous compression formats. In
|
||||
any case, the compression improvements are so modest compared to other more
|
||||
modern approaches, that it's not worth the effort to implement.
|
||||
|
||||
41. I'm having a problem with the zip functions in zlib, can you help?
|
||||
|
||||
There are no zip functions in zlib. You are probably using minizip by
|
||||
Giles Vollant, which is found in the contrib directory of zlib. It is not
|
||||
part of zlib. In fact none of the stuff in contrib is part of zlib. The
|
||||
files in there are not supported by the zlib authors. You need to contact
|
||||
the authors of the respective contribution for help.
|
||||
|
||||
42. The match.asm code in contrib is under the GNU General Public License.
|
||||
Since it's part of zlib, doesn't that mean that all of zlib falls under the
|
||||
GNU GPL?
|
||||
|
||||
No. The files in contrib are not part of zlib. They were contributed by
|
||||
other authors and are provided as a convenience to the user within the zlib
|
||||
distribution. Each item in contrib has its own license.
|
||||
|
||||
43. Is zlib subject to export controls? What is its ECCN?
|
||||
|
||||
zlib is not subject to export controls, and so is classified as EAR99.
|
||||
|
||||
44. Can you please sign these lengthy legal documents and fax them back to us
|
||||
so that we can use your software in our product?
|
||||
|
||||
No. Go away. Shoo.
|
|
@ -0,0 +1,68 @@
|
|||
CMakeLists.txt cmake build file
|
||||
ChangeLog history of changes
|
||||
FAQ Frequently Asked Questions about zlib
|
||||
INDEX this file
|
||||
Makefile dummy Makefile that tells you to ./configure
|
||||
Makefile.in template for Unix Makefile
|
||||
README guess what
|
||||
configure configure script for Unix
|
||||
make_vms.com makefile for VMS
|
||||
test/example.c zlib usages examples for build testing
|
||||
test/minigzip.c minimal gzip-like functionality for build testing
|
||||
test/infcover.c inf*.c code coverage for build coverage testing
|
||||
treebuild.xml XML description of source file dependencies
|
||||
zconf.h.cmakein zconf.h template for cmake
|
||||
zconf.h.in zconf.h template for configure
|
||||
zlib.3 Man page for zlib
|
||||
zlib.3.pdf Man page in PDF format
|
||||
zlib.map Linux symbol information
|
||||
zlib.pc.in Template for pkg-config descriptor
|
||||
zlib.pc.cmakein zlib.pc template for cmake
|
||||
zlib2ansi perl script to convert source files for C++ compilation
|
||||
|
||||
amiga/ makefiles for Amiga SAS C
|
||||
as400/ makefiles for AS/400
|
||||
doc/ documentation for formats and algorithms
|
||||
msdos/ makefiles for MSDOS
|
||||
nintendods/ makefile for Nintendo DS
|
||||
old/ makefiles for various architectures and zlib documentation
|
||||
files that have not yet been updated for zlib 1.2.x
|
||||
qnx/ makefiles for QNX
|
||||
watcom/ makefiles for OpenWatcom
|
||||
win32/ makefiles for Windows
|
||||
|
||||
zlib public header files (required for library use):
|
||||
zconf.h
|
||||
zlib.h
|
||||
|
||||
private source files used to build the zlib library:
|
||||
adler32.c
|
||||
compress.c
|
||||
crc32.c
|
||||
crc32.h
|
||||
deflate.c
|
||||
deflate.h
|
||||
gzclose.c
|
||||
gzguts.h
|
||||
gzlib.c
|
||||
gzread.c
|
||||
gzwrite.c
|
||||
infback.c
|
||||
inffast.c
|
||||
inffast.h
|
||||
inffixed.h
|
||||
inflate.c
|
||||
inflate.h
|
||||
inftrees.c
|
||||
inftrees.h
|
||||
trees.c
|
||||
trees.h
|
||||
uncompr.c
|
||||
zutil.c
|
||||
zutil.h
|
||||
|
||||
source files for sample programs
|
||||
See examples/README.examples
|
||||
|
||||
unsupported contributions by third parties
|
||||
See contrib/README.contrib
|
|
@ -1,56 +1,52 @@
|
|||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.3 is a general purpose data compression library. All the code is
|
||||
zlib 1.2.8 is a general purpose data compression library. All the code is
|
||||
thread safe. The data format used by the zlib library is described by RFCs
|
||||
(Request for Comments) 1950 to 1952 in the files
|
||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
||||
and rfc1952.txt (gzip format). These documents are also available in other
|
||||
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
|
||||
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||||
rfc1952 (gzip format).
|
||||
|
||||
All functions of the compression library are documented in the file zlib.h
|
||||
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||||
of the library is given in the file example.c which also tests that the library
|
||||
is working correctly. Another example is given in the file minigzip.c. The
|
||||
compression library itself is composed of all source files except example.c and
|
||||
minigzip.c.
|
||||
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||||
of the library is given in the file test/example.c which also tests that
|
||||
the library is working correctly. Another example is given in the file
|
||||
test/minigzip.c. The compression library itself is composed of all source
|
||||
files in the root directory.
|
||||
|
||||
To compile all files and run the test program, follow the instructions given at
|
||||
the top of Makefile. In short "make test; make install" should work for most
|
||||
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
|
||||
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
|
||||
the top of Makefile.in. In short "./configure; make test", and if that goes
|
||||
well, "make install" should work for most flavors of Unix. For Windows, use
|
||||
one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
|
||||
make_vms.com.
|
||||
|
||||
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
||||
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
||||
http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
|
||||
please check this site to verify that you have the latest version of zlib;
|
||||
otherwise get the latest version and check whether the problem still exists or
|
||||
not.
|
||||
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
||||
http://zlib.net/ . Before reporting a problem, please check this site to
|
||||
verify that you have the latest version of zlib; otherwise get the latest
|
||||
version and check whether the problem still exists or not.
|
||||
|
||||
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
|
||||
for help.
|
||||
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
|
||||
|
||||
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available in
|
||||
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
|
||||
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available at
|
||||
http://marknelson.us/1997/01/01/zlib-engine/ .
|
||||
|
||||
The changes made in version 1.2.3 are documented in the file ChangeLog.
|
||||
The changes made in version 1.2.8 are documented in the file ChangeLog.
|
||||
|
||||
Unsupported third party contributions are provided in directory "contrib".
|
||||
Unsupported third party contributions are provided in directory contrib/ .
|
||||
|
||||
A Java implementation of zlib is available in the Java Development Kit
|
||||
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
|
||||
See the zlib home page http://www.zlib.org for details.
|
||||
zlib is available in Java using the java.util.zip package, documented at
|
||||
http://java.sun.com/developer/technicalArticles/Programming/compression/ .
|
||||
|
||||
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
|
||||
CPAN (Comprehensive Perl Archive Network) sites
|
||||
http://www.cpan.org/modules/by-module/Compress/
|
||||
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
|
||||
at CPAN (Comprehensive Perl Archive Network) sites, including
|
||||
http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
|
||||
|
||||
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
||||
available in Python 1.5 and later versions, see
|
||||
http://www.python.org/doc/lib/module-zlib.html
|
||||
http://docs.python.org/library/zlib.html .
|
||||
|
||||
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
|
||||
availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
|
||||
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
||||
|
||||
An experimental package to read and write files in .zip format, written on top
|
||||
of zlib by Gilles Vollant <info@winimage.com>, is available in the
|
||||
|
@ -74,25 +70,21 @@ Notes for some targets:
|
|||
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
|
||||
other compilers. Use "make test" to check your compiler.
|
||||
|
||||
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
|
||||
- gzdopen is not supported on RISCOS or BEOS.
|
||||
|
||||
- For PalmOs, see http://palmzlib.sourceforge.net/
|
||||
|
||||
- When building a shared, i.e. dynamic library on Mac OS X, the library must be
|
||||
installed before testing (do "make install" before "make test"), since the
|
||||
library location is specified in the library.
|
||||
|
||||
|
||||
Acknowledgments:
|
||||
|
||||
The deflate format used by zlib was defined by Phil Katz. The deflate
|
||||
and zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
||||
people who reported problems and suggested various improvements in zlib;
|
||||
they are too numerous to cite here.
|
||||
The deflate format used by zlib was defined by Phil Katz. The deflate and
|
||||
zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
||||
people who reported problems and suggested various improvements in zlib; they
|
||||
are too numerous to cite here.
|
||||
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-2004 Jean-loup Gailly and Mark Adler
|
||||
(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
|
||||
|
@ -113,13 +105,11 @@ Copyright notice:
|
|||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
If you use the zlib library in a product, we would appreciate *not*
|
||||
receiving lengthy legal documents to sign. The sources are provided
|
||||
for free but without warranty of any kind. The library has been
|
||||
entirely written by Jean-loup Gailly and Mark Adler; it does not
|
||||
include third-party code.
|
||||
If you use the zlib library in a product, we would appreciate *not* receiving
|
||||
lengthy legal documents to sign. The sources are provided for free but without
|
||||
warranty of any kind. The library has been entirely written by Jean-loup
|
||||
Gailly and Mark Adler; it does not include third-party code.
|
||||
|
||||
If you redistribute modified sources, we would appreciate that you include
|
||||
in the file ChangeLog history information documenting your changes. Please
|
||||
read the FAQ for more information on the distribution of modified source
|
||||
versions.
|
||||
If you redistribute modified sources, we would appreciate that you include in
|
||||
the file ChangeLog history information documenting your changes. Please read
|
||||
the FAQ for more information on the distribution of modified source versions.
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2011 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id: adler32.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
#include "zutil.h"
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#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 */
|
||||
|
||||
|
@ -18,39 +20,44 @@
|
|||
#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 */
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
# define CHOP(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
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 MOD4(a) \
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
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 MOD4(a) a %= BASE
|
||||
# define MOD28(a) a %= BASE
|
||||
# define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -89,7 +96,7 @@ uLong ZEXPORT adler32(adler, buf, len)
|
|||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
|
@ -125,25 +132,47 @@ uLong ZEXPORT adler32(adler, buf, len)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
local uLong adler32_combine_(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
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 */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
1. Compression algorithm (deflate)
|
||||
|
||||
The deflation algorithm used by gzip (also zip and zlib) is a variation of
|
||||
LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
|
||||
the input data. The second occurrence of a string is replaced by a
|
||||
pointer to the previous string, in the form of a pair (distance,
|
||||
length). Distances are limited to 32K bytes, and lengths are limited
|
||||
to 258 bytes. When a string does not occur anywhere in the previous
|
||||
32K bytes, it is emitted as a sequence of literal bytes. (In this
|
||||
description, `string' must be taken as an arbitrary sequence of bytes,
|
||||
and is not restricted to printable characters.)
|
||||
|
||||
Literals or match lengths are compressed with one Huffman tree, and
|
||||
match distances are compressed with another tree. The trees are stored
|
||||
in a compact form at the start of each block. The blocks can have any
|
||||
size (except that the compressed data for one block must fit in
|
||||
available memory). A block is terminated when deflate() determines that
|
||||
it would be useful to start another block with fresh trees. (This is
|
||||
somewhat similar to the behavior of LZW-based _compress_.)
|
||||
|
||||
Duplicated strings are found using a hash table. All input strings of
|
||||
length 3 are inserted in the hash table. A hash index is computed for
|
||||
the next 3 bytes. If the hash chain for this index is not empty, all
|
||||
strings in the chain are compared with the current input string, and
|
||||
the longest match is selected.
|
||||
|
||||
The hash chains are searched starting with the most recent strings, to
|
||||
favor small distances and thus take advantage of the Huffman encoding.
|
||||
The hash chains are singly linked. There are no deletions from the
|
||||
hash chains, the algorithm simply discards matches that are too old.
|
||||
|
||||
To avoid a worst-case situation, very long hash chains are arbitrarily
|
||||
truncated at a certain length, determined by a runtime option (level
|
||||
parameter of deflateInit). So deflate() does not always find the longest
|
||||
possible match but generally finds a match which is long enough.
|
||||
|
||||
deflate() also defers the selection of matches with a lazy evaluation
|
||||
mechanism. After a match of length N has been found, deflate() searches for
|
||||
a longer match at the next input byte. If a longer match is found, the
|
||||
previous match is truncated to a length of one (thus producing a single
|
||||
literal byte) and the process of lazy evaluation begins again. Otherwise,
|
||||
the original match is kept, and the next match search is attempted only N
|
||||
steps later.
|
||||
|
||||
The lazy match evaluation is also subject to a runtime parameter. If
|
||||
the current match is long enough, deflate() reduces the search for a longer
|
||||
match, thus speeding up the whole process. If compression ratio is more
|
||||
important than speed, deflate() attempts a complete second search even if
|
||||
the first match is already long enough.
|
||||
|
||||
The lazy match evaluation is not performed for the fastest compression
|
||||
modes (level parameter 1 to 3). For these fast modes, new strings
|
||||
are inserted in the hash table only when no match was found, or
|
||||
when the match is not too long. This degrades the compression ratio
|
||||
but saves time since there are both fewer insertions and fewer searches.
|
||||
|
||||
|
||||
2. Decompression algorithm (inflate)
|
||||
|
||||
2.1 Introduction
|
||||
|
||||
The key question is how to represent a Huffman code (or any prefix code) so
|
||||
that you can decode fast. The most important characteristic is that shorter
|
||||
codes are much more common than longer codes, so pay attention to decoding the
|
||||
short codes fast, and let the long codes take longer to decode.
|
||||
|
||||
inflate() sets up a first level table that covers some number of bits of
|
||||
input less than the length of longest code. It gets that many bits from the
|
||||
stream, and looks it up in the table. The table will tell if the next
|
||||
code is that many bits or less and how many, and if it is, it will tell
|
||||
the value, else it will point to the next level table for which inflate()
|
||||
grabs more bits and tries to decode a longer code.
|
||||
|
||||
How many bits to make the first lookup is a tradeoff between the time it
|
||||
takes to decode and the time it takes to build the table. If building the
|
||||
table took no time (and if you had infinite memory), then there would only
|
||||
be a first level table to cover all the way to the longest code. However,
|
||||
building the table ends up taking a lot longer for more bits since short
|
||||
codes are replicated many times in such a table. What inflate() does is
|
||||
simply to make the number of bits in the first table a variable, and then
|
||||
to set that variable for the maximum speed.
|
||||
|
||||
For inflate, which has 286 possible codes for the literal/length tree, the size
|
||||
of the first table is nine bits. Also the distance trees have 30 possible
|
||||
values, and the size of the first table is six bits. Note that for each of
|
||||
those cases, the table ended up one bit longer than the ``average'' code
|
||||
length, i.e. the code length of an approximately flat code which would be a
|
||||
little more than eight bits for 286 symbols and a little less than five bits
|
||||
for 30 symbols.
|
||||
|
||||
|
||||
2.2 More details on the inflate table lookup
|
||||
|
||||
Ok, you want to know what this cleverly obfuscated inflate tree actually
|
||||
looks like. You are correct that it's not a Huffman tree. It is simply a
|
||||
lookup table for the first, let's say, nine bits of a Huffman symbol. The
|
||||
symbol could be as short as one bit or as long as 15 bits. If a particular
|
||||
symbol is shorter than nine bits, then that symbol's translation is duplicated
|
||||
in all those entries that start with that symbol's bits. For example, if the
|
||||
symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
|
||||
symbol is nine bits long, it appears in the table once.
|
||||
|
||||
If the symbol is longer than nine bits, then that entry in the table points
|
||||
to another similar table for the remaining bits. Again, there are duplicated
|
||||
entries as needed. The idea is that most of the time the symbol will be short
|
||||
and there will only be one table look up. (That's whole idea behind data
|
||||
compression in the first place.) For the less frequent long symbols, there
|
||||
will be two lookups. If you had a compression method with really long
|
||||
symbols, you could have as many levels of lookups as is efficient. For
|
||||
inflate, two is enough.
|
||||
|
||||
So a table entry either points to another table (in which case nine bits in
|
||||
the above example are gobbled), or it contains the translation for the symbol
|
||||
and the number of bits to gobble. Then you start again with the next
|
||||
ungobbled bit.
|
||||
|
||||
You may wonder: why not just have one lookup table for how ever many bits the
|
||||
longest symbol is? The reason is that if you do that, you end up spending
|
||||
more time filling in duplicate symbol entries than you do actually decoding.
|
||||
At least for deflate's output that generates new trees every several 10's of
|
||||
kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
|
||||
would take too long if you're only decoding several thousand symbols. At the
|
||||
other extreme, you could make a new table for every bit in the code. In fact,
|
||||
that's essentially a Huffman tree. But then you spend two much time
|
||||
traversing the tree while decoding, even for short symbols.
|
||||
|
||||
So the number of bits for the first lookup table is a trade of the time to
|
||||
fill out the table vs. the time spent looking at the second level and above of
|
||||
the table.
|
||||
|
||||
Here is an example, scaled down:
|
||||
|
||||
The code being decoded, with 10 symbols, from 1 to 6 bits long:
|
||||
|
||||
A: 0
|
||||
B: 10
|
||||
C: 1100
|
||||
D: 11010
|
||||
E: 11011
|
||||
F: 11100
|
||||
G: 11101
|
||||
H: 11110
|
||||
I: 111110
|
||||
J: 111111
|
||||
|
||||
Let's make the first table three bits long (eight entries):
|
||||
|
||||
000: A,1
|
||||
001: A,1
|
||||
010: A,1
|
||||
011: A,1
|
||||
100: B,2
|
||||
101: B,2
|
||||
110: -> table X (gobble 3 bits)
|
||||
111: -> table Y (gobble 3 bits)
|
||||
|
||||
Each entry is what the bits decode as and how many bits that is, i.e. how
|
||||
many bits to gobble. Or the entry points to another table, with the number of
|
||||
bits to gobble implicit in the size of the table.
|
||||
|
||||
Table X is two bits long since the longest code starting with 110 is five bits
|
||||
long:
|
||||
|
||||
00: C,1
|
||||
01: C,1
|
||||
10: D,2
|
||||
11: E,2
|
||||
|
||||
Table Y is three bits long since the longest code starting with 111 is six
|
||||
bits long:
|
||||
|
||||
000: F,2
|
||||
001: F,2
|
||||
010: G,2
|
||||
011: G,2
|
||||
100: H,2
|
||||
101: H,2
|
||||
110: I,3
|
||||
111: J,3
|
||||
|
||||
So what we have here are three tables with a total of 20 entries that had to
|
||||
be constructed. That's compared to 64 entries for a single table. Or
|
||||
compared to 16 entries for a Huffman tree (six two entry tables and one four
|
||||
entry table). Assuming that the code ideally represents the probability of
|
||||
the symbols, it takes on the average 1.25 lookups per symbol. That's compared
|
||||
to one lookup for the single table, or 1.66 lookups per symbol for the
|
||||
Huffman tree.
|
||||
|
||||
There, I think that gives you a picture of what's going on. For inflate, the
|
||||
meaning of a particular symbol is often more than just a letter. It can be a
|
||||
byte (a "literal"), or it can be either a length or a distance which
|
||||
indicates a base value and a number of bits to fetch after the code that is
|
||||
added to the base value. Or it might be the special end-of-block code. The
|
||||
data structures created in inftrees.c try to encode all that information
|
||||
compactly in the tables.
|
||||
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
References:
|
||||
|
||||
[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
|
||||
Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
|
||||
pp. 337-343.
|
||||
|
||||
``DEFLATE Compressed Data Format Specification'' available in
|
||||
http://www.ietf.org/rfc/rfc1951.txt
|
|
@ -1,9 +1,8 @@
|
|||
/* compress.c -- compress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id: compress.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
@ -29,7 +28,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
|||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.next_in = (z_const Bytef *)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
#ifdef MAXSEG_64K
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
|
@ -75,5 +74,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
|
|||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* 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 <rbrown64@csc.com.au> for his contribution of faster
|
||||
|
@ -9,7 +9,6 @@
|
|||
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: crc32.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
/*
|
||||
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
|
||||
|
@ -17,6 +16,8 @@
|
|||
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
|
||||
|
@ -25,35 +26,16 @@
|
|||
# define DYNAMIC_CRC_TABLE
|
||||
# endif /* !DYNAMIC_CRC_TABLE */
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#include "zutil.h" /* for STDC and FAR definitions */
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#if !defined(NOBYFOUR) && defined(Z_U4)
|
||||
# define BYFOUR
|
||||
#endif
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
|
@ -67,14 +49,16 @@
|
|||
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 unsigned long FAR crc_table[TBLS][256];
|
||||
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 unsigned long FAR *));
|
||||
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:
|
||||
|
@ -104,9 +88,9 @@ local void make_crc_table OF((void));
|
|||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
z_crc_t c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
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};
|
||||
|
@ -118,13 +102,13 @@ local void make_crc_table()
|
|||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
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 = (unsigned long)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;
|
||||
|
@ -135,11 +119,11 @@ local void make_crc_table()
|
|||
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] = REV(c);
|
||||
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] = REV(c);
|
||||
crc_table[k + 4][n] = ZSWAP32(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
|
@ -161,7 +145,7 @@ local void make_crc_table()
|
|||
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 unsigned long FAR ");
|
||||
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
|
||||
|
@ -181,12 +165,13 @@ local void make_crc_table()
|
|||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
const z_crc_t FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
|
||||
(unsigned long)(table[n]),
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
|
@ -201,13 +186,13 @@ local void write_table(out, table)
|
|||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
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 unsigned long FAR *)crc_table;
|
||||
return (const z_crc_t FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -218,7 +203,7 @@ const unsigned long FAR * ZEXPORT get_crc_table()
|
|||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
uInt len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0UL;
|
||||
|
||||
|
@ -229,7 +214,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
|||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
z_crc_t endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
|
@ -263,17 +248,17 @@ local unsigned long crc32_little(crc, buf, len)
|
|||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
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 u4 FAR *)(const void FAR *)buf;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
|
@ -303,17 +288,17 @@ local unsigned long crc32_big(crc, buf, len)
|
|||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
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 u4 FAR *)(const void FAR *)buf;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
|
@ -330,7 +315,7 @@ local unsigned long crc32_big(crc, buf, len)
|
|||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
return (unsigned long)(ZSWAP32(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
|
@ -366,22 +351,22 @@ local void gf2_matrix_square(square, mat)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
local uLong crc32_combine_(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
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 */
|
||||
if (len2 == 0)
|
||||
/* degenerate case (also disallow negative lengths) */
|
||||
if (len2 <= 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
|
||||
odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
|
@ -420,3 +405,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
local const z_crc_t FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
* REFERENCES
|
||||
*
|
||||
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
||||
* Available in http://www.ietf.org/rfc/rfc1951.txt
|
||||
* 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.
|
||||
|
@ -47,12 +47,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* @(#) $Id: deflate.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
const char deflate_copyright[] =
|
||||
" deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
|
||||
" 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
|
||||
|
@ -79,19 +78,18 @@ 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));
|
||||
#ifndef FASTEST
|
||||
#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
|
||||
#endif
|
||||
local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
|
||||
|
||||
#ifdef DEBUG
|
||||
local void check_match OF((deflate_state *s, IPos start, IPos match,
|
||||
|
@ -110,11 +108,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
|
|||
#endif
|
||||
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
/* 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
|
||||
|
@ -161,6 +154,9 @@ local const config configuration_table[10] = {
|
|||
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
|
||||
|
@ -241,10 +237,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
|
||||
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) strm->zfree = zcfree;
|
||||
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;
|
||||
|
@ -288,6 +293,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
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);
|
||||
|
@ -297,7 +304,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
s->status = FINISH_STATE;
|
||||
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
|
||||
strm->msg = ERR_MSG(Z_MEM_ERROR);
|
||||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
|
@ -318,43 +325,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
|||
uInt dictLength;
|
||||
{
|
||||
deflate_state *s;
|
||||
uInt length = dictLength;
|
||||
uInt n;
|
||||
IPos hash_head = 0;
|
||||
uInt str, n;
|
||||
int wrap;
|
||||
unsigned avail;
|
||||
z_const unsigned char *next;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
||||
strm->state->wrap == 2 ||
|
||||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
|
||||
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;
|
||||
|
||||
s = strm->state;
|
||||
if (s->wrap)
|
||||
/* 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 (length < MIN_MATCH) return Z_OK;
|
||||
if (length > MAX_DIST(s)) {
|
||||
length = MAX_DIST(s);
|
||||
dictionary += dictLength - length; /* use the tail of the dictionary */
|
||||
/* 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;
|
||||
}
|
||||
zmemcpy(s->window, dictionary, length);
|
||||
s->strstart = length;
|
||||
s->block_start = (long)length;
|
||||
|
||||
/* Insert all strings in the hash table (except for the last two bytes).
|
||||
* s->lookahead stays null, so s->ins_h will be recomputed at the next
|
||||
* call of fill_window.
|
||||
*/
|
||||
s->ins_h = s->window[0];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[1]);
|
||||
for (n = 0; n <= length - MIN_MATCH; n++) {
|
||||
INSERT_STRING(s, n, hash_head);
|
||||
/* 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);
|
||||
}
|
||||
if (hash_head) hash_head = 0; /* to make compiler happy */
|
||||
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 deflateReset (strm)
|
||||
int ZEXPORT deflateResetKeep (strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
|
@ -384,11 +418,22 @@ int ZEXPORT deflateReset (strm)
|
|||
s->last_flush = Z_NO_FLUSH;
|
||||
|
||||
_tr_init(s);
|
||||
lm_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;
|
||||
|
@ -400,15 +445,43 @@ int ZEXPORT deflateSetHeader (strm, 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;
|
||||
strm->state->bi_valid = bits;
|
||||
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -435,9 +508,12 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
|||
}
|
||||
func = configuration_table[s->level].func;
|
||||
|
||||
if (func != configuration_table[level].func && strm->total_in != 0) {
|
||||
if ((strategy != s->strategy || func != configuration_table[level].func) &&
|
||||
strm->total_in != 0) {
|
||||
/* Flush the last buffer: */
|
||||
err = deflate(strm, Z_PARTIAL_FLUSH);
|
||||
err = deflate(strm, Z_BLOCK);
|
||||
if (err == Z_BUF_ERROR && s->pending == 0)
|
||||
err = Z_OK;
|
||||
}
|
||||
if (s->level != level) {
|
||||
s->level = level;
|
||||
|
@ -481,33 +557,66 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
|
|||
* 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, as well as wrap.
|
||||
* But even the conservative upper bound of about 14% expansion does not
|
||||
* seem onerous for output buffer allocation.
|
||||
* 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 destLen;
|
||||
uLong complen, wraplen;
|
||||
Bytef *str;
|
||||
|
||||
/* conservative upper bound */
|
||||
destLen = sourceLen +
|
||||
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
|
||||
/* conservative upper bound for compressed data */
|
||||
complen = sourceLen +
|
||||
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
|
||||
|
||||
/* if can't get parameters, return conservative bound */
|
||||
/* if can't get parameters, return conservative bound plus zlib wrapper */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL)
|
||||
return destLen;
|
||||
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 */
|
||||
s = strm->state;
|
||||
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
|
||||
return destLen;
|
||||
return complen + wraplen;
|
||||
|
||||
/* default settings: return tight bound for that case */
|
||||
return compressBound(sourceLen);
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13 - 6 + wraplen;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
|
@ -532,19 +641,22 @@ local void putShortMSB (s, b)
|
|||
local void flush_pending(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
unsigned len = strm->state->pending;
|
||||
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, strm->state->pending_out, len);
|
||||
zmemcpy(strm->next_out, s->pending_out, len);
|
||||
strm->next_out += len;
|
||||
strm->state->pending_out += len;
|
||||
s->pending_out += len;
|
||||
strm->total_out += len;
|
||||
strm->avail_out -= len;
|
||||
strm->state->pending -= len;
|
||||
if (strm->state->pending == 0) {
|
||||
strm->state->pending_out = strm->state->pending_buf;
|
||||
s->pending -= len;
|
||||
if (s->pending == 0) {
|
||||
s->pending_out = s->pending_buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,7 +669,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
deflate_state *s;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL ||
|
||||
flush > Z_FINISH || flush < 0) {
|
||||
flush > Z_BLOCK || flush < 0) {
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
s = strm->state;
|
||||
|
@ -581,7 +693,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
put_byte(s, 31);
|
||||
put_byte(s, 139);
|
||||
put_byte(s, 8);
|
||||
if (s->gzhead == NULL) {
|
||||
if (s->gzhead == Z_NULL) {
|
||||
put_byte(s, 0);
|
||||
put_byte(s, 0);
|
||||
put_byte(s, 0);
|
||||
|
@ -608,7 +720,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
|
||||
4 : 0));
|
||||
put_byte(s, s->gzhead->os & 0xff);
|
||||
if (s->gzhead->extra != NULL) {
|
||||
if (s->gzhead->extra != Z_NULL) {
|
||||
put_byte(s, s->gzhead->extra_len & 0xff);
|
||||
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
|
||||
}
|
||||
|
@ -650,7 +762,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
}
|
||||
#ifdef GZIP
|
||||
if (s->status == EXTRA_STATE) {
|
||||
if (s->gzhead->extra != NULL) {
|
||||
if (s->gzhead->extra != Z_NULL) {
|
||||
uInt beg = s->pending; /* start of bytes to update crc */
|
||||
|
||||
while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
|
||||
|
@ -678,7 +790,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
s->status = NAME_STATE;
|
||||
}
|
||||
if (s->status == NAME_STATE) {
|
||||
if (s->gzhead->name != NULL) {
|
||||
if (s->gzhead->name != Z_NULL) {
|
||||
uInt beg = s->pending; /* start of bytes to update crc */
|
||||
int val;
|
||||
|
||||
|
@ -709,7 +821,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
s->status = COMMENT_STATE;
|
||||
}
|
||||
if (s->status == COMMENT_STATE) {
|
||||
if (s->gzhead->comment != NULL) {
|
||||
if (s->gzhead->comment != Z_NULL) {
|
||||
uInt beg = s->pending; /* start of bytes to update crc */
|
||||
int val;
|
||||
|
||||
|
@ -771,7 +883,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
* 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 && flush <= old_flush &&
|
||||
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
|
||||
flush != Z_FINISH) {
|
||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||
}
|
||||
|
@ -787,7 +899,9 @@ int ZEXPORT deflate (strm, flush)
|
|||
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
|
||||
block_state bstate;
|
||||
|
||||
bstate = (*(configuration_table[s->level].func))(s, flush);
|
||||
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;
|
||||
|
@ -808,13 +922,18 @@ int ZEXPORT deflate (strm, flush)
|
|||
if (bstate == block_done) {
|
||||
if (flush == Z_PARTIAL_FLUSH) {
|
||||
_tr_align(s);
|
||||
} else { /* FULL_FLUSH or SYNC_FLUSH */
|
||||
} 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);
|
||||
|
@ -909,12 +1028,12 @@ int ZEXPORT deflateCopy (dest, source)
|
|||
|
||||
ss = source->state;
|
||||
|
||||
zmemcpy(dest, source, sizeof(z_stream));
|
||||
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(ds, ss, sizeof(deflate_state));
|
||||
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
||||
ds->strm = dest;
|
||||
|
||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||
|
@ -930,8 +1049,8 @@ int ZEXPORT deflateCopy (dest, source)
|
|||
}
|
||||
/* following zmemcpy do not work for 16-bit MSDOS */
|
||||
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
||||
zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
||||
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
||||
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);
|
||||
|
@ -965,15 +1084,15 @@ local int read_buf(strm, buf, size)
|
|||
|
||||
strm->avail_in -= len;
|
||||
|
||||
zmemcpy(buf, strm->next_in, len);
|
||||
if (strm->state->wrap == 1) {
|
||||
strm->adler = adler32(strm->adler, strm->next_in, len);
|
||||
strm->adler = adler32(strm->adler, buf, len);
|
||||
}
|
||||
#ifdef GZIP
|
||||
else if (strm->state->wrap == 2) {
|
||||
strm->adler = crc32(strm->adler, strm->next_in, len);
|
||||
strm->adler = crc32(strm->adler, buf, len);
|
||||
}
|
||||
#endif
|
||||
zmemcpy(buf, strm->next_in, len);
|
||||
strm->next_in += len;
|
||||
strm->total_in += len;
|
||||
|
||||
|
@ -1000,6 +1119,7 @@ local void lm_init (s)
|
|||
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;
|
||||
|
@ -1167,12 +1287,13 @@ local uInt longest_match(s, cur_match)
|
|||
return s->lookahead;
|
||||
}
|
||||
#endif /* ASMV */
|
||||
#endif /* FASTEST */
|
||||
|
||||
#else /* FASTEST */
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Optimized version for level == 1 or strategy == Z_RLE only
|
||||
* Optimized version for FASTEST only
|
||||
*/
|
||||
local uInt longest_match_fast(s, cur_match)
|
||||
local uInt longest_match(s, cur_match)
|
||||
deflate_state *s;
|
||||
IPos cur_match; /* current match */
|
||||
{
|
||||
|
@ -1225,6 +1346,8 @@ local uInt longest_match_fast(s, 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.
|
||||
|
@ -1271,6 +1394,8 @@ local void fill_window(s)
|
|||
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);
|
||||
|
||||
|
@ -1303,7 +1428,6 @@ local void fill_window(s)
|
|||
later. (Using level 0 permanently is not an optimal usage of
|
||||
zlib, so we don't care about this pathological case.)
|
||||
*/
|
||||
/* %%% avoid this when Z_RLE */
|
||||
n = s->hash_size;
|
||||
p = &s->head[n];
|
||||
do {
|
||||
|
@ -1324,7 +1448,7 @@ local void fill_window(s)
|
|||
#endif
|
||||
more += wsize;
|
||||
}
|
||||
if (s->strm->avail_in == 0) return;
|
||||
if (s->strm->avail_in == 0) break;
|
||||
|
||||
/* If there was no sliding:
|
||||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||||
|
@ -1343,39 +1467,88 @@ local void fill_window(s)
|
|||
s->lookahead += n;
|
||||
|
||||
/* Initialize the hash value now that we have some input: */
|
||||
if (s->lookahead >= MIN_MATCH) {
|
||||
s->ins_h = s->window[s->strstart];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
||||
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, eof) { \
|
||||
#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), \
|
||||
(eof)); \
|
||||
(last)); \
|
||||
s->block_start = s->strstart; \
|
||||
flush_pending(s->strm); \
|
||||
Tracev((stderr,"[FLUSH]")); \
|
||||
}
|
||||
|
||||
/* Same but force premature exit if necessary. */
|
||||
#define FLUSH_BLOCK(s, eof) { \
|
||||
FLUSH_BLOCK_ONLY(s, eof); \
|
||||
if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
|
||||
#define FLUSH_BLOCK(s, last) { \
|
||||
FLUSH_BLOCK_ONLY(s, last); \
|
||||
if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -1434,8 +1607,14 @@ local block_state deflate_stored(s, flush)
|
|||
FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
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;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -1449,7 +1628,7 @@ local block_state deflate_fast(s, flush)
|
|||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
IPos hash_head = NIL; /* head of the hash chain */
|
||||
IPos hash_head; /* head of the hash chain */
|
||||
int bflush; /* set if current block must be flushed */
|
||||
|
||||
for (;;) {
|
||||
|
@ -1469,6 +1648,7 @@ local block_state deflate_fast(s, flush)
|
|||
/* 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);
|
||||
}
|
||||
|
@ -1481,19 +1661,8 @@ local block_state deflate_fast(s, flush)
|
|||
* of window index 0 (in particular we have to avoid a match
|
||||
* of the string with itself at the start of the input file).
|
||||
*/
|
||||
#ifdef FASTEST
|
||||
if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
|
||||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
|
||||
s->match_length = longest_match_fast (s, hash_head);
|
||||
}
|
||||
#else
|
||||
if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
|
||||
s->match_length = longest_match (s, hash_head);
|
||||
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
|
||||
s->match_length = longest_match_fast (s, hash_head);
|
||||
}
|
||||
#endif
|
||||
/* longest_match() or longest_match_fast() sets match_start */
|
||||
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);
|
||||
|
@ -1541,8 +1710,14 @@ local block_state deflate_fast(s, flush)
|
|||
}
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
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
|
||||
|
@ -1555,7 +1730,7 @@ local block_state deflate_slow(s, flush)
|
|||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
IPos hash_head = NIL; /* head of hash chain */
|
||||
IPos hash_head; /* head of hash chain */
|
||||
int bflush; /* set if current block must be flushed */
|
||||
|
||||
/* Process the input block. */
|
||||
|
@ -1576,6 +1751,7 @@ local block_state deflate_slow(s, flush)
|
|||
/* 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);
|
||||
}
|
||||
|
@ -1591,12 +1767,8 @@ local block_state deflate_slow(s, flush)
|
|||
* of window index 0 (in particular we have to avoid a match
|
||||
* of the string with itself at the start of the input file).
|
||||
*/
|
||||
if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
|
||||
s->match_length = longest_match (s, hash_head);
|
||||
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
|
||||
s->match_length = longest_match_fast (s, hash_head);
|
||||
}
|
||||
/* longest_match() or longest_match_fast() sets match_start */
|
||||
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
|
||||
|
@ -1669,12 +1841,17 @@ local block_state deflate_slow(s, flush)
|
|||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
s->match_available = 0;
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
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 */
|
||||
|
||||
#if 0
|
||||
/* ===========================================================================
|
||||
* 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
|
||||
|
@ -1684,43 +1861,52 @@ local block_state deflate_rle(s, flush)
|
|||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
int bflush; /* set if current block must be flushed */
|
||||
uInt run; /* length of run */
|
||||
uInt max; /* maximum length of run */
|
||||
uInt prev; /* byte at distance one to match */
|
||||
Bytef *scan; /* scan for end of run */
|
||||
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 encodable run.
|
||||
* for the longest run, plus one for the unrolled loop.
|
||||
*/
|
||||
if (s->lookahead < MAX_MATCH) {
|
||||
if (s->lookahead <= MAX_MATCH) {
|
||||
fill_window(s);
|
||||
if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
|
||||
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 */
|
||||
run = 0;
|
||||
if (s->strstart > 0) { /* if there is a previous byte, that is */
|
||||
max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
|
||||
s->match_length = 0;
|
||||
if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
|
||||
scan = s->window + s->strstart - 1;
|
||||
prev = *scan++;
|
||||
do {
|
||||
if (*scan++ != prev)
|
||||
break;
|
||||
} while (++run < max);
|
||||
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 (run >= MIN_MATCH) {
|
||||
check_match(s, s->strstart, s->strstart - 1, run);
|
||||
_tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
|
||||
s->lookahead -= run;
|
||||
s->strstart += run;
|
||||
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]));
|
||||
|
@ -1730,7 +1916,51 @@ local block_state deflate_rle(s, flush)
|
|||
}
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2004 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
|||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: deflate.h 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#ifndef DEFLATE_H
|
||||
#define DEFLATE_H
|
||||
|
@ -48,6 +47,9 @@
|
|||
#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
|
||||
|
@ -101,7 +103,7 @@ typedef struct internal_state {
|
|||
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; /* STORED (for zip only) or DEFLATED */
|
||||
Byte method; /* can only be DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
|
@ -188,7 +190,7 @@ typedef struct internal_state {
|
|||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
||||
/* 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 */
|
||||
|
@ -244,7 +246,7 @@ typedef struct internal_state {
|
|||
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 */
|
||||
int last_eob_len; /* bit length of EOB code for last 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 */
|
||||
|
@ -260,6 +262,13 @@ typedef struct internal_state {
|
|||
* 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.
|
||||
|
@ -278,14 +287,19 @@ typedef struct internal_state {
|
|||
* 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 _tr_init OF((deflate_state *s));
|
||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void _tr_align OF((deflate_state *s));
|
||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
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)])
|
||||
|
@ -298,11 +312,11 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
|||
/* Inline versions of _tr_tally for speed: */
|
||||
|
||||
#if defined(GEN_TREES_H) || !defined(STDC)
|
||||
extern uch _length_code[];
|
||||
extern uch _dist_code[];
|
||||
extern uch ZLIB_INTERNAL _length_code[];
|
||||
extern uch ZLIB_INTERNAL _dist_code[];
|
||||
#else
|
||||
extern const uch _length_code[];
|
||||
extern const uch _dist_code[];
|
||||
extern const uch ZLIB_INTERNAL _length_code[];
|
||||
extern const uch ZLIB_INTERNAL _dist_code[];
|
||||
#endif
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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 <stdio.h>
|
||||
#include "zlib.h"
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
|
||||
# include <io.h>
|
||||
#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 <windows.h>
|
||||
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
|
||||
#else
|
||||
# ifndef NO_STRERROR
|
||||
# include <errno.h>
|
||||
# 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
|
File diff suppressed because it is too large
Load Diff
|
@ -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:%d>", fd); /* for debugging */
|
||||
#else
|
||||
sprintf(path, "<fd:%d>", 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
|
|
@ -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;
|
||||
}
|
|
@ -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 <stdarg.h>
|
||||
|
||||
/* -- 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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2008, 2010, 2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -64,13 +64,13 @@
|
|||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void inflate_fast(strm, start)
|
||||
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;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
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 */
|
||||
|
@ -79,7 +79,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
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 */
|
||||
|
@ -87,7 +87,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
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 this; /* retrieved table entry */
|
||||
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 */
|
||||
|
@ -106,7 +106,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
write = state->write;
|
||||
wnext = state->wnext;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
|
@ -124,20 +124,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = lcode[hold & lmask];
|
||||
here = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(this.bits);
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
op = (unsigned)(here.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
PUP(out) = (unsigned char)(this.val);
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
PUP(out) = (unsigned char)(here.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(this.val);
|
||||
len = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
|
@ -155,14 +155,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = dcode[hold & dmask];
|
||||
here = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(this.bits);
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
op = (unsigned)(here.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(this.val);
|
||||
dist = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
|
@ -187,12 +187,34 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
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 (write == 0) { /* very common case */
|
||||
if (wnext == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
|
@ -202,17 +224,17 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (write < op) { /* wrap around window */
|
||||
from += wsize + write - op;
|
||||
op -= write;
|
||||
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 (write < len) { /* some from start of window */
|
||||
op = write;
|
||||
if (wnext < len) { /* some from start of window */
|
||||
op = wnext;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
|
@ -222,7 +244,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += write - op;
|
||||
from += wnext - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
|
@ -259,7 +281,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
this = dcode[this.val + (hold & ((1U << op) - 1))];
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
|
@ -269,7 +291,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
this = lcode[this.val + (hold & ((1U << op) - 1))];
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
|
@ -305,7 +327,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
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 write == 0
|
||||
- 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003 Mark Adler
|
||||
* Copyright (C) 1995-2003, 2010 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
||||
void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* 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.
|
||||
/* 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] = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inflate.c -- zlib decompression
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2012 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
* - 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 write == 0 case for speed in inflate_fast()
|
||||
* - 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()
|
||||
|
@ -93,14 +93,15 @@
|
|||
|
||||
/* function prototypes */
|
||||
local void fixedtables OF((struct inflate_state FAR *state));
|
||||
local int updatewindow OF((z_streamp strm, unsigned out));
|
||||
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, unsigned char FAR *buf,
|
||||
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
|
||||
unsigned len));
|
||||
|
||||
int ZEXPORT inflateReset(strm)
|
||||
int ZEXPORT inflateResetKeep(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
@ -109,22 +110,123 @@ z_streamp strm;
|
|||
state = (struct inflate_state FAR *)strm->state;
|
||||
strm->total_in = strm->total_out = state->total = 0;
|
||||
strm->msg = Z_NULL;
|
||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
||||
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->wsize = 0;
|
||||
state->whave = 0;
|
||||
state->write = 0;
|
||||
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;
|
||||
|
@ -134,6 +236,11 @@ int value;
|
|||
|
||||
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;
|
||||
|
@ -141,57 +248,6 @@ int value;
|
|||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
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) return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
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;
|
||||
if (windowBits < 0) {
|
||||
state->wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
else {
|
||||
state->wrap = (windowBits >> 4) + 1;
|
||||
#ifdef GUNZIP
|
||||
if (windowBits < 48) windowBits &= 15;
|
||||
#endif
|
||||
}
|
||||
if (windowBits < 8 || windowBits > 15) {
|
||||
ZFREE(strm, state);
|
||||
strm->state = Z_NULL;
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
state->wbits = (unsigned)windowBits;
|
||||
state->window = Z_NULL;
|
||||
return inflateReset(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit_(strm, version, stream_size)
|
||||
z_streamp strm;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
|
||||
}
|
||||
|
||||
/*
|
||||
Return state with length and distance decoding tables and index sizes set to
|
||||
fixed code decoding. Normally this returns fixed tables from inffixed.h.
|
||||
|
@ -286,8 +342,8 @@ void makefixed()
|
|||
low = 0;
|
||||
for (;;) {
|
||||
if ((low % 7) == 0) printf("\n ");
|
||||
printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
|
||||
state.lencode[low].val);
|
||||
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(',');
|
||||
}
|
||||
|
@ -320,12 +376,13 @@ void makefixed()
|
|||
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, out)
|
||||
local int updatewindow(strm, end, copy)
|
||||
z_streamp strm;
|
||||
unsigned out;
|
||||
const Bytef *end;
|
||||
unsigned copy;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned copy, dist;
|
||||
unsigned dist;
|
||||
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
|
@ -340,30 +397,29 @@ unsigned out;
|
|||
/* if window not in use yet, initialize */
|
||||
if (state->wsize == 0) {
|
||||
state->wsize = 1U << state->wbits;
|
||||
state->write = 0;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
}
|
||||
|
||||
/* copy state->wsize or less output bytes into the circular window */
|
||||
copy = out - strm->avail_out;
|
||||
if (copy >= state->wsize) {
|
||||
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
|
||||
state->write = 0;
|
||||
zmemcpy(state->window, end - state->wsize, state->wsize);
|
||||
state->wnext = 0;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
dist = state->wsize - state->write;
|
||||
dist = state->wsize - state->wnext;
|
||||
if (dist > copy) dist = copy;
|
||||
zmemcpy(state->window + state->write, strm->next_out - copy, dist);
|
||||
zmemcpy(state->window + state->wnext, end - copy, dist);
|
||||
copy -= dist;
|
||||
if (copy) {
|
||||
zmemcpy(state->window, strm->next_out - copy, copy);
|
||||
state->write = copy;
|
||||
zmemcpy(state->window, end - copy, copy);
|
||||
state->wnext = copy;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
state->write += dist;
|
||||
if (state->write == state->wsize) state->write = 0;
|
||||
state->wnext += dist;
|
||||
if (state->wnext == state->wsize) state->wnext = 0;
|
||||
if (state->whave < state->wsize) state->whave += dist;
|
||||
}
|
||||
}
|
||||
|
@ -464,11 +520,6 @@ unsigned out;
|
|||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define REVERSE(q) \
|
||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
/*
|
||||
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
|
||||
|
@ -556,7 +607,7 @@ z_streamp strm;
|
|||
int flush;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *next; /* next input */
|
||||
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 */
|
||||
|
@ -564,7 +615,7 @@ int flush;
|
|||
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 this; /* current decoding table entry */
|
||||
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 */
|
||||
|
@ -619,7 +670,9 @@ int flush;
|
|||
}
|
||||
DROPBITS(4);
|
||||
len = BITS(4) + 8;
|
||||
if (len > state->wbits) {
|
||||
if (state->wbits == 0)
|
||||
state->wbits = len;
|
||||
else if (len > state->wbits) {
|
||||
strm->msg = (char *)"invalid window size";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
|
@ -760,7 +813,7 @@ int flush;
|
|||
#endif
|
||||
case DICTID:
|
||||
NEEDBITS(32);
|
||||
strm->adler = state->check = REVERSE(hold);
|
||||
strm->adler = state->check = ZSWAP32(hold);
|
||||
INITBITS();
|
||||
state->mode = DICT;
|
||||
case DICT:
|
||||
|
@ -771,7 +824,7 @@ int flush;
|
|||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = TYPE;
|
||||
case TYPE:
|
||||
if (flush == Z_BLOCK) goto inf_leave;
|
||||
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
|
||||
case TYPEDO:
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
|
@ -791,7 +844,11 @@ int flush;
|
|||
fixedtables(state);
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = LEN; /* decode codes */
|
||||
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",
|
||||
|
@ -816,6 +873,9 @@ int flush;
|
|||
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;
|
||||
|
@ -861,7 +921,7 @@ int flush;
|
|||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
|
@ -876,19 +936,18 @@ int flush;
|
|||
case CODELENS:
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.val < 16) {
|
||||
NEEDBITS(this.bits);
|
||||
DROPBITS(this.bits);
|
||||
state->lens[state->have++] = this.val;
|
||||
if (here.val < 16) {
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
}
|
||||
else {
|
||||
if (this.val == 16) {
|
||||
NEEDBITS(this.bits + 2);
|
||||
DROPBITS(this.bits);
|
||||
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;
|
||||
|
@ -898,16 +957,16 @@ int flush;
|
|||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
}
|
||||
else if (this.val == 17) {
|
||||
NEEDBITS(this.bits + 3);
|
||||
DROPBITS(this.bits);
|
||||
else if (here.val == 17) {
|
||||
NEEDBITS(here.bits + 3);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
else {
|
||||
NEEDBITS(this.bits + 7);
|
||||
DROPBITS(this.bits);
|
||||
NEEDBITS(here.bits + 7);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
|
@ -925,9 +984,18 @@ int flush;
|
|||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* build code tables */
|
||||
/* 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->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
|
@ -936,7 +1004,7 @@ int flush;
|
|||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (code const FAR *)(state->next);
|
||||
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);
|
||||
|
@ -946,88 +1014,102 @@ int flush;
|
|||
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 (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.op && (this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if (here.op && (here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->lencode[last.val +
|
||||
here = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
state->back += last.bits;
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
state->length = (unsigned)this.val;
|
||||
if ((int)(this.op) == 0) {
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
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", this.val));
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
state->mode = LIT;
|
||||
break;
|
||||
}
|
||||
if (this.op & 32) {
|
||||
if (here.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->back = -1;
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
if (this.op & 64) {
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
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 (;;) {
|
||||
this = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if ((here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->distcode[last.val +
|
||||
here = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
state->back += last.bits;
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
if (this.op & 64) {
|
||||
DROPBITS(here.bits);
|
||||
state->back += here.bits;
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)this.val;
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
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) {
|
||||
|
@ -1036,11 +1118,6 @@ int flush;
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
if (state->offset > state->whave + out - left) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
state->mode = MATCH;
|
||||
case MATCH:
|
||||
|
@ -1048,12 +1125,32 @@ int flush;
|
|||
copy = out - left;
|
||||
if (state->offset > copy) { /* copy from window */
|
||||
copy = state->offset - copy;
|
||||
if (copy > state->write) {
|
||||
copy -= state->write;
|
||||
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->write - copy);
|
||||
from = state->window + (state->wnext - copy);
|
||||
if (copy > state->length) copy = state->length;
|
||||
}
|
||||
else { /* copy from output */
|
||||
|
@ -1088,7 +1185,7 @@ int flush;
|
|||
#ifdef GUNZIP
|
||||
state->flags ? hold :
|
||||
#endif
|
||||
REVERSE(hold)) != state->check) {
|
||||
ZSWAP32(hold)) != state->check) {
|
||||
strm->msg = (char *)"incorrect data check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
|
@ -1132,8 +1229,9 @@ int flush;
|
|||
*/
|
||||
inf_leave:
|
||||
RESTORE();
|
||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
||||
if (updatewindow(strm, out)) {
|
||||
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;
|
||||
}
|
||||
|
@ -1146,7 +1244,8 @@ int flush;
|
|||
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 == 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;
|
||||
|
@ -1166,13 +1265,37 @@ z_streamp strm;
|
|||
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 id;
|
||||
unsigned long dictid;
|
||||
int ret;
|
||||
|
||||
/* check state */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
|
@ -1180,29 +1303,21 @@ uInt dictLength;
|
|||
if (state->wrap != 0 && state->mode != DICT)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check for correct dictionary id */
|
||||
/* check for correct dictionary identifier */
|
||||
if (state->mode == DICT) {
|
||||
id = adler32(0L, Z_NULL, 0);
|
||||
id = adler32(id, dictionary, dictLength);
|
||||
if (id != state->check)
|
||||
dictid = adler32(0L, Z_NULL, 0);
|
||||
dictid = adler32(dictid, dictionary, dictLength);
|
||||
if (dictid != state->check)
|
||||
return Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* copy dictionary to window */
|
||||
if (updatewindow(strm, strm->avail_out)) {
|
||||
/* 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;
|
||||
}
|
||||
if (dictLength > state->wsize) {
|
||||
zmemcpy(state->window, dictionary + dictLength - state->wsize,
|
||||
state->wsize);
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
zmemcpy(state->window + state->wsize - dictLength, dictionary,
|
||||
dictLength);
|
||||
state->whave = dictLength;
|
||||
}
|
||||
state->havedict = 1;
|
||||
Tracev((stderr, "inflate: dictionary set\n"));
|
||||
return Z_OK;
|
||||
|
@ -1238,7 +1353,7 @@ gz_headerp head;
|
|||
*/
|
||||
local unsigned syncsearch(have, buf, len)
|
||||
unsigned FAR *have;
|
||||
unsigned char FAR *buf;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
unsigned got;
|
||||
|
@ -1350,8 +1465,8 @@ z_streamp source;
|
|||
}
|
||||
|
||||
/* copy state */
|
||||
zmemcpy(dest, source, sizeof(z_stream));
|
||||
zmemcpy(copy, state, sizeof(struct inflate_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);
|
||||
|
@ -1366,3 +1481,32 @@ z_streamp source;
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2009 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -32,11 +32,13 @@ typedef enum {
|
|||
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: waiting for length/lit code */
|
||||
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 */
|
||||
|
@ -53,19 +55,21 @@ typedef enum {
|
|||
/*
|
||||
State transitions between above modes -
|
||||
|
||||
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||||
(most modes can go to BAD or MEM on error -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||||
NAME -> COMMENT -> HCRC -> TYPE
|
||||
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 -> STORED or TABLE or LEN or CHECK
|
||||
STORED -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN
|
||||
Read deflate codes:
|
||||
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
|
||||
|
@ -73,7 +77,7 @@ typedef enum {
|
|||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||||
/* state maintained between inflate() calls. Approximately 10K bytes. */
|
||||
struct inflate_state {
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
|
@ -88,7 +92,7 @@ struct inflate_state {
|
|||
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 write; /* window write index */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
|
@ -112,4 +116,7 @@ struct inflate_state {
|
|||
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 */
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
|||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
|
||||
" 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
|
||||
|
@ -29,7 +29,7 @@ const char inflate_copyright[] =
|
|||
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 inflate_table(type, lens, codes, table, bits, work)
|
||||
int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
|
||||
codetype type;
|
||||
unsigned short FAR *lens;
|
||||
unsigned codes;
|
||||
|
@ -50,7 +50,7 @@ unsigned short FAR *work;
|
|||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code this; /* table entry for duplication */
|
||||
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 */
|
||||
|
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
|||
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, 201, 196};
|
||||
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,
|
||||
|
@ -115,15 +115,15 @@ unsigned short FAR *work;
|
|||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)1;
|
||||
this.val = (unsigned short)0;
|
||||
*(*table)++ = this; /* make a table to force an error */
|
||||
*(*table)++ = this;
|
||||
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 <= MAXBITS; min++)
|
||||
for (min = 1; min < max; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
|
@ -166,11 +166,10 @@ unsigned short FAR *work;
|
|||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked when a LENS table is being made
|
||||
against the space in *table, ENOUGH, minus the maximum space needed by
|
||||
the worst case distance code, MAXD. This should never happen, but the
|
||||
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
|
||||
This assumes that when type == LENS, bits == 9.
|
||||
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
|
||||
|
@ -209,24 +208,25 @@ unsigned short FAR *work;
|
|||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
this.op = (unsigned char)0;
|
||||
this.val = work[sym];
|
||||
here.op = (unsigned char)0;
|
||||
here.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
this.op = (unsigned char)(extra[work[sym]]);
|
||||
this.val = base[work[sym]];
|
||||
here.op = (unsigned char)(extra[work[sym]]);
|
||||
here.val = base[work[sym]];
|
||||
}
|
||||
else {
|
||||
this.op = (unsigned char)(32 + 64); /* end of block */
|
||||
this.val = 0;
|
||||
here.op = (unsigned char)(32 + 64); /* end of block */
|
||||
here.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
|
@ -235,7 +235,7 @@ unsigned short FAR *work;
|
|||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = this;
|
||||
next[(huff >> drop) + fill] = here;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
|
@ -277,7 +277,8 @@ unsigned short FAR *work;
|
|||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
|
@ -288,38 +289,14 @@ unsigned short FAR *work;
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
this.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
this.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = this;
|
||||
|
||||
/* 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;
|
||||
/* 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 */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2005, 2010 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -35,21 +35,28 @@ typedef struct {
|
|||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Maximum size of dynamic tree. The maximum found in a long but non-
|
||||
exhaustive search was 1444 code structures (852 for length/literals
|
||||
and 592 for distances, the latter actually the result of an
|
||||
exhaustive search). The true maximum is not known, but the value
|
||||
below is more than safe. */
|
||||
#define ENOUGH 2048
|
||||
#define MAXD 592
|
||||
/* 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 inftable() */
|
||||
/* Type of code to build for inflate_table() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
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));
|
||||
|
|
|
@ -1,322 +0,0 @@
|
|||
/* minigzip.c -- simulate gzip using the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* minigzip is a minimal implementation of the gzip utility. This is
|
||||
* only an example of using zlib and isn't meant to replace the
|
||||
* full-featured gzip. No attempt is made to deal with file systems
|
||||
* limiting names to 14 or 8+3 characters, etc... Error checking is
|
||||
* very limited. So use minigzip only for testing; use gzip for the
|
||||
* real thing. On MSDOS, use only on file names without extension
|
||||
* or in pipe mode.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: minigzip.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_MMAP
|
||||
# include <sys/types.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
#else
|
||||
# define SET_BINARY_MODE(file)
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
# define unlink delete
|
||||
# define GZ_SUFFIX "-gz"
|
||||
#endif
|
||||
#ifdef RISCOS
|
||||
# define unlink remove
|
||||
# define GZ_SUFFIX "-gz"
|
||||
# define fileno(file) file->__file
|
||||
#endif
|
||||
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fileno */
|
||||
#endif
|
||||
|
||||
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
|
||||
extern int unlink OF((const char *));
|
||||
#endif
|
||||
|
||||
#ifndef GZ_SUFFIX
|
||||
# define GZ_SUFFIX ".gz"
|
||||
#endif
|
||||
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
|
||||
|
||||
#define BUFLEN 16384
|
||||
#define MAX_NAME_LEN 1024
|
||||
|
||||
#ifdef MAXSEG_64K
|
||||
# define local static
|
||||
/* Needed for systems with limitation on stack size. */
|
||||
#else
|
||||
# define local
|
||||
#endif
|
||||
|
||||
char *prog;
|
||||
|
||||
void error OF((const char *msg));
|
||||
void gz_compress OF((FILE *in, gzFile out));
|
||||
#ifdef USE_MMAP
|
||||
int gz_compress_mmap OF((FILE *in, gzFile out));
|
||||
#endif
|
||||
void gz_uncompress OF((gzFile in, FILE *out));
|
||||
void file_compress OF((char *file, char *mode));
|
||||
void file_uncompress OF((char *file));
|
||||
int main OF((int argc, char *argv[]));
|
||||
|
||||
/* ===========================================================================
|
||||
* Display error message and exit
|
||||
*/
|
||||
void error(msg)
|
||||
const char *msg;
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", prog, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Compress input to output then close both files.
|
||||
*/
|
||||
|
||||
void gz_compress(in, out)
|
||||
FILE *in;
|
||||
gzFile out;
|
||||
{
|
||||
local char buf[BUFLEN];
|
||||
int len;
|
||||
int err;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
/* Try first compressing with mmap. If mmap fails (minigzip used in a
|
||||
* pipe), use the normal fread loop.
|
||||
*/
|
||||
if (gz_compress_mmap(in, out) == Z_OK) return;
|
||||
#endif
|
||||
for (;;) {
|
||||
len = (int)fread(buf, 1, sizeof(buf), in);
|
||||
if (ferror(in)) {
|
||||
perror("fread");
|
||||
exit(1);
|
||||
}
|
||||
if (len == 0) break;
|
||||
|
||||
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
|
||||
}
|
||||
fclose(in);
|
||||
if (gzclose(out) != Z_OK) error("failed gzclose");
|
||||
}
|
||||
|
||||
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
|
||||
|
||||
/* Try compressing the input file at once using mmap. Return Z_OK if
|
||||
* if success, Z_ERRNO otherwise.
|
||||
*/
|
||||
int gz_compress_mmap(in, out)
|
||||
FILE *in;
|
||||
gzFile out;
|
||||
{
|
||||
int len;
|
||||
int err;
|
||||
int ifd = fileno(in);
|
||||
caddr_t buf; /* mmap'ed buffer for the entire input file */
|
||||
off_t buf_len; /* length of the input file */
|
||||
struct stat sb;
|
||||
|
||||
/* Determine the size of the file, needed for mmap: */
|
||||
if (fstat(ifd, &sb) < 0) return Z_ERRNO;
|
||||
buf_len = sb.st_size;
|
||||
if (buf_len <= 0) return Z_ERRNO;
|
||||
|
||||
/* Now do the actual mmap: */
|
||||
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
|
||||
if (buf == (caddr_t)(-1)) return Z_ERRNO;
|
||||
|
||||
/* Compress the whole file at once: */
|
||||
len = gzwrite(out, (char *)buf, (unsigned)buf_len);
|
||||
|
||||
if (len != (int)buf_len) error(gzerror(out, &err));
|
||||
|
||||
munmap(buf, buf_len);
|
||||
fclose(in);
|
||||
if (gzclose(out) != Z_OK) error("failed gzclose");
|
||||
return Z_OK;
|
||||
}
|
||||
#endif /* USE_MMAP */
|
||||
|
||||
/* ===========================================================================
|
||||
* Uncompress input to output then close both files.
|
||||
*/
|
||||
void gz_uncompress(in, out)
|
||||
gzFile in;
|
||||
FILE *out;
|
||||
{
|
||||
local char buf[BUFLEN];
|
||||
int len;
|
||||
int err;
|
||||
|
||||
for (;;) {
|
||||
len = gzread(in, buf, sizeof(buf));
|
||||
if (len < 0) error (gzerror(in, &err));
|
||||
if (len == 0) break;
|
||||
|
||||
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
|
||||
error("failed fwrite");
|
||||
}
|
||||
}
|
||||
if (fclose(out)) error("failed fclose");
|
||||
|
||||
if (gzclose(in) != Z_OK) error("failed gzclose");
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Compress the given file: create a corresponding .gz file and remove the
|
||||
* original.
|
||||
*/
|
||||
void file_compress(file, mode)
|
||||
char *file;
|
||||
char *mode;
|
||||
{
|
||||
local char outfile[MAX_NAME_LEN];
|
||||
FILE *in;
|
||||
gzFile out;
|
||||
|
||||
strcpy(outfile, file);
|
||||
strcat(outfile, GZ_SUFFIX);
|
||||
|
||||
in = fopen(file, "rb");
|
||||
if (in == NULL) {
|
||||
perror(file);
|
||||
exit(1);
|
||||
}
|
||||
out = gzopen(outfile, mode);
|
||||
if (out == NULL) {
|
||||
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
|
||||
exit(1);
|
||||
}
|
||||
gz_compress(in, out);
|
||||
|
||||
unlink(file);
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Uncompress the given file and remove the original.
|
||||
*/
|
||||
void file_uncompress(file)
|
||||
char *file;
|
||||
{
|
||||
local char buf[MAX_NAME_LEN];
|
||||
char *infile, *outfile;
|
||||
FILE *out;
|
||||
gzFile in;
|
||||
uInt len = (uInt)strlen(file);
|
||||
|
||||
strcpy(buf, file);
|
||||
|
||||
if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
|
||||
infile = file;
|
||||
outfile = buf;
|
||||
outfile[len-3] = '\0';
|
||||
} else {
|
||||
outfile = file;
|
||||
infile = buf;
|
||||
strcat(infile, GZ_SUFFIX);
|
||||
}
|
||||
in = gzopen(infile, "rb");
|
||||
if (in == NULL) {
|
||||
fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
|
||||
exit(1);
|
||||
}
|
||||
out = fopen(outfile, "wb");
|
||||
if (out == NULL) {
|
||||
perror(file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
gz_uncompress(in, out);
|
||||
|
||||
unlink(infile);
|
||||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
|
||||
* -d : decompress
|
||||
* -f : compress with Z_FILTERED
|
||||
* -h : compress with Z_HUFFMAN_ONLY
|
||||
* -r : compress with Z_RLE
|
||||
* -1 to -9 : compression level
|
||||
*/
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int uncompr = 0;
|
||||
gzFile file;
|
||||
char outmode[20];
|
||||
|
||||
strcpy(outmode, "wb6 ");
|
||||
|
||||
prog = argv[0];
|
||||
argc--, argv++;
|
||||
|
||||
while (argc > 0) {
|
||||
if (strcmp(*argv, "-d") == 0)
|
||||
uncompr = 1;
|
||||
else if (strcmp(*argv, "-f") == 0)
|
||||
outmode[3] = 'f';
|
||||
else if (strcmp(*argv, "-h") == 0)
|
||||
outmode[3] = 'h';
|
||||
else if (strcmp(*argv, "-r") == 0)
|
||||
outmode[3] = 'R';
|
||||
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
|
||||
(*argv)[2] == 0)
|
||||
outmode[2] = (*argv)[1];
|
||||
else
|
||||
break;
|
||||
argc--, argv++;
|
||||
}
|
||||
if (outmode[3] == ' ')
|
||||
outmode[3] = 0;
|
||||
if (argc == 0) {
|
||||
SET_BINARY_MODE(stdin);
|
||||
SET_BINARY_MODE(stdout);
|
||||
if (uncompr) {
|
||||
file = gzdopen(fileno(stdin), "rb");
|
||||
if (file == NULL) error("can't gzdopen stdin");
|
||||
gz_uncompress(file, stdout);
|
||||
} else {
|
||||
file = gzdopen(fileno(stdout), outmode);
|
||||
if (file == NULL) error("can't gzdopen stdout");
|
||||
gz_compress(stdin, file);
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
if (uncompr) {
|
||||
file_uncompress(*argv);
|
||||
} else {
|
||||
file_compress(*argv, outmode);
|
||||
}
|
||||
} while (argv++, --argc);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
@ -29,7 +30,6 @@
|
|||
* Addison-Wesley, 1983. ISBN 0-201-06672-6.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: trees.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
/* #define GEN_TREES_H */
|
||||
|
||||
|
@ -73,11 +73,6 @@ local const uch bl_order[BL_CODES]
|
|||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||||
*/
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data. These are initialized only once.
|
||||
*/
|
||||
|
@ -150,9 +145,9 @@ 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, ct_data *ltree,
|
||||
ct_data *dtree));
|
||||
local void set_data_type OF((deflate_state *s));
|
||||
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));
|
||||
|
@ -203,12 +198,12 @@ local void send_bits(s, value, length)
|
|||
* unused bits in value.
|
||||
*/
|
||||
if (s->bi_valid > (int)Buf_size - length) {
|
||||
s->bi_buf |= (value << s->bi_valid);
|
||||
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 |= value << s->bi_valid;
|
||||
s->bi_buf |= (ush)value << s->bi_valid;
|
||||
s->bi_valid += length;
|
||||
}
|
||||
}
|
||||
|
@ -218,12 +213,12 @@ local void send_bits(s, value, length)
|
|||
{ int len = length;\
|
||||
if (s->bi_valid > (int)Buf_size - len) {\
|
||||
int val = value;\
|
||||
s->bi_buf |= (val << s->bi_valid);\
|
||||
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 |= (value) << s->bi_valid;\
|
||||
s->bi_buf |= (ush)(value) << s->bi_valid;\
|
||||
s->bi_valid += len;\
|
||||
}\
|
||||
}
|
||||
|
@ -250,11 +245,13 @@ local void tr_static_init()
|
|||
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;
|
||||
|
@ -348,13 +345,14 @@ void gen_trees_header()
|
|||
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
|
||||
}
|
||||
|
||||
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
|
||||
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 _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
||||
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));
|
||||
|
@ -379,7 +377,7 @@ void gen_trees_header()
|
|||
/* ===========================================================================
|
||||
* Initialize the tree data structures for a new zlib stream.
|
||||
*/
|
||||
void _tr_init(s)
|
||||
void ZLIB_INTERNAL _tr_init(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
tr_static_init();
|
||||
|
@ -395,7 +393,6 @@ void _tr_init(s)
|
|||
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
#ifdef DEBUG
|
||||
s->compressed_len = 0L;
|
||||
s->bits_sent = 0L;
|
||||
|
@ -864,13 +861,13 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
|||
/* ===========================================================================
|
||||
* Send a stored block
|
||||
*/
|
||||
void _tr_stored_block(s, buf, stored_len, eof)
|
||||
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 eof; /* true if this is the last block for a file */
|
||||
int last; /* one if this is the last block for a file */
|
||||
{
|
||||
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
|
||||
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;
|
||||
|
@ -878,18 +875,20 @@ void _tr_stored_block(s, buf, stored_len, eof)
|
|||
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.
|
||||
* The current inflate code requires 9 bits of lookahead. If the
|
||||
* last two codes for the previous block (real code plus EOB) were coded
|
||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
||||
* the last real code. In this case we send two empty static blocks instead
|
||||
* of one. (There are no problems if the previous block is stored or fixed.)
|
||||
* To simplify the code, we assume the worst case of last real code encoded
|
||||
* on one bit only.
|
||||
*/
|
||||
void _tr_align(s)
|
||||
void ZLIB_INTERNAL _tr_align(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
|
@ -898,31 +897,17 @@ void _tr_align(s)
|
|||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||
#endif
|
||||
bi_flush(s);
|
||||
/* Of the 10 bits for the empty block, we have already sent
|
||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
||||
* the EOB of the previous block) was thus at least one plus the length
|
||||
* of the EOB plus what we have just sent of the empty static block.
|
||||
*/
|
||||
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
send_code(s, END_BLOCK, static_ltree);
|
||||
#ifdef DEBUG
|
||||
s->compressed_len += 10L;
|
||||
#endif
|
||||
bi_flush(s);
|
||||
}
|
||||
s->last_eob_len = 7;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Determine the best encoding for the current block: dynamic trees, static
|
||||
* trees or store, and output the encoded block to the zip file.
|
||||
*/
|
||||
void _tr_flush_block(s, buf, stored_len, eof)
|
||||
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 eof; /* true if this is the last block for a file */
|
||||
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 */
|
||||
|
@ -931,8 +916,8 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
|||
if (s->level > 0) {
|
||||
|
||||
/* Check if the file is binary or text */
|
||||
if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
|
||||
set_data_type(s);
|
||||
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)));
|
||||
|
@ -978,23 +963,25 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
|||
* 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, eof);
|
||||
_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)+eof, 3);
|
||||
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
|
||||
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)+eof, 3);
|
||||
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, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
|
||||
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
|
||||
|
@ -1005,21 +992,21 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
|||
*/
|
||||
init_block(s);
|
||||
|
||||
if (eof) {
|
||||
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*eof));
|
||||
s->compressed_len-7*last));
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Save the match info and tally the frequency counts. Return true if
|
||||
* the current block must be flushed.
|
||||
*/
|
||||
int _tr_tally (s, dist, lc)
|
||||
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) */
|
||||
|
@ -1071,8 +1058,8 @@ int _tr_tally (s, dist, lc)
|
|||
*/
|
||||
local void compress_block(s, ltree, dtree)
|
||||
deflate_state *s;
|
||||
ct_data *ltree; /* literal tree */
|
||||
ct_data *dtree; /* distance tree */
|
||||
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) */
|
||||
|
@ -1114,28 +1101,48 @@ local void compress_block(s, ltree, dtree)
|
|||
} while (lx < s->last_lit);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
s->last_eob_len = ltree[END_BLOCK].Len;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Set the data type to BINARY or TEXT, using a crude approximation:
|
||||
* set it to Z_TEXT if all symbols are either printable characters (33 to 255)
|
||||
* or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
|
||||
* 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 void set_data_type(s)
|
||||
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;
|
||||
|
||||
for (n = 0; n < 9; 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)
|
||||
break;
|
||||
if (n == 9)
|
||||
for (n = 14; n < 32; n++)
|
||||
if (s->dyn_ltree[n].Freq != 0)
|
||||
break;
|
||||
s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
|
||||
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;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -1201,7 +1208,6 @@ local void copy_block(s, buf, len, header)
|
|||
int header; /* true if block header must be written */
|
||||
{
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
|
||||
if (header) {
|
||||
put_short(s, (ush)len);
|
||||
|
|
|
@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
|
|||
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
||||
};
|
||||
|
||||
const uch _dist_code[DIST_CODE_LEN] = {
|
||||
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,
|
||||
|
@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
|
|||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
||||
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,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/* uncompr.c -- decompress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id: uncompr.c 26956 2004-04-25 08:48:21Z VS $ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
@ -16,8 +15,6 @@
|
|||
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.
|
||||
This function can be used to decompress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
|
||||
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
|
||||
|
@ -32,7 +29,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
|||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
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;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id: zconf.h 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
@ -11,52 +10,145 @@
|
|||
/*
|
||||
* 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
|
||||
# define deflateInit_ z_deflateInit_
|
||||
#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 deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# 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 inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# 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 compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# 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
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# 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 voidpf z_voidpf
|
||||
# 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)
|
||||
|
@ -125,6 +217,12 @@
|
|||
# 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
|
||||
|
@ -171,6 +269,14 @@
|
|||
# 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
|
||||
|
@ -284,49 +390,121 @@ typedef uLong FAR uLongf;
|
|||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||
# include <limits.h>
|
||||
# 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
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
|
||||
#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 <sys/types.h> /* for off_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
# include <stdarg.h> /* for va_list */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef Z_SOLO
|
||||
# include <stddef.h> /* 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 <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* 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(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
#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")
|
||||
#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 */
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
.TH ZLIB 3 "28 Apr 2013"
|
||||
.SH NAME
|
||||
zlib \- compression/decompression library
|
||||
.SH SYNOPSIS
|
||||
[see
|
||||
.I zlib.h
|
||||
for full description]
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I zlib
|
||||
library is a general purpose data compression library.
|
||||
The code is thread safe, assuming that the standard library functions
|
||||
used are thread safe, such as memory allocation routines.
|
||||
It 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 may be added later
|
||||
with the same stream interface.
|
||||
.LP
|
||||
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.
|
||||
.LP
|
||||
The library also supports reading and writing files in
|
||||
.IR gzip (1)
|
||||
(.gz) format
|
||||
with an interface similar to that of stdio.
|
||||
.LP
|
||||
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 the case of corrupted input.
|
||||
.LP
|
||||
All functions of the compression library are documented in the file
|
||||
.IR zlib.h .
|
||||
The distribution source includes examples of use of the library
|
||||
in the files
|
||||
.I test/example.c
|
||||
and
|
||||
.IR test/minigzip.c,
|
||||
as well as other examples in the
|
||||
.IR examples/
|
||||
directory.
|
||||
.LP
|
||||
Changes to this version are documented in the file
|
||||
.I ChangeLog
|
||||
that accompanies the source.
|
||||
.LP
|
||||
.I zlib
|
||||
is available in Java using the java.util.zip package:
|
||||
.IP
|
||||
http://java.sun.com/developer/technicalArticles/Programming/compression/
|
||||
.LP
|
||||
A Perl interface to
|
||||
.IR zlib ,
|
||||
written by Paul Marquess (pmqs@cpan.org),
|
||||
is available at CPAN (Comprehensive Perl Archive Network) sites,
|
||||
including:
|
||||
.IP
|
||||
http://search.cpan.org/~pmqs/IO-Compress-Zlib/
|
||||
.LP
|
||||
A Python interface to
|
||||
.IR zlib ,
|
||||
written by A.M. Kuchling (amk@magnet.com),
|
||||
is available in Python 1.5 and later versions:
|
||||
.IP
|
||||
http://docs.python.org/library/zlib.html
|
||||
.LP
|
||||
.I zlib
|
||||
is built into
|
||||
.IR tcl:
|
||||
.IP
|
||||
http://wiki.tcl.tk/4610
|
||||
.LP
|
||||
An experimental package to read and write files in .zip format,
|
||||
written on top of
|
||||
.I zlib
|
||||
by Gilles Vollant (info@winimage.com),
|
||||
is available at:
|
||||
.IP
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
and also in the
|
||||
.I contrib/minizip
|
||||
directory of the main
|
||||
.I zlib
|
||||
source distribution.
|
||||
.SH "SEE ALSO"
|
||||
The
|
||||
.I zlib
|
||||
web site can be found at:
|
||||
.IP
|
||||
http://zlib.net/
|
||||
.LP
|
||||
The data format used by the zlib library is described by RFC
|
||||
(Request for Comments) 1950 to 1952 in the files:
|
||||
.IP
|
||||
http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
|
||||
.br
|
||||
http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
|
||||
.br
|
||||
http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
|
||||
.LP
|
||||
Mark Nelson wrote an article about
|
||||
.I zlib
|
||||
for the Jan. 1997 issue of Dr. Dobb's Journal;
|
||||
a copy of the article is available at:
|
||||
.IP
|
||||
http://marknelson.us/1997/01/01/zlib-engine/
|
||||
.SH "REPORTING PROBLEMS"
|
||||
Before reporting a problem,
|
||||
please check the
|
||||
.I zlib
|
||||
web site to verify that you have the latest version of
|
||||
.IR zlib ;
|
||||
otherwise,
|
||||
obtain the latest version and see if the problem still exists.
|
||||
Please read the
|
||||
.I zlib
|
||||
FAQ at:
|
||||
.IP
|
||||
http://zlib.net/zlib_faq.html
|
||||
.LP
|
||||
before asking for help.
|
||||
Send questions and/or comments to zlib@gzip.org,
|
||||
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
|
||||
.SH AUTHORS
|
||||
Version 1.2.8
|
||||
Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)
|
||||
and Mark Adler (madler@alumni.caltech.edu).
|
||||
.LP
|
||||
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.
|
||||
See the distribution directory with respect to requirements
|
||||
governing redistribution.
|
||||
The deflate format used by
|
||||
.I zlib
|
||||
was defined by Phil Katz.
|
||||
The deflate and
|
||||
.I zlib
|
||||
specifications were written by L. Peter Deutsch.
|
||||
Thanks to all the people who reported problems and suggested various
|
||||
improvements in
|
||||
.IR zlib ;
|
||||
who are too numerous to cite here.
|
||||
.LP
|
||||
UNIX manual page by R. P. C. Rodgers,
|
||||
U.S. National Library of Medicine (rodgers@nlm.nih.gov).
|
||||
.\" end of man page
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,83 @@
|
|||
ZLIB_1.2.0 {
|
||||
global:
|
||||
compressBound;
|
||||
deflateBound;
|
||||
inflateBack;
|
||||
inflateBackEnd;
|
||||
inflateBackInit_;
|
||||
inflateCopy;
|
||||
local:
|
||||
deflate_copyright;
|
||||
inflate_copyright;
|
||||
inflate_fast;
|
||||
inflate_table;
|
||||
zcalloc;
|
||||
zcfree;
|
||||
z_errmsg;
|
||||
gz_error;
|
||||
gz_intmax;
|
||||
_*;
|
||||
};
|
||||
|
||||
ZLIB_1.2.0.2 {
|
||||
gzclearerr;
|
||||
gzungetc;
|
||||
zlibCompileFlags;
|
||||
} ZLIB_1.2.0;
|
||||
|
||||
ZLIB_1.2.0.8 {
|
||||
deflatePrime;
|
||||
} ZLIB_1.2.0.2;
|
||||
|
||||
ZLIB_1.2.2 {
|
||||
adler32_combine;
|
||||
crc32_combine;
|
||||
deflateSetHeader;
|
||||
inflateGetHeader;
|
||||
} ZLIB_1.2.0.8;
|
||||
|
||||
ZLIB_1.2.2.3 {
|
||||
deflateTune;
|
||||
gzdirect;
|
||||
} ZLIB_1.2.2;
|
||||
|
||||
ZLIB_1.2.2.4 {
|
||||
inflatePrime;
|
||||
} ZLIB_1.2.2.3;
|
||||
|
||||
ZLIB_1.2.3.3 {
|
||||
adler32_combine64;
|
||||
crc32_combine64;
|
||||
gzopen64;
|
||||
gzseek64;
|
||||
gztell64;
|
||||
inflateUndermine;
|
||||
} ZLIB_1.2.2.4;
|
||||
|
||||
ZLIB_1.2.3.4 {
|
||||
inflateReset2;
|
||||
inflateMark;
|
||||
} ZLIB_1.2.3.3;
|
||||
|
||||
ZLIB_1.2.3.5 {
|
||||
gzbuffer;
|
||||
gzoffset;
|
||||
gzoffset64;
|
||||
gzclose_r;
|
||||
gzclose_w;
|
||||
} ZLIB_1.2.3.4;
|
||||
|
||||
ZLIB_1.2.5.1 {
|
||||
deflatePending;
|
||||
} ZLIB_1.2.3.5;
|
||||
|
||||
ZLIB_1.2.5.2 {
|
||||
deflateResetKeep;
|
||||
gzgetc_;
|
||||
inflateResetKeep;
|
||||
} ZLIB_1.2.5.1;
|
||||
|
||||
ZLIB_1.2.7.1 {
|
||||
inflateGetDictionary;
|
||||
gzvprintf;
|
||||
} ZLIB_1.2.5.2;
|
|
@ -0,0 +1,13 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
sharedlibdir=@sharedlibdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: zlib
|
||||
Description: zlib compression library
|
||||
Version: @VERSION@
|
||||
|
||||
Requires:
|
||||
Libs: -L${libdir} -L${sharedlibdir} -lz
|
||||
Cflags: -I${includedir}
|
|
@ -1,17 +1,19 @@
|
|||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id: zutil.c 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#include "zutil.h"
|
||||
#ifndef Z_SOLO
|
||||
# include "gzguts.h"
|
||||
#endif
|
||||
|
||||
#ifndef NO_DUMMY_DECL
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
const char * const z_errmsg[10] = {
|
||||
z_const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
|
@ -34,25 +36,25 @@ uLong ZEXPORT zlibCompileFlags()
|
|||
uLong flags;
|
||||
|
||||
flags = 0;
|
||||
switch (sizeof(uInt)) {
|
||||
switch ((int)(sizeof(uInt))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1; break;
|
||||
case 8: flags += 2; break;
|
||||
default: flags += 3;
|
||||
}
|
||||
switch (sizeof(uLong)) {
|
||||
switch ((int)(sizeof(uLong))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 2; break;
|
||||
case 8: flags += 2 << 2; break;
|
||||
default: flags += 3 << 2;
|
||||
}
|
||||
switch (sizeof(voidpf)) {
|
||||
switch ((int)(sizeof(voidpf))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 4; break;
|
||||
case 8: flags += 2 << 4; break;
|
||||
default: flags += 3 << 4;
|
||||
}
|
||||
switch (sizeof(z_off_t)) {
|
||||
switch ((int)(sizeof(z_off_t))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 6; break;
|
||||
case 8: flags += 2 << 6; break;
|
||||
|
@ -85,27 +87,27 @@ uLong ZEXPORT zlibCompileFlags()
|
|||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
#ifdef STDC
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifdef NO_vsnprintf
|
||||
flags += 1L << 25;
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_vsprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
flags += 1L << 24;
|
||||
flags += 1L << 24;
|
||||
# ifdef NO_snprintf
|
||||
flags += 1L << 25;
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_sprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_snprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
@ -117,9 +119,9 @@ uLong ZEXPORT zlibCompileFlags()
|
|||
# ifndef verbose
|
||||
# define verbose 0
|
||||
# endif
|
||||
int z_verbose = verbose;
|
||||
int ZLIB_INTERNAL z_verbose = verbose;
|
||||
|
||||
void z_error (m)
|
||||
void ZLIB_INTERNAL z_error (m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
|
@ -146,7 +148,7 @@ const char * ZEXPORT zError(err)
|
|||
|
||||
#ifndef HAVE_MEMCPY
|
||||
|
||||
void zmemcpy(dest, source, len)
|
||||
void ZLIB_INTERNAL zmemcpy(dest, source, len)
|
||||
Bytef* dest;
|
||||
const Bytef* source;
|
||||
uInt len;
|
||||
|
@ -157,7 +159,7 @@ void zmemcpy(dest, source, len)
|
|||
} while (--len != 0);
|
||||
}
|
||||
|
||||
int zmemcmp(s1, s2, len)
|
||||
int ZLIB_INTERNAL zmemcmp(s1, s2, len)
|
||||
const Bytef* s1;
|
||||
const Bytef* s2;
|
||||
uInt len;
|
||||
|
@ -170,7 +172,7 @@ int zmemcmp(s1, s2, len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void zmemzero(dest, len)
|
||||
void ZLIB_INTERNAL zmemzero(dest, len)
|
||||
Bytef* dest;
|
||||
uInt len;
|
||||
{
|
||||
|
@ -181,6 +183,7 @@ void zmemzero(dest, len)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
#ifdef SYS16BIT
|
||||
|
||||
|
@ -213,7 +216,7 @@ local ptr_table table[MAX_PTR];
|
|||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf = opaque; /* just to make some compilers happy */
|
||||
ulg bsize = (ulg)items*size;
|
||||
|
@ -237,7 +240,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
|||
return buf;
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
if (*(ush*)&ptr != 0) { /* object < 64K */
|
||||
|
@ -272,13 +275,13 @@ void zcfree (voidpf opaque, voidpf ptr)
|
|||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
_hfree(ptr);
|
||||
|
@ -297,7 +300,7 @@ extern voidp calloc OF((uInt items, uInt size));
|
|||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (opaque, items, size)
|
||||
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
|
@ -307,7 +310,7 @@ voidpf zcalloc (opaque, items, size)
|
|||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void zcfree (opaque, ptr)
|
||||
void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
|
@ -316,3 +319,5 @@ void zcfree (opaque, ptr)
|
|||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -8,35 +8,28 @@
|
|||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: zutil.h 35458 2005-09-10 21:15:17Z MW $ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef _WIN32_WCE
|
||||
#if defined(STDC) && !defined(Z_SOLO)
|
||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_ERRNO_H
|
||||
# ifdef _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. We rename it to
|
||||
* avoid conflict with other libraries that use the same workaround.
|
||||
*/
|
||||
# define errno z_errno
|
||||
# endif
|
||||
extern int errno;
|
||||
#else
|
||||
# ifndef _WIN32_WCE
|
||||
# include <errno.h>
|
||||
# endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
|
@ -50,13 +43,13 @@ typedef unsigned short ush;
|
|||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
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 = (char*)ERR_MSG(err), (err))
|
||||
return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
@ -88,16 +81,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# 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 <alloc.h>
|
||||
# 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 <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -117,18 +112,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# ifdef M_I86
|
||||
#include <malloc.h>
|
||||
# if defined(M_I86) && !defined(Z_SOLO)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
@ -151,7 +148,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600))
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
|
@ -163,6 +160,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
# 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
|
||||
|
@ -175,40 +185,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
|
||||
/* functions */
|
||||
|
||||
#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
|
||||
#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) && defined(_MSC_VER) && _MSC_VER > 1500
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __SASC
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
#ifdef VMS
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(pyr)
|
||||
#if defined(pyr) || defined(Z_SOLO)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
|
@ -232,16 +209,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
extern void zmemzero OF((Bytef* dest, uInt len));
|
||||
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 <stdio.h>
|
||||
extern int z_verbose;
|
||||
extern void z_error OF((char *m));
|
||||
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 ;}
|
||||
|
@ -257,13 +234,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
|
||||
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
||||
void zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#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 */
|
||||
|
|
|
@ -48,7 +48,10 @@
|
|||
<ClCompile Include="src\zlib\compress.c" />
|
||||
<ClCompile Include="src\zlib\crc32.c" />
|
||||
<ClCompile Include="src\zlib\deflate.c" />
|
||||
<ClCompile Include="src\zlib\gzio.c" />
|
||||
<ClCompile Include="src\zlib\gzclose.c" />
|
||||
<ClCompile Include="src\zlib\gzlib.c" />
|
||||
<ClCompile Include="src\zlib\gzread.c" />
|
||||
<ClCompile Include="src\zlib\gzwrite.c" />
|
||||
<ClCompile Include="src\zlib\infback.c" />
|
||||
<ClCompile Include="src\zlib\inffast.c" />
|
||||
<ClCompile Include="src\zlib\inflate.c" />
|
||||
|
@ -57,4 +60,17 @@
|
|||
<ClCompile Include="src\zlib\uncompr.c" />
|
||||
<ClCompile Include="src\zlib\zutil.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\zlib\crc32.h" />
|
||||
<ClInclude Include="src\zlib\deflate.h" />
|
||||
<ClInclude Include="src\zlib\gzguts.h" />
|
||||
<ClInclude Include="src\zlib\inffast.h" />
|
||||
<ClInclude Include="src\zlib\inffixed.h" />
|
||||
<ClInclude Include="src\zlib\inflate.h" />
|
||||
<ClInclude Include="src\zlib\inftrees.h" />
|
||||
<ClInclude Include="src\zlib\trees.h" />
|
||||
<ClInclude Include="src\zlib\zconf.h" />
|
||||
<ClInclude Include="src\zlib\zlib.h" />
|
||||
<ClInclude Include="src\zlib\zutil.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -18,7 +18,16 @@
|
|||
<ClCompile Include="src\zlib\deflate.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\gzio.c">
|
||||
<ClCompile Include="src\zlib\gzclose.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\gzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\gzread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\gzwrite.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\zlib\infback.c">
|
||||
|
@ -43,4 +52,39 @@
|
|||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\zlib\crc32.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\deflate.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\gzguts.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\inffast.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\inffixed.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\inflate.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\inftrees.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\trees.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\zconf.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\zlib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\zlib\zutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue